tkormann 02/03/21 04:58:03 Modified: sources/org/apache/batik/bridge SVGTextElementBridge.java Added: samples/tests/spec/scripting textProperties.svg Log: basic support for all CSS properties on <text> element. tspan do not work yet (a bit more complicated). At this time, a new map is created each time per CSSEngineEvent. The only optimization so far is to reuse the layouted version of the AttributedString is the CSS properties only affects rendering and not layout) - eg. fill vs. letter-spacing Revision Changes Path 1.1 xml-batik/samples/tests/spec/scripting/textProperties.svg Index: textProperties.svg =================================================================== <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20000802//EN" "http://www.w3.org/TR/2000/CR-SVG-20000802/DTD/svg-20000802.dtd"> <!-- ====================================================================== --> <!-- Copyright (C) The Apache Software Foundation. All rights reserved. --> <!-- --> <!-- This software is published under the terms of the Apache Software --> <!-- License version 1.1, a copy of which has been included with this --> <!-- distribution in the LICENSE file. --> <!-- ====================================================================== --> <!-- ====================================================================== --> <!-- Modification of a rect's attributes --> <!-- --> <!-- @author [EMAIL PROTECTED] --> <!-- @version $Id: textProperties.svg,v 1.1 2002/03/21 12:58:03 tkormann Exp $ --> <!-- ====================================================================== --> <?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?> <svg id="body" width="450" height="500" viewBox="0 0 450 500"> <title>text CSS properties on 'onload'</title> <text x="50%" y="45" class="title">text CSS properties on 'onload'</text> <script type="text/ecmascript"><![CDATA[ function changeStyle(evt, newValue) { evt.target.setAttribute("style", newValue); } ]]></script> <g id="test-content" style="font-size:18"> <text x="100" y="100" onload="changeStyle(evt, 'font-family:Impact')">font-family:Arial</text> <text x="100" y="140" onload="changeStyle(evt, 'font-size:32')">font-size:32</text> <text x="100" y="180" onload="changeStyle(evt, 'fill:crimson')">fill:crimson</text> <text x="100" y="220" onload="changeStyle(evt, 'stroke:orange;font-size:18')">stroke:orange; font-size:18</text> <text x="50%" y="260" onload="changeStyle(evt, 'text-anchor:start')">text-anchor:start</text> <text x="50%" y="300" onload="changeStyle(evt, 'text-anchor:middle')">text-anchor:middle</text> <text x="50%" y="340" onload="changeStyle(evt, 'text-anchor:end')">text-anchor:end</text> <text x="100" y="380" onload="changeStyle(evt, 'font-weight:bold')">font-weight:bold</text> <text x="100" y="420" onload="changeStyle(evt, 'font-style:italic')">font-style:italic</text> <text x="100" y="460" onload="changeStyle(evt, 'letter-spacing:10')">letter-spacing:10</text> </g> </svg> 1.55 +107 -3 xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java Index: SVGTextElementBridge.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java,v retrieving revision 1.54 retrieving revision 1.55 diff -u -r1.54 -r1.55 --- SVGTextElementBridge.java 20 Mar 2002 16:34:43 -0000 1.54 +++ SVGTextElementBridge.java 21 Mar 2002 12:58:03 -0000 1.55 @@ -69,12 +69,14 @@ * * @author <a href="[EMAIL PROTECTED]">Stephane Hillion</a> * @author <a href="[EMAIL PROTECTED]">Bill Haneman</a> - * @version $Id: SVGTextElementBridge.java,v 1.54 2002/03/20 16:34:43 tkormann Exp $ + * @version $Id: SVGTextElementBridge.java,v 1.55 2002/03/21 12:58:03 tkormann Exp $ */ public class SVGTextElementBridge extends AbstractGraphicsNodeBridge { protected final static Integer ZERO = new Integer(0); + protected AttributedString layoutedText; + /** * Constructs a new bridge for the <text> element. */ @@ -172,10 +174,11 @@ Element e, GraphicsNode node) { e.normalize(); - AttributedString as = buildAttributedString(ctx, e); addGlyphPositionAttributes(as, e, ctx); - ((TextNode)node).setAttributedCharacterIterator(as.getIterator()); + if (ctx.isDynamic()) { + layoutedText = new AttributedString(as.getIterator()); + } // now add the painting attributes, cannot do it before this because // some of the Paint objects need to know the bounds of the text @@ -198,10 +201,111 @@ // BridgeUpdateHandler implementation ////////////////////////////////// /** + * This flag bit indicates if a new ACI has been created in + * response to a CSSEngineEvent. + * Avoid creating one ShapePainter per CSS property change + */ + private boolean hasNewACI; + + /** * Invoked when an MutationEvent of type 'DOMAttrModified' is fired. */ public void handleDOMAttrModifiedEvent(MutationEvent evt) { super.handleDOMAttrModifiedEvent(evt); + } + + /** + * Invoked when CSS properties have changed on an element. + * + * @param evt the CSSEngine event that describes the update + */ + public void handleCSSEngineEvent(CSSEngineEvent evt) { + hasNewACI = false; + int [] properties = evt.getProperties(); + // first try to find CSS properties that change the layout + for (int i=0; i < properties.length; ++i) { + switch(properties[i]) { + case SVGCSSEngine.TEXT_ANCHOR_INDEX: + case SVGCSSEngine.FONT_SIZE_INDEX: + case SVGCSSEngine.FONT_WEIGHT_INDEX: + case SVGCSSEngine.FONT_STYLE_INDEX: + case SVGCSSEngine.FONT_STRETCH_INDEX: + case SVGCSSEngine.FONT_FAMILY_INDEX: + case SVGCSSEngine.BASELINE_SHIFT_INDEX: + case SVGCSSEngine.UNICODE_BIDI_INDEX: + case SVGCSSEngine.DIRECTION_INDEX: + case SVGCSSEngine.WRITING_MODE_INDEX: + case SVGCSSEngine.GLYPH_ORIENTATION_VERTICAL_INDEX: + case SVGCSSEngine.LETTER_SPACING_INDEX: + case SVGCSSEngine.WORD_SPACING_INDEX: + case SVGCSSEngine.KERNING_INDEX: { + if (!hasNewACI) { + hasNewACI = true; + AttributedString as = buildAttributedString(ctx, e); + addGlyphPositionAttributes(as, e, ctx); + layoutedText = new AttributedString(as.getIterator()); + TextNode tn = (TextNode)node; + TextDecoration textDecoration = + getTextDecoration(e, tn, new TextDecoration(), ctx); + addPaintAttributes(as, e, tn, textDecoration, ctx); + tn.setAttributedCharacterIterator(as.getIterator()); + } + break; + } + } + } + // go for the other CSS properties + super.handleCSSEngineEvent(evt); + } + + /** + * Invoked for each CSS property that has changed. + */ + protected void handleCSSPropertyChanged(int property) { + switch(property) { + case SVGCSSEngine.FILL_INDEX: + case SVGCSSEngine.FILL_OPACITY_INDEX: + case SVGCSSEngine.STROKE_INDEX: + case SVGCSSEngine.STROKE_OPACITY_INDEX: + case SVGCSSEngine.STROKE_WIDTH_INDEX: + case SVGCSSEngine.STROKE_LINECAP_INDEX: + case SVGCSSEngine.STROKE_LINEJOIN_INDEX: + case SVGCSSEngine.STROKE_MITERLIMIT_INDEX: + case SVGCSSEngine.STROKE_DASHARRAY_INDEX: + case SVGCSSEngine.STROKE_DASHOFFSET_INDEX: + case SVGCSSEngine.TEXT_DECORATION_INDEX: { + if (!hasNewACI) { + hasNewACI = true; + System.out.println(node+" "+property); + AttributedString as = + new AttributedString(layoutedText.getIterator()); + TextNode tn = (TextNode)node; + TextDecoration textDecoration = + getTextDecoration(e, tn, new TextDecoration(), ctx); + addPaintAttributes(as, e, tn, textDecoration, ctx); + tn.setAttributedCharacterIterator(as.getIterator()); + } + break; + } + case SVGCSSEngine.TEXT_RENDERING_INDEX: { + RenderingHints hints = node.getRenderingHints(); + hints = CSSUtilities.convertTextRendering(e, hints); + if (hints != null) { + node.setRenderingHints(hints); + } + break; + } + case SVGCSSEngine.COLOR_RENDERING_INDEX: { + RenderingHints hints = node.getRenderingHints(); + hints = CSSUtilities.convertColorRendering(e, hints); + if (hints != null) { + node.setRenderingHints(hints); + } + break; + } + default: + super.handleCSSPropertyChanged(property); + } } // -----------------------------------------------------------------------
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]