colorlab
clone your own copy | download snapshot

Snapshots | iceberg

Inside this repository

poster_back_text.py
text/x-python

Download raw (10.9 KB)

# -*- coding: utf-8 -*-

from chiplotle import *
from chiplotle.hpgl import commands
import random
import math
import re
from configureMemory import configureMemory
from instantiate_plotter_on_port import instantiate_plotter_on_port

#################################
## VIRTUAL OR HARDWARE PLOTTER ##
#################################

VIRTUAL = False

x_unit = 0
y_unit = 0

# if VIRTUAL:
#     from chiplotle.tools.plottertools import instantiate_virtual_plotter
#     plotter =  instantiate_virtual_plotter(left_bottom = Coordinate(-17300,-11880), right_top = Coordinate(16340,11880), type="DPX-3300")
#     plotter.margins.hard.draw_outline()
#     plotter.select_pen(1)

# else:
#     plotter = instantiate_plotters( )[0]
#     plotter.select_pen(1)

#######################################
## VARIOUS FUNCTIONS TO PROCESS TEXT ##
#######################################

def mm(amount):
    return amount * 40

def cm(amount):
    return amount * 400

def units_to_cm(amount):
    return amount / 400.0

def title(input_text, char_widht, char_height):
    input_text = input_text.upper()
    if " " in input_text:
        formatted_text = input_text.replace(" ", "\r\n")
        input_text = formatted_text
    title = shapes.group([])
    movement = 0
    for i in range(8):
        title_text = shapes.label(input_text, units_to_cm(char_widht), units_to_cm(char_height),0,0)
        transforms.center_at(title_text, (movement,0))
        title.append(title_text)
        movement += (y_unit)/7
    return title

def title_splitter(text): # Makes the title have the same spacing as the pattern.
    gapped_title = shapes.group([])
    pos_y = 0 * y_unit
    change = 8 * y_unit 
    for letter in text:
        l = title(letter, 5 * y_unit, 6 * x_unit)
        transforms.rotate(l, math.radians(90))
        transforms.offset(l, (0, pos_y))
        gapped_title.append(l)
        pos_y += change

    return gapped_title

# Returns a tuple with the word, and a boolean whether it's bold
# if it's bold also return tokens before and after bold sign
# *word*, → ('word,', True)
def add_style_annotation (word):
    m = re.match(r'^(\W?)\*(.+)\*(\W?)$', word)

    if m:
        return ('{}{}{}'.format(m.group(1), m.group(2), m.group(3)), True)
    else:
        return (word, False)

# Changes boldness across multiple word to bold per word.
# *one two three* *one* *two* *three*
def bold_per_word (m):
    return re.sub(r'(\s+)', '*\\1*', m.group(0))

def tokenize_text (text):
    text = re.sub(r'\*[^\*]+\*', bold_per_word, text.replace('\r\n', '\n').replace('\n', ' __newline__ '))
    return [add_style_annotation(w) for w in re.split(r'\s+', text)]


def line_length(txt, char_width):
    return len(txt) * char_width * 1.3

def make_label (text, char_width, char_height, offset):
    line = shapes.label(text, units_to_cm(char_width), units_to_cm(char_height), -.1, 1)
    transforms.offset(line, (0, -offset))
    return line

# Transform text lines into plotter labels
def make_labels (lines, charwidth, charheight, charspace=None, linespace=None, offset=None):
    text = '{}{}'.format(chr(10), chr(13)).join(lines)
    label = shapes.label(text, charwidth=units_to_cm(charwidth), charheight=units_to_cm(charheight), charspace=charspace, linespace=linespace)
    if offset:
        transforms.offset(label, offset)
    return label

def bufferLength (annotated_words, separator=" ", prefix="", char_width=1):
    if annotated_words:
        separator_length = line_length(separator, char_width)
        length = line_length(prefix, char_width)

        # Loop through words, if they're bold count an extra char
        for word, bold in annotated_words:
            length += line_length(word, char_width)
            if bold:
                length += line_length(word[-1], char_width)

        # add spaces
        length += (len(annotated_words) - 1) * separator_length

        return length
    else:
        return 0

