/*
 * 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: AlignmentContext.java 1616312 2014-08-06 19:19:31Z gadams $ */

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.
/** * 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.
/** The height or BPD of this context. */
private int areaHeight;
The computed line-height property value applicable.
/** The computed line-height property value applicable. */
private int lineHeight;
The distance in BPD from the top of the box to the alignmentPoint.
/** The distance in BPD from the top of the box to the alignmentPoint. */
private int alignmentPoint;
The baseline shift value in effect.
/** The baseline shift value in effect. */
private int baselineShiftValue;
The computed alignment baseline identifier.
/** The computed alignment baseline identifier. */
private int alignmentBaselineIdentifier;
The x height.
/** The x height. */
private int xHeight; private ScaledBaselineTable scaledBaselineTable; private ScaledBaselineTable actualBaselineTable; private AlignmentContext parentAlignmentContext;
Creates a new instance of AlignmentContext for graphics areas.
Params:
  • height – the total height of the area
  • alignmentAdjust – the alignment-adjust property
  • alignmentBaseline – the alignment-baseline property
  • baselineShift – the baseline-shift property
  • dominantBaseline – the dominant-baseline property
  • parentAlignmentContext – the parent alignment context
/** * 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.
Params:
  • font – the font
  • lineHeight – the computed value of the lineHeight property
  • alignmentAdjust – the alignment-adjust property
  • alignmentBaseline – the alignment-baseline property
  • baselineShift – the baseline-shift property
  • dominantBaseline – the dominant-baseline property
  • parentAlignmentContext – the parent alignment context
/** * 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.
Params:
  • altitude – the altitude of the area
  • depth – the depth of the area
  • lineHeight – the line height
  • xHeight – the xHeight
  • alignmentAdjust – the alignment-adjust property
  • alignmentBaseline – the alignment-baseline property
  • baselineShift – the baseline-shift property
  • dominantBaseline – the dominant-baseline property
  • parentAlignmentContext – the parent alignment context
/** * 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.
Params:
  • font – the font
  • lineHeight – the computed value of the lineHeight property
  • writingMode – the current writing mode
/** * 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.
Returns:the default alignment point
/** * 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.
Returns:the baseline shift
/** * Returns the current value of baseline shift in effect. * @return the baseline shift */
public int getBaselineShiftValue() { return baselineShiftValue; }
Returns the current alignment baseline identifier.
Returns:the alignment baseline identifier
/** * 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.
Params:
  • alignmentBaseline – the alignment-baseline property
  • parentDominantBaselineIdentifier – the dominant baseline of the parent fo
/** * 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.
Params:
  • alignmentAdjust – the alignment-adjust property
/** * 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.
Returns:the scaled baseline table
/** * Return the scaled baseline table for this context. * @return the scaled baseline table */
private ScaledBaselineTable getScaledBaselineTable() { return this.scaledBaselineTable; }
Return the dominant baseline identifier.
Returns:the dominant baseline identifier
/** * 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.
Params:
  • baselineShift – the baseline shift property value
/** * 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.
Returns:the parent alignment context
/** * 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.
Returns:the offset in shift direction
/** * 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.
Returns:the offset in shift direction
/** * 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.
Returns:the offset in shift direction
/** * 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.
Params:
  • alignmentBaselineId – the alignment baseline
Returns:the offset
/** * 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.
Params:
  • baselineIdentifier – the baseline
Returns:the 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.
Returns:the 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.
Returns:the height
/** * Return the total height of the context. * @return the height */
public int getHeight() { return areaHeight; }
Return the line height of the context.
Returns:the height
/** * 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.
Returns:the altitude
/** * 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.
Returns:the altitude
/** * 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.
Returns:the x height
/** * 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.
Params:
  • newLineHeight – the new height of the line
  • newAlignmentPoint – the new alignment point
/** * 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.
Returns:the offset for rendering
/** * 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.
Returns:true if this is still the initial baseline table
/** * 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}
/** {@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(); } }