123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.inline;
-
- import org.apache.fop.datatypes.Length;
- import org.apache.fop.datatypes.LengthBase;
- import org.apache.fop.datatypes.SimplePercentBaseContext;
- import org.apache.fop.fo.Constants;
- import org.apache.fop.fonts.Font;
- import org.apache.fop.traits.WritingMode;
-
- /**
- * The alignment context is carried within a LayoutContext and as
- * part of the Knuth Inline elements to facilitate proper line building.
- * All measurements are in mpt.
- */
- public class AlignmentContext implements Constants {
-
- /** The height or BPD of this context. */
- private int areaHeight;
-
- /** The computed line-height property value applicable. */
- private int lineHeight;
-
- /** The distance in BPD from the top of the box to the alignmentPoint. */
- private int alignmentPoint;
-
- /** The baseline shift value in effect. */
- private int baselineShiftValue;
-
- /** The computed alignment baseline identifier. */
- private int alignmentBaselineIdentifier;
-
- /** The x height. */
- private int xHeight;
-
- private ScaledBaselineTable scaledBaselineTable;
- private ScaledBaselineTable actualBaselineTable;
- private AlignmentContext parentAlignmentContext;
-
- /**
- * Creates a new instance of AlignmentContext
- * for graphics areas.
- * @param height the total height of the area
- * @param alignmentAdjust the alignment-adjust property
- * @param alignmentBaseline the alignment-baseline property
- * @param baselineShift the baseline-shift property
- * @param dominantBaseline the dominant-baseline property
- * @param parentAlignmentContext the parent alignment context
- */
- AlignmentContext(int height,
- Length alignmentAdjust,
- int alignmentBaseline,
- Length baselineShift,
- int dominantBaseline,
- AlignmentContext parentAlignmentContext) {
-
- this(height, 0, height, height, alignmentAdjust, alignmentBaseline, baselineShift,
- dominantBaseline, parentAlignmentContext);
- }
-
- /**
- * Creates a new instance.
- *
- * @param font the font
- * @param lineHeight the computed value of the lineHeight property
- * @param alignmentAdjust the alignment-adjust property
- * @param alignmentBaseline the alignment-baseline property
- * @param baselineShift the baseline-shift property
- * @param dominantBaseline the dominant-baseline property
- * @param parentAlignmentContext the parent alignment context
- */
- AlignmentContext(Font font,
- int lineHeight,
- Length alignmentAdjust,
- int alignmentBaseline,
- Length baselineShift,
- int dominantBaseline,
- AlignmentContext parentAlignmentContext) {
- this(font.getAscender(), font.getDescender(), lineHeight, font.getXHeight(),
- alignmentAdjust, alignmentBaseline, baselineShift, dominantBaseline,
- parentAlignmentContext);
- }
-
- /**
- * Creates a new instance of AlignmentContext.
- * @param altitude the altitude of the area
- * @param depth the depth of the area
- * @param lineHeight the line height
- * @param xHeight the xHeight
- * @param alignmentAdjust the alignment-adjust property
- * @param alignmentBaseline the alignment-baseline property
- * @param baselineShift the baseline-shift property
- * @param dominantBaseline the dominant-baseline property
- * @param parentAlignmentContext the parent alignment context
- */
- private AlignmentContext(int altitude,
- int depth,
- int lineHeight,
- int xHeight,
- Length alignmentAdjust,
- int alignmentBaseline,
- Length baselineShift,
- int dominantBaseline,
- AlignmentContext parentAlignmentContext) {
-
- this.areaHeight = altitude - depth;
- this.lineHeight = lineHeight;
- this.xHeight = xHeight;
- this.parentAlignmentContext = parentAlignmentContext;
- this.scaledBaselineTable = parentAlignmentContext.getScaledBaselineTable();
- setAlignmentBaselineIdentifier(alignmentBaseline
- , parentAlignmentContext.getDominantBaselineIdentifier());
- setBaselineShift(baselineShift);
- int dominantBaselineIdentifier = parentAlignmentContext.getDominantBaselineIdentifier();
- boolean newScaledBaselineTableRequired = false;
- if (baselineShiftValue != 0) {
- newScaledBaselineTableRequired = true;
- }
- switch (dominantBaseline) {
- case EN_AUTO:
- newScaledBaselineTableRequired = baselineShiftValue != 0;
- break;
- case EN_USE_SCRIPT: // TODO
- break;
- case EN_NO_CHANGE:
- break;
- case EN_RESET_SIZE:
- newScaledBaselineTableRequired = true;
- break;
- default:
- newScaledBaselineTableRequired = true;
- dominantBaselineIdentifier = dominantBaseline;
- break;
- }
- actualBaselineTable = new ScaledBaselineTable(
- altitude,
- depth,
- xHeight,
- dominantBaselineIdentifier,
- scaledBaselineTable.getWritingMode());
- if (newScaledBaselineTableRequired) {
- scaledBaselineTable = new ScaledBaselineTable(
- altitude,
- depth,
- xHeight,
- dominantBaselineIdentifier,
- scaledBaselineTable.getWritingMode());
- }
- setAlignmentAdjust(alignmentAdjust);
- }
-
- /**
- * Creates a new instance of AlignmentContext based simply
- * on the font and the writing mode.
- * @param font the font
- * @param lineHeight the computed value of the lineHeight property
- * @param writingMode the current writing mode
- */
- AlignmentContext(Font font, int lineHeight, WritingMode writingMode) {
- this.areaHeight = font.getAscender() - font.getDescender();
- this.lineHeight = lineHeight;
- this.xHeight = font.getXHeight();
- this.scaledBaselineTable = new ScaledBaselineTable(font.getAscender(), font.getDescender(),
- font.getXHeight(), Constants.EN_ALPHABETIC, writingMode);
- this.actualBaselineTable = scaledBaselineTable;
- this.alignmentBaselineIdentifier = getDominantBaselineIdentifier();
- this.alignmentPoint = font.getAscender();
- this.baselineShiftValue = 0;
- }
-
- /**
- * Returns the alignment point for this context.
- * This is the point on the start edge of the area this context
- * applies to measured from the before edge of the area.
- * @return the default alignment point
- */
- public int getAlignmentPoint() {
- return alignmentPoint;
- }
-
- /**
- * Returns the current value of baseline shift in effect.
- * @return the baseline shift
- */
- public int getBaselineShiftValue() {
- return baselineShiftValue;
- }
-
- /**
- * Returns the current alignment baseline identifier.
- *
- * @return the alignment baseline identifier
- */
- public int getAlignmentBaselineIdentifier() {
- return alignmentBaselineIdentifier;
- }
-
- /**
- * Sets the current alignment baseline identifier. For
- * alignment-baseline values of "auto" and "baseline" this
- * method does the conversion into the appropriate computed
- * value assuming script is "auto" and the fo is not fo:character.
- * @param alignmentBaseline the alignment-baseline property
- * @param parentDominantBaselineIdentifier the dominant baseline of the parent fo
- */
- private void setAlignmentBaselineIdentifier(int alignmentBaseline
- , int parentDominantBaselineIdentifier) {
- switch (alignmentBaseline) {
- case EN_AUTO: // fall through
- case EN_BASELINE:
- this.alignmentBaselineIdentifier = parentDominantBaselineIdentifier;
- break;
- case EN_BEFORE_EDGE:
- case EN_TEXT_BEFORE_EDGE:
- case EN_CENTRAL:
- case EN_MIDDLE:
- case EN_AFTER_EDGE:
- case EN_TEXT_AFTER_EDGE:
- case EN_IDEOGRAPHIC:
- case EN_ALPHABETIC:
- case EN_HANGING:
- case EN_MATHEMATICAL:
- this.alignmentBaselineIdentifier = alignmentBaseline;
- break;
- default: throw new IllegalArgumentException(String.valueOf(alignmentBaseline));
- }
- }
-
- /**
- * Sets the current alignment baseline identifer. For
- * alignment-baseline values of "auto" and "baseline" this
- * method does the conversion into the appropriate computed
- * value assuming script is "auto" and the fo is not fo:character.
- * @param alignmentAdjust the alignment-adjust property
- */
- private void setAlignmentAdjust(Length alignmentAdjust) {
- int beforeEdge = actualBaselineTable.getBaseline(EN_BEFORE_EDGE);
- switch (alignmentAdjust.getEnum()) {
- case EN_AUTO:
- alignmentPoint = beforeEdge
- - actualBaselineTable.getBaseline(alignmentBaselineIdentifier);
- break;
- case EN_BASELINE:
- alignmentPoint = beforeEdge;
- break;
- case EN_BEFORE_EDGE:
- case EN_TEXT_BEFORE_EDGE:
- case EN_CENTRAL:
- case EN_MIDDLE:
- case EN_AFTER_EDGE:
- case EN_TEXT_AFTER_EDGE:
- case EN_IDEOGRAPHIC:
- case EN_ALPHABETIC:
- case EN_HANGING:
- case EN_MATHEMATICAL:
- alignmentPoint = beforeEdge
- - actualBaselineTable.getBaseline(alignmentAdjust.getEnum());
- break;
- default:
- alignmentPoint = beforeEdge
- + alignmentAdjust.getValue(new SimplePercentBaseContext(null
- , LengthBase.ALIGNMENT_ADJUST
- , lineHeight));
- break;
- }
- }
-
- /**
- * Return the scaled baseline table for this context.
- * @return the scaled baseline table
- */
- private ScaledBaselineTable getScaledBaselineTable() {
- return this.scaledBaselineTable;
- }
-
- /**
- * Return the dominant baseline identifier.
- * @return the dominant baseline identifier
- */
- public int getDominantBaselineIdentifier() {
- return actualBaselineTable.getDominantBaselineIdentifier();
- }
-
- /**
- * Return the writing mode.
- * @return the writing mode
- */
- /* public WritingMode getWritingMode() {
- return scaledBaselineTable.getWritingMode();
- }*/
-
- /**
- * Calculates the baseline shift value based on the baseline-shift
- * property value.
- * @param baselineShift the baseline shift property value
- */
- private void setBaselineShift(Length baselineShift) {
- baselineShiftValue = 0;
- switch (baselineShift.getEnum()) {
- case EN_BASELINE: //Nothing to do
- break;
- case EN_SUB:
- baselineShiftValue = Math.round(-((float)xHeight / 2)
- + (float)parentAlignmentContext.getActualBaselineOffset(EN_ALPHABETIC)
- );
- break;
- case EN_SUPER:
- baselineShiftValue = Math.round((float)parentAlignmentContext.getXHeight()
- + (float)parentAlignmentContext.getActualBaselineOffset(EN_ALPHABETIC)
- );
- break;
- case 0: // A <length> or <percentage> value
- baselineShiftValue = baselineShift.getValue(
- new SimplePercentBaseContext(null
- , LengthBase.CUSTOM_BASE
- , parentAlignmentContext.getLineHeight()));
- break;
- default: throw new IllegalArgumentException(String.valueOf(baselineShift.getEnum()));
- }
- }
-
- /**
- * Return the parent alignment context.
- * @return the parent alignment context
- */
- public AlignmentContext getParentAlignmentContext() {
- return parentAlignmentContext;
- }
-
- /**
- * Return the offset between the current dominant baseline and
- * the parent dominant baseline.
- * @return the offset in shift direction
- */
- private int getBaselineOffset() {
- if (parentAlignmentContext == null) {
- return 0;
- }
- return parentAlignmentContext.getScaledBaselineTable()
- .getBaseline(alignmentBaselineIdentifier)
- - scaledBaselineTable
- .deriveScaledBaselineTable(parentAlignmentContext
- .getDominantBaselineIdentifier())
- .getBaseline(alignmentBaselineIdentifier)
- - scaledBaselineTable
- .getBaseline(parentAlignmentContext
- .getDominantBaselineIdentifier())
- + baselineShiftValue;
- }
-
- /**
- * Return the offset between the current dominant baseline and
- * the outermost parent dominant baseline.
- * @return the offset in shift direction
- */
- private int getTotalBaselineOffset() {
- int offset = 0;
- if (parentAlignmentContext != null) {
- offset = getBaselineOffset() + parentAlignmentContext.getTotalBaselineOffset();
- }
- return offset;
- }
-
- /**
- * Return the offset between the alignment baseline and
- * the outermost parent dominant baseline.
- * @return the offset in shift direction
- */
- public int getTotalAlignmentBaselineOffset() {
- return getTotalAlignmentBaselineOffset(alignmentBaselineIdentifier);
- }
-
- /**
- * Return the offset between the given alignment baseline and
- * the outermost parent dominant baseline.
- * @param alignmentBaselineId the alignment baseline
- * @return the offset
- */
- private int getTotalAlignmentBaselineOffset(int alignmentBaselineId) {
- int offset = baselineShiftValue;
- if (parentAlignmentContext != null) {
- offset = parentAlignmentContext.getTotalBaselineOffset()
- + parentAlignmentContext.getScaledBaselineTable()
- .getBaseline(alignmentBaselineId)
- + baselineShiftValue;
- }
- return offset;
- }
-
- /**
- * Return the offset between the dominant baseline and
- * the given actual baseline.
- *
- * @param baselineIdentifier the baseline
- * @return the offset
- */
- private int getActualBaselineOffset(int baselineIdentifier) {
- // This is the offset from the dominant baseline to the alignment baseline
- int offset = getTotalAlignmentBaselineOffset() - getTotalBaselineOffset();
- // Add the offset to the actual baseline we want
- offset += actualBaselineTable.deriveScaledBaselineTable(alignmentBaselineIdentifier)
- .getBaseline(baselineIdentifier);
- return offset;
- }
-
- /**
- * Return the offset the outermost parent dominant baseline
- * and the top of this box.
- * @return the offset
- */
- private int getTotalTopOffset() {
- int offset = getTotalAlignmentBaselineOffset() + getAltitude();
- return offset;
- }
-
- /**
- * Return the total height of the context.
- * @return the height
- */
- public int getHeight() {
- return areaHeight;
- }
-
- /**
- * Return the line height of the context.
- * @return the height
- */
- private int getLineHeight() {
- return lineHeight;
- }
-
- /**
- * The altitude of the context that is the height above the
- * alignment point.
- * @return the altitude
- */
- public int getAltitude() {
- return alignmentPoint;
- }
-
- /**
- * The depth of the context that is the height below
- * alignment point.
- * @return the altitude
- */
- public int getDepth() {
- return getHeight() - alignmentPoint;
- }
-
- /**
- * The x height of the context.
- * @return the x height
- */
- private int getXHeight() {
- return this.xHeight;
- }
-
- /**
- * Resizes the line as specified. Assumes that the new alignment point
- * is on the dominant baseline, that is this function should be called for
- * line areas only.
- * @param newLineHeight the new height of the line
- * @param newAlignmentPoint the new alignment point
- */
- public void resizeLine(int newLineHeight, int newAlignmentPoint) {
- areaHeight = newLineHeight;
- alignmentPoint = newAlignmentPoint;
- scaledBaselineTable.setBeforeAndAfterBaselines(alignmentPoint
- , alignmentPoint - areaHeight);
- }
-
- /**
- * Returns the offset from the before-edge of the parent to
- * this context.
- * @return the offset for rendering
- */
- public int getOffset() {
- int offset = 0;
- if (parentAlignmentContext != null) {
- offset = parentAlignmentContext.getTotalTopOffset() - getTotalTopOffset();
- } else {
- offset = getAltitude() - scaledBaselineTable.getBaseline(EN_TEXT_BEFORE_EDGE);
- }
- return offset;
- }
-
- /**
- * Returns an indication if we still use the initial baseline table.
- * The initial baseline table is the table generated by the Line LM.
- * @return true if this is still the initial baseline table
- */
- public boolean usesInitialBaselineTable() {
- return parentAlignmentContext == null
- || (scaledBaselineTable == parentAlignmentContext.getScaledBaselineTable()
- && parentAlignmentContext.usesInitialBaselineTable());
- }
-
- /* private boolean isHorizontalWritingMode() {
- return (getWritingMode() == WritingMode.LR_TB || getWritingMode() == WritingMode.RL_TB);
- }*/
-
- /** {@inheritDoc} */
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append("areaHeight=").append(areaHeight);
- sb.append(" lineHeight=").append(lineHeight);
- sb.append(" alignmentPoint=").append(alignmentPoint);
- sb.append(" alignmentBaselineID=").append(alignmentBaselineIdentifier);
- sb.append(" baselineShift=").append(baselineShiftValue);
- return sb.toString();
- }
-
- }
|