| /* |
| * Copyright 1999-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* $Id$ */ |
| |
| package org.apache.fop.layoutmgr; |
| |
| import org.apache.fop.fo.Constants; |
| import org.apache.fop.layoutmgr.inline.HyphContext; |
| import org.apache.fop.traits.MinOptMax; |
| |
| |
| /** |
| * This class is used to pass information to the getNextBreakPoss() |
| * method. It is set up by higher level LM and used by lower level LM. |
| */ |
| public class LayoutContext { |
| /** |
| * Values for flags. |
| */ |
| public static final int LINEBREAK_AT_LF_ONLY = 0x01; |
| /** Generated break possibility is first in a new area */ |
| public static final int NEW_AREA = 0x02; |
| public static final int IPD_UNKNOWN = 0x04; |
| /** Signal to a Line LM that a higher level LM may provoke a change |
| * in the reference area, thus ref area IPD. The LineLM should return |
| * without looking for a line break. |
| */ |
| public static final int CHECK_REF_AREA = 0x08; |
| |
| /** |
| * If this flag is set, it indicates that any leading fo:character |
| * objects with suppress-at-line-break="suppress" should not generate |
| * areas. This is the case at the beginning of each new LineArea |
| * except the first. |
| */ |
| public static final int SUPPRESS_LEADING_SPACE = 0x10; |
| public static final int FIRST_AREA = 0x20; |
| public static final int TRY_HYPHENATE = 0x40; |
| public static final int LAST_AREA = 0x80; |
| |
| public static final int RESOLVE_LEADING_SPACE = 0x100; |
| |
| /** |
| * This flag indicates that there's a keep-with-next that hasn't |
| * been processed, yet. |
| */ |
| public static final int KEEP_WITH_NEXT_PENDING = 0x200; |
| /** |
| * This flag indicates that there's a keep-with-previous that hasn't |
| * been processed, yet. |
| */ |
| public static final int KEEP_WITH_PREVIOUS_PENDING = 0x400; |
| |
| |
| public int flags; // Contains some set of flags defined above |
| /** |
| * Total available stacking dimension for a "galley-level" layout |
| * manager (Line or Flow). It is passed by the parent LM. For LineLM, |
| * the block LM determines this based on indent properties. |
| * These LM <b>may</b> wish to pass this information down to lower |
| * level LM to allow them to optimize returned break possibilities. |
| */ |
| MinOptMax stackLimit; |
| |
| /** True if current element list is spanning in multi-column layout. */ |
| private int nextSpan = Constants.NOT_SET; |
| |
| /** inline-progression-dimension of nearest ancestor reference area */ |
| int refIPD; |
| |
| /** Current pending space-after or space-end from preceding area */ |
| SpaceSpecifier trailingSpace; |
| |
| /** Current pending space-before or space-start from ancestor areas */ |
| SpaceSpecifier leadingSpace; |
| |
| /** Current hyphenation context. May be null. */ |
| private HyphContext hyphContext = null; |
| |
| /** Alignment in BP direction */ |
| private int bpAlignment = Constants.EN_START; |
| |
| /** Stretch or shrink value when making areas. */ |
| private double ipdAdjust = 0.0; |
| |
| /** Stretch or shrink value when adding spaces. */ |
| private double dSpaceAdjust = 0.0; |
| |
| private int iLineHeight; |
| private int iBaseline; |
| private int iMiddleShift; |
| private int iTopShift; /*LF*/ |
| private int iBottomShift; /*LF*/ |
| private int iSpaceBefore; /*LF*/ |
| private int iSpaceAfter; /*LF*/ |
| |
| public LayoutContext(LayoutContext parentLC) { |
| this.flags = parentLC.flags; |
| this.refIPD = parentLC.refIPD; |
| this.stackLimit = null; // Don't reference parent MinOptMax! |
| this.leadingSpace = parentLC.leadingSpace; //??? |
| this.trailingSpace = parentLC.trailingSpace; //??? |
| this.hyphContext = parentLC.hyphContext; |
| this.bpAlignment = parentLC.bpAlignment; |
| this.dSpaceAdjust = parentLC.dSpaceAdjust; |
| this.ipdAdjust = parentLC.ipdAdjust; |
| this.iLineHeight = parentLC.iLineHeight; |
| this.iBaseline = parentLC.iBaseline; |
| this.iMiddleShift = parentLC.iMiddleShift; |
| /*LF*/ this.iTopShift = parentLC.iTopShift; |
| /*LF*/ this.iBottomShift = parentLC.iBottomShift; |
| /*LF*/ this.iSpaceBefore = parentLC.iSpaceBefore; |
| /*LF*/ this.iSpaceAfter = parentLC.iSpaceAfter; |
| // Copy other fields as necessary. Use clone??? |
| } |
| |
| public LayoutContext(int flags) { |
| this.flags = flags; |
| this.refIPD = 0; |
| stackLimit = new MinOptMax(0); |
| leadingSpace = null; |
| trailingSpace = null; |
| } |
| |
| public void setFlags(int flags) { |
| setFlags(flags, true); |
| } |
| |
| public void setFlags(int flags, boolean bSet) { |
| if (bSet) { |
| this.flags |= flags; |
| } else { |
| this.flags &= ~flags; |
| } |
| } |
| |
| public void unsetFlags(int flags) { |
| setFlags(flags, false); |
| } |
| |
| public boolean isStart() { |
| return ((this.flags & NEW_AREA) != 0); |
| } |
| |
| public boolean startsNewArea() { |
| return ((this.flags & NEW_AREA) != 0 && leadingSpace != null); |
| } |
| |
| public boolean isFirstArea() { |
| return ((this.flags & FIRST_AREA) != 0); |
| } |
| |
| public boolean isLastArea() { |
| return ((this.flags & LAST_AREA) != 0); |
| } |
| |
| public boolean suppressLeadingSpace() { |
| return ((this.flags & SUPPRESS_LEADING_SPACE) != 0); |
| } |
| |
| public boolean isKeepWithNextPending() { |
| return ((this.flags & KEEP_WITH_NEXT_PENDING) != 0); |
| } |
| |
| public boolean isKeepWithPreviousPending() { |
| return ((this.flags & KEEP_WITH_PREVIOUS_PENDING) != 0); |
| } |
| |
| public void setLeadingSpace(SpaceSpecifier space) { |
| leadingSpace = space; |
| } |
| |
| public SpaceSpecifier getLeadingSpace() { |
| return leadingSpace; |
| } |
| |
| public boolean resolveLeadingSpace() { |
| return ((this.flags & RESOLVE_LEADING_SPACE) != 0); |
| } |
| |
| public void setTrailingSpace(SpaceSpecifier space) { |
| trailingSpace = space; |
| } |
| |
| public SpaceSpecifier getTrailingSpace() { |
| return trailingSpace; |
| } |
| |
| public void setStackLimit(MinOptMax limit) { |
| stackLimit = limit; |
| } |
| |
| public MinOptMax getStackLimit() { |
| return stackLimit; |
| } |
| |
| public void setRefIPD(int ipd) { |
| refIPD = ipd; |
| } |
| |
| public int getRefIPD() { |
| return refIPD; |
| } |
| |
| public void setHyphContext(HyphContext hyph) { |
| hyphContext = hyph; |
| } |
| |
| public HyphContext getHyphContext() { |
| return hyphContext; |
| } |
| |
| public boolean tryHyphenate() { |
| return ((this.flags & TRY_HYPHENATE) != 0); |
| } |
| |
| /** |
| * Sets the currently applicable alignment in BP direction. |
| * @param alignment one of EN_START, EN_JUSTIFY etc. |
| */ |
| public void setBPAlignment(int alignment) { |
| this.bpAlignment = alignment; |
| } |
| |
| /** @return the currently applicable alignment in BP direction (EN_START, EN_JUSTIFY...) */ |
| public int getBPAlignment() { |
| return this.bpAlignment; |
| } |
| |
| public void setSpaceAdjust(double adjust) { |
| dSpaceAdjust = adjust; |
| } |
| |
| public double getSpaceAdjust() { |
| return dSpaceAdjust; |
| } |
| |
| public void setIPDAdjust(double ipdA) { |
| ipdAdjust = ipdA; |
| } |
| |
| public double getIPDAdjust() { |
| return ipdAdjust; |
| } |
| |
| public void setLineHeight(int lh) { |
| iLineHeight = lh; |
| } |
| |
| public int getLineHeight() { |
| return iLineHeight; |
| } |
| |
| public void setBaseline(int bl) { |
| iBaseline = bl; |
| } |
| |
| public int getBaseline() { |
| return iBaseline; |
| } |
| |
| public void setMiddleShift(int ms) { |
| iMiddleShift = ms; |
| } |
| |
| public int getMiddleBaseline() { |
| return iBaseline + iMiddleShift; |
| } |
| |
| public void setTopShift(int ts) { |
| iTopShift = ts; |
| } |
| |
| public int getTopBaseline() { |
| return iBaseline + iTopShift; |
| } |
| |
| public void setBottomShift(int bs) { |
| iBottomShift = bs; |
| } |
| |
| public int getBottomBaseline() { |
| return iBaseline + iBottomShift; |
| } |
| |
| public int getSpaceBefore() { |
| return iSpaceBefore; |
| } |
| |
| public void setSpaceBefore(int sp) { |
| iSpaceBefore = sp; |
| } |
| |
| public int getSpaceAfter() { |
| return iSpaceAfter; |
| } |
| |
| public void setSpaceAfter(int sp) { |
| iSpaceAfter = sp; |
| } |
| |
| /** |
| * @return true if the current element list ends early because of a span change |
| * in multi-column layout. |
| */ |
| public int getNextSpan() { |
| return nextSpan; |
| } |
| |
| /** |
| * Used to signal the PSLM that the element list ends early because of a span change in |
| * multi-column layout. |
| * @param span the new span value (legal values: NOT_SET, EN_NONE, EN_ALL) |
| */ |
| public void signalSpanChange(int span) { |
| if (span == Constants.NOT_SET || span == Constants.EN_NONE || span == Constants.EN_ALL) { |
| this.nextSpan = span; |
| } else { |
| throw new IllegalArgumentException("Illegal value on signalSpanChange() for span: " |
| + span); |
| } |
| } |
| |
| /** @see java.lang.Object#toString() */ |
| public String toString() { |
| return "Layout Context:" + |
| "\nStack Limit: \t" + (getStackLimit() == null ? "null" : getStackLimit().toString()) + |
| "\nTrailing Space: \t" + (getTrailingSpace() == null ? "null" : getTrailingSpace().toString()) + |
| "\nLeading Space: \t" + (getLeadingSpace() == null ? "null" : getLeadingSpace().toString()) + |
| "\nReference IPD: \t" + getRefIPD() + |
| "\nSpace Adjust: \t" + getSpaceAdjust() + |
| "\nIPD Adjust: \t" + getIPDAdjust() + |
| "\nLine Height: \t" + getLineHeight() + |
| "\nBaseline: \t" + getBaseline() + |
| "\nMiddle Baseline: \t" + getMiddleBaseline() + |
| "\nResolve Leading Space: \t" + resolveLeadingSpace() + |
| "\nSuppress Leading Space: \t" + suppressLeadingSpace() + |
| "\nIs First Area: \t" + isFirstArea() + |
| "\nStarts New Area: \t" + startsNewArea() + |
| "\nIs Last Area: \t" + isLastArea() + |
| "\nTry Hyphenate: \t" + tryHyphenate() + |
| "\nKeeps: \t[" + (isKeepWithNextPending()?"keep-with-next":"") + "][" |
| + (isKeepWithPreviousPending()?"keep-with-previous":"") + "] pending"; |
| } |
| } |
| |