|
|
@@ -18,23 +18,30 @@ |
|
|
|
*/ |
|
|
|
package org.apache.fop.area; |
|
|
|
|
|
|
|
import java.awt.geom.Rectangle2D; |
|
|
|
|
|
|
|
import org.apache.fop.datastructs.Node; |
|
|
|
import org.apache.fop.datastructs.SyncedNode; |
|
|
|
import org.apache.fop.fo.FONode; |
|
|
|
import org.apache.fop.fo.expr.PropertyException; |
|
|
|
import org.apache.fop.fo.flow.FoPageSequence; |
|
|
|
import org.apache.fop.fo.properties.WritingMode; |
|
|
|
|
|
|
|
/** |
|
|
|
* The base class for all areas. <code>Area</code> extends <code>Node</code> |
|
|
|
* because all areas will find themselves in a tree of some kind. |
|
|
|
* The base class for all gemetrical areas. <code>Area</code> extends |
|
|
|
* <code>AreaNode</code> because all areas will find themselves in a tree of |
|
|
|
* some kind. It represents its geometry with a |
|
|
|
* <code>Rectangle2D.Double</code>, whose dimensions are expressed in Java |
|
|
|
* and XSL points, i.e. 1/72 of an inch, which facilitates conversions to |
|
|
|
* integral millipoints. It also allows the use of Java facilities like |
|
|
|
* <code>java.awt.GraphicsConfiguration.getNormalizingTransform()</code> |
|
|
|
* which, "Returns a AffineTransform that can be concatenated with the default |
|
|
|
* AffineTransform of a GraphicsConfiguration so that 72 units in user space |
|
|
|
* equals 1 inch in device space." |
|
|
|
* @author pbw |
|
|
|
* @version $Revision$ $Name$ |
|
|
|
*/ |
|
|
|
public class Area extends SyncedNode implements Cloneable { |
|
|
|
public class Area extends AreaNode implements Cloneable { |
|
|
|
|
|
|
|
/** The page-sequence which generated this area. */ |
|
|
|
protected FoPageSequence pageSeq = null; |
|
|
|
/** The FO node that generated this node. */ |
|
|
|
protected FONode generatedBy = null; |
|
|
|
/** Current inline progression dimension. May be unknown. */ |
|
|
|
protected Integer iPDim = null; |
|
|
|
/** Maximum required inline progression dimension. May be unknown. */ |
|
|
@@ -47,7 +54,28 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
protected Integer bPDimMax = null; |
|
|
|
/** Mimimum required block progression dimension. May be unknown. */ |
|
|
|
protected Integer bPDimMin = null; |
|
|
|
|
|
|
|
/** The geometrical area. The <code>width</code> of this |
|
|
|
* <code>Rectangle</code> is the <code>inline-progression-dimension</code> |
|
|
|
* of the area, and the <code>height</code> is the |
|
|
|
* <code>bllock-progression-dimension</code>. */ |
|
|
|
protected Rectangle2D area = null; |
|
|
|
/** True if the the <code>writing-mode</code> of the content area is |
|
|
|
* horizontal */ |
|
|
|
protected boolean contentIsHorizontal = true; |
|
|
|
/** True if the the <code>writing-mode</code> of the content area is |
|
|
|
* left-to-right */ |
|
|
|
protected boolean contentLeftToRight = true; |
|
|
|
|
|
|
|
private void setup() { |
|
|
|
try { |
|
|
|
contentIsHorizontal = |
|
|
|
WritingMode.isHorizontal(generatedBy.getWritingMode()); |
|
|
|
contentLeftToRight = |
|
|
|
WritingMode.isLeftToRight(generatedBy.getWritingMode()); |
|
|
|
} catch (PropertyException e) { |
|
|
|
throw new RuntimeException(e.getMessage()); |
|
|
|
} |
|
|
|
} |
|
|
|
/** |
|
|
|
* @param pageSeq through which this area was generated |
|
|
|
* @param generatedBy the given <code>FONode</code> generated this |
|
|
@@ -63,9 +91,8 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
int index, |
|
|
|
Object sync) |
|
|
|
throws IndexOutOfBoundsException { |
|
|
|
super(parent, index, sync); |
|
|
|
this.pageSeq = pageSeq; |
|
|
|
this.generatedBy = generatedBy; |
|
|
|
super(pageSeq, generatedBy, parent, index, sync); |
|
|
|
setup(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -80,9 +107,8 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
FONode generatedBy, |
|
|
|
Node parent, |
|
|
|
Object sync) { |
|
|
|
super(parent, sync); |
|
|
|
this.pageSeq = pageSeq; |
|
|
|
this.generatedBy = generatedBy; |
|
|
|
super(pageSeq, generatedBy, parent, sync); |
|
|
|
setup(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -94,47 +120,85 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
public Area( |
|
|
|
FoPageSequence pageSeq, |
|
|
|
FONode generatedBy) { |
|
|
|
super(); |
|
|
|
this.pageSeq = pageSeq; |
|
|
|
this.generatedBy = generatedBy; |
|
|
|
super(pageSeq, generatedBy); |
|
|
|
setup(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @return the generatedBy |
|
|
|
* Gets the <code>block-progression-dimension</code> of the contents of |
|
|
|
* this area in millipoints. This value is taken from the appropriate |
|
|
|
* dimension of the <code>Rectangle2D</code> representing this area. If no |
|
|
|
* <code>Rectangle2D</code> exists, a zero-dimensioned default is first |
|
|
|
* created, then the zero value is returned. |
|
|
|
* @return the <code>block-progression-dimension</code> in millipoints |
|
|
|
*/ |
|
|
|
public FONode getGeneratedBy() { |
|
|
|
synchronized (sync) { |
|
|
|
return generatedBy; |
|
|
|
} |
|
|
|
public int getBPDim() { |
|
|
|
return (int)(getBPDimPts()*1000); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param generatedBy to set |
|
|
|
* Gets the <code>block-progression-dimension</code> of the contents of |
|
|
|
* this area in points. This value is taken from the appropriate dimension |
|
|
|
* of the <code>Rectangle2D</code> representing this area. If no |
|
|
|
* <code>Rectangle2D</code> exists, a zero-dimensioned default is first |
|
|
|
* created, then the zero value is returned. |
|
|
|
* @return the <code>block-progression-dimension</code> in points |
|
|
|
*/ |
|
|
|
public void setGeneratedBy(FONode generatedBy) { |
|
|
|
public double getBPDimPts() { |
|
|
|
synchronized (sync) { |
|
|
|
this.generatedBy = generatedBy; |
|
|
|
if (area == null) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if (contentIsHorizontal) { |
|
|
|
return area.getHeight(); |
|
|
|
} else { |
|
|
|
return area.getWidth(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @return the bPDim |
|
|
|
* Sets the <code>block-progression-dimension</code> of the contents of |
|
|
|
* this area to the specified value in millipoints. |
|
|
|
* This value is applied to the appropriate dimension of the |
|
|
|
* <code>Rectangle2D</code> representing this area. If no |
|
|
|
* <code>Rectangle2D</code> exists, a zero-dimensioned default is first |
|
|
|
* created, then the value is applied. |
|
|
|
* @param millipts <code>block-progression-dimension</code> to set, in |
|
|
|
* millipoints |
|
|
|
*/ |
|
|
|
public Integer getBPDim() { |
|
|
|
synchronized (sync) { |
|
|
|
return bPDim; |
|
|
|
} |
|
|
|
public void setBPDim(int millipts) { |
|
|
|
setBPDimPts(millipts/1000.0f); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param dim to set |
|
|
|
* Sets the <code>block-progression-dimension</code> of the contents of |
|
|
|
* this area to the specified value in points. |
|
|
|
* This value is applied to the appropriate dimension of the |
|
|
|
* <code>Rectangle2D</code> representing this area. If no |
|
|
|
* <code>Rectangle2D</code> exists, a zero-dimensioned default is first |
|
|
|
* created, then the value is applied. |
|
|
|
* @param pts <code>block-progression-dimension</code> to set, in points |
|
|
|
*/ |
|
|
|
public void setBPDim(Integer dim) { |
|
|
|
public void setBPDimPts(double pts) { |
|
|
|
synchronized (sync) { |
|
|
|
bPDim = dim; |
|
|
|
if (area == null) { |
|
|
|
area = new Rectangle2D.Double(); |
|
|
|
} |
|
|
|
if (contentIsHorizontal) { |
|
|
|
area.setRect( |
|
|
|
area.getX(),area.getY(), area.getWidth(), pts); |
|
|
|
} else { |
|
|
|
area.setRect( |
|
|
|
area.getX(),area.getY(), pts, area.getHeight()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @return the bPDimMax |
|
|
|
* Gets the <code>block-progression-dimension</code> maximum value, |
|
|
|
* in millipoints |
|
|
|
* @return the <code>block-progression-dimension</code> maximum value |
|
|
|
*/ |
|
|
|
public Integer getBPDimMax() { |
|
|
|
synchronized (sync) { |
|
|
@@ -143,7 +207,10 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param dimMax to set |
|
|
|
* Sets the <code>block-progression-dimension</code> maximum value, |
|
|
|
* in millipoints |
|
|
|
* @param dimMax <code>block-progression-dimension</code> maximum value |
|
|
|
* to set |
|
|
|
*/ |
|
|
|
public void setBPDimMax(Integer dimMax) { |
|
|
|
synchronized (sync) { |
|
|
@@ -152,7 +219,9 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @return the bPDimMin |
|
|
|
* Gets the <code>block-progression-dimension</code> minimum value, |
|
|
|
* in millipoints |
|
|
|
* @return the <code>block-progression-dimension</code> minimum value |
|
|
|
*/ |
|
|
|
public Integer getBPDimMin() { |
|
|
|
synchronized (sync) { |
|
|
@@ -161,7 +230,10 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param dimMin to set |
|
|
|
* Sets the <code>block-progression-dimension</code> minimum value, |
|
|
|
* in millipoints |
|
|
|
* @param dimMin <code>block-progression-dimension</code> minimum value |
|
|
|
* to set |
|
|
|
*/ |
|
|
|
public void setBPDimMin(Integer dimMin) { |
|
|
|
synchronized (sync) { |
|
|
@@ -170,25 +242,76 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @return the iPDim |
|
|
|
* Gets the <code>inline-progression-dimension</code> of the contents of |
|
|
|
* this area in millipoints. This value is taken from the appropriate |
|
|
|
* dimension of the <code>Rectangle2D</code> representing this area. If no |
|
|
|
* <code>Rectangle2D</code> exists, a zero-dimensioned default is first |
|
|
|
* created, then the zero value is returned. |
|
|
|
* @return the <code>inline-progression-dimension</code> in millipoints |
|
|
|
*/ |
|
|
|
public int getIPDim() { |
|
|
|
return (int)(getIPDimPts()*1000); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Gets the <code>inline-progression-dimension</code> of the contents of |
|
|
|
* this area in points. This value is taken from the appropriate dimension |
|
|
|
* of the <code>Rectangle2D</code> representing this area. If no |
|
|
|
* <code>Rectangle2D</code> exists, a zero-dimensioned default is first |
|
|
|
* created, then the zero value is returned. |
|
|
|
* @return the <code>inline-progression-dimension</code> in points |
|
|
|
*/ |
|
|
|
public Integer getIPDim() { |
|
|
|
public double getIPDimPts() { |
|
|
|
synchronized (sync) { |
|
|
|
return iPDim; |
|
|
|
if (area == null) { |
|
|
|
area = new Rectangle2D.Double(); |
|
|
|
} |
|
|
|
if (contentIsHorizontal){ |
|
|
|
return area.getWidth(); |
|
|
|
} else { |
|
|
|
return area.getHeight(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param dim to set |
|
|
|
* Sets the <code>inline-progression-dimension</code> of the contents of |
|
|
|
* this area, in millipoints. This value is applied to the appropriate |
|
|
|
* dimension of the <code>Rectangle2D</code> representing this area. If no |
|
|
|
* <code>Rectangle2D</code> exists, a zero-dimensioned default is first |
|
|
|
* created, then the value is applied. |
|
|
|
* @param millipts <code>inline-progression-dimension</code> to set, in |
|
|
|
* millipoints |
|
|
|
*/ |
|
|
|
public void setIPDim(int millipts) { |
|
|
|
setIPDimPts(millipts/1000.0f); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Sets the <code>inline-progression-dimension</code> of the contents of |
|
|
|
* this area, in points. This value is applied to the appropriate |
|
|
|
* dimension of the <code>Rectangle2D</code> representing this area. If no |
|
|
|
* <code>Rectangle2D</code> exists, a zero-dimensioned default is first |
|
|
|
* created, then the value is applied. |
|
|
|
* @param pts <code>inline-progression-dimension</code> to set, in points |
|
|
|
*/ |
|
|
|
public void setIPDim(Integer dim) { |
|
|
|
public void setIPDimPts(double pts) { |
|
|
|
synchronized (sync) { |
|
|
|
iPDim = dim; |
|
|
|
if (area == null) { |
|
|
|
area = new Rectangle2D.Double(); |
|
|
|
} |
|
|
|
if (contentIsHorizontal){ |
|
|
|
area.setRect(area.getX(), area.getY(), pts, area.getHeight()); |
|
|
|
} else { |
|
|
|
area.setRect(area.getX(), area.getY(), area.getWidth(), pts); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @return the iPDimMax |
|
|
|
* Gets the <code>inline-progression-dimension</code> maximum value, |
|
|
|
* in millipoints |
|
|
|
* @return the <code>inline-progression-dimension</code> maximum value |
|
|
|
*/ |
|
|
|
public Integer getIPDimMax() { |
|
|
|
synchronized(sync) { |
|
|
@@ -197,7 +320,10 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param dimMax to set |
|
|
|
* Sets the <code>inline-progression-dimension</code> maximum value, |
|
|
|
* in millipoints |
|
|
|
* @param dimMax <code>inline-progression-dimension</code> maximum value |
|
|
|
* to set |
|
|
|
*/ |
|
|
|
public void setIPDimMax(Integer dimMax) { |
|
|
|
synchronized (sync) { |
|
|
@@ -206,7 +332,9 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @return the iPDimMin |
|
|
|
* Gets the <code>inline-progression-dimension</code> mimimum value, |
|
|
|
* in millipoints |
|
|
|
* @return the <code>inline-progression-dimension</code> minimum value |
|
|
|
*/ |
|
|
|
public Integer getIPDimMin() { |
|
|
|
synchronized (sync) { |
|
|
@@ -215,7 +343,10 @@ public class Area extends SyncedNode implements Cloneable { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param dimMin to set |
|
|
|
* Sets the <code>inline-progression-dimension</code> minimum value, |
|
|
|
* in millipoints |
|
|
|
* @param dimMin <code>inline-progression-dimension</code> minimum value |
|
|
|
* to set |
|
|
|
*/ |
|
|
|
public void setIPDimMin(Integer dimMin) { |
|
|
|
synchronized (sync) { |