Hi again !
I solved it, although the solution might not be 100% (only supprots
matrix-transformations, not translate, scale, and skew-commands). But since I
always use matrix-tranformations in my software, it works perfectly for me.
So if anyone is having the same problem as I had, here's a bit of code that
will solve it:
This code is extracted from a special FlowRootSVGElement-class where
getElement() returns the flowRoot-element.
/**
* Retrieves the total transformation Matrix from the documents root to
this element
* Since the flowRoot-object itself is not Locatable, get the first
Element in flowRegion and calculate the transformation-matrix to that object
instead.
* @return
*/
public SVGMatrix getDocumentTransformToThisElement()
{
try
{
NodeList nl = getFlowRegionNodes(getElement());
Element e = null;
if (nl != null && nl.getLength() > 0)
for (int x = 0; x < nl.getLength(); x++)
if (nl.item(x).getNodeType() ==
Node.ELEMENT_NODE)
{
e = (Element)nl.item(x);
break;
}
if (e != null)
return getTransformToElement(e).inverse();
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
/**
* A number of the flowRoot:s elements doesn't support SVGLocatable,
which has the effect that
* that getDocumentElement().getTransformToElement() will not work. So
this method retrieves
* all the transform-data by getting it from SVGLocatable when
possible, and otherwise extracting
* it from the matrix-data in the transform-tag - all the way from the
object up to the DocumentElement.
*
* @param e
* @return
*/
protected SVGMatrix getTransformToElement(Element e)
{
// Initialize our node's Current Transformation Matrix
SVGMatrix CTM = new SVGOMMatrix(new AffineTransform(1d, 0d, 0d, 1d,
0d, 0d));
// Work our way bacwards through the ancestor nodes stopping at the
// SVG Document
do
{
if (e.getNodeType() == Node.ELEMENT_NODE)
{
// Multiply the new CTM with what we've accumulated so
far
try {
SVGLocatable loc_e = (SVGLocatable)e;
CTM = loc_e.getCTM().multiply(CTM);
} catch (Exception ex)
{
// Not SVGLocatable, extract the matrix-data
manually from the transform-tag
AffineTransform af =
FlowRootSvgElement.GetObjTransform(e, true);
if (af != null)
{
SVGMatrix m = new SVGOMMatrix(af);
CTM = m.multiply(CTM);
}
}
}
}
while ( ( e = (Element)e.getParentNode() ) !=
e.getOwnerDocument().getDocumentElement() );
return CTM;
}
/**
* Will return the current transformation of the Element
* @param el
* @param includeTranslation If the translation-data should be removed
from the translation or not
* @return
*/
public static AffineTransform GetObjTransform(Element el, boolean
includeTranslation)
{
float values[] = new float[] {1, 0, 0, 1, 0, 0};
// get the value of the transform-node
String tmpTransform = el.getAttribute("transform");
// if transform exists, extract the values
if (tmpTransform != null && tmpTransform != "")
{
try
{
Pattern p =
Pattern.compile("matrix\\((\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\)");
Matcher m = p.matcher(tmpTransform);
m.find();
for(int x = 0; x < 6; x++)
values[x] =
Float.valueOf(m.group(x+1)).floatValue();
if (!includeTranslation) // Remove the
translation
values[4] = values[5] = 0;
}
catch (Exception ex)
{
System.out.println(tmpTransform);
ex.printStackTrace();
return null;
}
}
// Create a transformation-object from the values in transfom
return new AffineTransform(values);
}
Regards
Henric Rosvall
-----Original Message-----
From: Henric Rosvall [mailto:[EMAIL PROTECTED]
Sent: den 12 oktober 2006 16:52
To: [email protected]
Subject: flowRoot and getTransformToElement
Hi !
I'm, trying to implement multiline-text in my software by adding support for
modifying flowRoot-elements. To get information about where an element is
located, I traverse down to the objects in flowRegion, and get the BBox of
those objects (since flowRoot, flowRegion and such doesn't implement
SVGLocatable), and it works perfectly - at least until I try to get the
transform from the document root down to the obects in the flowRegion. It
doesn't seem to matter how much I've moved or rotated the flowRoot-Element,
getTransformToElement() still returns a SVGMatrix that shows no transformation
what so ever.
Here's a cut out example of the outputted SVG after I've opened the example SVG
in Batik (flowText.svg), and played around with it a bit:
<flowRoot font-size="20" id="maintext_0" transform="matrix(0.9591868
8.604429E-4 -0.41767913 0.73524845 188.0 46.0)">
<flowRegion>
<rect x="17" width="200" height="400" y="80"/>
<rect x="233" width="200" height="400" y="80"/>
</flowRegion>
<flowDiv>
<flowPara indent="20" margin-bottom="10">This is an <flowSpan
fill="crimson" font-size="40">exÂample</flowSpan> of a very long string that
is split â€across multiÂple lines via text wrapÂping.</flowPara>
</flowDiv>
</flowRoot>
As you can see there are some interesting matrix-transformations on the
flowRoot-element, but when trying to get the transform to the first rect in
flowRegion, it still returns a SVGMatrix without any transform - dispite the
fact that the rendering works perfectly.
The call I make to get the transform to the SVGElement e (which in this case
just happens to be the first rect in flowRegion):
((SVGSVGElement)e.getOwnerDocument().getDocumentElement()).getTransformToElement((SVGElement)e);
I'm using Batik 1.6. Would it help to upgrade to the latest build, or are there
some other way to solve this? Or am I simply doing something very wrong?
Regards
Henric Rosvall
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]