def makeLines (text, width, char_width, prefix = ""):
  lines = []
  buff = []
  separator = " "
  # print(text, tokenize_text(text))
  for token in tokenize_text(text):
    # print(token)
    length = bufferLength(buff, separator, prefix, char_width)
    word_length = bufferLength([token], separator, separator, char_width)

    if (width and length + word_length > width) or token[0] == '__newline__':
      lines.append(buff)
      buff = [token] if token[0] <> '__newline__' else []
    else:
      if '°' in token[0]:
        buff.append((token[0].replace("°", chr(14) + chr(122) + chr(15)), token[1]))
      else:
        buff.append(token)

  if buff:
    lines.append(buff)

  normal = [prefix + separator.join([word for word, _ in line]) for line in lines]
  bold = [prefix + separator.join([word if bold else len(word) * ' ' for word, bold in line]) for line in lines]

  return (normal, bold)

def body(input_text, width, char_width, char_height, line_height, charspace=-.1, linespace=None):
  linesRegular, _ = makeLines(input_text, width, char_width)

  return make_labels(linesRegular, charwidth=char_width, charheight=char_height, charspace=charspace, linespace=linespace)

#######################
## VARIOUS FUNCTIONS ##
#######################

def kask(): #Draws the KASK logo
  logo = shapes.group([])
  half = shapes.group([])
  lower_half = shapes.group([])

  height = 1 * x_unit
  width = 0.8 * y_unit

  vertical_indent = height / 2.0

  k_1 = shapes.label("K", units_to_cm(width), units_to_cm(height),0,0)
  a = shapes.label("A", units_to_cm(width), units_to_cm(height),0,0)
  transforms.offset(a, (1 * y_unit, vertical_indent))
  s = shapes.label("S", units_to_cm(width), units_to_cm(height),0,0)
  transforms.offset(s, (2 * y_unit, vertical_indent))
  k_2 = shapes.label("K", units_to_cm(width), units_to_cm(height),0,0)
  transforms.offset(k_2, (3 * y_unit, 0))

  half.append(k_1)
  half.append(a)
  half.append(s)
  half.append(k_2)
  
  k_3 = shapes.label("K", units_to_cm(width), units_to_cm(height),0,0)
  a_1 = shapes.label("A", units_to_cm(width), units_to_cm(height),0,0)
  transforms.offset(a_1, (1 * y_unit, vertical_indent))
  s_1 = shapes.label("S", units_to_cm(width), units_to_cm(height),0,0)
  transforms.offset(s_1, (2 * y_unit, vertical_indent))
  k_4 = shapes.label("K", units_to_cm(width), units_to_cm(height),0,0)
  transforms.offset(k_4, (3 * y_unit, 0))

  lower_half.append(k_3)
  lower_half.append(a_1)
  lower_half.append(s_1)
  lower_half.append(k_4)
  
  logo.append(half)
  transforms.rotate(lower_half, math.radians(180))
  transforms.offset(lower_half, (3.8 * y_unit,- 0.2 * y_unit))
  logo.append(lower_half)

  border = shapes.ellipse(5.5 * y_unit, 4 * x_unit)
  transforms.offset(border, ((3.8 * y_unit)/2, (-0.2 * y_unit)/2))
  logo.append(border)

  transforms.rotate(logo, math.radians(90))
  transforms.center_at(logo, (0,0))
  return logo

def conservatorium ():
  charwidth = .2 * x_unit
  charheight = 0.3 * y_unit
  shift = 0.5 * charheight

  parts = ['CON', 'SER', 'VA', 'TO', 'RIUM']

  logo = Group()
  lines = Group()

  outline = shapes.rectangle(16 * 1.5 * charwidth, 6.5 * 2 * charheight)
  transforms.offset(outline, (7 * 1.5 * charwidth, -2.1 * 2 * charheight))
  logo.append(outline)

  for r in range(6):
    omit = len(parts) - r
    line = Group()
    x = 0
    for p, text in enumerate(parts):
      if p <> omit:
        label = shapes.label(text, charwidth=units_to_cm(charwidth), charheight=units_to_cm(charheight), charspace=0, linespace=0)
        if p % 2 == 1:
          transforms.offset(label, (x, shift))
        else:
          transforms.offset(label, (x, 0))
        line.append(label)

      x += len(text) * charwidth * 1.55

    transforms.offset(line, (0, -charheight * 2 * r))

    lines.append(line)
  
  # transforms.center_at(lines, (0,0))

  logo.append(lines)

  transforms.rotate(logo, math.radians(90))

  return logo

