<property>
<name>background-image</name>
<inherited>false</inherited>
- <datatype>ToBeImplemented</datatype>
+ <datatype>String</datatype>
<default>none</default>
</property>
<property>
<name>background-repeat</name>
<inherited>false</inherited>
- <datatype>ToBeImplemented</datatype>
+ <datatype>Enum</datatype>
+ <enumeration>
+ <value const="REPEAT">repeat</value>
+ <value const="REPEATX">repeat-x</value>
+ <value const="REPEATY">repeat-y</value>
+ <value const="NOREPEAT">no-repeat</value>
+ </enumeration>
<default>repeat</default>
</property>
<property>
<name>background-position-horizontal</name>
<inherited>false</inherited>
- <datatype>ToBeImplemented</datatype>
+ <datatype>Length</datatype>
<default>0%</default>
</property>
<property>
<name>background-position-vertical</name>
<inherited>false</inherited>
- <datatype>ToBeImplemented</datatype>
+ <datatype>Length</datatype>
<default>0%</default>
</property>
<property>
* each page is either rendered if ready or prepared
* for later rendering.
* Once a page is rendered it is cleared to release the
- * contents but the PageViewport is retained.
+ * contents but the PageViewport is retained. So even
+ * though the pages are stored the contents are discarded.
*/
public static class RenderPagesModel extends StorePagesModel {
/**
public static final Integer PADDING_BEFORE = new Integer(21);
public static final Integer PADDING_AFTER = new Integer(22);
- static HashMap s_hmTraitInfo;
+ static HashMap shmTraitInfo;
private static class TraitInfo {
String sName;
static {
// Create a hashmap mapping trait code to name for external representation
- s_hmTraitInfo = new HashMap();
- s_hmTraitInfo.put(ID_LINK, new TraitInfo("id-link", String.class));
- s_hmTraitInfo.put(INTERNAL_LINK,
+ shmTraitInfo = new HashMap();
+ shmTraitInfo.put(ID_LINK, new TraitInfo("id-link", String.class));
+ shmTraitInfo.put(INTERNAL_LINK,
new TraitInfo("internal-link", PageViewport.class));
- s_hmTraitInfo.put(EXTERNAL_LINK,
+ shmTraitInfo.put(EXTERNAL_LINK,
new TraitInfo("external-link", String.class));
- s_hmTraitInfo.put(FONT_NAME,
+ shmTraitInfo.put(FONT_NAME,
new TraitInfo("font-family", String.class));
- s_hmTraitInfo.put(FONT_SIZE,
+ shmTraitInfo.put(FONT_SIZE,
new TraitInfo("font-size", Integer.class));
- s_hmTraitInfo.put(COLOR, new TraitInfo("color", String.class));
- s_hmTraitInfo.put(ID_AREA, new TraitInfo("id-area", String.class));
- s_hmTraitInfo.put(BACKGROUND,
+ shmTraitInfo.put(COLOR, new TraitInfo("color", String.class));
+ shmTraitInfo.put(ID_AREA, new TraitInfo("id-area", String.class));
+ shmTraitInfo.put(BACKGROUND,
new TraitInfo("background", Background.class));
- s_hmTraitInfo.put(UNDERLINE,
- new TraitInfo("underline", Integer.class));
- s_hmTraitInfo.put(OVERLINE,
- new TraitInfo("overline", Integer.class));
- s_hmTraitInfo.put(LINETHROUGH,
- new TraitInfo("linethrough", Integer.class));
- s_hmTraitInfo.put(OFFSET, new TraitInfo("offset", Integer.class));
- s_hmTraitInfo.put(SHADOW, new TraitInfo("shadow", Integer.class));
- s_hmTraitInfo.put(BORDER_START,
+ shmTraitInfo.put(UNDERLINE,
+ new TraitInfo("underline", Boolean.class));
+ shmTraitInfo.put(OVERLINE,
+ new TraitInfo("overline", Boolean.class));
+ shmTraitInfo.put(LINETHROUGH,
+ new TraitInfo("linethrough", Boolean.class));
+ shmTraitInfo.put(OFFSET, new TraitInfo("offset", Integer.class));
+ shmTraitInfo.put(SHADOW, new TraitInfo("shadow", Integer.class));
+ shmTraitInfo.put(BORDER_START,
new TraitInfo("border-start", BorderProps.class));
- s_hmTraitInfo.put(BORDER_END,
+ shmTraitInfo.put(BORDER_END,
new TraitInfo("border-end", BorderProps.class));
- s_hmTraitInfo.put(BORDER_BEFORE,
+ shmTraitInfo.put(BORDER_BEFORE,
new TraitInfo("border-before", BorderProps.class));
- s_hmTraitInfo.put(BORDER_AFTER,
+ shmTraitInfo.put(BORDER_AFTER,
new TraitInfo("border-after", BorderProps.class));
- s_hmTraitInfo.put(PADDING_START,
+ shmTraitInfo.put(PADDING_START,
new TraitInfo("padding-start", Integer.class));
- s_hmTraitInfo.put(PADDING_END,
+ shmTraitInfo.put(PADDING_END,
new TraitInfo("padding-end", Integer.class));
- s_hmTraitInfo.put(PADDING_BEFORE,
+ shmTraitInfo.put(PADDING_BEFORE,
new TraitInfo("padding-before", Integer.class));
- s_hmTraitInfo.put(PADDING_AFTER,
+ shmTraitInfo.put(PADDING_AFTER,
new TraitInfo("padding-after", Integer.class));
}
public static String getTraitName(Object traitCode) {
- Object obj = s_hmTraitInfo.get(traitCode);
+ Object obj = shmTraitInfo.get(traitCode);
if (obj != null) {
return ((TraitInfo) obj).sName;
} else {
}
public static Object getTraitCode(String sTraitName) {
- Iterator iter = s_hmTraitInfo.entrySet().iterator();
+ Iterator iter = shmTraitInfo.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
TraitInfo ti = (TraitInfo) entry.getValue();
}
private static Class getTraitClass(Object oTraitCode) {
- TraitInfo ti = (TraitInfo) s_hmTraitInfo.get(oTraitCode);
+ TraitInfo ti = (TraitInfo) shmTraitInfo.get(oTraitCode);
return (ti != null ? ti.sClass : null);
}
}
public static class Background {
- ColorType color;
- String url;
- int repeat;
- int horiz;
- int vertical;
+ public ColorType color = null;
+ public String url = null;
+ public int repeat;
+ public int horiz;
+ public int vertical;
}
}
public BackgroundProps getBackgroundProps() {
BackgroundProps bp = new BackgroundProps();
+ bp.backAttachment = properties.get("background-attachment").getEnum();
+ bp.backColor = properties.get("background-color").getColorType();
+ if (bp.backColor.alpha() == 1) {
+ bp.backColor = null;
+ }
+
+ bp.backImage = properties.get("background-image").getString();
+ if (bp.backImage == null || "none".equals(bp.backImage)) {
+ bp.backImage = null;
+ } else {
+ bp.backRepeat = properties.get("background-repeat").getEnum();
+ Property prop = properties.get("background-position-horizontal");
+ if(prop != null) {
+ bp.backPosHorizontal = prop.getLength();
+ }
+ prop = properties.get("background-position-vertical");
+ if(prop != null) {
+ bp.backPosVertical = prop.getLength();
+ }
+ }
+
return bp;
}
return myRefOrient;
}
}
+
"text-indent").getLength().mvalue();
this.keepWithNext =
this.properties.get("keep-with-next").getEnum();
- this.backgroundColor = this.properties.get(
- "background-color").getColorType();
this.blockWidows =
this.properties.get("widows").getNumber().intValue();
/**
* Set to true if all content completely laid out.
*/
- boolean bDone=false;
+ boolean bDone = false;
/**
* Border separation value in the block-progression dimension.
package org.apache.fop.layout;
import org.apache.fop.datatypes.Length;
-
-import java.awt.Color;
+import org.apache.fop.datatypes.ColorType;
/**
- * Store all hyphenation related properties on an FO.
+ * Store all background related properties on an FO.
* Public "structure" allows direct member access.
*/
public class BackgroundProps {
public int backAttachment;
- public Color backColor;
+ public ColorType backColor;
public String backImage;
public int backRepeat;
public Length backPosHorizontal;
import org.apache.fop.area.Resolveable;
import org.apache.fop.area.PageViewport;
import org.apache.fop.fo.PropertyManager;
+import org.apache.fop.area.Trait;
+import org.apache.fop.layout.BorderAndPadding;
+import org.apache.fop.layout.BackgroundProps;
+import org.apache.fop.traits.BorderProps;
import java.util.ListIterator;
return parentLM.retrieveMarker(name, pos, boundary);
}
+ /**
+ * Add borders to an area.
+ * Layout managers that create areas with borders can use this to
+ * add the borders to the area.
+ */
+ public void addBorders(Area curBlock, BorderAndPadding bordProps) {
+ BorderProps bps = getBorderProps(bordProps, BorderAndPadding.TOP);
+ if(bps.width != 0) {
+ curBlock.addTrait(Trait.BORDER_BEFORE, bps);
+ }
+ bps = getBorderProps(bordProps, BorderAndPadding.BOTTOM);
+ if(bps.width != 0) {
+ curBlock.addTrait(Trait.BORDER_AFTER, bps);
+ }
+ bps = getBorderProps(bordProps, BorderAndPadding.LEFT);
+ if(bps.width != 0) {
+ curBlock.addTrait(Trait.BORDER_START, bps);
+ }
+ bps = getBorderProps(bordProps, BorderAndPadding.RIGHT);
+ if(bps.width != 0) {
+ curBlock.addTrait(Trait.BORDER_END, bps);
+ }
+ }
+
+ private BorderProps getBorderProps(BorderAndPadding bordProps, int side) {
+ BorderProps bps;
+ bps = new BorderProps(bordProps.getBorderStyle(side),
+ bordProps.getBorderWidth(side, false),
+ bordProps.getBorderColor(side));
+ return bps;
+ }
+
+ /**
+ * Add background to an area.
+ * Layout managers that create areas with a background can use this to
+ * add the background to the area.
+ */
+ public void addBackground(Area curBlock, BackgroundProps backProps) {
+ Trait.Background back = new Trait.Background();
+ back.color = backProps.backColor;
+
+ if(backProps.backImage != null) {
+ back.url = backProps.backImage;
+ back.repeat = backProps.backRepeat;
+ if(backProps.backPosHorizontal != null) {
+ back.horiz = backProps.backPosHorizontal.mvalue();
+ }
+ if(backProps.backPosVertical != null) {
+ back.vertical = backProps.backPosVertical.mvalue();
+ }
+ }
+
+ if(back.color != null || back.url != null) {
+ curBlock.addTrait(Trait.BACKGROUND, back);
+ }
+ }
}
LayoutProps layoutProps;
BorderAndPadding borderProps;
- BackgroundProps backgroundsPops;
+ BackgroundProps backgroundProps;
int lead = 12000;
int lineHeight = 14000;
protected void initProperties(PropertyManager pm) {
layoutProps = pm.getLayoutProps();
borderProps = pm.getBorderAndPadding();
- backgroundsPops = pm.getBackgroundProps();
+ backgroundProps = pm.getBackgroundProps();
}
public BreakPoss getNextBreakPoss(LayoutContext context) {
curBlockArea = new Block();
// set traits
- addBorders(curBlockArea);
+ addBorders(curBlockArea, borderProps);
+ addBackground(curBlockArea, backgroundProps);
// Set up dimensions
// Must get dimensions from parent area
Area parentArea = parentLM.getParentArea(curBlockArea);
int referenceIPD = parentArea.getIPD();
curBlockArea.setIPD(referenceIPD);
+ curBlockArea.setWidth(referenceIPD);
// Get reference IPD from parentArea
setCurrentArea(curBlockArea); // ??? for generic operations
}
return curBlockArea;
}
- public void addBorders(Block curBlock) {
- BorderProps bps = getBorderProps(BorderAndPadding.TOP);
- if(bps.width != 0) {
- curBlock.addTrait(Trait.BORDER_START, bps);
- }
- bps = getBorderProps(BorderAndPadding.BOTTOM);
- if(bps.width != 0) {
- curBlock.addTrait(Trait.BORDER_END, bps);
- }
- bps = getBorderProps(BorderAndPadding.LEFT);
- if(bps.width != 0) {
- curBlock.addTrait(Trait.BORDER_BEFORE, bps);
- }
- bps = getBorderProps(BorderAndPadding.RIGHT);
- if(bps.width != 0) {
- curBlock.addTrait(Trait.BORDER_AFTER, bps);
- }
- }
-
- private BorderProps getBorderProps(int side) {
- BorderProps bps;
- bps = new BorderProps(borderProps.getBorderStyle(side),
- borderProps.getBorderWidth(side, false),
- borderProps.getBorderColor(side));
- return bps;
- }
-
public boolean addChild(Area childArea) {
if (curBlockArea != null) {
if (childArea instanceof LineArea) {
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyManager;
import org.apache.fop.layout.BorderAndPadding;
+import org.apache.fop.layout.BackgroundProps;
import org.apache.fop.traits.InlineProps;
import org.apache.fop.area.Area;
import org.apache.fop.area.MinOptMax;
/**
* Size of any start or end borders and padding.
*/
- private MinOptMax m_allocIPD = new MinOptMax(0);
+ private MinOptMax allocIPD = new MinOptMax(0);
/**
* Size of border and padding in BPD (ie, before and after).
*/
- private MinOptMax m_extraBPD;
+ private MinOptMax extraBPD;
- private InlineProps m_inlineProps = null;
- private BorderAndPadding m_borderProps = null;
+ private InlineProps inlineProps = null;
+ private BorderAndPadding borderProps = null;
+ private BackgroundProps backgroundProps;
- private Area m_currentArea; // LineArea or InlineParent
+ private Area currentArea; // LineArea or InlineParent
- private BreakPoss m_prevBP;
- private LayoutContext m_childLC ;
+ private BreakPoss prevBP;
+ private LayoutContext childLC ;
- private LayoutManager m_lastChildLM = null; // Set when return last breakposs
- private boolean m_bAreaCreated = false;
+ private LayoutManager lastChildLM = null; // Set when return last breakposs
+ private boolean bAreaCreated = false;
/** Used to store previous content IPD for each child LM. */
- private HashMap m_hmPrevIPD = new HashMap();
+ private HashMap hmPrevIPD = new HashMap();
public InlineStackingLayoutManager(FObj fobj,
ListIterator childLMiter) {
protected void initProperties(PropertyManager propMgr) {
// super.initProperties(propMgr);
- m_inlineProps = propMgr.getInlineProps();
- m_borderProps = propMgr.getBorderAndPadding();
+ inlineProps = propMgr.getInlineProps();
+ borderProps = propMgr.getBorderAndPadding();
// Calculdate border and padding size in BPD
- int iPad = m_borderProps.getPadding(BorderAndPadding.BEFORE, false);
- iPad += m_borderProps.getBorderWidth(BorderAndPadding.BEFORE,
+ int iPad = borderProps.getPadding(BorderAndPadding.BEFORE, false);
+ iPad += borderProps.getBorderWidth(BorderAndPadding.BEFORE,
false);
- iPad += m_borderProps.getPadding(BorderAndPadding.AFTER, false);
- iPad += m_borderProps.getBorderWidth(BorderAndPadding.AFTER, false);
- m_extraBPD = new MinOptMax(iPad);
+ iPad += borderProps.getPadding(BorderAndPadding.AFTER, false);
+ iPad += borderProps.getBorderWidth(BorderAndPadding.AFTER, false);
+ extraBPD = new MinOptMax(iPad);
+
+ backgroundProps = propMgr.getBackgroundProps();
}
private MinOptMax getExtraIPD(boolean bNotFirst, boolean bNotLast) {
- int iBP = m_borderProps.getPadding(BorderAndPadding.START,
+ int iBP = borderProps.getPadding(BorderAndPadding.START,
bNotFirst);
- iBP += m_borderProps.getBorderWidth(BorderAndPadding.START,
+ iBP += borderProps.getBorderWidth(BorderAndPadding.START,
bNotFirst);
- iBP += m_borderProps.getPadding(BorderAndPadding.END, bNotLast);
- iBP += m_borderProps.getBorderWidth(BorderAndPadding.END, bNotLast);
+ iBP += borderProps.getPadding(BorderAndPadding.END, bNotLast);
+ iBP += borderProps.getBorderWidth(BorderAndPadding.END, bNotLast);
return new MinOptMax(iBP);
}
protected boolean hasLeadingFence(boolean bNotFirst) {
- int iBP = m_borderProps.getPadding(BorderAndPadding.START,
+ int iBP = borderProps.getPadding(BorderAndPadding.START,
bNotFirst);
- iBP += m_borderProps.getBorderWidth(BorderAndPadding.START,
+ iBP += borderProps.getBorderWidth(BorderAndPadding.START,
bNotFirst);
return (iBP > 0);
}
protected boolean hasTrailingFence(boolean bNotLast) {
- int iBP = m_borderProps.getPadding(BorderAndPadding.END, bNotLast);
- iBP += m_borderProps.getBorderWidth(BorderAndPadding.END, bNotLast);
+ int iBP = borderProps.getPadding(BorderAndPadding.END, bNotLast);
+ iBP += borderProps.getBorderWidth(BorderAndPadding.END, bNotLast);
return (iBP > 0);
}
// Back up the child LM Position
Position childPos = prevPos.getPosition();
reset(childPos);
- if (m_prevBP != null &&
- m_prevBP.getLayoutManager() != childPos.getLM()) {
- m_childLC = null;
+ if (prevBP != null &&
+ prevBP.getLayoutManager() != childPos.getLM()) {
+ childLC = null;
}
- m_prevBP = new BreakPoss(childPos);
+ prevBP = new BreakPoss(childPos);
} else {
// Backup to start of first child layout manager
- m_prevBP = null;
+ prevBP = null;
// super.resetPosition(prevPos);
reset(prevPos);
// If any areas created, we are restarting!
- m_bAreaCreated = false;
+ bAreaCreated = false;
}
// Do we need to reset some context like pending or prevContent?
- // What about m_prevBP?
+ // What about prevBP?
}
* propagate to first child LM
*/
public boolean canBreakBefore(LayoutContext context) {
- if (m_inlineProps.spaceStart.space.min > 0 ||
+ if (inlineProps.spaceStart.space.min > 0 ||
hasLeadingFence(false)) {
return true;
}
}
protected MinOptMax getPrevIPD(LayoutManager lm) {
- return (MinOptMax) m_hmPrevIPD.get(lm);
+ return (MinOptMax) hmPrevIPD.get(lm);
}
protected void clearPrevIPD() {
- m_hmPrevIPD.clear();
+ hmPrevIPD.clear();
}
if (lc.startsNewArea()) {
// First call to this LM in new parent "area", but this may
// not be the first area created by this inline
- m_childLC = new LayoutContext(lc);
- lc.getLeadingSpace().addSpace(m_inlineProps.spaceStart);
+ childLC = new LayoutContext(lc);
+ lc.getLeadingSpace().addSpace(inlineProps.spaceStart);
// Check for "fence"
if (hasLeadingFence(!lc.isFirstArea())) {
* and initialize pending space from previous LM sibling's
* trailing space specifiers.
*/
- boolean bFirstChildBP = (m_prevBP == null ||
- m_prevBP.getLayoutManager() != curLM);
+ boolean bFirstChildBP = (prevBP == null ||
+ prevBP.getLayoutManager() != curLM);
- initChildLC(m_childLC, m_prevBP, lc.startsNewArea(),
+ initChildLC(childLC, prevBP, lc.startsNewArea(),
bFirstChildBP, leadingSpace);
if (lc.tryHyphenate()) {
- m_childLC.setHyphContext(lc.getHyphContext());
+ childLC.setHyphContext(lc.getHyphContext());
}
- if (((bp = curLM.getNextBreakPoss(m_childLC)) != null) ||
+ if (((bp = curLM.getNextBreakPoss(childLC)) != null) ||
(lc.tryHyphenate() &&
!lc.getHyphContext().hasMoreHyphPoints())) {
break;
myBP.setFlag(BreakPoss.ISLAST, bIsLast);
if (bIsLast) {
- m_lastChildLM = bp.getLayoutManager();
+ lastChildLM = bp.getLayoutManager();
}
// Update dimension information for our allocation area,
// This includes all previous breakinfo
MinOptMax bpDim = (MinOptMax) bp.getStackingSize().clone();
- MinOptMax prevIPD = updatePrevIPD(bp, m_prevBP, lc.startsNewArea(),
+ MinOptMax prevIPD = updatePrevIPD(bp, prevBP, lc.startsNewArea(),
lc.isFirstArea());
if (lc.startsNewArea()) {
// call in this LM
trailingSpace = (SpaceSpecifier) trailingSpace.clone();
}
- trailingSpace.addSpace(m_inlineProps.spaceEnd);
+ trailingSpace.addSpace(inlineProps.spaceEnd);
myBP.setTrailingSpace(trailingSpace);
// Add start and end borders and padding
bpDim.add(getExtraIPD(!lc.isFirstArea(), !bIsLast));
myBP.setStackingSize(bpDim);
myBP.setNonStackingSize(
- MinOptMax.add(bp.getNonStackingSize(), m_extraBPD));
+ MinOptMax.add(bp.getNonStackingSize(), extraBPD));
- m_prevBP = bp;
+ prevBP = bp;
// if (bIsLast) {
// setFinished(true); // Our last area, so indicate done
// }
// Space-start before first child area placed
prevIPD.add(bp.resolveLeadingSpace());
}
- m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
+ hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
} else {
// In case of reset to a previous position, it may already
// be calculated
- prevIPD = (MinOptMax) m_hmPrevIPD.get(bp.getLayoutManager());
+ prevIPD = (MinOptMax) hmPrevIPD.get(bp.getLayoutManager());
if (prevIPD == null) {
// ASSERT(prevBP.getLayoutManager() != bp.getLayoutManager());
/* This is first bp generated by child (in this parent area).
* pending space-end with previous break.
* Corresponds to Space between two child areas.
*/
- prevIPD = (MinOptMax) m_hmPrevIPD.get(
+ prevIPD = (MinOptMax) hmPrevIPD.get(
prevBP.getLayoutManager());
prevIPD = MinOptMax.add(prevIPD, bp.resolveLeadingSpace());
prevIPD.add(prevBP.getStackingSize());
- m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
+ hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
}
}
return prevIPD;
/* How to know if first area created by this LM? Keep a count and
* reset it if getNextBreakPoss() is called again.
*/
- if (hasLeadingFence(m_bAreaCreated)) {
+ if (hasLeadingFence(bAreaCreated)) {
getContext().setLeadingSpace(new SpaceSpecifier(false));
getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE,
true);
false);
}
- context.getLeadingSpace().addSpace(m_inlineProps.spaceStart);
+ context.getLeadingSpace().addSpace(inlineProps.spaceStart);
// posIter iterates over positions returned by this LM
* the last area for the current LM also.
*/
boolean bIsLast =
- (getContext().isLastArea() && prevLM == m_lastChildLM);
+ (getContext().isLastArea() && prevLM == lastChildLM);
if (hasTrailingFence(bIsLast)) {
addSpace(getCurrentArea(),
getContext().getTrailingSpace().resolve(false),
}
// Add own trailing space to parent context (or set on area?)
if(context.getTrailingSpace() != null) {
- context.getTrailingSpace().addSpace(m_inlineProps.spaceEnd);
+ context.getTrailingSpace().addSpace(inlineProps.spaceEnd);
}
// Add border and padding to current area and set flags (FIRST, LAST ...)
TraitSetter.setBorderPaddingTraits(getCurrentArea(),
- m_borderProps, m_bAreaCreated, !bIsLast);
+ borderProps, bAreaCreated, !bIsLast);
+
+ if(borderProps != null) {
+ addBorders(getCurrentArea(), borderProps);
+ }
+ if(backgroundProps != null) {
+ addBackground(getCurrentArea(), backgroundProps);
+ }
+
parentLM.addChild(getCurrentArea());
context.setFlags(LayoutContext.LAST_AREA, bIsLast);
- m_bAreaCreated = true;
+ bAreaCreated = true;
}
protected Area getCurrentArea() {
- return m_currentArea;
+ return currentArea;
}
protected void setCurrentArea(Area area) {
- m_currentArea = area;
+ currentArea = area;
}
}
protected void setChildContext(LayoutContext lc) {
- m_childLC = lc;
+ childLC = lc;
}
// Current child layout context
protected LayoutContext getContext() {
- return m_childLC ;
+ return childLC ;
}
protected void addSpace(Area parentArea, MinOptMax spaceRange,
protected boolean preLoadNext() {
// skip over child FObj's that don't add lms
while (m_baseIter.hasNext()) {
- FObj fobj = (FObj) m_baseIter.next();
- //m_listLMs.add(fobj.getLayoutManager());
- fobj.addLayoutManager(m_listLMs);
- if(m_curPos < m_listLMs.size()) {
- return true;
+ Object theobj = m_baseIter.next();
+ if(theobj instanceof FObj) {
+ FObj fobj = (FObj) theobj;
+ //m_listLMs.add(fobj.getLayoutManager());
+ fobj.addLayoutManager(m_listLMs);
+ if(m_curPos < m_listLMs.size()) {
+ return true;
+ }
}
}
return false;
curWordArea.addTrait(Trait.FONT_NAME, textInfo.fs.getFontName());
curWordArea.addTrait(Trait.FONT_SIZE,
new Integer(textInfo.fs.getFontSize()));
+ curWordArea.addTrait(Trait.COLOR, this.textInfo.color);
return curWordArea;
}
-
}
package org.apache.fop.layoutmgr.table;
+import org.apache.fop.fo.PropertyManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.MinOptMax;
+import org.apache.fop.layout.BorderAndPadding;
+import org.apache.fop.layout.BackgroundProps;
import java.util.ArrayList;
import java.util.List;
* Cells are organised into rows.
*/
public class Body extends BlockStackingLayoutManager {
+ private BorderAndPadding borderProps = null;
+ private BackgroundProps backgroundProps;
private boolean rows = true;
private List columns;
super(fobj);
}
+ protected void initProperties(PropertyManager propMgr) {
+ borderProps = propMgr.getBorderAndPadding();
+ backgroundProps = propMgr.getBackgroundProps();
+ }
+
/**
* Set the columns from the table.
*
reset(null);
}
}
+
+ /**
+ * Create a body area.
+ * This area has the background and width set.
+ *
+ * @return the new body area
+ */
+ public Area createColumnArea() {
+ Area curBlockArea = new Block();
+
+ if(backgroundProps != null) {
+ addBackground(curBlockArea, backgroundProps);
+ }
+ return curBlockArea;
+ }
}
package org.apache.fop.layoutmgr.table;
+import org.apache.fop.fo.PropertyManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.MinOptMax;
+import org.apache.fop.layout.BorderAndPadding;
+import org.apache.fop.layout.BackgroundProps;
import java.util.ArrayList;
*/
public class Cell extends BlockStackingLayoutManager {
+ private BorderAndPadding borderProps = null;
+ private BackgroundProps backgroundProps;
+
private Block curBlockArea;
private ArrayList childBreaks = new ArrayList();
super(fobj);
}
+ protected void initProperties(PropertyManager propMgr) {
+ borderProps = propMgr.getBorderAndPadding();
+ backgroundProps = propMgr.getBackgroundProps();
+ }
+
/**
* Get the next break possibility for this cell.
* A cell contains blocks so there are breaks around the blocks
}
}
+ if(borderProps != null) {
+ addBorders(curBlockArea, borderProps);
+ }
+ if(backgroundProps != null) {
+ addBackground(curBlockArea, backgroundProps);
+ }
+
flush();
childBreaks.clear();
package org.apache.fop.layoutmgr.table;
+import org.apache.fop.fo.PropertyManager;
import org.apache.fop.layoutmgr.AbstractLayoutManager;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.fo.flow.TableColumn;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
+import org.apache.fop.layout.BorderAndPadding;
+import org.apache.fop.layout.BackgroundProps;
/**
* LayoutManager for a table-column FO.
*/
public class Column extends AbstractLayoutManager {
private int columnWidth;
+ private BorderAndPadding borderProps = null;
+ private BackgroundProps backgroundProps;
/**
* Create a new column layout manager.
columnWidth = fobj.getColumnWidth();
}
+ protected void initProperties(PropertyManager propMgr) {
+ borderProps = propMgr.getBorderAndPadding();
+ backgroundProps = propMgr.getBackgroundProps();
+ }
+
/**
* Get the next break possibility.
* Columns do not create or return any areas.
* @return the new column area
*/
public Area createColumnArea() {
- return new Block();
+ Area curBlockArea = new Block();
+
+ if(backgroundProps != null) {
+ addBackground(curBlockArea, backgroundProps);
+ }
+ return curBlockArea;
}
}
package org.apache.fop.layoutmgr.table;
+import org.apache.fop.fo.PropertyManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.fo.FObj;
import org.apache.fop.area.Area;
+import org.apache.fop.area.Block;
import org.apache.fop.area.MinOptMax;
+import org.apache.fop.layout.BorderAndPadding;
+import org.apache.fop.layout.BackgroundProps;
import java.util.Iterator;
import java.util.ArrayList;
private List columns = null;
private int rowHeight;
private int yoffset;
+ private BorderAndPadding borderProps = null;
+ private BackgroundProps backgroundProps;
private class RowPosition extends LeafPosition {
protected List cellBreaks;
super(fobj);
}
+ protected void initProperties(PropertyManager propMgr) {
+ borderProps = propMgr.getBorderAndPadding();
+ backgroundProps = propMgr.getBackgroundProps();
+ }
+
/**
* Set the columns from the table.
*
MinOptMax.subtract(context.getStackLimit(),
stackSize));
- Column col = (Column)columns.get(cellcount - 1);
+ int size = columns.size();
+ Column col;
+ if (cellcount > size - 1) {
+ col = (Column)columns.get(size - 1);
+ } else {
+ col = (Column)columns.get(cellcount - 1);
+ }
childLC.setRefIPD(col.getWidth());
while (!curLM.isFinished()) {
PositionIterator breakPosIter;
breakPosIter = new BreakPossPosIter(cellsbr, 0, cellsbr.size());
iStartPos = lfp.getLeafPos() + 1;
- Column col = (Column)columns.get(cellcount++);
+
+ int size = columns.size();
+ Column col;
+ if (cellcount > size - 1) {
+ col = (Column)columns.get(size - 1);
+ } else {
+ col = (Column)columns.get(cellcount);
+ cellcount++;
+ }
+
while ((childLM = (Cell)breakPosIter.getNextChildLM()) != null) {
childLM.setXOffset(xoffset);
childLM.setYOffset(yoffset);
reset(null);
}
}
+
+
+ /**
+ * Get the area for this row for background.
+ *
+ * @return the row area
+ */
+ public Area getRowArea() {
+ Area block = new Block();
+ if(backgroundProps != null) {
+ addBackground(block, backgroundProps);
+ }
+ return block;
+ }
}
package org.apache.fop.layoutmgr.table;
+import org.apache.fop.fo.PropertyManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.MinOptMax;
+import org.apache.fop.layout.BorderAndPadding;
+import org.apache.fop.layout.BackgroundProps;
import java.util.ArrayList;
import java.util.List;
private Body tableHeader = null;
private Body tableFooter = null;
+ private BorderAndPadding borderProps = null;
+ private BackgroundProps backgroundProps;
+
private Block curBlockArea;
private ArrayList bodyBreaks = new ArrayList();
super(fobj);
}
+ protected void initProperties(PropertyManager propMgr) {
+ borderProps = propMgr.getBorderAndPadding();
+ backgroundProps = propMgr.getBackgroundProps();
+ }
+
/**
* Set the columns for this table.
*
curBlockArea.setHeight(tableHeight);
+ if(borderProps != null) {
+ addBorders(curBlockArea, borderProps);
+ }
+ if(backgroundProps != null) {
+ addBackground(curBlockArea, backgroundProps);
+ }
+
flush();
bodyBreaks.clear();
// Avalon
import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
/**
* Abstract base class for all renderers. The Abstract renderer does all the
* handle viewports. This keeps track of the current block and inline position.
*/
public abstract class AbstractRenderer extends AbstractLogEnabled
- implements Renderer {
+ implements Renderer, Configurable {
/**
* user agent
}
}
+ public void configure(Configuration conf) throws ConfigurationException {
+ }
}
+
import org.apache.fop.layout.FontInfo;
// Java
+import java.util.ArrayList;
import java.io.IOException;
import java.io.OutputStream;
/** Font configuration */
protected FontInfo fontInfo;
+ protected ArrayList fontList = null;
+
/**
* Set up the font info
*
*/
public void setupFontInfo(FontInfo fontInfo) {
this.fontInfo = fontInfo;
- FontSetup.setup(fontInfo, null);
+ FontSetup.setup(fontInfo, fontList);
}
/** @see org.apache.fop.render.Renderer */
* FontInfo contains meta information on fonts (where is the metrics file etc.)
*/
public class EmbedFontInfo {
- private String metricsFile, embedFile, name;
+ private String metricsFile, embedFile;
private boolean kerning;
private ArrayList fontTriplets;
- public EmbedFontInfo(String name, String metricsFile, boolean kerning,
+ public EmbedFontInfo(String metricsFile, boolean kerning,
ArrayList fontTriplets, String embedFile) {
- this.name = name;
this.metricsFile = metricsFile;
this.embedFile = embedFile;
this.kerning = kerning;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.Version;
import org.apache.fop.fo.properties.RuleStyle;
+import org.apache.fop.fo.properties.BackgroundRepeat;
import org.apache.fop.pdf.PDFStream;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFInfo;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.Page;
import org.apache.fop.area.RegionReference;
+import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.BlockViewport;
import org.apache.fop.area.LineArea;
import org.apache.fop.layout.FontState;
import org.apache.fop.layout.FontMetric;
import org.apache.fop.traits.BorderProps;
+import org.apache.fop.datatypes.ColorType;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
import org.w3c.dom.Document;
import java.awt.geom.AffineTransform;
import java.util.HashMap;
import java.util.List;
+import java.util.ArrayList;
/*
todo:
protected int currentFontSize = 0;
protected int pageHeight;
+ protected HashMap filterMap = new HashMap();
+
/**
* true if a TJ command is left to be written
*/
public PDFRenderer() {
}
+ /**
+ * Configure the PDF renderer.
+ * Get the configuration to be used for pdf stream filters,
+ * fonts etc.
+ */
+ public void configure(Configuration conf) throws ConfigurationException {
+ Configuration filters = conf.getChild("filterList");
+ Configuration[] filt = filters.getChildren("value");
+ ArrayList filterList = new ArrayList();
+ for (int i = 0; i < filt.length; i++) {
+ String name = filt[i].getValue();
+ filterList.add(name);
+ }
+
+ filterMap.put(PDFStream.DEFAULT_FILTER, filterList);
+
+ Configuration[] font = conf.getChildren("font");
+ for (int i = 0; i < font.length; i++) {
+ Configuration[] triple = font[i].getChildren("font-triplet");
+ ArrayList tripleList = new ArrayList();
+ for (int j = 0; j < triple.length; j++) {
+ tripleList.add(new FontTriplet(triple[j].getAttribute("name"),
+ triple[j].getAttribute("style"),
+ triple[j].getAttribute("weight")));
+ }
+
+ EmbedFontInfo efi;
+ efi = new EmbedFontInfo(font[i].getAttribute("metrics-url"),
+ font[i].getAttributeAsBoolean("kerning"),
+ tripleList, font[i].getAttribute("embed-url"));
+
+ if(fontList == null) {
+ fontList = new ArrayList();
+ }
+ fontList.add(efi);
+ }
+
+ }
+
/**
* set the PDF document's producer
*
ostream = stream;
this.pdfDoc = new PDFDocument(Version.getVersion());
this.pdfDoc.setProducer(producer);
+ this.pdfDoc.setFilterMap(filterMap);
pdfDoc.outputHeader(stream);
}
super.renderRegion(region);
}
+ /**
+ * Handle block traits.
+ * The block could be any sort of block with any positioning
+ * so this should render the traits such as border and background
+ * in its position.
+ *
+ * @param block the block to render the traits
+ */
protected void handleBlockTraits(Block block) {
- // draw border and background
- BorderProps bps = (BorderProps)block.getTrait(Trait.BORDER_BEFORE);
- if(bps != null) {
- float startx = ((float) currentBlockIPPosition) / 1000f;
- float starty = (currentBPPosition / 1000f);
- float endx = (currentBlockIPPosition + block.getWidth()) / 1000f;
+ float startx = currentIPPosition / 1000f;
+ float starty = currentBPPosition / 1000f;
+ drawBackAndBorders(block, startx, starty,
+ block.getWidth() / 1000f, block.getHeight() / 1000f);
+ }
+ /**
+ * Draw the background and borders.
+ * This draws the background and border traits for an area given
+ * the position.
+ *
+ * @param block the area to get teh traits from
+ * @param startx the start x position
+ * @param starty the start y position
+ * @param width the width of the area
+ * @param height the height of the area
+ */
+ protected void drawBackAndBorders(Area block, float startx, float starty, float width, float height) {
+ // draw background then border
+
+ closeText();
+
+ boolean started = false;
+ Trait.Background back;
+ back = (Trait.Background)block.getTrait(Trait.BACKGROUND);
+ if(back != null) {
+ started = true;
currentStream.add("ET\n");
currentStream.add("q\n");
- currentStream.add(bps.width / 1000f + " w\n");
+ if (back.color != null) {
+ updateColor(back.color, true, null);
+ currentStream.add(startx + " " + starty + " "
+ + width + " " + height + " re\n");
+ currentStream.add("f\n");
+ }
+ if (back.url != null) {
+ ImageFactory fact = ImageFactory.getInstance();
+ FopImage fopimage = fact.getImage(back.url, userAgent);
+ if (fopimage != null && fopimage.load(FopImage.DIMENSIONS, userAgent)) {
+ if (back.repeat == BackgroundRepeat.REPEAT) {
+ // create a pattern for the image
+ } else {
+ // place once
+ Rectangle2D pos;
+ pos = new Rectangle2D.Float((startx + back.horiz) * 1000,
+ (starty + back.vertical) * 1000,
+ fopimage.getWidth() * 1000,
+ fopimage.getHeight() * 1000);
+ putImage(back.url, pos);
+ }
+ }
+ }
+ }
- currentStream.add(startx + " " + starty + " m\n");
- currentStream.add(endx + " " + starty + " l\n");
- currentStream.add("S\n");
+ BorderProps bps = (BorderProps)block.getTrait(Trait.BORDER_BEFORE);
+ if(bps != null) {
+ float endx = startx + width;
- currentStream.add("Q\n");
- currentStream.add("BT\n");
+ if(!started) {
+ started = true;
+ currentStream.add("ET\n");
+ currentStream.add("q\n");
+ }
+
+ updateColor(bps.color, false, null);
+ currentStream.add(bps.width / 1000f + " w\n");
+
+ drawLine(startx, starty, endx, starty);
}
bps = (BorderProps)block.getTrait(Trait.BORDER_START);
if(bps != null) {
+ float endy = starty + height;
+
+ if(!started) {
+ started = true;
+ currentStream.add("ET\n");
+ currentStream.add("q\n");
+ }
+
+ updateColor(bps.color, false, null);
+ currentStream.add(bps.width / 1000f + " w\n");
+
+ drawLine(startx, starty, startx, endy);
}
bps = (BorderProps)block.getTrait(Trait.BORDER_AFTER);
if(bps != null) {
+ float sy = starty + height;
+ float endx = startx + width;
+
+ if(!started) {
+ started = true;
+ currentStream.add("ET\n");
+ currentStream.add("q\n");
+ }
+
+ updateColor(bps.color, false, null);
+ currentStream.add(bps.width / 1000f + " w\n");
+
+ drawLine(startx, sy, endx, sy);
}
bps = (BorderProps)block.getTrait(Trait.BORDER_END);
if(bps != null) {
+ float sx = startx + width;
+ float endy = starty + height;
+
+ if(!started) {
+ started = true;
+ currentStream.add("ET\n");
+ currentStream.add("q\n");
+ }
+
+ updateColor(bps.color, false, null);
+ currentStream.add(bps.width / 1000f + " w\n");
+ drawLine(sx, starty, sx, endy);
+ }
+ if(started) {
+ currentStream.add("Q\n");
+ currentStream.add("BT\n");
}
}
+ /**
+ * Draw a line.
+ *
+ * @param startx the start x position
+ * @param starty the start y position
+ * @param endx the x end position
+ * @param endy the y end position
+ */
+ private void drawLine(float startx, float starty, float endx, float endy) {
+ currentStream.add(startx + " " + starty + " m\n");
+ currentStream.add(endx + " " + endy + " l\n");
+ currentStream.add("S\n");
+ }
+
protected void renderBlockViewport(BlockViewport bv, List children) {
// clip and position viewport if necessary
* @param ip the inline parent area
*/
public void renderInlineParent(InlineParent ip) {
+ float start = currentBlockIPPosition / 1000f;
+ float top = (ip.getOffset() + currentBPPosition) / 1000f;
+ float width = ip.getWidth() / 1000f;
+ float height = ip.getHeight() / 1000f;
+ drawBackAndBorders(ip, start, top, width, height);
+
+ // render contents
+ super.renderInlineParent(ip);
+
+ // place the link over the top
Object tr = ip.getTrait(Trait.INTERNAL_LINK);
boolean internal = false;
String dest = null;
internal = true;
}
if (dest != null) {
- float start = currentBlockIPPosition;
- float top = (ip.getOffset() + currentBPPosition) / 1000f;
- float height = ip.getHeight() / 1000f;
- super.renderInlineParent(ip);
- float width = (currentBlockIPPosition - start) / 1000f;
- start = start / 1000f;
// add link to pdf document
Rectangle2D rect = new Rectangle2D.Float(start, top, width, height);
// transform rect to absolute coords
int type = internal ? PDFLink.INTERNAL : PDFLink.EXTERNAL;
PDFLink pdflink = pdfDoc.makeLink(rect, dest, type);
currentPage.addAnnotation(pdflink);
- } else {
- super.renderInlineParent(ip);
}
}
String endText = useMultiByte ? "> " : ") ";
updateFont(name, size, pdf);
- updateColor(true, pdf);
+ ColorType ct = (ColorType)word.getTrait(Trait.COLOR);
+ if(ct != null) {
+ updateColor(ct, true, pdf);
+ }
int rx = currentBlockIPPosition;
// int bl = pageHeight - currentBPPosition;
}
}
- private void updateColor(boolean fill, StringBuffer pdf) {
- /*PDFColor areaColor = null;
- if (this.currentFill instanceof PDFColor) {
- areaColor = (PDFColor)this.currentFill;
- }
+ private void updateColor(ColorType col, boolean fill, StringBuffer pdf) {
+ PDFColor areaColor = null;
+ //if (this.currentFill instanceof PDFColor) {
+ // areaColor = (PDFColor)this.currentFill;
+ //}
- if (areaColor == null || areaColor.red() != (double)area.getRed()
- || areaColor.green() != (double)area.getGreen()
- || areaColor.blue() != (double)area.getBlue()) {
+ if (areaColor == null || areaColor.red() != (double)col.red()
+ || areaColor.green() != (double)col.green()
+ || areaColor.blue() != (double)col.blue()) {
- areaColor = new PDFColor((double)area.getRed(),
- (double)area.getGreen(),
- (double)area.getBlue());
+ areaColor = new PDFColor((double)col.red(),
+ (double)col.green(),
+ (double)col.blue());
- closeText();
- this.currentFill = areaColor;
- pdf.append(this.currentFill.getColorSpaceOut(true));
- }*/
+ closeText();
+ //this.currentFill = areaColor;
+ if(pdf != null) {
+ pdf.append(areaColor.getColorSpaceOut(fill));
+ } else {
+ currentStream.add(areaColor.getColorSpaceOut(fill));
+ }
+ }
}
private void updateFont(String name, int size, StringBuffer pdf) {
public void renderImage(Image image, Rectangle2D pos) {
String url = image.getURL();
+ putImage(url, pos);
+ }
+ protected void putImage(String url, Rectangle2D pos) {
PDFXObject xobject = pdfDoc.getImage(url);
if (xobject != null) {
int w = (int) pos.getWidth() / 1000;
float endx = (currentBlockIPPosition + area.getWidth()) / 1000f;
if (!alt) {
currentStream.add(area.getRuleThickness() / 1000f + " w\n");
-
- currentStream.add(startx + " " + starty + " m\n");
- currentStream.add(endx + " " + starty + " l\n");
- currentStream.add("S\n");
+ drawLine(startx, starty, endx, starty);
} else {
if (style == RuleStyle.DOUBLE) {
float third = area.getRuleThickness() / 3000f;
currentStream.add(third + " w\n");
- currentStream.add(startx + " " + starty + " m\n");
- currentStream.add(endx + " " + starty + " l\n");
- currentStream.add("S\n");
+ drawLine(startx, starty, endx, starty);
- currentStream.add(startx + " " + (starty + 2 * third) + " m\n");
- currentStream.add(endx + " " + (starty + 2 * third) + " l\n");
- currentStream.add("S\n");
+ drawLine(startx, (starty + 2 * third), endx, (starty + 2 * third));
} else {
float half = area.getRuleThickness() / 2000f;