<property>
<name>reference-orientation</name>
<inherited>true</inherited>
- <datatype>ToBeImplemented</datatype>
+ <datatype>Number</datatype>
<default>0</default>
</property>
<property>
<property>
<name>column-count</name>
<inherited>false</inherited>
- <datatype>String</datatype>
+ <datatype>Number</datatype>
<default>1</default>
</property>
<property>
BeforeFloat beforeFloat;
MainReference mainReference;
Footnote footnote;
+ private int columnGap;
+ private int columnCount;
/** Maximum block progression dimension. Note: min=opt=max */
private MinOptMax maxBPD;
super(BODY);
}
+ // Number of columns when not spanning
+ public void setColumnCount(int colCount) {
+ this.columnCount = colCount;
+ }
+
+ // A length (mpoints)
+ public void setColumnGap(int colGap) {
+ this.columnGap = colGap;
+ }
+
public void setParent(Area area) {
super.setParent(area);
// Only if not scrolling or overflow !!!
--- /dev/null
+/*
+ * $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;
+import java.awt.Rectangle;
+import java.io.Serializable;
+
+import org.apache.fop.fo.properties.WritingMode;
+
+/**
+ * Describe a PDF or PostScript style coordinate transformation matrix (CTM).
+ * The matrix encodes translations, scaling and rotations of the coordinate
+ * system used to render pages.
+ */
+
+public class CTM implements Serializable {
+ private double a,b,c,d,e,f;
+
+ private static CTM s_CTM_lrtb = new CTM(1,0,0,-1,0,0);
+ private static CTM s_CTM_rltb = new CTM(-1,0,0,-1,0,0);
+ private static CTM s_CTM_tbrl = new CTM(0,-1,-1,0,0,0);
+/**
+ * Create the identity matrix
+ */
+ public CTM() {
+ a=1;
+ b=0;
+ c=0;
+ d=1;
+ e=0;
+ f=0;
+ }
+
+ /**
+ * Initialize a CTM from the passed arguments.
+ */
+ public CTM(double a, double b, double c, double d, double e, double f) {
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.d = d;
+ this.e = e;
+ this.f = f;
+ }
+
+ /**
+ * Initialize a CTM to the identity matrix with a translation
+ * specified by x and y.
+ */
+ public CTM(double x, double y) {
+ this.a = 1;
+ this.b = 0;
+ this.c = 0;
+ this.d = 1;
+ this.e = x;
+ this.f = y;
+ }
+
+ /**
+ * Return a CTM which will transform coordinates for a particular writing-mode
+ * into normalized first quandrant coordinates.
+ * @param wm A writing mode constant from fo.properties.WritingMode, ie.
+ * one of LR_TB, RL_TB, TB_RL.
+ * @param ipd The inline-progression dimension of the reference area whose
+ * CTM is being set..
+ * @param bpd The block-progression dimension of the reference area whose
+ * CTM is being set.
+ */
+ static public CTM getWMctm(int wm, int ipd, int bpd) {
+ switch (wm) {
+ case WritingMode.LR_TB:
+ return s_CTM_lrtb.translate(0,bpd);
+ case WritingMode.RL_TB:
+ return s_CTM_rltb.translate(ipd, bpd);
+ case WritingMode.TB_RL: // CJK
+ return s_CTM_tbrl.translate(bpd, ipd);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Multiply new passed CTM with this one and generate a new result CTM.
+ * @param premult The CTM to multiply with this one. The new one will be
+ * the first multiplicand.
+ * @return CTM The result of multiplying premult * this.
+ */
+ public CTM multiply(CTM premult) {
+ CTM rslt= new CTM (
+ (premult.a * a) + (premult.b * c),
+ (premult.a * b) + (premult.b * d),
+ (premult.c * a) + (premult.d * c),
+ (premult.c * b) + (premult.d * d),
+ (premult.e * a) + (premult.f * c) + e,
+ (premult.e * b) + (premult.f * d) + f
+ );
+ return rslt;
+ }
+
+ /**
+ * Rotate this CTM by "angle" radians and return a new result CTM.
+ * This is used to account for reference-orientation.
+ * @param angle The angle in radians. Positive angles are measured counter-
+ * clockwise.
+ * @return CTM The result of rotating this CTM.
+ */
+ public CTM rotate(double angle) {
+ double rad = Math.toRadians(angle);
+ double cos = Math.cos(rad);
+ double sin = Math.sin(rad);
+ CTM rotate= new CTM(cos, sin, -sin, cos, 0, 0);
+ return multiply(rotate);
+ }
+
+ /**
+ * Translate this CTM by the passed x and y values and return a new result CTM.
+ * @param x The amount to translate along the x axis.
+ * @param y The amount to translate along the y axis.
+ * @return CTM The result of translating this CTM.
+ */
+ public CTM translate(double x, double y) {
+ CTM translate= new CTM(1,0,0,1,x,y);
+ return multiply(translate);
+ }
+
+ /**
+ * Scale this CTM by the passed x and y values and return a new result CTM.
+ * @param x The amount to scale along the x axis.
+ * @param y The amount to scale along the y axis.
+ * @return CTM The result of scaling this CTM.
+ */
+ public CTM scale(double x, double y) {
+ CTM scale= new CTM(x,0,0,y,0,0);
+ return multiply(scale);
+ }
+
+ /**
+ * Transform a rectangle by the CTM to produce a rectangle in the transformed
+ * coordinate system.
+ * @param inRect The rectangle in the original coordinate system
+ * @return Rectangle2D The rectangle in the transformed coordinate system.
+ */
+ public Rectangle2D transform(Rectangle2D inRect) {
+ // Store as 2 sets of 2 points and transform those, then
+ // recalculate the width and height
+ int x1t = (int)(inRect.getX()*a + inRect.getY()*c + e);
+ int y1t = (int)(inRect.getX()*b + inRect.getY()*d + f);
+ int x2t = (int)((inRect.getX()+inRect.getWidth())*a +
+ (inRect.getY()+inRect.getHeight())*c + e);
+ int y2t = (int)((inRect.getX()+inRect.getWidth())*b +
+ (inRect.getY()+inRect.getHeight())*d + f);
+ // Normalize with x1 < x2
+ if (x1t > x2t) {
+ int tmp = x2t;
+ x2t = x1t;
+ x1t = tmp;
+ }
+ if (y1t > y2t) {
+ int tmp = y2t;
+ y2t = y1t;
+ y1t = tmp;
+ }
+ return new Rectangle(x1t, y1t, x2t-x1t, y2t-y1t);
+ }
+}
public static final int END = 3;
public static final int AFTER = 4;
int regionClass = BEFORE;
+ private CTM ctm;
public RegionReference(int type) {
regionClass = type;
}
+ /**
+ * Set the Coordinate Transformation Matrix which transforms content
+ * coordinates in this region reference area which are specified in
+ * terms of "start" and "before" into coordinates in a system which
+ * is positioned in "absolute" directions (with origin at lower left of
+ * the region reference area.
+ */
+ public void setCTM(CTM ctm) {
+ this.ctm = ctm;
+ }
+
// the list of block areas from the static flow
ArrayList blocks = new ArrayList();
--- /dev/null
+/*
+ * $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.datatypes;
+
+
+/**
+ * This datatype hold a pair of resolved lengths,
+ * specifiying the dimensions in
+ * both inline and block-progression-directions.
+ */
+public class FODimension {
+
+ public int ipd;
+ public int bpd;
+
+
+ public FODimension(int ipd, int bpd) {
+ this.ipd = ipd;
+ this.bpd = bpd;
+ }
+}
package org.apache.fop.fo;
+
+import java.awt.geom.Rectangle2D;
+import org.apache.fop.area.CTM;
+import org.apache.fop.datatypes.FODimension;
import org.apache.fop.layout.FontState;
import org.apache.fop.layout.FontInfo;
import org.apache.fop.layout.BorderAndPadding;
import org.apache.fop.fo.properties.BreakAfter;
import org.apache.fop.fo.properties.BreakBefore;
import org.apache.fop.fo.properties.Constants;
+import org.apache.fop.fo.properties.WritingMode;
import org.apache.fop.layout.HyphenationProps;
import org.apache.fop.apps.FOPException;
import java.text.MessageFormat;
}
}
+
public MarginProps getMarginProps() {
MarginProps props = new MarginProps();
this.properties.get("margin-left").getLength().mvalue();
props.marginRight =
this.properties.get("margin-right").getLength().mvalue();
- /*
- * // need to get opt, min and max
- * props.spaceBefore = this.properties.get("space-before").getLength().mvalue();
- * props.spaceAfter = this.properties.get("space-after").getLength().mvalue();
- * props.startIndent = this.properties.get("start-indent").getLength().mvalue();
- * props.endIndent = this.properties.get("end-indent").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();
+
return props;
}
AbsolutePositionProps props = new AbsolutePositionProps();
return props;
}
+
+ 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());
+ if (absRefOrient % 180 == 0) {
+ 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();
+ }
+ /* 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());
+ // 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(height, 0); // height = absVPrect.width
+ break;
+ case 180:
+ ctm = ctm.translate(width, height);
+ break;
+ case 270:
+ ctm = ctm.translate(0, width); // width = absVPrect.height
+ 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
+ * can set ipd and bpd appropriately based on the writing mode.
+ */
+
+ if (wm == WritingMode.LR_TB || wm == WritingMode.RL_TB) {
+ reldims.ipd = width;
+ reldims.bpd = height;
+ }
+ else {
+ reldims.ipd=height;
+ reldims.bpd=width;
+ }
+ // 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));
+ }
+
+ /**
+ * Calculate absolute reference-orientation relative to media orientation.
+ */
+ private int getAbsRefOrient(int myRefOrient) {
+ return myRefOrient;
+ }
}
package org.apache.fop.fo.pagination;
import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
// FOP
+
+import org.apache.fop.datatypes.FODimension;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.layout.BorderAndPadding;
import org.apache.fop.layout.BackgroundProps;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.area.CTM;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.RegionReference;
/**
* Creates a RegionViewport Area object for this pagination Region.
*/
- public RegionViewport makeRegionViewport(Rectangle pageRefRect) {
- return new RegionViewport(getViewportRectangle(pageRefRect));
+ public RegionViewport makeRegionViewport(FODimension reldims, CTM pageCTM) {
+ Rectangle2D relRegionRect = getViewportRectangle(reldims);
+ Rectangle2D absRegionRect = pageCTM.transform(relRegionRect);
+ // Get the region viewport rectangle in absolute coords by
+ // transforming it using the page CTM
+ return new RegionViewport(absRegionRect);
}
- abstract protected Rectangle getViewportRectangle(Rectangle pageRefRect);
-
+ abstract protected Rectangle getViewportRectangle(FODimension pageRefRect);
- public RegionReference makeRegionReferenceArea() {
+ /**
+ * Create the region reference area for this region master.
+ * @param absRegVPRect The region viewport rectangle is "absolute" coordinates
+ * where x=distance from left, y=distance from bottom, width=right-left
+ * height=top-bottom
+ */
+ public RegionReference makeRegionReferenceArea(Rectangle2D absRegVPRect) {
RegionReference r = new RegionReference(getRegionAreaClass());
- setRegionTraits(r);
+ setRegionTraits(r, absRegVPRect);
return r;
}
- protected void setRegionTraits(RegionReference r) {
+ protected void setRegionTraits(RegionReference r, Rectangle2D absRegVPRect) {
// Common Border, Padding, and Background Properties
BorderAndPadding bap = propMgr.getBorderAndPadding();
BackgroundProps bProps = propMgr.getBackgroundProps();
// this.properties.get("clip");
// this.properties.get("display-align");
this.overflow = this.properties.get("overflow").getEnum();
- // this.properties.get("reference-orientation");
- // this.properties.get("writing-mode");
-
+ FODimension reldims = new FODimension(0,0);
+ r.setCTM(propMgr.getCTMandRelDims(absRegVPRect, reldims));
+
//r.setBackground(bProps);
}
// FOP
import org.apache.fop.fo.*;
+import org.apache.fop.datatypes.FODimension;
import org.apache.fop.apps.FOPException;
import org.apache.fop.area.RegionReference;
}
- protected Rectangle getViewportRectangle (Rectangle pageRefRect) {
+ protected Rectangle getViewportRectangle (FODimension reldims) {
// Depends on extent and precedence
Rectangle vpRect =
- new Rectangle((int)pageRefRect.getX(),
- (int)pageRefRect.getY() - (int)pageRefRect.getHeight() +
- getExtent(),
- (int)pageRefRect.getWidth(), getExtent());
+ new Rectangle(0, reldims.bpd - getExtent(),
+ reldims.ipd, getExtent());
if (getPrecedence() == false) {
adjustIPD(vpRect);
}
package org.apache.fop.fo.pagination;
// FOP
+
+import org.apache.fop.datatypes.FODimension;
import org.apache.fop.fo.*;
import org.apache.fop.apps.FOPException;
import org.apache.fop.area.RegionReference;
}
- protected Rectangle getViewportRectangle (Rectangle pageRefRect) {
+ protected Rectangle getViewportRectangle (FODimension reldims) {
// Depends on extent and precedence
- Rectangle vpRect = new Rectangle(pageRefRect);
- vpRect.height = getExtent();
+ // This should return rectangle in writing-mode coordinates relative
+ // to the page-reference area rectangle
+ // This means the origin is (start, before) and the dimensions are (ipd,bpd)
+ // Before is always 0, start depends on extent
+ // ipd depends on precedence, bpd=extent
+ Rectangle vpRect = new Rectangle(0, 0, reldims.ipd, getExtent());
if (getPrecedence() == false) {
adjustIPD(vpRect);
}
package org.apache.fop.fo.pagination;
import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
// FOP
+
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.properties.Overflow;
import org.apache.fop.datatypes.ColorType;
+import org.apache.fop.datatypes.FODimension;
import org.apache.fop.apps.FOPException;
import org.apache.fop.area.RegionReference;
import org.apache.fop.area.BodyRegion;
super(parent);
}
- protected Rectangle getViewportRectangle (Rectangle pageRefRect)
+ protected Rectangle getViewportRectangle (FODimension reldims)
{
// Common Margin Properties-Block
+ // Need these in writing-mode relative coordinates
+ // Or shall we get absolute and transform to relative using writing mode?
MarginProps mProps = propMgr.getMarginProps();
- return
- new Rectangle((int)pageRefRect.getX() + mProps.marginLeft,
- (int)pageRefRect.getY() - mProps.marginTop,
- (int)pageRefRect.getWidth() - mProps.marginLeft -
- mProps.marginRight,
- (int)pageRefRect.getHeight() - mProps.marginTop -
- mProps.marginBottom);
+ return new Rectangle( mProps.startIndent, mProps.spaceBefore,
+ reldims.ipd - mProps.startIndent - mProps.endIndent,
+ reldims.bpd - mProps.spaceBefore - mProps.spaceAfter);
}
- protected void setRegionTraits(RegionReference r) {
- super.setRegionTraits(r);
-
- String columnCountAsString =
- this.properties.get("column-count").getString();
- int columnCount = 1;
- try {
- columnCount = Integer.parseInt(columnCountAsString);
- } catch (NumberFormatException nfe) {
- log.error("Bad value on region body 'column-count'");
- columnCount = 1;
- }
- if ((columnCount > 1) && (overflow == Overflow.SCROLL)) {
- // recover by setting 'column-count' to 1. This is allowed but
- // not required by the spec.
- log.error("Setting 'column-count' to 1 because "
- + "'overflow' is set to 'scroll'");
- columnCount = 1;
- }
-// r.setColumnCount(columnCount);
-
-// int columnGap =
-// this.properties.get("column-gap").getLength().mvalue();
-// r.setColumnGap(columnGap);
+ protected void setRegionTraits(RegionReference r, Rectangle2D absRegVPRect) {
+ super.setRegionTraits(r, absRegVPRect);
// r.setBackgroundColor(backgroundColor);
}
/**
* Override the inherited method.
*/
- public RegionReference makeRegionReferenceArea() {
+ public RegionReference makeRegionReferenceArea(Rectangle2D absRegVPRect) {
// Should set some column stuff here I think, or put it elsewhere
- return new BodyRegion();
+ BodyRegion body = new BodyRegion();
+ int columnCount=
+ this.properties.get("column-count").getNumber().intValue();
+ if ((columnCount > 1) && (overflow == Overflow.SCROLL)) {
+ // recover by setting 'column-count' to 1. This is allowed but
+ // not required by the spec.
+ log.error("Setting 'column-count' to 1 because "
+ + "'overflow' is set to 'scroll'");
+ columnCount = 1;
+ }
+ body.setColumnCount(columnCount);
+
+ int columnGap =
+ this.properties.get("column-gap").getLength().mvalue();
+ body.setColumnGap(columnGap);
+ return body;
}
}
// FOP
import org.apache.fop.fo.*;
+import org.apache.fop.datatypes.FODimension;
import org.apache.fop.apps.FOPException;
import org.apache.fop.area.RegionReference;
}
- protected Rectangle getViewportRectangle (Rectangle pageRefRect) {
+ protected Rectangle getViewportRectangle (FODimension reldims) {
// Depends on extent and precedence
Rectangle vpRect =
- new Rectangle((int)pageRefRect.getX() + (int)pageRefRect.getWidth() -
- getExtent(),
- (int)pageRefRect.getY(),
- getExtent(), (int)pageRefRect.getHeight());
+ new Rectangle(reldims.ipd - getExtent(), 0,
+ getExtent(), reldims.bpd);
adjustIPD(vpRect);
return vpRect;
}
-
protected String getDefaultRegionName() {
return "xsl-region-end";
}
// FOP
import org.apache.fop.fo.*;
+import org.apache.fop.datatypes.FODimension;
import org.apache.fop.apps.FOPException;
import org.apache.fop.area.RegionReference;
}
- protected Rectangle getViewportRectangle (Rectangle pageRefRect) {
+ protected Rectangle getViewportRectangle (FODimension reldims) {
// Depends on extent and precedence
+ // This is the rectangle relative to the page-reference area in
+ // writing-mode relative coordinates
Rectangle vpRect =
- new Rectangle((int)pageRefRect.getX(),
- (int)pageRefRect.getY(),
- getExtent(), (int)pageRefRect.getHeight());
+ new Rectangle(0, 0, getExtent(), reldims.bpd);
adjustIPD(vpRect);
return vpRect;
}
// FOP
import org.apache.fop.fo.*;
import org.apache.fop.fo.properties.*;
+import org.apache.fop.area.CTM;
+import org.apache.fop.datatypes.FODimension;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.Page;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.apps.FOPException;
import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Iterator;
import org.xml.sax.Attributes;
// this.properties.get("reference-orientation");
// this.properties.get("writing-mode");
- // Common Margin Properties-Block
+ // Get absolute margin properties (top, left, bottom, right)
MarginProps mProps = propMgr.getMarginProps();
/* Create the page reference area rectangle in first quadrant coordinates
* The media rectangle itself is (0,0,pageWidth,pageHeight).
*/
Rectangle pageRefRect =
- new Rectangle(mProps.marginLeft, pageHeight - mProps.marginTop,
+ new Rectangle(mProps.marginLeft, mProps.marginBottom,
pageWidth - mProps.marginLeft - mProps.marginRight,
pageHeight - mProps.marginTop - mProps.marginBottom);
// ??? KL shouldn't this take the viewport too???
Page page = new Page(); // page reference area
+ // Set up the CTM on the page reference area based on writing-mode
+ // and reference-orientation
+ FODimension reldims=new FODimension(0,0);
+ CTM pageCTM = propMgr.getCTMandRelDims(pageRefRect, reldims);
+
// Create a RegionViewport/ reference area pair for each page region
boolean bHasBody=false;
for (Iterator regenum = _regions.values().iterator();
regenum.hasNext(); ) {
Region r = (Region)regenum.next();
- RegionViewport rvp = r.makeRegionViewport(pageRefRect);
- rvp.setRegion(r.makeRegionReferenceArea());
+ RegionViewport rvp = r.makeRegionViewport(reldims, pageCTM);
+ rvp.setRegion(r.makeRegionReferenceArea(rvp.getViewArea()));
page.setRegion(r.getRegionAreaClass(), rvp);
if (r.getRegionAreaClass() == RegionReference.BODY) {
bHasBody = true;