start implementation of block-container

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
This commit is contained in:
Keiron Liddle 2002-08-30 08:03:24 +00:00
parent 5f7e2cdf16
commit e05b816bf5
10 changed files with 706 additions and 212 deletions

View 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;
}

View 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;
}
}

View File

@ -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;
}
}

View 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;
}
}
}
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 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;
}
}

View 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 {
}
}

View 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;
}
}

View 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() {}

View File

@ -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);
}
}
}

View 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();
}

View 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);