Obtained from: Submitted by: Reviewed by: Add BreakPossibility style LayoutManager code as an alternative to Keiron's "direct area creation" method. Not currently enabled: to do so, one must make 2 changes in the source. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194758 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_20_4-doc
<property> | <property> | ||||
<name>word-spacing</name> | <name>word-spacing</name> | ||||
<inherited>true</inherited> | <inherited>true</inherited> | ||||
<datatype>ToBeImplemented</datatype> | |||||
<default>normal</default> | |||||
<use-generic>GenericSpace</use-generic> | |||||
<default subproperty="precedence">force</default> | |||||
<default subproperty="conditionality">discard</default> | |||||
<default>0pt</default> | |||||
<!-- <default>normal</default> --> | |||||
</property> | </property> | ||||
<!-- Color-related Properties --> | <!-- Color-related Properties --> |
this.columnCount = colCount; | this.columnCount = colCount; | ||||
} | } | ||||
// Number of columns when not spanning | |||||
public int getColumnCount() { | |||||
return this.columnCount ; | |||||
} | |||||
// A length (mpoints) | // A length (mpoints) | ||||
public void setColumnGap(int colGap) { | public void setColumnGap(int colGap) { | ||||
this.columnGap = colGap; | this.columnGap = colGap; |
* variables are package visible. | * variables are package visible. | ||||
*/ | */ | ||||
public class MinOptMax implements java.io.Serializable { | |||||
public class MinOptMax implements java.io.Serializable, Cloneable { | |||||
/** Publicly visible min(imum), opt(imum) and max(imum) values.*/ | /** Publicly visible min(imum), opt(imum) and max(imum) values.*/ | ||||
public int min; | public int min; | ||||
this.max = max; | this.max = max; | ||||
} | } | ||||
public Object clone() { | |||||
try { | |||||
return super.clone(); | |||||
} catch (CloneNotSupportedException ex) { | |||||
// SHOULD NEVER OCCUR - all members are primitive types! | |||||
return null; | |||||
} | |||||
} | |||||
public static MinOptMax subtract(MinOptMax op1, MinOptMax op2) { | public static MinOptMax subtract(MinOptMax op1, MinOptMax op2) { | ||||
return new MinOptMax(op1.min - op2.max, op1.opt - op2.opt, | return new MinOptMax(op1.min - op2.max, op1.opt - op2.opt, | ||||
op1.max - op2.min); | op1.max - op2.min); | ||||
op1.max + op2.max); | op1.max + op2.max); | ||||
} | } | ||||
public static MinOptMax multiply(MinOptMax op1, double mult) { | |||||
return new MinOptMax((int)(op1.min * mult), | |||||
(int)(op1.opt * mult), | |||||
(int)(op1.max * mult)); | |||||
} | |||||
public void add(MinOptMax op) { | public void add(MinOptMax op) { | ||||
min += op.min; | min += op.min; | ||||
opt += op.opt; | opt += op.opt; |
return this.precedence; | return this.precedence; | ||||
} | } | ||||
/* | |||||
* public boolean isDiscard() { | |||||
* return (this.conditionality == DISCARD); | |||||
* } | |||||
*/ | |||||
public Property getConditionality() { | public Property getConditionality() { | ||||
return this.conditionality; | return this.conditionality; | ||||
} | } |
import org.apache.fop.apps.FOPException; | import org.apache.fop.apps.FOPException; | ||||
import org.apache.fop.layoutmgr.LayoutManager; | import org.apache.fop.layoutmgr.LayoutManager; | ||||
import org.apache.fop.layoutmgr.TextLayoutManager; | import org.apache.fop.layoutmgr.TextLayoutManager; | ||||
import org.apache.fop.layoutmgr.TextBPLayoutManager; | |||||
import java.util.NoSuchElementException; | import java.util.NoSuchElementException; | ||||
import java.util.List; | import java.util.List; | ||||
System.arraycopy(tmp, 0, ca, 0, length); | System.arraycopy(tmp, 0, ca, 0, length); | ||||
} | } | ||||
list.add(new TextLayoutManager(this, ca, textInfo)); | list.add(new TextLayoutManager(this, ca, textInfo)); | ||||
// TEST VARIANT USING Karen's BreakPoss scheme | |||||
// list.add(new TextBPLayoutManager(this, ca, textInfo)); | |||||
} | } | ||||
public CharIterator charIterator() { | public CharIterator charIterator() { |
public ArrayList getMarkers() { | public ArrayList getMarkers() { | ||||
return new ArrayList(markers.values()); | return new ArrayList(markers.values()); | ||||
} | } | ||||
/** | |||||
* lets layout managers access FO properties via PropertyManager | |||||
* @return the property manager for this FO | |||||
*/ | |||||
public PropertyManager getPropertyManager() { | |||||
return this.propMgr; | |||||
} | |||||
} | } | ||||
} | } | ||||
protected void addCharacters(char data[], int start, int length) { | protected void addCharacters(char data[], int start, int length) { | ||||
if (textInfo == null) { | |||||
textInfo = new TextInfo(); | |||||
try { | |||||
textInfo.fs = propMgr.getFontState(fontInfo); | |||||
} catch (FOPException fopex) { | |||||
log.error("Error setting FontState for characters: " + | |||||
fopex.getMessage()); | |||||
} | |||||
ColorType c = getProperty("color").getColorType(); | |||||
textInfo.color = c; | |||||
textInfo.verticalAlign = | |||||
getProperty("vertical-align").getEnum(); | |||||
textInfo.wrapOption = getProperty("wrap-option").getEnum(); | |||||
textInfo.whiteSpaceCollapse = | |||||
getProperty("white-space-collapse").getEnum(); | |||||
if(textInfo == null) { | |||||
// Really only need one of these, but need to get fontInfo | |||||
// stored in propMgr for later use. | |||||
propMgr.setFontInfo(fontInfo); | |||||
textInfo = propMgr.getTextLayoutProps(fontInfo); | |||||
} | } | ||||
FOText ft = new FOText(data, start, length, textInfo); | FOText ft = new FOText(data, start, length, textInfo); |
import java.awt.geom.Rectangle2D; | import java.awt.geom.Rectangle2D; | ||||
import org.apache.fop.area.CTM; | import org.apache.fop.area.CTM; | ||||
import org.apache.fop.datatypes.FODimension; | import org.apache.fop.datatypes.FODimension; | ||||
import org.apache.fop.fo.TextInfo; // should be somewhere else probably... | |||||
import org.apache.fop.layout.FontState; | import org.apache.fop.layout.FontState; | ||||
import org.apache.fop.layout.FontInfo; | import org.apache.fop.layout.FontInfo; | ||||
import org.apache.fop.layout.BorderAndPadding; | import org.apache.fop.layout.BorderAndPadding; | ||||
import org.apache.fop.layout.MarginProps; | import org.apache.fop.layout.MarginProps; | ||||
import org.apache.fop.layout.BackgroundProps; | |||||
import org.apache.fop.layout.MarginInlineProps; | import org.apache.fop.layout.MarginInlineProps; | ||||
import org.apache.fop.layout.BackgroundProps; | |||||
import org.apache.fop.layout.AccessibilityProps; | import org.apache.fop.layout.AccessibilityProps; | ||||
import org.apache.fop.layout.AuralProps; | import org.apache.fop.layout.AuralProps; | ||||
import org.apache.fop.layout.RelativePositionProps; | import org.apache.fop.layout.RelativePositionProps; | ||||
import org.apache.fop.layout.AbsolutePositionProps; | 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.fo.properties.BreakAfter; | import org.apache.fop.fo.properties.BreakAfter; | ||||
import org.apache.fop.fo.properties.BreakBefore; | import org.apache.fop.fo.properties.BreakBefore; | ||||
import org.apache.fop.fo.properties.Constants; | import org.apache.fop.fo.properties.Constants; | ||||
import org.apache.fop.fo.properties.WritingMode; | import org.apache.fop.fo.properties.WritingMode; | ||||
import org.apache.fop.fo.properties.Span; | |||||
import org.apache.fop.layout.HyphenationProps; | import org.apache.fop.layout.HyphenationProps; | ||||
import org.apache.fop.apps.FOPException; | import org.apache.fop.apps.FOPException; | ||||
import java.text.MessageFormat; | import java.text.MessageFormat; | ||||
public class PropertyManager { | public class PropertyManager { | ||||
private PropertyList properties; | private PropertyList properties; | ||||
private FontInfo m_fontInfo = null; | |||||
private FontState fontState = null; | private FontState fontState = null; | ||||
private BorderAndPadding borderAndPadding = null; | private BorderAndPadding borderAndPadding = null; | ||||
private HyphenationProps hyphProps = null; | private HyphenationProps hyphProps = null; | ||||
private TextInfo textInfo = null; | |||||
private String[] saLeft; | private String[] saLeft; | ||||
private String[] saRight; | private String[] saRight; | ||||
this.properties = pList; | this.properties = pList; | ||||
} | } | ||||
public void setFontInfo(FontInfo fontInfo) { | |||||
m_fontInfo = fontInfo; | |||||
} | |||||
private void initDirections() { | private void initDirections() { | ||||
saLeft = new String[1]; | saLeft = new String[1]; | ||||
saRight = new String[1]; | saRight = new String[1]; | ||||
public FontState getFontState(FontInfo fontInfo) throws FOPException { | public FontState getFontState(FontInfo fontInfo) throws FOPException { | ||||
if (fontState == null) { | if (fontState == null) { | ||||
if (fontInfo == null) { | |||||
fontInfo = m_fontInfo; | |||||
} | |||||
else if (m_fontInfo == null) { | |||||
m_fontInfo = fontInfo; | |||||
} | |||||
String fontFamily = properties.get("font-family").getString(); | String fontFamily = properties.get("font-family").getString(); | ||||
String fontStyle = properties.get("font-style").getString(); | String fontStyle = properties.get("font-style").getString(); | ||||
String fontWeight = properties.get("font-weight").getString(); | String fontWeight = properties.get("font-weight").getString(); | ||||
return props; | return props; | ||||
} | } | ||||
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()); | |||||
return props; | |||||
} | |||||
public AccessibilityProps getAccessibilityProps() { | public AccessibilityProps getAccessibilityProps() { | ||||
AccessibilityProps props = new AccessibilityProps(); | AccessibilityProps props = new AccessibilityProps(); | ||||
String str; | String str; | ||||
return props; | return props; | ||||
} | } | ||||
public BlockProps getBlockProps() { | |||||
BlockProps props = new BlockProps(); | |||||
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(); | |||||
return props; | |||||
} | |||||
public LayoutProps getLayoutProps() { | |||||
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()); | |||||
return props; | |||||
} | |||||
public TextInfo getTextLayoutProps(FontInfo fontInfo) { | |||||
if (textInfo == null) { | |||||
textInfo = new TextInfo(); | |||||
try { | |||||
textInfo.fs = getFontState(fontInfo); | |||||
} catch (FOPException fopex) { | |||||
/* log.error("Error setting FontState for characters: " + | |||||
fopex.getMessage());*/ | |||||
// Now what should we do ??? | |||||
} | |||||
textInfo.color = properties.get("color").getColorType(); | |||||
textInfo.verticalAlign = | |||||
properties.get("vertical-align").getEnum(); | |||||
textInfo.wrapOption = properties.get("wrap-option").getEnum(); | |||||
textInfo.bWrap = (textInfo.wrapOption == Constants.WRAP); | |||||
textInfo.wordSpacing = | |||||
new SpaceVal(properties.get("word-spacing").getSpace()); | |||||
/* textInfo.letterSpacing = | |||||
new SpaceVal(properties.get("letter-spacing").getSpace());*/ | |||||
textInfo.whiteSpaceCollapse = | |||||
properties.get("white-space-collapse").getEnum(); | |||||
textInfo.lineHeight = this.properties. | |||||
get("line-height").getLength().mvalue(); | |||||
} | |||||
return textInfo; | |||||
} | |||||
public CTM getCTMandRelDims(Rectangle2D absVPrect, FODimension reldims) { | public CTM getCTMandRelDims(Rectangle2D absVPrect, FODimension reldims) { | ||||
int width, height; | int width, height; | ||||
// We will use the absolute reference-orientation to set up the CTM. | // We will use the absolute reference-orientation to set up the CTM. |
package org.apache.fop.fo; | package org.apache.fop.fo; | ||||
// FOP | // FOP | ||||
import org.apache.fop.layout.Area; | |||||
import org.apache.fop.layout.BlockArea; | |||||
import org.apache.fop.layout.FontState; | import org.apache.fop.layout.FontState; | ||||
import org.apache.fop.layout.*; | |||||
import org.apache.fop.datatypes.*; | |||||
import org.apache.fop.fo.properties.*; | |||||
import org.apache.fop.apps.FOPException; | |||||
import org.apache.fop.layoutmgr.LayoutManager; | |||||
import org.apache.fop.layoutmgr.TextLayoutManager; | |||||
import java.util.NoSuchElementException; | |||||
import org.apache.fop.datatypes.ColorType; | |||||
import org.apache.fop.traits.SpaceVal; | |||||
/** | /** | ||||
* Collection of properties used in | |||||
*/ | */ | ||||
public class TextInfo { | public class TextInfo { | ||||
public FontState fs; | public FontState fs; | ||||
public ColorType color; | public ColorType color; | ||||
public int wrapOption; | public int wrapOption; | ||||
public boolean bWrap ; // True if wrap-option = WRAP | |||||
public int whiteSpaceCollapse; | public int whiteSpaceCollapse; | ||||
public int verticalAlign; | public int verticalAlign; | ||||
public int lineHeight; | public int lineHeight; | ||||
// Props used for calculating inline-progression-dimension | |||||
public SpaceVal wordSpacing; | |||||
public SpaceVal letterSpacing; | |||||
// Add hyphenation props too | |||||
// Textdecoration | // Textdecoration | ||||
public boolean underlined = false; | public boolean underlined = false; | ||||
public boolean overlined = false; | public boolean overlined = false; |
public void addLayoutManager(List list) { | public void addLayoutManager(List list) { | ||||
BlockLayoutManager blm = new BlockLayoutManager(this); | BlockLayoutManager blm = new BlockLayoutManager(this); | ||||
TextInfo ti = new TextInfo(); | |||||
try { | |||||
ti.fs = propMgr.getFontState(fontInfo); | |||||
} catch (FOPException fopex) { | |||||
log.error("Error setting FontState for characters: " + | |||||
fopex.getMessage()); | |||||
} | |||||
ti.lineHeight = this.lineHeight; | |||||
ColorType c = getProperty("color").getColorType(); | |||||
ti.color = c; | |||||
ti.verticalAlign = getProperty("vertical-align").getEnum(); | |||||
TextInfo ti = propMgr.getTextLayoutProps(fontInfo); | |||||
blm.setBlockTextInfo(ti); | blm.setBlockTextInfo(ti); | ||||
list.add(blm); | list.add(blm); | ||||
} | } |
package org.apache.fop.layout; | package org.apache.fop.layout; | ||||
/** | /** | ||||
* Store all hyphenation related properties on an FO. | |||||
* Store all inline "margin" related properties | |||||
* Public "structure" allows direct member access. | * Public "structure" allows direct member access. | ||||
*/ | */ | ||||
public class MarginInlineProps { | public class MarginInlineProps { | ||||
public int marginBottom; | public int marginBottom; | ||||
public int marginLeft; | public int marginLeft; | ||||
public int marginRight; | public int marginRight; | ||||
public int spaceBefore; | |||||
public int spaceAfter; | |||||
public int startIndent; | |||||
public int endIndent; | |||||
public int spaceStart; | |||||
public int spaceEnd; | |||||
public MarginInlineProps() {} | public MarginInlineProps() {} | ||||
public boolean generateAreas() { | public boolean generateAreas() { | ||||
ArrayList lms = new ArrayList(); | ArrayList lms = new ArrayList(); | ||||
LayoutManager lm = null; | LayoutManager lm = null; | ||||
FObj curFobj = fobj; | |||||
if (fobj != null) { | if (fobj != null) { | ||||
ListIterator children = fobj.getChildren(); | ListIterator children = fobj.getChildren(); | ||||
while (children.hasNext()) { | while (children.hasNext()) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
lm = new LineLayoutManager(inlines, lineHeight, lead, | |||||
lm = new LineLayoutManager(curFobj, inlines, lineHeight, lead, | |||||
follow); | follow); | ||||
// !!!! To test BreakPoss Line LayoutManager, uncomment! | |||||
/* | |||||
lm = new LineBPLayoutManager(curFobj, inlines, lineHeight, | |||||
lead, follow); | |||||
*/ | |||||
lms.set(count, lm); | lms.set(count, lm); | ||||
} | } | ||||
lm.setParentLM(this); | lm.setParentLM(this); |
protected MinOptMax resolveSpaceSpecifier(Area nextArea) { | protected MinOptMax resolveSpaceSpecifier(Area nextArea) { | ||||
SpaceSpecifier spaceSpec = new SpaceSpecifier(); | |||||
SpaceSpecifier spaceSpec = new SpaceSpecifier(false); | |||||
// Area prevArea = getCurrentArea().getLast(); | // Area prevArea = getCurrentArea().getLast(); | ||||
// if (prevArea != null) { | // if (prevArea != null) { | ||||
// spaceSpec.addSpace(prevArea.getSpaceAfter()); | // spaceSpec.addSpace(prevArea.getSpaceAfter()); | ||||
// } | // } | ||||
// spaceSpec.addSpace(nextArea.getSpaceBefore()); | // spaceSpec.addSpace(nextArea.getSpaceBefore()); | ||||
return spaceSpec.resolve(); | |||||
return spaceSpec.resolve(false); | |||||
} | } | ||||
/** | /** |
* | * | ||||
* How do we handle Unicode BIDI? | * How do we handle Unicode BIDI? | ||||
*/ | */ | ||||
public class LineLayoutManager extends AbstractLayoutManager { | |||||
public class LineLayoutManager extends AbstractBPLayoutManager { | |||||
private LineInfo currentLine = null; | private LineInfo currentLine = null; | ||||
private boolean bFirstLine = true; | private boolean bFirstLine = true; | ||||
private MinOptMax totalIPD; | private MinOptMax totalIPD; | ||||
// footnotes, floats? | // footnotes, floats? | ||||
} | } | ||||
public LineLayoutManager(List lms, int lh, int l, int f) { | |||||
super(null); | |||||
public LineLayoutManager(FObj fobjBlock, List lms, int lh, int l, int f) { | |||||
super(fobjBlock); | |||||
lmList = lms; | lmList = lms; | ||||
lineHeight = lh; | lineHeight = lh; | ||||
lead = l; | lead = l; | ||||
if (currentLine != null) { | if (currentLine != null) { | ||||
// Adjust spacing as necessary | // Adjust spacing as necessary | ||||
adjustSpacing(); | adjustSpacing(); | ||||
verticalAlign(); | |||||
verticalAlign(currentLine.area); | |||||
boolean res = parentLM.addChild(currentLine.area); | boolean res = parentLM.addChild(currentLine.area); | ||||
} | } | ||||
private void verticalAlign() { | |||||
protected void verticalAlign(LineArea lineArea) { | |||||
int maxHeight = lineHeight; | int maxHeight = lineHeight; | ||||
List inlineAreas = currentLine.area.getInlineAreas(); | |||||
List inlineAreas = lineArea.getInlineAreas(); | |||||
// get smallest possible offset to before edge | // get smallest possible offset to before edge | ||||
// this depends on the height of no and middle alignments | // this depends on the height of no and middle alignments | ||||
} | } | ||||
} | } | ||||
if (before + after > maxHeight) { | if (before + after > maxHeight) { | ||||
currentLine.area.setHeight(before + after); | |||||
lineArea.setHeight(before + after); | |||||
} else { | } else { | ||||
currentLine.area.setHeight(maxHeight); | |||||
lineArea.setHeight(maxHeight); | |||||
} | } | ||||
} | } | ||||
return currentLine.area; | return currentLine.area; | ||||
} | } | ||||
private void createLine() { | |||||
protected void createLine() { | |||||
currentLine = new LineInfo(); | currentLine = new LineInfo(); | ||||
currentLine.startPos = curPos; | currentLine.startPos = curPos; | ||||
currentLine.area = new LineArea(); | currentLine.area = new LineArea(); |
package org.apache.fop.layoutmgr; | package org.apache.fop.layoutmgr; | ||||
import org.apache.fop.area.Area; | |||||
import org.apache.fop.area.MinOptMax; | import org.apache.fop.area.MinOptMax; | ||||
import org.apache.fop.datatypes.Space; | |||||
import org.apache.fop.traits.SpaceVal; | |||||
import java.util.Vector; | |||||
/** | /** | ||||
* Accumulate a sequence of space-specifiers (XSL space type) on | * Accumulate a sequence of space-specifiers (XSL space type) on | ||||
*/ | */ | ||||
public class SpaceSpecifier { | public class SpaceSpecifier { | ||||
private boolean m_bStartsRefArea; | |||||
private boolean m_bHasForcing=false; | |||||
private Vector m_vecSpaceVals = new Vector(3); | |||||
public SpaceSpecifier(boolean bStartsRefArea) { | |||||
m_bStartsRefArea = bStartsRefArea; | |||||
} | |||||
/** | |||||
* Clear all space specifiers and fences. | |||||
*/ | |||||
public void clear() { | |||||
m_bHasForcing=false; | |||||
m_vecSpaceVals.clear(); | |||||
} | |||||
/** | |||||
* Add a new space to the sequence. If this sequence starts a reference | |||||
* area, and the added space is conditional, and there are no | |||||
* non-conditional values in the sequence yet, then ignore it. Otherwise | |||||
* add it to the sequence. | |||||
*/ | |||||
public void addSpace(SpaceVal moreSpace) { | |||||
if (!m_bStartsRefArea || !moreSpace.bConditional || | |||||
!m_vecSpaceVals.isEmpty()) { | |||||
if (moreSpace.bForcing) { | |||||
if (m_bHasForcing == false) { | |||||
// Remove all other values (must all be non-forcing) | |||||
// Back to the preceding fence | |||||
m_vecSpaceVals.clear(); | |||||
m_bHasForcing = true; | |||||
} | |||||
m_vecSpaceVals.add(moreSpace); | |||||
} | |||||
else if (m_bHasForcing==false) { | |||||
m_vecSpaceVals.add(moreSpace); | |||||
} | |||||
} | |||||
} | |||||
/** | /** | ||||
* Combine passed space property value with any existing space. | |||||
* Add a "fence" following or preceding any space-specifiers. | |||||
* Note that we always add specifiers to the sequence in the | |||||
* progression direction, either inline or block. | |||||
*/ | */ | ||||
public void addSpace(Space moreSpace) { | |||||
public void addFence() { | |||||
// Fence as first value clears m_bStartsRefArea | |||||
// Fence clears m_bHasForcing | |||||
} | } | ||||
public MinOptMax resolve() { | |||||
return new MinOptMax(); | |||||
/** | |||||
* Resolve the current sequence of space-specifiers, accounting for | |||||
* forcing values and "fence" behavior. | |||||
* @param bEndsReferenceArea True if the sequence should be resolved | |||||
* at the trailing edge of reference area. | |||||
* @return The resolved value as a min/opt/max triple. | |||||
*/ | |||||
public MinOptMax resolve(boolean bEndsReferenceArea) { | |||||
int lastIndex = m_vecSpaceVals.size(); | |||||
if (bEndsReferenceArea) { | |||||
// Start from the end and count conditional specifiers | |||||
// Stop at first non-conditional or first fence | |||||
for (; lastIndex > 0; --lastIndex) { | |||||
SpaceVal sval = | |||||
(SpaceVal)m_vecSpaceVals.elementAt(lastIndex-1); | |||||
if (!sval.bConditional) { | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
MinOptMax resSpace = new MinOptMax(0); | |||||
// Must calculate in sub-sequences delimited by fences! | |||||
int iMaxPrec = -1; | |||||
for(int index=0; index < lastIndex; index++) { | |||||
SpaceVal sval = (SpaceVal)m_vecSpaceVals.elementAt(index); | |||||
if (m_bHasForcing) { | |||||
resSpace.add(sval.space); | |||||
} | |||||
else if (sval.iPrecedence > iMaxPrec) { | |||||
iMaxPrec = sval.iPrecedence; | |||||
resSpace = sval.space; | |||||
} | |||||
else if (sval.iPrecedence == iMaxPrec) { | |||||
if (sval.space.opt > resSpace.opt) { | |||||
resSpace = sval.space; | |||||
} | |||||
else if (sval.space.opt == resSpace.opt) { | |||||
if (resSpace.min < sval.space.min) { | |||||
resSpace.min = sval.space.min; | |||||
} | |||||
if (resSpace.max > sval.space.max) { | |||||
resSpace.max = sval.space.max; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return resSpace; | |||||
} | } | ||||
} | } |
/* | |||||
* $Id$ | |||||
* Copyright (C) 2002 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.traits; | |||||
import org.apache.fop.datatypes.Length; | |||||
/** | |||||
* Store all block-level layout properties on an FO. | |||||
* Public "structure" allows direct member access. | |||||
*/ | |||||
public class BlockProps { | |||||
public int firstIndent; // text-indent | |||||
public int lastIndent; // last-line-indent | |||||
public int textAlign; | |||||
public int textAlignLast; | |||||
public int lineStackType; // line-stacking-strategy (enum) | |||||
public BlockProps() {} | |||||
} |
/* | |||||
* $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.traits; | |||||
/** | |||||
* Store all inline "margin" related properties | |||||
* Public "structure" allows direct member access. | |||||
*/ | |||||
public class InlineProps { | |||||
public int marginTop; | |||||
public int marginBottom; | |||||
public int marginLeft; | |||||
public int marginRight; | |||||
public SpaceVal spaceStart; | |||||
public SpaceVal spaceEnd; | |||||
public InlineProps() {} | |||||
} |
/* | |||||
* $Id$ | |||||
* Copyright (C) 2002 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.traits; | |||||
import org.apache.fop.datatypes.Length; | |||||
import org.apache.fop.fo.properties.Constants; | |||||
/** | |||||
* Store properties affecting layout: break-before, break-after, keeps, span. | |||||
* for a block level FO. | |||||
* Public "structure" allows direct member access. | |||||
*/ | |||||
public class LayoutProps { | |||||
public int breakBefore; // enum constant BreakBefore.xxx | |||||
public int breakAfter; // enum constant BreakAfter.xxx | |||||
public boolean bIsSpan; | |||||
public SpaceVal spaceBefore; | |||||
public SpaceVal spaceAfter; | |||||
private static final int[] s_breakPriorities = new int[] { | |||||
Constants.AUTO, Constants.COLUMN, Constants.PAGE }; | |||||
public LayoutProps() { | |||||
breakBefore = breakAfter = Constants.AUTO; | |||||
bIsSpan = false; | |||||
} | |||||
// public static int higherBreak(int brkParent, int brkChild) { | |||||
// if (brkParent == brkChild) return brkChild; | |||||
// for (int i=0; i < s_breakPriorities.length; i++) { | |||||
// int bp = s_breakPriorities[i]; | |||||
// if (bp == brkParent) return brkChild; | |||||
// else if (bp == brkChild) return brkParent; | |||||
// } | |||||
// return brkChild; | |||||
// } | |||||
public void combineWithParent(LayoutProps parentLP) { | |||||
if (parentLP.breakBefore != breakBefore) { | |||||
for (int i=0; i < s_breakPriorities.length; i++) { | |||||
int bp = s_breakPriorities[i]; | |||||
if (bp == breakBefore) { | |||||
breakBefore = parentLP.breakBefore; | |||||
break; | |||||
} | |||||
else if (bp == parentLP.breakBefore) break; | |||||
} | |||||
} | |||||
// Parent span always overrides child span | |||||
bIsSpan = parentLP.bIsSpan; | |||||
} | |||||
} |
/* | |||||
* $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.traits; | |||||
import org.apache.fop.datatypes.Space; | |||||
import org.apache.fop.area.MinOptMax; | |||||
import org.apache.fop.fo.Property; | |||||
import org.apache.fop.fo.properties.Constants; | |||||
/** | |||||
* Store a single Space property value in simplified form, with all | |||||
* Length values resolved. | |||||
*/ | |||||
public class SpaceVal { | |||||
public final MinOptMax space; | |||||
public final boolean bConditional; | |||||
public final boolean bForcing; | |||||
public final int iPrecedence; // Numeric only, if forcing, set to 0 | |||||
public SpaceVal(Space spaceprop) { | |||||
space = new MinOptMax( | |||||
spaceprop.getMinimum().getLength().mvalue(), | |||||
spaceprop.getOptimum().getLength().mvalue(), | |||||
spaceprop.getMaximum().getLength().mvalue()); | |||||
bConditional = (spaceprop.getConditionality().getEnum() == | |||||
Constants.DISCARD); | |||||
Property precProp = spaceprop.getPrecedence(); | |||||
if (precProp.getNumber() != null) { | |||||
iPrecedence = precProp.getNumber().intValue(); | |||||
bForcing = false; | |||||
} | |||||
else { | |||||
bForcing = (precProp.getEnum() == Constants.FORCE); | |||||
iPrecedence=0; | |||||
} | |||||
} | |||||
public SpaceVal(MinOptMax space, boolean bConditional, boolean bForcing, | |||||
int iPrecedence) { | |||||
this.space = space; | |||||
this.bConditional = bConditional; | |||||
this.bForcing = bForcing; | |||||
this.iPrecedence = iPrecedence; | |||||
} | |||||
} | |||||