001package com.hfg.svg; 002 003import com.hfg.css.CSS; 004import com.hfg.css.CSSProperty; 005import com.hfg.graphics.Graphics2DState; 006import com.hfg.graphics.units.GfxUnits; 007import com.hfg.graphics.units.Points; 008import com.hfg.graphics.ColorUtil; 009import com.hfg.graphics.TextUtil; 010import com.hfg.util.StringUtil; 011import com.hfg.xml.XMLTag; 012 013import java.awt.*; 014import java.awt.geom.Point2D; 015import java.awt.geom.Rectangle2D; 016 017//------------------------------------------------------------------------------ 018/** 019 * Object representation of an SVG (Scalable Vector Graphics) text tag. 020 * 021 * @author J. Alex Taylor, hairyfatguy.com 022 */ 023//------------------------------------------------------------------------------ 024// com.hfg XML/HTML Coding Library 025// 026// This library is free software; you can redistribute it and/or 027// modify it under the terms of the GNU Lesser General Public 028// License as published by the Free Software Foundation; either 029// version 2.1 of the License, or (at your option) any later version. 030// 031// This library is distributed in the hope that it will be useful, 032// but WITHOUT ANY WARRANTY; without even the implied warranty of 033// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 034// Lesser General Public License for more details. 035// 036// You should have received a copy of the GNU Lesser General Public 037// License along with this library; if not, write to the Free Software 038// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 039// 040// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 041// jataylor@hairyfatguy.com 042//------------------------------------------------------------------------------ 043 044public class SvgText extends AbstractSvgNode implements SvgNode 045{ 046 private Font mFont; 047 048 //************************************************************************** 049 // CONSTRUCTORS 050 //************************************************************************** 051 052 //--------------------------------------------------------------------------- 053 public SvgText() 054 { 055 super(SVG.text); 056// setFont(sDefaultFont); 057 } 058 059 //--------------------------------------------------------------------------- 060 public SvgText(String inText) 061 { 062 this(); 063 setContent(inText); 064 } 065 066 //--------------------------------------------------------------------------- 067 public SvgText(String inText, Font inFont, Point2D inLocation) 068 { 069 this(inText); 070 setFont(inFont); 071 072 double x = inLocation.getX(); 073 double y = inLocation.getY(); 074 075 setAttribute(SvgAttr.x, (Math.floor(x) == x ? (int) x : String.format("%.3f", inLocation.getX()))); 076 setAttribute(SvgAttr.y, (Math.floor(y) == y ? (int) y : String.format("%.3f", inLocation.getY()))); 077 } 078 079 //--------------------------------------------------------------------------- 080 public SvgText(XMLTag inXMLTag) 081 { 082 this(); 083 initFromXMLTag(inXMLTag); 084 } 085 086 //************************************************************************** 087 // PUBLIC METHODS 088 //************************************************************************** 089 090 //--------------------------------------------------------------------------- 091 public SvgText setX(int inValue) 092 { 093 setAttribute(SvgAttr.x, inValue); 094 return this; 095 } 096 097 //--------------------------------------------------------------------------- 098 public SvgText setX(float inValue) 099 { 100 setAttribute(SvgAttr.x, inValue); 101 return this; 102 } 103 104 //--------------------------------------------------------------------------- 105 public Float getX() 106 { 107 String xAttr = getAttributeValue(SvgAttr.x); 108 return (StringUtil.isSet(xAttr) ? Float.parseFloat(xAttr) : null); 109 } 110 111 112 //--------------------------------------------------------------------------- 113 public SvgText setY(int inValue) 114 { 115 setAttribute(SvgAttr.y, inValue); 116 return this; 117 } 118 119 //--------------------------------------------------------------------------- 120 public SvgText setY(float inValue) 121 { 122 setAttribute(SvgAttr.y, inValue); 123 return this; 124 } 125 126 //--------------------------------------------------------------------------- 127 public Float getY() 128 { 129 String yAttr = getAttributeValue(SvgAttr.y); 130 return (StringUtil.isSet(yAttr) ? Float.parseFloat(yAttr) : null); 131 } 132 133 134 //--------------------------------------------------------------------------- 135 /** 136 * Sets a relative (delta) X coordinate adjustment to the text position. 137 * Can be absolute (in, cm, mm, pt, pc) or relative (em, ex, px) lengths. 138 * @param inValue a relative X coordinate adjustment to the text position 139 * @return this text object to allow for method chaining 140 */ 141 public SvgText setDx(String inValue) 142 { 143 setAttribute(SvgAttr.dx, inValue); 144 return this; 145 } 146 147 //--------------------------------------------------------------------------- 148 public String getDx() 149 { 150 return getAttributeValue(SvgAttr.dx); 151 } 152 153 154 //--------------------------------------------------------------------------- 155 /** 156 * Sets a relative (delta) Y coordinate adjustment to the text position. 157 * Can be absolute (in, cm, mm, pt, pc) or relative (em, ex, px) lengths. 158 * @param inValue a relative Y coordinate adjustment to the text position 159 * @return this text object to allow for method chaining 160 */ 161 public SvgText setDy(String inValue) 162 { 163 setAttribute(SvgAttr.dy, inValue); 164 return this; 165 } 166 167 //--------------------------------------------------------------------------- 168 public String getDy() 169 { 170 return getAttributeValue(SvgAttr.dy); 171 } 172 173 174 //--------------------------------------------------------------------------- 175 public int getWidth() 176 { 177 return (int) Float.parseFloat(getAttributeValue(SvgAttr.width)); 178 } 179 180 //--------------------------------------------------------------------------- 181 public int getHeight() 182 { 183 return (int) Float.parseFloat(getAttributeValue(SvgAttr.height)); 184 } 185 186 //--------------------------------------------------------------------------- 187 public SvgText setFill(Color inColor) 188 { 189 setAttribute(SvgAttr.fill, "#" + ColorUtil.colorToHex(inColor)); 190 return this; 191 } 192 193 //--------------------------------------------------------------------------- 194 public SvgText setFont(Font inValue) 195 { 196 if (inValue != null) 197 { 198 // TODO: Remove existing style fields relating to the font. 199 200 mFont = inValue; 201 addStyle(CSSProperty.font_family.name() + ":" + mFont.getName()); 202 addStyle(CSSProperty.font_size.name() + ":" + new Points(mFont.getSize2D()).to(GfxUnits.pixels) + "px"); 203 if (mFont.isBold()) 204 { 205 addStyle(CSS.BOLD); 206 } 207 208 if (mFont.isItalic()) 209 { 210 addStyle(CSS.ITALIC); 211 } 212 } 213 214 return this; 215 } 216 217 //--------------------------------------------------------------------------- 218 @Override 219 public SvgText setFilter(String inValue) 220 { 221 return (SvgText) super.setFilter(inValue); 222 } 223 224 //--------------------------------------------------------------------------- 225 public SvgText setTitle(String inValue) 226 { 227 setAttribute(SvgAttr.title, inValue); 228 return this; 229 } 230 231 //--------------------------------------------------------------------------- 232 @Override 233 public SvgText setClass(String inValue) 234 { 235 return (SvgText) super.setClass(inValue); 236 } 237 238 //--------------------------------------------------------------------------- 239 @Override 240 public SvgText setId(String inValue) 241 { 242 return (SvgText) super.setId(inValue); 243 } 244 245 //-------------------------------------------------------------------------- 246 @Override 247 public SvgText addStyle(String inValue) 248 { 249 return (SvgText) super.addStyle(inValue); 250 } 251 252 //--------------------------------------------------------------------------- 253 @Override 254 public SvgText setStyle(String inValue) 255 { 256 return (SvgText) super.setStyle(inValue); 257 } 258 259 //--------------------------------------------------------------------------- 260 @Override 261 public SvgText setTransform(String inValue) 262 { 263 return (SvgText) super.setTransform(inValue); 264 } 265 266 //--------------------------------------------------------------------------- 267 @Override 268 public SvgText setAttribute(String inName, Object inValue) 269 { 270 return (SvgText) super.setAttribute(inName, inValue); 271 } 272 273 //--------------------------------------------------------------------------- 274 public SvgTSpan addTSpan() 275 { 276 SvgTSpan tSpan = new SvgTSpan(); 277 addSubtag(tSpan); 278 279 return tSpan; 280 } 281 282 //--------------------------------------------------------------------------- 283 public SvgTSpan addTSpan(CharSequence inTitle) 284 { 285 SvgTSpan tSpan = new SvgTSpan(inTitle); 286 addSubtag(tSpan); 287 288 return tSpan; 289 } 290 291 //--------------------------------------------------------------------------- 292 @Override 293 public Rectangle getBoundsBox() 294 { 295 float x = (getX() != null ? getX() : 0); 296 float y = (getAttributeValue(SvgAttr.y) != null ? Float.parseFloat(getAttributeValue(SvgAttr.y)) : 0); 297 298 Rectangle textBounds = (mFont != null ? TextUtil.getStringRect(getContent(), mFont) : new Rectangle(0, 0, 0, 0)); 299 300 Rectangle boundsBox = new Rectangle2D.Float(x, y - textBounds.height, textBounds.width, textBounds.height).getBounds(); 301 adjustBoundsForTransform(boundsBox); 302 303 return boundsBox; 304 } 305 306 //-------------------------------------------------------------------------- 307 @Override 308 public void draw(Graphics2D g2) 309 { 310 // Save settings 311 Graphics2DState origState = new Graphics2DState(g2); 312 313 Paint paint = getG2Paint(); 314 if (paint != null) g2.setPaint(paint); 315 316 if (mFont != null) 317 { 318 g2.setFont(mFont); 319 } 320 else 321 { 322 Font locallyAdjustedFont = getAdjustedFont(origState.getFont()); 323 if (locallyAdjustedFont != null) 324 { 325 g2.setFont(locallyAdjustedFont); 326 } 327 } 328 329 applyTransforms(g2); 330 331 float x = (getX() != null ? getX() : 0); 332 float y = (getY() != null ? getY() : 0); 333 334 g2.drawString(getContent(), x, y); 335 336 // Restore settings 337 origState.applyTo(g2); 338 } 339 340}