All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.fop.area.LineArea Maven / Gradle / Ivy

Go to download

Apache FOP (Formatting Objects Processor) is the world's first print formatter driven by XSL formatting objects (XSL-FO) and the world's first output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PCL, PS, AFP, TIFF, PNG, SVG, XML (area tree representation), Print, AWT and TXT. The primary output target is PDF.

There is a newer version: 2.9
Show newest version
/*
 * 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: LineArea.java 1761020 2016-09-16 11:17:35Z ssteiner $ */

package org.apache.fop.area;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.fop.area.inline.InlineArea;

import static org.apache.fop.fo.Constants.EN_CENTER;
import static org.apache.fop.fo.Constants.EN_END;
import static org.apache.fop.fo.Constants.EN_JUSTIFY;
import static org.apache.fop.fo.Constants.EN_START;

/**
 * The line area.
 * This is a line area that contains inline areas.
 */
public class LineArea extends Area {

    private static final long serialVersionUID = 7670235908329290684L;

    /**
     * this class stores information about line width and potential adjustments
     * that can be used in order to re-compute adjustement and / or indents when a
     * page-number or a page-number-citation is resolved
     */
    // @SuppressFBWarnings("SE_INNER_CLASS")
    private final class LineAdjustingInfo implements Serializable {

        private static final long serialVersionUID = -6103629976229458273L;

        private int lineAlignment;
        private int difference;
        private int availableStretch;
        private int availableShrink;
        private double variationFactor;
        private boolean bAddedToAreaTree;

        private LineAdjustingInfo(int alignment, int diff,
                                  int stretch, int shrink) {
            lineAlignment = alignment;
            difference = diff;
            availableStretch = stretch;
            availableShrink = shrink;
            variationFactor = 1.0;
            bAddedToAreaTree = false;
        }

        /** {@inheritDoc} */
        public String toString() {
            return getClass().getSimpleName()
                + ": diff=" + difference
                + ", variation=" + variationFactor
                + ", stretch=" + availableStretch
                + ", shrink=" + availableShrink;
        }
    }

    private LineAdjustingInfo adjustingInfo;

    // this class can contain the dominant char styling info
    // this means that many renderers can optimise a bit

    private List inlineAreas = new ArrayList();

    /**
     * default constructor:
     * nothing to do
     */
    public LineArea() {
    }

    /**
     * constructor with extra parameters:
     * a new LineAdjustingInfo object is created
     * @param alignment alignment of this line
     * @param diff      difference between content width and line width
     * @param stretch   the available stretch for any adjustments
     * @param shrink    the available shrink for any adjustments
     */
    public LineArea(int alignment, int diff,
                    int stretch, int shrink) {
        adjustingInfo = new LineAdjustingInfo(alignment, diff, stretch, shrink);
    }

    /**
     * Add a child area to this line area.
     *
     * @param childArea the inline child area to add
     */
    @Override
    public void addChildArea(Area childArea) {
        if (childArea instanceof InlineArea) {
            addInlineArea((InlineArea)childArea);
            // set the parent area for the child area
            ((InlineArea)childArea).setParentArea(this);
        }
    }

    /**
     * Add an inline child area to this line area.
     *
     * @param area the inline child area to add
     */
    public void addInlineArea(InlineArea area) {
        inlineAreas.add(area);
    }

