]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
start implementation of block-container
authorKeiron Liddle <keiron@apache.org>
Fri, 30 Aug 2002 08:03:24 +0000 (08:03 +0000)
committerKeiron Liddle <keiron@apache.org>
Fri, 30 Aug 2002 08:03:24 +0000 (08:03 +0000)
does absolute and static and the various reference-orientation

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

src/org/apache/fop/area/Block.java
src/org/apache/fop/area/BlockParent.java
src/org/apache/fop/area/BlockViewport.java [new file with mode: 0644]
src/org/apache/fop/fo/PropertyManager.java
src/org/apache/fop/fo/flow/BlockContainer.java
src/org/apache/fop/fo/flow/InstreamForeignObject.java
src/org/apache/fop/layout/AbsolutePositionProps.java
src/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java [new file with mode: 0644]
src/org/apache/fop/render/AbstractRenderer.java
src/org/apache/fop/render/pdf/PDFRenderer.java

index d1e605d430a21c4cdee67b2a0c25ced42fb496eb..0d745207cef387ef59387eaaad2485c8b3bbd5eb 100644 (file)
@@ -67,6 +67,10 @@ public class Block extends BlockParent implements Serializable {
         return bpd;
     }
 
+    public void setPositioning(int pos) {
+        positioning = pos;
+    }
+
     public int getPositioning() {
         return positioning;
     }
index 2274c37906c5db16256a8a40376ae38e169eac88..f265e6d1031d417b8c149fb1c8293fdc4615180b 100644 (file)
@@ -38,4 +38,11 @@ public class BlockParent extends Area implements Serializable {
         return children;
     }
 
+    public void setBounds(Rectangle2D b) {
+        bounds = b;
+    }
+
+    public Rectangle2D getBounds() {
+        return bounds;
+    }
 }
diff --git a/src/org/apache/fop/area/BlockViewport.java b/src/org/apache/fop/area/BlockViewport.java
new file mode 100644 (file)
index 0000000..9544382
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * $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.area;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * A BlockViewport.
+ * This is used for block level Viewport/reference pairs.
+ * The block-container creates this area.
+ */
+public class BlockViewport extends Block {
+    // clipping for this viewport
+    boolean clip = false;
+    CTM viewportCTM;
+
+    public BlockViewport() {
+
+    }
+
+    public void setCTM(CTM ctm) {
+        viewportCTM = ctm;
+    }
+
+    public CTM getCTM() {
+        return viewportCTM;
+    }
+
+    public void setClip(boolean cl) {
+        clip = cl;
+    }
+
+    public boolean getClip() {
+        return clip;
+    }
+}
index 2599cb0dfdf607209cbf4b73e58d91c0de00bbba..44a98f735ba63ab3fb0d4ab16d8615100e047c1f 100644 (file)
@@ -26,7 +26,7 @@ import org.apache.fop.layout.AbsolutePositionProps;
 import org.apache.fop.traits.BlockProps;
 import org.apache.fop.traits.InlineProps;
 import org.apache.fop.traits.SpaceVal;
-import org.apache.fop.traits.LayoutProps;  // keep, break, span, space?
+import org.apache.fop.traits.LayoutProps; // keep, break, span, space?
 import org.apache.fop.fo.properties.BreakAfter;
 import org.apache.fop.fo.properties.BreakBefore;
 import org.apache.fop.fo.properties.Constants;
