deweese 2003/08/22 03:49:06 Modified: sources/org/apache/batik/bridge BridgeEventSupport.java SVGFontFamily.java SVGTextElementBridge.java UserAgent.java UserAgentAdapter.java sources/org/apache/batik/css/engine CSSEngine.java sources/org/apache/batik/gvt/event AWTEventDispatcher.java sources/org/apache/batik/gvt/font AWTGVTGlyphVector.java Glyph.java sources/org/apache/batik/gvt/renderer StrokingTextPainter.java sources/org/apache/batik/gvt/text GlyphLayout.java sources/org/apache/batik/swing/svg JSVGComponent.java sources/org/apache/batik/transcoder SVGAbstractTranscoder.java Log: 1) clientX/Y should now be correct when the event target is a text element. 2) selectSubString should now work. 3) Text layout should be very marginally faster. 4) BridgeContext.dispose() is now called a bit later when transcoding (for nodes that need access to CSS when rendering - multiImage basicly). Revision Changes Path 1.51 +7 -5 xml-batik/sources/org/apache/batik/bridge/BridgeEventSupport.java Index: BridgeEventSupport.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/BridgeEventSupport.java,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- BridgeEventSupport.java 9 Aug 2003 16:58:37 -0000 1.50 +++ BridgeEventSupport.java 22 Aug 2003 10:49:06 -0000 1.51 @@ -304,7 +304,8 @@ boolean cancelable) { Point clientXY = evt.getClientPoint(); GraphicsNode node = evt.getGraphicsNode(); - Element targetElement = getEventTarget(node, clientXY); + Element targetElement = getEventTarget(node, + (Point)clientXY.clone()); Element relatedElement = getRelatedElement(evt); dispatchMouseEvent(eventType, targetElement, @@ -421,9 +422,10 @@ if (target != null && node instanceof TextNode) { TextNode textNode = (TextNode)node; List list = textNode.getTextRuns(); + Point pt = (Point)coords.clone(); // place coords in text node coordinate system try { - node.getGlobalTransform().createInverse().transform(coords, coords); + node.getGlobalTransform().createInverse().transform(pt, pt); } catch (NoninvertibleTransformException ex) { } if (list != null){ @@ -432,8 +434,8 @@ (StrokingTextPainter.TextRun)list.get(i); AttributedCharacterIterator aci = run.getACI(); TextSpanLayout layout = run.getLayout(); - float x = (float)coords.getX(); - float y = (float)coords.getY(); + float x = (float)pt.getX(); + float y = (float)pt.getY(); TextHit textHit = layout.hitTestChar(x, y); if (textHit != null && layout.getBounds2D().contains(x, y)) { Object delimiter = aci.getAttribute 1.7 +43 -1 xml-batik/sources/org/apache/batik/bridge/SVGFontFamily.java Index: SVGFontFamily.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGFontFamily.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- SVGFontFamily.java 8 Aug 2003 11:38:51 -0000 1.6 +++ SVGFontFamily.java 22 Aug 2003 10:49:06 -0000 1.7 @@ -56,7 +56,11 @@ import org.apache.batik.gvt.font.GVTFontFace; import org.apache.batik.gvt.font.GVTFontFamily; import org.apache.batik.gvt.text.GVTAttributedCharacterIterator; +import org.apache.batik.util.SVGConstants; + import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** * A font family class for SVG fonts. @@ -69,6 +73,9 @@ protected GVTFontFace fontFace; protected Element fontElement; protected BridgeContext ctx; + protected Boolean complex = null; + + /** * Constructs an SVGFontFamily. @@ -120,5 +127,40 @@ (GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER); return fontBridge.createFont(ctx, fontElement, textElement, size, fontFace); + } + + /** + * This method looks at the SVG font and checks if any of + * the glyphs use renderable child elements. If so this + * is a complex font in that full CSS inheritance needs to + * be applied. Otherwise if it only uses the 'd' attribute + * it does not need CSS treatment. + */ + public boolean isComplex() { + if (complex != null) return complex.booleanValue(); + boolean ret = isComplex(fontElement, ctx); + complex = new Boolean(ret); + return ret; + } + + public static boolean isComplex(Element fontElement, BridgeContext ctx) { + NodeList glyphElements = fontElement.getElementsByTagNameNS + (SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_GLYPH_TAG); + + int numGlyphs = glyphElements.getLength(); + for (int i = 0; i < numGlyphs; i++) { + Element glyph = (Element)glyphElements.item(i); + Node child = glyph.getFirstChild(); + for (;child != null; child = child.getNextSibling()) { + if (child.getNodeType() != Node.ELEMENT_NODE) + continue; + Element e = (Element)child; + Bridge b = ctx.getBridge(e); + if ((b != null) && (b instanceof GraphicsNodeBridge)) { + return true; + } + } + } + return false; } } 1.87 +27 -11 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.86 retrieving revision 1.87 diff -u -r1.86 -r1.87 --- SVGTextElementBridge.java 20 Aug 2003 11:31:45 -0000 1.86 +++ SVGTextElementBridge.java 22 Aug 2003 10:49:06 -0000 1.87 @@ -113,9 +113,15 @@ implements SVGTextContent { protected final static Integer ZERO = new Integer(0); + public static final + AttributedCharacterIterator.Attribute TEXT_COMPOUND_DELIMITER + = GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER; + protected AttributedString layoutedText; + protected boolean usingComplexSVGFont = false; + /** * Constructs a new bridge for the <text> element. */ @@ -1213,7 +1219,12 @@ TextNode node, TextDecoration textDecoration, BridgeContext ctx) { - + // TODO: All paint properties for an element should be + // bundled into one 'PaintProperty' object and only + // the one object should be associated with the ACI. + // This would also allow fill/stroke/underline etc + // changes to just update the PaintProperty object + // and trigger a repaint (avoiding relayout). // 'requiredFeatures', 'requiredExtensions' and 'systemLanguage' if (!SVGUtilities.matchUserAgent(element, ctx.getUserAgent())) { @@ -1223,15 +1234,15 @@ // calculate which chars in the string belong to this element int firstChar = -1; - for (int i = 0; i < aci.getEndIndex(); i++) { + for (int i = 0; i < aci.getEndIndex();) { aci.setIndex(i); - Element delimeter = (Element)aci.getAttribute( - GVTAttributedCharacterIterator. - TextAttribute.TEXT_COMPOUND_DELIMITER); + Element delimeter = (Element)aci.getAttribute + (TEXT_COMPOUND_DELIMITER); if (delimeter == element || nodeAncestorOf(element, delimeter)) { firstChar = i; break; } + i = aci.getRunLimit(TEXT_COMPOUND_DELIMITER); } if (firstChar == -1) return; // Element not part of aci (no chars in elem usually) @@ -1239,13 +1250,13 @@ int lastChar = aci.getEndIndex()-1; for (int i = aci.getEndIndex()-1; i >= 0; i--) { aci.setIndex(i); - Element delimeter = (Element)aci.getAttribute( - GVTAttributedCharacterIterator. - TextAttribute.TEXT_COMPOUND_DELIMITER); + Element delimeter = (Element)aci.getAttribute + (TEXT_COMPOUND_DELIMITER); if (delimeter == element || nodeAncestorOf(element, delimeter)) { lastChar = i; break; } + i = aci.getRunStart(TEXT_COMPOUND_DELIMITER); } // Opacity @@ -1418,6 +1429,12 @@ GVTFontFamily fontFamily = SVGFontUtilities.getFontFamily(element, ctx, fontFamilyName, fontWeightString, fontStyleString); + if (fontFamily instanceof SVGFontFamily) { + SVGFontFamily svgFF = (SVGFontFamily)fontFamily; + if (svgFF.isComplex()) { + usingComplexSVGFont = true; + } + } fontFamilyList.add(fontFamily); } @@ -2680,8 +2697,7 @@ lastMark = textNode.getMarkerForChar(lastChar,false); } - textNode.setSelection(firstMark,lastMark); - + ctx.getUserAgent().setTextSelection(firstMark,lastMark); } protected int getCharNumAtPosition(Element e, float x, float y){ 1.29 +9 -1 xml-batik/sources/org/apache/batik/bridge/UserAgent.java Index: UserAgent.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/UserAgent.java,v retrieving revision 1.28 retrieving revision 1.29 diff -u -r1.28 -r1.29 --- UserAgent.java 8 Aug 2003 11:38:51 -0000 1.28 +++ UserAgent.java 22 Aug 2003 10:49:06 -0000 1.29 @@ -56,6 +56,7 @@ import java.awt.geom.Dimension2D; import org.apache.batik.gvt.event.EventDispatcher; +import org.apache.batik.gvt.text.Mark; import org.apache.batik.util.ParsedURL; import org.w3c.dom.Element; import org.w3c.dom.svg.SVGAElement; @@ -165,6 +166,13 @@ * @param cursor the new cursor */ void setSVGCursor(Cursor cursor); + + /** + * Informs the user agent that the text selection has changed. + * @param start The Mark for the start of the selection. + * @param end The Mark for the end of the selection. + */ + void setTextSelection(Mark start, Mark end); /** * Returns the class name of the XML parser. 1.17 +7 -1 xml-batik/sources/org/apache/batik/bridge/UserAgentAdapter.java Index: UserAgentAdapter.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/UserAgentAdapter.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- UserAgentAdapter.java 9 Aug 2003 16:58:37 -0000 1.16 +++ UserAgentAdapter.java 22 Aug 2003 10:49:06 -0000 1.17 @@ -60,6 +60,7 @@ import java.util.Set; import org.apache.batik.gvt.event.EventDispatcher; +import org.apache.batik.gvt.text.Mark; import org.apache.batik.util.ParsedURL; import org.apache.batik.util.SVGConstants; import org.apache.batik.util.XMLResourceDescriptor; @@ -246,6 +247,11 @@ * Unsupported operation. */ public void setSVGCursor(Cursor cursor) { } + + /** + * This user agent doesn't display text selections. + */ + public void setTextSelection(Mark start, Mark end) { } /** * Unsupported operation. 1.32 +10 -5 xml-batik/sources/org/apache/batik/css/engine/CSSEngine.java Index: CSSEngine.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/css/engine/CSSEngine.java,v retrieving revision 1.31 retrieving revision 1.32 diff -u -r1.31 -r1.32 --- CSSEngine.java 14 Aug 2003 00:53:51 -0000 1.31 +++ CSSEngine.java 22 Aug 2003 10:49:06 -0000 1.32 @@ -1888,11 +1888,16 @@ } if (nv == ov) continue; - if ((nv == null) || - (!nv.equals(ov) && !nv.getCssText().equals(ov.getCssText()))) { - count++; - diffs[i] = true; + if ((nv != null) && (ov != null)) { + if (nv.equals(ov)) continue; + String ovCssText = ov.getCssText(); + String nvCssText = nv.getCssText(); + if ((nvCssText == ovCssText) || + ((nvCssText != null) && nvCssText.equals(ovCssText))) + continue; } + count++; + diffs[i] = true; } int []props = null; if (count != 0) { 1.19 +1 -2 xml-batik/sources/org/apache/batik/gvt/event/AWTEventDispatcher.java Index: AWTEventDispatcher.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/event/AWTEventDispatcher.java,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- AWTEventDispatcher.java 9 Aug 2003 16:58:44 -0000 1.18 +++ AWTEventDispatcher.java 22 Aug 2003 10:49:06 -0000 1.19 @@ -443,7 +443,6 @@ screenPos.y += evt.getY(); } - if (lastHit != node) { // post an MOUSE_EXITED if (lastHit != null) { 1.27 +13 -8 xml-batik/sources/org/apache/batik/gvt/font/AWTGVTGlyphVector.java Index: AWTGVTGlyphVector.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/AWTGVTGlyphVector.java,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- AWTGVTGlyphVector.java 9 Aug 2003 16:58:43 -0000 1.26 +++ AWTGVTGlyphVector.java 22 Aug 2003 10:49:06 -0000 1.27 @@ -83,8 +83,8 @@ private CharacterIterator ci; // This contains the glyphPostions after doing a performDefaultLayout - private Point2D[] defaultGlyphPositions; - private Point2D[] glyphPositions; + private Point2D [] defaultGlyphPositions; + private Point2D.Float[] glyphPositions; // need to keep track of the glyphTransforms since GlyphVector doesn't // seem to @@ -688,9 +688,14 @@ glyphOutlines [i] = null; glyphMetrics [i] = null; Point2D glyphPos = defaultGlyphPositions[i]; - glyphPositions[i] = new Point2D.Float - ((float)((glyphPos.getX() * scaleFactor)-shiftLeft), - (float) (glyphPos.getY() * scaleFactor)); + float x = (float)((glyphPos.getX() * scaleFactor)-shiftLeft); + float y = (float) (glyphPos.getY() * scaleFactor); + if (glyphPositions[i] == null) { + glyphPositions[i] = new Point2D.Float(x,y); + } else { + glyphPositions[i].x = x; + glyphPositions[i].y = y; + } // if c is a transparent arabic char then need to shift the // following glyphs left so that the current glyph is overwritten @@ -711,8 +716,8 @@ * Sets the position of the specified glyph within this GlyphVector. */ public void setGlyphPosition(int glyphIndex, Point2D newPos) { - glyphPositions[glyphIndex] = - new Point2D.Float((float)newPos.getX(), (float)newPos.getY()); + glyphPositions[glyphIndex].x = (float)newPos.getX(); + glyphPositions[glyphIndex].y = (float)newPos.getY(); outline = null; visualBounds = null; logicalBounds = null; 1.13 +4 -3 xml-batik/sources/org/apache/batik/gvt/font/Glyph.java Index: Glyph.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/Glyph.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- Glyph.java 8 Aug 2003 11:39:16 -0000 1.12 +++ Glyph.java 22 Aug 2003 10:49:06 -0000 1.13 @@ -85,7 +85,7 @@ private float vertAdvY; private int glyphCode; private AffineTransform transform; - private Point2D position; + private Point2D.Float position; private GVTGlyphMetrics metrics; private float kernScale; @@ -281,7 +281,8 @@ * @param position The new glyph position. */ public void setPosition(Point2D position) { - this.position = position; + this.position.x = (float)position.getX(); + this.position.y = (float)position.getY(); outline = null; bounds = null; } 1.49 +2 -2 xml-batik/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java Index: StrokingTextPainter.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java,v retrieving revision 1.48 retrieving revision 1.49 diff -u -r1.48 -r1.49 --- StrokingTextPainter.java 9 Aug 2003 16:58:40 -0000 1.48 +++ StrokingTextPainter.java 22 Aug 2003 10:49:06 -0000 1.49 @@ -164,7 +164,7 @@ extendedAtts.add(FLOW_PARAGRAPH); extendedAtts.add(TEXT_COMPOUND_DELIMITER); extendedAtts.add(GVT_FONT); - extendedAtts.add(BIDI_LEVEL); + // extendedAtts.add(BIDI_LEVEL); } /** 1.57 +28 -19 xml-batik/sources/org/apache/batik/gvt/text/GlyphLayout.java Index: GlyphLayout.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/text/GlyphLayout.java,v retrieving revision 1.56 retrieving revision 1.57 diff -u -r1.56 -r1.57 --- GlyphLayout.java 9 Aug 2003 16:58:42 -0000 1.56 +++ GlyphLayout.java 22 Aug 2003 10:49:06 -0000 1.57 @@ -312,9 +312,11 @@ // System.out.println("DXY: [" + dx +","+dy+"]"); float [] gp = gv.getGlyphPositions(0, numGlyphs+1, null); + Point2D.Float pos = new Point2D.Float(); for (int i=0; i<=numGlyphs; i++) { - gv.setGlyphPosition(i, new Point2D.Float(gp[2*i]+dx, - gp[2*i+1]+dy)); + pos.x = gp[2*i ]+dx; + pos.y = gp[2*i+1]+dy; + gv.setGlyphPosition(i, pos); } } @@ -1134,6 +1136,8 @@ float curr_x_pos = (float)offset.getX(); float curr_y_pos = (float)offset.getY(); + Point2D.Float pos = new Point2D.Float(); + while (i < numGlyphs) { //System.out.println("limit: " + runLimit + ", " + aciIndex); if (aciIndex+aciStart >= runLimit) { @@ -1305,8 +1309,9 @@ } // set the new glyph position - gv.setGlyphPosition(i, new Point2D.Float - (curr_x_pos+ox,curr_y_pos+oy)); + pos.x = curr_x_pos+ox; + pos.y = curr_y_pos+oy; + gv.setGlyphPosition(i, pos); // calculte the position of the next glyph if (!ArabicTextHandler.arabicCharTransparent(ch)) { @@ -1383,7 +1388,9 @@ i++; } // Update last glyph pos - gv.setGlyphPosition(i, new Point2D.Float(curr_x_pos,curr_y_pos)); + pos.x = curr_x_pos; + pos.y = curr_y_pos; + gv.setGlyphPosition(i, pos); advance = new Point2D.Float((float)(curr_x_pos - offset.getX()), (float)(curr_y_pos - offset.getY())); @@ -1630,11 +1637,13 @@ float initY = gp[1]; float dx = 0f; float dy = 0f; + Point2D.Float pos = new Point2D.Float(); for (int i = 0; i <= numGlyphs; i++) { dx = gp[2*i] -initX; dy = gp[2*i+1]-initY; - gv.setGlyphPosition(i, new Point2D.Float(initX+dx*xScale, - initY+dy*yScale)); + pos.x = initX+dx*xScale; + pos.y = initY+dy*yScale; + gv.setGlyphPosition(i, pos); if ((stretchGlyphs) && (i != numGlyphs)) { // stretch the glyph @@ -1859,8 +1868,7 @@ } gv.setGlyphTransform(i, glyphPathTransform); - gv.setGlyphPosition(i, new Point2D.Double(charMidPoint.getX(), - charMidPoint.getY())); + gv.setGlyphPosition (i, charMidPoint); // keep track of the last glyph drawn to make calculating the // textPathAdvance value easier later lastGlyphDrawn = i; @@ -2473,6 +2481,7 @@ // based on info collected in first trip through glyphVector... int lineEnd = 0; int i; + Point2D.Float pos = new Point2D.Float(); for (i =0; i<numGlyphs; i++) { if (i == lineEnd) { // Always comes through here on first char... @@ -2515,19 +2524,19 @@ break; } } - float x = lineLoc.x + (gp[2*i] -xOrig)*xScale+xAdj; - float y = lineLoc.y + ((gp[2 * i + 1] - yOrig) + - verticalAlignOffset); - gv.setGlyphPosition(i, new Point2D.Float(x, y)); + pos.x = lineLoc.x + (gp[2*i] -xOrig)*xScale+xAdj; + pos.y = lineLoc.y + ((gp[2 * i + 1] - yOrig) + + verticalAlignOffset); + gv.setGlyphPosition(i, pos); } - float x = xOrig; - float y = yOrig; + pos.x = xOrig; + pos.y = yOrig; if (lineLoc != null) { - x = lineLoc.x + (gp[2*i] -xOrig)*xScale+xAdj; - y = lineLoc.y + (gp[2 * i + 1] - yOrig) + verticalAlignOffset; + pos.x = lineLoc.x + (gp[2*i] -xOrig)*xScale+xAdj; + pos.y = lineLoc.y + (gp[2 * i + 1] - yOrig) + verticalAlignOffset; } - gv.setGlyphPosition(i, new Point2D.Float(x, y)); + gv.setGlyphPosition(i, pos); } /** 1.82 +28 -1 xml-batik/sources/org/apache/batik/swing/svg/JSVGComponent.java Index: JSVGComponent.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/swing/svg/JSVGComponent.java,v retrieving revision 1.81 retrieving revision 1.82 diff -u -r1.81 -r1.82 --- JSVGComponent.java 14 Aug 2003 00:53:52 -0000 1.81 +++ JSVGComponent.java 22 Aug 2003 10:49:06 -0000 1.82 @@ -96,6 +96,7 @@ import org.apache.batik.gvt.CompositeGraphicsNode; import org.apache.batik.gvt.GraphicsNode; import org.apache.batik.gvt.event.EventDispatcher; +import org.apache.batik.gvt.text.Mark; import org.apache.batik.gvt.renderer.ImageRenderer; import org.apache.batik.swing.gvt.GVTTreeRenderer; import org.apache.batik.swing.gvt.GVTTreeRendererEvent; @@ -2351,6 +2352,23 @@ } /** + * Informs the user agent that the text selection has changed. + * @param start The Mark for the start of the selection. + * @param end The Mark for the end of the selection. + */ + public void setTextSelection(final Mark start, final Mark end) { + if (EventQueue.isDispatchThread()) { + userAgent.setTextSelection(start, end); + } else { + EventQueue.invokeLater(new Runnable() { + public void run() { + userAgent.setTextSelection(start, end); + } + }); + } + } + + /** * Returns the class name of the XML parser. */ public String getXMLParserClassName() { @@ -3023,6 +3041,15 @@ public void setSVGCursor(Cursor cursor) { if (cursor != JSVGComponent.this.getCursor()) JSVGComponent.this.setCursor(cursor); + } + + /** + * Informs the user agent that the text selection has changed. + * @param start The Mark for the start of the selection. + * @param end The Mark for the end of the selection. + */ + public void setTextSelection(Mark start, Mark end) { + JSVGComponent.this.textSelectionManager.setSelection(start, end); } /** 1.13 +9 -2 xml-batik/sources/org/apache/batik/transcoder/SVGAbstractTranscoder.java Index: SVGAbstractTranscoder.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/transcoder/SVGAbstractTranscoder.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- SVGAbstractTranscoder.java 21 Aug 2003 00:44:39 -0000 1.12 +++ SVGAbstractTranscoder.java 22 Aug 2003 10:49:06 -0000 1.13 @@ -182,6 +182,14 @@ return new SAXSVGDocumentFactory(parserClassname); } + public void transcode(TranscoderInput input, TranscoderOutput output) + throws TranscoderException { + + super.transcode(input, output); + + if (ctx != null) + ctx.dispose(); + } /** * Transcodes the specified Document as an image in the specified output. * @@ -296,7 +304,6 @@ } this.root = gvtRoot; - ctx.dispose(); } protected CanvasGraphicsNode getCanvasGraphicsNode(GraphicsNode gn) {
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]