From 6776ed9f1a81e517139d85eb6d2e28911fd0fc35 Mon Sep 17 00:00:00 2001 From: kitfox Date: Tue, 19 Mar 2013 05:20:37 +0000 Subject: Adding support for style sheets. git-svn-id: https://svn.java.net/svn/svgsalamander~svn/trunk/svg-core@153 7dc7fa77-23fb-e6ad-8e2e-c86bd48ed22b --- src/main/java/com/kitfox/svg/Text.java | 297 +++++++++++++++++---------------- 1 file changed, 156 insertions(+), 141 deletions(-) (limited to 'src/main/java/com/kitfox/svg/Text.java') diff --git a/src/main/java/com/kitfox/svg/Text.java b/src/main/java/com/kitfox/svg/Text.java index 1b9087c..713f29c 100644 --- a/src/main/java/com/kitfox/svg/Text.java +++ b/src/main/java/com/kitfox/svg/Text.java @@ -33,47 +33,45 @@ * * Created on January 26, 2004, 1:56 AM */ - package com.kitfox.svg; import com.kitfox.svg.xml.StyleAttribute; -import java.awt.*; -import java.awt.font.*; -import java.awt.geom.*; -import java.util.*; -import java.util.regex.*; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Rectangle2D; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; //import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - /** * @author Mark McKay * @author Mark McKay */ public class Text extends ShapeElement { + public static final String TAG_NAME = "text"; float x = 0; float y = 0; AffineTransform transform = null; - String fontFamily; float fontSize; - //List of strings and tspans containing the content of this node LinkedList content = new LinkedList(); - Shape textShape; - public static final int TXAN_START = 0; public static final int TXAN_MIDDLE = 1; public static final int TXAN_END = 2; int textAnchor = TXAN_START; - public static final int TXST_NORMAL = 0; public static final int TXST_ITALIC = 1; public static final int TXST_OBLIQUE = 2; int fontStyle; - public static final int TXWE_NORMAL = 0; public static final int TXWE_BOLD = 1; public static final int TXWE_BOLDER = 2; @@ -88,24 +86,30 @@ public class Text extends ShapeElement public static final int TXWE_800 = 11; public static final int TXWE_900 = 12; int fontWeight; - - /** Creates a new instance of Stop */ + + /** + * Creates a new instance of Stop + */ public Text() { } - + + public String getTagName() + { + return TAG_NAME; + } + public void appendText(String text) { content.addLast(text); } - + public void appendTspan(Tspan tspan) throws SVGElementException { super.loaderAddChild(null, tspan); content.addLast(tspan); -// tspan.setParent(this); } - + /** * Discard cached information */ @@ -113,25 +117,12 @@ public class Text extends ShapeElement { build(); } - + public java.util.List getContent() { return content; } -/* - public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) - { - //Load style string - super.loaderStartElement(helper, attrs, parent); - - String x = attrs.getValue("x"); - String y = attrs.getValue("y"); - //String transform = attrs.getValue("transform"); - - this.x = XMLParseUtil.parseFloat(x); - this.y = XMLParseUtil.parseFloat(y); - } - */ + /** * Called after the start element but before the end element to indicate * each child tag that has been processed @@ -139,83 +130,112 @@ public class Text extends ShapeElement public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException { super.loaderAddChild(helper, child); - + content.addLast(child); } - + /** * Called during load process to add text scanned within a tag */ public void loaderAddText(SVGLoaderHelper helper, String text) { Matcher matchWs = Pattern.compile("\\s*").matcher(text); - if (!matchWs.matches()) content.addLast(text); + if (!matchWs.matches()) + { + content.addLast(text); + } } - + public void build() throws SVGException { super.build(); - + StyleAttribute sty = new StyleAttribute(); - - if (getPres(sty.setName("x"))) x = sty.getFloatValueWithUnits(); - - if (getPres(sty.setName("y"))) y = sty.getFloatValueWithUnits(); - - if (getStyle(sty.setName("font-family"))) fontFamily = sty.getStringValue(); - else fontFamily = "Sans Serif"; - - if (getStyle(sty.setName("font-size"))) fontSize = sty.getFloatValueWithUnits(); - else fontSize = 12f; - + + if (getPres(sty.setName("x"))) + { + x = sty.getFloatValueWithUnits(); + } + + if (getPres(sty.setName("y"))) + { + y = sty.getFloatValueWithUnits(); + } + + if (getStyle(sty.setName("font-family"))) + { + fontFamily = sty.getStringValue(); + } else + { + fontFamily = "Sans Serif"; + } + + if (getStyle(sty.setName("font-size"))) + { + fontSize = sty.getFloatValueWithUnits(); + } else + { + fontSize = 12f; + } + if (getStyle(sty.setName("font-style"))) { String s = sty.getStringValue(); if ("normal".equals(s)) { fontStyle = TXST_NORMAL; - } - else if ("italic".equals(s)) + } else if ("italic".equals(s)) { fontStyle = TXST_ITALIC; - } - else if ("oblique".equals(s)) + } else if ("oblique".equals(s)) { fontStyle = TXST_OBLIQUE; } + } else + { + fontStyle = TXST_NORMAL; } - else fontStyle = TXST_NORMAL; - + if (getStyle(sty.setName("font-weight"))) { String s = sty.getStringValue(); if ("normal".equals(s)) { fontWeight = TXWE_NORMAL; - } - else if ("bold".equals(s)) + } else if ("bold".equals(s)) { fontWeight = TXWE_BOLD; } + } else + { + fontWeight = TXWE_BOLD; } - else fontWeight = TXWE_BOLD; - + if (getStyle(sty.setName("text-anchor"))) { String s = sty.getStringValue(); - if (s.equals("middle")) textAnchor = TXAN_MIDDLE; - else if (s.equals("end")) textAnchor = TXAN_END; - else textAnchor = TXAN_START; + if (s.equals("middle")) + { + textAnchor = TXAN_MIDDLE; + } else if (s.equals("end")) + { + textAnchor = TXAN_END; + } else + { + textAnchor = TXAN_START; + } + } else + { + textAnchor = TXAN_START; } - else textAnchor = TXAN_START; - + //text anchor //text-decoration //text-rendering - + buildFont(); } - + protected void buildFont() throws SVGException { int style; @@ -240,58 +260,58 @@ public class Text extends ShapeElement weight = java.awt.Font.PLAIN; break; } - + //Get font Font font = diagram.getUniverse().getFont(fontFamily); if (font == null) { // System.err.println("Could not load font"); - - java.awt.Font sysFont = new java.awt.Font(fontFamily, style | weight, (int)fontSize); + + java.awt.Font sysFont = new java.awt.Font(fontFamily, style | weight, (int) fontSize); buildSysFont(sysFont); return; } - + // font = new java.awt.Font(font.getFamily(), style | weight, font.getSize()); - + // Area textArea = new Area(); GeneralPath textPath = new GeneralPath(); textShape = textPath; - + float cursorX = x, cursorY = y; - + FontFace fontFace = font.getFontFace(); //int unitsPerEm = fontFace.getUnitsPerEm(); int ascent = fontFace.getAscent(); - float fontScale = fontSize / (float)ascent; - + float fontScale = fontSize / (float) ascent; + // AffineTransform oldXform = g.getTransform(); AffineTransform xform = new AffineTransform(); - + for (Iterator it = content.iterator(); it.hasNext();) { Object obj = it.next(); - + if (obj instanceof String) { - String text = (String)obj; + String text = (String) obj; if (text != null) { text = text.trim(); } - + strokeWidthScalar = 1f / fontScale; - + for (int i = 0; i < text.length(); i++) { xform.setToIdentity(); xform.setToTranslation(cursorX, cursorY); xform.scale(fontScale, fontScale); // g.transform(xform); - + String unicode = text.substring(i, i + 1); MissingGlyph glyph = font.getGlyph(unicode); - + Shape path = glyph.getPath(); if (path != null) { @@ -299,24 +319,23 @@ public class Text extends ShapeElement textPath.append(path, false); } // else glyph.render(g); - + cursorX += fontScale * glyph.getHorizAdvX(); - + // g.setTransform(oldXform); } - + strokeWidthScalar = 1f; - } - else if (obj instanceof Tspan) + } else if (obj instanceof Tspan) { - Tspan tspan = (Tspan)obj; - + Tspan tspan = (Tspan) obj; + xform.setToIdentity(); xform.setToTranslation(cursorX, cursorY); xform.scale(fontScale, fontScale); // tspan.setCursorX(cursorX); // tspan.setCursorY(cursorY); - + Shape tspanShape = tspan.getShape(); tspanShape = xform.createTransformedShape(tspanShape); textPath.append(tspanShape, false); @@ -324,9 +343,9 @@ public class Text extends ShapeElement // cursorX = tspan.getCursorX(); // cursorY = tspan.getCursorY(); } - + } - + switch (textAnchor) { case TXAN_MIDDLE: @@ -345,67 +364,66 @@ public class Text extends ShapeElement } } } - + private void buildSysFont(java.awt.Font font) throws SVGException { GeneralPath textPath = new GeneralPath(); textShape = textPath; - + float cursorX = x, cursorY = y; - + // FontMetrics fm = g.getFontMetrics(font); FontRenderContext frc = new FontRenderContext(null, true, true); - + // FontFace fontFace = font.getFontFace(); //int unitsPerEm = fontFace.getUnitsPerEm(); // int ascent = fm.getAscent(); // float fontScale = fontSize / (float)ascent; - + // AffineTransform oldXform = g.getTransform(); AffineTransform xform = new AffineTransform(); - + for (Iterator it = content.iterator(); it.hasNext();) { Object obj = it.next(); - + if (obj instanceof String) { - String text = (String)obj; - + String text = (String) obj; + Shape textShape = font.createGlyphVector(frc, text).getOutline(cursorX, cursorY); textPath.append(textShape, false); // renderShape(g, textShape); // g.drawString(text, cursorX, cursorY); - + Rectangle2D rect = font.getStringBounds(text, frc); - cursorX += (float)rect.getWidth(); - } - else if (obj instanceof Tspan) + cursorX += (float) rect.getWidth(); + } else if (obj instanceof Tspan) { /* - Tspan tspan = (Tspan)obj; + Tspan tspan = (Tspan)obj; - xform.setToIdentity(); - xform.setToTranslation(cursorX, cursorY); + xform.setToIdentity(); + xform.setToTranslation(cursorX, cursorY); - Shape tspanShape = tspan.getShape(); - tspanShape = xform.createTransformedShape(tspanShape); - textArea.add(new Area(tspanShape)); + Shape tspanShape = tspan.getShape(); + tspanShape = xform.createTransformedShape(tspanShape); + textArea.add(new Area(tspanShape)); - cursorX += tspanShape.getBounds2D().getWidth(); + cursorX += tspanShape.getBounds2D().getWidth(); */ - - - Tspan tspan = (Tspan)obj; + + + Tspan tspan = (Tspan) obj; tspan.setCursorX(cursorX); tspan.setCursorY(cursorY); tspan.addShape(textPath); cursorX = tspan.getCursorX(); cursorY = tspan.getCursorY(); - + } } - + switch (textAnchor) { case TXAN_MIDDLE: @@ -424,28 +442,28 @@ public class Text extends ShapeElement } } } - - + public void render(Graphics2D g) throws SVGException { beginLayer(g); renderShape(g, textShape); finishLayer(g); } - + public Shape getShape() { return shapeToParent(textShape); } - + public Rectangle2D getBoundingBox() throws SVGException { return boundsToParent(includeStrokeInBounds(textShape.getBounds2D())); } - + /** - * Updates all attributes in this diagram associated with a time event. - * Ie, all attributes with track information. + * Updates all attributes in this diagram associated with a time event. Ie, + * all attributes with track information. + * * @return - true if this node has changed state as a result of the time * update */ @@ -453,11 +471,11 @@ public class Text extends ShapeElement { // if (trackManager.getNumTracks() == 0) return false; boolean changeState = super.updateTime(curTime); - + //Get current values for parameters StyleAttribute sty = new StyleAttribute(); boolean shapeChange = false; - + if (getPres(sty.setName("x"))) { float newVal = sty.getFloatValueWithUnits(); @@ -467,7 +485,7 @@ public class Text extends ShapeElement shapeChange = true; } } - + if (getPres(sty.setName("y"))) { float newVal = sty.getFloatValueWithUnits(); @@ -477,7 +495,7 @@ public class Text extends ShapeElement shapeChange = true; } } - + if (getPres(sty.setName("font-family"))) { String newVal = sty.getStringValue(); @@ -487,7 +505,7 @@ public class Text extends ShapeElement shapeChange = true; } } - + if (getPres(sty.setName("font-size"))) { float newVal = sty.getFloatValueWithUnits(); @@ -497,8 +515,8 @@ public class Text extends ShapeElement shapeChange = true; } } - - + + if (getStyle(sty.setName("font-style"))) { String s = sty.getStringValue(); @@ -506,12 +524,10 @@ public class Text extends ShapeElement if ("normal".equals(s)) { newVal = TXST_NORMAL; - } - else if ("italic".equals(s)) + } else if ("italic".equals(s)) { newVal = TXST_ITALIC; - } - else if ("oblique".equals(s)) + } else if ("oblique".equals(s)) { newVal = TXST_OBLIQUE; } @@ -521,7 +537,7 @@ public class Text extends ShapeElement shapeChange = true; } } - + if (getStyle(sty.setName("font-weight"))) { String s = sty.getStringValue(); @@ -529,8 +545,7 @@ public class Text extends ShapeElement if ("normal".equals(s)) { newVal = TXWE_NORMAL; - } - else if ("bold".equals(s)) + } else if ("bold".equals(s)) { newVal = TXWE_BOLD; } @@ -540,14 +555,14 @@ public class Text extends ShapeElement shapeChange = true; } } - + if (shapeChange) { build(); // buildFont(); // return true; } - + return changeState || shapeChange; } } -- cgit v1.2.3-55-g7522