123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /*
- * 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.fo.Constants;
- import org.apache.fop.traits.WritingMode;
-
-
- /**
- * The FOP specific incarnation of the XSL-FO scaled baseline table.
- * All baseline tables are scaled to the font size of the font they
- * apply to. This class uses a coordinate system with its origin
- * where the dominant baseline intersects the start edge of the box.
- * All measurements are in mpt.
- */
- final class ScaledBaselineTable {
-
- private static final float HANGING_BASELINE_FACTOR = 0.8f;
-
- private static final float MATHEMATICAL_BASELINE_FACTOR = 0.5f;
-
- private final int altitude;
-
- private final int depth;
-
- private final int xHeight;
-
- private final int dominantBaselineIdentifier;
-
- private final WritingMode writingMode;
-
- private final int dominantBaselineOffset;
-
- private int beforeEdgeOffset;
-
- private int afterEdgeOffset;
-
-
- /**
- *
- * Creates a new instance of BasicScaledBaselineTable for the given
- * altitude, depth, xHeight, baseline and writing mode.
- * @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
- */
- ScaledBaselineTable(int altitude,
- int depth,
- int xHeight,
- int dominantBaselineIdentifier,
- WritingMode 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
- */
- int getDominantBaselineIdentifier() {
- return this.dominantBaselineIdentifier;
- }
-
- /**
- * Return the writing mode for this baseline table.
- * @return the writing mode
- */
- WritingMode getWritingMode() {
- return this.writingMode;
- }
-
- /**
- * Return the offset of the given baseline from the dominant baseline.
- *
- * @param baselineIdentifier a baseline identifier
- * @return the offset from the dominant baseline
- */
- int getBaseline(int baselineIdentifier) {
- int offset = 0;
- if (!isHorizontalWritingMode()) {
- switch (baselineIdentifier) {
- case Constants.EN_TOP:
- case Constants.EN_TEXT_TOP:
- case Constants.EN_TEXT_BOTTOM:
- case Constants.EN_BOTTOM:
- throw new IllegalArgumentException("Baseline " + baselineIdentifier
- + " only supported for horizontal writing modes");
- default: // TODO
- }
- }
- switch (baselineIdentifier) {
- case Constants.EN_TOP: // fall through
- case Constants.EN_BEFORE_EDGE:
- offset = beforeEdgeOffset;
- break;
- case Constants.EN_TEXT_TOP:
- case Constants.EN_TEXT_BEFORE_EDGE:
- case Constants.EN_HANGING:
- case Constants.EN_CENTRAL:
- case Constants.EN_MIDDLE:
- case Constants.EN_MATHEMATICAL:
- case Constants.EN_ALPHABETIC:
- case Constants.EN_IDEOGRAPHIC:
- case Constants.EN_TEXT_BOTTOM:
- case Constants.EN_TEXT_AFTER_EDGE:
- offset = getBaselineDefaultOffset(baselineIdentifier) - dominantBaselineOffset;
- break;
- case Constants.EN_BOTTOM: // fall through
- case Constants.EN_AFTER_EDGE:
- offset = afterEdgeOffset;
- break;
- default: throw new IllegalArgumentException(String.valueOf(baselineIdentifier));
- }
- return offset;
- }
-
- private boolean isHorizontalWritingMode() {
- return writingMode.isHorizontal();
- }
-
- /**
- * 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 Constants.EN_TEXT_BEFORE_EDGE:
- offset = altitude;
- break;
- case Constants.EN_HANGING:
- offset = Math.round(altitude * HANGING_BASELINE_FACTOR);
- break;
- case Constants.EN_CENTRAL:
- offset = (altitude - depth) / 2 + depth;
- break;
- case Constants.EN_MIDDLE:
- offset = xHeight / 2;
- break;
- case Constants.EN_MATHEMATICAL:
- offset = Math.round(altitude * MATHEMATICAL_BASELINE_FACTOR);
- break;
- case Constants.EN_ALPHABETIC:
- offset = 0;
- break;
- case Constants.EN_IDEOGRAPHIC: // Fall through
- case Constants.EN_TEXT_AFTER_EDGE:
- offset = depth;
- break;
- default: throw new IllegalArgumentException(String.valueOf(baselineIdentifier));
- }
- return offset;
- }
-
- /**
- * Sets the position of the before and after baselines.
- * This is usually only done for line areas. For other
- * areas the position of the before and after baselines
- * are fixed when the table is constructed.
- * @param beforeBaseline the offset of the before-edge baseline from the dominant baseline
- * @param afterBaseline the offset of the after-edge baseline from the dominant baseline
- */
- void setBeforeAndAfterBaselines(int beforeBaseline, int afterBaseline) {
- beforeEdgeOffset = beforeBaseline;
- afterEdgeOffset = afterBaseline;
- }
-
- /**
- * Return a new baseline table for the given baseline based
- * on the current baseline table.
- * @param baselineIdentifier the baseline identifer
- * @return a new baseline with the new baseline
- */
- ScaledBaselineTable deriveScaledBaselineTable(int baselineIdentifier) {
- ScaledBaselineTable bac = new ScaledBaselineTable(altitude, depth, xHeight,
- baselineIdentifier, this.writingMode);
- return bac;
- }
-
- }
|