Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index



Hi everyone.

Some thoughts on the current svg text import implementation.

(1)
The ShapeWritingVisitor does not handle <tspan> element.
In fact only <text> element are mapped to XML_TEXT id,
the id for <tspan> element is XML_TSPAN and no such case
is present in the ShapeWritingVisitor::operator().

(2)
Only 'x' and 'y' attributes whose value is a single coordinate
are handled, whilst the value of such attributes can be a list
of coordinates where the n-th coordinate pair represents the
position at which the n-th character included in the given <text>
or <tspan> element has to be placed.
Reference: http://www.w3.org/TR/SVG11/text.html#TextElementXAttribute


A draft of a *possible* solution:

(1)
Implement an ad-hoc visitor to be applied to the svg DOM tree
before any other visitor in order to "normalize" text elements.
After normalization a <text> or <tspan> element that owns
a TEXT_NODE (that is an inter-tag character sequence) does not
own any ELEMENT_NODE.
So for example:
      <text>svg<tspan>import</tspan>filter</text>
should be transformed in:
      <text>
        <tspan>svg</tspan>
        <tspan>import</tspan>
        <tspan>filter</tspan>
      </text>

and:
      <text x="10, 20, 30" y="5, 15">HELLO<\text>
should be transformed in:
      <text>
        <tspan x="10" y="5">H</tspan>
        <tspan x="20" y="15">E</tspan>
        <tspan x="30">LLO</tspan>
      <\text>

(2)
Add to the AnnotateVisitor two new properties:
mnTextCurrentXPos, mnTextCurrentYPos.
After setting up all style properties the AnnotateVisitor
should perform something like the following pseudo-code.

if( Element is <text> or <tspan> )
{
    if( Element has 'x' attribute )
        mnTextCurrentXPos = value of 'x';


    if( Element has TEXT_NODE )
    {
        // text elements that does not have a TEXT_NODE are just
        // container providing style we do not need to handle them
        // further

        // the 'x' attribute will be added if not present
        set the value of the 'x' attribute to mnTextCurrentXPos;

        aText = extract text from Element;
        // compute the text width using
        // the current text style
        width = computeTextWidth( aText, aCurrentState )
        mnTextCurrentXPos += width;
    }

    // do the same for the y attribute
}

Moreover each time a root text element starts
the value of mnTextCurrentXPos and mnTextCurrentYPos
should be reset to zero.

The above implementation follows what all browsers at present
do for rendering svg text: that is if a <tspan> element does
not specify an 'x' attribute the current text position is used,
that is the last seen 'x' attribute not the parent one.
Indeed the standard says something different:

<< If the attribute is not specified: (a) if an ancestor ‘text’
or ‘tspan’ element specifies an absolute X coordinate for
a given character via an ‘x’ attribute, then that absolute X
coordinate is used (nearest ancestor has precedence),
else (b) the starting X coordinate for rendering the glyphs
corresponding to a given character is the X coordinate of
the resulting current text position from the most recently
rendered glyph for the current ‘text’ element.>>


Computation of text width and height should take into account
the value of text style attributes.
The real problem is how to perform such computations ?

Note that in order to not make things even more complex I have
ignored dx, dy, and rotate attributes and transformations too.

(3)
XML_TEXT and XML_TSPAN should be handled by the same case:
if the element owns a TEXT_NODE (and so no ELEMENT_NODE after
normalization) the text is extracted and a odf text element
is created;
in case the element has only ELEMENT_NODEs (that is one or more
<tspan>) it should be handled as a <g> element.
The visitElements routine will be responsible for iterating
on children (<tspan> elements).


Well for sure it lacks a lot of details and I have not taken
into account several issues, anyway I think it can be regarded
as a start point.

Cheers,
-- Marco

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.