summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/extensions/lettering_along_path.py152
-rw-r--r--lib/lettering/utils.py4
2 files changed, 80 insertions, 76 deletions
diff --git a/lib/extensions/lettering_along_path.py b/lib/extensions/lettering_along_path.py
index dcce8e1e..40c8206a 100644
--- a/lib/extensions/lettering_along_path.py
+++ b/lib/extensions/lettering_along_path.py
@@ -73,32 +73,33 @@ class TextAlongPath:
self.path = Stroke(path).as_multi_line_string().geoms[0]
self.text_position = text_position
- self.glyphs = [glyph for glyph in self.text.iterdescendants(SVG_GROUP_TAG) if glyph.label and len(glyph.label) == 1]
+ self.glyphs = [glyph for glyph in self.text.iterdescendants(SVG_GROUP_TAG) if glyph.get('inkstitch:letter-group', '') == 'glyph']
if not self.glyphs:
errormsg(_("The text doesn't contain any glyphs."))
return
self.load_settings()
+ self.font = get_font_by_id(self.settings.font)
+ if self.font is None:
+ errormsg(_("Couldn't identify the font specified in the lettering group."))
+ return
if self.glyphs[0].get('transform', None) is not None:
self._reset_glyph_transforms()
hidden_commands = self.hide_commands()
- space_indices, stretch_space, text_baseline = self.get_position_and_stretch_values()
- start_position = self.get_start_position()
- self.transform_glyphs(start_position, stretch_space, space_indices, text_baseline)
+ self.glyphs_along_path()
self.restore_commands(hidden_commands)
def _reset_glyph_transforms(self):
- font = get_font_by_id(self.settings.font)
- if font is not None:
+ if self.font is not None:
try:
text_group = list(self.text.iterchildren(SVG_GROUP_TAG))[0]
except IndexError:
pass
for glyph in text_group.iterchildren():
glyph.delete()
- rendered_text = font.render_text(
+ rendered_text = self.font.render_text(
self.settings.text,
text_group,
None, # we don't know the font variant (?)
@@ -106,41 +107,84 @@ class TextAlongPath:
self.settings.trim_option,
self.settings.use_trim_symbols
)
- self.glyphs = [glyph for glyph in rendered_text.iterdescendants(SVG_GROUP_TAG) if glyph.label and len(glyph.label) == 1]
+ self.glyphs = [glyph for glyph in rendered_text.iterdescendants(SVG_GROUP_TAG) if glyph.get('inkstitch:letter-group', '') == 'glyph']
- def get_start_position(self):
- start_position = 0
- text_length = self.text_length()
- path_length = self.path.length
- if self.text_position == 'center':
- start_position = (path_length - text_length) / 2
- if self.text_position == 'right':
- start_position = path_length - text_length
- return start_position
+ def glyphs_along_path(self):
+ path = self.path
+ for text_line in self.text.getchildren()[0].iterchildren():
+ self.transform_glyphs(path, text_line)
- def get_position_and_stretch_values(self):
- text_bbox = self.glyphs[0].getparent().bounding_box()
- text_baseline = text_bbox.bottom
+ # offset path for the next line
+ path = path.offset_curve(self.font.leading)
+
+ def transform_glyphs(self, path, line):
+ line_bbox = line.bounding_box()
+ text_baseline = line_bbox.bottom
+ text_width = line_bbox.width
if self.text_position == 'stretch':
- text_content = self.settings.text
- space_indices = [i for i, t in enumerate(text_content) if t == " "]
- text_bbox = self.text.bounding_box()
- text_width = convert_unit(text_bbox.width, 'px', self.svg.unit)
-
- if len(text_content) - 1 != 0:
- path_length = self.path.length
- stretch_space = (path_length - text_width) / (len(text_content) - 1)
- else:
- stretch_space = 0
+ num_spaces = len(line) - 1
+
+ line_glyphs = [glyph for glyph in line.iterdescendants(SVG_GROUP_TAG) if glyph.get('inkstitch:letter-group', '') == 'glyph']
+ total_stretch_spaces = len(line_glyphs) - 1 + num_spaces
+
+ stretch_space = (path.length - text_width) / total_stretch_spaces
else:
stretch_space = 0
- space_indices = []
- return space_indices, stretch_space, text_baseline
+ start_position = self.get_start_position(text_width, path.length)
+ text_scale = Transform(f'scale({self.settings.scale / 100})')
+ distance = start_position
+ old_bbox = None
+
+ words = line.getchildren()
+ if self.font.text_direction == "rtl":
+ words.reverse()
+ for word in words:
+ glyphs = word.getchildren()
+ if self.font.text_direction == "rtl":
+ glyphs.reverse()
+ for glyph in glyphs:
+ # dimensions
+ bbox = glyph.bounding_box()
+ transformed_bbox = glyph.bounding_box(word.composed_transform())
+ left = bbox.left
+ transformed_left = transformed_bbox.left
+ width = convert_unit(transformed_bbox.width, 'px', self.svg.unit)
+
+ # adjust position
+ if old_bbox:
+ distance += convert_unit(transformed_left - old_bbox.right, 'px', self.svg.unit) + stretch_space
+
+ new_distance = distance + width
+
+ # calculate and apply transform
+ first = path.interpolate(distance)
+ last = path.interpolate(new_distance)
+
+ angle = degrees(atan2(last.y - first.y, last.x - first.x)) % 360
+ translate = InkstitchPoint(first.x, first.y) - InkstitchPoint(left, text_baseline)
+
+ transform = Transform(f"rotate({angle}, {first.x}, {first.y}) translate({translate.x} {translate.y})")
+ correction_transform = Transform(get_correction_transform(glyph))
+ glyph.transform = correction_transform @ transform @ glyph.transform @ text_scale
+
+ # set values for next iteration
+ distance = new_distance
+ old_bbox = transformed_bbox
+
+ distance += stretch_space
+
+ def get_start_position(self, text_length, path_length):
+ start_position = 0
+ if self.text_position == 'center':
+ start_position = (path_length - text_length) / 2
+ if self.text_position == 'right':
+ start_position = path_length - text_length
+ return start_position
- def text_length(self):
- return convert_unit(self.text.bounding_box().width, 'px', self.svg.unit)
+ def text_length(self, line):
+ return convert_unit(line.bounding_box().width, 'px', self.svg.unit)
def hide_commands(self):
# hide commmands for bounding box calculation
@@ -156,46 +200,6 @@ class TextAlongPath:
for command in hidden_commands:
command.style['display'] = "inline"
- def transform_glyphs(self, start_position, stretch_space, space_indices, text_baseline):
- text_scale = Transform(f'scale({self.settings.scale / 100})')
- distance = start_position
- old_bbox = None
- i = 0
-
- for glyph in self.glyphs:
- # dimensions
- bbox = glyph.bounding_box()
- transformed_bbox = glyph.bounding_box(glyph.getparent().composed_transform())
- left = bbox.left
- transformed_left = transformed_bbox.left
- width = convert_unit(transformed_bbox.width, 'px', self.svg.unit)
-
- # adjust position
- if old_bbox:
- distance += convert_unit(transformed_left - old_bbox.right, 'px', self.svg.unit) + stretch_space
-
- if self.text_position == 'stretch' and i in space_indices:
- distance += stretch_space
- i += 1
-
- new_distance = distance + width
-
- # calculate and apply transform
- first = self.path.interpolate(distance)
- last = self.path.interpolate(new_distance)
-
- angle = degrees(atan2(last.y - first.y, last.x - first.x)) % 360
- translate = InkstitchPoint(first.x, first.y) - InkstitchPoint(left, text_baseline)
-
- transform = Transform(f"rotate({angle}, {first.x}, {first.y}) translate({translate.x} {translate.y})")
- correction_transform = Transform(get_correction_transform(glyph))
- glyph.transform = correction_transform @ transform @ glyph.transform @ text_scale
-
- # set values for next iteration
- distance = new_distance
- old_bbox = transformed_bbox
- i += 1
-
def load_settings(self):
"""Load the settings saved into the text element"""
diff --git a/lib/lettering/utils.py b/lib/lettering/utils.py
index bd7a208d..9641e0a4 100644
--- a/lib/lettering/utils.py
+++ b/lib/lettering/utils.py
@@ -47,7 +47,7 @@ def get_font_by_id(font_id):
continue
for font_dir in font_dirs:
font = _get_font_from_path(font_path, font_dir)
- if font and font.id == font_id:
+ if font and font_id in [font.id, font.marked_custom_font_id]:
return font
return None
@@ -61,7 +61,7 @@ def get_font_by_name(font_name):
continue
for font_dir in font_dirs:
font = _get_font_from_path(font_path, font_dir)
- if font and font.name == font_name:
+ if font and font_name in [font.name, font.marked_custom_font_name]:
return font
return None