]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugfix: Area generated by page-number is now cloned for each addAreas() call.
authorJeremias Maerki <jeremias@apache.org>
Tue, 17 May 2005 16:58:52 +0000 (16:58 +0000)
committerJeremias Maerki <jeremias@apache.org>
Tue, 17 May 2005 16:58:52 +0000 (16:58 +0000)
Bugfix: page-number-citations are now properly resolved. The new method in AreaTreeHandler may not be optimal, but I haven't found a better way, yet.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198642 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/area/AreaTreeHandler.java
src/java/org/apache/fop/layoutmgr/CharacterLayoutManager.java
src/java/org/apache/fop/layoutmgr/ContentLayoutManager.java
src/java/org/apache/fop/layoutmgr/LeaderLayoutManager.java
src/java/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java
src/java/org/apache/fop/layoutmgr/PageNumberCitationLayoutManager.java
src/java/org/apache/fop/layoutmgr/PageNumberLayoutManager.java
src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java

index ca0f87c7d73a37530827e1f1275e1b27407d6380..01a4b616be9116f46741377f92b2d9947573e43e 100644 (file)
@@ -160,19 +160,45 @@ public class AreaTreeHandler extends FOEventHandler {
              * See if this ID is in the unresolved idref list, if so
              * resolve Resolvable objects tied to it.
              */
-            Set todo = (Set) unresolvedIDRefs.get(id);
-            if (todo != null) {
-                for (Iterator iter = todo.iterator(); iter.hasNext();) {
-                    Resolvable res = (Resolvable) iter.next();
-                    res.resolveIDRef(id, pvList);
-                }
-                unresolvedIDRefs.remove(id);
-            }
+            tryIDResolution(id, pv, pvList);
         } else {
             pvList.add(pv);
         }
     }
 
+    /**
+     * Tries to resolve all unresolved ID references on the given page.
+     * @param id ID to resolve
+     * @param pv page viewport whose ID refs to resolve
+     * @param List of PageViewports
+     */
+    private void tryIDResolution(String id, PageViewport pv, List pvList) {
+        Set todo = (Set) unresolvedIDRefs.get(id);
+        if (todo != null) {
+            for (Iterator iter = todo.iterator(); iter.hasNext();) {
+                Resolvable res = (Resolvable) iter.next();
+                res.resolveIDRef(id, pvList);
+            }
+            unresolvedIDRefs.remove(id);
+        }
+    }
+
+    /**
+     * Tries to resolve all unresolved ID references on the given page.
+     * @param pv page viewport whose ID refs to resolve
+     */
+    public void tryIDResolution(PageViewport pv) {
+        String[] ids = pv.getIDRefs();
+        if (ids != null) {
+            for (int i = 0; i < ids.length; i++) {
+                List pvList = (List) idLocations.get(ids[i]);
+                if (pvList != null) {
+                    tryIDResolution(ids[i], pv, pvList);
+                }
+            }
+        }
+    }
+    
     /**
      * Get the list of page viewports that have an area with a given id.
      * @param id the id to lookup
index 2f366108924ccf02face8347dba63a9329bc17ee..10180122b4460945b71aec06af0c4fb694c1723b 100644 (file)
@@ -69,23 +69,24 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
      * inline area.
      * This is used for vertical alignment.
      * Subclasses should override this if necessary.
+     * @param area the inline area to be updated
      * @param context the layout context used for adding the area
      */
