View | Details | Raw Unified | Return to bug 33760
Collapse All | Expand All

(-)src/java/org/apache/fop/area/CTM.java (+14 lines)
Lines 310-314 Link Here
310
        // Now transform for writing mode
310
        // Now transform for writing mode
311
        return ctm.multiply(CTM.getWMctm(writingMode, reldims.ipd, reldims.bpd));
311
        return ctm.multiply(CTM.getWMctm(writingMode, reldims.ipd, reldims.bpd));
312
    }
312
    }
313
    
314
    
315
    /**gets the x shift of this CTM
316
     * @return the x shift as a double 
317
     */
318
    public double getXShift(){
319
    	return this.e;
320
    }
313
321
322
    /**gets the y shift of this CTM
323
     * @return the y shift as a double 
324
     */
325
    public double getYShift(){
326
    	return this.f;
327
    }
314
}
328
}
(-)src/java/org/apache/fop/render/AbstractRenderer.java (-15 / +121 lines)
Lines 59-65 Link Here
59
import org.apache.fop.area.inline.TextArea;
59
import org.apache.fop.area.inline.TextArea;
60
import org.apache.fop.area.inline.Character;
60
import org.apache.fop.area.inline.Character;
61
import org.apache.fop.apps.FOUserAgent;
61
import org.apache.fop.apps.FOUserAgent;
62
import org.apache.fop.datatypes.ColorType;
62
import org.apache.fop.fo.Constants;
63
import org.apache.fop.fo.Constants;
64
import org.apache.fop.fonts.Font;
63
import org.apache.fop.fonts.FontInfo;
65
import org.apache.fop.fonts.FontInfo;
64
import org.apache.commons.logging.Log;
66
import org.apache.commons.logging.Log;
65
import org.apache.commons.logging.LogFactory;
67
import org.apache.commons.logging.LogFactory;
Lines 109-114 Link Here
109
     */
111
     */
110
    protected int containingIPPosition = 0;
112
    protected int containingIPPosition = 0;
111
113
114
    /** Name of currently selected font */
115
    protected String currentFontName = "";
116
112
    /**
117
    /**
113
     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
118
     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
114
     */
119
     */
Lines 255-264 Link Here
255
            Rectangle2D view = port.getViewArea();
260
            Rectangle2D view = port.getViewArea();
256
            // The CTM will transform coordinates relative to
261
            // The CTM will transform coordinates relative to
257
            // this region-reference area into page coords, so
262
            // this region-reference area into page coords, so
258
            // set origin for the region to 0,0.
263
            // set origin for the region to 0,0. 
259
            currentBPPosition = 0;
264
            //currentBPPosition = 0; 
260
            currentIPPosition = 0;
265
            //currentIPPosition = 0; 
261
266
            //FIXME containingXXXPosition is reseted in startVParea();
267
            
262
            RegionReference region = port.getRegion();
268
            RegionReference region = port.getRegion();
263
            handleRegionTraits(port);
269
            handleRegionTraits(port);
264
270
Lines 266-272 Link Here
266
            startVParea(region.getCTM());
272
            startVParea(region.getCTM());
267
            // do after starting viewport area
273
            // do after starting viewport area
268
            if (region.getRegionClass() == FO_REGION_BODY) {
274
            if (region.getRegionClass() == FO_REGION_BODY) {
269
                renderBodyRegion((BodyRegion) region);
275
                renderBodyRegion((BodyRegion) region); 
270
            } else {
276
            } else {
271
                renderRegion(region);
277
                renderRegion(region);
272
            }
278
            }
Lines 275-285 Link Here
275
    }
281
    }
276
282
277
    /**
283
    /**
284
	 * The CTM will transform coordinates relative to this 
285
	 * region-reference area into page coords
286
	 * 
287
	 * @param ctm The coordinate transformation matrix to use
288
	 */
289
	protected void startVParea(CTM ctm) { }
290
291
    /**
278
     * (todo) Description of the Method
292
     * (todo) Description of the Method
279
     *
280
     * @param ctm  The coordinate transformation matrix to use
281
     */
293
     */
282
    protected void startVParea(CTM ctm) { }
294
    protected void endVParea() { }
283
295
284
    /**
296
    /**
285
     * Handle the traits for a region
297
     * Handle the traits for a region
Lines 287-300 Link Here
287
     * (See Sect. 6.4.1.2 of XSL-FO spec.)
299
     * (See Sect. 6.4.1.2 of XSL-FO spec.)
288
     * @param rv the RegionViewport whose region is to be drawn
300
     * @param rv the RegionViewport whose region is to be drawn
289
     */
301
     */