    /**
     * 

Set (en masse) the inline child areas of this line area.

*

Used by bidirectional processing after line area consituent reordering.

* @param inlineAreas the list of inline areas */ public void setInlineAreas(List inlineAreas) { for (InlineArea ia : (Iterable) inlineAreas) { Area pa = ia.getParentArea(); if (pa == null) { ia.setParentArea(this); } else { assert pa == this; } } this.inlineAreas = inlineAreas; } /** * Get the inline child areas of this line area. * * @return the list of inline areas */ public List getInlineAreas() { return inlineAreas; } /** * Get the start indent of this line area. * The start indent is used for offsetting the start of * the inline areas for alignment or other indents. * * @return the start indent value */ public int getStartIndent() { if (hasTrait(Trait.START_INDENT)) { return getTraitAsInteger(Trait.START_INDENT); } else { return 0; } } /** * Get the end indent of this line area. * The end indent is used for offsetting the end of * the inline areas for alignment or other indents. * * @return the end indent value */ public int getEndIndent() { if (hasTrait(Trait.END_INDENT)) { return getTraitAsInteger(Trait.END_INDENT); } else { return 0; } } /** * Updates the extents of the line area from its children. */ public void updateExtentsFromChildren() { int ipd = 0; int bpd = 0; for (InlineArea inlineArea : inlineAreas) { ipd = Math.max(ipd, inlineArea.getAllocIPD()); bpd += inlineArea.getAllocBPD(); } setIPD(ipd); setBPD(bpd); } /** * receive notification about the ipd variation of a descendant area * and perform the needed adjustment, according to the alignment; * in particular: *
    *
  • left-aligned text needs no adjustement;
  • *
  • right-aligned text and centered text are handled locally, * adjusting the indent of this LineArea;
  • *
  • justified text requires a more complex adjustment, as the * variation factor computed on the basis of the total * stretch and shrink of the line must be applied in every * descendant leaf areas (text areas and leader areas).
  • *
* @param ipdVariation the difference between old and new ipd */ public void handleIPDVariation(int ipdVariation) { int si = getStartIndent(); int ei = getEndIndent(); switch (adjustingInfo.lineAlignment) { case EN_START: // adjust end indent addTrait(Trait.END_INDENT, ei - ipdVariation); break; case EN_CENTER: // adjust start and end indents addTrait(Trait.START_INDENT, si - ipdVariation / 2); addTrait(Trait.END_INDENT, ei - ipdVariation / 2); break; case EN_END: // adjust start indent addTrait(Trait.START_INDENT, si - ipdVariation); break; case EN_JUSTIFY: // compute variation factor adjustingInfo.variationFactor *= (float) (adjustingInfo.difference - ipdVariation) / adjustingInfo.difference; adjustingInfo.difference -= ipdVariation; // if the LineArea has already been added to the area tree, // call finalize(); otherwise, wait for the LineLM to call it if (adjustingInfo.bAddedToAreaTree) { finish(); } break; default: throw new RuntimeException(); } } /** * apply the variation factor to all descendant areas * and destroy the AdjustingInfo object if there are * no UnresolvedAreas left */ public void finish() { if (adjustingInfo.lineAlignment == EN_JUSTIFY) { if (log.isTraceEnabled()) { log.trace("Applying variation factor to justified line: " + adjustingInfo); } // justified line: apply the variation factor boolean bUnresolvedAreasPresent = false; // recursively apply variation factor to descendant areas for (InlineArea inlineArea : inlineAreas) { bUnresolvedAreasPresent |= inlineArea .applyVariationFactor(adjustingInfo.variationFactor, adjustingInfo.availableStretch, adjustingInfo.availableShrink); } if (!bUnresolvedAreasPresent) { // there are no more UnresolvedAreas: // destroy the AdjustingInfo instance adjustingInfo = null; } else { // this method will be called again later: // the first time, it is called by the LineLM, // afterwards it must be called by the LineArea itself if (!adjustingInfo.bAddedToAreaTree) { adjustingInfo.bAddedToAreaTree = true; } // reset the variation factor adjustingInfo.variationFactor = 1.0; } } else { // the line is not justified: the ipd variation has already // been handled, modifying the line indent } } public int getEffectiveIPD() { int maxIPD = 0; if (inlineAreas != null) { for (Area area : inlineAreas) { int effectiveIPD = area.getEffectiveIPD(); if (effectiveIPD > maxIPD) { maxIPD = effectiveIPD; } } } return maxIPD; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy