aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache/fop/area/LineArea.java
blob: 306d50be63a65137a16306d55a4476fb53b105c4 (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
/*
 * $Id$
 * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
 * For details on use and redistribution please refer to the
 * LICENSE file included with these sources.
 */

package org.apache.fop.area;

import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.layoutmgr.LayoutInfo;
import org.apache.fop.fo.properties.VerticalAlign;

import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

// a line area can contain information in ranges of child inline
// areas that have properties such as
// links, background, underline, bold, id areas
public class LineArea extends Area {
    int stacking = LR;
    // contains inline areas
    // has start indent and length, dominant baseline, height
    int startIndent;
    int length;

    int lineHeight;
    // this is the offset for the dominant baseline
    int baseLine;

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

    ArrayList inlineAreas = new ArrayList();

    public void setHeight(int height) {
        lineHeight = height;
    }

    public int getHeight() {
        return lineHeight;
    }

    public MinOptMax getContentBPD() {
        return new MinOptMax(lineHeight);
    }

    public void addChild(Area childArea) {
	if (childArea instanceof InlineArea) {
	    addInlineArea((InlineArea)childArea);
	}
    }

    public void addInlineArea(InlineArea area) {
        inlineAreas.add(area);
    }

    public List getInlineAreas() {
        return inlineAreas;
    }

    public void verticalAlign(int lh, int lead, int follow) {
        int maxHeight = lh;
        List inlineAreas = getInlineAreas();

        // get smallest possible offset to before edge
        // this depends on the height of no and middle alignments
        int before = lead;
        int after = follow;
        int halfLeading = (lineHeight - lead - follow) / 2;
        before += halfLeading;
        for (Iterator iter = inlineAreas.iterator(); iter.hasNext();) {
            InlineArea inline = (InlineArea) iter.next();
            LayoutInfo info = inline.info;
            int al;
            int ld = inline.getHeight();
            if (info != null) {
                al = info.alignment;
                ld = info.lead;
            } else {
                al = VerticalAlign.BASELINE;
            }
            if (al == VerticalAlign.BASELINE) {
                if (ld > before) {
                    before = ld;
                }
                if (inline.getHeight() > before) {
                    before = inline.getHeight();
                }
            } else if (al == VerticalAlign.MIDDLE) {
                if (inline.getHeight() / 2 + lead / 2 > before) {
                    before = inline.getHeight() / 2 + lead / 2;
                }
                if (inline.getHeight() / 2 - lead / 2 > after) {
                    after = inline.getHeight() / 2 - lead / 2;
                }
            } else if (al == VerticalAlign.TOP) {
            } else if (al == VerticalAlign.BOTTOM) {
            }
        }
        // then align all before, no and middle alignment
        for (Iterator iter = inlineAreas.iterator(); iter.hasNext();) {
            InlineArea inline = (InlineArea) iter.next();
            LayoutInfo info = inline.info;
            int al;
            int ld = inline.getHeight();
            boolean bloffset = false;
            if (info != null) {
                al = info.alignment;
                ld = info.lead;
                bloffset = info.blOffset;
            } else {
                al = VerticalAlign.BASELINE;
            }
            if (al == VerticalAlign.BASELINE) {
                // the offset position for text is the baseline
                if (bloffset) {
                    inline.setOffset(before);
                } else {
                    inline.setOffset(before - ld);
                }
                if (inline.getHeight() - ld > after) {
                    after = inline.getHeight() - ld;
                }
            } else if (al == VerticalAlign.MIDDLE) {
                inline.setOffset(before - inline.getHeight() / 2 -
                                 lead / 2);
            } else if (al == VerticalAlign.TOP) {
                inline.setOffset(0);
                if (inline.getHeight() - before > after) {
                    after = inline.getHeight() - before;
                }
            } else if (al == VerticalAlign.BOTTOM) {
                if (inline.getHeight() - before > after) {
                    after = inline.getHeight() - before;
                }
            }
        }

        // after alignment depends on maximum height of before
        // and middle alignments
        for (Iterator iter = inlineAreas.iterator(); iter.hasNext();) {
            InlineArea inline = (InlineArea) iter.next();
            LayoutInfo info = inline.info;
            int al;
            if (info != null) {
                al = info.alignment;
            } else {
                al = VerticalAlign.BASELINE;
            }
            if (al == VerticalAlign.BASELINE) {
            } else if (al == VerticalAlign.MIDDLE) {
            } else if (al == VerticalAlign.TOP) {
            } else if (al == VerticalAlign.BOTTOM) {
                inline.setOffset(before + after - inline.getHeight());
            }
        }
        if (before + after > maxHeight) {
            setHeight(before + after);
        } else {
            setHeight(maxHeight);
        }
    }
}