290
    protected void handleRegionTraits(RegionViewport rv) {
302
    protected void handleRegionTraits(RegionViewport region) {
291
        // draw border and background
303
304
        currentFontName = ""; // TODO why here?
305
        Rectangle2D viewArea = region.getViewArea();
306
        float startx = (float) (viewArea.getX() / 1000f);
307
        float starty = (float) (viewArea.getY() / 1000f);
308
        float width = (float) (viewArea.getWidth() / 1000f);
309
        float height = (float) (viewArea.getHeight() / 1000f);
310
311
        if (region.getRegion().getRegionClass() == FO_REGION_BODY) {
312
            currentBPPosition = region.getBorderAndPaddingWidthBefore();
313
            currentIPPosition = region.getBorderAndPaddingWidthStart();
314
        }
315
        drawBackAndBorders(region, startx, starty, width, height);
292
    }
316
    }
293
317
294
    /**
318
    /**
295
     * (todo) Description of the Method
319
     * Draw the background and borders. This draws the background and border
320
     * traits for an area given the position.
321
     * 
322
     * @param block the area to get the traits from
323
     * @param startx the start x position
324
     * @param starty the start y position
325
     * @param width the width of the area
326
     * @param height the height of the area
296
     */
327
     */
297
    protected void endVParea() { }
328
 protected void drawBackAndBorders(RegionViewport region, float startx,
329
            float starty, float width, float height) {
330
    }
298
331
299
    /**
332
    /**
300
     * Renders a region reference area.
333
     * Renders a region reference area.
Lines 429-436 Link Here
429
            int saveBP = currentBPPosition;
462
            int saveBP = currentBPPosition;
430
463
431
            CTM ctm = bv.getCTM();
464
            CTM ctm = bv.getCTM();
432
            currentIPPosition = 0;
465
            //currentIPPosition = 0;
433
            currentBPPosition = 0;
466
            //currentBPPosition = 0;
434
467
435
            startVParea(ctm);
468
            startVParea(ctm);
436
            handleBlockTraits(bv);
469
            handleBlockTraits(bv);
Lines 559-566 Link Here
559
    protected void renderTextDecoration(InlineArea area) {
592
    protected void renderTextDecoration(InlineArea area) {
560
        //getLogger().debug("renderTextDecoration for " + area + " -> " + area.getTrait(Trait.UNDERLINE));
593
        //getLogger().debug("renderTextDecoration for " + area + " -> " + area.getTrait(Trait.UNDERLINE));
561
    }
594
    }
595
    
596
    /**
597
     * Paints the text decoration marks.
598
     * @param fs Current font
599
     * @param inline inline area to paint the marks for
600
     * @param baseline position of the baseline
601
     * @param startx start IPD
602
     */
603
    protected void renderTextDecoration(Font fs, InlineArea inline, 
604
                    int baseline, int startx) {
605
        boolean hasTextDeco = inline.hasUnderline() 
606
                || inline.hasOverline() 
607
                || inline.hasLineThrough();
608
        if (hasTextDeco) {
609
            endTextObject();
610
            updateLineStyle(Constants.EN_SOLID);
611
            updateLineWidth(fs.getDescender() / -8 / 1000f);
612
            float endx = (startx + inline.getIPD()) / 1000f;
613
            if (inline.hasUnderline()) {
614
                ColorType ct = (ColorType) inline.getTrait(Trait.UNDERLINE_COLOR);
615
                updateColor(ct, false, null);
616
                float y = baseline - fs.getDescender() / 2;
617
                drawLine(startx / 1000f, y / 1000f, endx, y / 1000f);
618
            }
619
            if (inline.hasOverline()) {
620
                ColorType ct = (ColorType) inline.getTrait(Trait.OVERLINE_COLOR);
621
                updateColor(ct, false, null);
622
                float y = (float)(baseline - (1.1 * fs.getCapHeight()));
623
                drawLine(startx / 1000f, y / 1000f, endx, y / 1000f);
624
            }
625
            if (inline.hasLineThrough()) {
626
                ColorType ct = (ColorType) inline.getTrait(Trait.LINETHROUGH_COLOR);
627
                updateColor(ct, false, null);
628
                float y = (float)(baseline - (0.45 * fs.getCapHeight()));
629
                drawLine(startx / 1000f, y / 1000f, endx, y / 1000f);
630
            }  
631
        }
632
    }
562
633
563
    /**
634
    /**
635
     * Sets the current line style. The line width should be 
636
     * set with updateLineWidth() before calling this method
637
     * @param style the constant for the style of the line as an int
638
     */
639
    protected void updateLineStyle(int style) {}
640
641
    /** Indicates the end of a text object. */
642
	protected void endTextObject() { }
643
644
	/**
645
     * Sets the current line width in points.
646
     * @param width line width in points
647
     */
648
	protected void updateLineWidth(float width) {}
649
650
	  /**
651
     * Draw a line. 
652
     *
653
     * @param startx the start x position
654
     * @param starty the start y position
655
     * @param endx the x end position
656
     * @param endy the y end position
657
     */
