| /* |
| * 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.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.fop.datatypes.Length; |
| import org.apache.fop.datatypes.LengthBase; |
| import org.apache.fop.datatypes.SimplePercentBaseContext; |
| import org.apache.fop.fo.Constants; |
| |
| |
| /** |
| * An implementation of the ScaledBaselineTable interface which calculates |
| * all baselines given the height above and below the dominant baseline. |
| */ |
| public class BasicScaledBaselineTable implements ScaledBaselineTable, Constants { |
| |
| /** A logger for this class */ |
| protected Log log = LogFactory.getLog(BasicScaledBaselineTable.class); |
| |
| private int altitude; |
| private int depth; |
| private int xHeight; |
| private int dominantBaselineIdentifier; |
| private int writingMode; |
| private int dominantBaselineOffset; |
| private int beforeEdgeOffset; |
| private int afterEdgeOffset; |
| |
| private static final float HANGING_BASELINE_FACTOR = 0.8f; |
| private static final float MATHEMATICAL_BASELINE_FACTOR = 0.5f; |
| |
| /** |
| * |
| * Creates a new instance of BasicScaledBaselineTable for the given |
| * altitude, depth, xHeight, baseline and writingmode. |
| * @param altitude the height of the box or the font ascender |
| * @param depth the font descender or 0 |
| * @param xHeight the font xHeight |
| * @param dominantBaselineIdentifier the dominant baseline given as an integer constant |
| * @param writingMode the writing mode given as an integer constant |
| */ |
| public BasicScaledBaselineTable(int altitude |
| , int depth |
| , int xHeight |
| , int dominantBaselineIdentifier |
| , int writingMode) { |
| this.altitude = altitude; |
| this.depth = depth; |
| this.xHeight = xHeight; |
| this.dominantBaselineIdentifier = dominantBaselineIdentifier; |
| this.writingMode = writingMode; |
| this.dominantBaselineOffset = getBaselineDefaultOffset(this.dominantBaselineIdentifier); |
| this.beforeEdgeOffset = altitude - dominantBaselineOffset; |
| this.afterEdgeOffset = depth - dominantBaselineOffset; |
| } |
| |
| /** |
| * Return the dominant baseline for this baseline table. |
| * @return the dominant baseline |
| */ |
| public int getDominantBaselineIdentifier() { |
| return this.dominantBaselineIdentifier; |
| } |
| |
| /** |
| * Return the writing mode for this baseline table. |
| * @return the writing mode |
| */ |
| public int getWritingMode() { |
| return this.writingMode; |
| } |
| |
| /** |
| * Return the baseline offset measured from the dominant |
| * baseline for the given baseline. |
| * @param baselineIdentifier the baseline identifier |
| * @return the baseline offset |
| */ |
| public int getBaseline(int baselineIdentifier) { |
| int offset = 0; |
| if (!isHorizontalWritingMode()) { |
| switch (baselineIdentifier) { |
| case EN_TOP: |
| case EN_TEXT_TOP: |
| case EN_TEXT_BOTTOM: |
| case EN_BOTTOM: |
| log.warn("The given baseline is only supported for horizontal" |
| + " writing modes"); |
| return 0; |
| } |
| } |
| switch (baselineIdentifier) { |
| case EN_TOP: // fall through |
| case EN_BEFORE_EDGE: |
| offset = beforeEdgeOffset; |
| break; |
| case EN_TEXT_TOP: |
| case EN_TEXT_BEFORE_EDGE: |
| case EN_HANGING: |
| case EN_CENTRAL: |
| case EN_MIDDLE: |
| case EN_MATHEMATICAL: |
| case EN_ALPHABETIC: |
| case EN_IDEOGRAPHIC: |
| case EN_TEXT_BOTTOM: |
| case EN_TEXT_AFTER_EDGE: |
| offset = getBaselineDefaultOffset(baselineIdentifier) - dominantBaselineOffset; |
| break; |
| case EN_BOTTOM: // fall through |
| case EN_AFTER_EDGE: |
| offset = afterEdgeOffset; |
| break; |
| } |
| return offset; |
| } |
| |
| private boolean isHorizontalWritingMode() { |
| return writingMode == EN_LR_TB || writingMode == EN_RL_TB; |
| } |
| |
| /** |
| * Return the baseline offset measured from the font's default |
| * baseline for the given baseline. |
| * @param baselineIdentifier the baseline identifier |
| * @return the baseline offset |
| */ |
| private int getBaselineDefaultOffset(int baselineIdentifier) { |
| int offset = 0; |
| switch (baselineIdentifier) { |
| case EN_TEXT_BEFORE_EDGE: |
| offset = altitude; |
| break; |
| case EN_HANGING: |
| offset = (int)Math.round(altitude * HANGING_BASELINE_FACTOR); |
| break; |
| case EN_CENTRAL: |
| offset = (altitude - depth) / 2 + depth; |
| break; |
| case EN_MIDDLE: |
| offset = xHeight / 2; |
| break; |
| case EN_MATHEMATICAL: |
| offset = (int)Math.round(altitude * MATHEMATICAL_BASELINE_FACTOR); |
| break; |
| case EN_ALPHABETIC: |
| offset = 0; |
| break; |
| case EN_IDEOGRAPHIC: // Fall through |
| case EN_TEXT_AFTER_EDGE: |
| offset = depth; |
| break; |
| } |
| return offset; |
| } |
| |
| /** |
| * @see ScaledBaselineTable#setBeforeAndAfterBaselines(int, int) |
| */ |
| public void setBeforeAndAfterBaselines(int beforeBaseline, int afterBaseline) { |
| beforeEdgeOffset = beforeBaseline; |
| afterEdgeOffset = afterBaseline; |
| } |
| |
| /** |
| * @see ScaledBaselineTable#deriveScaledBaselineTable(int) |
| */ |
| public ScaledBaselineTable deriveScaledBaselineTable(int baselineIdentifier) { |
| BasicScaledBaselineTable bac |
| = new BasicScaledBaselineTable(altitude, depth, xHeight |
| , baselineIdentifier, this.writingMode); |
| return bac; |
| } |
| |
| } |