def hogent():
  charwidth = .5 * x_unit
  charheight = .6 * y_unit

  hogent = shapes.label('HO\r\nGENT', charwidth=units_to_cm(charwidth), charheight=units_to_cm(charheight), charspace=0, linespace=0)
  howest = shapes.label('howest', charwidth=units_to_cm(charwidth) * .75, charheight=units_to_cm(charheight), charspace=-.1, linespace=0)
  
  transforms.offset(hogent, (0, charheight * -1))
  transforms.offset(howest, (0, charheight * -6))

  logo = Group([hogent, howest])

  transforms.rotate(logo, math.radians(90))
  transforms.center_at(logo, (0,0))

  return logo

def x(input):
  return input * x_unit

def y(input):
  return input * y_unit

def draw (plotter, pen=1, speed=15, force=3):
  global x_unit, y_unit

  #######################
  ## DEFINING THE GRID ##
  #######################

  plotter.set_origin_bottom_left()
  width = plotter.margins.hard.width
  height = plotter.margins.hard.height

  x_unit = width / 80.0 
  y_unit = height / 64.0 


  ######################
  ## DRAWING THE TEXT ##
  ######################
  plotter.select_pen(pen)
  plotter.write(commands.FS(force))
  plotter.write(commands.VS(speed))

  header_title_text = "Colorlab research,"
  header_text = "Colorlab research, initiated by Laboratorium with\nOSP (Einar Andersen, Gijs de Heij & Sarah Magnan)."
  body_text = "This publication is published under the Free Art License and has been generated with a python script.\nAll files are available on osp.kitchen/work/colorlab.\n\nPlotted with living colors produced by Maria Boto Ordonez within Kask Laboratorium.\n\nwww.laboratorium.bio."

  poster_title = shapes.group([])

  living = title_splitter("Living")
  transforms.offset(living, (x(71), y(1)))
  colors = title_splitter("Colors")
  transforms.offset(colors, (x(79), y(1)))

  header_t = body(header_text, y(14), y(0.2), x(0.4), x(1))
  transforms.rotate(header_t, math.radians(90))
  transforms.offset(header_t, (x(70), y(48)))

  body_t = body(body_text, y(14), y(0.2), x(0.4), x(1))
  transforms.rotate(body_t, math.radians(90))
  transforms.offset(body_t, (x(73), y(48)))

  kask_logo = kask()
  transforms.center_at(kask_logo, (x(60), y(44)))

  conservatorium_logo = conservatorium()
  transforms.center_at(conservatorium_logo, (x(60), y(50.75)))

  hogent_logo = hogent()
  transforms.center_at(hogent_logo, (x(60), y(55)))
  transforms.offset(hogent_logo, (x(.25), 0))

  poster_title.extend([living, colors, header_t, body_t, kask_logo, conservatorium_logo, hogent_logo])
  plotter.write(poster_title)


  ############
  ## FINISH ##
  ############

  plotter.select_pen(0)

if __name__ == '__main__':
  if VIRTUAL:
    from chiplotle.tools.plottertools import instantiate_virtual_plotter
    plotter = instantiate_virtual_plotter(left_bottom = Coordinate(-17300,-11880), right_top = Coordinate(16340,11880), type="DPX-3300")
    plotter.margins.hard.draw_outline()
    draw(plotter, pen=1, speed=15, force=3)


  else:
    # plotter = instantiate_plotters()[0]
    plotter = instantiate_plotter_on_port('/dev/ttyUSB0')
    configureMemory(plotter, 9678, 2048, 0, 0, 0, 1024)
    plotter.rotate(0)

    while (True):
      draw(plotter, pen=1, speed=15, force=3)
      next = str(raw_input('Plot next?'))


  if VIRTUAL:
      io.view(plotter)