summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/kitfox/svg/Text.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/kitfox/svg/Text.java')
-rw-r--r--src/main/java/com/kitfox/svg/Text.java297
1 files changed, 156 insertions, 141 deletions
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 <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
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;
}
}