Opened 14 years ago

Closed 10 years ago

#1856 closed defect (fixed)

long strings don't wrap in SVG output

Reported by: walter Owned by: kandarpk
Priority: High Milestone: Unspecified
Component: Turtleart Version: Git as of bugdate
Severity: Major Keywords: sugar-love
Cc: rgs, smparrish Distribution/OS: Unspecified
Bug Status: New


Long strings don't wrap in the SVG output generated in Turtle Art. Is there a way to autowrap or do we need to generate separate tspans for each line?

Attachments (1)

svg_text_split_into_multiple_lines.patch (3.3 KB) - added by timClicks 14 years ago.
untested fix

Download all attachments as: .zip

Change History (10)

comment:1 Changed 14 years ago by walter

  • Priority changed from Unspecified by Maintainer to High

comment:2 Changed 14 years ago by timclicks


Each 'text' element causes a single string of text to be rendered. SVG performs no automatic line breaking or word wrapping. To achieve the effect of multiple lines of text, use one of the following methods:

  • The author or authoring package needs to pre-compute the line breaks and use multiple 'text' elements (one for each line of text).
  • The author or authoring package needs to pre-compute the line breaks and use a single 'text' element with one or more 'tspan' child elements with appropriate values for attributes x, y, dx and dy to set new start positions for those characters which start new lines. (This approach allows user text selection across multiple lines of text -- see Text selection and clipboard operations.)
  • Express the text to be rendered in another XML namespace such as XHTML [XHTML] embedded inline within a 'foreignObject' element. (Note: the exact semantics of this approach are not completely defined at this time.)

comment:3 Changed 14 years ago by rgs

  • Cc rgs added

comment:4 Changed 14 years ago by timClicks

This is one strategy for a function that would meet 2. 2 appears to be the friendliest to the user, because then they can select the whole paragraph.

parse SVG files, looking for text elements

for each text element

store the attrs as a dict
if there is a attrstyle?line-height?, then

set h as that value


set h to 13px #? - just a guess

split the contents into multiple strings #using split_at_len perhaps (below)
tspans = []
for each line in the split

tspans.append('<tspan x="%s" y="%s">%s</tspan>' % (x_of_parent, y_of_parent+h,line ))

insert tspans into the text area

def split_at_len(s, max_len=50, delimiter=None):
    Returns a list of strings, that are split from an
    input string. Delimits on whitespace by default.
    if delimiter is None:
        s = s.split()
        s = s.split(delimiter)

    lines = []
    current_line = ''
    for word in s:
        if len(current_line) >= max_len:
            current_line = word
            current_line = '%s %s' % (current_line, word);
    lines[0] = lines[0][1:] #hack required by string formatting
    return lines

Changed 14 years ago by timClicks

untested fix

comment:5 Changed 14 years ago by seeta

  • Owner changed from walter to kandarpk
  • Status changed from new to assigned

comment:6 Changed 14 years ago by smparrish

kandarpk Can you provide a status update?

comment:7 Changed 14 years ago by smparrish

  • Cc smparrish added

comment:8 Changed 14 years ago by smparrish

  • seeta_dev set to Kandarp

comment:9 Changed 10 years ago by walter

  • Resolution set to fixed
  • Status changed from assigned to closed

Fixed by Jorge Alberto Gómez López (in TB v194)

Note: See TracTickets for help on using tickets.