diff options
Diffstat (limited to 'src/java/org/apache/fop')
20 files changed, 398 insertions, 105 deletions
diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java index f6bb52cb3..1f782b2ea 100644 --- a/src/java/org/apache/fop/fonts/CustomFont.java +++ b/src/java/org/apache/fop/fonts/CustomFont.java @@ -190,12 +190,17 @@ public abstract class CustomFont extends Typeface return fontBBox; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public int getFlags() { return flags; } + + /** {@inheritDoc} */ + public boolean isSymbolicFont() { + return ((getFlags() & 4) != 0) || "ZapfDingbatsEncoding".equals(getEncodingName()); + //Note: The check for ZapfDingbats is necessary as the PFM does not reliably indicate + //if a font is symbolic. + } /** * Returns the font weight (100, 200...800, 900). This value may be different from the diff --git a/src/java/org/apache/fop/fonts/FontDescriptor.java b/src/java/org/apache/fop/fonts/FontDescriptor.java index 841d99de2..fb9c7d02e 100644 --- a/src/java/org/apache/fop/fonts/FontDescriptor.java +++ b/src/java/org/apache/fop/fonts/FontDescriptor.java @@ -53,7 +53,11 @@ public interface FontDescriptor extends FontMetrics { */ int getFlags(); - + /** + * Indicates whether the font is a symbolic font. + * @return true if the font is a symbolic font (i.e. Symbol or ZapfDingbats) + */ + boolean isSymbolicFont(); /** * Returns the font's bounding box. * @return the bounding box diff --git a/src/java/org/apache/fop/fonts/FontReader.java b/src/java/org/apache/fop/fonts/FontReader.java index 51d90c7e5..6f148f503 100644 --- a/src/java/org/apache/fop/fonts/FontReader.java +++ b/src/java/org/apache/fop/fonts/FontReader.java @@ -27,8 +27,6 @@ import java.util.Set; import javax.xml.parsers.SAXParserFactory; -import org.apache.fop.apps.FOPException; -import org.apache.fop.fonts.apps.TTFReader; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.Locator; @@ -36,6 +34,9 @@ import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; +import org.apache.fop.apps.FOPException; +import org.apache.fop.fonts.apps.TTFReader; + /** * Class for reading a metric.xml file and creating a font object. * Typical usage: @@ -228,11 +229,11 @@ public class FontReader extends DefaultHandler { if ("font-name".equals(localName)) { returnFont.setFontName(content); } else if ("full-name".equals(localName)) { - multiFont.setFullName(content); + returnFont.setFullName(content); } else if ("family-name".equals(localName)) { Set s = new java.util.HashSet(); s.add(content); - multiFont.setFamilyNames(s); + returnFont.setFamilyNames(s); } else if ("ttc-name".equals(localName) && isCID) { multiFont.setTTCName(content); } else if ("encoding".equals(localName)) { diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java index b4f7773a3..70b971fff 100644 --- a/src/java/org/apache/fop/fonts/LazyFont.java +++ b/src/java/org/apache/fop/fonts/LazyFont.java @@ -321,14 +321,18 @@ public class LazyFont extends Typeface implements FontDescriptor { return realFontDescriptor.getAscender(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public int getFlags() { load(true); return realFontDescriptor.getFlags(); } + /** {@inheritDoc} */ + public boolean isSymbolicFont() { + load(true); + return realFontDescriptor.isSymbolicFont(); + } + /** * {@inheritDoc} */ diff --git a/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java index 55a7ae1c0..d59fd5c7e 100644 --- a/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java +++ b/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java @@ -32,6 +32,7 @@ public class UnixFontDirFinder extends NativeFontDirFinder { return new String[] { System.getProperty("user.home") + "/.fonts", // user "/usr/local/fonts", // local + "/usr/local/share/fonts", // local shared "/usr/share/fonts", // system "/usr/X11R6/lib/X11/fonts" // X }; diff --git a/src/java/org/apache/fop/layoutmgr/table/RowPainter.java b/src/java/org/apache/fop/layoutmgr/table/RowPainter.java index bed9c53ae..d432c7657 100644 --- a/src/java/org/apache/fop/layoutmgr/table/RowPainter.java +++ b/src/java/org/apache/fop/layoutmgr/table/RowPainter.java @@ -229,8 +229,12 @@ class RowPainter { // Then add areas for cells finishing on the current row for (int i = 0; i < colCount; i++) { - GridUnit currentGU = currentRow.getGridUnit(i); - if (!currentGU.isEmpty() && currentGU.getColSpanIndex() == 0 + GridUnit currentGU = currentRow.getGridUnit(i); + if (currentGU.isEmpty()) { + // TODO remove once missing cells are properly implemented (i.e., replaced + // by an fo:table-cell element containing an empty fo:block) + firstCellOnPage[i] = false; + } else if (currentGU.getColSpanIndex() == 0 && (lastInPart || currentGU.isLastGridUnitRowSpan()) && firstCellParts[i] != null) { assert firstCellParts[i].pgu == currentGU.getPrimary(); @@ -260,7 +264,8 @@ class RowPainter { actualRowHeight, borderBeforeWhich, borderAfterWhich, lastOnPage); firstCellParts[i] = null; - firstCellOnPage[i] = false; + Arrays.fill(firstCellOnPage, i, i + currentGU.getCell().getNumberColumnsSpanned(), + false); } } currentRowOffset += actualRowHeight; diff --git a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java index 7a2ee171c..9b4a03a67 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; import java.util.Map; import org.apache.commons.logging.Log; @@ -41,6 +42,7 @@ import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; +import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.KnuthPossPosIter; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.ListElement; @@ -232,6 +234,17 @@ public class TableContentLayoutManager implements PercentBaseContext { //Get elements for next row group nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType); + /* + * The last break element produced by TableStepper (for the previous row + * group) may be used to represent the break between the two row groups. + * Its penalty value and break class must just be overridden by the + * characteristics of the keep or break between the two. + * + * However, we mustn't forget that if the after border of the last row of + * the row group is thicker in the normal case than in the trailing case, + * an additional glue will be appended to the element list. So we may have + * to go two steps backwards in the list. + */ //Determine keep constraints int penaltyStrength = BlockLevelLayoutManager.KEEP_AUTO; @@ -246,24 +259,35 @@ public class TableContentLayoutManager implements PercentBaseContext { if (breakBetween != Constants.EN_AUTO) { penaltyValue = -KnuthElement.INFINITE; } - TableHFPenaltyPosition penaltyPos = new TableHFPenaltyPosition(getTableLM()); - int penaltyLen = 0; - if (bodyType == TableRowIterator.BODY) { - if (!getTableLM().getTable().omitHeaderAtBreak()) { - penaltyLen += getHeaderNetHeight(); - penaltyPos.headerElements = getHeaderElements(); - } - if (!getTableLM().getTable().omitFooterAtBreak()) { - penaltyLen += getFooterNetHeight(); - penaltyPos.footerElements = getFooterElements(); - } + BreakElement breakElement; + ListIterator elemIter = returnList.listIterator(returnList.size()); + ListElement elem = (ListElement) elemIter.previous(); + if (elem instanceof KnuthGlue) { + breakElement = (BreakElement) elemIter.previous(); + } else { + breakElement = (BreakElement) elem; } - returnList.add(new BreakElement(penaltyPos, - penaltyLen, penaltyValue, breakBetween, context)); + breakElement.setPenaltyValue(penaltyValue); + breakElement.setBreakClass(breakBetween); returnList.addAll(nextRowGroupElems); breakBetween = context.getBreakAfter(); } } + /* + * The last break produced for the last row-group of this table part must be + * removed, because the breaking after the table will be handled by TableLM. + * Unless the element list ends with a glue, which must be kept to accurately + * represent the content. In such a case the break is simply disabled by setting + * its penalty to infinite. + */ + ListIterator elemIter = returnList.listIterator(returnList.size()); + ListElement elem = (ListElement) elemIter.previous(); + if (elem instanceof KnuthGlue) { + BreakElement breakElement = (BreakElement) elemIter.previous(); + breakElement.setPenaltyValue(KnuthElement.INFINITE); + } else { + elemIter.remove(); + } context.updateKeepWithPreviousPending(keepWithPrevious); context.setBreakBefore(breakBefore); diff --git a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java index 7c963338f..6aa619368 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java @@ -282,13 +282,8 @@ public class TableStepper { laststep = step; step = getNextStep(); } while (step >= 0); - if (!returnList.isEmpty()) { - lastTCPos.setFlag(TableContentPosition.LAST_IN_ROWGROUP, true); - // It's not up to TableStepper to decide whether there can/must be a break - // after the row group or not, but to ancestor stacking elements - assert returnList.getLast() instanceof BreakElement; - returnList.removeLast(); - } + assert !returnList.isEmpty(); + lastTCPos.setFlag(TableContentPosition.LAST_IN_ROWGROUP, true); return returnList; } diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java index 02f0c2cdb..6211b5da7 100644 --- a/src/java/org/apache/fop/pdf/PDFFactory.java +++ b/src/java/org/apache/fop/pdf/PDFFactory.java @@ -1203,10 +1203,11 @@ public class PDFFactory { PDFFontDescriptor pdfdesc = makeFontDescriptor(descriptor); PDFFont font = null; - font = PDFFont.createFont(fontname, fonttype, basefont, encoding); + font = PDFFont.createFont(fontname, fonttype, basefont, null); getDocument().registerObject(font); if (fonttype == FontType.TYPE0) { + font.setEncoding(encoding); CIDFont cidMetrics; if (metrics instanceof LazyFont) { cidMetrics = (CIDFont)((LazyFont) metrics).getRealFont(); @@ -1252,7 +1253,9 @@ public class PDFFactory { //Handle encoding SingleByteEncoding mapping = singleByteFont.getEncoding(); - if (PDFEncoding.isPredefinedEncoding(mapping.getName())) { + if (singleByteFont.isSymbolicFont()) { + //no encoding, use the font's encoding + } else if (PDFEncoding.isPredefinedEncoding(mapping.getName())) { font.setEncoding(mapping.getName()); } else { Object pdfEncoding = createPDFEncoding(mapping, diff --git a/src/java/org/apache/fop/pdf/PDFFont.java b/src/java/org/apache/fop/pdf/PDFFont.java index 14f1a657c..1f76f1e11 100644 --- a/src/java/org/apache/fop/pdf/PDFFont.java +++ b/src/java/org/apache/fop/pdf/PDFFont.java @@ -62,8 +62,6 @@ public class PDFFont extends PDFDictionary { setEncoding((PDFEncoding)encoding); } else if (encoding instanceof String) { setEncoding((String)encoding); - } else { - throw new IllegalArgumentException("Illegal value for encoding"); } } diff --git a/src/java/org/apache/fop/pdf/PDFResources.java b/src/java/org/apache/fop/pdf/PDFResources.java index b0c0128e1..da213bb87 100644 --- a/src/java/org/apache/fop/pdf/PDFResources.java +++ b/src/java/org/apache/fop/pdf/PDFResources.java @@ -28,6 +28,8 @@ import java.util.Set; import org.apache.fop.fonts.FontDescriptor; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.Typeface; +import org.apache.fop.fonts.base14.Symbol; +import org.apache.fop.fonts.base14.ZapfDingbats; import org.apache.fop.util.ColorProfileUtil; /** @@ -109,8 +111,12 @@ public class PDFResources extends PDFObject { if (font instanceof FontDescriptor) { desc = (FontDescriptor)font; } + String encoding = font.getEncodingName(); + if (font instanceof Symbol || font instanceof ZapfDingbats) { + encoding = null; //Symbolic fonts shouldn't specify an encoding value in PDF + } addFont(doc.getFactory().makeFont( - f, font.getEmbedFontName(), font.getEncodingName(), font, desc)); + f, font.getEmbedFontName(), encoding, font, desc)); } } } diff --git a/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java index dd1a4dd7c..19796eada 100644 --- a/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java @@ -32,12 +32,13 @@ import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.Raster; import java.awt.image.WritableRaster; +import java.io.IOException; import org.apache.fop.render.RendererContext.RendererContextWrapper; import org.apache.fop.util.UnitConv; /** - * Graphics2DAdapter implementation for PCL and HP GL/2. + * Abstract base class for Graphics2DAdapter implementations. */ public abstract class AbstractGraphics2DAdapter implements Graphics2DAdapter { @@ -134,4 +135,12 @@ public abstract class AbstractGraphics2DAdapter implements Graphics2DAdapter { g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); } + /** {@inheritDoc} */ + public void paintImage(Graphics2DImagePainter painter, + RendererContext context, + int x, int y, int width, int height) throws IOException { + paintImage((org.apache.xmlgraphics.java2d.Graphics2DImagePainter)painter, + context, x, y, width, height); + } + } diff --git a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java index 0c5732ac7..86210b07a 100644 --- a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java +++ b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java @@ -37,6 +37,7 @@ import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.area.BlockViewport; import org.apache.fop.area.CTM; +import org.apache.fop.area.NormalFlow; import org.apache.fop.area.RegionViewport; import org.apache.fop.area.Trait; import org.apache.fop.area.inline.ForeignObject; @@ -520,6 +521,69 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { } } + /** {@inheritDoc} */ + protected void renderReferenceArea(Block block) { + // save position and offset + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + //Establish a new coordinate system + AffineTransform at = new AffineTransform(); + at.translate(currentIPPosition, currentBPPosition); + at.translate(block.getXOffset(), block.getYOffset()); + at.translate(0, block.getSpaceBefore()); + + if (!at.isIdentity()) { + saveGraphicsState(); + concatenateTransformationMatrix(mptToPt(at)); + } + + currentIPPosition = 0; + currentBPPosition = 0; + handleBlockTraits(block); + + List children = block.getChildAreas(); + if (children != null) { + renderBlocks(block, children); + } + + if (!at.isIdentity()) { + restoreGraphicsState(); + } + + // stacked and relative blocks effect stacking + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } + + /** {@inheritDoc} */ + protected void renderFlow(NormalFlow flow) { + // save position and offset + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + //Establish a new coordinate system + AffineTransform at = new AffineTransform(); + at.translate(currentIPPosition, currentBPPosition); + + if (!at.isIdentity()) { + saveGraphicsState(); + concatenateTransformationMatrix(mptToPt(at)); + } + + currentIPPosition = 0; + currentBPPosition = 0; + super.renderFlow(flow); + + if (!at.isIdentity()) { + restoreGraphicsState(); + } + + // stacked and relative blocks effect stacking + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } + /** * Concatenates the current transformation matrix with the given one, therefore establishing * a new coordinate system. diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java index 816fa4067..20eceac8c 100644 --- a/src/java/org/apache/fop/render/AbstractRenderer.java +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -484,6 +484,13 @@ public abstract class AbstractRenderer } /** + * Renders a block area that represents a reference area. The reference area establishes + * a new coordinate system. + * @param block the block area + */ + protected abstract void renderReferenceArea(Block block); + + /** * Renders a list of block areas. * * @param parent the parent block if the parent is a block, otherwise @@ -551,6 +558,8 @@ public abstract class AbstractRenderer // simply move position currentBPPosition += block.getAllocBPD(); } + } else if (Boolean.TRUE.equals(block.getTrait(Trait.IS_REFERENCE_AREA))) { + renderReferenceArea(block); } else { // save position and offset int saveIP = currentIPPosition; diff --git a/src/java/org/apache/fop/render/Graphics2DAdapter.java b/src/java/org/apache/fop/render/Graphics2DAdapter.java index 0123e04a1..4fbdbe09a 100644 --- a/src/java/org/apache/fop/render/Graphics2DAdapter.java +++ b/src/java/org/apache/fop/render/Graphics2DAdapter.java @@ -47,4 +47,23 @@ public interface Graphics2DAdapter { RendererContext context, int x, int y, int width, int height) throws IOException; + /** + * Paints an arbitrary images on a given Graphics2D instance. The renderer + * providing this functionality must set up a Graphics2D instance so that + * the image with the given extents (in mpt) can be painted by the painter + * passed to this method. The Graphics2DImagePainter is then passed this + * Graphics2D instance so the image can be painted. + * @param painter the painter which will paint the actual image + * @param context the renderer context for the current renderer + * @param x X position of the image + * @param y Y position of the image + * @param width width of the image + * @param height height of the image + * @throws IOException In case of an I/O error while writing the output format + * @deprecated Use the variant with the Graphics2DImagePainter from XML Graphics Commons instead + */ + void paintImage(Graphics2DImagePainter painter, + RendererContext context, + int x, int y, int width, int height) throws IOException; + } diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java index bfdf56d2b..790732c12 100644 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java @@ -57,6 +57,7 @@ import org.apache.fop.area.BlockViewport; import org.apache.fop.area.BodyRegion; import org.apache.fop.area.CTM; import org.apache.fop.area.LineArea; +import org.apache.fop.area.NormalFlow; import org.apache.fop.area.OffDocumentItem; import org.apache.fop.area.PageViewport; import org.apache.fop.area.RegionReference; @@ -488,45 +489,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } } -// /** -// * {@inheritDoc} -// */ -// protected void drawBackAndBorders(Area area, float startx, float starty, -// float width, float height) { -// super.drawBackAndBorders(area, startx, starty, width, height); -// Trait.Background back = (Trait.Background) area -// .getTrait(Trait.BACKGROUND); -// -// // the current block has a background so its contents are placed inside -// // an overlay -// // after drawing the background and borders -// if (back != null) { -// int x = pts2units(startx); -// int y = pts2units(starty); -// int w = mpts2units(width); -// int h = mpts2units(height); -// int res = getResolution(); -// final int rotation = 0; -// getAFPDataStream().startOverlay(x, y, w, h, res, res, rotation); -//// Color col = back.getColor(); -//// getAFPDataStream().createShading(x, y, w, h, col); -// } -// } -// -//// /** -//// * {@inheritDoc} -//// */ -// protected void renderBlock(Block block) { -//// // new block so start page segment -////// getAFPDataStream().startPageSegment(); -// super.renderBlock(block); -// getAFPDataStream().endOverlay(); -////// getAFPDataStream().endPageSegment(); -// } - - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void renderBlockViewport(BlockViewport bv, List children) { // clip and position viewport if necessary @@ -659,6 +622,76 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } /** {@inheritDoc} */ + protected void renderReferenceArea(Block block) { + //TODO Remove this method once concatenateTransformationMatrix() is implemented + + // save position and offset + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + //Establish a new coordinate system + AffineTransform at = new AffineTransform(); + at.translate(currentIPPosition, currentBPPosition); + at.translate(block.getXOffset(), block.getYOffset()); + at.translate(0, block.getSpaceBefore()); + + if (!at.isIdentity()) { + Rectangle2D contentRect + = new Rectangle2D.Double(at.getTranslateX(), at.getTranslateY(), + block.getAllocIPD(), block.getAllocBPD()); + pushViewPortPos(new ViewPortPos(contentRect, new CTM(at))); + } + + currentIPPosition = 0; + currentBPPosition = 0; + handleBlockTraits(block); + + List children = block.getChildAreas(); + if (children != null) { + renderBlocks(block, children); + } + + if (!at.isIdentity()) { + popViewPortPos(); + } + + // stacked and relative blocks effect stacking + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } + + /** {@inheritDoc} */ + protected void renderFlow(NormalFlow flow) { + // save position and offset + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + //Establish a new coordinate system + AffineTransform at = new AffineTransform(); + at.translate(currentIPPosition, currentBPPosition); + + if (!at.isIdentity()) { + Rectangle2D contentRect + = new Rectangle2D.Double(at.getTranslateX(), at.getTranslateY(), + flow.getAllocIPD(), flow.getAllocBPD()); + pushViewPortPos(new ViewPortPos(contentRect, new CTM(at))); + } + + currentIPPosition = 0; + currentBPPosition = 0; + super.renderFlow(flow); + + if (!at.isIdentity()) { + popViewPortPos(); + } + + // stacked and relative blocks effect stacking + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } + + + /** {@inheritDoc} */ protected void concatenateTransformationMatrix(AffineTransform at) { // Not used here since AFPRenderer defines its own renderBlockViewport() // method. @@ -1104,23 +1137,24 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } } - /** - * Restores the state stack after a break out. - * - * @param breakOutList - * the state stack to restore. - */ - public void restoreStateStackAfterBreakOut(List breakOutList) { - + /** {@inheritDoc} */ + public List breakOutOfStateStack() { + log.debug("Block.FIXED --> break out"); + List breakOutList = new java.util.ArrayList(); + //Don't pop the last ViewPortPos (created by renderPage()) + while (this.viewPortPositions.size() > 1) { + breakOutList.add(0, popViewPortPos()); + } + return breakOutList; } - /** - * Breaks out of the state stack to handle fixed block-containers. - * - * @return the saved state stack to recreate later - */ - public List breakOutOfStateStack() { - return null; + /** {@inheritDoc} */ + public void restoreStateStackAfterBreakOut(List breakOutList) { + log.debug("Block.FIXED --> restoring context after break-out"); + for (int i = 0, c = breakOutList.size(); i < c; i++) { + ViewPortPos vps = (ViewPortPos)breakOutList.get(i); + pushViewPortPos(vps); + } } /** Saves the graphics state of the rendering engine. */ @@ -1609,13 +1643,14 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { getAFPDataStream().setOffsets(vpp.x, vpp.y, vpp.rot); } - private void popViewPortPos() { - viewPortPositions.remove(viewPortPositions.size() - 1); + private ViewPortPos popViewPortPos() { + ViewPortPos current = (ViewPortPos)viewPortPositions.remove(viewPortPositions.size() - 1); if (viewPortPositions.size() > 0) { ViewPortPos vpp = (ViewPortPos) viewPortPositions .get(viewPortPositions.size() - 1); getAFPDataStream().setOffsets(vpp.x, vpp.y, vpp.rot); } + return current; } /** diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderer.java b/src/java/org/apache/fop/render/pcl/PCLRenderer.java index 11e78ea97..10d66fb4e 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRenderer.java +++ b/src/java/org/apache/fop/render/pcl/PCLRenderer.java @@ -66,6 +66,7 @@ import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.area.BlockViewport; import org.apache.fop.area.CTM; +import org.apache.fop.area.NormalFlow; import org.apache.fop.area.PageViewport; import org.apache.fop.area.RegionViewport; import org.apache.fop.area.Trait; @@ -1028,6 +1029,79 @@ public class PCLRenderer extends PrintRenderer { //currentFontName = saveFontName; } + /** {@inheritDoc} */ + protected void renderReferenceArea(Block block) { + //TODO This is the same code as in AbstractPathOrientedRenderer + //So there's some optimization potential but not otherwise PCLRenderer is a little + //difficult to derive from AbstractPathOrientedRenderer. Maybe an additional layer + //between PrintRenderer and AbstractPathOrientedRenderer is necessary. + + // save position and offset + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + //Establish a new coordinate system + AffineTransform at = new AffineTransform(); + at.translate(currentIPPosition, currentBPPosition); + at.translate(block.getXOffset(), block.getYOffset()); + at.translate(0, block.getSpaceBefore()); + + if (!at.isIdentity()) { + saveGraphicsState(); + concatenateTransformationMatrix(mptToPt(at)); + } + + currentIPPosition = 0; + currentBPPosition = 0; + handleBlockTraits(block); + + List children = block.getChildAreas(); + if (children != null) { + renderBlocks(block, children); + } + + if (!at.isIdentity()) { + restoreGraphicsState(); + } + + // stacked and relative blocks effect stacking + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } + + /** {@inheritDoc} */ + protected void renderFlow(NormalFlow flow) { + //TODO This is the same code as in AbstractPathOrientedRenderer + //So there's some optimization potential but not otherwise PCLRenderer is a little + //difficult to derive from AbstractPathOrientedRenderer. Maybe an additional layer + //between PrintRenderer and AbstractPathOrientedRenderer is necessary. + + // save position and offset + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + //Establish a new coordinate system + AffineTransform at = new AffineTransform(); + at.translate(currentIPPosition, currentBPPosition); + + if (!at.isIdentity()) { + saveGraphicsState(); + concatenateTransformationMatrix(mptToPt(at)); + } + + currentIPPosition = 0; + currentBPPosition = 0; + super.renderFlow(flow); + + if (!at.isIdentity()) { + restoreGraphicsState(); + } + + // stacked and relative blocks effect stacking + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } + /** * Concatenates the current transformation matrix with the given one, therefore establishing * a new coordinate system. diff --git a/src/java/org/apache/fop/render/ps/PSImageUtils.java b/src/java/org/apache/fop/render/ps/PSImageUtils.java new file mode 100644 index 000000000..27eb736d8 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSImageUtils.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.ps; + +/** + * Utility code for rendering images in PostScript. + * @deprecated Kept for compatibility with older FOP extensions (like Barcode4J). Use the + * super-class instead. + */ +public class PSImageUtils extends org.apache.xmlgraphics.ps.PSImageUtils { + +} diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java index eb3c92e1b..94cd107c7 100644 --- a/src/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -754,9 +754,17 @@ public class XMLRenderer extends PrintRenderer { endElement("flow"); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + protected void renderReferenceArea(Block block) { + handleBlockTraits(block); + + List children = block.getChildAreas(); + if (children != null) { + renderBlocks(block, children); + } + } + + /** {@inheritDoc} */ protected void renderBlock(Block block) { atts.clear(); addAreaAttributes(block); diff --git a/src/java/org/apache/fop/util/CloseBlockerOutputStream.java b/src/java/org/apache/fop/util/CloseBlockerOutputStream.java index 7192e76d2..c0db8c8b7 100644 --- a/src/java/org/apache/fop/util/CloseBlockerOutputStream.java +++ b/src/java/org/apache/fop/util/CloseBlockerOutputStream.java @@ -19,25 +19,25 @@ package org.apache.fop.util; -import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; +import org.apache.commons.io.output.ProxyOutputStream; + /** * This is a decorator to block calls to close() to the underlying stream. */ -public class CloseBlockerOutputStream extends FilterOutputStream { +public class CloseBlockerOutputStream extends ProxyOutputStream { /** - * @see java.io.FilterOutputStream#FilterOutputStream(OutputStream) + * Main constructor. + * @param out the underlying stream */ public CloseBlockerOutputStream(OutputStream out) { super(out); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void close() throws IOException { try { flush(); |