-    protected void offsetArea(LayoutContext context) {
-        int bpd = curArea.getBPD();
+    protected void offsetArea(InlineArea area, LayoutContext context) {
+        int bpd = area.getBPD();
         switch (verticalAlignment) {
             case EN_MIDDLE:
-                curArea.setOffset(context.getMiddleBaseline() + fs.getXHeight() / 2);
+                area.setOffset(context.getMiddleBaseline() + fs.getXHeight() / 2);
             break;
             case EN_TOP:
-                curArea.setOffset(fs.getAscender());
+                area.setOffset(fs.getAscender());
             break;
             case EN_BOTTOM:
-                curArea.setOffset(context.getLineHeight() - bpd + fs.getAscender());
+                area.setOffset(context.getLineHeight() - bpd + fs.getAscender());
             break;
             case EN_BASELINE:
             default:
-                curArea.setOffset(context.getBaseline());
+                area.setOffset(context.getBaseline());
             break;
         }
     }
index c1571f0713ecc903065d63dc6ebdf95ee8e2236c..08885990bada831b50a8f45f105f6d7dd158daf4 100644 (file)
@@ -212,11 +212,6 @@ public class ContentLayoutManager implements InlineLevelLayoutManager {
         return false;
     }
 
-    /** @see org.apache.fop.layoutmgr.LayoutManager */
-    public BreakPoss getNextBreakPoss(LayoutContext context) {
-        return null;
-    }
-
     /** @see org.apache.fop.layoutmgr.LayoutManager */
     public boolean isFinished() {
         return false;
index 32859279454ddd88dd59b938141e0154715ed3ce..70dde9baf63f93680393c04498f62573538dc183 100644 (file)
@@ -146,42 +146,42 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
         return leaderArea;
      }
 
-    protected void offsetArea(LayoutContext context) {
+    protected void offsetArea(InlineArea area, LayoutContext context) {
         int pattern = fobj.getLeaderPattern();
-        int bpd = curArea.getBPD();
+        int bpd = area.getBPD();
 
         switch (pattern) {
             case EN_RULE: 
                 switch (verticalAlignment) {
                     case EN_TOP:
-                        curArea.setOffset(0);
+                        area.setOffset(0);
                     break;
                     case EN_MIDDLE:
-                        curArea.setOffset(context.getMiddleBaseline() - bpd / 2);
+                        area.setOffset(context.getMiddleBaseline() - bpd / 2);
                     break;
                     case EN_BOTTOM:
-                        curArea.setOffset(context.getLineHeight() - bpd);
+                        area.setOffset(context.getLineHeight() - bpd);
                     break;
                     case EN_BASELINE: // fall through
                     default:
-                        curArea.setOffset(context.getBaseline() - bpd);
+                        area.setOffset(context.getBaseline() - bpd);
                     break;
                 }
             break;
             case EN_DOTS: 
                 switch (verticalAlignment) {
                     case EN_TOP:
-                        curArea.setOffset(0);
+                        area.setOffset(0);
                     break;
                     case EN_MIDDLE:
-                        curArea.setOffset(context.getMiddleBaseline());
+                        area.setOffset(context.getMiddleBaseline());
                     break;
                     case EN_BOTTOM:
-                        curArea.setOffset(context.getLineHeight() - bpd + font.getAscender());
+                        area.setOffset(context.getLineHeight() - bpd + font.getAscender());
                     break;
                     case EN_BASELINE: // fall through
                     default:
-                        curArea.setOffset(context.getBaseline());
+                        area.setOffset(context.getBaseline());
                     break;
                 }
             break;
@@ -191,17 +191,17 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
             case EN_USECONTENT: 
                 switch (verticalAlignment) {
                     case EN_TOP:
-                        curArea.setOffset(0);
+                        area.setOffset(0);
                     break;
                     case EN_MIDDLE:
-                        curArea.setOffset(context.getMiddleBaseline());
+                        area.setOffset(context.getMiddleBaseline());
                     break;
                     case EN_BOTTOM:
-                        curArea.setOffset(context.getLineHeight() - bpd);
+                        area.setOffset(context.getLineHeight() - bpd);
                     break;
                     case EN_BASELINE: // fall through
                     default:
-                        curArea.setOffset(context.getBaseline());
+                        area.setOffset(context.getBaseline());
                     break;
                 }
             break;
@@ -215,12 +215,12 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
         } else {
             addId();
 
-            widthAdjustArea(context);
+            widthAdjustArea(curArea, context);
 
             // add content areas
             KnuthPossPosIter contentIter = new KnuthPossPosIter(contentList, 0, contentList.size());
             clm.addAreas(contentIter, context);
-            offsetArea(context);
+            offsetArea(curArea, context);
 
             parentLM.addChildArea(curArea);
 
index a3dcba1114faafbea9c0fd2d828dce416ca73e80..83a5c55e10a28114f7a0723630bd590336bc11be 100644 (file)
@@ -33,7 +33,7 @@ import java.util.LinkedList;
  * This class can be extended to handle the creation and adding of the
  * inline area.
  */
-public class LeafNodeLayoutManager extends AbstractLayoutManager 
+public abstract class LeafNodeLayoutManager extends AbstractLayoutManager 
                                    implements InlineLevelLayoutManager {
     /**
      * The inline area that this leafnode will add.
@@ -172,17 +172,26 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager
     public void addAreas(PositionIterator posIter, LayoutContext context) {
         addId();
 
-        offsetArea(context);
-        widthAdjustArea(context);
-        parentLM.addChildArea(curArea);
+        InlineArea area = getEffectiveArea();
+        offsetArea(area, context);
+        widthAdjustArea(area, context);
+        parentLM.addChildArea(area);
 
         while (posIter.hasNext()) {
             posIter.next();
         }
     }
 
+    /**
+     * @return the effective area to be added to the area tree. Normally, this is simply "curArea"
+     * but in the case of page-number(-citation) curArea is cloned, updated and returned.
+     */
+    protected InlineArea getEffectiveArea() {
+        return curArea;
+    }
+    
     protected void addId() {
-        // Do nothing here, overriden in subclasses that has a 'id' property.
+        // Do nothing here, overriden in subclasses that have an 'id' property.
     }
     
     /**
@@ -191,23 +200,24 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager
      * inline area.
      * This is used for vertical alignment.
      * Subclasses should override this if necessary.
+     * @param area the inline area to be updated
      * @param context the layout context used for adding the area
      */
-    protected void offsetArea(LayoutContext context) {
-        int bpd = curArea.getBPD();
+    protected void offsetArea(InlineArea area, LayoutContext context) {
+        int bpd = area.getBPD();
         switch (verticalAlignment) {
             case EN_MIDDLE:
-                curArea.setOffset(context.getMiddleBaseline() - bpd / 2);
+                area.setOffset(context.getMiddleBaseline() - bpd / 2);
             break;
             case EN_TOP:
-                curArea.setOffset(context.getTopBaseline());
+                area.setOffset(context.getTopBaseline());
             break;
             case EN_BOTTOM:
-                curArea.setOffset(context.getBottomBaseline() - bpd);
+                area.setOffset(context.getBottomBaseline() - bpd);
             break;
             case EN_BASELINE:
             default:
-                curArea.setOffset(context.getBaseline() - bpd);
+                area.setOffset(context.getBaseline() - bpd);
             break;
         }
     }
@@ -216,9 +226,10 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager
      * Adjust the width of the area when adding.
      * This uses the min/opt/max values to adjust the with
      * of the inline area by a percentage.
+     * @param area the inline area to be updated
      * @param context the layout context for adding this area
      */
-    protected void widthAdjustArea(LayoutContext context) {
+    protected void widthAdjustArea(InlineArea area, LayoutContext context) {
         double dAdjust = context.getIPDAdjust();
         int width = areaInfo.ipdArea.opt;
         if (dAdjust < 0) {
@@ -228,7 +239,7 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager
             width = (int) (width + dAdjust * (areaInfo.ipdArea.max
                                              - areaInfo.ipdArea.opt));
         }
-        curArea.setIPD(width);
+        area.setIPD(width);
     }
 
     /**
index f03973694cccb76f5e7c02cc96fd9fcbf4deee0a..743db69af6b4a2ff07f9244c335e6eee872c8bca 100644 (file)
@@ -33,7 +33,7 @@ import org.apache.fop.fonts.Font;
 public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager {
 
     private PageNumberCitation fobj;
-    Font font = null;
+    private Font font = null;
     
     // whether the page referred to by the citation has been resolved yet
     private boolean resolved = false;
@@ -62,8 +62,8 @@ public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager {
         }
     }
     
-    protected void offsetArea(LayoutContext context) {
-        curArea.setOffset(context.getBaseline());
+    protected void offsetArea(InlineArea area, LayoutContext context) {
+        area.setOffset(context.getBaseline());
     }
 
     /**
@@ -81,12 +81,7 @@ public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager {
             int width = getStringWidth(str);
             text.setTextArea(str);
             inline.setIPD(width);
-            inline.setBPD(font.getAscender() - font.getDescender());
-            inline.setOffset(font.getAscender());
             
-            inline.addTrait(Trait.FONT_NAME, font.getFontName());
-            inline.addTrait(Trait.FONT_SIZE,
-                         new Integer(font.getFontSize()));
             resolved = true;
         } else {
             resolved = false;
@@ -94,12 +89,12 @@ public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager {
             String str = "MMM"; // reserve three spaces for page number
             int width = getStringWidth(str);
             inline.setIPD(width);
-            inline.setBPD(font.getAscender() - font.getDescender());
-            inline.setOffset(font.getAscender());
             
-            inline.addTrait(Trait.FONT_NAME, font.getFontName());
-            inline.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize()));
         }
+        inline.setBPD(font.getAscender() - font.getDescender());
+        inline.setOffset(font.getAscender());
+        inline.addTrait(Trait.FONT_NAME, font.getFontName());
+        inline.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize()));
         TraitSetter.addTextDecoration(inline, fobj.getTextDecoration());
         
         return inline;
index 382ff9dfd5047fd4cb27bd6055da3b0dcaf3b808..908ee58fc045235a0b181a5c81cd8e9792a38f16 100644 (file)
@@ -29,7 +29,7 @@ import org.apache.fop.fonts.Font;
  */
 public class PageNumberLayoutManager extends LeafNodeLayoutManager {
     private PageNumber fobj;
-    Font font = null;
+    private Font font = null;
     
     /**
      * Constructor
@@ -64,8 +64,27 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager {
         return inline;
     }
     
-    protected void offsetArea(LayoutContext context) {
-        curArea.setOffset(context.getBaseline());
+    protected void offsetArea(InlineArea area, LayoutContext context) {
+        area.setOffset(context.getBaseline());
+    }
+    
+    protected InlineArea getEffectiveArea() {
+        TextArea baseArea = (TextArea)curArea;
+        //TODO Maybe replace that with a clone() call or better, a copy constructor
+        //TODO or even better: delay area creation until addAreas() stage
+        //TextArea is cloned because the LM is reused in static areas and the area can't be.
+        TextArea ta = new TextArea();
+        ta.setIPD(baseArea.getIPD());
+        ta.setBPD(baseArea.getBPD());
+        ta.setOffset(baseArea.getOffset());
+        ta.addTrait(Trait.FONT_NAME, font.getFontName()); //only to initialize the trait map
+        ta.getTraits().putAll(baseArea.getTraits());
+        updateContent(ta);
+        return ta;
+    }
+    
+    private void updateContent(TextArea area) {
+        area.setTextArea(getCurrentPV().getPageNumberString());
     }
     
     protected void addId() {
index d5363f2c6f45ead3c4bcbaae1a93cb9ef754e6c5..54dd6e2fc8fe0f10695832fdea84072bf7d45935 100644 (file)
@@ -531,6 +531,10 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
         layoutSideRegion(FO_REGION_AFTER);
         layoutSideRegion(FO_REGION_START);
         layoutSideRegion(FO_REGION_END);
+        
+        // Try to resolve any unresolved IDs for the current page.
+        // 
+        areaTreeHandler.tryIDResolution(curPV);
         // Queue for ID resolution and rendering
         areaTreeHandler.getAreaTreeModel().addPage(curPV);
         log.debug("page finished: " + curPV.getPageNumberString()