658
	protected void drawLine(float startx, float starty, float endx, float endy) { }
659
660
	 /**
661
     * Establishes a new foreground or fill color.
662
     * @param col the color to apply (null skips this operation)
663
     * @param fill true to set the fill color, false for the foreground color
664
     * @param pdf StringBuffer to write the PDF code to, if null, the code is
665
     *     written to the current stream.
666
     */
667
    protected void updateColor(ColorType col, boolean fill, StringBuffer pdf) { }
668
669
	/**
564
     * Renders a line area. <p>
670
     * Renders a line area. <p>
565
     *
671
     *
566
     * A line area may have grouped styling for its children such as underline,
672
     * A line area may have grouped styling for its children such as underline,
Lines 629-635 Link Here
629
        currentIPPosition = saveIP + ip.getAllocIPD();
735
        currentIPPosition = saveIP + ip.getAllocIPD();
630
    }
736
    }
631
737
632
    /** @see org.apache.fop.render.Renderer */
738
    /** @see org.apache.fop.render.Renderer */  //TODO nothing to see there
633
    protected void renderViewport(Viewport viewport) {
739
    protected void renderViewport(Viewport viewport) {
634
        Area content = viewport.getContent();
740
        Area content = viewport.getContent();
635
        int saveBP = currentBPPosition;
741
        int saveBP = currentBPPosition;
(-)src/java/org/apache/fop/render/awt/AWTRenderer.java (-172 / +770 lines)
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
}
(-)src/java/org/apache/fop/render/pdf/PDFRenderer.java (-91 / +25 lines)
Lines 19-67 Link Here
19
package org.apache.fop.render.pdf;
19
package org.apache.fop.render.pdf;
20
20
21
// Java
21
// Java
22
import java.io.IOException;
23
import java.io.OutputStream;
24
import java.awt.Color;
22
import java.awt.Color;
25
import java.awt.geom.Rectangle2D;
26
import java.awt.geom.AffineTransform;
23
import java.awt.geom.AffineTransform;
24
import java.awt.geom.Rectangle2D;
25
import java.io.IOException;
26
import java.io.OutputStream;
27
import java.util.Iterator;
27
import java.util.Iterator;
28
import java.util.Map;
29
import java.util.List;
28
import java.util.List;
29
import java.util.Map;
30
30
31
// XML
32
import org.w3c.dom.Document;
33
34
// Avalon
35
import org.apache.avalon.framework.configuration.Configuration;
31
import org.apache.avalon.framework.configuration.Configuration;
36
import org.apache.avalon.framework.configuration.ConfigurationException;
32
import org.apache.avalon.framework.configuration.ConfigurationException;
37
38
// FOP
39
import org.apache.fop.apps.FOPException;
33
import org.apache.fop.apps.FOPException;
40
import org.apache.fop.apps.FOUserAgent;
34
import org.apache.fop.apps.FOUserAgent;
41
import org.apache.fop.area.Area;
35
import org.apache.fop.area.Area;
42
import org.apache.fop.area.Block;
36
import org.apache.fop.area.Block;
43
import org.apache.fop.area.BlockViewport;
37
import org.apache.fop.area.BlockViewport;
38
import org.apache.fop.area.BookmarkData;
44
import org.apache.fop.area.CTM;
39
import org.apache.fop.area.CTM;
45
import org.apache.fop.area.LineArea;
40
import org.apache.fop.area.LineArea;
41
import org.apache.fop.area.OffDocumentItem;
46
import org.apache.fop.area.Page;
42
import org.apache.fop.area.Page;
47
import org.apache.fop.area.PageViewport;
43
import org.apache.fop.area.PageViewport;
48
import org.apache.fop.area.RegionViewport;
49
import org.apache.fop.area.Trait;
44
import org.apache.fop.area.Trait;
50
import org.apache.fop.area.OffDocumentItem;
51
import org.apache.fop.area.BookmarkData;
52
import org.apache.fop.area.inline.Character;
45
import org.apache.fop.area.inline.Character;
53
import org.apache.fop.area.inline.InlineArea;
54
import org.apache.fop.area.inline.TextArea;
55
import org.apache.fop.area.inline.Viewport;
56
import org.apache.fop.area.inline.ForeignObject;
46
import org.apache.fop.area.inline.ForeignObject;
57
import org.apache.fop.area.inline.Image;
47
import org.apache.fop.area.inline.Image;
58
import org.apache.fop.area.inline.Leader;
59
import org.apache.fop.area.inline.InlineParent;
48
import org.apache.fop.area.inline.InlineParent;
49
import org.apache.fop.area.inline.Leader;
50
import org.apache.fop.area.inline.TextArea;
51
import org.apache.fop.area.inline.Viewport;
60
import org.apache.fop.datatypes.ColorType;
52
import org.apache.fop.datatypes.ColorType;
61
import org.apache.fop.fonts.Typeface;
53
import org.apache.fop.fo.Constants;
62
import org.apache.fop.fonts.Font;
54
import org.apache.fop.fonts.Font;
63
import org.apache.fop.fonts.FontSetup;
64
import org.apache.fop.fonts.FontMetrics;
55
import org.apache.fop.fonts.FontMetrics;
56
import org.apache.fop.fonts.FontSetup;
57
import org.apache.fop.fonts.Typeface;
65
import org.apache.fop.image.FopImage;
58
import org.apache.fop.image.FopImage;
66
import org.apache.fop.image.ImageFactory;
59
import org.apache.fop.image.ImageFactory;
67
import org.apache.fop.image.XMLImage;
60
import org.apache.fop.image.XMLImage;
Lines 83-89 Link Here
83
import org.apache.fop.render.PrintRenderer;
76
import org.apache.fop.render.PrintRenderer;
84
import org.apache.fop.render.RendererContext;
77
import org.apache.fop.render.RendererContext;
85
import org.apache.fop.traits.BorderProps;
78
import org.apache.fop.traits.BorderProps;
86
import org.apache.fop.fo.Constants;
79
import org.w3c.dom.Document;
87
80
88
81
89
/*
82
/*
Lines 162-169 Link Here
162
    /** drawing state */
155
    /** drawing state */
163
    protected PDFState currentState = null;
156
    protected PDFState currentState = null;
164
157
165
    /** Name of currently selected font */
166
    protected String currentFontName = "";
167
    /** Size of currently selected font */
158
    /** Size of currently selected font */
168
    protected int currentFontSize = 0;
159
    protected int currentFontSize = 0;
169
    /** page height */
160
    /** page height */
Lines 484-489 Link Here
484
     * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM)
