google-code-export / svgweb

Automatically exported from code.google.com/p/svgweb
Other
1 stars 1 forks source link

tspan without x,y attibutes positioned incorrectly #439

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Within a text element place a tspan around some of the text.  If this tspan
has no x,y attributes, the position of the tspan text is positioned
incorrectly at the x,y of the parent text element.

The tspan text should start from the current text position as determined by
any preceding text.  Text following the tspan should start from the current
text position at the end of the tspan text.

The key line in the attached example is

<text font-family="Arial" font-size="144" fill="black" x="145" y="254">one
<tspan fill="red">two</tspan> three</text>

You would expect the text to appear as "one two three" with "two" being
red.  Instead, "onethree" is rendered on top of a red "two".

Tested with Xp, Vista, Opera, Firefox, Webkit,... Flash 10 and
Gelatinous-Cube. The attached example embeds svg via the script tag and
references svg.js:
<script src="../src/svg.js" data-path="../src"></script>

Original issue reported on code.google.com by k...@svgmaker.com on 8 Dec 2009 at 3:30

Attachments:

GoogleCodeExporter commented 9 years ago
For my own needs I created a quick/temporary solution. Basically I look up the 
'older
sibling' of the current node and calculate the offset based on the location and 
width
of the older sibling. It works for my purposes but should be reviewed and 
probably
refactored.

In the 'getAttribute'-function in SVGTextNode.as I replaced:
} else if ( (name == "x" || name == "y") ) {
...

With
} else if ( (name == "x" || name == "y") ) {
  if (_getAttribute(name)==null) {
    var index:int = svgParent.svgChildren.indexOf(this);
    if (index>0) {
      var prevSibling:SVGNode = svgParent.svgChildren[index-1];
      if (prevSibling is SVGTspanNode) {
        if (name == "x") {
          this.setAttribute("x",
Number(prevSibling.getAttribute("x"))+Number(prevSibling.topSprite.width)).toStr
ing());
        } else if (name == "y") {
            this.setAttribute("y",prevSibling.getAttribute("y"));
        }
      }
    }                
  }
 ...

Original comment by Matthijs.Mullender on 12 Jan 2010 at 2:20

GoogleCodeExporter commented 9 years ago
Thanks, Matthijs, but unfortunately, that approach doesn't help my example.

For the key line in the example,

<text font-family="Arial" font-size="144" fill="black" x="145" y="254">one
<tspan fill="red">two</tspan> three</text>

There is no (previous) tspan sibling to query for an x attribute + width.

The example is a simple case of the challenge of text layout.  Essentially, the
positioning of glyphs in each descendant node of a text element can depend on
all/some/none of the descendants as well as the root text node itself.

For example, if text-anchor="middle" were added to the text element of my 
example

<text text-anchor="middle" x="145" y="254">one <tspan fill="red">two</tspan> 
three</text>

The widths of all child nodes would be required before the correct positioning 
could
be determined.

Complicate it further with nested tspans , x,y lists and <a> elements, and it 
quickly
becomes very difficult to manage text layout from the level of each individual 
child
node.  The layout needs to be managed at the level of the text element node 
across
all descendants - a top down approach.

Original comment by k...@svgmaker.com on 13 Jan 2010 at 8:29