ASF Bugzilla – Attachment 14371 Details for
Bug 33760
[Patch] current AWTRenderer
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
[PATCH] implementation of the AWTRenderer
PatchAWTRenderer.txt (text/plain), 76.30 KB, created by
renaud richardet
on 2005-02-27 23:52:25 UTC
(
hide
)
Description:
[PATCH] implementation of the AWTRenderer
Filename:
MIME Type:
Creator:
renaud richardet
Created:
2005-02-27 23:52:25 UTC
Size:
76.30 KB
patch
obsolete
>Index: src/java/org/apache/fop/area/CTM.java >=================================================================== >RCS file: /home/cvspublic/xml-fop/src/java/org/apache/fop/area/CTM.java,v >retrieving revision 1.9 >diff -u -r1.9 CTM.java >--- src/java/org/apache/fop/area/CTM.java 24 Nov 2004 21:07:28 -0000 1.9 >+++ src/java/org/apache/fop/area/CTM.java 27 Feb 2005 22:27:31 -0000 >@@ -310,5 +310,19 @@ > // Now transform for writing mode > return ctm.multiply(CTM.getWMctm(writingMode, reldims.ipd, reldims.bpd)); > } >+ >+ >+ /**gets the x shift of this CTM >+ * @return the x shift as a double >+ */ >+ public double getXShift(){ >+ return this.e; >+ } > >+ /**gets the y shift of this CTM >+ * @return the y shift as a double >+ */ >+ public double getYShift(){ >+ return this.f; >+ } > } >Index: src/java/org/apache/fop/render/AbstractRenderer.java >=================================================================== >RCS file: /home/cvspublic/xml-fop/src/java/org/apache/fop/render/AbstractRenderer.java,v >retrieving revision 1.42 >diff -u -r1.42 AbstractRenderer.java >--- src/java/org/apache/fop/render/AbstractRenderer.java 7 Feb 2005 11:00:19 -0000 1.42 >+++ src/java/org/apache/fop/render/AbstractRenderer.java 27 Feb 2005 22:27:36 -0000 >@@ -59,7 +59,9 @@ > import org.apache.fop.area.inline.TextArea; > import org.apache.fop.area.inline.Character; > import org.apache.fop.apps.FOUserAgent; >+import org.apache.fop.datatypes.ColorType; > import org.apache.fop.fo.Constants; >+import org.apache.fop.fonts.Font; > import org.apache.fop.fonts.FontInfo; > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; >@@ -109,6 +111,9 @@ > */ > protected int containingIPPosition = 0; > >+ /** Name of currently selected font */ >+ protected String currentFontName = ""; >+ > /** > * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration) > */ >@@ -255,10 +260,11 @@ > Rectangle2D view = port.getViewArea(); > // The CTM will transform coordinates relative to > // this region-reference area into page coords, so >- // set origin for the region to 0,0. >- currentBPPosition = 0; >- currentIPPosition = 0; >- >+ // set origin for the region to 0,0. >+ //currentBPPosition = 0; >+ //currentIPPosition = 0; >+ //FIXME containingXXXPosition is reseted in startVParea(); >+ > RegionReference region = port.getRegion(); > handleRegionTraits(port); > >@@ -266,7 +272,7 @@ > startVParea(region.getCTM()); > // do after starting viewport area > if (region.getRegionClass() == FO_REGION_BODY) { >- renderBodyRegion((BodyRegion) region); >+ renderBodyRegion((BodyRegion) region); > } else { > renderRegion(region); > } >@@ -275,11 +281,17 @@ > } > > /** >+ * The CTM will transform coordinates relative to this >+ * region-reference area into page coords >+ * >+ * @param ctm The coordinate transformation matrix to use >+ */ >+ protected void startVParea(CTM ctm) { } >+ >+ /** > * (todo) Description of the Method >- * >- * @param ctm The coordinate transformation matrix to use > */ >- protected void startVParea(CTM ctm) { } >+ protected void endVParea() { } > > /** > * Handle the traits for a region >@@ -287,14 +299,35 @@ > * (See Sect. 6.4.1.2 of XSL-FO spec.) > * @param rv the RegionViewport whose region is to be drawn > */ >- protected void handleRegionTraits(RegionViewport rv) { >- // draw border and background >+ protected void handleRegionTraits(RegionViewport region) { >+ >+ currentFontName = ""; // TODO why here? >+ Rectangle2D viewArea = region.getViewArea(); >+ float startx = (float) (viewArea.getX() / 1000f); >+ float starty = (float) (viewArea.getY() / 1000f); >+ float width = (float) (viewArea.getWidth() / 1000f); >+ float height = (float) (viewArea.getHeight() / 1000f); >+ >+ if (region.getRegion().getRegionClass() == FO_REGION_BODY) { >+ currentBPPosition = region.getBorderAndPaddingWidthBefore(); >+ currentIPPosition = region.getBorderAndPaddingWidthStart(); >+ } >+ drawBackAndBorders(region, startx, starty, width, height); > } > > /** >- * (todo) Description of the Method >+ * Draw the background and borders. This draws the background and border >+ * traits for an area given the position. >+ * >+ * @param block the area to get the traits from >+ * @param startx the start x position >+ * @param starty the start y position >+ * @param width the width of the area >+ * @param height the height of the area > */ >- protected void endVParea() { } >+ protected void drawBackAndBorders(RegionViewport region, float startx, >+ float starty, float width, float height) { >+ } > > /** > * Renders a region reference area. >@@ -429,8 +462,8 @@ > int saveBP = currentBPPosition; > > CTM ctm = bv.getCTM(); >- currentIPPosition = 0; >- currentBPPosition = 0; >+ //currentIPPosition = 0; >+ //currentBPPosition = 0; > > startVParea(ctm); > handleBlockTraits(bv); >@@ -559,8 +592,81 @@ > protected void renderTextDecoration(InlineArea area) { > //getLogger().debug("renderTextDecoration for " + area + " -> " + area.getTrait(Trait.UNDERLINE)); > } >+ >+ /** >+ * Paints the text decoration marks. >+ * @param fs Current font >+ * @param inline inline area to paint the marks for >+ * @param baseline position of the baseline >+ * @param startx start IPD >+ */ >+ protected void renderTextDecoration(Font fs, InlineArea inline, >+ int baseline, int startx) { >+ boolean hasTextDeco = inline.hasUnderline() >+ || inline.hasOverline() >+ || inline.hasLineThrough(); >+ if (hasTextDeco) { >+ endTextObject(); >+ updateLineStyle(Constants.EN_SOLID); >+ updateLineWidth(fs.getDescender() / -8 / 1000f); >+ float endx = (startx + inline.getIPD()) / 1000f; >+ if (inline.hasUnderline()) { >+ ColorType ct = (ColorType) inline.getTrait(Trait.UNDERLINE_COLOR); >+ updateColor(ct, false, null); >+ float y = baseline - fs.getDescender() / 2; >+ drawLine(startx / 1000f, y / 1000f, endx, y / 1000f); >+ } >+ if (inline.hasOverline()) { >+ ColorType ct = (ColorType) inline.getTrait(Trait.OVERLINE_COLOR); >+ updateColor(ct, false, null); >+ float y = (float)(baseline - (1.1 * fs.getCapHeight())); >+ drawLine(startx / 1000f, y / 1000f, endx, y / 1000f); >+ } >+ if (inline.hasLineThrough()) { >+ ColorType ct = (ColorType) inline.getTrait(Trait.LINETHROUGH_COLOR); >+ updateColor(ct, false, null); >+ float y = (float)(baseline - (0.45 * fs.getCapHeight())); >+ drawLine(startx / 1000f, y / 1000f, endx, y / 1000f); >+ } >+ } >+ } > > /** >+ * Sets the current line style. The line width should be >+ * set with updateLineWidth() before calling this method >+ * @param style the constant for the style of the line as an int >+ */ >+ protected void updateLineStyle(int style) {} >+ >+ /** Indicates the end of a text object. */ >+ protected void endTextObject() { } >+ >+ /** >+ * Sets the current line width in points. >+ * @param width line width in points >+ */ >+ protected void updateLineWidth(float width) {} >+ >+ /** >+ * Draw a line. >+ * >+ * @param startx the start x position >+ * @param starty the start y position >+ * @param endx the x end position >+ * @param endy the y end position >+ */ >+ protected void drawLine(float startx, float starty, float endx, float endy) { } >+ >+ /** >+ * Establishes a new foreground or fill color. >+ * @param col the color to apply (null skips this operation) >+ * @param fill true to set the fill color, false for the foreground color >+ * @param pdf StringBuffer to write the PDF code to, if null, the code is >+ * written to the current stream. >+ */ >+ protected void updateColor(ColorType col, boolean fill, StringBuffer pdf) { } >+ >+ /** > * Renders a line area. <p> > * > * A line area may have grouped styling for its children such as underline, >@@ -629,7 +735,7 @@ > currentIPPosition = saveIP + ip.getAllocIPD(); > } > >- /** @see org.apache.fop.render.Renderer */ >+ /** @see org.apache.fop.render.Renderer */ //TODO nothing to see there > protected void renderViewport(Viewport viewport) { > Area content = viewport.getContent(); > int saveBP = currentBPPosition; >Index: src/java/org/apache/fop/render/awt/AWTRenderer.java >=================================================================== >RCS file: /home/cvspublic/xml-fop/src/java/org/apache/fop/render/awt/AWTRenderer.java,v >retrieving revision 1.33 >diff -u -r1.33 AWTRenderer.java >--- src/java/org/apache/fop/render/awt/AWTRenderer.java 24 Nov 2004 21:07:30 -0000 1.33 >+++ src/java/org/apache/fop/render/awt/AWTRenderer.java 27 Feb 2005 22:27:38 -0000 >@@ -26,6 +26,7 @@ > */ > > // Java >+import java.awt.BasicStroke; > import java.awt.Color; > import java.awt.Dimension; > import java.awt.Graphics; >@@ -35,6 +36,8 @@ > import java.awt.event.WindowAdapter; > import java.awt.event.WindowEvent; > import java.awt.geom.AffineTransform; >+import java.awt.geom.Line2D; >+import java.awt.geom.NoninvertibleTransformException; > import java.awt.geom.Rectangle2D; > import java.awt.image.BufferedImage; > import java.awt.print.PageFormat; >@@ -45,41 +48,103 @@ > import java.util.Map; > import java.util.Vector; > >-import org.apache.fop.fonts.FontInfo; >+import org.apache.batik.bridge.BridgeContext; >+import org.apache.batik.bridge.GVTBuilder; >+import org.apache.batik.bridge.ViewBox; >+import org.apache.batik.gvt.GraphicsNode; > import org.apache.fop.apps.FOPException; > import org.apache.fop.apps.FOUserAgent; > import org.apache.fop.area.Area; >+import org.apache.fop.area.Block; >+import org.apache.fop.area.CTM; > import org.apache.fop.area.Page; > import org.apache.fop.area.PageViewport; >-import org.apache.fop.area.RegionViewport; > import org.apache.fop.area.Trait; >+import org.apache.fop.area.inline.Character; >+import org.apache.fop.area.inline.ForeignObject; >+import org.apache.fop.area.inline.Image; >+import org.apache.fop.area.inline.Leader; > import org.apache.fop.area.inline.TextArea; > import org.apache.fop.datatypes.ColorType; >+import org.apache.fop.fonts.Font; >+import org.apache.fop.fonts.FontInfo; >+import org.apache.fop.fonts.FontMetrics; > import org.apache.fop.image.FopImage; > import org.apache.fop.image.ImageFactory; >+import org.apache.fop.image.XMLImage; > import org.apache.fop.render.AbstractRenderer; >-import org.apache.fop.traits.BorderProps; >-import org.apache.fop.render.awt.FontMetricsMapper; >+import org.apache.fop.render.RendererContext; > import org.apache.fop.render.awt.viewer.PreviewDialog; > import org.apache.fop.render.awt.viewer.Translator; >+import org.apache.fop.svg.SVGUserAgent; >+import org.apache.fop.traits.BorderProps; >+import org.w3c.dom.Document; >+import org.w3c.dom.svg.SVGDocument; >+import org.w3c.dom.svg.SVGSVGElement; > > /** >- * This is FOP's AWT renderer. >+ * Java2DRenderer provides the abstract technical foundation for all rendering >+ * with the Java2D API. Renderers like AWTRenderer subclass it and provide the >+ * concrete output paths. >+ * >+ * A lot of the logic is performed by AbstractRenderer. The class-variables >+ * currentIPPosition and currentBPPosition hold the position of the currently >+ * rendered area. >+ * >+ * The rendering process is basically always the same: void renderXXXXX(Area >+ * area){ get the currentPosition updateColor(area); updateFont(area); String s = >+ * area.getTextArea(); graphics.draw(new Shape(args)); } >+ * > */ >-public class AWTRenderer extends AbstractRenderer implements Printable, Pageable { >+public class AWTRenderer extends AbstractRenderer implements Printable, >+ Pageable { > >- /** The MIME type for PostScript */ >+ /** The MIME type for AWT-Rendering */ > public static final String MIME_TYPE = "application/awt"; > > protected double scaleFactor = 100.0; >+ > protected int pageNumber = 0; >+ > private int pageWidth = 0; >+ > private int pageHeight = 0; >+ > private Vector pageViewportList = new java.util.Vector(); >+ > private Vector pageList = new java.util.Vector(); >+ > private Vector bufferedImageList = new java.util.Vector(); >- private BufferedImage currentPageImage = null; >- >+ >+ protected BufferedImage currentPageImage = null; >+ >+ /** the graphic used to draw on the BufferedImage */ >+ protected Graphics2D graphics = null; >+ >+ /** the stroke used for graphics */ >+ protected BasicStroke stroke = new BasicStroke(); >+ >+ /** a basic stroke to reset the stroke */ >+ protected final BasicStroke basicStroke = new BasicStroke(); >+ >+ private boolean debug = true; >+ >+ protected boolean antialiasing = true; >+ >+ protected boolean qualityRendering = true; >+ >+ /** Size of currently selected font */ >+ protected int currentFontSize = 0; >+ >+ /** Currently selected Color */ >+ protected Color currentColor = null; >+ >+ /** Width of current line */ >+ protected float currentLineWidth = 0; >+ >+ /** Style of current line */ >+ protected int currentLineStyle = 0; >+ > /** Font configuration */ > protected FontInfo fontInfo; > >@@ -89,13 +154,14 @@ > protected Translator translator = null; > > private Map fontNames = new java.util.Hashtable(); >+ > private Map fontStyles = new java.util.Hashtable(); >+ > private Color saveColor = null; > > /** >- * The preview dialog frame used for display of the documents. >- * Also used as the AWT Component for FontSetup in generating >- * valid font measures. >+ * The preview dialog frame used for display of the documents. Also used as >+ * the AWT Component for FontSetup in generating valid font measures. > */ > protected PreviewDialog frame; > >@@ -127,9 +193,10 @@ > public void setupFontInfo(FontInfo inFontInfo) { > // create a temp Image to test font metrics on > fontInfo = inFontInfo; >- BufferedImage fontImage = >- new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); >+ BufferedImage fontImage = new BufferedImage(100, 100, >+ BufferedImage.TYPE_INT_RGB); > FontSetup.setup(fontInfo, fontImage.createGraphics()); >+ // FIXME is this implemented correctly? > } > > public int getPageNumber() { >@@ -148,17 +215,16 @@ > return scaleFactor; > } > >- public void startRenderer(OutputStream out) >- throws IOException { >+ public void startRenderer(OutputStream out) throws IOException { > // empty pageViewportList, in case of a reload from PreviewDialog > pageViewportList.removeAllElements(); > pageList.removeAllElements(); > bufferedImageList.removeAllElements(); >- System.out.println("\nRegion Types: 0-Before/Top, 1-Start/Left, 2-Body, 3-End/Right, 4-After/Bottom"); >+ System.out >+ .println("\nRegion Types: 0-Before/Top, 1-Start/Left, 2-Body, 3-End/Right, 4-After/Bottom"); > } > >- public void stopRenderer() >- throws IOException { >+ public void stopRenderer() throws IOException { > frame.setStatus(translator.getString("Status.Show")); > frame.showPage(); > } >@@ -188,7 +254,7 @@ > } > }); > >- //Centers the window >+ // Centers the window > Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); > Dimension frameSize = frame.getSize(); > if (frameSize.height > screenSize.height) { >@@ -198,18 +264,22 @@ > frameSize.width = screenSize.width; > } > frame.setLocation((screenSize.width - frameSize.width) / 2, >- (screenSize.height - frameSize.height) / 2); >+ (screenSize.height - frameSize.height) / 2); > frame.setVisible(true); > frame.setStatus(translator.getString("Status.Build.FO.tree")); > return frame; > } > >- /** This method override only stores the PageViewport in a vector. >- * No actual rendering performed -- this is done by getPageImage(pageNum) instead. >- * @param pageViewport the <code>PageViewport</code> object supplied by the Area Tree >- * @see org.apache.fop.render.Renderer >- */ >- public void renderPage(PageViewport pageViewport) throws IOException, FOPException { >+ /** >+ * This method override only stores the PageViewport in a vector. No actual >+ * rendering performed -- this is done by getPageImage(pageNum) instead. >+ * >+ * @param pageViewport the <code>PageViewport</code> object supplied by >+ * the Area Tree >+ * @see org.apache.fop.render.Renderer >+ */ >+ public void renderPage(PageViewport pageViewport) throws IOException, >+ FOPException { > pageViewportList.add(pageViewport); > pageList.add(pageViewport.getPage().clone()); > bufferedImageList.add(getPageImage(pageViewport)); >@@ -219,31 +289,42 @@ > return (BufferedImage) bufferedImageList.get(pageNum); > } > >- /** Generates a desired page from the renderer's page viewport vector. >+ /** >+ * Generates a desired page from the renderer's page viewport vector. >+ * > * @param pageNum the 0-based page number to generate >- * @return the <code>java.awt.image.BufferedImage</code> corresponding to the page >- * @throws FOPException in case of an out-of-range page number requested >- */ >- public BufferedImage getPageImage(PageViewport pageViewport) throws FOPException { >+ * @return the <code>java.awt.image.BufferedImage</code> corresponding to >+ * the page >+ * @throws FOPException in case of an out-of-range page number requested >+ */ >+ public BufferedImage getPageImage(PageViewport pageViewport) >+ throws FOPException { > Page page = pageViewport.getPage(); > > Rectangle2D bounds = pageViewport.getViewArea(); >- pageWidth = (int) Math.round(bounds.getWidth() / 1000f ); >- pageHeight = (int) Math.round(bounds.getHeight() / 1000f ); >-/* >- System.out.println("(Page) X, Y, Width, Height: " + bounds.getX() >- + " " + bounds.getY() >- + " " + bounds.getWidth() >- + " " + bounds.getHeight()); >-*/ >- currentPageImage = >- new BufferedImage((int)((pageWidth * (int)scaleFactor) / 100), >- (int)((pageHeight * (int)scaleFactor) / 100), >- BufferedImage.TYPE_INT_RGB); >- >- Graphics2D graphics = currentPageImage.createGraphics(); >- graphics.setRenderingHint (RenderingHints.KEY_FRACTIONALMETRICS, >- RenderingHints.VALUE_FRACTIONALMETRICS_ON); >+ pageWidth = (int) Math.round(bounds.getWidth() / 1000f); >+ pageHeight = (int) Math.round(bounds.getHeight() / 1000f); >+ >+ System.out.println("(Page) X, Y, Width, Height: " + bounds.getX() + " " >+ + bounds.getY() + " " + bounds.getWidth() + " " >+ + bounds.getHeight() + ", pageWidth " + pageWidth >+ + ", pageHeight " + pageHeight); >+ >+ currentPageImage = new BufferedImage( >+ (int) ((pageWidth * (int) scaleFactor) / 100), >+ (int) ((pageHeight * (int) scaleFactor) / 100), >+ BufferedImage.TYPE_INT_RGB); >+ >+ graphics = currentPageImage.createGraphics(); >+ graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, >+ RenderingHints.VALUE_FRACTIONALMETRICS_ON); >+ if (antialiasing) { >+ graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, >+ RenderingHints.VALUE_TEXT_ANTIALIAS_ON); >+ } >+ if (qualityRendering) >+ graphics.setRenderingHint(RenderingHints.KEY_RENDERING, >+ RenderingHints.VALUE_RENDER_QUALITY); > > // transform page based on scale factor supplied > AffineTransform at = graphics.getTransform(); >@@ -254,47 +335,63 @@ > graphics.setColor(Color.white); > graphics.fillRect(0, 0, pageWidth, pageHeight); > graphics.setColor(Color.black); >+ // TODO Why draw those silly lines? > graphics.drawRect(-1, -1, pageWidth + 2, pageHeight + 2); > graphics.drawLine(pageWidth + 2, 0, pageWidth + 2, pageHeight + 2); > graphics.drawLine(pageWidth + 3, 1, pageWidth + 3, pageHeight + 3); > graphics.drawLine(0, pageHeight + 2, pageWidth + 2, pageHeight + 2); > graphics.drawLine(1, pageHeight + 3, pageWidth + 3, pageHeight + 3); > >+ // reset the current Positions >+ currentBPPosition = 0; >+ currentIPPosition = 0; >+ >+ // this toggles the rendering of all areas > renderPageAreas(page); > return currentPageImage; > } > >- /** Generates a desired page from the renderer's page viewport vector. >+ /** >+ * TODO refactor with getPageImage(PageViewport) Generates a desired page >+ * from the renderer's page viewport vector. >+ * > * @param pageNum the 0-based page number to generate >- * @return the <code>java.awt.image.BufferedImage</code> corresponding to the page >- * @throws FOPException in case of an out-of-range page number requested >- */ >+ * @return the <code>java.awt.image.BufferedImage</code> corresponding to >+ * the page >+ * @throws FOPException in case of an out-of-range page number requested >+ */ > public BufferedImage getPageImage(int pageNum) throws FOPException { > if (pageNum < 0 || pageNum >= pageViewportList.size()) { > throw new FOPException("out-of-range page number (" + pageNum >- + ") requested; only " + pageViewportList.size() >- + " page(s) available."); >+ + ") requested; only " + pageViewportList.size() >+ + " page(s) available."); > } >- PageViewport pageViewport = (PageViewport) pageViewportList.get(pageNum); >+ PageViewport pageViewport = (PageViewport) pageViewportList >+ .get(pageNum); > Page page = (Page) pageList.get(pageNum); > > Rectangle2D bounds = pageViewport.getViewArea(); >- pageWidth = (int) Math.round(bounds.getWidth() / 1000f ); >- pageHeight = (int) Math.round(bounds.getHeight() / 1000f ); >-/* >- System.out.println("(Page) X, Y, Width, Height: " + bounds.getX() >- + " " + bounds.getY() >- + " " + bounds.getWidth() >- + " " + bounds.getHeight()); >-*/ >- currentPageImage = >- new BufferedImage((int)((pageWidth * (int)scaleFactor) / 100), >- (int)((pageHeight * (int)scaleFactor) / 100), >- BufferedImage.TYPE_INT_RGB); >- >- Graphics2D graphics = currentPageImage.createGraphics(); >- graphics.setRenderingHint (RenderingHints.KEY_FRACTIONALMETRICS, >- RenderingHints.VALUE_FRACTIONALMETRICS_ON); >+ pageWidth = (int) Math.round(bounds.getWidth() / 1000f); >+ pageHeight = (int) Math.round(bounds.getHeight() / 1000f); >+ /* >+ * System.out.println("(Page) X, Y, Width, Height: " + bounds.getX() + " " + >+ * bounds.getY() + " " + bounds.getWidth() + " " + bounds.getHeight()); >+ */ >+ currentPageImage = new BufferedImage( >+ (int) ((pageWidth * (int) scaleFactor) / 100), >+ (int) ((pageHeight * (int) scaleFactor) / 100), >+ BufferedImage.TYPE_INT_RGB); >+ >+ graphics = currentPageImage.createGraphics(); >+ graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, >+ RenderingHints.VALUE_FRACTIONALMETRICS_ON); >+ if (antialiasing) { >+ graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, >+ RenderingHints.VALUE_TEXT_ANTIALIAS_ON); >+ } >+ if (qualityRendering) >+ graphics.setRenderingHint(RenderingHints.KEY_RENDERING, >+ RenderingHints.VALUE_RENDER_QUALITY); > > // transform page based on scale factor supplied > AffineTransform at = graphics.getTransform(); >@@ -311,155 +408,263 @@ > graphics.drawLine(0, pageHeight + 2, pageWidth + 2, pageHeight + 2); > graphics.drawLine(1, pageHeight + 3, pageWidth + 3, pageHeight + 3); > >+ // reset the current Positions >+ currentBPPosition = 0; >+ currentIPPosition = 0; >+ > renderPageAreas(page); > return currentPageImage; > } > > /** >- * Handle the traits for a region >- * This is used to draw the traits for the given page region. >- * (See Sect. 6.4.1.2 of XSL-FO spec.) >- * @param region the RegionViewport whose region is to be drawn >- */ >- protected void handleRegionTraits(RegionViewport region) { >- Rectangle2D viewArea = region.getViewArea(); >- >- int startX = (int) Math.round((viewArea.getX() / 1000f) >- * (scaleFactor / 100f)); >- int startY = (int) Math.round((viewArea.getY() / 1000f) >- * (scaleFactor / 100f)); >- // for rounding to work correctly, need to take into account >- // fractional portion of X and Y. >- int width = (int) Math.round(((viewArea.getX() + viewArea.getWidth()) / 1000f) >- * (scaleFactor / 100f)) - startX; >- int height = (int) Math.round(((viewArea.getY() + viewArea.getHeight()) / 1000f) >- * (scaleFactor / 100f)) - startY; >- >- if (region.getRegion() != null) { >- System.out.print("\nRegion type = " + region.getRegion().getRegionClass()); >- } >- >- System.out.println(" X, Width, Y, Height: " + startX >- + " " + width >- + " " + startY >- + " " + height >- ); >- >- drawBackAndBorders(region, startX, startY, width, height); >+ * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM) >+ */ >+ protected void startVParea(CTM ctm) { >+ >+ // Uses the x shift (param e) and y shift (param f) >+ // of the CTM to update the current Positions >+ currentIPPosition += (int) ctm.getXShift(); >+ currentBPPosition += (int) ctm.getYShift(); >+ // TODO is this supporting other writing modes? > } > > /** >- * Draw the background and borders. >- * This draws the background and border traits for an area given >- * the position. >- * >+ * Draw the background and borders. This draws the background and border >+ * traits for an area given the position. >+ * > * @param block the area to get the traits from > * @param startx the start x position > * @param starty the start y position > * @param width the width of the area > * @param height the height of the area > */ >- protected void drawBackAndBorders(Area block, >- int startx, int starty, >- int width, int height) { >+ protected void drawBackAndBorders(Area area, float startx, float starty, >+ float width, float height) { >+ // TODO put in AbstractRenderer and call drawBackground() >+ // and drawBorders() >+ >+ BorderProps bpsBefore = (BorderProps) area >+ .getTrait(Trait.BORDER_BEFORE); >+ BorderProps bpsAfter = (BorderProps) area.getTrait(Trait.BORDER_AFTER); >+ BorderProps bpsStart = (BorderProps) area.getTrait(Trait.BORDER_START); >+ BorderProps bpsEnd = (BorderProps) area.getTrait(Trait.BORDER_END); > >- // draw background then border >- Graphics2D graphics = currentPageImage.createGraphics(); >+ // draw background > Trait.Background back; >- back = (Trait.Background) block.getTrait(Trait.BACKGROUND); >+ back = (Trait.Background) area.getTrait(Trait.BACKGROUND); > if (back != null) { > >+ // Calculate padding rectangle >+ float sx = startx; >+ float sy = starty; >+ float paddRectWidth = width; >+ float paddRectHeight = height; >+ >+ if (bpsStart != null) { >+ sx += bpsStart.width / 1000f; >+ paddRectWidth -= bpsStart.width / 1000f; >+ } >+ if (bpsBefore != null) { >+ sy += bpsBefore.width / 1000f; >+ paddRectHeight -= bpsBefore.width / 1000f; >+ } >+ if (bpsEnd != null) { >+ paddRectWidth -= bpsEnd.width / 1000f; >+ } >+ if (bpsAfter != null) { >+ paddRectHeight -= bpsAfter.width / 1000f; >+ } >+ > if (back.getColor() != null) { >- graphics.setColor(back.getColor().getAWTColor()); >- graphics.fillRect(startx, starty, width, height); >+ drawBackground(back, sx, sy, paddRectWidth, paddRectHeight); > } >- if (back.getURL() != null) { // TODO: implement >- ImageFactory fact = ImageFactory.getInstance(); >- FopImage fopimage = fact.getImage(back.getURL(), userAgent); >+ >+ // background image >+ if (back.getFopImage() != null) { >+ FopImage fopimage = back.getFopImage(); > if (fopimage != null && fopimage.load(FopImage.DIMENSIONS)) { >- if (back.getRepeat() == EN_REPEAT) { >- // create a pattern for the image >- } else { >- // place once >- Rectangle2D pos; >- pos = new Rectangle2D.Float((startx + back.getHoriz()) * 1000, >- (starty + back.getVertical()) * 1000, >- fopimage.getWidth() * 1000, >- fopimage.getHeight() * 1000); >-// putImage(back.getURL(), pos); >+ // TODO clip(sx, sy, paddRectWidth, paddRectHeight); >+ int horzCount = (int) ((paddRectWidth * 1000 / fopimage >+ .getIntrinsicWidth()) + 1.0f); >+ int vertCount = (int) ((paddRectHeight * 1000 / fopimage >+ .getIntrinsicHeight()) + 1.0f); >+ if (back.getRepeat() == EN_NOREPEAT) { >+ horzCount = 1; >+ vertCount = 1; >+ } else if (back.getRepeat() == EN_REPEATX) { >+ vertCount = 1; >+ } else if (back.getRepeat() == EN_REPEATY) { >+ horzCount = 1; >+ } >+ // change from points to millipoints >+ sx *= 1000; >+ sy *= 1000; >+ if (horzCount == 1) { >+ sx += back.getHoriz(); > } >+ if (vertCount == 1) { >+ sy += back.getVertical(); >+ } >+ for (int x = 0; x < horzCount; x++) { >+ for (int y = 0; y < vertCount; y++) { >+ // place once >+ Rectangle2D pos; >+ pos = new Rectangle2D.Float(sx >+ + (x * fopimage.getIntrinsicWidth()), sy >+ + (y * fopimage.getIntrinsicHeight()), >+ fopimage.getIntrinsicWidth(), fopimage >+ .getIntrinsicHeight()); >+ putImage(back.getURL(), pos); //TODO test >+ } >+ } >+ >+ } else { >+ getLogger().warn( >+ "Can't find background image: " + back.getURL()); > } > } > } > >- BorderProps bps = (BorderProps) block.getTrait(Trait.BORDER_BEFORE); >+ // draw border //TODO not touched, maybe better implemented in pdf? >+ // -->to be tested >+ BorderProps bps = (BorderProps) area.getTrait(Trait.BORDER_BEFORE); > if (bps != null) { >- int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f)); >+ int borderWidth = (int) Math.round((bps.width / 1000f) >+ * (scaleFactor / 100f)); > graphics.setColor(bps.color.getAWTColor()); >- graphics.fillRect(startx, starty, width, borderWidth); >+ graphics.fillRect((int) startx, (int) starty, (int) width, >+ borderWidth); > } >- bps = (BorderProps) block.getTrait(Trait.BORDER_AFTER); >+ bps = (BorderProps) area.getTrait(Trait.BORDER_AFTER); > if (bps != null) { >- int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f)); >- int sy = starty + height; >+ int borderWidth = (int) Math.round((bps.width / 1000f) >+ * (scaleFactor / 100f)); >+ float sy = starty + height; > graphics.setColor(bps.color.getAWTColor()); >- graphics.fillRect(startx, starty + height - borderWidth, >- width, borderWidth); >+ graphics.fillRect((int) startx, >+ (int) (starty + height - borderWidth), (int) width, >+ borderWidth); > } >- bps = (BorderProps) block.getTrait(Trait.BORDER_START); >+ bps = (BorderProps) area.getTrait(Trait.BORDER_START); > if (bps != null) { >- int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f)); >+ int borderWidth = (int) Math.round((bps.width / 1000f) >+ * (scaleFactor / 100f)); > graphics.setColor(bps.color.getAWTColor()); >- graphics.fillRect(startx, starty, borderWidth, height); >+ graphics.fillRect((int) startx, (int) starty, borderWidth, >+ (int) height); > } >- bps = (BorderProps) block.getTrait(Trait.BORDER_END); >+ bps = (BorderProps) area.getTrait(Trait.BORDER_END); > if (bps != null) { >- int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f)); >- int sx = startx + width; >+ int borderWidth = (int) Math.round((bps.width / 1000f) >+ * (scaleFactor / 100f)); >+ float sx = startx + width; > graphics.setColor(bps.color.getAWTColor()); >- graphics.fillRect(startx + width - borderWidth, starty, >- borderWidth, height); >+ graphics.fillRect((int) (startx + width - borderWidth), >+ (int) starty, borderWidth, (int) height); > } >- >+ >+ } >+ >+ /** >+ * Draw the Background Rectangle of a given area. >+ * >+ * @param back the Trait.Background >+ * @param sx x coordinate of the rectangle to be filled. >+ * @param sy y the y coordinate of the rectangle to be filled. >+ * @param paddRectWidth the width of the rectangle to be filled. >+ * @param paddRectHeight the height of the rectangle to be filled. >+ */ >+ protected void drawBackground(Trait.Background back, float sx, float sy, >+ float paddRectWidth, float paddRectHeight) { >+ >+ graphics.setColor(back.getColor().getAWTColor()); >+ graphics.fillRect((int) sx, (int) sy, (int) paddRectWidth, >+ (int) paddRectHeight); >+ } >+ >+ /** >+ * Handle block traits. The block could be any sort of block with any >+ * positioning so this should render the traits such as border and >+ * background in its position. >+ * >+ * @param block the block to render the traits >+ */ >+ protected void handleBlockTraits(Block block) { >+ // TODO only copied from pdf >+ // TODO check and try to put in AbstractRenderer >+ int borderPaddingStart = block.getBorderAndPaddingWidthStart(); >+ int borderPaddingBefore = block.getBorderAndPaddingWidthBefore(); >+ >+ float startx = currentIPPosition / 1000f; >+ float starty = currentBPPosition / 1000f; >+ float width = block.getIPD() / 1000f; >+ float height = block.getBPD() / 1000f; >+ >+ startx += block.getStartIndent() / 1000f; >+ startx -= block.getBorderAndPaddingWidthStart() / 1000f; >+ width += borderPaddingStart / 1000f; >+ width += block.getBorderAndPaddingWidthEnd() / 1000f; >+ height += borderPaddingBefore / 1000f; >+ height += block.getBorderAndPaddingWidthAfter() / 1000f; >+ >+ drawBackAndBorders(block, startx, starty, width, height); > } >- >+ > /** > * @see org.apache.fop.render.Renderer#renderText(TextArea) > */ > public void renderText(TextArea text) { >- System.out.println("In render text: " + text.getTextArea()); > >- Graphics2D graphics = currentPageImage.createGraphics(); >+ float x = currentIPPosition / 1000f; >+ float y = (currentBPPosition + text.getOffset()) / 1000f; // baseline >+ >+ updateColor(text); >+ updateFont(text); >+ String s = text.getTextArea(); >+ graphics.drawString(s, x, y); >+ >+ getLogger().debug( >+ s + " cX " + currentIPPosition + "curY" + currentBPPosition >+ + " x " + x + " y " + y); >+ >+ // rendering text decorations //TODO refactorize > String fontName = (String) text.getTrait(Trait.FONT_NAME); > int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); >-// Typeface f = (Typeface) fontInfo.getFonts().get(fontName); >- ColorType ct = (ColorType) text.getTrait(Trait.COLOR); >+ FontMetrics metrics = fontInfo.getMetricsFor(fontName); >+ Font fs = new Font(fontName, metrics, size); >+ super.renderTextDecoration(fs, text, (currentBPPosition + text >+ .getOffset()), currentIPPosition); >+ renderTextDecoration(fs, text, (int) y, (int) x); > >- FontMetricsMapper mapper = (FontMetricsMapper) >- fontInfo.getMetricsFor(fontName); >- if (mapper == null) { >- mapper = new FontMetricsMapper("MonoSpaced", java.awt.Font.PLAIN, >- graphics); >- } >- >-// graphics.setColor(ct.getAWTColor()); >-// graphics.setFont(mapper.getFont(size)); >- graphics.setColor(java.awt.Color.black); >- graphics.setFont(new java.awt.Font("monospaced", java.awt.Font.PLAIN, >- 10)); >- >- int rx = currentIPPosition; >- int bl = currentBPPosition + text.getOffset(); >- >- int newx = (int) (rx + 500) / 1000; >- int newy = (int) (pageHeight - (bl + 500) / 1000); >- >- String s = text.getTextArea(); >-// graphics.drawString(s, newx, newy); >- graphics.drawString(s, 220, 200); >+ super.renderText(text); >+ } >+ >+ /** >+ * @see org.apache.fop.render.Renderer#renderCharacter(Character) >+ */ >+ public void renderCharacter(Character ch) { >+ >+ float x = currentIPPosition / 1000f; >+ float y = (currentBPPosition + ch.getOffset()) / 1000f; // baseline > >- // TODO: render text decorations >- currentIPPosition += text.getAllocIPD(); >+ updateColor(ch); >+ updateFont(ch); >+ String s = ch.getChar(); >+ graphics.drawString(s, x, y); >+ >+ getLogger().debug( >+ s + " cX " + currentIPPosition + "curY" + currentBPPosition); >+ >+ // rendering text decorations //TODO refactorize >+ String fontName = (String) ch.getTrait(Trait.FONT_NAME); >+ int size = ((Integer) ch.getTrait(Trait.FONT_SIZE)).intValue(); >+ FontMetrics metrics = fontInfo.getMetricsFor(fontName); >+ Font fs = new Font(fontName, metrics, size); >+ super.renderTextDecoration(fs, ch, >+ (currentBPPosition + ch.getOffset()), currentIPPosition); >+ renderTextDecoration(fs, ch, (int) y, (int) x); >+ >+ super.renderCharacter(ch); > } > > /** @see org.apache.fop.render.AbstractRenderer */ >@@ -467,4 +672,397 @@ > return MIME_TYPE; > } > >+ /** >+ * Render leader area. This renders a leader area which is an area with a >+ * rule. >+ * >+ * @param area the leader area to render >+ */ >+ public void renderLeader(Leader area) { >+ >+ // TODO leader-length: 25%, 50%, 75%, 100% not working yet >+ >+ float startx = ((float) currentIPPosition) / 1000f; >+ float starty = ((currentBPPosition + area.getOffset()) / 1000f); >+ float endx = (currentIPPosition + area.getIPD()) / 1000f; >+ >+ updateColor(area); >+ >+ Line2D.Float leader = new Line2D.Float(startx, starty, endx, starty); >+ float thickness = area.getRuleThickness() / 1000f; >+ >+ int style = area.getRuleStyle(); >+ switch (style) { >+ case EN_SOLID: >+ case EN_DOTTED: >+ case EN_DASHED: >+ updateLineWidth(thickness); >+ updateLineStyle(style); >+ graphics.draw(leader); >+ break; >+ case EN_DOUBLE: >+ updateLineWidth(thickness / 3f); // only a third >+ updateLineStyle(EN_SOLID); >+ >+ Line2D.Float upperLeader = new Line2D.Float(startx, starty, endx, >+ starty); >+ graphics.draw(upperLeader); >+ Line2D.Float lowerLeader = new Line2D.Float(startx, starty + 2 >+ * thickness, endx, starty + 2 * thickness); >+ graphics.draw(lowerLeader); >+ break; >+ case EN_GROOVE: >+ // The rule looks as though it were carved into the canvas. >+ // (Top/left half of the rule's thickness is the >+ // color specified; the other half is white.) >+ >+ updateLineWidth(thickness / 2f); // only the half >+ updateLineStyle(EN_SOLID); >+ >+ Line2D.Float upperLeader2 = new Line2D.Float(startx, starty, endx, >+ starty); >+ graphics.draw(upperLeader2); >+ Line2D.Float lowerLeader2 = new Line2D.Float(startx, starty >+ + thickness, endx, starty + thickness); >+ graphics.setColor(Color.WHITE); >+ graphics.draw(lowerLeader2); >+ // TODO the implementation could be nicer, f.eg. with triangles at >+ // the tip of the lines. See also RenderX's implementation (looks >+ // like a button) >+ break; >+ case EN_RIDGE: >+ // The opposite of "groove", the rule looks as though it were >+ // coming out of the canvas. (Bottom/right half of the rule's >+ // thickness is the color specified; the other half is white.) >+ >+ updateLineWidth(thickness / 2f); // only the half >+ updateLineStyle(EN_SOLID); >+ >+ Line2D.Float lowerLeader3 = new Line2D.Float(startx, starty >+ + thickness, endx, starty + thickness); >+ graphics.draw(lowerLeader3); >+ Line2D.Float upperLeader3 = new Line2D.Float(startx, starty, endx, >+ starty); >+ graphics.setColor(Color.WHITE); >+ graphics.draw(upperLeader3); >+ // TODO the implementation could be nicer, f.eg. with triangles at >+ // the tip of the lines. See also RenderX's implementation (looks >+ // like a button) >+ break; >+ case EN_NONE: >+ // No rule is drawn >+ break; >+ >+ } // end switch >+ >+ graphics.setStroke(basicStroke); // reset the stroke >+ >+ super.renderLeader(area); >+ } >+ >+ // TODO abstractize? >+ /** >+ * Converts a ColorType to a java.awt.Color (sRGB). >+ * >+ * @param col the color >+ * @return the converted color >+ */ >+ protected Color toColor(ColorType col) { >+ return new Color(col.getRed(), col.getGreen(), col.getBlue()); >+ } >+ >+ /** >+ * Establishes a new foreground or fill color. >+ * >+ * @param col the color to apply (null skips this operation) >+ * @param fill true to set the fill color, false for the foreground color >+ * @param pdf StringBuffer to write the PDF code to, if null, the code is >+ * written to the current stream. >+ */ >+ protected void updateColor(ColorType col, boolean fill, StringBuffer pdf) { >+ if (col == null) { >+ return; >+ } >+ Color newCol = toColor(col); >+ graphics.setColor(newCol); >+ } >+ >+ protected void updateColor(Area area) { >+ ColorType ct = (ColorType) area.getTrait(Trait.COLOR); >+ try { // FIXME there must be another way (that always works) >+ currentColor = ct.getAWTColor(); >+ } catch (Exception e) { >+ getLogger() >+ .warn( >+ "Can't find color: " + ct >+ + "color set by default to black"); >+ currentColor = java.awt.Color.black; >+ } >+ graphics.setColor(currentColor); >+ } >+ >+ protected void updateFont(String name, int size, StringBuffer pdf) { >+ if ((!name.equals(this.currentFontName)) >+ || (size != this.currentFontSize)) { >+ >+ // graphics.setFont(xxxx); //TODO >+ // this.currentFontName = name; >+ // this.currentFontSize = size; >+ } >+ } >+ >+ protected void updateFont(Area area) { >+ >+ // FIXME Fonts are not working properly yet >+ >+ String fontName = (String) area.getTrait(Trait.FONT_NAME); >+ int size = ((Integer) area.getTrait(Trait.FONT_SIZE)).intValue(); >+ >+ FontMetricsMapper mapper = (FontMetricsMapper) fontInfo >+ .getMetricsFor(fontName); >+ java.awt.Font font = mapper.getFont(size); >+ >+ // graphics.setFont(new java.awt.Font("SansSerif", java.awt.Font.PLAIN, >+ // (int)(size/1000f))); >+ graphics.setFont(font); >+ >+ } >+ >+ /** >+ * Sets the current line width in points. >+ * >+ * @param width line width in points >+ */ >+ protected void updateLineWidth(float width) { >+ this.currentLineWidth = width; >+ } >+ >+ /** >+ * Sets the current line style. The line width should be set with >+ * updateLineWidth() before calling this method >+ * >+ * @param style the constant for the style of the line as an int >+ */ >+ protected void updateLineStyle(int style) { >+ switch (style) { >+ case EN_DOTTED: >+ stroke = new BasicStroke(currentLineWidth, BasicStroke.CAP_BUTT, >+ BasicStroke.JOIN_BEVEL, 0f, new float[] { 2f }, 0f); >+ graphics.setStroke(stroke); >+ break; >+ case EN_DASHED: >+ stroke = new BasicStroke(currentLineWidth, BasicStroke.CAP_BUTT, >+ BasicStroke.JOIN_BEVEL, 0f, new float[] { 8f, 2f }, 0f); >+ graphics.setStroke(stroke); >+ break; >+ default: // EN_SOLID: >+ stroke = new BasicStroke(currentLineWidth); >+ graphics.setStroke(stroke); >+ break; >+ } >+ } >+ >+ /** >+ * Draw a line. >+ * >+ * @param startx the start x position >+ * @param starty the start y position >+ * @param endx the x end position >+ * @param endy the y end position >+ */ >+ protected void drawLine(float startx, float starty, float endx, float endy) { >+ graphics.draw(new Line2D.Float(startx, starty, endx, endy)); >+ } >+ >+ // TODO abstractize, or refactorize with putImage >+ /** >+ * @see org.apache.fop.render.AbstractRenderer#renderImage(Image, >+ * Rectangle2D) >+ */ >+ public void renderImage(Image image, Rectangle2D pos) { >+ endTextObject(); >+ String url = image.getURL(); >+ putImage(url, pos); >+ } >+ >+ /** >+ * Adds a PDF XObject (a bitmap) to the PDF that will later be referenced. >+ * >+ * @param url URL of the bitmap >+ * @param pos Position of the bitmap >+ */ >+ protected void putImage(String Purl, Rectangle2D pos) { >+ >+ int x = currentIPPosition; // TODO + area.getXOffset(); >+ int y = currentBPPosition; >+ String url = ImageFactory.getURL(Purl); >+ >+ ImageFactory fact = ImageFactory.getInstance(); >+ FopImage fopimage = fact.getImage(url, userAgent); >+ >+ if (fopimage == null) { >+ return; >+ } >+ if (!fopimage.load(FopImage.DIMENSIONS)) { >+ return; >+ } >+ int w = fopimage.getWidth(); >+ int h = fopimage.getHeight(); >+ String mime = fopimage.getMimeType(); >+ if ("text/xml".equals(mime)) { >+ if (!fopimage.load(FopImage.ORIGINAL_DATA)) { >+ return; >+ } >+ Document doc = ((XMLImage) fopimage).getDocument(); >+ String ns = ((XMLImage) fopimage).getNameSpace(); >+ renderDocument(doc, ns, pos); >+ >+ } else if ("image/svg+xml".equals(mime)) { >+ if (!fopimage.load(FopImage.ORIGINAL_DATA)) { >+ return; >+ } >+ Document doc = ((XMLImage) fopimage).getDocument(); >+ renderSVGDocument(doc, pos); // TODO check if ok. >+ >+ } else if (("image/eps".equals(mime)) || ("image/jpeg".equals(mime))) { >+ if (!fopimage.load(FopImage.ORIGINAL_DATA)) { >+ return; >+ } >+ java.awt.Image awtImage = new javax.swing.ImageIcon(url).getImage(); >+ graphics.drawImage(awtImage, (int) (x / 1000f), (int) (y / 1000f), >+ (int) w, h, null); >+ currentBPPosition += (h * 1000); // TODO doesn't work! >+ >+ } else if ("image/bmp".equals(mime)) { >+ if (!fopimage.load(FopImage.BITMAP)) { >+ return; >+ } >+ try { >+ java.awt.Image awtImage = new BMPReader().loadbitmap(url); >+ graphics.drawImage(awtImage, (int) (x / 1000f), >+ (int) (y / 1000f), (int) w, h, null); >+ } catch (Exception e) { >+ getLogger().warn(e); >+ } >+ currentBPPosition += (h * 1000); // TODO doesn't work! >+ >+ } else { >+ if (!fopimage.load(FopImage.BITMAP)) { >+ return; >+ } >+ java.awt.Image awtImage = new javax.swing.ImageIcon(url).getImage(); >+ graphics.drawImage(awtImage, (int) (x / 1000f), (int) (y / 1000f), >+ (int) w, h, null); >+ currentBPPosition += (h * 1000); // TODO doesn't work! >+ } >+ } >+ >+ /** >+ * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, >+ * Rectangle2D) >+ */ >+ public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { >+ endTextObject(); >+ Document doc = fo.getDocument(); >+ String ns = fo.getNameSpace(); >+ if (ns.equals("http://www.w3.org/2000/svg")) { >+ // FIXME ren: is this the right way to do it? >+ renderSVGDocument(doc, pos); >+ } else { >+ renderDocument(doc, ns, pos); >+ } >+ // this.currentXPosition += area.getContentWidth(); TODO >+ } >+ >+ /** >+ * Renders an XML document (SVG for example). >+ * >+ * @param doc DOM document representing the XML document >+ * @param ns Namespace for the document >+ * @param pos Position on the page >+ */ >+ public void renderDocument(Document doc, String ns, Rectangle2D pos) { >+ RendererContext context; >+ context = new RendererContext(MIME_TYPE); >+ context.setUserAgent(userAgent); >+ // TODO implement >+ /* >+ * context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc); >+ * context.setProperty(PDFXMLHandler.OUTPUT_STREAM, ostream); >+ * context.setProperty(PDFXMLHandler.PDF_STATE, currentState); >+ * context.setProperty(PDFXMLHandler.PDF_PAGE, currentPage); >+ * context.setProperty(PDFXMLHandler.PDF_CONTEXT, currentContext == null ? >+ * currentPage : currentContext); >+ * context.setProperty(PDFXMLHandler.PDF_CONTEXT, currentContext); >+ * context.setProperty(PDFXMLHandler.PDF_STREAM, currentStream); >+ * context.setProperty(PDFXMLHandler.PDF_XPOS, new >+ * Integer(currentIPPosition + (int) pos.getX())); >+ * context.setProperty(PDFXMLHandler.PDF_YPOS, new >+ * Integer(currentBPPosition + (int) pos.getY())); >+ * context.setProperty(PDFXMLHandler.PDF_FONT_INFO, fontInfo); >+ * context.setProperty(PDFXMLHandler.PDF_FONT_NAME, currentFontName); >+ * context.setProperty(PDFXMLHandler.PDF_FONT_SIZE, new >+ * Integer(currentFontSize)); >+ * context.setProperty(PDFXMLHandler.PDF_WIDTH, new Integer((int) >+ * pos.getWidth())); context.setProperty(PDFXMLHandler.PDF_HEIGHT, new >+ * Integer((int) pos.getHeight())); renderXML(userAgent, context, doc, >+ * ns); >+ */ >+ } >+ >+ protected void renderSVGDocument(Document doc, Rectangle2D pos) { >+ >+ int x = currentIPPosition; // TODO + area.getXOffset(); >+ int y = currentBPPosition; >+ >+ RendererContext context; >+ context = new RendererContext(MIME_TYPE); >+ context.setUserAgent(userAgent); >+ >+ SVGUserAgent ua = new SVGUserAgent(context.getUserAgent() >+ .getPixelUnitToMillimeter(), new AffineTransform()); >+ >+ GVTBuilder builder = new GVTBuilder(); >+ BridgeContext ctx = new BridgeContext(ua); >+ >+ GraphicsNode root; >+ try { >+ root = builder.build(ctx, doc); >+ } catch (Exception e) { >+ getLogger().error( >+ "svg graphic could not be built: " + e.getMessage(), e); >+ return; >+ } >+ float w = (float) ctx.getDocumentSize().getWidth() * 1000f; >+ float h = (float) ctx.getDocumentSize().getHeight() * 1000f; >+ >+ // correct integer roundoff TODO ren: needed? >+ graphics.translate(x / 1000, y / 1000); >+ >+ SVGSVGElement svg = ((SVGDocument) doc).getRootElement(); >+ // TODO ren: do we need the whole at-stuff? >+ AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, >+ w / 1000f, h / 1000f); >+ AffineTransform inverse = null; >+ try { >+ inverse = at.createInverse(); >+ } catch (NoninvertibleTransformException e) { >+ } >+ if (!at.isIdentity()) { >+ graphics.transform(at); >+ } >+ >+ try { >+ root.paint(graphics); >+ } catch (Exception e) { >+ e.printStackTrace(); >+ } >+ >+ if (inverse != null && !inverse.isIdentity()) { >+ graphics.transform(inverse); >+ } >+ // correct integer roundoff TODO ren: needed? >+ // graphics.translate(-x / 1000f, y / 1000f - pageHeight); >+ graphics.translate(-(x + 500) / 1000, (y + 500) / 1000 - pageHeight); >+ } > } >Index: src/java/org/apache/fop/render/pdf/PDFRenderer.java >=================================================================== >RCS file: /home/cvspublic/xml-fop/src/java/org/apache/fop/render/pdf/PDFRenderer.java,v >retrieving revision 1.81 >diff -u -r1.81 PDFRenderer.java >--- src/java/org/apache/fop/render/pdf/PDFRenderer.java 16 Feb 2005 10:15:45 -0000 1.81 >+++ src/java/org/apache/fop/render/pdf/PDFRenderer.java 27 Feb 2005 22:27:44 -0000 >@@ -19,49 +19,42 @@ > package org.apache.fop.render.pdf; > > // Java >-import java.io.IOException; >-import java.io.OutputStream; > import java.awt.Color; >-import java.awt.geom.Rectangle2D; > import java.awt.geom.AffineTransform; >+import java.awt.geom.Rectangle2D; >+import java.io.IOException; >+import java.io.OutputStream; > import java.util.Iterator; >-import java.util.Map; > import java.util.List; >+import java.util.Map; > >-// XML >-import org.w3c.dom.Document; >- >-// Avalon > import org.apache.avalon.framework.configuration.Configuration; > import org.apache.avalon.framework.configuration.ConfigurationException; >- >-// FOP > import org.apache.fop.apps.FOPException; > import org.apache.fop.apps.FOUserAgent; > import org.apache.fop.area.Area; > import org.apache.fop.area.Block; > import org.apache.fop.area.BlockViewport; >+import org.apache.fop.area.BookmarkData; > import org.apache.fop.area.CTM; > import org.apache.fop.area.LineArea; >+import org.apache.fop.area.OffDocumentItem; > import org.apache.fop.area.Page; > import org.apache.fop.area.PageViewport; >-import org.apache.fop.area.RegionViewport; > import org.apache.fop.area.Trait; >-import org.apache.fop.area.OffDocumentItem; >-import org.apache.fop.area.BookmarkData; > import org.apache.fop.area.inline.Character; >-import org.apache.fop.area.inline.InlineArea; >-import org.apache.fop.area.inline.TextArea; >-import org.apache.fop.area.inline.Viewport; > import org.apache.fop.area.inline.ForeignObject; > import org.apache.fop.area.inline.Image; >-import org.apache.fop.area.inline.Leader; > import org.apache.fop.area.inline.InlineParent; >+import org.apache.fop.area.inline.Leader; >+import org.apache.fop.area.inline.TextArea; >+import org.apache.fop.area.inline.Viewport; > import org.apache.fop.datatypes.ColorType; >-import org.apache.fop.fonts.Typeface; >+import org.apache.fop.fo.Constants; > import org.apache.fop.fonts.Font; >-import org.apache.fop.fonts.FontSetup; > import org.apache.fop.fonts.FontMetrics; >+import org.apache.fop.fonts.FontSetup; >+import org.apache.fop.fonts.Typeface; > import org.apache.fop.image.FopImage; > import org.apache.fop.image.ImageFactory; > import org.apache.fop.image.XMLImage; >@@ -83,7 +76,7 @@ > import org.apache.fop.render.PrintRenderer; > import org.apache.fop.render.RendererContext; > import org.apache.fop.traits.BorderProps; >-import org.apache.fop.fo.Constants; >+import org.w3c.dom.Document; > > > /* >@@ -162,8 +155,6 @@ > /** drawing state */ > protected PDFState currentState = null; > >- /** Name of currently selected font */ >- protected String currentFontName = ""; > /** Size of currently selected font */ > protected int currentFontSize = 0; > /** page height */ >@@ -484,6 +475,12 @@ > * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM) > */ > protected void startVParea(CTM ctm) { >+ // The CTM will transform coordinates relative to >+ // this region-reference area into page coords, so >+ // set origin for the region to 0,0. >+ currentIPPosition = 0; >+ currentBPPosition = 0; >+ > // Set the given CTM in the graphics state > currentState.push(); > currentState.setTransform( >@@ -503,27 +500,7 @@ > currentState.pop(); > } > >- /** >- * Handle the traits for a region >- * This is used to draw the traits for the given page region. >- * (See Sect. 6.4.1.2 of XSL-FO spec.) >- * @param region the RegionViewport whose region is to be drawn >- */ >- protected void handleRegionTraits(RegionViewport region) { >- currentFontName = ""; >- Rectangle2D viewArea = region.getViewArea(); >- float startx = (float)(viewArea.getX() / 1000f); >- float starty = (float)(viewArea.getY() / 1000f); >- float width = (float)(viewArea.getWidth() / 1000f); >- float height = (float)(viewArea.getHeight() / 1000f); >- >- if (region.getRegion().getRegionClass() == FO_REGION_BODY) { >- currentBPPosition = region.getBorderAndPaddingWidthBefore(); >- currentIPPosition = region.getBorderAndPaddingWidthStart(); >- } >- drawBackAndBorders(region, startx, starty, width, height); >- } >- >+ > /** > * Handle block traits. > * The block could be any sort of block with any positioning >@@ -985,14 +962,14 @@ > * Sets the current line width in points. > * @param width line width in points > */ >- private void updateLineWidth(float width) { >+ protected void updateLineWidth(float width) { > if (currentState.setLineWidth(width)) { > //Only write if value has changed WRT the current line width > currentStream.add(width + " w\n"); > } > } > >- private void updateLineStyle(int style) { >+ protected void updateLineStyle(int style) { > switch (style) { > case Constants.EN_DASHED: > currentStream.add("[3] 0 d\n"); >@@ -1042,7 +1019,7 @@ > * @param endx the x end position > * @param endy the y end position > */ >- private void drawLine(float startx, float starty, float endx, float endy) { >+ protected void drawLine(float startx, float starty, float endx, float endy) { > currentStream.add(startx + " " + starty + " m "); > currentStream.add(endx + " " + endy + " l S\n"); > } >@@ -1123,9 +1100,6 @@ > > startVParea(ctm); > >- currentIPPosition = 0; >- currentBPPosition = 0; >- > renderBlocks(bv, children); > endVParea(); > >@@ -1192,8 +1166,6 @@ > > if (ctm != null) { > startVParea(ctm); >- currentIPPosition = 0; >- currentBPPosition = 0; > } > renderBlocks(bv, children); > if (ctm != null) { >@@ -1429,7 +1401,7 @@ > prevWordX = rx; > > String s = text.getTextArea(); >- >+ System.out.println(s+" currXPos "+rx+" currYPos "+bl); > FontMetrics metrics = fontInfo.getMetricsFor(name); > Font fs = new Font(name, metrics, size); > escapeText(s, fs, useMultiByte, pdf); >@@ -1441,44 +1413,6 @@ > > super.renderText(text); > } >- >- /** >- * Paints the text decoration marks. >- * @param fs Current font >- * @param inline inline area to paint the marks for >- * @param baseline position of the baseline >- * @param startx start IPD >- */ >- protected void renderTextDecoration(Font fs, InlineArea inline, >- int baseline, int startx) { >- boolean hasTextDeco = inline.hasUnderline() >- || inline.hasOverline() >- || inline.hasLineThrough(); >- if (hasTextDeco) { >- endTextObject(); >- updateLineStyle(Constants.EN_SOLID); >- updateLineWidth(fs.getDescender() / -8 / 1000f); >- float endx = (startx + inline.getIPD()) / 1000f; >- if (inline.hasUnderline()) { >- ColorType ct = (ColorType) inline.getTrait(Trait.UNDERLINE_COLOR); >- updateColor(ct, false, null); >- float y = baseline - fs.getDescender() / 2; >- drawLine(startx / 1000f, y / 1000f, endx, y / 1000f); >- } >- if (inline.hasOverline()) { >- ColorType ct = (ColorType) inline.getTrait(Trait.OVERLINE_COLOR); >- updateColor(ct, false, null); >- float y = (float)(baseline - (1.1 * fs.getCapHeight())); >- drawLine(startx / 1000f, y / 1000f, endx, y / 1000f); >- } >- if (inline.hasLineThrough()) { >- ColorType ct = (ColorType) inline.getTrait(Trait.LINETHROUGH_COLOR); >- updateColor(ct, false, null); >- float y = (float)(baseline - (0.45 * fs.getCapHeight())); >- drawLine(startx / 1000f, y / 1000f, endx, y / 1000f); >- } >- } >- } > > /** > * Escapes text according to PDF rules. >@@ -1592,7 +1526,7 @@ > * @param pdf StringBuffer to write the PDF code to, if null, the code is > * written to the current stream. > */ >- private void updateColor(ColorType col, boolean fill, StringBuffer pdf) { >+ protected void updateColor(ColorType col, boolean fill, StringBuffer pdf) { > if (col == null) { > return; > } >Index: src/java/org/apache/fop/render/ps/PSRenderer.java >=================================================================== >RCS file: /home/cvspublic/xml-fop/src/java/org/apache/fop/render/ps/PSRenderer.java,v >retrieving revision 1.36 >diff -u -r1.36 PSRenderer.java >--- src/java/org/apache/fop/render/ps/PSRenderer.java 6 Feb 2005 20:48:48 -0000 1.36 >+++ src/java/org/apache/fop/render/ps/PSRenderer.java 27 Feb 2005 22:27:46 -0000 >@@ -24,12 +24,11 @@ > import java.io.OutputStream; > import java.util.List; > >-// FOP > import org.apache.avalon.framework.configuration.Configuration; > import org.apache.avalon.framework.configuration.ConfigurationException; >-import org.apache.fop.area.Area; >-import org.apache.fop.area.RegionViewport; > import org.apache.fop.apps.FOPException; >+import org.apache.fop.apps.FOUserAgent; >+import org.apache.fop.area.Area; > import org.apache.fop.area.Block; > import org.apache.fop.area.BlockViewport; > import org.apache.fop.area.CTM; >@@ -38,16 +37,13 @@ > import org.apache.fop.area.inline.ForeignObject; > import org.apache.fop.area.inline.TextArea; > import org.apache.fop.datatypes.ColorType; >-import org.apache.fop.apps.FOUserAgent; > import org.apache.fop.fonts.FontSetup; > import org.apache.fop.fonts.Typeface; >-import org.apache.fop.render.PrintRenderer; >-import org.apache.fop.render.RendererContext; >- > import org.apache.fop.image.FopImage; > import org.apache.fop.image.ImageFactory; >+import org.apache.fop.render.PrintRenderer; >+import org.apache.fop.render.RendererContext; > import org.apache.fop.traits.BorderProps; >- > import org.w3c.dom.Document; > > /** >@@ -507,9 +503,6 @@ > > if (bv.getPositioning() == Block.ABSOLUTE) { > >- currentIPPosition = 0; >- currentBPPosition = 0; >- > //closeText(); > endTextObject(); > >@@ -603,6 +596,12 @@ > * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM) > */ > protected void startVParea(CTM ctm) { >+ // The CTM will transform coordinates relative to >+ // this region-reference area into page coords, so >+ // set origin for the region to 0,0. >+ currentIPPosition = 0; >+ currentBPPosition = 0; >+ > // Set the given CTM in the graphics state > //currentState.push(); > //currentState.setTransform(new AffineTransform(CTMHelper.toPDFArray(ctm))); >@@ -625,27 +624,7 @@ > restoreGraphicsState(); > //currentState.pop(); > } >- >- /** >- * Handle the traits for a region >- * This is used to draw the traits for the given page region. >- * (See Sect. 6.4.1.2 of XSL-FO spec.) >- * @param region the RegionViewport whose region is to be drawn >- */ >- protected void handleRegionTraits(RegionViewport region) { >- currentFontName = ""; >- float startx = 0; >- float starty = 0; >- Rectangle2D viewArea = region.getViewArea(); >- float width = (float)(viewArea.getWidth()); >- float height = (float)(viewArea.getHeight()); >- /* >- Trait.Background back; >- back = (Trait.Background)region.getTrait(Trait.BACKGROUND); >- */ >- drawBackAndBorders(region, startx, starty, width, height); >- } >- >+ > /** > * Handle block traits. > * The block could be any sort of block with any positioning >@@ -793,7 +772,7 @@ > * @param endx the x end position > * @param endy the y end position > */ >- private void drawLine(float startx, float starty, float endx, float endy) { >+ protected void drawLine(float startx, float starty, float endx, float endy) { > writeln(startx + " " + starty + " M "); > writeln(endx + " " + endy + " lineto"); > } >Index: src/java/org/apache/fop/render/awt/BMPReader.java >=================================================================== >RCS file: src/java/org/apache/fop/render/awt/BMPReader.java >diff -N src/java/org/apache/fop/render/awt/BMPReader.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/java/org/apache/fop/render/awt/BMPReader.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,185 @@ >+package org.apache.fop.render.awt; >+ >+import java.awt.Component; >+import java.awt.Container; >+import java.awt.Image; >+import java.awt.image.MemoryImageSource; >+import java.io.BufferedInputStream; >+import java.io.FileInputStream; >+import java.io.IOException; >+ >+import org.apache.commons.logging.Log; >+import org.apache.commons.logging.LogFactory; >+import org.apache.fop.apps.FOPException; >+ >+/** >+ * Class used to load windows bitmap images (.bmp) >+ * >+ * see http://www.javaworld.com/javaworld/javatips/jw-javatip43.html >+ * >+ */ >+public class BMPReader { >+ >+ /** logging instance */ >+ protected static Log logger = LogFactory.getLog("org.apache.fop.render"); >+ >+ private Image image; >+ >+ private BufferedInputStream bs; >+ >+ /** >+ * Loads a Bitmap from an url pointing to a .bmp-file. Reads only >+ * uncompressed 24- and 8-bit images. >+ * >+ * @param url >+ * the url of the bitmap >+ * @return Image the bitmap as an awt.Image >+ * @throws IOException >+ * if the url cannot be read >+ * @throws FOPException >+ * if the image is not a 24- or 8-bit image or if it is >+ * compressed >+ */ >+ public Image loadbitmap(String url) throws IOException, FOPException { >+ >+ bs = new BufferedInputStream(new FileInputStream(url)); >+ int bflen = 14; // 14 byte BITMAPFILEHEADER >+ byte bf[] = new byte[bflen]; >+ bs.read(bf, 0, bflen); >+ int bilen = 40; // 40-byte BITMAPINFOHEADER >+ byte bi[] = new byte[bilen]; >+ bs.read(bi, 0, bilen); >+ >+ // Interperet data. >+ int nsize = (((int) bf[5] & 0xff) << 24) | (((int) bf[4] & 0xff) << 16) >+ | (((int) bf[3] & 0xff) << 8) | (int) bf[2] & 0xff; >+ int nbisize = (((int) bi[3] & 0xff) << 24) >+ | (((int) bi[2] & 0xff) << 16) | (((int) bi[1] & 0xff) << 8) >+ | (int) bi[0] & 0xff; >+ int nwidth = (((int) bi[7] & 0xff) << 24) >+ | (((int) bi[6] & 0xff) << 16) | (((int) bi[5] & 0xff) << 8) >+ | (int) bi[4] & 0xff; >+ int nheight = (((int) bi[11] & 0xff) << 24) >+ | (((int) bi[10] & 0xff) << 16) | (((int) bi[9] & 0xff) << 8) >+ | (int) bi[8] & 0xff; >+ int nplanes = (((int) bi[13] & 0xff) << 8) | (int) bi[12] & 0xff; >+ int nbitcount = (((int) bi[15] & 0xff) << 8) | (int) bi[14] & 0xff; >+ >+ // Look for non-zero values to indicate compression >+ int ncompression = (((int) bi[19]) << 24) | (((int) bi[18]) << 16) >+ | (((int) bi[17]) << 8) | (int) bi[16]; >+ if (ncompression != 0) { >+ bs.close(); >+ throw new FOPException("Bitmap" + url + "could not be rendered. " >+ + "FOP only supports non-compressed Windows Bitmap"); >+ } >+ int nsizeimage = (((int) bi[23] & 0xff) << 24) >+ | (((int) bi[22] & 0xff) << 16) | (((int) bi[21] & 0xff) << 8) >+ | (int) bi[20] & 0xff; >+ int nxpm = (((int) bi[27] & 0xff) << 24) >+ | (((int) bi[26] & 0xff) << 16) | (((int) bi[25] & 0xff) << 8) >+ | (int) bi[24] & 0xff; >+ int nypm = (((int) bi[31] & 0xff) << 24) >+ | (((int) bi[30] & 0xff) << 16) | (((int) bi[29] & 0xff) << 8) >+ | (int) bi[28] & 0xff; >+ int nclrused = (((int) bi[35] & 0xff) << 24) >+ | (((int) bi[34] & 0xff) << 16) | (((int) bi[33] & 0xff) << 8) >+ | (int) bi[32] & 0xff; >+ int nclrimp = (((int) bi[39] & 0xff) << 24) >+ | (((int) bi[38] & 0xff) << 16) | (((int) bi[37] & 0xff) << 8) >+ | (int) bi[36] & 0xff; >+ >+ logger.debug("Rendering Bitmap" + url + "Colors important are :" >+ + nclrimp + "File type is :" + (char) bf[0] + (char) bf[1] >+ + "Size of file is :" + nsize + "Size of bitmapinfoheader is :" >+ + nbisize + "Width is :" + nwidth + "Height is :" + nheight >+ + "Planes is :" + nplanes + "BitCount is :" + nbitcount >+ + "Compression is :" + ncompression + "SizeImage is :" >+ + nsizeimage + "X-Pixels per meter is :" + nxpm >+ + "Y-Pixels per meter is :" + nypm + "Colors used are :" >+ + nclrused); >+ >+ if (nbitcount == 24) { >+ // No Palatte data for 24-bit format but scan lines are >+ // padded out to even 4-byte boundaries. >+ int npad = (nsizeimage / nheight) - nwidth * 3; >+ if (npad == 4) >+ npad = 0; // corrected >+ int ndata[] = new int[nheight * nwidth]; >+ byte brgb[] = new byte[(nwidth + npad) * 3 * nheight]; >+ bs.read(brgb, 0, (nwidth + npad) * 3 * nheight); >+ int nindex = 0; >+ for (int j = 0; j < nheight; j++) { >+ for (int i = 0; i < nwidth; i++) { >+ ndata[nwidth * (nheight - j - 1) + i] = (255 & 0xff) << 24 >+ | (((int) brgb[nindex + 2] & 0xff) << 16) >+ | (((int) brgb[nindex + 1] & 0xff) << 8) >+ | (int) brgb[nindex] & 0xff; >+ >+ nindex += 3; >+ } >+ nindex += npad; >+ } >+ >+ Component c = new Container(); >+ image = c.createImage(new MemoryImageSource(nwidth, nheight, ndata, >+ 0, nwidth)); >+ } else if (nbitcount == 8) { >+ // Have to determine the number of colors, the clrsused >+ // parameter is dominant if it is greater than zero. If >+ // zero, calculate colors based on bitsperpixel. >+ int nNumColors = 0; >+ if (nclrused > 0) { >+ nNumColors = nclrused; >+ } else { >+ nNumColors = (1 & 0xff) << nbitcount; >+ } >+ >+ // Some bitmaps do not have the sizeimage field calculated >+ // Ferret out these cases and fix 'em. >+ if (nsizeimage == 0) { >+ nsizeimage = ((((nwidth * nbitcount) + 31) & ~31) >> 3); >+ nsizeimage *= nheight; >+ } >+ >+ // Read the palatte colors. >+ int npalette[] = new int[nNumColors]; >+ byte bpalette[] = new byte[nNumColors * 4]; >+ bs.read(bpalette, 0, nNumColors * 4); >+ int nindex8 = 0; >+ for (int n = 0; n < nNumColors; n++) { >+ npalette[n] = (255 & 0xff) << 24 >+ | (((int) bpalette[nindex8 + 2] & 0xff) << 16) >+ | (((int) bpalette[nindex8 + 1] & 0xff) << 8) >+ | (int) bpalette[nindex8] & 0xff; >+ } >+ >+ // Read the image data (actually indices into the palette) >+ // Scan lines are still padded out to even 4-byte >+ // boundaries. >+ int npad8 = (nsizeimage / nheight) - nwidth; >+ int ndata8[] = new int[nwidth * nheight]; >+ byte bdata[] = new byte[(nwidth + npad8) * nheight]; >+ bs.read(bdata, 0, (nwidth + npad8) * nheight); >+ nindex8 = 0; >+ for (int j8 = 0; j8 < nheight; j8++) { >+ for (int i8 = 0; i8 < nwidth; i8++) { >+ ndata8[nwidth * (nheight - j8 - 1) + i8] = npalette[((int) bdata[nindex8] & 0xff)]; >+ nindex8++; >+ } >+ nindex8 += npad8; >+ } >+ >+ Component c = new Container(); >+ image = c.createImage(new MemoryImageSource(nwidth, nheight, >+ ndata8, 0, nwidth)); >+ } else { >+ throw new FOPException("Bitmap" + url + "could not be rendered. " >+ + "FOP only supports 24-bit or 8-bit Windows Bitmap"); >+ } >+ >+ bs.close(); >+ return image; >+ >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 33760
:
14371
|
14372
|
14426
|
14520
|
15340