From: Keiron Liddle Date: Tue, 8 Jan 2002 09:52:18 +0000 (+0000) Subject: does some basic text into pdf and svg output just for a start X-Git-Tag: fop-0_20_4-doc~163 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=aca1e4f9afd5d27a9ad6cea9871c4ae4632653e7;p=xmlgraphics-fop.git does some basic text into pdf and svg output just for a start git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194617 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/org/apache/fop/apps/Driver.java b/src/org/apache/fop/apps/Driver.java index d9144270a..5a49d02e2 100644 --- a/src/org/apache/fop/apps/Driver.java +++ b/src/org/apache/fop/apps/Driver.java @@ -8,6 +8,7 @@ package org.apache.fop.apps; // FOP +import org.apache.fop.fo.FOUserAgent; import org.apache.fop.fo.FOTreeBuilder; import org.apache.fop.fo.ElementMapping; import org.apache.fop.layout.AreaTree; @@ -200,6 +201,13 @@ public class Driver { _stream = stream; } + public void setUserAgent(FOUserAgent agent) { + } + + private FOUserAgent getUserAgent() { + return new FOUserAgent(); + } + public void setLogger(Logger logger) { log = logger; } @@ -349,6 +357,7 @@ public class Driver { */ public void setRenderer(Renderer renderer) { renderer.setLogger(getLogger()); + renderer.setUserAgent(getUserAgent()); _renderer = renderer; } diff --git a/src/org/apache/fop/apps/Fop.java b/src/org/apache/fop/apps/Fop.java index 3b82f8910..4dc42dcfb 100644 --- a/src/org/apache/fop/apps/Fop.java +++ b/src/org/apache/fop/apps/Fop.java @@ -17,14 +17,22 @@ public class Fop { Starter starter = options.getStarter(); starter.run(); } catch (FOPException e) { - System.err.println("" + e.getMessage()); + if("null".equals(e.getMessage())) { + System.err.println("NullPointerException"); + } else { + System.err.println("" + e.getMessage()); + } if (options != null && options.isDebugMode().booleanValue()) { e.printStackTrace(); + } else { + System.err.println("Turn on debugging for more information"); } } catch (java.io.FileNotFoundException e) { System.err.println("" + e.getMessage()); if (options != null && options.isDebugMode().booleanValue()) { e.printStackTrace(); + } else { + System.err.println("Turn on debugging for more information"); } } } diff --git a/src/org/apache/fop/area/Block.java b/src/org/apache/fop/area/Block.java index 97d07151f..ccad5f345 100644 --- a/src/org/apache/fop/area/Block.java +++ b/src/org/apache/fop/area/Block.java @@ -33,7 +33,6 @@ public class Block extends BlockParent implements Serializable { // available markers, markers are discarded once page complete private ArrayList markers = null; - boolean blocks = false; // a block with may contain the dominant styling info in // terms of most lines or blocks with info @@ -44,25 +43,15 @@ public class Block extends BlockParent implements Serializable { public void addBlock(Block block) { if (children == null) { children = new ArrayList(); - } else if (!blocks) { - // error } - blocks = true; children.add(block); } public void addLineArea(LineArea line) { if (children == null) { children = new ArrayList(); - } else if (blocks) { - // error } children.add(line); - - } - - public boolean isChildrenBlocks() { - return blocks; } public int getPositioning() { diff --git a/src/org/apache/fop/area/Property.java b/src/org/apache/fop/area/Property.java index 4c6d5914c..61d7b3bc2 100644 --- a/src/org/apache/fop/area/Property.java +++ b/src/org/apache/fop/area/Property.java @@ -29,6 +29,8 @@ public class Property implements Serializable { public static final int OFFSET = 13; public static final int SHADOW = 14; + public static final int FONT_STATE = 100; + public int propType; public Object data; diff --git a/src/org/apache/fop/fo/FOText.java b/src/org/apache/fop/fo/FOText.java index a3a2bb393..369b4f04e 100644 --- a/src/org/apache/fop/fo/FOText.java +++ b/src/org/apache/fop/fo/FOText.java @@ -38,18 +38,18 @@ public class FOText extends FObj { TextInfo textInfo; public static class TextInfo { - FontState fs; - float red; - float green; - float blue; - int wrapOption; - int whiteSpaceCollapse; - int verticalAlign; + public FontState fs; + public float red; + public float green; + public float blue; + public int wrapOption; + public int whiteSpaceCollapse; + public int verticalAlign; // Textdecoration - protected boolean underlined = false; - protected boolean overlined = false; - protected boolean lineThrough = false; + public boolean underlined = false; + public boolean overlined = false; + public boolean lineThrough = false; } TextState ts; diff --git a/src/org/apache/fop/fo/FOUserAgent.java b/src/org/apache/fop/fo/FOUserAgent.java index d89f308e4..39f9b8bcf 100644 --- a/src/org/apache/fop/fo/FOUserAgent.java +++ b/src/org/apache/fop/fo/FOUserAgent.java @@ -73,7 +73,7 @@ public class FOUserAgent { handler.handleXML(ctx, doc, namespace); } catch (Throwable t) { // could not handle document - t.printStackTrace(); + ctx.getLogger().error("Could not render XML", t); } } else { // no handler found for document diff --git a/src/org/apache/fop/fo/flow/Flow.java b/src/org/apache/fop/fo/flow/Flow.java index 9538f81b7..f0828f426 100644 --- a/src/org/apache/fop/fo/flow/Flow.java +++ b/src/org/apache/fop/fo/flow/Flow.java @@ -87,14 +87,11 @@ public class Flow extends FObj { protected void setFlowName(String name) throws FOPException { if (name == null || name.equals("")) { - log.warn("A 'flow-name' is required for " - + getName() - + ". This constraint will be enforced in future versions of FOP"); - _flowName = "xsl-region-body"; + throw new FOPException("A 'flow-name' is required for " + + getName()); } else { _flowName = name; } - } public String getFlowName() { diff --git a/src/org/apache/fop/fo/flow/InstreamForeignObject.java b/src/org/apache/fop/fo/flow/InstreamForeignObject.java index 6c5ee2a30..107ce8081 100644 --- a/src/org/apache/fop/fo/flow/InstreamForeignObject.java +++ b/src/org/apache/fop/fo/flow/InstreamForeignObject.java @@ -10,6 +10,7 @@ package org.apache.fop.fo.flow; // FOP import org.apache.fop.fo.*; import org.apache.fop.fo.properties.*; +import org.apache.fop.area.Area; import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.Viewport; import org.apache.fop.area.inline.ForeignObject; @@ -21,6 +22,8 @@ import org.apache.fop.layout.BackgroundProps; import org.apache.fop.layout.MarginInlineProps; import org.apache.fop.layout.RelativePositionProps; import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.SplitContext; import org.w3c.dom.Document; @@ -54,6 +57,31 @@ public class InstreamForeignObject extends FObj { super(parent); } + public LayoutManager getLayoutManager() { + return new LayoutManager() { + LayoutManager lm; + public void generateAreas() { + lm.addChild(getInlineArea()); + } + + public Area getParentArea (Area childArea) { + return null; + } + + public void addChild (Area childArea) { + } + + public boolean splitArea(Area areaToSplit, SplitContext context) { + return false; + } + + public void setParentLM(LayoutManager lm) { + this.lm = lm; + } + + }; + } + /** * Get the inline area created by this element. */ @@ -93,11 +121,22 @@ public class InstreamForeignObject extends FObj { // if replaced then use height then ignore block-progression-dimension //int h = this.properties.get("height").getLength().mvalue(); - // use line-height then ignore dimension in height direction - int lh = this.properties.get("line-height").getLength().mvalue(); + // use specified line-height then ignore dimension in height direction + boolean hasLH = properties.get("line-height").getSpecifiedValue() != null; + int bpd = 0; + boolean bpdauto = false; + if(hasLH) { + bpd = properties.get("line-height").getLength().mvalue(); + } else { + // this property does not apply when the line-height applies + // isn't the block-progression-dimension always in the same + // direction as the line height? + bpdauto = properties.get("block-progression-dimension").getLength().isAuto(); + bpd = properties.get("block-progression-dimension").getLength().mvalue(); + } - int bpd = this.properties.get("block-progression-dimension").getLength().mvalue(); - int ipd = this.properties.get("inline-progression-dimension").getLength().mvalue(); + //boolean ipdauto = properties.get("inline-progression-dimension").getLength().isAuto(); + //int ipd = properties.get("inline-progression-dimension").getLength().mvalue(); // if auto then use the intrinsic size of the content scaled // to the content-height and content-width diff --git a/src/org/apache/fop/fo/flow/Leader.java b/src/org/apache/fop/fo/flow/Leader.java index dc3ca017a..642b20dcd 100644 --- a/src/org/apache/fop/fo/flow/Leader.java +++ b/src/org/apache/fop/fo/flow/Leader.java @@ -200,5 +200,5 @@ public class Leader extends FObjMixed { // this.hasLines = true; return 1; } - } + diff --git a/src/org/apache/fop/fo/flow/RetrieveMarker.java b/src/org/apache/fop/fo/flow/RetrieveMarker.java index eb3d0497f..2baa6419f 100644 --- a/src/org/apache/fop/fo/flow/RetrieveMarker.java +++ b/src/org/apache/fop/fo/flow/RetrieveMarker.java @@ -64,7 +64,7 @@ public class RetrieveMarker extends FObjMixed { } } - Status status = new Status(Status.AREA_FULL_NONE); + Status status = new Status(Status.OK); if (null != bestMarker) { // System.out.println("Laying out marker '" + bestMarker + "' in area '" + area + "'"); // the 'markers' referred to in this method are internal; they have diff --git a/src/org/apache/fop/image/FopImageFactory.java b/src/org/apache/fop/image/FopImageFactory.java index b9cbec594..7e98c9a0d 100644 --- a/src/org/apache/fop/image/FopImageFactory.java +++ b/src/org/apache/fop/image/FopImageFactory.java @@ -21,6 +21,11 @@ import org.apache.fop.image.analyser.ImageReaderFactory; import org.apache.fop.image.analyser.ImageReader; import org.apache.fop.configuration.Configuration; +/* +handle context: base dir, logger, caching + +*/ + /** * create FopImage objects (with a configuration file - not yet implemented). * @author Eric SCHAEFFER diff --git a/src/org/apache/fop/layout/FontInfo.java b/src/org/apache/fop/layout/FontInfo.java index 9ef871176..c8b6fa955 100644 --- a/src/org/apache/fop/layout/FontInfo.java +++ b/src/org/apache/fop/layout/FontInfo.java @@ -8,7 +8,6 @@ package org.apache.fop.layout; import java.util.HashMap; -import java.util.Enumeration; import org.apache.fop.apps.FOPException; diff --git a/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java index 56fbc72f5..deb7027fe 100644 --- a/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -8,6 +8,7 @@ package org.apache.fop.layoutmgr; import org.apache.fop.fo.FObj; +import org.apache.fop.fo.FONode; import org.apache.fop.area.Area; import java.util.ListIterator; @@ -21,12 +22,12 @@ public abstract class AbstractLayoutManager implements LayoutManager { public AbstractLayoutManager(FObj fobj) { - this.fobj = fobj; - this.parentLM = null; + this.fobj = fobj; + this.parentLM = null; } public void setParentLM(LayoutManager lm) { - this.parentLM = lm; + this.parentLM = lm; } @@ -36,38 +37,41 @@ public abstract class AbstractLayoutManager implements LayoutManager { * its generateAreas method. */ public void generateAreas() { - ListIterator children = fobj.getChildren(); - while (children.hasNext()) { - LayoutManager lm = ((FObj)children.next()).getLayoutManager(); - if (lm != null) { - lm.setParentLM(this); - lm.generateAreas(); - } - } - flush(); // Add last area to parent + ListIterator children = fobj.getChildren(); + while (children.hasNext()) { + FONode node = (FONode) children.next(); + if (node instanceof FObj) { + LayoutManager lm = ((FObj) node).getLayoutManager(); + if (lm != null) { + lm.setParentLM(this); + lm.generateAreas(); + } + } + } + flush(); // Add last area to parent } -// /** -// * Ask the parent LayoutManager to add the current (full) area to the -// * appropriate parent area. -// * @param bFinished If true, this area is finished, either because it's -// * completely full or because there is no more content to put in it. -// * If false, we are in the middle of this area. This can happen, -// * for example, if we find floats in a line. We stop the current area, -// * and add it (temporarily) to its parent so that we can see if there -// * is enough space to place the float(s) anchored in the line. -// */ -// protected void flush(Area area, boolean bFinished) { -// if (area != null) { -// // area.setFinished(true); -// parentLM.addChild(area, bFinished); // ???? -// if (bFinished) { -// setCurrentArea(null); -// } -// } -// } - - /** + // /** + // * Ask the parent LayoutManager to add the current (full) area to the + // * appropriate parent area. + // * @param bFinished If true, this area is finished, either because it's + // * completely full or because there is no more content to put in it. + // * If false, we are in the middle of this area. This can happen, + // * for example, if we find floats in a line. We stop the current area, + // * and add it (temporarily) to its parent so that we can see if there + // * is enough space to place the float(s) anchored in the line. + // */ + // protected void flush(Area area, boolean bFinished) { + // if (area != null) { + // // area.setFinished(true); + // parentLM.addChild(area, bFinished); // ???? + // if (bFinished) { + // setCurrentArea(null); + // } + // } + // } + + /** * Force current area to be added to parent area. */ abstract protected void flush(); @@ -84,12 +88,12 @@ public abstract class AbstractLayoutManager implements LayoutManager { * BPD. */ abstract public Area getParentArea(Area childArea); - -// public boolean generatesInlineAreas() { -// return false; -// } + + // public boolean generatesInlineAreas() { + // return false; + // } /** @@ -97,12 +101,12 @@ public abstract class AbstractLayoutManager implements LayoutManager { * dimension of the current area to be exceeded, the parent LM is called * to add it. */ - abstract public void addChild(Area childArea) ; + abstract public void addChild(Area childArea); /** Do nothing */ public boolean splitArea(Area areaToSplit, SplitContext context) { - context.nextArea = areaToSplit; - return false; + context.nextArea = areaToSplit; + return false; } - } + diff --git a/src/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/org/apache/fop/layoutmgr/BlockLayoutManager.java index d398fdaba..291f05d2a 100644 --- a/src/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -23,43 +23,42 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { private Block curBlockArea; public BlockLayoutManager(FObj fobj) { - super(fobj); + super(fobj); } // DESIGN. Potential alternative to getParentArea() scheme -// /** -// * Called by child layout manager to get the available space for -// * content in the inline progression direction. -// * Note that a manager may need to ask its parent for this. -// * For a block area, available IPD is determined by indents. -// */ -// public int getContentIPD() { -// getArea(); // make if not existing -// return blockArea.getIPD(); -// } + // /** + // * Called by child layout manager to get the available space for + // * content in the inline progression direction. + // * Note that a manager may need to ask its parent for this. + // * For a block area, available IPD is determined by indents. + // */ + // public int getContentIPD() { + // getArea(); // make if not existing + // return blockArea.getIPD(); + // } /** * Generate areas by tellings all layout managers for its FO's * children to generate areas. */ public void generateAreas() { - ListIterator children = fobj.getChildren(); - LayoutManager lm=null; - while (children.hasNext()) { - FObj childFO = (FObj)children.next(); - if (childFO.generatesInlineAreas()) { - children.previous(); - lm = new LineLayoutManager(children); - } - else { - lm = childFO.getLayoutManager(); - } - if (lm != null) { - lm.setParentLM(this); - lm.generateAreas(); - } - } - flush(); // Add last area to parent + ListIterator children = fobj.getChildren(); + LayoutManager lm = null; + while (children.hasNext()) { + FObj childFO = (FObj) children.next(); + if (childFO.generatesInlineAreas()) { + children.previous(); + lm = new LineLayoutManager(children); + } else { + lm = childFO.getLayoutManager(); + } + if (lm != null) { + lm.setParentLM(this); + lm.generateAreas(); + } + } + flush(); // Add last area to parent } @@ -74,74 +73,73 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { * BPD. */ public Area getParentArea(Area childArea) { - if (curBlockArea == null) { - curBlockArea = new Block(); - // Set up dimensions - // Must get dimensions from parent area - //MinOptMax referenceIPD = parentLM.getReferenceIPD(); - Area parentArea = parentLM.getParentArea(curBlockArea); - // Get reference IPD from parentArea - setCurrentArea(curBlockArea); // ??? for generic operations - } - return curBlockArea; + if (curBlockArea == null) { + curBlockArea = new Block(); + // Set up dimensions + // Must get dimensions from parent area + //MinOptMax referenceIPD = parentLM.getReferenceIPD(); + Area parentArea = parentLM.getParentArea(curBlockArea); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; } - + public void addChild(Area childArea) { - if (curBlockArea != null) { - if (childArea instanceof LineArea) { - // Something about widows and orphans - // Position the line area and calculate size... - curBlockArea.addLineArea((LineArea)childArea); - } - else { - super.addChild(childArea); - } - } + if (curBlockArea != null) { + if (childArea instanceof LineArea) { + // Something about widows and orphans + // Position the line area and calculate size... + curBlockArea.addLineArea((LineArea) childArea); + } else { + super.addChild(childArea); + } + } } -// /** -// * Called by child LayoutManager when it has filled one of its areas. -// * If no current container, make one. -// * See if the area will fit in the current container. -// * If so, add it. -// * @param childArea the area to add: will either be a LineArea or -// * a BlockArea. -// */ -// public void addChild(Area childArea) { -// /* If the childArea fits entirely in the maximum available BPD -// * add it and return an OK status. -// * If it doesn't all fit, overrun or ask for split? -// * Might as well just add it since the page layout process -// * may need to make other adjustments, resulting in changing -// * split point. -// */ -// // Things like breaks on child area can cause premature -// // termination of the current area. -// /* We go past the theoretical maximum to be able to handle things -// * like widows. -// */ -// // WARNING: this doesn't take into account space-specifier -// // adujstment between childArea and last content of blockArea! -// if (blockArea.getContentBPD().min + childArea.getAllocationBPD().min -// > blockArea.getAvailBPD().max) { -// if (++extraLines <= iWidows) { -// blockArea.add(childArea); -// } -// else { -// blockArea.setIsLast(false); -// parentLM.addChildArea(blockArea); -// // Make a new one for this area -// blockArea = makeAreaForChild(childArea); -// extraLines = 0; // Count potential widows -// blockArea.add(childArea); -// } -// } -// else { -// blockArea.add(childArea); -// } -// } + // /** + // * Called by child LayoutManager when it has filled one of its areas. + // * If no current container, make one. + // * See if the area will fit in the current container. + // * If so, add it. + // * @param childArea the area to add: will either be a LineArea or + // * a BlockArea. + // */ + // public void addChild(Area childArea) { + // /* If the childArea fits entirely in the maximum available BPD + // * add it and return an OK status. + // * If it doesn't all fit, overrun or ask for split? + // * Might as well just add it since the page layout process + // * may need to make other adjustments, resulting in changing + // * split point. + // */ + // // Things like breaks on child area can cause premature + // // termination of the current area. + // /* We go past the theoretical maximum to be able to handle things + // * like widows. + // */ + // // WARNING: this doesn't take into account space-specifier + // // adujstment between childArea and last content of blockArea! + // if (blockArea.getContentBPD().min + childArea.getAllocationBPD().min + // > blockArea.getAvailBPD().max) { + // if (++extraLines <= iWidows) { + // blockArea.add(childArea); + // } + // else { + // blockArea.setIsLast(false); + // parentLM.addChildArea(blockArea); + // // Make a new one for this area + // blockArea = makeAreaForChild(childArea); + // extraLines = 0; // Count potential widows + // blockArea.add(childArea); + // } + // } + // else { + // blockArea.add(childArea); + // } + // } } diff --git a/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index 65474c4ed..423af36d3 100644 --- a/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -19,8 +19,7 @@ import java.util.Iterator; * Base LayoutManager class for all areas which stack their child * areas in the block-progression direction, such as Flow, Block, ListBlock. */ -public abstract class BlockStackingLayoutManager - extends AbstractLayoutManager { +public abstract class BlockStackingLayoutManager extends AbstractLayoutManager { /** Reference to FO whose areas it's managing or to the traits * of the FO. */ @@ -28,105 +27,104 @@ public abstract class BlockStackingLayoutManager BlockParent parentArea = null; public BlockStackingLayoutManager(FObj fobj) { - super(fobj); + super(fobj); } public boolean splitArea(Area area, SplitContext splitContext) { - // Divide area so that it will be within targetLength if possible - // If not, it can be shorter, but not longer. - /* Iterate over contents of the area. */ - - // Need to figure out if we can do this generically - // Logically a BlockStacking LM only handles Block-type areas - if (!(area instanceof BlockParent)) { - return false; - } - Iterator areaIter = ((BlockParent)area).getChildAreas().iterator(); - - - BreakCost minBreakCost = null; - MinOptMax remainBPD = splitContext.targetBPD; - splitContext.nextArea = area; - - while (areaIter.hasNext()) { - Area childArea = (Area)areaIter.next(); - if (remainBPD.max < childArea.getAllocationBPD().min) { - // Past the end point: try to break it - // TODO: get a LayoutManager to do the split of the child - // area, either Area => LM or Area => gen FO => LM - LayoutManager childLM = childArea.getGeneratingFObj(). - getLayoutManager(); - splitContext.targetBPD = remainBPD; - if (childLM.splitArea(childArea, splitContext) == false) { - // Can't split, so must split this area before childArea - // Can we pass the iter? - // If already saw several a potential break, use it - if (minBreakCost != null) { - /* Split 'area', placing all children after - * minBreakCost.getArea() into a new area, - * which we store in the splitContext. - */ - // splitContext.nextArea = area.splitAfter(minBreakCost.getArea()); - } - else { - /* This area will be shorter than the desired minimum. - * Split before the current childArea (which will be - * the first area in the newly created Area. - */ - //splitContext.nextArea = area.splitBefore(childArea); - } - } - else return true; // childLM has done the work for us! - // Set cost, dimension ??? - break; - } - else { - remainBPD.subtract(childArea.getAllocationBPD()); - if (remainBPD.min < 0) { - // Potential breakpoint: remember break Position and - // break "cost" (constraint violation) - BreakCost breakCost = evaluateBreakCost(area, childArea); - minBreakCost = breakCost.chooseLowest(minBreakCost); - } - } - //Note: size of area when split can depend on conditional - // space, border and padding of the split area!!! - } - // True if some part of area can be placed, false if none is placed - return (splitContext.nextArea != area); - + // Divide area so that it will be within targetLength if possible + // If not, it can be shorter, but not longer. + /* Iterate over contents of the area. */ + + // Need to figure out if we can do this generically + // Logically a BlockStacking LM only handles Block-type areas + if (!(area instanceof BlockParent)) { + return false; + } + Iterator areaIter = ((BlockParent) area).getChildAreas().iterator(); + + + BreakCost minBreakCost = null; + MinOptMax remainBPD = splitContext.targetBPD; + splitContext.nextArea = area; + + while (areaIter.hasNext()) { + Area childArea = (Area) areaIter.next(); + if (remainBPD.max < childArea.getAllocationBPD().min) { + // Past the end point: try to break it + // TODO: get a LayoutManager to do the split of the child + // area, either Area => LM or Area => gen FO => LM + LayoutManager childLM = + childArea.getGeneratingFObj(). getLayoutManager(); + splitContext.targetBPD = remainBPD; + if (childLM.splitArea(childArea, splitContext) == false) { + // Can't split, so must split this area before childArea + // Can we pass the iter? + // If already saw several a potential break, use it + if (minBreakCost != null) { + /* Split 'area', placing all children after + * minBreakCost.getArea() into a new area, + * which we store in the splitContext. + */ + // splitContext.nextArea = area.splitAfter(minBreakCost.getArea()); + } else { + /* This area will be shorter than the desired minimum. + * Split before the current childArea (which will be + * the first area in the newly created Area. + */ + //splitContext.nextArea = area.splitBefore(childArea); + } + } else + return true; // childLM has done the work for us! + // Set cost, dimension ??? + break; + } else { + remainBPD.subtract(childArea.getAllocationBPD()); + if (remainBPD.min < 0) { + // Potential breakpoint: remember break Position and + // break "cost" (constraint violation) + BreakCost breakCost = + evaluateBreakCost(area, childArea); + minBreakCost = breakCost.chooseLowest(minBreakCost); + } + } + //Note: size of area when split can depend on conditional + // space, border and padding of the split area!!! + } + // True if some part of area can be placed, false if none is placed + return (splitContext.nextArea != area); + } private BreakCost evaluateBreakCost(Area parent, Area child) { - return new BreakCost(child,0); + return new BreakCost(child, 0); } - /** return current area being filled + /** return current area being filled */ protected BlockParent getCurrentArea() { - return this.parentArea; + return this.parentArea; } - /** + /** * Set the current area being filled. */ protected void setCurrentArea(BlockParent parentArea) { - this.parentArea = parentArea; + this.parentArea = parentArea; } protected MinOptMax resolveSpaceSpecifier(Area nextArea) { - SpaceSpecifier spaceSpec = new SpaceSpecifier(); -// Area prevArea = getCurrentArea().getLast(); -// if (prevArea != null) { -// spaceSpec.addSpace(prevArea.getSpaceAfter()); -// } -// spaceSpec.addSpace(nextArea.getSpaceBefore()); - return spaceSpec.resolve(); + SpaceSpecifier spaceSpec = new SpaceSpecifier(); + // Area prevArea = getCurrentArea().getLast(); + // if (prevArea != null) { + // spaceSpec.addSpace(prevArea.getSpaceAfter()); + // } + // spaceSpec.addSpace(nextArea.getSpaceBefore()); + return spaceSpec.resolve(); } /** @@ -139,39 +137,38 @@ public abstract class BlockStackingLayoutManager * @param parentArea the area in which to add the childArea */ protected void addChildToArea(Area childArea, BlockParent parentArea) { - // This should be a block-level Area (Block in the generic sense) - if (!(childArea instanceof Block)) { - System.err.println("Child not a Block in BlockStackingLM!"); - return; - } - - // See if the whole thing fits, including space before - // Calculate space between last child in curFlow and childArea - MinOptMax targetDim = parentArea.getAvailBPD(); - MinOptMax spaceBefore = resolveSpaceSpecifier(childArea) ; - targetDim.subtract(spaceBefore); - if (targetDim.max >= childArea.getAllocationBPD().min) { - //parentArea.addBlock(new InterBlockSpace(spaceBefore)); - parentArea.addBlock((Block)childArea); - return; - } - else { - // Probably need something like max BPD so we don't get into - // infinite loops with large unbreakable chunks - SplitContext splitContext = new SplitContext(targetDim); - - LayoutManager childLM = childArea.getGeneratingFObj(). - getLayoutManager(); - if (childLM.splitArea(childArea, splitContext)) { - //parentArea.addBlock(new InterBlockSpace(spaceBefore)); - parentArea.addBlock((Block)childArea); - } - flush(); // hand off current area to parent - getParentArea(splitContext.nextArea); - // Check that reference IPD hasn't changed!!! - // If it has, we must "reflow" the content - addChild(splitContext.nextArea); - } + // This should be a block-level Area (Block in the generic sense) + if (!(childArea instanceof Block)) { + System.err.println("Child not a Block in BlockStackingLM!"); + return; + } + + // See if the whole thing fits, including space before + // Calculate space between last child in curFlow and childArea + MinOptMax targetDim = parentArea.getAvailBPD(); + MinOptMax spaceBefore = resolveSpaceSpecifier(childArea); + targetDim.subtract(spaceBefore); + if (targetDim.max >= childArea.getAllocationBPD().min) { + //parentArea.addBlock(new InterBlockSpace(spaceBefore)); + parentArea.addBlock((Block) childArea); + return; + } else { + // Probably need something like max BPD so we don't get into + // infinite loops with large unbreakable chunks + SplitContext splitContext = new SplitContext(targetDim); + + LayoutManager childLM = + childArea.getGeneratingFObj(). getLayoutManager(); + if (childLM.splitArea(childArea, splitContext)) { + //parentArea.addBlock(new InterBlockSpace(spaceBefore)); + parentArea.addBlock((Block) childArea); + } + flush(); // hand off current area to parent + getParentArea(splitContext.nextArea); + // Check that reference IPD hasn't changed!!! + // If it has, we must "reflow" the content + addChild(splitContext.nextArea); + } } @@ -184,14 +181,15 @@ public abstract class BlockStackingLayoutManager * @param childArea the area to add: will be some block-stacked Area. */ public void addChild(Area childArea) { - addChildToArea(childArea, getCurrentArea()); + addChildToArea(childArea, getCurrentArea()); } - /** + /** * Force current area to be added to parent area. */ protected void flush() { - parentLM.addChild(getCurrentArea()); + if (getCurrentArea() != null) + parentLM.addChild(getCurrentArea()); } diff --git a/src/org/apache/fop/layoutmgr/BreakCost.java b/src/org/apache/fop/layoutmgr/BreakCost.java index 66d513fc1..98b05e19f 100644 --- a/src/org/apache/fop/layoutmgr/BreakCost.java +++ b/src/org/apache/fop/layoutmgr/BreakCost.java @@ -19,15 +19,15 @@ public class BreakCost { private int cost; // Will be more complicated than this! public BreakCost(Area breakArea, int cost) { - this.breakArea = breakArea; - this.cost = cost; + this.breakArea = breakArea; + this.cost = cost; } Area getArea() { - return breakArea; + return breakArea; } public BreakCost chooseLowest(BreakCost otherCost) { - return this; + return this; } } diff --git a/src/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/org/apache/fop/layoutmgr/FlowLayoutManager.java index f68d693da..9c9a05a56 100644 --- a/src/org/apache/fop/layoutmgr/FlowLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/FlowLayoutManager.java @@ -28,7 +28,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager { * It is created by the PageSequence FO. */ public FlowLayoutManager(FObj fobj) { - super(fobj); + super(fobj); } @@ -39,17 +39,17 @@ public class FlowLayoutManager extends BlockStackingLayoutManager { * at any one time. The actual work is done by BlockStackingLM. */ public void addChild(Area childArea) { - addChildToArea(childArea, - this.currentAreas[childArea.getAreaClass()]); + addChildToArea(childArea, + this.currentAreas[childArea.getAreaClass()]); } public Area getParentArea(Area childArea) { - // Get an area from the Page - BlockParent parentArea = - (BlockParent)parentLM.getParentArea(childArea); - this.currentAreas[parentArea.getAreaClass()] = parentArea; - setCurrentArea(parentArea); - return parentArea; + // Get an area from the Page + BlockParent parentArea = + (BlockParent) parentLM.getParentArea(childArea); + this.currentAreas[parentArea.getAreaClass()] = parentArea; + setCurrentArea(parentArea); + return parentArea; } diff --git a/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java b/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java index 41073a139..e219fa71a 100644 --- a/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java @@ -22,16 +22,16 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager { private InlineArea curArea; public LeafNodeLayoutManager(FObj fobj) { - super(fobj); + super(fobj); } protected void setCurrentArea(InlineArea ia) { - curArea = ia; + curArea = ia; } protected void flush() { - parentLM.addChild(curArea); + parentLM.addChild(curArea); } /** @@ -44,8 +44,8 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager { * This is a leaf-node, so this method is never called. */ public Area getParentArea(Area childArea) { - return null; + return null; } - + } diff --git a/src/org/apache/fop/layoutmgr/LineLayoutManager.java b/src/org/apache/fop/layoutmgr/LineLayoutManager.java index 060575231..4d87d859d 100644 --- a/src/org/apache/fop/layoutmgr/LineLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/LineLayoutManager.java @@ -31,80 +31,76 @@ public class LineLayoutManager extends AbstractLayoutManager { private MinOptMax remainingIPD; public LineLayoutManager(ListIterator fobjIter) { - super(null); - this.fobjIter = fobjIter; + super(null); + this.fobjIter = fobjIter; } - /** * Call child layout managers to generate content as long as they * generate inline areas. If a block-level generating LM is found, * finish any line being filled and return to the parent LM. */ public void generateAreas() { - this.bFirstLine = true; - while (fobjIter.hasNext()) { - FObj childFO = (FObj)fobjIter.next(); - if (childFO.generatesInlineAreas()==false) { - // It generates blocks, pass back to parent - // Back up one - fobjIter.previous(); - break; - } - else { // generates inline area - curLM = childFO.getLayoutManager(); - if (curLM != null) { - curLM.setParentLM(this); - curLM.generateAreas(); - } - } - } - flush(); // Add last area to parent + this.bFirstLine = true; + while (fobjIter.hasNext()) { + FObj childFO = (FObj) fobjIter.next(); + if (childFO.generatesInlineAreas() == false) { + // It generates blocks, pass back to parent + // Back up one + fobjIter.previous(); + break; + } else { // generates inline area + curLM = childFO.getLayoutManager(); + if (curLM != null) { + curLM.setParentLM(this); + curLM.generateAreas(); + } + } + } + flush(); // Add last area to parent } - /** * Align and position curLine and add it to parentContainer. * Set curLine to null. */ public void flush() { - if (lineArea != null) { - // Adjust spacing as necessary - // Calculate height, based on content (or does the Area do this?) - parentLM.addChild(lineArea); - lineArea = null; - } + if (lineArea != null) { + // Adjust spacing as necessary + // Calculate height, based on content (or does the Area do this?) + lineArea.setHeight(14000); + parentLM.addChild(lineArea); + lineArea = null; + } } - /** * Return current lineArea or generate a new one if necessary. */ public Area getParentArea(Area childArea) { - if (lineArea == null) { - createLine(); - } - return lineArea; + if (lineArea == null) { + createLine(); + } + return lineArea; } private void createLine() { - lineArea = new LineArea(); - /* Set line IPD from parentArea - * This accounts for indents. What about first line indent? - * Should we set an "isFirst" flag on the lineArea to signal - * that to the parent (Block) LM? That's where indent property - * information will be managed. - */ - Area parent = parentLM.getParentArea(lineArea); - // lineArea.setContentIPD(parent.getContentIPD()); - // remainingIPD = parent.getContentIPD(); - // OR??? - // remainingIPD = parentLM.getContentIPD(); - remainingIPD = new MinOptMax(100000); // TESTING!!! - this.bFirstLine = false; + lineArea = new LineArea(); + /* Set line IPD from parentArea + * This accounts for indents. What about first line indent? + * Should we set an "isFirst" flag on the lineArea to signal + * that to the parent (Block) LM? That's where indent property + * information will be managed. + */ + Area parent = parentLM.getParentArea(lineArea); + // lineArea.setContentIPD(parent.getContentIPD()); + // remainingIPD = parent.getContentIPD(); + // OR??? + // remainingIPD = parentLM.getContentIPD(); + remainingIPD = new MinOptMax(300000); // TESTING!!! + this.bFirstLine = false; } - /** * Called by child LayoutManager when it has filled one of its areas. * See if the area will fit in the current container. @@ -113,49 +109,54 @@ public class LineLayoutManager extends AbstractLayoutManager { * @param childArea the area to add: should be an InlineArea subclass! */ public void addChild(Area childArea) { - if ((childArea instanceof InlineArea)==false) { - // SIGNAL AN ERROR!!! - return; - } - InlineArea inlineArea = (InlineArea)childArea; - if (lineArea == null) { - createLine(); - } - if (inlineArea.getAllocationIPD().min < remainingIPD.max) { - lineArea.addInlineArea(inlineArea); - remainingIPD.subtract(inlineArea.getAllocationIPD()); - // Calculate number of spaces - // Forced line break after this area (ex. ends with LF in nowrap) - /* NOTYET! - if (inlineArea.breakAfter()) { - flush(); - } - */ - /* Check if line could end after this area (potential line-break - * character. If not, it must be joined with following inline - * area to make a word. Otherwise, if the line could break here - * and if it is "full", add it to the parent area. - */ - if (remainingIPD.min<=0) { - flush(); - } - } - - else { - /* The inline area won't entirely fit in this line. Ask its - * layout manager to split it (by hyphenation for example), - * in order to fit part of it in the line. - * Note: only the current child LM could have generated this - * area, so we ask it to do the split. - */ - SplitContext splitContext = new SplitContext(remainingIPD); - if (curLM.splitArea(inlineArea, splitContext)) { - // inlineArea should now fit - lineArea.addInlineArea(inlineArea); - flush(); - } - addChild(splitContext.nextArea); - } + if ((childArea instanceof InlineArea) == false) { + // SIGNAL AN ERROR!!! + return; + } + InlineArea inlineArea = (InlineArea) childArea; + if (lineArea == null) { + createLine(); + } + if (inlineArea.getAllocationIPD().min < remainingIPD.max) { + lineArea.addInlineArea(inlineArea); + remainingIPD.subtract(inlineArea.getAllocationIPD()); + // Calculate number of spaces + // Forced line break after this area (ex. ends with LF in nowrap) + /* NOTYET! + if (inlineArea.breakAfter()) { + flush(); + } + */ + /* Check if line could end after this area (potential line-break + * character. If not, it must be joined with following inline + * area to make a word. Otherwise, if the line could break here + * and if it is "full", add it to the parent area. + */ + if (remainingIPD.min <= 0) { + flush(); + } + } + else { + /* The inline area won't entirely fit in this line. Ask its + * layout manager to split it (by hyphenation for example), + * in order to fit part of it in the line. + * Note: only the current child LM could have generated this + * area, so we ask it to do the split. + */ + SplitContext splitContext = new SplitContext(remainingIPD); + if (curLM.splitArea(inlineArea, splitContext)) { + // inlineArea should now fit + lineArea.addInlineArea(inlineArea); + flush(); + addChild(splitContext.nextArea); + } else { + lineArea.addInlineArea((InlineArea)splitContext.nextArea); + remainingIPD.subtract(inlineArea.getAllocationIPD()); + if (remainingIPD.min <= 0) { + flush(); + } + } + } } } diff --git a/src/org/apache/fop/layoutmgr/PageLayoutManager.java b/src/org/apache/fop/layoutmgr/PageLayoutManager.java index 9e7bb9642..caa55a4f8 100644 --- a/src/org/apache/fop/layoutmgr/PageLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/PageLayoutManager.java @@ -16,8 +16,7 @@ import org.apache.fop.fo.properties.Constants; * LayoutManager for a PageSequence and its flow. * It manages all page-related layout. */ -public class PageLayoutManager extends AbstractLayoutManager - implements Runnable{ +public class PageLayoutManager extends AbstractLayoutManager implements Runnable { /** True if haven't yet laid out any pages.*/ private boolean bFirstPage; @@ -48,12 +47,12 @@ public class PageLayoutManager extends AbstractLayoutManager * It is created by the PageSequence FO. */ public PageLayoutManager(AreaTree areaTree, PageSequence pageseq) { - super( pageseq); - this.areaTree = areaTree; + super(pageseq); + this.areaTree = areaTree; } - /** + /** * The layout process is designed to be able to be run in a thread. * In theory it can run at the same * time as FO tree generation, once the layout-master-set has been read. @@ -63,7 +62,7 @@ public class PageLayoutManager extends AbstractLayoutManager * rendering process can also run in a parallel thread. */ public void run() { - generateAreas(); + generateAreas(); } @@ -71,11 +70,12 @@ public class PageLayoutManager extends AbstractLayoutManager * For now, only handle normal flow areas. */ public void addChild(Area childArea) { - if (childArea ==null) return; - if (childArea.getAreaClass() == Area.CLASS_NORMAL) { - placeFlowRefArea(childArea); - } - else ; // TODO: all the others! + if (childArea == null) + return; + if (childArea.getAreaClass() == Area.CLASS_NORMAL) { + placeFlowRefArea(childArea); + } else + ; // TODO: all the others! } /** @@ -86,27 +86,27 @@ public class PageLayoutManager extends AbstractLayoutManager * possibly moving to the next column or to the next page. */ protected void placeFlowRefArea(Area area) { - // assert (curSpan != null); - // assert (area == curFlow); - // assert (curFlow == curSpan.getFlow(curSpan.getColumnCount()-1)); - // assert (area.getBPD().min < curSpan.getHeight()); - // Last column on this page is filled - // See if the flow is full. The Flow LM can add an area before - // it's full in the case of a break or a span. - // Also in the case of a float to be placed. In that case, there - // may be further material added later. - // The Flow LM sets the "finished" flag on the Flow Area if it has - // completely filled it. In this case, if on the last column - // end the page. - - // Alternatively the child LM indicates to parent that it's full? - if (area.getAllocationBPD().max >= curSpan.getMaxBPD().min) { - // Consider it filled - if (curSpan.getColumnCount() == curSpanColumns) { - finishPage(); - } - else curFlow = null; // Create new flow on next getParentArea() - } + // assert (curSpan != null); + // assert (area == curFlow); + // assert (curFlow == curSpan.getFlow(curSpan.getColumnCount()-1)); + // assert (area.getBPD().min < curSpan.getHeight()); + // Last column on this page is filled + // See if the flow is full. The Flow LM can add an area before + // it's full in the case of a break or a span. + // Also in the case of a float to be placed. In that case, there + // may be further material added later. + // The Flow LM sets the "finished" flag on the Flow Area if it has + // completely filled it. In this case, if on the last column + // end the page. + + // Alternatively the child LM indicates to parent that it's full? + if (area.getAllocationBPD().max >= curSpan.getMaxBPD().min) { + // Consider it filled + if (curSpan.getColumnCount() == curSpanColumns) { + finishPage(); + } else + curFlow = null; // Create new flow on next getParentArea() + } } @@ -122,37 +122,38 @@ public class PageLayoutManager extends AbstractLayoutManager } protected void placeFootnote(Area area) { - // After doing this, reduce available space on the curSpan. - // This has to be propagated to the curFlow (FlowLM) so that - // it can adjust its limit for composition (or it just asks - // curSpan for BPD before doing the break?) - // If multi-column, we may have to balance to find more space - // for a float. When? + // After doing this, reduce available space on the curSpan. + // This has to be propagated to the curFlow (FlowLM) so that + // it can adjust its limit for composition (or it just asks + // curSpan for BPD before doing the break?) + // If multi-column, we may have to balance to find more space + // for a float. When? } - private PageViewport makeNewPage(boolean bIsBlank, boolean bIsLast) { - finishPage(); - try { - curPage = ((PageSequence)fobj).createPage(bIsBlank, bIsLast); - } catch (FOPException fopex) { /* ???? */ } - curBody = (BodyRegion) curPage.getPage(). - getRegion(RegionReference.BODY).getRegion(); - return curPage; - } + private PageViewport makeNewPage(boolean bIsBlank, boolean bIsLast) { + finishPage(); + try { + curPage = ((PageSequence) fobj).createPage(bIsBlank, bIsLast); + } catch (FOPException fopex) { /* ???? */ + } + curBody = (BodyRegion) curPage.getPage(). getRegion( + RegionReference.BODY).getRegion(); + return curPage; + } private void finishPage() { - if (curPage != null) { - // Layout static content into the regions - // Need help from pageseq for this - // Queue for ID resolution and rendering - areaTree.addPage(curPage); - curPage = null; - curBody = null; - curSpan=null; - curFlow=null; - } + if (curPage != null) { + // Layout static content into the regions + // Need help from pageseq for this + // Queue for ID resolution and rendering + areaTree.addPage(curPage); + curPage = null; + curBody = null; + curSpan = null; + curFlow = null; + } } /** @@ -163,70 +164,65 @@ public class PageLayoutManager extends AbstractLayoutManager * and span properties set. */ public Area getParentArea(Area childArea) { - int aclass = childArea.getAreaClass() ; - if (aclass == Area.CLASS_NORMAL) { - // TODO: how to get properties from the Area??? - // Need span, break - int breakVal = Constants.AUTO; // childArea.getBreakBefore(); - if (breakVal != Constants.AUTO) { - // We may be forced to make new page - handleBreak(breakVal); - } - else if (curPage == null) { - makeNewPage(false, false); - } - // Now we should be on the right kind of page - boolean bNeedSpan = false; - int span = Constants.NONE; // childArea.getSpan() - int numCols=1; - if (span == Constants.ALL) { - // Assume the number of columns is stored on the curBody object. - //numCols = curBody.getProperty(NUMBER_OF_COLUMNS); - } - if (curSpan == null) { - createBodyMainReferenceArea(); - bNeedSpan = true; - } - else if (numCols != curSpanColumns) { - // TODO: BALANCE EXISTING COLUMNS - if (curSpanColumns > 1) { - // balanceColumns(); - } - bNeedSpan = true; - } - if (bNeedSpan) { - // Make a new span and the first flow - createSpan(numCols); - } - else if (curFlow == null) { - createFlow(); - } - return curFlow; - } - else { - if (curPage == null) { - makeNewPage(false, false); - } - // Now handle different kinds of areas - if (aclass == Area.CLASS_BEFORE_FLOAT) { - BeforeFloat bf = curBody.getBeforeFloat(); - if (bf == null) { - bf = new BeforeFloat(); - curBody.setBeforeFloat(bf); - } - return bf; - } - else if (aclass == Area.CLASS_FOOTNOTE) { - Footnote fn = curBody.getFootnote(); - if (fn == null) { - fn = new Footnote(); - curBody.setFootnote(fn); - } - return fn; - } - // TODO!!! other area classes (side-float, absolute, fixed) - return null; - } + int aclass = childArea.getAreaClass(); + if (aclass == Area.CLASS_NORMAL) { + // TODO: how to get properties from the Area??? + // Need span, break + int breakVal = Constants.AUTO; // childArea.getBreakBefore(); + if (breakVal != Constants.AUTO) { + // We may be forced to make new page + handleBreak(breakVal); + } else if (curPage == null) { + makeNewPage(false, false); + } + // Now we should be on the right kind of page + boolean bNeedSpan = false; + int span = Constants.NONE; // childArea.getSpan() + int numCols = 1; + if (span == Constants.ALL) { + // Assume the number of columns is stored on the curBody object. + //numCols = curBody.getProperty(NUMBER_OF_COLUMNS); + } + if (curSpan == null) { + createBodyMainReferenceArea(); + bNeedSpan = true; + } else if (numCols != curSpanColumns) { + // TODO: BALANCE EXISTING COLUMNS + if (curSpanColumns > 1) { + // balanceColumns(); + } + bNeedSpan = true; + } + if (bNeedSpan) { + // Make a new span and the first flow + createSpan(numCols); + } else if (curFlow == null) { + createFlow(); + } + return curFlow; + } else { + if (curPage == null) { + makeNewPage(false, false); + } + // Now handle different kinds of areas + if (aclass == Area.CLASS_BEFORE_FLOAT) { + BeforeFloat bf = curBody.getBeforeFloat(); + if (bf == null) { + bf = new BeforeFloat(); + curBody.setBeforeFloat(bf); + } + return bf; + } else if (aclass == Area.CLASS_FOOTNOTE) { + Footnote fn = curBody.getFootnote(); + if (fn == null) { + fn = new Footnote(); + curBody.setFootnote(fn); + } + return fn; + } + // TODO!!! other area classes (side-float, absolute, fixed) + return null; + } } @@ -236,22 +232,22 @@ public class PageLayoutManager extends AbstractLayoutManager * not have the desired "handedness". */ protected void handleBreak(int breakVal) { - if (breakVal == Constants.COLUMN) { - if (curSpan != null && - curSpan.getColumnCount() != curSpanColumns) { - // Move to next column - createFlow(); - return; - } - // else need new page - breakVal = Constants.PAGE; - } - if (needEmptyPage(breakVal)) { - curPage = makeNewPage(true, false); - } - if (needNewPage(breakVal)) { - curPage = makeNewPage(false, false); - } + if (breakVal == Constants.COLUMN) { + if (curSpan != null && + curSpan.getColumnCount() != curSpanColumns) { + // Move to next column + createFlow(); + return; + } + // else need new page + breakVal = Constants.PAGE; + } + if (needEmptyPage(breakVal)) { + curPage = makeNewPage(true, false); + } + if (needNewPage(breakVal)) { + curPage = makeNewPage(false, false); + } } @@ -264,82 +260,82 @@ public class PageLayoutManager extends AbstractLayoutManager * block until the queue of layoutable stuff is empty! */ private boolean needEmptyPage(int breakValue) { - return false; -// if (breakValue == Constants.PAGE || curPage.isEmpty()) { -// // any page is OK or we already have an empty page -// return false; -// } -// else { -// /* IF we are on the kind of page we need, we'll need a new page. */ -// if (curPage.getPageNumber()%2 != 0) { -// // Current page is odd -// return (breakValue == Constants.ODD_PAGE); -// } -// else { -// return (breakValue == Constants.EVEN_PAGE); -// } -// } + return false; + // if (breakValue == Constants.PAGE || curPage.isEmpty()) { + // // any page is OK or we already have an empty page + // return false; + // } + // else { + // /* IF we are on the kind of page we need, we'll need a new page. */ + // if (curPage.getPageNumber()%2 != 0) { + // // Current page is odd + // return (breakValue == Constants.ODD_PAGE); + // } + // else { + // return (breakValue == Constants.EVEN_PAGE); + // } + // } } - + /** * See if need to generate a new page for a forced break condition. * TODO: methods to see if the current page is empty and to get * its number. */ private boolean needNewPage(int breakValue) { - return false; -// if (curPage.isEmpty()) { -// if (breakValue == Constants.PAGE) { -// return false; -// } -// else if (curPage.getPageNumber()%2 != 0) { -// // Current page is odd -// return (breakValue == Constants.EVEN_PAGE); -// } -// else { -// return (breakValue == Constants.ODD_PAGE); -// } -// } -// else { -// return true; -// } + return false; + // if (curPage.isEmpty()) { + // if (breakValue == Constants.PAGE) { + // return false; + // } + // else if (curPage.getPageNumber()%2 != 0) { + // // Current page is odd + // return (breakValue == Constants.EVEN_PAGE); + // } + // else { + // return (breakValue == Constants.ODD_PAGE); + // } + // } + // else { + // return true; + // } } private void createBodyMainReferenceArea() { - curBody.setMainReference(new MainReference()); + curBody.setMainReference(new MainReference()); } private Flow createFlow() { - curFlow = new Flow(); - // Set IPD and max BPD on the curFlow from curBody - curSpan.addFlow(curFlow); - return curFlow; + curFlow = new Flow(); + // Set IPD and max BPD on the curFlow from curBody + curSpan.addFlow(curFlow); + return curFlow; } private void createSpan(int numCols) { - // check number of columns (= all in Body or 1) - // If already have a span, get its size and position (as MinMaxOpt) - // This determines the position of the new span area - // Attention: space calculation between the span areas. - -// MinOptMax newpos ; -// if (curSpan != null) { -// newpos = curSpan.getPosition(BPD); -// newpos.add(curSpan.getDimension(BPD)); -// } -// else newpos = new MinOptMax(); - curSpan = new Span(numCols); - //curSpan.setPosition(BPD, newpos); - curBody.getMainReference().addSpan(curSpan); - createFlow(); + // check number of columns (= all in Body or 1) + // If already have a span, get its size and position (as MinMaxOpt) + // This determines the position of the new span area + // Attention: space calculation between the span areas. + + // MinOptMax newpos ; + // if (curSpan != null) { + // newpos = curSpan.getPosition(BPD); + // newpos.add(curSpan.getDimension(BPD)); + // } + // else newpos = new MinOptMax(); + curSpan = new Span(numCols); + //curSpan.setPosition(BPD, newpos); + curBody.getMainReference().addSpan(curSpan); + createFlow(); } // See finishPage... protected void flush() { - finishPage(); + finishPage(); } } diff --git a/src/org/apache/fop/layoutmgr/SpaceSpecifier.java b/src/org/apache/fop/layoutmgr/SpaceSpecifier.java index ca33c07a1..69391c9b4 100644 --- a/src/org/apache/fop/layoutmgr/SpaceSpecifier.java +++ b/src/org/apache/fop/layoutmgr/SpaceSpecifier.java @@ -26,6 +26,6 @@ public class SpaceSpecifier { } public MinOptMax resolve() { - return new MinOptMax(); + return new MinOptMax(); } } diff --git a/src/org/apache/fop/layoutmgr/SplitContext.java b/src/org/apache/fop/layoutmgr/SplitContext.java index d798af5d1..439c91024 100644 --- a/src/org/apache/fop/layoutmgr/SplitContext.java +++ b/src/org/apache/fop/layoutmgr/SplitContext.java @@ -16,8 +16,8 @@ public class SplitContext { MinOptMax targetBPD; public SplitContext(MinOptMax targetBPD) { - this.targetBPD = targetBPD; - nextArea = null; + this.targetBPD = targetBPD; + nextArea = null; } } diff --git a/src/org/apache/fop/layoutmgr/TextLayoutManager.java b/src/org/apache/fop/layoutmgr/TextLayoutManager.java index 570515d60..2aa848ada 100644 --- a/src/org/apache/fop/layoutmgr/TextLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/TextLayoutManager.java @@ -10,48 +10,233 @@ package org.apache.fop.layoutmgr; import org.apache.fop.fo.FObj; import org.apache.fop.fo.FOText; // For TextInfo: TODO: make independent! import org.apache.fop.area.Area; +import org.apache.fop.area.Property; import org.apache.fop.area.inline.Word; +import org.apache.fop.util.CharUtilities; + +import org.apache.fop.fo.properties.*; import java.util.ListIterator; /** * LayoutManager for text (a sequence of characters) which generates one - * more inline areas. + * or more inline areas. */ public class TextLayoutManager extends LeafNodeLayoutManager { private char[] chars; private FOText.TextInfo textInfo; - public TextLayoutManager(FObj fobj, char[] chars, - FOText.TextInfo textInfo) { - super(fobj); - this.chars = chars; - this.textInfo = textInfo; + /* values that prev (below) may take */ + protected static final int NOTHING = 0; + protected static final int WHITESPACE = 1; + protected static final int TEXT = 2; + + public TextLayoutManager(FObj fobj, char[] chars, + FOText.TextInfo textInfo) { + super(fobj); + this.chars = chars; + this.textInfo = textInfo; } /** * Generate inline areas for words in text. */ public void generateAreas() { - // Handle white-space characteristics. Maybe there is no area to - // generate.... - - // Iterate over characters and make text areas. - // Add each one to parent. Handle word-space. - Word curWordArea = new Word(); - curWordArea.setWord(new String(chars)); - setCurrentArea(curWordArea); - flush(); + // Handle white-space characteristics. Maybe there is no area to + // generate.... + + // Iterate over characters and make text areas. + // Add each one to parent. Handle word-space. +// Word curWordArea = new Word(); +// curWordArea.setWord(new String(chars)); +//System.out.println("word:" + new String(chars)); + //parentLM.addChild(curWordArea); +parseChars(); + + //setCurrentArea(curWordArea); + //flush(); } + protected void parseChars() { + + // With CID fonts, space isn't neccesary currentFontState.width(32) + int whitespaceWidth = CharUtilities.getCharWidth(' ', textInfo.fs); + + int wordStart = 0; + int wordLength = 0; + int wordWidth = 0; + int spaceWidth = 0; + + int prev = NOTHING; + + boolean isText = false; + + /* iterate over each character */ + for (int i = 0; i < chars.length; i++) { + int charWidth; + /* get the character */ + char c = chars[i]; + if (!(CharUtilities.isSpace(c) || (c == '\n') || (c == '\r') || (c == '\t') + || (c == '\u2028'))) { + charWidth = CharUtilities.getCharWidth(c, textInfo.fs); + isText = true; + prev = TEXT; +wordLength++; +wordWidth += charWidth; + // Add support for zero-width spaces + if (charWidth <= 0 && c != '\u200B' && c != '\uFEFF') + charWidth = whitespaceWidth; + } else { + if ((c == '\n') || (c == '\r') || (c == '\t')) + charWidth = whitespaceWidth; + else + charWidth = CharUtilities.getCharWidth(c, textInfo.fs); + + isText = false; + + if (prev == WHITESPACE) { + + // if current & previous are WHITESPACE + + if (textInfo.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) { + if (CharUtilities.isSpace(c)) { + spaceWidth += CharUtilities.getCharWidth(c, textInfo.fs); + } else if (c == '\n' || c == '\u2028') { + // force line break + if (spaceWidth > 0) { + /*InlineSpace is = new InlineSpace(spaceWidth); + addChild(is);*/ + spaceWidth = 0; + } + } else if (c == '\t') { + spaceWidth += 8 * whitespaceWidth; + } + } else if (c == '\u2028') { + // Line separator + // Breaks line even if WhiteSpaceCollapse = True + if (spaceWidth > 0) { + /*InlineSpace is = new InlineSpace(spaceWidth); + is.setUnderlined(textState.getUnderlined()); + is.setOverlined(textState.getOverlined()); + is.setLineThrough(textState.getLineThrough()); + addChild(is);*/ + spaceWidth = 0; + } + } + + } else if (prev == TEXT) { + + // if current is WHITESPACE and previous TEXT + // the current word made it, so + // add the space before the current word (if there + // was some) + + if (spaceWidth > 0) { + /*InlineSpace is = new InlineSpace(spaceWidth); + if (prevUlState) { + is.setUnderlined(textState.getUnderlined()); + } + if (prevOlState) { + is.setOverlined(textState.getOverlined()); + } + if (prevLTState) { + is.setLineThrough(textState.getLineThrough()); + } + addChild(is);*/ + spaceWidth = 0; + } + // add the current word + + if (wordLength > 0) { + // The word might contain nonbreaking + // spaces. Split the word and add InlineSpace + // as necessary. All spaces inside the word + // Have a fixed width. + Word curWordArea = new Word(); +curWordArea.setWidth(wordWidth); + curWordArea.setWord(new String(chars, wordStart, wordLength + 1)); +Property prop = new Property(); +prop.propType = Property.FONT_STATE; +prop.data = textInfo.fs; +curWordArea.addProperty(prop); + parentLM.addChild(curWordArea); + + // reset word width + wordWidth = 0; + } + + // deal with this new whitespace following the + // word we just added + prev = WHITESPACE; + + spaceWidth = CharUtilities.getCharWidth(c, textInfo.fs); + + if (textInfo.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) { + if (c == '\n' || c == '\u2028') { + // force a line break + } else if (c == '\t') { + spaceWidth = whitespaceWidth; + } + } else if (c == '\u2028') { + } + } else { + + // if current is WHITESPACE and no previous + + if (textInfo.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) { + if (CharUtilities.isSpace(c)) { + prev = WHITESPACE; + spaceWidth = CharUtilities.getCharWidth(c, textInfo.fs); + } else if (c == '\n') { + // force line break + // textdecoration not used because spaceWidth is 0 + /*InlineSpace is = new InlineSpace(spaceWidth); + addChild(is);*/ + } else if (c == '\t') { + prev = WHITESPACE; + spaceWidth = 8 * whitespaceWidth; + } + + } else { + // skip over it + wordStart++; + } + } + wordStart = i; +wordLength = 0; + } + } // end of iteration over text + + if (wordLength > 0) { + // The word might contain nonbreaking + // spaces. Split the word and add InlineSpace + // as necessary. All spaces inside the word + // Have a fixed width. +if(wordStart + wordLength > chars.length - 1) { +wordLength = chars.length - 1 - wordStart; +} + + Word curWordArea = new Word(); +curWordArea.setWidth(wordWidth); + curWordArea.setWord(new String(chars, wordStart, wordLength + 1)); +Property prop = new Property(); +prop.propType = Property.FONT_STATE; +prop.data = textInfo.fs; +curWordArea.addProperty(prop); + parentLM.addChild(curWordArea); + + } + + chars = null; + } /** Try to split the word area by hyphenating the word. */ public boolean splitArea(Area areaToSplit, SplitContext context) { - context.nextArea = areaToSplit; - return false; + context.nextArea = areaToSplit; + return false; } - } + diff --git a/src/org/apache/fop/render/AbstractRenderer.java b/src/org/apache/fop/render/AbstractRenderer.java index 8a90b96b1..4d6584b38 100644 --- a/src/org/apache/fop/render/AbstractRenderer.java +++ b/src/org/apache/fop/render/AbstractRenderer.java @@ -134,8 +134,8 @@ public abstract class AbstractRenderer implements Renderer { protected void renderRegionViewport(RegionViewport port) { if (port != null) { Rectangle2D view = port.getViewArea(); - currentBPPosition = (int) view.getY(); - currentIPPosition = (int) view.getX(); + currentBPPosition = (int) (view.getY() / 1000); + currentIPPosition = (int) (view.getX() / 1000); currentBlockIPPosition = currentIPPosition; RegionReference region = port.getRegion(); @@ -224,24 +224,11 @@ public abstract class AbstractRenderer implements Renderer { } protected void renderBlock(Block block) { - boolean childrenblocks = block.isChildrenBlocks(); List children = block.getChildAreas(); - if (childrenblocks) { - renderBlocks(children); + if (children == null) { + // simply move position } else { - if (children == null) { - // simply move position - } else { - // a line area is rendered from the top left position - // of the line, each inline object is offset from there - for (int count = 0; count < children.size(); count++) { - LineArea line = (LineArea) children.get(count); - currentBlockIPPosition = currentIPPosition; - renderLineArea(line); - currentBPPosition += line.getHeight(); - } - - } + renderBlocks(children); } } @@ -311,8 +298,17 @@ public abstract class AbstractRenderer implements Renderer { protected void renderBlocks(List blocks) { for (int count = 0; count < blocks.size(); count++) { - Block block = (Block) blocks.get(count); - renderBlock(block); + Object obj = blocks.get(count); + if(obj instanceof Block) { + renderBlock((Block)obj); + } else { + // a line area is rendered from the top left position + // of the line, each inline object is offset from there + LineArea line = (LineArea) obj; + currentBlockIPPosition = currentIPPosition; + renderLineArea(line); + currentBPPosition += line.getHeight(); + } } } } diff --git a/src/org/apache/fop/render/RendererContext.java b/src/org/apache/fop/render/RendererContext.java index 1fa2a1616..2049a95a1 100644 --- a/src/org/apache/fop/render/RendererContext.java +++ b/src/org/apache/fop/render/RendererContext.java @@ -6,6 +6,8 @@ */ package org.apache.fop.render; +import org.apache.log.Logger; + import java.util.HashMap; /** @@ -15,6 +17,7 @@ import java.util.HashMap; */ public class RendererContext { String mime; + Logger log; HashMap props = new HashMap(); public RendererContext(String m) { @@ -25,6 +28,14 @@ public class RendererContext { return mime; } + public void setLogger(Logger logger) { + log = logger; + } + + public Logger getLogger() { + return log; + } + public void setProperty(String name, Object val) { props.put(name, val); } diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java index efaaea94c..45bcee788 100644 --- a/src/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/org/apache/fop/render/pdf/PDFRenderer.java @@ -22,6 +22,8 @@ import org.apache.fop.render.pdf.fonts.LazyFont; import org.apache.fop.area.*; import org.apache.fop.area.inline.*; +import org.apache.fop.area.inline.Character; +import org.apache.fop.layout.FontState; import org.w3c.dom.Document; @@ -30,6 +32,7 @@ import java.io.IOException; import java.io.OutputStream; import java.awt.geom.Rectangle2D; import java.util.HashMap; +import java.util.List; /* TODO: @@ -92,7 +95,11 @@ public class PDFRenderer extends PrintRenderer { */ PDFPage currentPage; + // drawing state PDFColor currentColor; + String currentFontName = ""; + int currentFontSize = 0; + int pageHeight; /** * true if a TJ command is left to be written @@ -191,6 +198,7 @@ public class PDFRenderer extends PrintRenderer { Rectangle2D bounds = page.getViewArea(); double w = bounds.getWidth(); double h = bounds.getHeight(); + pageHeight = (int)h; currentPage = this.pdfDoc.makePage(this.pdfResources, (int) Math.round(w / 1000), (int) Math.round(h / 1000)); pageReferences.put(page, currentPage.referencePDF()); @@ -208,4 +216,213 @@ public class PDFRenderer extends PrintRenderer { this.pdfDoc.output(ostream); } + public void renderCharacter(Character ch) { + + super.renderCharacter(ch); + } + + public void renderWord(Word word) { + StringBuffer pdf = new StringBuffer(); + + FontState fs = null; + + List props = word.getPropertyList(); + for(int count = 0; count < props.size(); count++) { + Property pro = (Property)props.get(count); + if(pro.propType == Property.FONT_STATE) { + fs = (FontState)pro.data; + } + } + String name = fs.getFontName(); + int size = fs.getFontSize(); + + // This assumes that *all* CIDFonts use a /ToUnicode mapping + boolean useMultiByte = false; + Font f = (Font)fs.getFontInfo().getFonts().get(name); + if (f instanceof LazyFont){ + if(((LazyFont) f).getRealFont() instanceof CIDFont){ + useMultiByte = true; + } + } else if (f instanceof CIDFont){ + useMultiByte = true; + } + // String startText = useMultiByte ? " " : ") "; + + updateFont(name, size, pdf); + updateColor(true, pdf); + + int rx = currentBlockIPPosition; + int bl = pageHeight - currentBPPosition; + + // Set letterSpacing + //float ls = fs.getLetterSpacing() / this.currentFontSize; + //pdf.append(ls).append(" Tc\n"); + + if (!textOpen || bl != prevWordY) { + closeText(); + + pdf.append("1 0 0 1 " + (rx / 1000f) + " " + (bl / 1000f) + + " Tm [" + startText); + prevWordY = bl; + textOpen = true; + } else { + // express the space between words in thousandths of an em + int space = prevWordX - rx + prevWordWidth; + float emDiff = (float)space / (float)currentFontSize * 1000f; + // this prevents a problem in Acrobat Reader and other viewers + // where large numbers cause text to disappear or default to + // a limit + if (emDiff < -33000) { + closeText(); + + pdf.append("1 0 0 1 " + (rx / 1000f) + " " + (bl / 1000f) + + " Tm [" + startText); + textOpen = true; + } else { + pdf.append(Float.toString(emDiff)); + pdf.append(" "); + pdf.append(startText); + } + } + prevWordWidth = word.getWidth(); + prevWordX = rx; + + String s = word.getWord(); + + escapeText(s, fs, useMultiByte, pdf); + pdf.append(endText); + + currentStream.add(pdf.toString()); + + super.renderWord(word); + } + + public void escapeText(String s, FontState fs, boolean useMultiByte, StringBuffer pdf) { + String startText = useMultiByte ? "<" : "("; + String endText = useMultiByte ? "> " : ") "; + + boolean kerningAvailable = false; + HashMap kerning = null; + kerning = fs.getKerning(); + if (kerning != null &&!kerning.isEmpty()) { + kerningAvailable = true; + } + + int l = s.length(); + + for (int i = 0; i < l; i++) { + char ch = fs.mapChar(s.charAt(i)); + + if (!useMultiByte) { + if (ch > 127) { + pdf.append("\\"); + pdf.append(Integer.toOctalString((int)ch)); + } else { + switch (ch) { + case '(': + case ')': + case '\\': + pdf.append("\\"); + break; + } + pdf.append(ch); + } + } else { + pdf.append(getUnicodeString(ch)); + } + + if (kerningAvailable && (i + 1) < l) { + addKerning(pdf, (new Integer((int)ch)), + (new Integer((int)fs.mapChar(s.charAt(i + 1)))), + kerning, startText, endText); + } + } + } + + /** + * Convert a char to a multibyte hex representation + */ + private String getUnicodeString(char c) { + StringBuffer buf = new StringBuffer(4); + + byte[] uniBytes = null; + try { + char[] a = {c}; + uniBytes = new String(a).getBytes("UnicodeBigUnmarked"); + } catch (java.io.UnsupportedEncodingException e) { + // This should never fail + } + + for (int i = 0; i < uniBytes.length; i++) { + int b = (uniBytes[i] < 0) ? (int)(256 + uniBytes[i]) + : (int)uniBytes[i]; + + String hexString = Integer.toHexString(b); + if (hexString.length() == 1) + buf = buf.append("0" + hexString); + else + buf = buf.append(hexString); + } + return buf.toString(); + } + + private void addKerning(StringBuffer buf, Integer ch1, Integer ch2, + HashMap kerning, String startText, + String endText) { + HashMap kernPair = (HashMap)kerning.get(ch1); + + if (kernPair != null) { + Integer width = (Integer)kernPair.get(ch2); + if (width != null) { + buf.append(endText).append(-(width.intValue())).append(' ').append(startText); + } + } + } + + /** + * Checks to see if we have some text rendering commands open + * still and writes out the TJ command to the stream if we do + */ + private void closeText() { + if (textOpen) { + currentStream.add("] TJ\n"); + textOpen = false; + prevWordX = 0; + prevWordY = 0; + } + } + + private void updateColor(boolean fill, StringBuffer pdf) { + /*PDFColor areaColor = null; + if (this.currentFill instanceof PDFColor) { + areaColor = (PDFColor)this.currentFill; + } + + if (areaColor == null || areaColor.red() != (double)area.getRed() + || areaColor.green() != (double)area.getGreen() + || areaColor.blue() != (double)area.getBlue()) { + + areaColor = new PDFColor((double)area.getRed(), + (double)area.getGreen(), + (double)area.getBlue()); + + closeText(); + this.currentFill = areaColor; + pdf.append(this.currentFill.getColorSpaceOut(true)); + }*/ + } + + private void updateFont(String name, int size, StringBuffer pdf) { + if ((!name.equals(this.currentFontName)) + || (size != this.currentFontSize)) { + closeText(); + + this.currentFontName = name; + this.currentFontSize = size; + pdf = pdf.append("/" + name + " " + (size / 1000) + " Tf\n"); + } + } } + diff --git a/src/org/apache/fop/tools/TestConverter.java b/src/org/apache/fop/tools/TestConverter.java index 2f06daffc..846c5773c 100644 --- a/src/org/apache/fop/tools/TestConverter.java +++ b/src/org/apache/fop/tools/TestConverter.java @@ -45,7 +45,7 @@ public class TestConverter { File destdir; File compare = null; String baseDir = "./"; - Hashtable differ = new Hashtable(); + HashMap differ = new HashMap(); private Logger log; /** @@ -117,7 +117,7 @@ public class TestConverter { * This runs the tests specified in the xml file fname. * The document is read as a dom and each testcase is covered. */ - public Hashtable runTests(String fname, String dest, String compDir) { + public HashMap runTests(String fname, String dest, String compDir) { log.debug("running tests in file:" + fname); try { if (compDir != null) { diff --git a/src/org/apache/fop/tools/anttasks/CompileXMLFiles.java b/src/org/apache/fop/tools/anttasks/CompileXMLFiles.java deleted file mode 100644 index 7342c2883..000000000 --- a/src/org/apache/fop/tools/anttasks/CompileXMLFiles.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.tools.anttasks; - -/** - * This class is an extension of Ant, a script utility from - * jakarta.apache.org. - * It takes a couple of xml files conforming to the xml-site dtd and - * writes them all into one xml file, deleting any reference to - * the proprietary protocol sbk. The configFile determines what files - * are read in what sequence. - */ -// Ant -import org.apache.tools.ant.Task; -import org.apache.tools.ant.BuildException; - - -// SAX -import org.xml.sax.Parser; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.Locator; -import org.xml.sax.AttributeList; - -// Java -import java.io.*; -import java.util.*; -import java.net.URL; - -public class CompileXMLFiles extends Task - implements org.xml.sax.EntityResolver, org.xml.sax.DTDHandler, - org.xml.sax.DocumentHandler, org.xml.sax.ErrorHandler { - private String configFile, outFile; - private String[] filenameList; - private String filenames; - private ArrayList files = new ArrayList(); - - // sets name of configuration file, which must - // be an xml file conforming to the book.dtd used by xml-site - public void setConfigFile(String configFile) { - this.configFile = configFile; - } - - public void setOutFile(String outFile) { - this.outFile = outFile; - } - - - // main method of this task - public void execute() throws BuildException { - boolean errors = false; - - if (!(new File(configFile).exists())) { - errors = true; - System.err.println("Task CompileXMLFiles - ERROR: config file " - + configFile + " is missing."); - } - - Parser parser = createParser(); - - if (parser == null) { - System.err.println("Task CompileXMLFiles - ERROR: Unable to create SAX parser"); - errors = true; - } - parser.setDocumentHandler(this); - try { - parser.parse(CompileXMLFiles.fileInputSource(configFile)); - } catch (SAXException e) { - System.out.println(e); - } catch (IOException ioe) { - System.out.println(ioe); - } - } // end: execute() - - - /* the following methods belong to the sax parser and implement the Document Handler */ - public InputSource resolveEntity(String publicId, - String systemId) throws SAXException { - return null; - } - - public void notationDecl(String name, String publicId, String systemId) { - // no op - } - - public void unparsedEntityDecl(String name, String publicId, - String systemId, String notationName) { - // no op - } - - public void setDocumentLocator(Locator locator) { - // no op - } - - public void startDocument() throws SAXException { - // no op - } - - /* - * After the cnfiguration file has been parsed all files which - * have been collected in the ArrayList files are concatinated - * and written to a new (temporary) file - */ - public void endDocument() throws SAXException { - String line, filename; - BufferedReader in; - try { - BufferedWriter out = - new BufferedWriter(new FileWriter("compileXMLFiles-tmp.xml")); - out.write("\n" - + "\n" + "]>\n"); - for(int count = 0; count < files.size(); count++) { - filename = (String)files.get(count); - in = new BufferedReader(new FileReader(filename)); - while ((line = in.readLine()) != null) { - // kill the lines pointing to the sbk protocol and the xml declaration - if (line.indexOf(""); - out.close(); - } catch (Exception e) { - System.out.println(e); - } - - } - - public void startElement(String name, - AttributeList atts) throws SAXException { - String id, label, source; - if (name.equals("document") || name.equals("entry")) { - source = atts.getValue("source"); - files.add(source); - } - } - - public void endElement(String name) throws SAXException { - // no op - } - - public void characters(char ch[], int start, - int length) throws SAXException { - // no op - } - - public void ignorableWhitespace(char ch[], int start, - int length) throws SAXException { - // no op - } - - public void processingInstruction(String target, - String data) throws SAXException { - // no op - } - - public void warning(SAXParseException e) throws SAXException { - // no op - } - - public void error(SAXParseException e) throws SAXException { - // no op - } - - public void fatalError(SAXParseException e) throws SAXException { - throw e; - } - - /* ------------------------ */ - - /** - * creates a SAX parser, using the value of org.xml.sax.parser - * defaulting to org.apache.xerces.parsers.SAXParser - * - * @return the created SAX parser - */ - static Parser createParser() { - String parserClassName = System.getProperty("org.xml.sax.parser"); - if (parserClassName == null) { - parserClassName = "org.apache.xerces.parsers.SAXParser"; - } - System.err.println("using SAX parser " + parserClassName); - - try { - return (Parser)Class.forName(parserClassName).newInstance(); - } catch (ClassNotFoundException e) { - System.err.println("Could not find " + parserClassName); - } catch (InstantiationException e) { - System.err.println("Could not instantiate " + parserClassName); - } catch (IllegalAccessException e) { - System.err.println("Could not access " + parserClassName); - } catch (ClassCastException e) { - System.err.println(parserClassName + " is not a SAX driver"); - } - return null; - } - - /** - * create an InputSource from a file name - * - * @param filename the name of the file - * @return the InputSource created - */ - protected static InputSource fileInputSource(String filename) { - - /* this code adapted from James Clark's in XT */ - File file = new File(filename); - String path = file.getAbsolutePath(); - String fSep = System.getProperty("file.separator"); - if (fSep != null && fSep.length() == 1) - path = path.replace(fSep.charAt(0), '/'); - if (path.length() > 0 && path.charAt(0) != '/') - path = '/' + path; - try { - return new InputSource(new URL("file", null, path).toString()); - } catch (java.net.MalformedURLException e) { - throw new Error("unexpected MalformedURLException"); - } - } - -} - diff --git a/src/org/apache/fop/tools/anttasks/RunTest.java b/src/org/apache/fop/tools/anttasks/RunTest.java index 53e58f89b..78d19ca07 100644 --- a/src/org/apache/fop/tools/anttasks/RunTest.java +++ b/src/org/apache/fop/tools/anttasks/RunTest.java @@ -76,15 +76,15 @@ public class RunTest extends Task { ClassLoader loader = new URLClassLoader(new URL[] { new URL("file:build/fop.jar") }); - Hashtable diff = runConverter(loader, "areatree", + HashMap diff = runConverter(loader, "areatree", "reference/output/"); if (diff != null &&!diff.isEmpty()) { System.out.println("===================================="); System.out.println("The following files differ:"); boolean broke = false; - for (Enumeration keys = diff.keys(); - keys.hasMoreElements(); ) { - Object fname = keys.nextElement(); + for (Iterator keys = diff.keySet().iterator(); + keys.hasNext(); ) { + Object fname = keys.next(); Boolean pass = (Boolean)diff.get(fname); System.out.println("file: " + fname + " - reference success: " + pass); @@ -165,11 +165,11 @@ public class RunTest extends Task { * file in the base directory. * @param loader the class loader to use to run the tests with */ - protected Hashtable runConverter(ClassLoader loader, String dest, + protected HashMap runConverter(ClassLoader loader, String dest, String compDir) { String converter = "org.apache.fop.tools.TestConverter"; - Hashtable diff = null; + HashMap diff = null; try { Class cla = Class.forName(converter, true, loader); Object tc = cla.newInstance(); @@ -185,7 +185,7 @@ public class RunTest extends Task { meth = cla.getMethod("runTests", new Class[] { String.class, String.class, String.class }); - diff = (Hashtable)meth.invoke(tc, new Object[] { + diff = (HashMap)meth.invoke(tc, new Object[] { testsuite, dest, compDir }); } catch (Exception e) { diff --git a/src/org/apache/fop/viewer/SecureResourceBundle.java b/src/org/apache/fop/viewer/SecureResourceBundle.java index 9e0f44048..2bbfc38e7 100644 --- a/src/org/apache/fop/viewer/SecureResourceBundle.java +++ b/src/org/apache/fop/viewer/SecureResourceBundle.java @@ -15,7 +15,6 @@ import java.io.*; * Die Klasse SecureResourceBundle ist ein Resourceundle, das im Falle eines fehlenden * Eintrages keinen Absturz verursacht, sondern die Meldung * Key key not found zurückgibt. - * @see PropertyResourceBundle * * @author Stanislav.Gorkhover@jCatalog.com * @version 1.0 18.03.1999 @@ -48,14 +47,10 @@ public class SecureResourceBundle extends ResourceBundle } } - - public Enumeration getKeys() { return lookup.keys(); } - - /** * Händelt den abgefragten Key, liefert entweder den zugehörigen Wert oder eine Meldung. * Die null wird nie zurückgegeben. @@ -101,5 +96,5 @@ public class SecureResourceBundle extends ResourceBundle public boolean isSourceFound() { return isSourceFound; } - } +