@@ -46,55 +46,54 @@ public class PropertyManager {
     private HyphenationProps hyphProps = null;
     private TextInfo textInfo = null;
 
-    private static String[] saBefore = new String[] {"before"};
-    private static String[] saAfter = new String[] {"after"};
-    private static String[] saStart = new String[] {"start"};
-    private static String[] saEnd = new String[] {"end"};
+    private static String[] saBefore = new String[]{"before"};
+    private static String[] saAfter = new String[]{"after"};
+    private static String[] saStart = new String[]{"start"};
+    private static String[] saEnd = new String[]{"end"};
 
-    private static MessageFormat msgColorFmt =
-        new MessageFormat("border-{0}-color");
-    private static MessageFormat msgStyleFmt =
-        new MessageFormat("border-{0}-style");
-    private static MessageFormat msgWidthFmt =
-        new MessageFormat("border-{0}-width");
-    private static MessageFormat msgPaddingFmt =
-        new MessageFormat("padding-{0}");
+    private static MessageFormat msgColorFmt = new MessageFormat("border-{0}-color");
+    private static MessageFormat msgStyleFmt = new MessageFormat("border-{0}-style");
+    private static MessageFormat msgWidthFmt = new MessageFormat("border-{0}-width");
+    private static MessageFormat msgPaddingFmt = new MessageFormat("padding-{0}");
 
     public PropertyManager(PropertyList pList) {
         this.properties = pList;
     }
 
+    public PropertyList getProperties() {
+        return properties;
+    }
+
     public void setFontInfo(FontInfo fontInfo) {
-       m_fontInfo = fontInfo;
+        m_fontInfo = fontInfo;
     }
 
 
     public FontState getFontState(FontInfo fontInfo) {
         if (fontState == null) {
-           if (fontInfo == null) {
-               fontInfo = m_fontInfo;
-           }
-           else if (m_fontInfo == null) {
-               m_fontInfo = fontInfo;
-           }
+            if (fontInfo == null) {
+                fontInfo = m_fontInfo;
+            } else if (m_fontInfo == null) {
+                m_fontInfo = fontInfo;
+            }
             String fontFamily = properties.get("font-family").getString();
             String fontStyle = properties.get("font-style").getString();
             String fw = properties.get("font-weight").getString();
             int fontWeight = 400;
-            if(fw.equals("bolder")) {
+            if (fw.equals("bolder")) {
                 // +100 from inherited
-            } else if(fw.equals("lighter")) {
+            } else if (fw.equals("lighter")) {
                 // -100 from inherited
             } else {
                 try {
                     fontWeight = Integer.parseInt(fw);
-                } catch(NumberFormatException nfe) {
+                } catch (NumberFormatException nfe) {
                 }
             }
-            fontWeight = ((int)fontWeight / 100) * 100;
-            if(fontWeight < 100) {
+            fontWeight = ((int) fontWeight / 100) * 100;
+            if (fontWeight < 100) {
                 fontWeight = 100;
-            } else if(fontWeight > 900) {
+            } else if (fontWeight > 900) {
                 fontWeight = 900;
             }
 
@@ -125,97 +124,104 @@ public class PropertyManager {
 
     private void initBorderInfo(int whichSide, String[] saSide) {
         borderAndPadding.setPadding(whichSide,
-                                    properties.get(msgPaddingFmt.format(saSide)).getCondLength());
+                                    properties.get(
+                                      msgPaddingFmt.format(saSide)).getCondLength());
         // If style = none, force width to 0, don't get Color
         int style = properties.get(msgStyleFmt.format(saSide)).getEnum();
         if (style != Constants.NONE) {
             borderAndPadding.setBorder(whichSide, style,
-                                       properties.get(msgWidthFmt.format(saSide)).getCondLength(),
-                                       properties.get(msgColorFmt.format(saSide)).getColorType());
+                                       properties.get(
+                                         msgWidthFmt.format(saSide)).getCondLength(),
+                                       properties.get(
+                                         msgColorFmt.format(saSide)).getColorType());
         }
     }
 
     public HyphenationProps getHyphenationProps() {
         if (hyphProps == null) {
             this.hyphProps = new HyphenationProps();
-            hyphProps.hyphenate = this.properties.get("hyphenate").getEnum();
-            hyphProps.hyphenationChar =
-                this.properties.get("hyphenation-character").getCharacter();
-            hyphProps.hyphenationPushCharacterCount =
-                this.properties.get("hyphenation-push-character-count").getNumber().intValue();
-            hyphProps.hyphenationRemainCharacterCount =
-                this.properties.get("hyphenation-remain-character-count").getNumber().intValue();
-            hyphProps.language = this.properties.get("language").getString();
+            hyphProps.hyphenate =
+              this.properties.get("hyphenate").getEnum();
+            hyphProps.hyphenationChar = this.properties.get(
+                                          "hyphenation-character").getCharacter();
+            hyphProps.hyphenationPushCharacterCount = this.properties.get(
+                      "hyphenation-push-character-count").getNumber().
+                    intValue();
+            hyphProps.hyphenationRemainCharacterCount = this.properties.get(
+                      "hyphenation-remain-character-count").getNumber().
+                    intValue();
+            hyphProps.language =
+              this.properties.get("language").getString();
             hyphProps.country = this.properties.get("country").getString();
         }
         return hyphProps;
     }
 
     /*public int checkBreakBefore(Area area) {
-        if (!(area instanceof ColumnArea)) {
-            switch (properties.get("break-before").getEnum()) {
-            case BreakBefore.PAGE:
-                return Status.FORCE_PAGE_BREAK;
-            case BreakBefore.ODD_PAGE:
-                return Status.FORCE_PAGE_BREAK_ODD;
-            case BreakBefore.EVEN_PAGE:
-                return Status.FORCE_PAGE_BREAK_EVEN;
-            case BreakBefore.COLUMN:
-                return Status.FORCE_COLUMN_BREAK;
-            default:
-                return Status.OK;
-            }
-        } else {
-            ColumnArea colArea = (ColumnArea)area;
-            switch (properties.get("break-before").getEnum()) {
-            case BreakBefore.PAGE:
-                // if first ColumnArea, and empty, return OK
-                if (!colArea.hasChildren() && (colArea.getColumnIndex() == 1))
-                    return Status.OK;
-                else
-                    return Status.FORCE_PAGE_BREAK;
-            case BreakBefore.ODD_PAGE:
-                // if first ColumnArea, empty, _and_ in odd page,
-                // return OK
-                if (!colArea.hasChildren() && (colArea.getColumnIndex() == 1)
-                        && (colArea.getPage().getNumber() % 2 != 0))
-                    return Status.OK;
-                else
-                    return Status.FORCE_PAGE_BREAK_ODD;
-            case BreakBefore.EVEN_PAGE:
-                // if first ColumnArea, empty, _and_ in even page,
-                // return OK
-                if (!colArea.hasChildren() && (colArea.getColumnIndex() == 1)
-                        && (colArea.getPage().getNumber() % 2 == 0))
-                    return Status.OK;
-                else
-                    return Status.FORCE_PAGE_BREAK_EVEN;
-            case BreakBefore.COLUMN:
-                // if ColumnArea is empty return OK
-                if (!area.hasChildren())
-                    return Status.OK;
-                else
-                    return Status.FORCE_COLUMN_BREAK;
-            default:
-                return Status.OK;
-            }
-        }
-    }
-
-    public int checkBreakAfter(Area area) {
-        switch (properties.get("break-after").getEnum()) {
-        case BreakAfter.PAGE:
-            return Status.FORCE_PAGE_BREAK;
-        case BreakAfter.ODD_PAGE:
-            return Status.FORCE_PAGE_BREAK_ODD;
-        case BreakAfter.EVEN_PAGE:
-            return Status.FORCE_PAGE_BREAK_EVEN;
-        case BreakAfter.COLUMN:
-            return Status.FORCE_COLUMN_BREAK;
-        default:
-            return Status.OK;
-        }
-    }*/
+         if (!(area instanceof ColumnArea)) {
+             switch (properties.get("break-before").getEnum()) {
+             case BreakBefore.PAGE:
+                 return Status.FORCE_PAGE_BREAK;
+             case BreakBefore.ODD_PAGE:
+                 return Status.FORCE_PAGE_BREAK_ODD;
+             case BreakBefore.EVEN_PAGE:
+                 return Status.FORCE_PAGE_BREAK_EVEN;
+             case BreakBefore.COLUMN:
+                 return Status.FORCE_COLUMN_BREAK;
+             default:
+                 return Status.OK;
+             }
+         } else {
+             ColumnArea colArea = (ColumnArea)area;
+             switch (properties.get("break-before").getEnum()) {
+             case BreakBefore.PAGE:
+                 // if first ColumnArea, and empty, return OK
+                 if (!colArea.hasChildren() && (colArea.getColumnIndex() == 1))
+                     return Status.OK;
+                 else
+                     return Status.FORCE_PAGE_BREAK;
+             case BreakBefore.ODD_PAGE:
+                 // if first ColumnArea, empty, _and_ in odd page,
+                 // return OK
+                 if (!colArea.hasChildren() && (colArea.getColumnIndex() == 1)
+                         && (colArea.getPage().getNumber() % 2 != 0))
+                     return Status.OK;
+                 else
+                     return Status.FORCE_PAGE_BREAK_ODD;
+             case BreakBefore.EVEN_PAGE:
+                 // if first ColumnArea, empty, _and_ in even page,
+                 // return OK
+                 if (!colArea.hasChildren() && (colArea.getColumnIndex() == 1)
+                         && (colArea.getPage().getNumber() % 2 == 0))
+                     return Status.OK;
+                 else
+                     return Status.FORCE_PAGE_BREAK_EVEN;
+             case BreakBefore.COLUMN:
+                 // if ColumnArea is empty return OK
+                 if (!area.hasChildren())
+                     return Status.OK;
+                 else
+                     return Status.FORCE_COLUMN_BREAK;
+             default:
+                 return Status.OK;
+             }
+         }
+     }
+
+     public int checkBreakAfter(Area area) {
+         switch (properties.get("break-after").getEnum()) {
+         case BreakAfter.PAGE:
+             return Status.FORCE_PAGE_BREAK;
+         case BreakAfter.ODD_PAGE:
+             return Status.FORCE_PAGE_BREAK_ODD;
+         case BreakAfter.EVEN_PAGE:
+             return Status.FORCE_PAGE_BREAK_EVEN;
+         case BreakAfter.COLUMN:
+             return Status.FORCE_COLUMN_BREAK;
+         default:
+             return Status.OK;
+         }
+     }*/
 
 
     public MarginProps getMarginProps() {
@@ -223,21 +229,25 @@ public class PropertyManager {
 
         // Common Margin Properties-Block
         props.marginTop =
-            this.properties.get("margin-top").getLength().mvalue();
+          this.properties.get("margin-top").getLength().mvalue();
         props.marginBottom =
-            this.properties.get("margin-bottom").getLength().mvalue();
+          this.properties.get("margin-bottom").getLength().mvalue();
         props.marginLeft =
-            this.properties.get("margin-left").getLength().mvalue();
+          this.properties.get("margin-left").getLength().mvalue();
         props.marginRight =
-            this.properties.get("margin-right").getLength().mvalue();
+          this.properties.get("margin-right").getLength().mvalue();
 
         // For now, we only get the optimum value for space-before and after
-        props.spaceBefore = this.properties.get("space-before").getSpace().
-           getOptimum().getLength().mvalue();
-        props.spaceAfter = this.properties.get("space-after").getSpace().
-           getOptimum().getLength().mvalue();
-        props.startIndent = this.properties.get("start-indent").getLength().mvalue();
-        props.endIndent = this.properties.get("end-indent").getLength().mvalue();
+        props.spaceBefore = this.properties.get(
+                              "space-before").getSpace(). getOptimum().getLength().
+                            mvalue();
+        props.spaceAfter = this.properties.get(
+                             "space-after").getSpace(). getOptimum().getLength().
+                           mvalue();
+        props.startIndent =
+          this.properties.get("start-indent").getLength().mvalue();
+        props.endIndent =
+          this.properties.get("end-indent").getLength().mvalue();
 
         return props;
     }
@@ -254,10 +264,10 @@ public class PropertyManager {
 
     public InlineProps getInlineProps() {
         InlineProps props = new InlineProps();
-        props.spaceStart = new SpaceVal(properties.get("space-start").
-                                       getSpace());
-        props.spaceEnd = new SpaceVal(properties.get("space-end").
-                                       getSpace());
+        props.spaceStart =
+          new SpaceVal(properties.get("space-start"). getSpace());
+        props.spaceEnd =
+          new SpaceVal(properties.get("space-end"). getSpace());
         return props;
     }
 
@@ -265,11 +275,11 @@ public class PropertyManager {
         AccessibilityProps props = new AccessibilityProps();
         String str;
         str = this.properties.get("source-document").getString();
-        if(!"none".equals(str)) {
+        if (!"none".equals(str)) {
             props.sourceDoc = str;
         }
         str = this.properties.get("role").getString();
-        if(!"none".equals(str)) {
+        if (!"none".equals(str)) {
             props.role = str;
         }
         return props;
@@ -287,19 +297,25 @@ public class PropertyManager {
 
     public AbsolutePositionProps getAbsolutePositionProps() {
         AbsolutePositionProps props = new AbsolutePositionProps();
+        props.absolutePosition =
+          this.properties.get("absolute-position").getEnum();
+        props.top = this.properties.get("top").getLength().mvalue();
+        props.bottom = this.properties.get("bottom").getLength().mvalue();
+        props.left = this.properties.get("left").getLength().mvalue();
+        props.right = this.properties.get("right").getLength().mvalue();
         return props;
     }
 
     public BlockProps getBlockProps() {
         BlockProps props = new BlockProps();
-        props.firstIndent = this.properties.get("text-indent").
-           getLength().mvalue();
+        props.firstIndent =
+          this.properties.get("text-indent"). getLength().mvalue();
         props.lastIndent = 0; /*this.properties.get("last-line-end-indent").getLength().mvalue(); */
         props.textAlign = this.properties.get("text-align").getEnum();
-        props.textAlignLast = this.properties.get("text-align-last").
-           getEnum();
-       props.lineStackType = this.properties.
-           get("line-stacking-strategy").getEnum();
+        props.textAlignLast =
+          this.properties.get("text-align-last"). getEnum();
+        props.lineStackType =
+          this.properties. get("line-stacking-strategy").getEnum();
 
         return props;
     }
@@ -308,81 +324,83 @@ public class PropertyManager {
         LayoutProps props = new LayoutProps();
         props.breakBefore = this.properties.get("break-before").getEnum();
         props.breakAfter = this.properties.get("break-after").getEnum();
-       props.bIsSpan = (this.properties.get("span").getEnum() == Span.ALL);
-        props.spaceBefore = new SpaceVal(this.properties.get("space-before").
-                                        getSpace());
-        props.spaceAfter = new SpaceVal(this.properties.get("space-after").
-                                       getSpace());
+        props.bIsSpan = (this.properties.get("span").getEnum() == Span.ALL);
+        props.spaceBefore = new SpaceVal(
+                              this.properties.get("space-before"). getSpace());
+        props.spaceAfter = new SpaceVal(
+                             this.properties.get("space-after"). getSpace());
         return props;
     }
 
     public TextInfo getTextLayoutProps(FontInfo fontInfo) {
-       if (textInfo == null) {
-           textInfo = new TextInfo();
-               textInfo.fs = getFontState(fontInfo);
-           textInfo.color = properties.get("color").getColorType();
+        if (textInfo == null) {
+            textInfo = new TextInfo();
+            textInfo.fs = getFontState(fontInfo);
+            textInfo.color = properties.get("color").getColorType();
 
-           textInfo.verticalAlign =
-                properties.get("vertical-align").getEnum();
+            textInfo.verticalAlign =
+              properties.get("vertical-align").getEnum();
 
-           textInfo.wrapOption = properties.get("wrap-option").getEnum();
-           textInfo.bWrap = (textInfo.wrapOption == Constants.WRAP);
+            textInfo.wrapOption = properties.get("wrap-option").getEnum();
+            textInfo.bWrap = (textInfo.wrapOption == Constants.WRAP);
 
-           textInfo.wordSpacing =
-               new SpaceVal(properties.get("word-spacing").getSpace());
+            textInfo.wordSpacing = new SpaceVal(
+                                     properties.get("word-spacing").getSpace());
 
-           /* textInfo.letterSpacing =
-              new SpaceVal(properties.get("letter-spacing").getSpace());*/
+            /* textInfo.letterSpacing =
+               new SpaceVal(properties.get("letter-spacing").getSpace());*/
 
-           textInfo.whiteSpaceCollapse =
-                properties.get("white-space-collapse").getEnum();
+            textInfo.whiteSpaceCollapse =
+              properties.get("white-space-collapse").getEnum();
 
-           textInfo.lineHeight = this.properties.
-               get("line-height").getLength().mvalue();
-       }
-       return textInfo;
+            textInfo.lineHeight = this.properties. get(
+                                    "line-height").getLength().mvalue();
+        }
+        return textInfo;
     }
 
-    public CTM getCTMandRelDims(Rectangle2D absVPrect, FODimension reldims) {
-       int width, height;
+    public CTM getCTMandRelDims(Rectangle2D absVPrect,
+                                FODimension reldims) {
+        int width, height;
         // We will use the absolute reference-orientation to set up the CTM.
         // The value here is relative to its ancestor reference area.
-        int absRefOrient =
-            getAbsRefOrient(this.properties.get("reference-orientation").
-                           getNumber().intValue());
+        int absRefOrient = getAbsRefOrient( this.properties.get(
+                                              "reference-orientation"). getNumber().intValue());
         if (absRefOrient % 180 == 0) {
-            width = (int)absVPrect.getWidth();
-            height = (int)absVPrect.getHeight();
-        }
-        else {
+            width = (int) absVPrect.getWidth();
+            height = (int) absVPrect.getHeight();
+        } else {
             // invert width and height since top left are rotated by 90 (cl or ccl)
-            height = (int)absVPrect.getWidth();
-            width = (int)absVPrect.getHeight();
+            height = (int) absVPrect.getWidth();
+            width = (int) absVPrect.getHeight();
         }
-        /* Set up the CTM for the content of this reference area. This will transform
-         * region content coordinates in writing-mode relative into absolute page-relative
-         * which will then be translated based on the position of the region viewport
-         * (Note: scrolling between region vp and ref area when doing online content!)
+        /* Set up the CTM for the content of this reference area.
+         * This will transform region content coordinates in
+         * writing-mode relative into absolute page-relative
+         * which will then be translated based on the position of
+         * the region viewport.
+         * (Note: scrolling between region vp and ref area when
+         * doing online content!)
          */
-         CTM ctm = new CTM(absVPrect.getX(), absVPrect.getY());
+        CTM ctm = new CTM(absVPrect.getX(), absVPrect.getY());
 
-         // First transform for rotation
-         if (absRefOrient != 0) {
+        // First transform for rotation
+        if (absRefOrient != 0) {
             // Rotation implies translation to keep the drawing area in the
             // first quadrant. Note: rotation is counter-clockwise
-             switch (absRefOrient) {
-               case 90:
-                ctm = ctm.translate(0, width); // width = absVPrect.height
-                break;
-            case 180:
-                ctm = ctm.translate(width, height);
-                break;
-            case 270:
-                ctm = ctm.translate(height,0); // height = absVPrect.width
-                break;
-           }
-           ctm = ctm.rotate(absRefOrient);
-         }
+            switch (absRefOrient) {
+                case 90:
+                    ctm = ctm.translate(0, width); // width = absVPrect.height
+                    break;
+                case 180:
+                    ctm = ctm.translate(width, height);
+                    break;
+                case 270:
+                    ctm = ctm.translate(height, 0); // height = absVPrect.width
+                    break;
+            }
+            ctm = ctm.rotate(absRefOrient);
+        }
         int wm = this.properties.get("writing-mode").getEnum();
         /* Since we've already put adjusted width and height values for the
          * top and left positions implied by the reference-orientation, we
@@ -392,13 +410,12 @@ public class PropertyManager {
         if (wm == WritingMode.LR_TB || wm == WritingMode.RL_TB) {
             reldims.ipd = width;
             reldims.bpd = height;
+        } else {
+            reldims.ipd = height;
+            reldims.bpd = width;
         }
-        else {
-            reldims.ipd=height;
-            reldims.bpd=width;
-        }
-       // Set a rectangle to be the writing-mode relative version???
-       // Now transform for writing mode
+        // Set a rectangle to be the writing-mode relative version???
+        // Now transform for writing mode
         return ctm.multiply(CTM.getWMctm(wm, reldims.ipd, reldims.bpd));
     }
 
@@ -406,6 +423,6 @@ public class PropertyManager {
      * Calculate absolute reference-orientation relative to media orientation.
      */
     private int getAbsRefOrient(int myRefOrient) {
-       return myRefOrient;
+        return myRefOrient;
     }
 }
index 6bd81f1e090840b765c0510d27e4b07e0a78fbd0..ab64158b6494be1c3c844cd6efee37cccb9a4ec3 100644 (file)
@@ -14,10 +14,12 @@ import org.apache.fop.fo.pagination.PageSequence;
 import org.apache.fop.layout.*;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.datatypes.*;
-
+import org.apache.fop.layoutmgr.BlockContainerLayoutManager;
 
 import org.xml.sax.Attributes;
 
+import java.util.List;
+
 public class BlockContainer extends FObj {
 
     ColorType backgroundColor;
@@ -42,6 +44,12 @@ public class BlockContainer extends FObj {
         setupID();
     }
 
+    public void addLayoutManager(List list) {
+        BlockContainerLayoutManager blm = new BlockContainerLayoutManager(this);
+        blm.setOverflow(properties.get("overflow").getEnum());
+        list.add(blm);
+    }
+
     public void setup() {
 
             // Common Accessibility Properties
@@ -75,11 +83,6 @@ public class BlockContainer extends FObj {
             this.backgroundColor =
                 this.properties.get("background-color").getColorType();
 
-            this.position = this.properties.get("position").getEnum();
-            this.top = this.properties.get("top").getLength().mvalue();
-            this.bottom = this.properties.get("bottom").getLength().mvalue();
-            this.left = this.properties.get("left").getLength().mvalue();
-            this.right = this.properties.get("right").getLength().mvalue();
             this.width = this.properties.get("width").getLength().mvalue();
             this.height = this.properties.get("height").getLength().mvalue();
             span = this.properties.get("span").getEnum();
@@ -99,3 +102,4 @@ public class BlockContainer extends FObj {
     }
 
 }
+
index b39e8c0db8995c8dc98c5d04463f3f08c5d85089..db947752aa813f43c2f5538ab6028eac4331319c 100644 (file)
@@ -201,7 +201,7 @@ public class InstreamForeignObject extends FObj {
             if(overflow == Overflow.HIDDEN) {
                 clip = true;
             } else if(overflow == Overflow.ERROR_IF_OVERFLOW) {
-                getLogger().error("Instream foreign object overflows the viewport");
+                getLogger().error("Instream foreign object overflows the viewport: clipping");
                 clip = true;
             }
         }
index e8e5d1a56429d0a239b4f0be5ae36364f750ccd7..521c47cebf3e5962f8b2656696521235d8fa005a 100644 (file)
@@ -15,10 +15,10 @@ import org.apache.fop.datatypes.Length;
  */
 public class AbsolutePositionProps {
     public int absolutePosition;
-    public Length top;
-    public Length right;
-    public Length bottom;
-    public Length left;
+    public int top;
+    public int right;
+    public int bottom;
+    public int left;
 
     public AbsolutePositionProps() {}
 
diff --git a/src/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
new file mode 100644 (file)
index 0000000..749a0d0
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * $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.layoutmgr;
+
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.TextInfo;
+import org.apache.fop.area.Area;
+import org.apache.fop.area.BlockParent;
+import org.apache.fop.area.BlockViewport;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.LineArea;
+import org.apache.fop.area.MinOptMax;
+import org.apache.fop.fo.PropertyManager;
+import org.apache.fop.layout.AbsolutePositionProps;
+import org.apache.fop.fo.properties.AbsolutePosition;
+import org.apache.fop.fo.properties.Overflow;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.area.CTM;
+import org.apache.fop.datatypes.FODimension;
+
+import java.util.ListIterator;
+import java.util.ArrayList;
+import java.util.List;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * LayoutManager for a block FO.
+ */
+public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
+
+    private BlockViewport viewportBlockArea;
+    private Block curBlockArea;
+
+    ArrayList childBreaks = new ArrayList();
+
+    AbsolutePositionProps abProps;
+    FODimension relDims;
+    CTM absoluteCTM;
+    boolean clip = false;
+    int overflow;
+    PropertyManager propManager;
+
+    public BlockContainerLayoutManager(FObj fobj) {
+        super(fobj);
+    }
+
+    public void setOverflow(int of) {
+        overflow = of;
+    }
+
+    protected void initProperties(PropertyManager pm) {
+        propManager = pm;
+
+        abProps = pm.getAbsolutePositionProps();
+        if(abProps.absolutePosition == AbsolutePosition.ABSOLUTE) {
+            Rectangle2D rect = new Rectangle2D.Double(abProps.left,
+                                abProps.top, abProps.right - abProps.left,
+                                abProps.bottom - abProps.top);
+            relDims = new FODimension(0, 0);
+            absoluteCTM = pm.getCTMandRelDims(rect, relDims);
+        }
+    }
+
+    protected int getRotatedIPD() {
+        PropertyList props = propManager.getProperties();
+        int height = props.get("height").getLength().mvalue();
+        height = props.get("inline-progression-dimension.optimum").getLength().mvalue();
+
+        return height;
+    }
+
+    public BreakPoss getNextBreakPoss(LayoutContext context) {
+
+        if(abProps.absolutePosition == AbsolutePosition.ABSOLUTE) {
+            return getAbsoluteBreakPoss(context);
+        }
+
+        Rectangle2D rect = new Rectangle2D.Double(0, 0, context.getRefIPD(),
+                                                  context.getStackLimit().opt);
+        relDims = new FODimension(0, 0);
+        absoluteCTM = propManager.getCTMandRelDims(rect, relDims);
+        double[] vals = absoluteCTM.toArray();
+
+        MinOptMax stackLimit;
+        int ipd = context.getRefIPD();
+        boolean rotated = vals[0] == 0.0;
+        if(rotated) {
+            // rotated 90 degrees
+            stackLimit = new MinOptMax(1000000);
+            ipd = getRotatedIPD();
+            absoluteCTM = new CTM(vals[0], vals[1], vals[2], vals[3], 0, 0);
+        } else {
+            if(vals[0] == -1.0) {
+                absoluteCTM = new CTM(vals[0], vals[1], vals[2], vals[3], 0, 0);
+            }
+            stackLimit = context.getStackLimit();
+        }
+
+        BPLayoutManager curLM ; // currently active LM
+
+        MinOptMax stackSize = new MinOptMax();
+        // if starting add space before
+        // stackSize.add(spaceBefore);
+        BreakPoss lastPos = null;
+
+        while ((curLM = getChildLM()) != null) {
+            // Make break positions and return blocks!
+            // Set up a LayoutContext
+            BreakPoss bp;
+
+            LayoutContext childLC = new LayoutContext(0);
+                childLC.setStackLimit(
+                  MinOptMax.subtract(stackLimit,
+                                     stackSize));
+                childLC.setRefIPD(ipd);
+
+            while (!curLM.isFinished()) {
+                if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
+                    stackSize.add(bp.getStackingSize());
+                    if (stackSize.min > stackLimit.max) {
+                        // reset to last break
+                        if (lastPos != null) {
+                            reset(lastPos.getPosition());
+                        } else {
+                            curLM.resetPosition(null);
+                        }
+                        break;
+                    }
+                    lastPos = bp;
+                    childBreaks.add(bp);
+
+                    childLC.setStackLimit(MinOptMax.subtract(
+                                           stackLimit, stackSize));
+                }
+            }
+            if(!rotated) {
+                BreakPoss breakPoss;
+                breakPoss = new BreakPoss(new LeafPosition(this,
+                                                   childBreaks.size() - 1));
+                breakPoss.setStackingSize(stackSize);
+                return breakPoss;
+            }
+        }
+        setFinished(true);
+        if(rotated) {
+            BreakPoss breakPoss;
+            breakPoss = new BreakPoss(new LeafPosition(this,
+                                               childBreaks.size() - 1));
+            breakPoss.setStackingSize(new MinOptMax(ipd));
+            return breakPoss;
+        }
+        return null;
+    }
+
+    public BreakPoss getAbsoluteBreakPoss(LayoutContext context) {
+
+        BPLayoutManager curLM ; // currently active LM
+
+        MinOptMax stackSize = new MinOptMax();
+
+        int ipd = relDims.ipd;
+
+        while ((curLM = getChildLM()) != null) {
+            // Make break positions and return blocks!
+            // Set up a LayoutContext 
+            BreakPoss bp;
+
+            LayoutContext childLC = new LayoutContext(0);
+                childLC.setStackLimit(new MinOptMax(1000000));
+                childLC.setRefIPD(ipd);
+
+            while (!curLM.isFinished()) {
+                if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
+                    stackSize.add(bp.getStackingSize());
+                    childBreaks.add(bp);
+                }
+            }
+        }
+        setFinished(true);
+        BreakPoss breakPoss = new BreakPoss(
+                                new LeafPosition(this, childBreaks.size() - 1));
+        // absolutely positioned areas do not contribute
+        // to the normal stacking
+        breakPoss.setStackingSize(new MinOptMax(0));
+
+        if(stackSize.min > relDims.bpd) {
+            if(overflow == Overflow.HIDDEN) {
+                clip = true;
+            } else if(overflow == Overflow.ERROR_IF_OVERFLOW) {
+                //log.error("contents overflows block-container viewport: clipping");
+                clip = true;
+            }
+        }
+
+        return breakPoss;
+    }
+
+    public void addAreas(PositionIterator parentIter,
+                         LayoutContext layoutContext) {
+        getParentArea(null);
+
+        BPLayoutManager childLM ;
+        int iStartPos = 0;
+        LayoutContext lc = new LayoutContext(0);
+        while (parentIter.hasNext()) {
+            LeafPosition lfp = (LeafPosition) parentIter.next();
+            // Add the block areas to Area
+            PositionIterator breakPosIter =
+              new BreakPossPosIter(childBreaks, iStartPos,
+                                   lfp.getLeafPos() + 1);
+            iStartPos = lfp.getLeafPos() + 1;
+            while ((childLM = breakPosIter.getNextChildLM()) != null) {
+                childLM.addAreas(breakPosIter, lc);
+            }
+        }
+
+        flush();
+
+        childBreaks.clear();
+        viewportBlockArea = null;
+        curBlockArea = null;
+    }
+
+    public Area getParentArea(Area childArea) {
+        if (curBlockArea == null) {
+            viewportBlockArea = new BlockViewport();
+            if(abProps.absolutePosition == AbsolutePosition.ABSOLUTE) {
+                Rectangle2D rect = new Rectangle2D.Double(abProps.left,
+                                    abProps.top, abProps.right - abProps.left,
+                                    abProps.bottom - abProps.top);
+                viewportBlockArea.setBounds(rect);
+                viewportBlockArea.setCTM(absoluteCTM);
+                viewportBlockArea.setClip(clip);
+            } else {
+                double[] vals = absoluteCTM.toArray();
+                boolean rotated = vals[0] == 0.0;
+                if(rotated) {
+                    Rectangle2D rect = new Rectangle2D.Double(0, 0,
+                                    relDims.bpd, getRotatedIPD());
+                    viewportBlockArea.setBounds(rect);
+                    viewportBlockArea.setCTM(absoluteCTM);
+                    viewportBlockArea.setClip(clip);
+                } else if(vals[0] == -1.0) {
+                    // need to set bpd to actual size for rotation
+                    // and stacking
+                    Rectangle2D rect = new Rectangle2D.Double(0, 0,
+                                    relDims.ipd, relDims.bpd);
+                    viewportBlockArea.setBounds(rect);
+                    viewportBlockArea.setCTM(absoluteCTM);
+                    viewportBlockArea.setClip(clip);
+                }
+            }
+
+            curBlockArea = new Block();
+            viewportBlockArea.addBlock(curBlockArea);
+
+            if(abProps.absolutePosition == AbsolutePosition.ABSOLUTE) {
+                viewportBlockArea.setPositioning(Block.ABSOLUTE);
+            }
+
+            // Set up dimensions
+            // Must get dimensions from parent area
+            Area parentArea = parentLM.getParentArea(curBlockArea);
+            int referenceIPD = parentArea.getIPD();
+            curBlockArea.setIPD(referenceIPD);
+            // Get reference IPD from parentArea
+            setCurrentArea(viewportBlockArea); // ??? for generic operations
+        }
+        return curBlockArea;
+    }
+
+
+    public boolean addChild(Area childArea) {
+        if (curBlockArea != null) {
+            curBlockArea.addBlock((Block) childArea);
+            //return super.addChild(childArea);
+        }
+        return false;
+    }
+
+    public void resetPosition(Position resetPos) {
+        if (resetPos == null) {
+            reset(null);
+        }
+    }
+}
+
index a21eb13749090c533f39143add856724174a0479..72ea1c6c4f5d56181f839d446ef44861c408026c 100644 (file)
@@ -95,7 +95,8 @@ public abstract class AbstractRenderer extends AbstractLogEnabled implements Ren
             } else if (inline instanceof Word) {
                 str += ((Word) inline).getWord();
             } else if (inline instanceof InlineParent) {
-                str += convertToString(((InlineParent)inline).getChildAreas());
+                str += convertToString(
+                         ((InlineParent) inline).getChildAreas());
             } else {
                 str += " ";
             }
@@ -135,21 +136,21 @@ public abstract class AbstractRenderer extends AbstractLogEnabled implements Ren
     protected void renderRegionViewport(RegionViewport port) {
         if (port != null) {
             Rectangle2D view = port.getViewArea();
-        // The CTM will transform coordinates relative to
-        // this region-reference area into page coords, so
-        // set origin for the region to 0,0.
+            // The CTM will transform coordinates relative to
+            // this region-reference area into page coords, so
+            // set origin for the region to 0,0.
             currentBPPosition = 0; // (int) (view.getY() / 1000);
             currentIPPosition = 0; // (int) (view.getX() / 1000);
             currentBlockIPPosition = currentIPPosition;
 
             RegionReference region = port.getRegion();
-        startVParea(region.getCTM());
+            startVParea(region.getCTM());
             if (region.getRegionClass() == RegionReference.BODY) {
                 renderBodyRegion((BodyRegion) region);
             } else {
                 renderRegion(region);
             }
-        endVParea();
+            endVParea();
         }
     }
 
@@ -237,6 +238,32 @@ public abstract class AbstractRenderer extends AbstractLogEnabled implements Ren
         List children = block.getChildAreas();
         if (children == null) {
             // simply move position
+        } else if (block instanceof BlockViewport) {
+            renderBlockViewport((BlockViewport) block, children);
+        } else {
+            renderBlocks(children);
+        }
+    }
+
+    protected void renderBlockViewport(BlockViewport bv, List children) {
+        // clip and position viewport if necessary
+        if (bv.getPositioning() == Block.ABSOLUTE) {
+            // save positions
+            int saveIP = currentIPPosition;
+            int saveBP = currentBPPosition;
+
+            CTM ctm = bv.getCTM();
+            currentIPPosition = 0;
+            currentBPPosition = 0;
+
+            startVParea(ctm);
+            renderBlocks(children);
+            endVParea();
+
+            // clip if necessary
+
+            currentIPPosition = saveIP;
+            currentBPPosition = saveBP;
         } else {
             renderBlocks(children);
         }
@@ -314,7 +341,7 @@ public abstract class AbstractRenderer extends AbstractLogEnabled implements Ren
         int saveIP = currentBlockIPPosition;
         Iterator iter = ip.getChildAreas().iterator();
         while (iter.hasNext()) {
-            ((InlineArea)iter.next()).render(this);
+            ((InlineArea) iter.next()).render(this);
         }
         currentBlockIPPosition = saveIP + ip.getWidth();
     }
@@ -322,14 +349,14 @@ public abstract class AbstractRenderer extends AbstractLogEnabled implements Ren
     protected void renderBlocks(List blocks) {
         for (int count = 0; count < blocks.size(); count++) {
             Object obj = blocks.get(count);
-            if(obj instanceof Block) {
-                renderBlock((Block)obj);
+            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
-                                         + line.getStartIndent();
+                currentBlockIPPosition =
+                  currentIPPosition + line.getStartIndent();
                 renderLineArea(line);
                 currentBPPosition += line.getHeight();
             }
index 84ac9cb96ef5b237c387b7d9c2e603bed4124496..c28056958d30e33c64fb369a9272203d05d65aa5 100644 (file)
@@ -276,6 +276,113 @@ public class PDFRenderer extends PrintRenderer {
         super.renderRegion(region);
     }
 
+    protected void renderBlockViewport(BlockViewport bv, List children) {
+        // clip and position viewport if necessary
+
+        // save positions
+        int saveIP = currentIPPosition;
+        int saveBP = currentBPPosition;
+
+        CTM ctm = bv.getCTM();
+
+        closeText();
+
+        if (bv.getPositioning() == Block.ABSOLUTE) {
+
+            currentIPPosition = 0;
+            currentBPPosition = 0;
+
+            currentStream.add("ET\n");
+
+            if(bv.getClip()) {
+                Rectangle2D rect = bv.getBounds();
+
+                currentStream.add("q\n");
+                float x = (float)rect.getX() / 1000f;
+                float y = (float)rect.getY() / 1000f;
+                float width = (float)rect.getWidth() / 1000f;
+                float height = (float)rect.getHeight() / 1000f;
+                clip(x, y, width, height);
+            }
+
+            startVParea(ctm);
+            renderBlocks(children);
+            endVParea();
+
+            if (bv.getClip()) {
+                currentStream.add("Q\n");
+            }
+            currentStream.add("BT\n");
+
+            // clip if necessary
+
+            currentIPPosition = saveIP;
+            currentBPPosition = saveBP;
+        } else {
+
+            Rectangle2D rect = bv.getBounds();
+
+            if(ctm != null) {
+                currentIPPosition = 0;
+                currentBPPosition = 0;
+
+                currentStream.add("ET\n");
+
+                double[] vals = ctm.toArray();
+                boolean aclock = vals[2] == 1.0;
+                if(vals[2] == 1.0) {
+                    ctm = ctm.translate(-saveBP - rect.getHeight(), -saveIP);
+                } else if(vals[0] == -1.0) {
+                    ctm = ctm.translate(-saveIP - rect.getWidth(), -saveBP - rect.getHeight());
+                } else {
+                    ctm = ctm.translate(saveBP, saveIP - rect.getWidth());
+                }
+            }
+
+            if(bv.getClip()) {
+                currentStream.add("q\n"); 
+                float x = (float)rect.getX() / 1000f;
+                float y = (float)rect.getY() / 1000f;
+                float width = (float)rect.getWidth() / 1000f;
+                float height = (float)rect.getHeight() / 1000f;
+                clip(x, y, width, height);
+            }
+
+            if(ctm != null) {
+                startVParea(ctm);
+            }
+            renderBlocks(children);
+            if(ctm != null) {
+                endVParea();
+            }
+        
+            if (bv.getClip()) {
+                currentStream.add("Q\n");
+            }
+            if(ctm != null) {
+                currentStream.add("BT\n");
+            }
+
+            // clip if necessary
+
+            if(rect != null) {
+                currentIPPosition = saveIP;
+                currentBPPosition = saveBP;
+                currentBPPosition += (int)(rect.getHeight());
+            }
+        }
+    }
+
+    protected void clip(float x, float y, float width, float height) {
+        currentStream.add(x + " " + y + " m\n");
+        currentStream.add((x + width) + " " + y + " l\n");
+        currentStream.add((x + width) + " " + (y + height) + " l\n");
+        currentStream.add(x + " " + (y + height) + " l\n");
+        currentStream.add("h\n");
+        currentStream.add("W\n");
+        currentStream.add("n\n");
+    }
+
     protected void renderLineArea(LineArea line) {
         super.renderLineArea(line);
         closeText();
@@ -609,13 +716,7 @@ public class PDFRenderer extends PrintRenderer {
             float y = (currentBPPosition + viewport.getOffset()) / 1000f;
             float width = viewport.getWidth() / 1000f;
             float height = viewport.getHeight() / 1000f;
-            currentStream.add(x + " " + y + " m\n");
-            currentStream.add((x + width) + " " + y + " l\n");
-            currentStream.add((x + width) + " " + (y + height) + " l\n");
-            currentStream.add(x + " " + (y + height) + " l\n");
-            currentStream.add("h\n");
-            currentStream.add("W\n");
-            currentStream.add("n\n");
+            clip(x, y, width, height);
         }
         super.renderViewport(viewport);