KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > svg > PDFTextPainter


1 /*
2  * $Id: PDFTextPainter.java,v 1.7.2.4 2003/02/25 15:08:11 jeremias Exp $
3  * ============================================================================
4  * The Apache Software License, Version 1.1
5  * ============================================================================
6  *
7  * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without modifica-
10  * tion, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if any, must
20  * include the following acknowledgment: "This product includes software
21  * developed by the Apache Software Foundation (http://www.apache.org/)."
22  * Alternately, this acknowledgment may appear in the software itself, if
23  * and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. The names "FOP" and "Apache Software Foundation" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * apache@apache.org.
29  *
30  * 5. Products derived from this software may not be called "Apache", nor may
31  * "Apache" appear in their name, without prior written permission of the
32  * Apache Software Foundation.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  * ============================================================================
45  *
46  * This software consists of voluntary contributions made by many individuals
47  * on behalf of the Apache Software Foundation and was originally created by
48  * James Tauber <jtauber@jtauber.com>. For more information on the Apache
49  * Software Foundation, please see <http://www.apache.org/>.
50  */

51 package org.apache.fop.svg;
52
53 import java.util.List JavaDoc;
54 import java.util.Map JavaDoc;
55 import java.util.Iterator JavaDoc;
56 import java.text.AttributedCharacterIterator JavaDoc;
57 import java.text.CharacterIterator JavaDoc;
58
59 import java.awt.Graphics2D JavaDoc;
60 import java.awt.Font JavaDoc;
61 import java.awt.Shape JavaDoc;
62 import java.awt.Paint JavaDoc;
63 import java.awt.Stroke JavaDoc;
64 import java.awt.Color JavaDoc;
65 import java.awt.geom.Point2D JavaDoc;
66 import java.awt.geom.Rectangle2D JavaDoc;
67 import java.awt.font.TextAttribute JavaDoc;
68
69 //Batik
70
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 //FOP
79
import org.apache.fop.layout.FontState;
80 import org.apache.fop.layout.FontInfo;
81
82 /**
83  * Renders the attributed character iterator of a <tt>TextNode</tt>.
84  *
85  * @author <a HREF="mailto:keiron@aftexsw.com">Keiron Liddle</a>
86  * @version $Id: PDFTextPainter.java,v 1.7.2.4 2003/02/25 15:08:11 jeremias Exp $
87  */

88 public class PDFTextPainter implements TextPainter {
89     FontState fontState;
90
91     /**
92      * Use the stroking text painter to get the bounds and shape.
93      * Also used as a fallback to draw the string with strokes.
94      */

95     protected static final TextPainter PROXY_PAINTER =
96         StrokingTextPainter.getInstance();
97
98
99     public PDFTextPainter(FontState fs) {
100         fontState = fs;
101     }
102
103     /**
104      * Paints the specified attributed character iterator using the
105      * specified Graphics2D and context and font context.
106      * @param node the TextNode to paint
107      * @param g2d the Graphics2D to use
108      * @param context the rendering context.
109      */

110     public void paint(TextNode node, Graphics2D JavaDoc g2d) {
111         // System.out.println("PDFText paint");
112
String JavaDoc txt = node.getText();
113         Point2D JavaDoc loc = node.getLocation();
114         /*
115
116         AttributedCharacterIterator aci =
117             node.getAttributedCharacterIterator();
118         if (aci.getBeginIndex() == aci.getEndIndex()) {
119             return;
120         }
121         // reset position to start of char iterator
122         char ch = aci.first();
123         if (ch == AttributedCharacterIterator.DONE) {
124             return;
125         }
126         */

127         TextNode.Anchor anchor =
128             (TextNode.Anchor)node.getAttributedCharacterIterator().getAttribute(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
129         if (anchor != null) {
130         }
131         /*
132         System.out.println("-----"+txt);
133         printAttrs(node.getAttributedCharacterIterator());
134         */

135         paintTextRuns(node.getTextRuns(), g2d, loc);
136
137     }
138
139
140     protected void paintTextRuns(List JavaDoc textRuns, Graphics2D JavaDoc g2d, Point2D JavaDoc loc) {
141         Point2D JavaDoc currentloc = loc;
142         Iterator JavaDoc 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 JavaDoc paintTextRun(StrokingTextPainter.TextRun run, Graphics2D JavaDoc g2d, Point2D JavaDoc loc) {
152         AttributedCharacterIterator JavaDoc aci = run.getACI();
153         return paintACI(aci, g2d, loc);
154     }
155
156
157     protected String JavaDoc getText(AttributedCharacterIterator JavaDoc aci) {
158         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(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 JavaDoc paintACI(AttributedCharacterIterator JavaDoc aci, Graphics2D JavaDoc g2d, Point2D JavaDoc loc) {
167         aci.first();
168
169         TextNode.Anchor anchor =
170             (TextNode.Anchor)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
171
172         //Adjust position of span
173
Float JavaDoc xpos =
174             (Float JavaDoc)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.X);
175         Float JavaDoc ypos =
176             (Float JavaDoc)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.Y);
177         Float JavaDoc dxpos =
178             (Float JavaDoc)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.DX);
179         Float JavaDoc dypos =
180             (Float JavaDoc)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         //Set up font
187
List JavaDoc gvtFonts =
188             (List JavaDoc)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
189         Paint JavaDoc forg = (Paint JavaDoc)aci.getAttribute(TextAttribute.FOREGROUND);
190         Float JavaDoc size = (Float JavaDoc)aci.getAttribute(TextAttribute.SIZE);
191         if (size == null) {
192             return loc;
193         }
194         Stroke JavaDoc stroke =
195             (Stroke JavaDoc)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.STROKE);
196
197         Float JavaDoc posture = (Float JavaDoc)aci.getAttribute(TextAttribute.POSTURE);
198         Float JavaDoc taWeight = (Float JavaDoc)aci.getAttribute(TextAttribute.WEIGHT);
199
200         if (forg instanceof Color JavaDoc) {
201             g2d.setColor((Color JavaDoc)forg);
202         }
203         g2d.setPaint(forg);
204         g2d.setStroke(stroke);
205
206         String JavaDoc style = ((posture != null) && (posture.floatValue() > 0.0))
207                        ? "italic" : "normal";
208         String JavaDoc 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 JavaDoc i = gvtFonts.iterator(); i.hasNext(); ) {
215                 GVTFontFamily fam = (GVTFontFamily)i.next();
216                 String JavaDoc 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 JavaDoc font = new Font JavaDoc(fontState.getFontFamily(), fStyle,
259                              (int)(fontState.getFontSize() / 1000));
260
261         g2d.setFont(font);
262
263         //Get text and paint
264
String JavaDoc 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         //printAttrs(aci);
277
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 JavaDoc aci) {
283         aci.first();
284         Iterator JavaDoc i = aci.getAttributes().entrySet().iterator();
285         while (i.hasNext()) {
286             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)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 JavaDoc 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 JavaDoc getHighlightShape(Mark beginMark, Mark endMark) {
360         System.out.println("PDFText getHighlightShape");
361         return null;
362     }
363
364     public Rectangle2D JavaDoc getBounds2D(TextNode node) {
365         return PROXY_PAINTER.getBounds2D(node);
366     }
367
368     public Rectangle2D JavaDoc getGeometryBounds(TextNode node) {
369         return PROXY_PAINTER.getGeometryBounds(node);
370     }
371
372     public Shape JavaDoc getOutline(TextNode node) {
373         return PROXY_PAINTER.getOutline(node);
374     }
375
376
377 }
378
379
Popular Tags