123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- /*
- * 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.area.inline;
-
- import java.io.Serializable;
- import java.util.List;
-
- import org.apache.fop.area.Area;
- import org.apache.fop.area.LineArea;
- import org.apache.fop.area.Trait;
- import org.apache.fop.complexscripts.bidi.InlineRun;
-
- /**
- * Inline Area
- * This area is for all inline areas that can be placed
- * in a line area.
- */
- public class InlineArea extends Area {
-
- private static final long serialVersionUID = -8940066479810170980L;
-
- /**
- * this class stores information about potential adjustments
- * that can be used in order to re-compute adjustments when a
- * page-number or a page-number-citation is resolved
- */
- protected class InlineAdjustingInfo implements Serializable {
-
- private static final long serialVersionUID = -5601387735459712149L;
-
- /** stretch of the inline area */
- protected int availableStretch;
- /** shrink of the inline area */
- protected int availableShrink;
- /** total adjustment (= ipd - width of fixed elements) */
- protected int adjustment;
-
- /**
- * Constructor
- *
- * @param stretch the available space for stretching
- * @param shrink the available space for shrinking
- * @param adj space adjustment type
- */
- protected InlineAdjustingInfo(int stretch, int shrink, int adj) {
- availableStretch = stretch;
- availableShrink = shrink;
- adjustment = adj;
- }
-
- /**
- * Apply the variation factor
- *
- * @param variationFactor the factor by which the adjustment is to be changed
- * @return the IPD increase
- */
- protected int applyVariationFactor(double variationFactor) {
- int oldAdjustment = adjustment;
- adjustment *= variationFactor;
- return adjustment - oldAdjustment;
- }
- }
-
- /**
- * offset position from before edge of parent area
- */
- protected int blockProgressionOffset;
-
- /**
- * parent area
- * it is needed in order to recompute adjust ratio and indents
- * when a page-number or a page-number-citation is resolved
- */
- private Area parentArea;
-
- /**
- * ipd variation of child areas: if this area has not already
- * been added and cannot notify its parent area, store the variation
- * and wait for the parent area to be set
- */
- private int storedIPDVariation;
-
- /**
- * The adjustment information object
- */
- protected InlineAdjustingInfo adjustingInfo;
-
- /**
- * Default constructor for inline area.
- */
- public InlineArea() {
- this (0, -1);
- }
-
- /**
- * Instantiate inline area.
- * @param blockProgressionOffset a block progression offset or zero
- * @param bidiLevel a resolved bidi level or -1
- */
- protected InlineArea(int blockProgressionOffset, int bidiLevel) {
- this.blockProgressionOffset = blockProgressionOffset;
- setBidiLevel(bidiLevel);
- }
-
- /**
- * @return the adjustment information object
- */
- public InlineAdjustingInfo getAdjustingInfo() {
- return adjustingInfo;
- }
-
- /**
- * Create a new adjustment information object
- * @param stretch the available space for stretching
- * @param shrink the available space for shrinking
- * @param adjustment space adjustment type
- */
- public void setAdjustingInfo(int stretch, int shrink, int adjustment) {
- adjustingInfo = new InlineAdjustingInfo(stretch, shrink, adjustment);
- }
-
- /**
- * Sets the adjustment information from an existing object
- * @param adjustingInfo the existing adjustment object
- */
- public void setAdjustingInfo(InlineAdjustingInfo adjustingInfo) {
- this.adjustingInfo = adjustingInfo;
- }
-
- /**
- * Modify the adjustment value in the adjustment information object
- * @param adjustment the new adjustment value
- */
- public void setAdjustment(int adjustment) {
- if (adjustingInfo != null) {
- adjustingInfo.adjustment = adjustment;
- }
- }
-
- /**
- * Increase the inline progression dimensions of this area.
- * This is used for inline parent areas that contain mulitple child areas.
- *
- * @param ipd the inline progression to increase by
- */
- public void increaseIPD(int ipd) {
- this.ipd += ipd;
- }
-
- /**
- * Set the block progression offset of this inline area.
- * This is used to set the offset of the inline area
- * which is relative to the before edge of the parent area.
- *
- * @param blockProgressionOffset the offset
- */
- public void setBlockProgressionOffset(int blockProgressionOffset) {
- this.blockProgressionOffset = blockProgressionOffset;
- }
-
- /**
- * Get the block progression offset of this inline area.
- * This returns the offset of the inline area
- * relative to the before edge of the parent area.
- *
- * @return the blockProgressionOffset
- */
- public int getBlockProgressionOffset() {
- return blockProgressionOffset;
- }
-
- /**
- * @param parentArea The parentArea to set.
- */
- public void setParentArea(Area parentArea) {
- this.parentArea = parentArea;
- }
-
- /**
- * @return Returns the parentArea.
- */
- public Area getParentArea() {
- return parentArea;
- }
-
- /**
- * Set the parent for the child area.
- *
- * {@inheritDoc}
- */
- @Override
- public void addChildArea(Area childArea) {
- super.addChildArea(childArea);
- if (childArea instanceof InlineArea) {
- ((InlineArea) childArea).setParentArea(this);
- }
- }
-
- /** @return true if the inline area is underlined. */
- public boolean hasUnderline() {
- return getTraitAsBoolean(Trait.UNDERLINE);
- }
-
- /** @return true if the inline area is overlined. */
- public boolean hasOverline() {
- return getTraitAsBoolean(Trait.OVERLINE);
- }
-
- /** @return true if the inline area has a line through. */
- public boolean hasLineThrough() {
- return getTraitAsBoolean(Trait.LINETHROUGH);
- }
-
- /** @return true if the inline area is blinking. */
- public boolean isBlinking() {
- return getTraitAsBoolean(Trait.BLINK);
- }
-
- /**
- * recursively apply the variation factor to all descendant areas
- * @param variationFactor the variation factor that must be applied to adjustments
- * @param lineStretch the total stretch of the line
- * @param lineShrink the total shrink of the line
- * @return true if there is an UnresolvedArea descendant
- */
- public boolean applyVariationFactor(double variationFactor,
- int lineStretch, int lineShrink) {
- // default behaviour: update the IPD and return false
- if (adjustingInfo != null) {
- setIPD(getIPD() + adjustingInfo.applyVariationFactor(variationFactor));
- }
- return false;
- }
-
- /**
- * Apply IPD variation.
- * @param ipdVariation the variation
- */
- public void handleIPDVariation(int ipdVariation) {
- if (log.isTraceEnabled()) {
- log.trace("Handling IPD variation for " + getClass().getSimpleName()
- + ": increase by " + ipdVariation + " mpt.");
- }
-
- increaseIPD(ipdVariation);
- notifyIPDVariation(ipdVariation);
- }
-
- /**
- * notify the parent area about the ipd variation of this area
- * or of a descendant area
- * @param ipdVariation the difference between new and old ipd
- */
- protected void notifyIPDVariation(int ipdVariation) {
- if (getParentArea() instanceof InlineArea) {
- ((InlineArea) getParentArea()).handleIPDVariation(ipdVariation);
- } else if (getParentArea() instanceof LineArea) {
- ((LineArea) getParentArea()).handleIPDVariation(ipdVariation);
- } else if (getParentArea() == null) {
- // parent area not yet set: store the variations
- storedIPDVariation += ipdVariation;
- }
- }
-
- /**
- * Returns the offset that this area would have if its offset and size were taking
- * children areas into account. The bpd of an inline area is taken from its nominal
- * font and doesn't depend on the bpds of its children elements. However, in the case
- * of a basic-link element we want the active area to cover all of the children
- * elements.
- *
- * @return the offset that this area would have if the before-edge of its
- * content-rectangle were coinciding with the <q>beforest</q> before-edge of its
- * children allocation-rectangles.
- * @see #getVirtualBPD()
- * @see BasicLinkArea
- */
- int getVirtualOffset() {
- return getBlockProgressionOffset();
- }
-
- /**
- * Returns the block-progression-dimension that this area would have if it were taking
- * its children elements into account. See {@linkplain #getVirtualOffset()}.
- *
- * @return the bpd
- */
- int getVirtualBPD() {
- return getBPD();
- }
-
- /**
- * Collection bidi inline runs.
- * @param runs current list of inline runs
- * @return modified list of inline runs, having appended new run
- */
- public List collectInlineRuns(List runs) {
- assert runs != null;
- runs.add(new InlineRun(this, new int[] {getBidiLevel()}));
- return runs;
- }
-
- /**
- * Determine if inline area IA is an ancestor inline area or same as this area.
- * @param ia inline area to test
- * @return true if specified inline area is an ancestor or same as this area
- */
- public boolean isAncestorOrSelf(InlineArea ia) {
- return (ia == this) || isAncestor(ia);
- }
-
- /**
- * Determine if inline area IA is an ancestor inline area of this area.
- * @param ia inline area to test
- * @return true if specified inline area is an ancestor of this area
- */
- public boolean isAncestor(InlineArea ia) {
- for (Area p = getParentArea(); p != null;) {
- if (p == ia) {
- return true;
- } else if (p instanceof InlineArea) {
- p = ((InlineArea) p).getParentArea();
- } else {
- p = null;
- }
- }
- return false;
- }
-
- }
|