Lines 26-31
Link Here
|
26 |
*/ |
26 |
*/ |
27 |
|
27 |
|
28 |
// Java |
28 |
// Java |
|
|
29 |
import java.awt.BasicStroke; |
29 |
import java.awt.Color; |
30 |
import java.awt.Color; |
30 |
import java.awt.Dimension; |
31 |
import java.awt.Dimension; |
31 |
import java.awt.Graphics; |
32 |
import java.awt.Graphics; |
Lines 35-40
Link Here
|
35 |
import java.awt.event.WindowAdapter; |
36 |
import java.awt.event.WindowAdapter; |
36 |
import java.awt.event.WindowEvent; |
37 |
import java.awt.event.WindowEvent; |
37 |
import java.awt.geom.AffineTransform; |
38 |
import java.awt.geom.AffineTransform; |
|
|
39 |
import java.awt.geom.Line2D; |
40 |
import java.awt.geom.NoninvertibleTransformException; |
38 |
import java.awt.geom.Rectangle2D; |
41 |
import java.awt.geom.Rectangle2D; |
39 |
import java.awt.image.BufferedImage; |
42 |
import java.awt.image.BufferedImage; |
40 |
import java.awt.print.PageFormat; |
43 |
import java.awt.print.PageFormat; |
Lines 45-85
Link Here
|
45 |
import java.util.Map; |
48 |
import java.util.Map; |
46 |
import java.util.Vector; |
49 |
import java.util.Vector; |
47 |
|
50 |
|
48 |
import org.apache.fop.fonts.FontInfo; |
51 |
import org.apache.batik.bridge.BridgeContext; |
|
|
52 |
import org.apache.batik.bridge.GVTBuilder; |
53 |
import org.apache.batik.bridge.ViewBox; |
54 |
import org.apache.batik.gvt.GraphicsNode; |
49 |
import org.apache.fop.apps.FOPException; |
55 |
import org.apache.fop.apps.FOPException; |
50 |
import org.apache.fop.apps.FOUserAgent; |
56 |
import org.apache.fop.apps.FOUserAgent; |
51 |
import org.apache.fop.area.Area; |
57 |
import org.apache.fop.area.Area; |
|
|
58 |
import org.apache.fop.area.Block; |
59 |
import org.apache.fop.area.CTM; |
52 |
import org.apache.fop.area.Page; |
60 |
import org.apache.fop.area.Page; |
53 |
import org.apache.fop.area.PageViewport; |
61 |
import org.apache.fop.area.PageViewport; |
54 |
import org.apache.fop.area.RegionViewport; |
|
|
55 |
import org.apache.fop.area.Trait; |
62 |
import org.apache.fop.area.Trait; |
|
|
63 |
import org.apache.fop.area.inline.Character; |
64 |
import org.apache.fop.area.inline.ForeignObject; |
65 |
import org.apache.fop.area.inline.Image; |
66 |
import org.apache.fop.area.inline.Leader; |
56 |
import org.apache.fop.area.inline.TextArea; |
67 |
import org.apache.fop.area.inline.TextArea; |
57 |
import org.apache.fop.datatypes.ColorType; |
68 |
import org.apache.fop.datatypes.ColorType; |
|
|
69 |
import org.apache.fop.fonts.Font; |
70 |
import org.apache.fop.fonts.FontInfo; |
71 |
import org.apache.fop.fonts.FontMetrics; |
58 |
import org.apache.fop.image.FopImage; |
72 |
import org.apache.fop.image.FopImage; |
59 |
import org.apache.fop.image.ImageFactory; |
73 |
import org.apache.fop.image.ImageFactory; |
|
|
74 |
import org.apache.fop.image.XMLImage; |
60 |
import org.apache.fop.render.AbstractRenderer; |
75 |
import org.apache.fop.render.AbstractRenderer; |
61 |
import org.apache.fop.traits.BorderProps; |
76 |
import org.apache.fop.render.RendererContext; |
62 |
import org.apache.fop.render.awt.FontMetricsMapper; |
|
|
63 |
import org.apache.fop.render.awt.viewer.PreviewDialog; |
77 |
import org.apache.fop.render.awt.viewer.PreviewDialog; |
64 |
import org.apache.fop.render.awt.viewer.Translator; |
78 |
import org.apache.fop.render.awt.viewer.Translator; |
|
|
79 |
import org.apache.fop.svg.SVGUserAgent; |
80 |
import org.apache.fop.traits.BorderProps; |
81 |
import org.w3c.dom.Document; |
82 |
import org.w3c.dom.svg.SVGDocument; |
83 |
import org.w3c.dom.svg.SVGSVGElement; |
65 |
|
84 |
|
66 |
/** |
85 |
/** |
67 |
* This is FOP's AWT renderer. |
86 |
* Java2DRenderer provides the abstract technical foundation for all rendering |
|
|
87 |
* with the Java2D API. Renderers like AWTRenderer subclass it and provide the |
88 |
* concrete output paths. |
89 |
* |
90 |
* A lot of the logic is performed by AbstractRenderer. The class-variables |
91 |
* currentIPPosition and currentBPPosition hold the position of the currently |
92 |
* rendered area. |
93 |
* |
94 |
* The rendering process is basically always the same: void renderXXXXX(Area |
95 |
* area){ get the currentPosition updateColor(area); updateFont(area); String s = |
96 |
* area.getTextArea(); graphics.draw(new Shape(args)); } |
97 |
* |
68 |
*/ |
98 |
*/ |
69 |
public class AWTRenderer extends AbstractRenderer implements Printable, Pageable { |
99 |
public class AWTRenderer extends AbstractRenderer implements Printable, |
|
|
100 |
Pageable { |
70 |
|
101 |
|
71 |
/** The MIME type for PostScript */ |
102 |
/** The MIME type for AWT-Rendering */ |
72 |
public static final String MIME_TYPE = "application/awt"; |
103 |
public static final String MIME_TYPE = "application/awt"; |
73 |
|
104 |
|
74 |
protected double scaleFactor = 100.0; |
105 |
protected double scaleFactor = 100.0; |
|
|
106 |
|
75 |
protected int pageNumber = 0; |
107 |
protected int pageNumber = 0; |
|
|
108 |
|
76 |
private int pageWidth = 0; |
109 |
private int pageWidth = 0; |
|
|
110 |
|
77 |
private int pageHeight = 0; |
111 |
private int pageHeight = 0; |
|
|
112 |
|
78 |
private Vector pageViewportList = new java.util.Vector(); |
113 |
private Vector pageViewportList = new java.util.Vector(); |
|
|
114 |
|
79 |
private Vector pageList = new java.util.Vector(); |
115 |
private Vector pageList = new java.util.Vector(); |
|
|
116 |
|
80 |
private Vector bufferedImageList = new java.util.Vector(); |
117 |
private Vector bufferedImageList = new java.util.Vector(); |
81 |
private BufferedImage currentPageImage = null; |
118 |
|
82 |
|
119 |
protected BufferedImage currentPageImage = null; |
|
|
120 |
|
121 |
/** the graphic used to draw on the BufferedImage */ |
122 |
protected Graphics2D graphics = null; |
123 |
|
124 |
/** the stroke used for graphics */ |
125 |
protected BasicStroke stroke = new BasicStroke(); |
126 |
|
127 |
/** a basic stroke to reset the stroke */ |
128 |
protected final BasicStroke basicStroke = new BasicStroke(); |
129 |
|
130 |
private boolean debug = true; |
131 |
|
132 |
protected boolean antialiasing = true; |
133 |
|
134 |
protected boolean qualityRendering = true; |
135 |
|
136 |
/** Size of currently selected font */ |
137 |
protected int currentFontSize = 0; |
138 |
|
139 |
/** Currently selected Color */ |
140 |
protected Color currentColor = null; |
141 |
|
142 |
/** Width of current line */ |
143 |
protected float currentLineWidth = 0; |
144 |
|
145 |
/** Style of current line */ |
146 |
protected int currentLineStyle = 0; |
147 |
|
83 |
/** Font configuration */ |
148 |
/** Font configuration */ |
84 |
protected FontInfo fontInfo; |
149 |
protected FontInfo fontInfo; |
85 |
|
150 |
|
Lines 89-101
Link Here
|
89 |
protected Translator translator = null; |
154 |
protected Translator translator = null; |
90 |
|
155 |
|
91 |
private Map fontNames = new java.util.Hashtable(); |
156 |
private Map fontNames = new java.util.Hashtable(); |
|
|
157 |
|
92 |
private Map fontStyles = new java.util.Hashtable(); |
158 |
private Map fontStyles = new java.util.Hashtable(); |
|
|
159 |
|
93 |
private Color saveColor = null; |
160 |
private Color saveColor = null; |
94 |
|
161 |
|
95 |
/** |
162 |
/** |
96 |
* The preview dialog frame used for display of the documents. |
163 |
* The preview dialog frame used for display of the documents. Also used as |
97 |
* Also used as the AWT Component for FontSetup in generating |
164 |
* the AWT Component for FontSetup in generating valid font measures. |
98 |
* valid font measures. |
|
|
99 |
*/ |
165 |
*/ |
100 |
protected PreviewDialog frame; |
166 |
protected PreviewDialog frame; |
101 |
|
167 |
|
Lines 127-135
Link Here
|
127 |
public void setupFontInfo(FontInfo inFontInfo) { |
193 |
public void setupFontInfo(FontInfo inFontInfo) { |
128 |
// create a temp Image to test font metrics on |
194 |
// create a temp Image to test font metrics on |
129 |
fontInfo = inFontInfo; |
195 |
fontInfo = inFontInfo; |
130 |
BufferedImage fontImage = |
196 |
BufferedImage fontImage = new BufferedImage(100, 100, |
131 |
new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); |
197 |
BufferedImage.TYPE_INT_RGB); |
132 |
FontSetup.setup(fontInfo, fontImage.createGraphics()); |
198 |
FontSetup.setup(fontInfo, fontImage.createGraphics()); |
|
|
199 |
// FIXME is this implemented correctly? |
133 |
} |
200 |
} |
134 |
|
201 |
|
135 |
public int getPageNumber() { |
202 |
public int getPageNumber() { |
Lines 148-164
Link Here
|
148 |
return scaleFactor; |
215 |
return scaleFactor; |
149 |
} |
216 |
} |
150 |
|
217 |
|
151 |
public void startRenderer(OutputStream out) |
218 |
public void startRenderer(OutputStream out) throws IOException { |
152 |
throws IOException { |
|
|
153 |
// empty pageViewportList, in case of a reload from PreviewDialog |
219 |
// empty pageViewportList, in case of a reload from PreviewDialog |
154 |
pageViewportList.removeAllElements(); |
220 |
pageViewportList.removeAllElements(); |
155 |
pageList.removeAllElements(); |
221 |
pageList.removeAllElements(); |
156 |
bufferedImageList.removeAllElements(); |
222 |
bufferedImageList.removeAllElements(); |
157 |
System.out.println("\nRegion Types: 0-Before/Top, 1-Start/Left, 2-Body, 3-End/Right, 4-After/Bottom"); |
223 |
System.out |
|
|
224 |
.println("\nRegion Types: 0-Before/Top, 1-Start/Left, 2-Body, 3-End/Right, 4-After/Bottom"); |
158 |
} |
225 |
} |
159 |
|
226 |
|
160 |
public void stopRenderer() |
227 |
public void stopRenderer() throws IOException { |
161 |
throws IOException { |
|
|
162 |
frame.setStatus(translator.getString("Status.Show")); |
228 |
frame.setStatus(translator.getString("Status.Show")); |
163 |
frame.showPage(); |
229 |
frame.showPage(); |
164 |
} |
230 |
} |
Lines 188-194
Link Here
|
188 |
} |
254 |
} |
189 |
}); |
255 |
}); |
190 |
|
256 |
|
191 |
//Centers the window |
257 |
// Centers the window |
192 |
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
258 |
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
193 |
Dimension frameSize = frame.getSize(); |
259 |
Dimension frameSize = frame.getSize(); |
194 |
if (frameSize.height > screenSize.height) { |
260 |
if (frameSize.height > screenSize.height) { |
Lines 198-215
Link Here
|
198 |
frameSize.width = screenSize.width; |
264 |
frameSize.width = screenSize.width; |
199 |
} |
265 |
} |
200 |
frame.setLocation((screenSize.width - frameSize.width) / 2, |
266 |
frame.setLocation((screenSize.width - frameSize.width) / 2, |
201 |
(screenSize.height - frameSize.height) / 2); |
267 |
(screenSize.height - frameSize.height) / 2); |
202 |
frame.setVisible(true); |
268 |
frame.setVisible(true); |
203 |
frame.setStatus(translator.getString("Status.Build.FO.tree")); |
269 |
frame.setStatus(translator.getString("Status.Build.FO.tree")); |
204 |
return frame; |
270 |
return frame; |
205 |
} |
271 |
} |
206 |
|
272 |
|
207 |
/** This method override only stores the PageViewport in a vector. |
273 |
/** |
208 |
* No actual rendering performed -- this is done by getPageImage(pageNum) instead. |
274 |
* This method override only stores the PageViewport in a vector. No actual |
209 |
* @param pageViewport the <code>PageViewport</code> object supplied by the Area Tree |
275 |
* rendering performed -- this is done by getPageImage(pageNum) instead. |
210 |
* @see org.apache.fop.render.Renderer |
276 |
* |
211 |
*/ |
277 |
* @param pageViewport the <code>PageViewport</code> object supplied by |
212 |
public void renderPage(PageViewport pageViewport) throws IOException, FOPException { |
278 |
* the Area Tree |
|
|
279 |
* @see org.apache.fop.render.Renderer |
280 |
*/ |
281 |
public void renderPage(PageViewport pageViewport) throws IOException, |
282 |
FOPException { |
213 |
pageViewportList.add(pageViewport); |
283 |
pageViewportList.add(pageViewport); |
214 |
pageList.add(pageViewport.getPage().clone()); |
284 |
pageList.add(pageViewport.getPage().clone()); |
215 |
bufferedImageList.add(getPageImage(pageViewport)); |
285 |
bufferedImageList.add(getPageImage(pageViewport)); |
Lines 219-249
Link Here
|
219 |
return (BufferedImage) bufferedImageList.get(pageNum); |
289 |
return (BufferedImage) bufferedImageList.get(pageNum); |
220 |
} |
290 |
} |
221 |
|
291 |
|
222 |
/** Generates a desired page from the renderer's page viewport vector. |
292 |
/** |
|
|
293 |
* Generates a desired page from the renderer's page viewport vector. |
294 |
* |
223 |
* @param pageNum the 0-based page number to generate |
295 |
* @param pageNum the 0-based page number to generate |
224 |
* @return the <code>java.awt.image.BufferedImage</code> corresponding to the page |
296 |
* @return the <code>java.awt.image.BufferedImage</code> corresponding to |
225 |
* @throws FOPException in case of an out-of-range page number requested |
297 |
* the page |
226 |
*/ |
298 |
* @throws FOPException in case of an out-of-range page number requested |
227 |
public BufferedImage getPageImage(PageViewport pageViewport) throws FOPException { |
299 |
*/ |
|
|
300 |
public BufferedImage getPageImage(PageViewport pageViewport) |
301 |
throws FOPException { |
228 |
Page page = pageViewport.getPage(); |
302 |
Page page = pageViewport.getPage(); |
229 |
|
303 |
|
230 |
Rectangle2D bounds = pageViewport.getViewArea(); |
304 |
Rectangle2D bounds = pageViewport.getViewArea(); |
231 |
pageWidth = (int) Math.round(bounds.getWidth() / 1000f ); |
305 |
pageWidth = (int) Math.round(bounds.getWidth() / 1000f); |
232 |
pageHeight = (int) Math.round(bounds.getHeight() / 1000f ); |
306 |
pageHeight = (int) Math.round(bounds.getHeight() / 1000f); |
233 |
/* |
307 |
|
234 |
System.out.println("(Page) X, Y, Width, Height: " + bounds.getX() |
308 |
System.out.println("(Page) X, Y, Width, Height: " + bounds.getX() + " " |
235 |
+ " " + bounds.getY() |
309 |
+ bounds.getY() + " " + bounds.getWidth() + " " |
236 |
+ " " + bounds.getWidth() |
310 |
+ bounds.getHeight() + ", pageWidth " + pageWidth |
237 |
+ " " + bounds.getHeight()); |
311 |
+ ", pageHeight " + pageHeight); |
238 |
*/ |
312 |
|
239 |
currentPageImage = |
313 |
currentPageImage = new BufferedImage( |
240 |
new BufferedImage((int)((pageWidth * (int)scaleFactor) / 100), |
314 |
(int) ((pageWidth * (int) scaleFactor) / 100), |
241 |
(int)((pageHeight * (int)scaleFactor) / 100), |
315 |
(int) ((pageHeight * (int) scaleFactor) / 100), |
242 |
BufferedImage.TYPE_INT_RGB); |
316 |
BufferedImage.TYPE_INT_RGB); |
243 |
|
317 |
|
244 |
Graphics2D graphics = currentPageImage.createGraphics(); |
318 |
graphics = currentPageImage.createGraphics(); |
245 |
graphics.setRenderingHint (RenderingHints.KEY_FRACTIONALMETRICS, |
319 |
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, |
246 |
RenderingHints.VALUE_FRACTIONALMETRICS_ON); |
320 |
RenderingHints.VALUE_FRACTIONALMETRICS_ON); |
|
|
321 |
if (antialiasing) { |
322 |
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, |
323 |
RenderingHints.VALUE_TEXT_ANTIALIAS_ON); |
324 |
} |
325 |
if (qualityRendering) |
326 |
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, |
327 |
RenderingHints.VALUE_RENDER_QUALITY); |
247 |
|
328 |
|
248 |
// transform page based on scale factor supplied |
329 |
// transform page based on scale factor supplied |
249 |
AffineTransform at = graphics.getTransform(); |
330 |
AffineTransform at = graphics.getTransform(); |
Lines 254-300
Link Here
|
254 |
graphics.setColor(Color.white); |
335 |
graphics.setColor(Color.white); |
255 |
graphics.fillRect(0, 0, pageWidth, pageHeight); |
336 |
graphics.fillRect(0, 0, pageWidth, pageHeight); |
256 |
graphics.setColor(Color.black); |
337 |
graphics.setColor(Color.black); |
|
|
338 |
// TODO Why draw those silly lines? |
257 |
graphics.drawRect(-1, -1, pageWidth + 2, pageHeight + 2); |
339 |
graphics.drawRect(-1, -1, pageWidth + 2, pageHeight + 2); |
258 |
graphics.drawLine(pageWidth + 2, 0, pageWidth + 2, pageHeight + 2); |
340 |
graphics.drawLine(pageWidth + 2, 0, pageWidth + 2, pageHeight + 2); |
259 |
graphics.drawLine(pageWidth + 3, 1, pageWidth + 3, pageHeight + 3); |
341 |
graphics.drawLine(pageWidth + 3, 1, pageWidth + 3, pageHeight + 3); |
260 |
graphics.drawLine(0, pageHeight + 2, pageWidth + 2, pageHeight + 2); |
342 |
graphics.drawLine(0, pageHeight + 2, pageWidth + 2, pageHeight + 2); |
261 |
graphics.drawLine(1, pageHeight + 3, pageWidth + 3, pageHeight + 3); |
343 |
graphics.drawLine(1, pageHeight + 3, pageWidth + 3, pageHeight + 3); |
262 |
|
344 |
|
|
|
345 |
// reset the current Positions |
346 |
currentBPPosition = 0; |
347 |
currentIPPosition = 0; |
348 |
|
349 |
// this toggles the rendering of all areas |
263 |
renderPageAreas(page); |
350 |
renderPageAreas(page); |
264 |
return currentPageImage; |
351 |
return currentPageImage; |
265 |
} |
352 |
} |
266 |
|
353 |
|
267 |
/** Generates a desired page from the renderer's page viewport vector. |
354 |
/** |
|
|
355 |
* TODO refactor with getPageImage(PageViewport) Generates a desired page |
356 |
* from the renderer's page viewport vector. |
357 |
* |
268 |
* @param pageNum the 0-based page number to generate |
358 |
* @param pageNum the 0-based page number to generate |
269 |
* @return the <code>java.awt.image.BufferedImage</code> corresponding to the page |
359 |
* @return the <code>java.awt.image.BufferedImage</code> corresponding to |
270 |
* @throws FOPException in case of an out-of-range page number requested |
360 |
* the page |
271 |
*/ |
361 |
* @throws FOPException in case of an out-of-range page number requested |
|
|
362 |
*/ |
272 |
public BufferedImage getPageImage(int pageNum) throws FOPException { |
363 |
public BufferedImage getPageImage(int pageNum) throws FOPException { |
273 |
if (pageNum < 0 || pageNum >= pageViewportList.size()) { |
364 |
if (pageNum < 0 || pageNum >= pageViewportList.size()) { |
274 |
throw new FOPException("out-of-range page number (" + pageNum |
365 |
throw new FOPException("out-of-range page number (" + pageNum |
275 |
+ ") requested; only " + pageViewportList.size() |
366 |
+ ") requested; only " + pageViewportList.size() |
276 |
+ " page(s) available."); |
367 |
+ " page(s) available."); |
277 |
} |
368 |
} |
278 |
PageViewport pageViewport = (PageViewport) pageViewportList.get(pageNum); |
369 |
PageViewport pageViewport = (PageViewport) pageViewportList |
|
|
370 |
.get(pageNum); |
279 |
Page page = (Page) pageList.get(pageNum); |
371 |
Page page = (Page) pageList.get(pageNum); |
280 |
|
372 |
|
281 |
Rectangle2D bounds = pageViewport.getViewArea(); |
373 |
Rectangle2D bounds = pageViewport.getViewArea(); |
282 |
pageWidth = (int) Math.round(bounds.getWidth() / 1000f ); |
374 |
pageWidth = (int) Math.round(bounds.getWidth() / 1000f); |
283 |
pageHeight = (int) Math.round(bounds.getHeight() / 1000f ); |
375 |
pageHeight = (int) Math.round(bounds.getHeight() / 1000f); |
284 |
/* |
376 |
/* |
285 |
System.out.println("(Page) X, Y, Width, Height: " + bounds.getX() |
377 |
* System.out.println("(Page) X, Y, Width, Height: " + bounds.getX() + " " + |
286 |
+ " " + bounds.getY() |
378 |
* bounds.getY() + " " + bounds.getWidth() + " " + bounds.getHeight()); |
287 |
+ " " + bounds.getWidth() |
379 |
*/ |
288 |
+ " " + bounds.getHeight()); |
380 |
currentPageImage = new BufferedImage( |
289 |
*/ |
381 |
(int) ((pageWidth * (int) scaleFactor) / 100), |
290 |
currentPageImage = |
382 |
(int) ((pageHeight * (int) scaleFactor) / 100), |
291 |
new BufferedImage((int)((pageWidth * (int)scaleFactor) / 100), |
383 |
BufferedImage.TYPE_INT_RGB); |
292 |
(int)((pageHeight * (int)scaleFactor) / 100), |
384 |
|
293 |
BufferedImage.TYPE_INT_RGB); |
385 |
graphics = currentPageImage.createGraphics(); |
294 |
|
386 |
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, |
295 |
Graphics2D graphics = currentPageImage.createGraphics(); |
387 |
RenderingHints.VALUE_FRACTIONALMETRICS_ON); |
296 |
graphics.setRenderingHint (RenderingHints.KEY_FRACTIONALMETRICS, |
388 |
if (antialiasing) { |
297 |
RenderingHints.VALUE_FRACTIONALMETRICS_ON); |
389 |
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, |
|
|
390 |
RenderingHints.VALUE_TEXT_ANTIALIAS_ON); |
391 |
} |
392 |
if (qualityRendering) |
393 |
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, |
394 |
RenderingHints.VALUE_RENDER_QUALITY); |
298 |
|
395 |
|
299 |
// transform page based on scale factor supplied |
396 |
// transform page based on scale factor supplied |
300 |
AffineTransform at = graphics.getTransform(); |
397 |
AffineTransform at = graphics.getTransform(); |
Lines 311-465
Link Here
|
311 |
graphics.drawLine(0, pageHeight + 2, pageWidth + 2, pageHeight + 2); |
408 |
graphics.drawLine(0, pageHeight + 2, pageWidth + 2, pageHeight + 2); |
312 |
graphics.drawLine(1, pageHeight + 3, pageWidth + 3, pageHeight + 3); |
409 |
graphics.drawLine(1, pageHeight + 3, pageWidth + 3, pageHeight + 3); |
313 |
|
410 |
|
|
|
411 |
// reset the current Positions |
412 |
currentBPPosition = 0; |
413 |
currentIPPosition = 0; |
414 |
|
314 |
renderPageAreas(page); |
415 |
renderPageAreas(page); |
315 |
return currentPageImage; |
416 |
return currentPageImage; |
316 |
} |
417 |
} |
317 |
|
418 |
|
318 |
/** |
419 |
/** |
319 |
* Handle the traits for a region |
420 |
* @see org.apache.fop.render.AbstractRenderer#startVParea(CTM) |
320 |
* This is used to draw the traits for the given page region. |
421 |
*/ |
321 |
* (See Sect. 6.4.1.2 of XSL-FO spec.) |
422 |
protected void startVParea(CTM ctm) { |
322 |
* @param region the RegionViewport whose region is to be drawn |
423 |
|
323 |
*/ |
424 |
// Uses the x shift (param e) and y shift (param f) |
324 |
protected void handleRegionTraits(RegionViewport region) { |
425 |
// of the CTM to update the current Positions |
325 |
Rectangle2D viewArea = region.getViewArea(); |
426 |
currentIPPosition += (int) ctm.getXShift(); |
326 |
|
427 |
currentBPPosition += (int) ctm.getYShift(); |
327 |
int startX = (int) Math.round((viewArea.getX() / 1000f) |
428 |
// TODO is this supporting other writing modes? |
328 |
* (scaleFactor / 100f)); |
|
|
329 |
int startY = (int) Math.round((viewArea.getY() / 1000f) |
330 |
* (scaleFactor / 100f)); |
331 |
// for rounding to work correctly, need to take into account |
332 |
// fractional portion of X and Y. |
333 |
int width = (int) Math.round(((viewArea.getX() + viewArea.getWidth()) / 1000f) |
334 |
* (scaleFactor / 100f)) - startX; |
335 |
int height = (int) Math.round(((viewArea.getY() + viewArea.getHeight()) / 1000f) |
336 |
* (scaleFactor / 100f)) - startY; |
337 |
|
338 |
if (region.getRegion() != null) { |
339 |
System.out.print("\nRegion type = " + region.getRegion().getRegionClass()); |
340 |
} |
341 |
|
342 |
System.out.println(" X, Width, Y, Height: " + startX |
343 |
+ " " + width |
344 |
+ " " + startY |
345 |
+ " " + height |
346 |
); |
347 |
|
348 |
drawBackAndBorders(region, startX, startY, width, height); |
349 |
} |
429 |
} |
350 |
|
430 |
|
351 |
/** |
431 |
/** |
352 |
* Draw the background and borders. |
432 |
* Draw the background and borders. This draws the background and border |
353 |
* This draws the background and border traits for an area given |
433 |
* traits for an area given the position. |
354 |
* the position. |
434 |
* |
355 |
* |
|
|
356 |
* @param block the area to get the traits from |
435 |
* @param block the area to get the traits from |
357 |
* @param startx the start x position |
436 |
* @param startx the start x position |
358 |
* @param starty the start y position |
437 |
* @param starty the start y position |
359 |
* @param width the width of the area |
438 |
* @param width the width of the area |
360 |
* @param height the height of the area |
439 |
* @param height the height of the area |
361 |
*/ |
440 |
*/ |
362 |
protected void drawBackAndBorders(Area block, |
441 |
protected void drawBackAndBorders(Area area, float startx, float starty, |
363 |
int startx, int starty, |
442 |
float width, float height) { |
364 |
int width, int height) { |
443 |
// TODO put in AbstractRenderer and call drawBackground() |
|
|
444 |
// and drawBorders() |
445 |
|
446 |
BorderProps bpsBefore = (BorderProps) area |
447 |
.getTrait(Trait.BORDER_BEFORE); |
448 |
BorderProps bpsAfter = (BorderProps) area.getTrait(Trait.BORDER_AFTER); |
449 |
BorderProps bpsStart = (BorderProps) area.getTrait(Trait.BORDER_START); |
450 |
BorderProps bpsEnd = (BorderProps) area.getTrait(Trait.BORDER_END); |
365 |
|
451 |
|
366 |
// draw background then border |
452 |
// draw background |
367 |
Graphics2D graphics = currentPageImage.createGraphics(); |
|
|
368 |
Trait.Background back; |
453 |
Trait.Background back; |
369 |
back = (Trait.Background) block.getTrait(Trait.BACKGROUND); |
454 |
back = (Trait.Background) area.getTrait(Trait.BACKGROUND); |
370 |
if (back != null) { |
455 |
if (back != null) { |
371 |
|
456 |
|
|
|
457 |
// Calculate padding rectangle |
458 |
float sx = startx; |
459 |
float sy = starty; |
460 |
float paddRectWidth = width; |
461 |
float paddRectHeight = height; |
462 |
|
463 |
if (bpsStart != null) { |
464 |
sx += bpsStart.width / 1000f; |
465 |
paddRectWidth -= bpsStart.width / 1000f; |
466 |
} |
467 |
if (bpsBefore != null) { |
468 |
sy += bpsBefore.width / 1000f; |
469 |
paddRectHeight -= bpsBefore.width / 1000f; |
470 |
} |
471 |
if (bpsEnd != null) { |
472 |
paddRectWidth -= bpsEnd.width / 1000f; |
473 |
} |
474 |
if (bpsAfter != null) { |
475 |
paddRectHeight -= bpsAfter.width / 1000f; |
476 |
} |
477 |
|
372 |
if (back.getColor() != null) { |
478 |
if (back.getColor() != null) { |
373 |
graphics.setColor(back.getColor().getAWTColor()); |
479 |
drawBackground(back, sx, sy, paddRectWidth, paddRectHeight); |
374 |
graphics.fillRect(startx, starty, width, height); |
|
|
375 |
} |
480 |
} |
376 |
if (back.getURL() != null) { // TODO: implement |
481 |
|
377 |
ImageFactory fact = ImageFactory.getInstance(); |
482 |
// background image |
378 |
FopImage fopimage = fact.getImage(back.getURL(), userAgent); |
483 |
if (back.getFopImage() != null) { |
|
|
484 |
FopImage fopimage = back.getFopImage(); |
379 |
if (fopimage != null && fopimage.load(FopImage.DIMENSIONS)) { |
485 |
if (fopimage != null && fopimage.load(FopImage.DIMENSIONS)) { |
380 |
if (back.getRepeat() == EN_REPEAT) { |
486 |
// TODO clip(sx, sy, paddRectWidth, paddRectHeight); |
381 |
// create a pattern for the image |
487 |
int horzCount = (int) ((paddRectWidth * 1000 / fopimage |
382 |
} else { |
488 |
.getIntrinsicWidth()) + 1.0f); |
383 |
// place once |
489 |
int vertCount = (int) ((paddRectHeight * 1000 / fopimage |
384 |
Rectangle2D pos; |
490 |
.getIntrinsicHeight()) + 1.0f); |
385 |
pos = new Rectangle2D.Float((startx + back.getHoriz()) * 1000, |
491 |
if (back.getRepeat() == EN_NOREPEAT) { |
386 |
(starty + back.getVertical()) * 1000, |
492 |
horzCount = 1; |
387 |
fopimage.getWidth() * 1000, |
493 |
vertCount = 1; |
388 |
fopimage.getHeight() * 1000); |
494 |
} else if (back.getRepeat() == EN_REPEATX) { |
389 |
// putImage(back.getURL(), pos); |
495 |
vertCount = 1; |
|
|
496 |
} else if (back.getRepeat() == EN_REPEATY) { |
497 |
horzCount = 1; |
498 |
} |
499 |
// change from points to millipoints |
500 |
sx *= 1000; |
501 |
sy *= 1000; |
502 |
if (horzCount == 1) { |
503 |
sx += back.getHoriz(); |
390 |
} |
504 |
} |
|
|
505 |
if (vertCount == 1) { |
506 |
sy += back.getVertical(); |
507 |
} |
508 |
for (int x = 0; x < horzCount; x++) { |
509 |
for (int y = 0; y < vertCount; y++) { |
510 |
// place once |
511 |
Rectangle2D pos; |
512 |
pos = new Rectangle2D.Float(sx |
513 |
+ (x * fopimage.getIntrinsicWidth()), sy |
514 |
+ (y * fopimage.getIntrinsicHeight()), |
515 |
fopimage.getIntrinsicWidth(), fopimage |
516 |
.getIntrinsicHeight()); |
517 |
putImage(back.getURL(), pos); //TODO test |
518 |
} |
519 |
} |
520 |
|
521 |
} else { |
522 |
getLogger().warn( |
523 |
"Can't find background image: " + back.getURL()); |
391 |
} |
524 |
} |
392 |
} |
525 |
} |
393 |
} |
526 |
} |
394 |
|
527 |
|
395 |
BorderProps bps = (BorderProps) block.getTrait(Trait.BORDER_BEFORE); |
528 |
// draw border //TODO not touched, maybe better implemented in pdf? |
|
|
529 |
// -->to be tested |
530 |
BorderProps bps = (BorderProps) area.getTrait(Trait.BORDER_BEFORE); |
396 |
if (bps != null) { |
531 |
if (bps != null) { |
397 |
int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f)); |
532 |
int borderWidth = (int) Math.round((bps.width / 1000f) |
|
|
533 |
* (scaleFactor / 100f)); |
398 |
graphics.setColor(bps.color.getAWTColor()); |
534 |
graphics.setColor(bps.color.getAWTColor()); |
399 |
graphics.fillRect(startx, starty, width, borderWidth); |
535 |
graphics.fillRect((int) startx, (int) starty, (int) width, |
|
|
536 |
borderWidth); |
400 |
} |
537 |
} |
401 |
bps = (BorderProps) block.getTrait(Trait.BORDER_AFTER); |
538 |
bps = (BorderProps) area.getTrait(Trait.BORDER_AFTER); |
402 |
if (bps != null) { |
539 |
if (bps != null) { |
403 |
int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f)); |
540 |
int borderWidth = (int) Math.round((bps.width / 1000f) |
404 |
int sy = starty + height; |
541 |
* (scaleFactor / 100f)); |
|
|
542 |
float sy = starty + height; |
405 |
graphics.setColor(bps.color.getAWTColor()); |
543 |
graphics.setColor(bps.color.getAWTColor()); |
406 |
graphics.fillRect(startx, starty + height - borderWidth, |
544 |
graphics.fillRect((int) startx, |
407 |
width, borderWidth); |
545 |
(int) (starty + height - borderWidth), (int) width, |
|
|
546 |
borderWidth); |
408 |
} |
547 |
} |
409 |
bps = (BorderProps) block.getTrait(Trait.BORDER_START); |
548 |
bps = (BorderProps) area.getTrait(Trait.BORDER_START); |
410 |
if (bps != null) { |
549 |
if (bps != null) { |
411 |
int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f)); |
550 |
int borderWidth = (int) Math.round((bps.width / 1000f) |
|
|
551 |
* (scaleFactor / 100f)); |
412 |
graphics.setColor(bps.color.getAWTColor()); |
552 |
graphics.setColor(bps.color.getAWTColor()); |
413 |
graphics.fillRect(startx, starty, borderWidth, height); |
553 |
graphics.fillRect((int) startx, (int) starty, borderWidth, |
|
|
554 |
(int) height); |
414 |
} |
555 |
} |
415 |
bps = (BorderProps) block.getTrait(Trait.BORDER_END); |
556 |
bps = (BorderProps) area.getTrait(Trait.BORDER_END); |
416 |
if (bps != null) { |
557 |
if (bps != null) { |
417 |
int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f)); |
558 |
int borderWidth = (int) Math.round((bps.width / 1000f) |
418 |
int sx = startx + width; |
559 |
* (scaleFactor / 100f)); |
|
|
560 |
float sx = startx + width; |
419 |
graphics.setColor(bps.color.getAWTColor()); |
561 |
graphics.setColor(bps.color.getAWTColor()); |
420 |
graphics.fillRect(startx + width - borderWidth, starty, |
562 |
graphics.fillRect((int) (startx + width - borderWidth), |
421 |
borderWidth, height); |
563 |
(int) starty, borderWidth, (int) height); |
422 |
} |
564 |
} |
423 |
|
565 |
|
|
|
566 |
} |
567 |
|
568 |
/** |
569 |
* Draw the Background Rectangle of a given area. |
570 |
* |
571 |
* @param back the Trait.Background |
572 |
* @param sx x coordinate of the rectangle to be filled. |
573 |
* @param sy y the y coordinate of the rectangle to be filled. |
574 |
* @param paddRectWidth the width of the rectangle to be filled. |
575 |
* @param paddRectHeight the height of the rectangle to be filled. |
576 |
*/ |
577 |
protected void drawBackground(Trait.Background back, float sx, float sy, |
578 |
float paddRectWidth, float paddRectHeight) { |
579 |
|
580 |
graphics.setColor(back.getColor().getAWTColor()); |
581 |
graphics.fillRect((int) sx, (int) sy, (int) paddRectWidth, |
582 |
(int) paddRectHeight); |
583 |
} |
584 |
|
585 |
/** |
586 |
* Handle block traits. The block could be any sort of block with any |
587 |
* positioning so this should render the traits such as border and |
588 |
* background in its position. |
589 |
* |
590 |
* @param block the block to render the traits |
591 |
*/ |
592 |
protected void handleBlockTraits(Block block) { |
593 |
// TODO only copied from pdf |
594 |
// TODO check and try to put in AbstractRenderer |
595 |
int borderPaddingStart = block.getBorderAndPaddingWidthStart(); |
596 |
int borderPaddingBefore = block.getBorderAndPaddingWidthBefore(); |
597 |
|
598 |
float startx = currentIPPosition / 1000f; |
599 |
float starty = currentBPPosition / 1000f; |
600 |
float width = block.getIPD() / 1000f; |
601 |
float height = block.getBPD() / 1000f; |
602 |
|
603 |
startx += block.getStartIndent() / 1000f; |
604 |
startx -= block.getBorderAndPaddingWidthStart() / 1000f; |
605 |
width += borderPaddingStart / 1000f; |
606 |
width += block.getBorderAndPaddingWidthEnd() / 1000f; |
607 |
height += borderPaddingBefore / 1000f; |
608 |
height += block.getBorderAndPaddingWidthAfter() / 1000f; |
609 |
|
610 |
drawBackAndBorders(block, startx, starty, width, height); |
424 |
} |
611 |
} |
425 |
|
612 |
|
426 |
/** |
613 |
/** |
427 |
* @see org.apache.fop.render.Renderer#renderText(TextArea) |
614 |
* @see org.apache.fop.render.Renderer#renderText(TextArea) |
428 |
*/ |
615 |
*/ |
429 |
public void renderText(TextArea text) { |
616 |
public void renderText(TextArea text) { |
430 |
System.out.println("In render text: " + text.getTextArea()); |
|
|
431 |
|
617 |
|
432 |
Graphics2D graphics = currentPageImage.createGraphics(); |
618 |
float x = currentIPPosition / 1000f; |
|
|
619 |
float y = (currentBPPosition + text.getOffset()) / 1000f; // baseline |
620 |
|
621 |
updateColor(text); |
622 |
updateFont(text); |
623 |
String s = text.getTextArea(); |
624 |
graphics.drawString(s, x, y); |
625 |
|
626 |
getLogger().debug( |
627 |
s + " cX " + currentIPPosition + "curY" + currentBPPosition |
628 |
+ " x " + x + " y " + y); |
629 |
|
630 |
// rendering text decorations //TODO refactorize |
433 |
String fontName = (String) text.getTrait(Trait.FONT_NAME); |
631 |
String fontName = (String) text.getTrait(Trait.FONT_NAME); |
434 |
int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); |
632 |
int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); |
435 |
// Typeface f = (Typeface) fontInfo.getFonts().get(fontName); |
633 |
FontMetrics metrics = fontInfo.getMetricsFor(fontName); |
436 |
ColorType ct = (ColorType) text.getTrait(Trait.COLOR); |
634 |
Font fs = new Font(fontName, metrics, size); |
|
|
635 |
super.renderTextDecoration(fs, text, (currentBPPosition + text |
636 |
.getOffset()), currentIPPosition); |
637 |
renderTextDecoration(fs, text, (int) y, (int) x); |
437 |
|
638 |
|
438 |
FontMetricsMapper mapper = (FontMetricsMapper) |
639 |
super.renderText(text); |
439 |
fontInfo.getMetricsFor(fontName); |
640 |
} |
440 |
if (mapper == null) { |
641 |
|
441 |
mapper = new FontMetricsMapper("MonoSpaced", java.awt.Font.PLAIN, |
642 |
/** |
442 |
graphics); |
643 |
* @see org.apache.fop.render.Renderer#renderCharacter(Character) |
443 |
} |
644 |
*/ |
444 |
|
645 |
public void renderCharacter(Character ch) { |
445 |
// graphics.setColor(ct.getAWTColor()); |
646 |
|
446 |
// graphics.setFont(mapper.getFont(size)); |
647 |
float x = currentIPPosition / 1000f; |
447 |
graphics.setColor(java.awt.Color.black); |
648 |
float y = (currentBPPosition + ch.getOffset()) / 1000f; // baseline |
448 |
graphics.setFont(new java.awt.Font("monospaced", java.awt.Font.PLAIN, |
|
|
449 |
10)); |
450 |
|
451 |
int rx = currentIPPosition; |
452 |
int bl = currentBPPosition + text.getOffset(); |
453 |
|
454 |
int newx = (int) (rx + 500) / 1000; |
455 |
int newy = (int) (pageHeight - (bl + 500) / 1000); |
456 |
|
457 |
String s = text.getTextArea(); |
458 |
// graphics.drawString(s, newx, newy); |
459 |
graphics.drawString(s, 220, 200); |
460 |
|
649 |
|
461 |
// TODO: render text decorations |
650 |
updateColor(ch); |
462 |
currentIPPosition += text.getAllocIPD(); |
651 |
updateFont(ch); |
|
|
652 |
String s = ch.getChar(); |
653 |
graphics.drawString(s, x, y); |
654 |
|
655 |
getLogger().debug( |
656 |
s + " cX " + currentIPPosition + "curY" + currentBPPosition); |
657 |
|
658 |
// rendering text decorations //TODO refactorize |
659 |
String fontName = (String) ch.getTrait(Trait.FONT_NAME); |
660 |
int size = ((Integer) ch.getTrait(Trait.FONT_SIZE)).intValue(); |
661 |
FontMetrics metrics = fontInfo.getMetricsFor(fontName); |
662 |
Font fs = new Font(fontName, metrics, size); |
663 |
super.renderTextDecoration(fs, ch, |
664 |
(currentBPPosition + ch.getOffset()), currentIPPosition); |
665 |
renderTextDecoration(fs, ch, (int) y, (int) x); |
666 |
|
667 |
super.renderCharacter(ch); |
463 |
} |
668 |
} |
464 |
|
669 |
|
465 |
/** @see org.apache.fop.render.AbstractRenderer */ |
670 |
/** @see org.apache.fop.render.AbstractRenderer */ |
Lines 467-470
Link Here
|
467 |
return MIME_TYPE; |
672 |
return MIME_TYPE; |
468 |
} |
673 |
} |
469 |
|
674 |
|
|
|
675 |
/** |
676 |
* Render leader area. This renders a leader area which is an area with a |
677 |
* rule. |
678 |
* |
679 |
* @param area the leader area to render |
680 |
*/ |
681 |
public void renderLeader(Leader area) { |
682 |
|
683 |
// TODO leader-length: 25%, 50%, 75%, 100% not working yet |
684 |
|
685 |
float startx = ((float) currentIPPosition) / 1000f; |
686 |
float starty = ((currentBPPosition + area.getOffset()) / 1000f); |
687 |
float endx = (currentIPPosition + area.getIPD()) / 1000f; |
688 |
|
689 |
updateColor(area); |
690 |
|
691 |
Line2D.Float leader = new Line2D.Float(startx, starty, endx, starty); |
692 |
float thickness = area.getRuleThickness() / 1000f; |
693 |
|
694 |
int style = area.getRuleStyle(); |
695 |
switch (style) { |
696 |
case EN_SOLID: |
697 |
case EN_DOTTED: |
698 |
case EN_DASHED: |
699 |
updateLineWidth(thickness); |
700 |
updateLineStyle(style); |
701 |
graphics.draw(leader); |
702 |
break; |
703 |
case EN_DOUBLE: |
704 |
updateLineWidth(thickness / 3f); // only a third |
705 |
updateLineStyle(EN_SOLID); |
706 |
|
707 |
Line2D.Float upperLeader = new Line2D.Float(startx, starty, endx, |
708 |
starty); |
709 |
graphics.draw(upperLeader); |
710 |
Line2D.Float lowerLeader = new Line2D.Float(startx, starty + 2 |
711 |
* thickness, endx, starty + 2 * thickness); |
712 |
graphics.draw(lowerLeader); |
713 |
break; |
714 |
case EN_GROOVE: |
715 |
// The rule looks as though it were carved into the canvas. |
716 |
// (Top/left half of the rule's thickness is the |
717 |
// color specified; the other half is white.) |
718 |
|
719 |
updateLineWidth(thickness / 2f); // only the half |
720 |
updateLineStyle(EN_SOLID); |
721 |
|
722 |
Line2D.Float upperLeader2 = new Line2D.Float(startx, starty, endx, |
723 |
starty); |
724 |
graphics.draw(upperLeader2); |
725 |
Line2D.Float lowerLeader2 = new Line2D.Float(startx, starty |
726 |
+ thickness, endx, starty + thickness); |
727 |
graphics.setColor(Color.WHITE); |
728 |
graphics.draw(lowerLeader2); |
729 |
// TODO the implementation could be nicer, f.eg. with triangles at |
730 |
// the tip of the lines. See also RenderX's implementation (looks |
731 |
// like a button) |
732 |
break; |
733 |
case EN_RIDGE: |
734 |
// The opposite of "groove", the rule looks as though it were |
735 |
// coming out of the canvas. (Bottom/right half of the rule's |
736 |
// thickness is the color specified; the other half is white.) |
737 |
|
738 |
updateLineWidth(thickness / 2f); // only the half |
739 |
updateLineStyle(EN_SOLID); |
740 |
|
741 |
Line2D.Float lowerLeader3 = new Line2D.Float(startx, starty |
742 |
+ thickness, endx, starty + thickness); |
743 |
graphics.draw(lowerLeader3); |
744 |
Line2D.Float upperLeader3 = new Line2D.Float(startx, starty, endx, |
745 |
starty); |
746 |
graphics.setColor(Color.WHITE); |
747 |
graphics.draw(upperLeader3); |
748 |
// TODO the implementation could be nicer, f.eg. with triangles at |
749 |
// the tip of the lines. See also RenderX's implementation (looks |
750 |
// like a button) |
751 |
break; |
752 |
case EN_NONE: |
753 |
// No rule is drawn |
754 |
break; |
755 |
|
756 |
} // end switch |
757 |
|
758 |
graphics.setStroke(basicStroke); // reset the stroke |
759 |
|
760 |
super.renderLeader(area); |
761 |
} |
762 |
|
763 |
// TODO abstractize? |
764 |
/** |
765 |
* Converts a ColorType to a java.awt.Color (sRGB). |
766 |
* |
767 |
* @param col the color |
768 |
* @return the converted color |
769 |
*/ |
770 |
protected Color toColor(ColorType col) { |
771 |
return new Color(col.getRed(), col.getGreen(), col.getBlue()); |
772 |
} |
773 |
|
774 |
/** |
775 |
* Establishes a new foreground or fill color. |
776 |
* |
777 |
* @param col the color to apply (null skips this operation) |
778 |
* @param fill true to set the fill color, false for the foreground color |
779 |
* @param pdf StringBuffer to write the PDF code to, if null, the code is |
780 |
* written to the current stream. |
781 |
*/ |
782 |
protected void updateColor(ColorType col, boolean fill, StringBuffer pdf) { |
783 |
if (col == null) { |
784 |
return; |
785 |
} |
786 |
Color newCol = toColor(col); |
787 |
graphics.setColor(newCol); |
788 |
} |
789 |
|
790 |
protected void updateColor(Area area) { |
791 |
ColorType ct = (ColorType) area.getTrait(Trait.COLOR); |
792 |
try { // FIXME there must be another way (that always works) |
793 |
currentColor = ct.getAWTColor(); |
794 |
} catch (Exception e) { |
795 |
getLogger() |
796 |
.warn( |
797 |
"Can't find color: " + ct |
798 |
+ "color set by default to black"); |
799 |
currentColor = java.awt.Color.black; |
800 |
} |
801 |
graphics.setColor(currentColor); |
802 |
} |
803 |
|
804 |
protected void updateFont(String name, int size, StringBuffer pdf) { |
805 |
if ((!name.equals(this.currentFontName)) |
806 |
|| (size != this.currentFontSize)) { |
807 |
|
808 |
// graphics.setFont(xxxx); //TODO |
809 |
// this.currentFontName = name; |
810 |
// this.currentFontSize = size; |
811 |
} |
812 |
} |
813 |
|
814 |
protected void updateFont(Area area) { |
815 |
|
816 |
// FIXME Fonts are not working properly yet |
817 |
|
818 |
String fontName = (String) area.getTrait(Trait.FONT_NAME); |
819 |
int size = ((Integer) area.getTrait(Trait.FONT_SIZE)).intValue(); |
820 |
|
821 |
FontMetricsMapper mapper = (FontMetricsMapper) fontInfo |
822 |
.getMetricsFor(fontName); |
823 |
java.awt.Font font = mapper.getFont(size); |
824 |
|
825 |
// graphics.setFont(new java.awt.Font("SansSerif", java.awt.Font.PLAIN, |
826 |
// (int)(size/1000f))); |
827 |
graphics.setFont(font); |
828 |
|
829 |
} |
830 |
|
831 |
/** |
832 |
* Sets the current line width in points. |
833 |
* |
834 |
* @param width line width in points |
835 |
*/ |
836 |
protected void updateLineWidth(float width) { |
837 |
this.currentLineWidth = width; |
838 |
} |
839 |
|
840 |
/** |
841 |
* Sets the current line style. The line width should be set with |
842 |
* updateLineWidth() before calling this method |
843 |
* |
844 |
* @param style the constant for the style of the line as an int |
845 |
*/ |
846 |
protected void updateLineStyle(int style) { |
847 |
switch (style) { |
848 |
case EN_DOTTED: |
849 |
stroke = new BasicStroke(currentLineWidth, BasicStroke.CAP_BUTT, |
850 |
BasicStroke.JOIN_BEVEL, 0f, new float[] { 2f }, 0f); |
851 |
graphics.setStroke(stroke); |
852 |
break; |
853 |
case EN_DASHED: |
854 |
stroke = new BasicStroke(currentLineWidth, BasicStroke.CAP_BUTT, |
855 |
BasicStroke.JOIN_BEVEL, 0f, new float[] { 8f, 2f }, 0f); |
856 |
graphics.setStroke(stroke); |
857 |
break; |
858 |
default: // EN_SOLID: |
859 |
stroke = new BasicStroke(currentLineWidth); |
860 |
graphics.setStroke(stroke); |
861 |
break; |
862 |
} |
863 |
} |
864 |
|
865 |
/** |
866 |
* Draw a line. |
867 |
* |
868 |
* @param startx the start x position |
869 |
* @param starty the start y position |
870 |
* @param endx the x end position |
871 |
* @param endy the y end position |
872 |
*/ |
873 |
protected void drawLine(float startx, float starty, float endx, float endy) { |
874 |
graphics.draw(new Line2D.Float(startx, starty, endx, endy)); |
875 |
} |
876 |
|
877 |
// TODO abstractize, or refactorize with putImage |
878 |
/** |
879 |
* @see org.apache.fop.render.AbstractRenderer#renderImage(Image, |
880 |
* Rectangle2D) |
881 |
*/ |
882 |
public void renderImage(Image image, Rectangle2D pos) { |
883 |
endTextObject(); |
884 |
String url = image.getURL(); |
885 |
putImage(url, pos); |
886 |
} |
887 |
|
888 |
/** |
889 |
* Adds a PDF XObject (a bitmap) to the PDF that will later be referenced. |
890 |
* |
891 |
* @param url URL of the bitmap |
892 |
* @param pos Position of the bitmap |
893 |
*/ |
894 |
protected void putImage(String Purl, Rectangle2D pos) { |
895 |
|
896 |
int x = currentIPPosition; // TODO + area.getXOffset(); |
897 |
int y = currentBPPosition; |
898 |
String url = ImageFactory.getURL(Purl); |
899 |
|
900 |
ImageFactory fact = ImageFactory.getInstance(); |
901 |
FopImage fopimage = fact.getImage(url, userAgent); |
902 |
|
903 |
if (fopimage == null) { |
904 |
return; |
905 |
} |
906 |
if (!fopimage.load(FopImage.DIMENSIONS)) { |
907 |
return; |
908 |
} |
909 |
int w = fopimage.getWidth(); |
910 |
int h = fopimage.getHeight(); |
911 |
String mime = fopimage.getMimeType(); |
912 |
if ("text/xml".equals(mime)) { |
913 |
if (!fopimage.load(FopImage.ORIGINAL_DATA)) { |
914 |
return; |
915 |
} |
916 |
Document doc = ((XMLImage) fopimage).getDocument(); |
917 |
String ns = ((XMLImage) fopimage).getNameSpace(); |
918 |
renderDocument(doc, ns, pos); |
919 |
|
920 |
} else if ("image/svg+xml".equals(mime)) { |
921 |
if (!fopimage.load(FopImage.ORIGINAL_DATA)) { |
922 |
return; |
923 |
} |
924 |
Document doc = ((XMLImage) fopimage).getDocument(); |
925 |
renderSVGDocument(doc, pos); // TODO check if ok. |
926 |
|
927 |
} else if (("image/eps".equals(mime)) || ("image/jpeg".equals(mime))) { |
928 |
if (!fopimage.load(FopImage.ORIGINAL_DATA)) { |
929 |
return; |
930 |
} |
931 |
java.awt.Image awtImage = new javax.swing.ImageIcon(url).getImage(); |
932 |
graphics.drawImage(awtImage, (int) (x / 1000f), (int) (y / 1000f), |
933 |
(int) w, h, null); |
934 |
currentBPPosition += (h * 1000); // TODO doesn't work! |
935 |
|
936 |
} else if ("image/bmp".equals(mime)) { |
937 |
if (!fopimage.load(FopImage.BITMAP)) { |
938 |
return; |
939 |
} |
940 |
try { |
941 |
java.awt.Image awtImage = new BMPReader().loadbitmap(url); |
942 |
graphics.drawImage(awtImage, (int) (x / 1000f), |
943 |
(int) (y / 1000f), (int) w, h, null); |
944 |
} catch (Exception e) { |
945 |
getLogger().warn(e); |
946 |
} |
947 |
currentBPPosition += (h * 1000); // TODO doesn't work! |
948 |
|
949 |
} else { |
950 |
if (!fopimage.load(FopImage.BITMAP)) { |
951 |
return; |
952 |
} |
953 |
java.awt.Image awtImage = new javax.swing.ImageIcon(url).getImage(); |
954 |
graphics.drawImage(awtImage, (int) (x / 1000f), (int) (y / 1000f), |
955 |
(int) w, h, null); |
956 |
currentBPPosition += (h * 1000); // TODO doesn't work! |
957 |
} |
958 |
} |
959 |
|
960 |
/** |
961 |
* @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, |
962 |
* Rectangle2D) |
963 |
*/ |
964 |
public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { |
965 |
endTextObject(); |
966 |
Document doc = fo.getDocument(); |
967 |
String ns = fo.getNameSpace(); |
968 |
if (ns.equals("http://www.w3.org/2000/svg")) { |
969 |
// FIXME ren: is this the right way to do it? |
970 |
renderSVGDocument(doc, pos); |
971 |
} else { |
972 |
renderDocument(doc, ns, pos); |
973 |
} |
974 |
// this.currentXPosition += area.getContentWidth(); TODO |
975 |
} |
976 |
|
977 |
/** |
978 |
* Renders an XML document (SVG for example). |
979 |
* |
980 |
* @param doc DOM document representing the XML document |
981 |
* @param ns Namespace for the document |
982 |
* @param pos Position on the page |
983 |
*/ |
984 |
public void renderDocument(Document doc, String ns, Rectangle2D pos) { |
985 |
RendererContext context; |
986 |
context = new RendererContext(MIME_TYPE); |
987 |
context.setUserAgent(userAgent); |
988 |
// TODO implement |
989 |
/* |
990 |
* context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc); |
991 |
* context.setProperty(PDFXMLHandler.OUTPUT_STREAM, ostream); |
992 |
* context.setProperty(PDFXMLHandler.PDF_STATE, currentState); |
993 |
* context.setProperty(PDFXMLHandler.PDF_PAGE, currentPage); |
994 |
* context.setProperty(PDFXMLHandler.PDF_CONTEXT, currentContext == null ? |
995 |
* currentPage : currentContext); |
996 |
* context.setProperty(PDFXMLHandler.PDF_CONTEXT, currentContext); |
997 |
* context.setProperty(PDFXMLHandler.PDF_STREAM, currentStream); |
998 |
* context.setProperty(PDFXMLHandler.PDF_XPOS, new |
999 |
* Integer(currentIPPosition + (int) pos.getX())); |
1000 |
* context.setProperty(PDFXMLHandler.PDF_YPOS, new |
1001 |
* Integer(currentBPPosition + (int) pos.getY())); |
1002 |
* context.setProperty(PDFXMLHandler.PDF_FONT_INFO, fontInfo); |
1003 |
* context.setProperty(PDFXMLHandler.PDF_FONT_NAME, currentFontName); |
1004 |
* context.setProperty(PDFXMLHandler.PDF_FONT_SIZE, new |
1005 |
* Integer(currentFontSize)); |
1006 |
* context.setProperty(PDFXMLHandler.PDF_WIDTH, new Integer((int) |
1007 |
* pos.getWidth())); context.setProperty(PDFXMLHandler.PDF_HEIGHT, new |
1008 |
* Integer((int) pos.getHeight())); renderXML(userAgent, context, doc, |
1009 |
* ns); |
1010 |
*/ |
1011 |
} |
1012 |
|
1013 |
protected void renderSVGDocument(Document doc, Rectangle2D pos) { |
1014 |
|
1015 |
int x = currentIPPosition; // TODO + area.getXOffset(); |
1016 |
int y = currentBPPosition; |
1017 |
|
1018 |
RendererContext context; |
1019 |
context = new RendererContext(MIME_TYPE); |
1020 |
context.setUserAgent(userAgent); |
1021 |
|
1022 |
SVGUserAgent ua = new SVGUserAgent(context.getUserAgent() |
1023 |
.getPixelUnitToMillimeter(), new AffineTransform()); |
1024 |
|
1025 |
GVTBuilder builder = new GVTBuilder(); |
1026 |
BridgeContext ctx = new BridgeContext(ua); |
1027 |
|
1028 |
GraphicsNode root; |
1029 |
try { |
1030 |
root = builder.build(ctx, doc); |
1031 |
} catch (Exception e) { |
1032 |
getLogger().error( |
1033 |
"svg graphic could not be built: " + e.getMessage(), e); |
1034 |
return; |
1035 |
} |
1036 |
float w = (float) ctx.getDocumentSize().getWidth() * 1000f; |
1037 |
float h = (float) ctx.getDocumentSize().getHeight() * 1000f; |
1038 |
|
1039 |
// correct integer roundoff TODO ren: needed? |
1040 |
graphics.translate(x / 1000, y / 1000); |
1041 |
|
1042 |
SVGSVGElement svg = ((SVGDocument) doc).getRootElement(); |
1043 |
// TODO ren: do we need the whole at-stuff? |
1044 |
AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, |
1045 |
w / 1000f, h / 1000f); |
1046 |
AffineTransform inverse = null; |
1047 |
try { |
1048 |
inverse = at.createInverse(); |
1049 |
} catch (NoninvertibleTransformException e) { |
1050 |
} |
1051 |
if (!at.isIdentity()) { |
1052 |
graphics.transform(at); |
1053 |
} |
1054 |
|
1055 |
try { |
1056 |
root.paint(graphics); |
1057 |
} catch (Exception e) { |
1058 |
e.printStackTrace(); |
1059 |
} |
1060 |
|
1061 |
if (inverse != null && !inverse.isIdentity()) { |
1062 |
graphics.transform(inverse); |
1063 |
} |
1064 |
// correct integer roundoff TODO ren: needed? |
1065 |
// graphics.translate(-x / 1000f, y / 1000f - pageHeight); |
1066 |
graphics.translate(-(x + 500) / 1000, (y + 500) / 1000 - pageHeight); |
1067 |
} |
470 |
} |
1068 |
} |