aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/area/inline/InlineArea.java
blob: 6d5d9ca98c7f883acf48f454538a247fd0d63c76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/*
 * 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 org.apache.fop.area.Area;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.Trait;

/**
 * Inline Area
 * This area is for all inline areas that can be placed
 * in a line area.
 */
public class InlineArea extends Area {

    /**
     * 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 {
        /** 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 offset = 0;

    /**
     * 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 = null;

    /**
     * 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 = 0;

    /**
     * The adjustment information object
     */
    protected InlineAdjustingInfo adjustingInfo = null;

    /**
     * @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);
    }

    /**
     * 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 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 offset the offset
     */
    public void setOffset(int offset) {
        this.offset = offset;
    }

    /**
     * Get the offset of this inline area.
     * This returns the offset of the inline area
     * which is relative to the before edge of the parent area.
     *
     * @return the offset
     */
    public int getOffset() {
        return offset;
    }

    /**
     * @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}
     */
    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;
    }

    public void handleIPDVariation(int ipdVariation) {
        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;
        }
    }
}