Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/ep_layer_letterpress.py
diff options
context:
space:
mode:
Diffstat (limited to 'ep_layer_letterpress.py')
-rw-r--r--ep_layer_letterpress.py216
1 files changed, 216 insertions, 0 deletions
diff --git a/ep_layer_letterpress.py b/ep_layer_letterpress.py
new file mode 100644
index 0000000..7ce19d9
--- /dev/null
+++ b/ep_layer_letterpress.py
@@ -0,0 +1,216 @@
+# coding: UTF8
+# Copyright 2009 Thomas Jourdan
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import math
+import random
+import pango
+import pangocairo
+import model_layer
+import ka_random
+import model_constraintpool
+import exon_color
+import exon_position
+import exon_direction
+import exon_buzzword
+
+class LetterPress(model_layer.Layer):
+ """LetterPress
+ inv: len(self.direction_steps) > 0
+ """
+
+ cdef = [{'bind' : 'family',
+ 'name' : 'Font family',
+ 'domain': model_constraintpool.STRING_1_OF_N,
+ 'enum' : ['Sans',
+ 'Nimbus Sans L',
+ 'Monospace',]},
+ {'bind' : 'style',
+ 'name' : 'Font style',
+ 'domain': model_constraintpool.INT_1_OF_N,
+ 'enum' : [('Normal', pango.STYLE_NORMAL),
+ ('Oblique', pango.STYLE_OBLIQUE),
+ ('Italic', pango.STYLE_ITALIC),]},
+ {'bind' : 'size',
+ 'name' : 'Font size',
+ 'domain': model_constraintpool.INT_RANGE,
+ 'min' : 4, 'max': 64},
+ ]
+
+ font_style = {pango.STYLE_NORMAL: 'Normal',
+ pango.STYLE_OBLIQUE: 'Oblique',
+ pango.STYLE_ITALIC: 'Italic',
+ }
+
+ def __init__(self, trunk):
+ """LetterPress diagram layer constructor"""
+ super(LetterPress, self).__init__(trunk)
+ cpool = model_constraintpool.ConstraintPool.get_pool()
+ self.textcolor = exon_color.Color(self.path, 0, 0, 0, 1)
+ self.family = cpool.get(self, 'family')[0]
+ self.style = cpool.get(self, 'style')[0]
+ self.size = cpool.get(self, 'size')[0]
+ self.center = exon_position.Position(self.path, 0.0, 0.0)
+ self.direction_steps = [exon_direction.Direction(self.path, 0.0, 0.0)]
+ self.buzzwords = exon_buzzword.Buzzword(self.path, [''])
+
+ def __eq__(self, other):
+ """Equality based on the objects components."""
+ equal = isinstance(other, LetterPress) \
+ and super(LetterPress, self).__eq__(other) \
+ and self.textcolor == other.textcolor \
+ and self.family == other.family \
+ and self.style == other.style \
+ and self.size == other.size \
+ and self.center == other.center \
+ and len(self.direction_steps) == len(other.direction_steps) \
+ and self.buzzwords == other.buzzwords
+ if equal:
+ for index, direction in enumerate(self.direction_steps):
+ equal = equal and direction == other.direction_steps[index]
+ return equal
+
+ def randomize(self):
+ """Randomize the layers components."""
+ super(LetterPress, self).randomize()
+ cpool = model_constraintpool.ConstraintPool.get_pool()
+ family_constraint = cpool.get(self, 'family')
+ style_constraint = cpool.get(self, 'style')
+ size_constraint = cpool.get(self, 'size')
+ self.textcolor.randomize()
+ self.family = random.choice(family_constraint)
+ self.style = random.choice(style_constraint)
+ self.size = random.randint(size_constraint[0], size_constraint[1])
+ self.center.randomize()
+ self.buzzwords.randomize()
+ self.direction_steps = []
+ for i in range(random.randint(1, 6)):
+ direction = exon_direction.Direction(self.path, 0.0, 0.0)
+ direction.randomize()
+ self.direction_steps.append(direction)
+
+ def mutate(self):
+ """Make small random changes to the layers components."""
+ super(LetterPress, self).mutate()
+ cpool = model_constraintpool.ConstraintPool.get_pool()
+ family_constraint = cpool.get(self, 'family')
+ style_constraint = cpool.get(self, 'style')
+ size_constraint = cpool.get(self, 'size')
+ self.textcolor.mutate()
+ if ka_random.is_mutating():
+ self.family = random.choice(family_constraint)
+ if ka_random.is_mutating():
+ self.style = random.choice(style_constraint)
+ if ka_random.is_mutating():
+ self.size += random.randint(-12, 12)
+ self.size = ka_random.limitate_range(self.size, \
+ size_constraint[0], \
+ size_constraint[1])
+ self.center.mutate()
+ self.buzzwords.mutate()
+ for direction in self.direction_steps:
+ direction.mutate()
+
+ def shuffle(self):
+ """Shuffle similar componets."""
+ super(LetterPress, self).shuffle()
+ self.buzzwords.shuffle()
+# self.direction_steps.shuffle()
+
+ def crossingover(self, other):
+ """
+ pre: isinstance(other, LetterPress)
+ pre: isinstance(self, LetterPress)
+ # check for distinct references, needs to copy content, not references
+ post: __return__ is not self
+ post: __return__ is not other
+ """
+ new_one = LetterPress(self.get_trunk())
+ crossing = self.crossingover_base(new_one, other, 5)
+ new_one.textcolor = self.textcolor.crossingover(other.textcolor)
+ new_one.center = self.center if crossing[0] else other.center
+ new_one.buzzwords = self.buzzwords if crossing[1] else other.buzzwords
+ new_one.family = self.family if crossing[2] else other.family
+ new_one.style = self.style if crossing[3] else other.style
+ new_one.size = self.size if crossing[4] else other.size
+ new_one.direction_steps = ka_random.crossingover(self.direction_steps, \
+ other.direction_steps)
+ return new_one
+
+ def draw(self, ctx, width, height):
+ """
+ pre: ctx is not None
+ pre: width > 0
+ pre: height > 0
+ pre: width == height
+ """
+# self.operator = cairo.OPERATOR_OVER
+ self.begin_draw(ctx, width, height)
+
+ ctx.scale(1.0/width, 1.0/height)
+ pango_ctx = pangocairo.CairoContext(ctx)
+ px, py = self.center.x_pos, self.center.y_pos
+ fi = di = -1
+ for word in self.buzzwords.wordlist:
+ di = (di+1) % len(self.direction_steps)
+ step = self.direction_steps[di]
+ px += step.offset * math.cos(step.radian)
+ py += step.offset * math.sin(step.radian)
+
+ layout = pango_ctx.create_layout()
+ fi = (fi+1) % len(self.family)
+ desc = pango.FontDescription(self.family[fi])
+ desc.set_size(self.size * pango.SCALE)
+ desc.set_style(self.style)
+ # desc.set_weight(self.font["weight"])
+ layout.set_text(word.encode('utf-8'))
+ layout.set_font_description(desc)
+ layout.set_alignment(pango.ALIGN_CENTER)
+ rgba = self.textcolor.rgba
+ pango_ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
+ pango_ctx.update_layout(layout)
+ pixel_extents = layout.get_pixel_extents()
+# extents = layout.get_extents()
+ dx = pixel_extents[1][2] / 2
+ dy = pixel_extents[1][3] / 2
+ pango_ctx.move_to((width * px) - dx, (height * py) - dy)
+ pango_ctx.show_layout(layout)
+
+ def explain(self, formater):
+# super(LetterPress, self).explain(formater)
+ formater.text_list('buzzwords: ', self.buzzwords.wordlist)
+ formater.color_item(self.textcolor, 'text color:')
+ formater.text_item(self.family \
+ + ', ' + LetterPress.font_style[self.style] \
+ + ', ' + str(self.size))
+ formater.position_item(self.center, 'center:')
+ formater.direction_array(self.direction_steps, 'direction:')
+
+ def copy(self):
+ """The LetterPress diagram layers copy constructor.
+ # check for distinct references, needs to copy content, not references
+ post: __return__ is not self
+ """
+ new_one = LetterPress(self.get_trunk())
+ self.copy_base(new_one)
+ new_one.textcolor = self.textcolor.copy()
+ new_one.family = self.family
+ new_one.style = self.style
+ new_one.size = self.size
+ new_one.center = self.center.copy()
+ new_one.buzzwords = self.buzzwords.copy()
+ new_one.direction_steps = ka_random.copy_list(self.direction_steps)
+ return new_one