1 51 package org.apache.fop.svg; 52 53 import java.util.List ; 54 import java.util.Map ; 55 import java.util.Iterator ; 56 import java.text.AttributedCharacterIterator ; 57 import java.text.CharacterIterator ; 58 59 import java.awt.Graphics2D ; 60 import java.awt.Font ; 61 import java.awt.Shape ; 62 import java.awt.Paint ; 63 import java.awt.Stroke ; 64 import java.awt.Color ; 65 import java.awt.geom.Point2D ; 66 import java.awt.geom.Rectangle2D ; 67 import java.awt.font.TextAttribute ; 68 69 import org.apache.batik.gvt.TextPainter; 71 import org.apache.batik.gvt.TextNode; 72 import org.apache.batik.gvt.text.GVTAttributedCharacterIterator; 73 import org.apache.batik.gvt.text.Mark; 74 import org.apache.batik.gvt.font.GVTFontFamily; 75 import org.apache.batik.gvt.renderer.StrokingTextPainter; 76 import org.apache.batik.gvt.renderer.StrokingTextPainter; 77 78 import org.apache.fop.layout.FontState; 80 import org.apache.fop.layout.FontInfo; 81 82 88 public class PDFTextPainter implements TextPainter { 89 FontState fontState; 90 91 95 protected static final TextPainter PROXY_PAINTER = 96 StrokingTextPainter.getInstance(); 97 98 99 public PDFTextPainter(FontState fs) { 100 fontState = fs; 101 } 102 103 110 public void paint(TextNode node, Graphics2D g2d) { 111 String txt = node.getText(); 113 Point2D loc = node.getLocation(); 114 127 TextNode.Anchor anchor = 128 (TextNode.Anchor)node.getAttributedCharacterIterator().getAttribute(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE); 129 if (anchor != null) { 130 } 131 135 paintTextRuns(node.getTextRuns(), g2d, loc); 136 137 } 138 139 140 protected void paintTextRuns(List textRuns, Graphics2D g2d, Point2D loc) { 141 Point2D currentloc = loc; 142 Iterator i = textRuns.iterator(); 143 while (i.hasNext()) { 144 StrokingTextPainter.TextRun run = 145 (StrokingTextPainter.TextRun)i.next(); 146 currentloc = paintTextRun(run, g2d, currentloc); 147 } 148 } 149 150 151 protected Point2D paintTextRun(StrokingTextPainter.TextRun run, Graphics2D g2d, Point2D loc) { 152 AttributedCharacterIterator aci = run.getACI(); 153 return paintACI(aci, g2d, loc); 154 } 155 156 157 protected String getText(AttributedCharacterIterator aci) { 158 StringBuffer sb = new StringBuffer (aci.getEndIndex()-aci.getBeginIndex()); 159 for (char c = aci.first(); c != CharacterIterator.DONE; c = aci.next()) { 160 sb.append(c); 161 } 162 return sb.toString(); 163 } 164 165 166 protected Point2D paintACI(AttributedCharacterIterator aci, Graphics2D g2d, Point2D loc) { 167 aci.first(); 168 169 TextNode.Anchor anchor = 170 (TextNode.Anchor)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE); 171 172 Float xpos = 174 (Float )aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.X); 175 Float ypos = 176 (Float )aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.Y); 177 Float dxpos = 178 (Float )aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.DX); 179 Float dypos = 180 (Float )aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.DY); 181 if (xpos != null) loc.setLocation(xpos.doubleValue(), loc.getY()); 182 if (ypos != null) loc.setLocation(loc.getX(), ypos.doubleValue()); 183 if (dxpos != null) loc.setLocation(loc.getX()+dxpos.doubleValue(), loc.getY()); 184 if (dypos != null) loc.setLocation(loc.getX(), loc.getY()+dypos.doubleValue()); 185 186 List gvtFonts = 188 (List )aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES); 189 Paint forg = (Paint )aci.getAttribute(TextAttribute.FOREGROUND); 190 Float size = (Float )aci.getAttribute(TextAttribute.SIZE); 191 if (size == null) { 192 return loc; 193 } 194 Stroke stroke = 195 (Stroke )aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.STROKE); 196 197 Float posture = (Float )aci.getAttribute(TextAttribute.POSTURE); 198 Float taWeight = (Float )aci.getAttribute(TextAttribute.WEIGHT); 199 200 if (forg instanceof Color ) { 201 g2d.setColor((Color )forg); 202 } 203 g2d.setPaint(forg); 204 g2d.setStroke(stroke); 205 206 String style = ((posture != null) && (posture.floatValue() > 0.0)) 207 ? "italic" : "normal"; 208 String weight = ((taWeight != null) && (taWeight.floatValue() > 1.0)) 209 ? "bold" : "normal"; 210 211 FontInfo fi = fontState.getFontInfo(); 212 boolean found = false; 213 if (gvtFonts != null) { 214 for (Iterator i = gvtFonts.iterator(); i.hasNext(); ) { 215 GVTFontFamily fam = (GVTFontFamily)i.next(); 216 String name = fam.getFamilyName(); 217 if (fi.hasFont(name, style, weight)) { 218 try { 219 int fsize = (int)size.floatValue(); 220 fontState = new FontState(fontState.getFontInfo(), 221 name, style, weight, 222 fsize * 1000, 0); 223 } catch (org.apache.fop.apps.FOPException fope) { 224 fope.printStackTrace(); 225 } 226 found = true; 227 break; 228 } 229 } 230 } 231 if (!found) { 232 try { 233 int fsize = (int)size.floatValue(); 234 fontState = new FontState(fontState.getFontInfo(), "any", 235 style, weight, fsize * 1000, 0); 236 } catch (org.apache.fop.apps.FOPException fope) { 237 fope.printStackTrace(); 238 } 239 } else { 240 if(g2d instanceof PDFGraphics2D) { 241 ((PDFGraphics2D)g2d).setOverrideFontState(fontState); 242 } 243 } 244 int fStyle = Font.PLAIN; 245 if (fontState.getFontWeight().equals("bold")) { 246 if (fontState.getFontStyle().equals("italic")) { 247 fStyle = Font.BOLD | Font.ITALIC; 248 } else { 249 fStyle = Font.BOLD; 250 } 251 } else { 252 if (fontState.getFontStyle().equals("italic")) { 253 fStyle = Font.ITALIC; 254 } else { 255 fStyle = Font.PLAIN; 256 } 257 } 258 Font font = new Font (fontState.getFontFamily(), fStyle, 259 (int)(fontState.getFontSize() / 1000)); 260 261 g2d.setFont(font); 262 263 String txt = getText(aci); 265 float advance = getStringWidth(txt); 266 float tx = 0; 267 if (anchor != null) { 268 switch (anchor.getType()) { 269 case TextNode.Anchor.ANCHOR_MIDDLE: 270 tx = -advance / 2; 271 break; 272 case TextNode.Anchor.ANCHOR_END: 273 tx = -advance; 274 } 275 } 276 g2d.drawString(txt, (float)(loc.getX() + tx), (float)loc.getY()); 278 loc.setLocation(loc.getX()+(double)advance, loc.getY()); 279 return loc; 280 } 281 282 private void printAttrs(AttributedCharacterIterator aci) { 283 aci.first(); 284 Iterator i = aci.getAttributes().entrySet().iterator(); 285 while (i.hasNext()) { 286 Map.Entry entry = (Map.Entry )i.next(); 287 if (entry.getValue() != null) System.out.println(entry.getKey()+": "+entry.getValue()); 288 } 289 int start = aci.getBeginIndex(); 290 System.out.print("AttrRuns: "); 291 while (aci.current() != CharacterIterator.DONE) { 292 int end = aci.getRunLimit(); 293 System.out.print(""+(end-start)+", "); 294 aci.setIndex(end); 295 if (start == end) break; 296 start = end; 297 } 298 System.out.println(""); 299 } 300 301 302 public float getStringWidth(String str) { 303 float wordWidth = 0; 304 float whitespaceWidth = fontState.width(fontState.mapChar(' ')); 305 306 for (int i = 0; i < str.length(); i++) { 307 float charWidth; 308 char c = str.charAt(i); 309 if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) { 310 charWidth = fontState.width(fontState.mapChar(c)); 311 if (charWidth <= 0) 312 charWidth = whitespaceWidth; 313 } else { 314 charWidth = whitespaceWidth; 315 } 316 wordWidth += charWidth; 317 } 318 return wordWidth / 1000f; 319 } 320 321 public Mark getMark(TextNode node, int pos, boolean all) { 322 System.out.println("PDFText getMark"); 323 return null; 324 } 325 326 public Mark selectAt(double x, double y, 327 TextNode node) { 328 System.out.println("PDFText selectAt"); 329 return null; 330 } 331 332 public Mark selectTo(double x, double y, Mark beginMark) { 333 System.out.println("PDFText selectTo"); 334 return null; 335 } 336 337 public Mark selectAll(double x, double y, 338 TextNode node) { 339 System.out.println("PDFText selectAll"); 340 return null; 341 } 342 343 public Mark selectFirst(TextNode node) { 344 System.out.println("PDFText selectFirst"); 345 return null; 346 } 347 348 public Mark selectLast(TextNode node) { 349 System.out.println("PDFText selectLast"); 350 return null; 351 } 352 353 public int[] getSelected(Mark start, 354 Mark finish) { 355 System.out.println("PDFText getSelected"); 356 return null; 357 } 358 359 public Shape getHighlightShape(Mark beginMark, Mark endMark) { 360 System.out.println("PDFText getHighlightShape"); 361 return null; 362 } 363 364 public Rectangle2D getBounds2D(TextNode node) { 365 return PROXY_PAINTER.getBounds2D(node); 366 } 367 368 public Rectangle2D getGeometryBounds(TextNode node) { 369 return PROXY_PAINTER.getGeometryBounds(node); 370 } 371 372 public Shape getOutline(TextNode node) { 373 return PROXY_PAINTER.getOutline(node); 374 } 375 376 377 } 378 379 | Popular Tags |