KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > joshy > html > util > FontUtil


1 package org.joshy.html.util;
2
3 import java.awt.Font JavaDoc;
4 import org.w3c.dom.Node JavaDoc;
5 import org.w3c.dom.Element JavaDoc;
6 import org.joshy.u;
7 import java.awt.Graphics2D JavaDoc;
8 import java.awt.font.*;
9 import org.joshy.html.box.*;
10 import org.joshy.html.Context;
11 import org.joshy.html.InlineLayout;
12
13 public class FontUtil {
14     
15 public static int len(Context c, Node JavaDoc node, String JavaDoc str) {
16     return c.getGraphics().getFontMetrics(getFont(c,node)).stringWidth(str);
17 }
18
19 public static int lineHeight(Context c, Node JavaDoc node) {
20     return c.getGraphics().getFontMetrics(getFont(c,node)).getHeight();
21 }
22
23 public static Font JavaDoc getFont(Context c, Node JavaDoc e) {
24     //u.p("testing node: " + e);
25
//Font f = c.getGraphics().getFont();
26

27     // if plain text then get the styling from the parent node
28
if(e.getNodeType() == e.TEXT_NODE) {
29         //u.p("it's a node");
30
Element JavaDoc el = (Element JavaDoc)e.getParentNode();
31         return getElementFont(c,el);
32     }
33     
34     if(e.getNodeType() == e.ELEMENT_NODE) {
35         Element JavaDoc el = (Element JavaDoc)e;
36         return getElementFont(c,el);
37     }
38     
39     u.p("big error in getFont(). Got a node that is neither txt nor element");
40     return null;
41 }
42
43 static boolean quick = false;
44 public static Font JavaDoc getElementFont(Context c, Element JavaDoc el) {
45     //u.p("testing node: " + e);
46
Font JavaDoc f = c.getGraphics().getFont();
47     if(quick) {
48         //f = f.deriveFont((float)((int)(Math.random()*10)));
49
return f;
50     }
51     
52     if(el.getParentNode().getNodeType() == el.DOCUMENT_NODE) {
53         //u.p("ended up at the top somehow!: ");
54
return c.getGraphics().getFont().deriveFont((float)10);
55     }
56     
57     
58
59     // calculate the font size
60
// look up the parent and use it's font size to scale against
61
// joshy: this will fail if the parent also has a relative size
62
// need to fix this by passing down the enclosing block's font size
63
// in the context
64
Element JavaDoc par = (Element JavaDoc)el.getParentNode();
65     float parent_size = c.css.getFloatProperty(par,"font-size");
66     float size = c.css.getFloatProperty(el,"font-size",parent_size);
67
68     String JavaDoc weight = c.css.getStringProperty(el,"font-weight");
69     String JavaDoc[] family = c.css.getStringArrayProperty(el,"font-family");
70     //u.p("families");
71
//u.p(family);
72
/*
73     if(!family[0].equals("sans-serif")) {
74         //u.p("family = ");
75         //u.p(family);
76         //u.p("");
77     }
78     */

79     String JavaDoc style = c.css.getStringProperty(el,"font-style");
80
81     f = c.getFontResolver().resolveFont(c,family,size,weight,style);
82
83     // calculate the font color
84
c.getGraphics().setColor(c.css.getColor(el));
85     return f;
86 }
87
88
89 public static void setupTextDecoration(Context c, Node JavaDoc node, InlineBox box) {
90     Element JavaDoc el = null;
91     if(node instanceof Element JavaDoc) {
92         el = (Element JavaDoc)node;
93     } else {
94         el = (Element JavaDoc)node.getParentNode();
95     }
96     String JavaDoc text_decoration = c.css.getStringProperty(el,"text-decoration");
97     if(text_decoration != null && text_decoration.equals("underline")) {
98         box.underline = true;
99     }
100     if(text_decoration != null && text_decoration.equals("line-through")) {
101         box.strikethrough = true;
102     }
103     if(text_decoration != null && text_decoration.equals("overline")) {
104         box.overline = true;
105     }
106
107 }
108
109 public static void setupVerticalAlign(Context c, Node JavaDoc node, InlineBox box) {
110     //u.p("setup vertical align: node = " + node + " box = " + box);
111
// get the parent node for styling
112
Node JavaDoc parent = node.getParentNode();
113     //u.p("parent = " + parent);
114
Element JavaDoc elem = null;
115     if(node.getNodeType() == node.TEXT_NODE) {
116         parent = parent.getParentNode();
117         elem = (Element JavaDoc)node.getParentNode();
118     } else {
119         elem = (Element JavaDoc)node;
120     }
121     //u.p("parent = " + parent + " elem = " + elem);
122

123     //int parent_height = FontUtil.lineHeight(c,parent);
124
Font JavaDoc parent_font = FontUtil.getFont(c,parent);
125     LineMetrics parent_metrics = null;
126     if(!InlineLayout.isReplaced(node)) {
127         if(!InlineLayout.isFloatedBlock(node,c)) {
128             parent_metrics = parent_font.getLineMetrics(box.text, ((Graphics2D JavaDoc)c.getGraphics()).getFontRenderContext());
129         } else {
130             parent_metrics = parent_font.getLineMetrics("Test", ((Graphics2D JavaDoc)c.getGraphics()).getFontRenderContext());
131         }
132     } else {
133         parent_metrics = parent_font.getLineMetrics("Test", ((Graphics2D JavaDoc)c.getGraphics()).getFontRenderContext());
134     }
135
136
137     // the height of the font
138
float parent_height = parent_metrics.getHeight();
139     //u.p("parent strikethrough height = " + parent_metrics.getStrikethroughOffset());
140
String JavaDoc vertical_align = c.css.getStringProperty(elem,"vertical-align");
141
142     // set the height of the box to the height of the font
143
if(!InlineLayout.isReplaced(node)) {
144         box.height = FontUtil.lineHeight(c,node);
145     }
146     //u.p("vertical align = " + vertical_align);
147

148     if(vertical_align == null) {
149         vertical_align = "baseline";
150     }
151     box.baseline = 0;
152     // box.y is relative to the parent's baseline
153
box.y = 0;
154     // do nothing for 'baseline'
155
box.vset = true;
156     if(vertical_align.equals("baseline")) {
157         //noop box.y = box.y;
158
}
159
160     // works okay i think
161
if(vertical_align.equals("super")) {
162         box.y = box.y + (int) (parent_metrics.getStrikethroughOffset()*2.0);
163     }
164
165     // works okay, i think
166
if(vertical_align.equals("sub")) {
167         box.y = box.y - (int) parent_metrics.getStrikethroughOffset();
168     }
169
170     // joshy: this is using the current baseline instead of the parent's baseline
171
// must fix
172
if(vertical_align.equals("text-top")) {
173         // the top of this text is equal to the top of the parent's text
174
// so we take the parent's height above the baseline and subtract our
175
// height above the baseline
176
box.y = -((int)parent_height - box.height);//(int) (parent_metrics.getStrikethroughOffset()*2.0);
177
}
178
179     // not implemented correctly yet
180
if(vertical_align.equals("text-bottom")) {
181         box.y = 0;
182     }
183
184     // not implemented correctly yet.
185
if(vertical_align.equals("top")) {
186         //u.p("before y = " + box.y);
187
//u.p("baseline = " + box.baseline);
188
box.y = box.y - box.baseline;//(int) (parent_metrics.getStrikethroughOffset()*2.0);
189
box.top_align = true;
190         //u.p("after y = " + box.y);
191
box.vset = false;
192     }
193     if(vertical_align.equals("bottom")) {
194         //u.p("before y = " + box.y);
195
//u.p("baseline = " + box.baseline);
196
box.y = box.y - box.baseline;//(int) (parent_metrics.getStrikethroughOffset()*2.0);
197
box.bottom_align = true;
198         //u.p("after y = " + box.y);
199
box.vset = false;
200     }
201     //u.p("returning box: " + box);
202
}
203
204 public static void setupVerticalAlign(Context c, Node JavaDoc node, LineBox box) {
205     // get the parent node for styling
206
Node JavaDoc parent = node.getParentNode();
207     Element JavaDoc elem = null;
208     if(node.getNodeType() == node.TEXT_NODE) {
209         parent = parent.getParentNode();
210         elem = (Element JavaDoc)node.getParentNode();
211     } else {
212         elem = (Element JavaDoc)node;
213     }
214
215
216     // top and bottom are dist from baseline
217
int top = 0;
218     int bot = 0;
219     int height = 0;
220     for(int i=0; i<box.getChildCount(); i++) {
221         InlineBox inline = (InlineBox)box.getChild(i);
222         // skip floated inlines. they don't affect height calculations
223
if(inline.floated) { continue; }
224         if(inline.vset) {
225             //u.p("looking at vset inline: " + inline);
226
// compare the top of the box
227
if(inline.y - inline.height < top) {
228                 top = inline.y - inline.height;
229             }
230             // compare the bottom of the box
231
if(inline.y + 0 > bot) {
232                 bot = inline.y + 0;
233             }
234         } else {
235         // if it's not one of the baseline derived vertical aligns
236
// then just compare the straight height of the inline
237
if(inline.height > height) {
238                 height = inline.height;
239             }
240         }
241     }
242
243     //u.p("line bot = " + bot + " top = " + top);
244
if(bot-top > height) {
245         box.height = bot-top;
246         box.baseline = box.height - bot;
247     } else {
248         box.height = height;
249         box.baseline = box.height;
250     }
251
252
253     //u.p("line height = " + box.height);
254

255     // loop through all inlines to set the last ones
256
for(int i=0; i<box.getChildCount(); i++) {
257         InlineBox inline = (InlineBox)box.getChild(i);
258         if(inline.floated) {
259             inline.y = -box.baseline+inline.height;
260         } else {
261         if(!inline.vset) {
262             inline.vset = true;
263             if(inline.top_align) {
264                 inline.y = -box.baseline+inline.height;
265             }
266             if(inline.bottom_align) {
267                 inline.y = 0;
268             }
269         }
270         }
271         //u.p("final inline = " + inline);
272
}
273
274 }
275
276 }
277
Popular Tags