475
     * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM)
485
     */
476
     */
486
    protected void startVParea(CTM ctm) {
477
    protected void startVParea(CTM ctm) {
478
        // The CTM will transform coordinates relative to
479
        // this region-reference area into page coords, so
480
        // set origin for the region to 0,0. 
481
    	currentIPPosition = 0;
482
        currentBPPosition = 0;
483
    	
487
        // Set the given CTM in the graphics state
484
        // Set the given CTM in the graphics state
488
        currentState.push();
485
        currentState.push();
489
        currentState.setTransform(
486
        currentState.setTransform(
Lines 503-529 Link Here
503
        currentState.pop();
500
        currentState.pop();
504
    }
501
    }
505
502
506
    /**
503
 
507
     * Handle the traits for a region
508
     * This is used to draw the traits for the given page region.
509
     * (See Sect. 6.4.1.2 of XSL-FO spec.)
510
     * @param region the RegionViewport whose region is to be drawn
511
     */
512
    protected void handleRegionTraits(RegionViewport region) {
513
        currentFontName = "";
514
        Rectangle2D viewArea = region.getViewArea();
515
        float startx = (float)(viewArea.getX() / 1000f);
516
        float starty = (float)(viewArea.getY() / 1000f);
517
        float width = (float)(viewArea.getWidth() / 1000f);
518
        float height = (float)(viewArea.getHeight() / 1000f);
519
520
        if (region.getRegion().getRegionClass() == FO_REGION_BODY) {
521
            currentBPPosition = region.getBorderAndPaddingWidthBefore();
522
            currentIPPosition = region.getBorderAndPaddingWidthStart();
523
        }
524
        drawBackAndBorders(region, startx, starty, width, height);
525
    }
526
527
    /**
504
    /**
528
     * Handle block traits.
505
     * Handle block traits.
529
     * The block could be any sort of block with any positioning
506
     * The block could be any sort of block with any positioning
Lines 985-998 Link Here
985
     * Sets the current line width in points.
962
     * Sets the current line width in points.
986
     * @param width line width in points
963
     * @param width line width in points
987
     */
964
     */
988
    private void updateLineWidth(float width) {
965
    protected void updateLineWidth(float width) {
989
        if (currentState.setLineWidth(width)) {
966
        if (currentState.setLineWidth(width)) {
990
            //Only write if value has changed WRT the current line width
967
            //Only write if value has changed WRT the current line width
991
            currentStream.add(width + " w\n");
968
            currentStream.add(width + " w\n");
992
        }
969
        }
993
    }
970
    }
994
    
971
    
995
    private void updateLineStyle(int style) {
972
    protected void updateLineStyle(int style) {
996
        switch (style) {
973
        switch (style) {
997
            case Constants.EN_DASHED:
974
            case Constants.EN_DASHED:
998
                currentStream.add("[3] 0 d\n");
975
                currentStream.add("[3] 0 d\n");
Lines 1042-1048 Link Here
1042
     * @param endx the x end position
1019
     * @param endx the x end position
1043
     * @param endy the y end position
1020
     * @param endy the y end position
1044
     */
1021
     */
1045
    private void drawLine(float startx, float starty, float endx, float endy) {
1022
    protected void drawLine(float startx, float starty, float endx, float endy) {
1046
        currentStream.add(startx + " " + starty + " m ");
1023
        currentStream.add(startx + " " + starty + " m ");
1047
        currentStream.add(endx + " " + endy + " l S\n");
1024
        currentStream.add(endx + " " + endy + " l S\n");
1048
    }
1025
    }
Lines 1123-1131 Link Here
1123
1100
1124
            startVParea(ctm);
1101
            startVParea(ctm);
1125
1102
1126
            currentIPPosition = 0;
1127
            currentBPPosition = 0;
1128
1129
            renderBlocks(bv, children);
1103
            renderBlocks(bv, children);
1130
            endVParea();
1104
            endVParea();
1131
1105
Lines 1192-1199 Link Here
1192
1166
1193
            if (ctm != null) {
1167
            if (ctm != null) {
1194
                startVParea(ctm);
1168
                startVParea(ctm);
1195
                currentIPPosition = 0;
1196
                currentBPPosition = 0;
1197
            }
1169
            }
1198
            renderBlocks(bv, children);
1170
            renderBlocks(bv, children);
1199
            if (ctm != null) {
1171
            if (ctm != null) {
Lines 1429-1435 Link Here
1429
        prevWordX = rx;
1401
        prevWordX = rx;
1430
1402
1431
        String s = text.getTextArea();
1403
        String s = text.getTextArea();
1432
1404
        System.out.println(s+" currXPos "+rx+" currYPos "+bl);
1433
        FontMetrics metrics = fontInfo.getMetricsFor(name);
1405
        FontMetrics metrics = fontInfo.getMetricsFor(name);
1434
        Font fs = new Font(name, metrics, size);
1406
        Font fs = new Font(name, metrics, size);
1435
        escapeText(s, fs, useMultiByte, pdf);
1407
        escapeText(s, fs, useMultiByte, pdf);
Lines 1441-1484 Link Here
1441
        
1413
        
1442
        super.renderText(text);
1414
        super.renderText(text);
1443
    }
1415
    }
1444
    
1445
    /**
1446
     * Paints the text decoration marks.
1447
     * @param fs Current font
1448
     * @param inline inline area to paint the marks for
1449
     * @param baseline position of the baseline
1450
     * @param startx start IPD
1451
     */
1452
    protected void renderTextDecoration(Font fs, InlineArea inline, 
1453
                    int baseline, int startx) {
1454
        boolean hasTextDeco = inline.hasUnderline() 
1455
                || inline.hasOverline() 
1456
                || inline.hasLineThrough();
1457
        if (hasTextDeco) {
1458
            endTextObject();
1459
            updateLineStyle(Constants.EN_SOLID);
1460
            updateLineWidth(fs.getDescender() / -8 / 1000f);
1461
            float endx = (startx + inline.getIPD()) / 1000f;
1462
            if (inline.hasUnderline()) {
1463
                ColorType ct = (ColorType) inline.getTrait(Trait.UNDERLINE_COLOR);
1464
                updateColor(ct, false, null);
1465
                float y = baseline - fs.getDescender() / 2;
1466
                drawLine(startx / 1000f, y / 1000f, endx, y / 1000f);
1467
            }
1468
            if (inline.hasOverline()) {
1469
                ColorType ct = (ColorType) inline.getTrait(Trait.OVERLINE_COLOR);
1470
                updateColor(ct, false, null);
1471
                float y = (float)(baseline - (1.1 * fs.getCapHeight()));
1472
                drawLine(startx / 1000f, y / 1000f, endx, y / 1000f);
1473
            }
1474
            if (inline.hasLineThrough()) {
1475
                ColorType ct = (ColorType) inline.getTrait(Trait.LINETHROUGH_COLOR);
1476
                updateColor(ct, false, null);
1477
                float y = (float)(baseline - (0.45 * fs.getCapHeight()));
1478
                drawLine(startx / 1000f, y / 1000f, endx, y / 1000f);
1479
            }
1480
        }
1481
    }
1482
1416
1483
    /**
1417
    /**
1484
     * Escapes text according to PDF rules.
1418
     * Escapes text according to PDF rules.
Lines 1592-1598 Link Here
1592
     * @param pdf StringBuffer to write the PDF code to, if null, the code is
1526
     * @param pdf StringBuffer to write the PDF code to, if null, the code is
1593
     *     written to the current stream.
1527
     *     written to the current stream.
1594
     */
1528
     */
1595
    private void updateColor(ColorType col, boolean fill, StringBuffer pdf) {
1529
    protected void updateColor(ColorType col, boolean fill, StringBuffer pdf) {
1596
        if (col == null) {
1530
        if (col == null) {
1597
            return;
1531
            return;
1598
        }
1532
        }
(-)src/java/org/apache/fop/render/ps/PSRenderer.java (-33 / +12 lines)
Lines 24-35 Link Here
24
import java.io.OutputStream;
24
import java.io.OutputStream;
25
import java.util.List;
25
import java.util.List;
26
26
27
// FOP
28
import org.apache.avalon.framework.configuration.Configuration;
27
import org.apache.avalon.framework.configuration.Configuration;
29
import org.apache.avalon.framework.configuration.ConfigurationException;
28
import org.apache.avalon.framework.configuration.ConfigurationException;
30
import org.apache.fop.area.Area;
31
import org.apache.fop.area.RegionViewport;
32
import org.apache.fop.apps.FOPException;
29
import org.apache.fop.apps.FOPException;
30
import org.apache.fop.apps.FOUserAgent;
31
import org.apache.fop.area.Area;
33
import org.apache.fop.area.Block;
32
import org.apache.fop.area.Block;
34
import org.apache.fop.area.BlockViewport;
33
import org.apache.fop.area.BlockViewport;
35
import org.apache.fop.area.CTM;
34
import org.apache.fop.area.CTM;
Lines 38-53 Link Here
38
import org.apache.fop.area.inline.ForeignObject;
37
import org.apache.fop.area.inline.ForeignObject;
39
import org.apache.fop.area.inline.TextArea;
38
import org.apache.fop.area.inline.TextArea;
40
import org.apache.fop.datatypes.ColorType;
39
import org.apache.fop.datatypes.ColorType;
41
import org.apache.fop.apps.FOUserAgent;
42
import org.apache.fop.fonts.FontSetup;
40
import org.apache.fop.fonts.FontSetup;
43
import org.apache.fop.fonts.Typeface;
41
import org.apache.fop.fonts.Typeface;
44
import org.apache.fop.render.PrintRenderer;
45
import org.apache.fop.render.RendererContext;
46
47
import org.apache.fop.image.FopImage;
42
import org.apache.fop.image.FopImage;
48
import org.apache.fop.image.ImageFactory;
43
import org.apache.fop.image.ImageFactory;
44
import org.apache.fop.render.PrintRenderer;
45
import org.apache.fop.render.RendererContext;
49
import org.apache.fop.traits.BorderProps;
46
import org.apache.fop.traits.BorderProps;
50
51
import org.w3c.dom.Document;
47
import org.w3c.dom.Document;
52
48
53
/**
49
/**
Lines 507-515 Link Here
507
503
508
        if (bv.getPositioning() == Block.ABSOLUTE) {
504
        if (bv.getPositioning() == Block.ABSOLUTE) {
509
505
510
            currentIPPosition = 0;
511
            currentBPPosition = 0;
512
513
            //closeText();
506
            //closeText();
514
            endTextObject();
507
            endTextObject();
515
508
Lines 603-608 Link Here
603
     * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM)
596
     * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM)
604
     */
597
     */
605
    protected void startVParea(CTM ctm) {
598
    protected void startVParea(CTM ctm) {
599
        // The CTM will transform coordinates relative to
600
        // this region-reference area into page coords, so
601
        // set origin for the region to 0,0. 
602
        currentIPPosition = 0;
603
        currentBPPosition = 0;
604
606
        // Set the given CTM in the graphics state
605
        // Set the given CTM in the graphics state
607
        //currentState.push();
606
        //currentState.push();
608
        //currentState.setTransform(new AffineTransform(CTMHelper.toPDFArray(ctm)));
607
        //currentState.setTransform(new AffineTransform(CTMHelper.toPDFArray(ctm)));
Lines 625-651 Link Here
625
        restoreGraphicsState();
624
        restoreGraphicsState();
626
        //currentState.pop();
625
        //currentState.pop();
627
    }
626
    }
628
627
  
629
    /**
630
     * Handle the traits for a region
631
     * This is used to draw the traits for the given page region.
632
     * (See Sect. 6.4.1.2 of XSL-FO spec.)
633
     * @param region the RegionViewport whose region is to be drawn
634
     */
635
    protected void handleRegionTraits(RegionViewport region) {
636
        currentFontName = "";
637
        float startx = 0;
638
        float starty = 0;
639
        Rectangle2D viewArea = region.getViewArea();
640
        float width = (float)(viewArea.getWidth());
641
        float height = (float)(viewArea.getHeight());
642
        /*
643
        Trait.Background back;
644
        back = (Trait.Background)region.getTrait(Trait.BACKGROUND);
645
        */
646
        drawBackAndBorders(region, startx, starty, width, height);
647
    }
648
649
    /**
628
    /**
650
     * Handle block traits.
629
     * Handle block traits.
651
     * The block could be any sort of block with any positioning
630
     * The block could be any sort of block with any positioning
Lines 793-799 Link Here
793
     * @param endx the x end position
772
     * @param endx the x end position
794
     * @param endy the y end position
773
     * @param endy the y end position
795
     */
774
     */
796
    private void drawLine(float startx, float starty, float endx, float endy) {
775
    protected void drawLine(float startx, float starty, float endx, float endy) {
797
        writeln(startx + " " + starty + " M ");
776
        writeln(startx + " " + starty + " M ");
798
        writeln(endx + " " + endy + " lineto");
777
        writeln(endx + " " + endy + " lineto");
799
    }
778
    }
(-)src/java/org/apache/fop/render/awt/BMPReader.java (+185 lines)
Added Link Here
1
package org.apache.fop.render.awt;
2
3
import java.awt.Component;
4
import java.awt.Container;
5
import java.awt.Image;
6
import java.awt.image.MemoryImageSource;
7
import java.io.BufferedInputStream;
8
import java.io.FileInputStream;
9
import java.io.IOException;
10
11
import org.apache.commons.logging.Log;
12
import org.apache.commons.logging.LogFactory;
13
import org.apache.fop.apps.FOPException;
14
15
/**
16
 * Class used to load windows bitmap images (.bmp)
17
 * 
18
 * see http://www.javaworld.com/javaworld/javatips/jw-javatip43.html
19
 * 
20
 */
21
public class BMPReader {
22
23
    /** logging instance */
24
    protected static Log logger = LogFactory.getLog("org.apache.fop.render");
25
26
    private Image image;
27
28
    private BufferedInputStream bs;
29
30
    /**
31
     * Loads a Bitmap from an url pointing to a .bmp-file. Reads only
32
     * uncompressed 24- and 8-bit images.
33
     * 
34
     * @param url
35
     *            the url of the bitmap
36
     * @return Image the bitmap as an awt.Image
37
     * @throws IOException
38
     *             if the url cannot be read
39
     * @throws FOPException
40
     *             if the image is not a 24- or 8-bit image or if it is
41
     *             compressed
42
     */
43
    public Image loadbitmap(String url) throws IOException, FOPException {
44
45
        bs = new BufferedInputStream(new FileInputStream(url));
46
        int bflen = 14; // 14 byte BITMAPFILEHEADER
47
        byte bf[] = new byte[bflen];
48
        bs.read(bf, 0, bflen);
49
        int bilen = 40; // 40-byte BITMAPINFOHEADER
50
        byte bi[] = new byte[bilen];
51
        bs.read(bi, 0, bilen);
52
53
        // Interperet data.
54
        int nsize = (((int) bf[5] & 0xff) << 24) | (((int) bf[4] & 0xff) << 16)
55
                | (((int) bf[3] & 0xff) << 8) | (int) bf[2] & 0xff;
56
        int nbisize = (((int) bi[3] & 0xff) << 24)
57
                | (((int) bi[2] & 0xff) << 16) | (((int) bi[1] & 0xff) << 8)
58
                | (int) bi[0] & 0xff;
59
        int nwidth = (((int) bi[7] & 0xff) << 24)
60
                | (((int) bi[6] & 0xff) << 16) | (((int) bi[5] & 0xff) << 8)
61
                | (int) bi[4] & 0xff;
62
        int nheight = (((int) bi[11] & 0xff) << 24)
63
                | (((int) bi[10] & 0xff) << 16) | (((int) bi[9] & 0xff) << 8)
64
                | (int) bi[8] & 0xff;
65
        int nplanes = (((int) bi[13] & 0xff) << 8) | (int) bi[12] & 0xff;
66
        int nbitcount = (((int) bi[15] & 0xff) << 8) | (int) bi[14] & 0xff;
67
68
        // Look for non-zero values to indicate compression
69
        int ncompression = (((int) bi[19]) << 24) | (((int) bi[18]) << 16)
70
                | (((int) bi[17]) << 8) | (int) bi[16];
71
        if (ncompression != 0) {
72
            bs.close();
73
            throw new FOPException("Bitmap" + url + "could not be rendered. "
74
                    + "FOP only supports non-compressed Windows Bitmap");
75
        }
76
        int nsizeimage = (((int) bi[23] & 0xff) << 24)
77
                | (((int) bi[22] & 0xff) << 16) | (((int) bi[21] & 0xff) << 8)
78
                | (int) bi[20] & 0xff;
79
        int nxpm = (((int) bi[27] & 0xff) << 24)
80
                | (((int) bi[26] & 0xff) << 16) | (((int) bi[25] & 0xff) << 8)
81
                | (int) bi[24] & 0xff;
82
        int nypm = (((int) bi[31] & 0xff) << 24)
83
                | (((int) bi[30] & 0xff) << 16) | (((int) bi[29] & 0xff) << 8)
84
                | (int) bi[28] & 0xff;
85
        int nclrused = (((int) bi[35] & 0xff) << 24)
86
                | (((int) bi[34] & 0xff) << 16) | (((int) bi[33] & 0xff) << 8)
87
                | (int) bi[32] & 0xff;
88
        int nclrimp = (((int) bi[39] & 0xff) << 24)
89
                | (((int) bi[38] & 0xff) << 16) | (((int) bi[37] & 0xff) << 8)
90
                | (int) bi[36] & 0xff;
91
92
        logger.debug("Rendering Bitmap" + url + "Colors important are :"
93
                + nclrimp + "File type is :" + (char) bf[0] + (char) bf[1]
94
                + "Size of file is :" + nsize + "Size of bitmapinfoheader is :"
95
                + nbisize + "Width is :" + nwidth + "Height is :" + nheight
96
                + "Planes is :" + nplanes + "BitCount is :" + nbitcount
97
                + "Compression is :" + ncompression + "SizeImage is :"
98
                + nsizeimage + "X-Pixels per meter is :" + nxpm
99
                + "Y-Pixels per meter is :" + nypm + "Colors used are :"
100
                + nclrused);
101
102
        if (nbitcount == 24) {
103
            // No Palatte data for 24-bit format but scan lines are
104
            // padded out to even 4-byte boundaries.
105
            int npad = (nsizeimage / nheight) - nwidth * 3;
106
            if (npad == 4)
107
                npad = 0; // corrected
108
            int ndata[] = new int[nheight * nwidth];
109
            byte brgb[] = new byte[(nwidth + npad) * 3 * nheight];
110
            bs.read(brgb, 0, (nwidth + npad) * 3 * nheight);
111
            int nindex = 0;
112
            for (int j = 0; j < nheight; j++) {
113
                for (int i = 0; i < nwidth; i++) {
114
                    ndata[nwidth * (nheight - j - 1) + i] = (255 & 0xff) << 24
115
                            | (((int) brgb[nindex + 2] & 0xff) << 16)
116
                            | (((int) brgb[nindex + 1] & 0xff) << 8)
117
                            | (int) brgb[nindex] & 0xff;
118
119
                    nindex += 3;
120
                }
121
                nindex += npad;
122
            }
123
124
            Component c = new Container();
125
            image = c.createImage(new MemoryImageSource(nwidth, nheight, ndata,
126
                    0, nwidth));
127
        } else if (nbitcount == 8) {
128
            // Have to determine the number of colors, the clrsused
129
            // parameter is dominant if it is greater than zero. If
130
            // zero, calculate colors based on bitsperpixel.
131
            int nNumColors = 0;
132
            if (nclrused > 0) {
133
                nNumColors = nclrused;
134
            } else {
135
                nNumColors = (1 & 0xff) << nbitcount;
136
            }
137
138
            // Some bitmaps do not have the sizeimage field calculated
139
            // Ferret out these cases and fix 'em.
140
            if (nsizeimage == 0) {
141
                nsizeimage = ((((nwidth * nbitcount) + 31) & ~31) >> 3);
142
                nsizeimage *= nheight;
143
            }
144
145
            // Read the palatte colors.
146
            int npalette[] = new int[nNumColors];
147
            byte bpalette[] = new byte[nNumColors * 4];
148
            bs.read(bpalette, 0, nNumColors * 4);
149
            int nindex8 = 0;
150
            for (int n = 0; n < nNumColors; n++) {
151
                npalette[n] = (255 & 0xff) << 24
152
                        | (((int) bpalette[nindex8 + 2] & 0xff) << 16)
153
                        | (((int) bpalette[nindex8 + 1] & 0xff) << 8)
154
                        | (int) bpalette[nindex8] & 0xff;
155
            }
156
157
            // Read the image data (actually indices into the palette)
158
            // Scan lines are still padded out to even 4-byte
159
            // boundaries.
160
            int npad8 = (nsizeimage / nheight) - nwidth;
161
            int ndata8[] = new int[nwidth * nheight];
162
            byte bdata[] = new byte[(nwidth + npad8) * nheight];
163
            bs.read(bdata, 0, (nwidth + npad8) * nheight);
164
            nindex8 = 0;
165
            for (int j8 = 0; j8 < nheight; j8++) {
166
                for (int i8 = 0; i8 < nwidth; i8++) {
167
                    ndata8[nwidth * (nheight - j8 - 1) + i8] = npalette[((int) bdata[nindex8] & 0xff)];
168
                    nindex8++;
169
                }
170
                nindex8 += npad8;
171
            }
172
173
            Component c = new Container();
174
            image = c.createImage(new MemoryImageSource(nwidth, nheight,
175
                    ndata8, 0, nwidth));
176
        } else {
177
            throw new FOPException("Bitmap" + url + "could not be rendered. "
178
                    + "FOP only supports 24-bit or 8-bit Windows Bitmap");
179
        }
180
181
        bs.close();
182
        return image;
183
184
    }
185
}

Return to bug 33760