History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/font/Underline.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/font/Underline.java+308−0
@@ -0,0 +1,308 @@
1+/*
2+ * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+/*
26+ *
27+ * (C) Copyright IBM Corp. 1998, All Rights Reserved
28+ */
29+
30+package sun.font;
31+
32+import java.awt.BasicStroke;
33+import java.awt.Graphics2D;
34+import java.awt.Shape;
35+import java.awt.Stroke;
36+
37+import java.awt.geom.GeneralPath;
38+import java.awt.geom.Line2D;
39+
40+import java.awt.font.TextAttribute;
41+
42+import java.util.concurrent.ConcurrentHashMap;
43+
44+/**
45+ * This class provides drawing and bounds-measurement of
46+ * underlines. Additionally, it has a factory method for
47+ * obtaining underlines from values of underline attributes.
48+ */
49+
50+abstract class Underline {
51+
52+ /**
53+ * Draws the underline into g2d. The thickness should be obtained
54+ * from a LineMetrics object. Note that some underlines ignore the
55+ * thickness parameter.
56+ * The underline is drawn from (x1, y) to (x2, y).
57+ */
58+ abstract void drawUnderline(Graphics2D g2d,
59+ float thickness,
60+ float x1,
61+ float x2,
62+ float y);
63+
64+ /**
65+ * Returns the bottom of the bounding rectangle for this underline.
66+ */
67+ abstract float getLowerDrawLimit(float thickness);
68+
69+ /**
70+ * Returns a Shape representing the underline. The thickness should be obtained
71+ * from a LineMetrics object. Note that some underlines ignore the
72+ * thickness parameter.
73+ */
74+ abstract Shape getUnderlineShape(float thickness,
75+ float x1,
76+ float x2,
77+ float y);
78+
79+ // Implementation of underline for standard and Input Method underlines.
80+ // These classes are private.
81+
82+ // IM Underlines ignore thickness param, and instead use
83+ // DEFAULT_THICKNESS
84+ private static final float DEFAULT_THICKNESS = 1.0f;
85+
86+ // StandardUnderline's constructor takes a boolean param indicating
87+ // whether to override the default thickness. These values clarify
88+ // the semantics of the parameter.
89+ private static final boolean USE_THICKNESS = true;
90+ private static final boolean IGNORE_THICKNESS = false;
91+
92+ // Implementation of standard underline and all input method underlines
93+ // except UNDERLINE_LOW_GRAY.
94+ private static final class StandardUnderline extends Underline {
95+
96+ // the amount by which to move the underline
97+ private float shift;
98+
99+ // the actual line thickness is this value times
100+ // the requested thickness
101+ private float thicknessMultiplier;
102+
103+ // if non-null, underline is drawn with a BasicStroke
104+ // with this dash pattern
105+ private float[] dashPattern;
106+
107+ // if false, all underlines are DEFAULT_THICKNESS thick
108+ // if true, use thickness param
109+ private boolean useThickness;
110+
111+ // cached BasicStroke
112+ private BasicStroke cachedStroke;
113+
114+ StandardUnderline(float shift,
115+ float thicknessMultiplier,
116+ float[] dashPattern,
117+ boolean useThickness) {
118+
119+ this.shift = shift;
120+ this.thicknessMultiplier = thicknessMultiplier;
121+ this.dashPattern = dashPattern;
122+ this.useThickness = useThickness;
123+ this.cachedStroke = null;
124+ }
125+
126+ private BasicStroke createStroke(float lineThickness) {
127+
128+ if (dashPattern == null) {
129+ return new BasicStroke(lineThickness,
130+ BasicStroke.CAP_BUTT,
131+ BasicStroke.JOIN_MITER);
132+ }
133+ else {
134+ return new BasicStroke(lineThickness,
135+ BasicStroke.CAP_BUTT,
136+ BasicStroke.JOIN_MITER,
137+ 10.0f,
138+ dashPattern,
139+ 0);
140+ }
141+ }
142+
143+ private float getLineThickness(float thickness) {
144+
145+ if (useThickness) {
146+ return thickness * thicknessMultiplier;
147+ }
148+ else {
149+ return DEFAULT_THICKNESS * thicknessMultiplier;
150+ }
151+ }
152+
153+ private Stroke getStroke(float thickness) {
154+
155+ float lineThickness = getLineThickness(thickness);
156+ BasicStroke stroke = cachedStroke;
157+ if (stroke == null ||
158+ stroke.getLineWidth() != lineThickness) {
159+
160+ stroke = createStroke(lineThickness);
161+ cachedStroke = stroke;
162+ }
163+
164+ return stroke;
165+ }
166+
167+ void drawUnderline(Graphics2D g2d,
168+ float thickness,
169+ float x1,
170+ float x2,
171+ float y) {
172+
173+
174+ Stroke saveStroke = g2d.getStroke();
175+ g2d.setStroke(getStroke(thickness));
176+ g2d.draw(new Line2D.Float(x1, y + shift, x2, y + shift));
177+ g2d.setStroke(saveStroke);
178+ }
179+
180+ float getLowerDrawLimit(float thickness) {
181+
182+ return shift + getLineThickness(thickness);
183+ }
184+
185+ Shape getUnderlineShape(float thickness,
186+ float x1,
187+ float x2,
188+ float y) {
189+
190+ Stroke ulStroke = getStroke(thickness);
191+ Line2D line = new Line2D.Float(x1, y + shift, x2, y + shift);
192+ return ulStroke.createStrokedShape(line);
193+ }
194+ }
195+
196+ // Implementation of UNDERLINE_LOW_GRAY.
197+ private static class IMGrayUnderline extends Underline {
198+
199+ private BasicStroke stroke;
200+
201+ IMGrayUnderline() {
202+ stroke = new BasicStroke(DEFAULT_THICKNESS,
203+ BasicStroke.CAP_BUTT,
204+ BasicStroke.JOIN_MITER,
205+ 10.0f,
206+ new float[] {1, 1},
207+ 0);
208+ }
209+
210+ void drawUnderline(Graphics2D g2d,
211+ float thickness,
212+ float x1,
213+ float x2,
214+ float y) {
215+
216+ Stroke saveStroke = g2d.getStroke();
217+ g2d.setStroke(stroke);
218+
219+ Line2D.Float drawLine = new Line2D.Float(x1, y, x2, y);
220+ g2d.draw(drawLine);
221+
222+ drawLine.y1 += DEFAULT_THICKNESS;
223+ drawLine.y2 += DEFAULT_THICKNESS;
224+ drawLine.x1 += DEFAULT_THICKNESS;
225+
226+ g2d.draw(drawLine);
227+
228+ g2d.setStroke(saveStroke);
229+ }
230+
231+ float getLowerDrawLimit(float thickness) {
232+
233+ return DEFAULT_THICKNESS * 2;
234+ }
235+
236+ Shape getUnderlineShape(float thickness,
237+ float x1,
238+ float x2,
239+ float y) {
240+
241+ GeneralPath gp = new GeneralPath();
242+
243+ Line2D.Float line = new Line2D.Float(x1, y, x2, y);
244+ gp.append(stroke.createStrokedShape(line), false);
245+
246+ line.y1 += DEFAULT_THICKNESS;
247+ line.y2 += DEFAULT_THICKNESS;
248+ line.x1 += DEFAULT_THICKNESS;
249+
250+ gp.append(stroke.createStrokedShape(line), false);
251+
252+ return gp;
253+ }
254+ }
255+
256+ // Keep a map of underlines, one for each type
257+ // of underline. The Underline objects are Flyweights
258+ // (shared across multiple clients), so they should be immutable.
259+ // If this implementation changes then clone underline
260+ // instances in getUnderline before returning them.
261+ private static final ConcurrentHashMap<Object, Underline>
262+ UNDERLINES = new ConcurrentHashMap<Object, Underline>(6);
263+ private static final Underline[] UNDERLINE_LIST;
264+
265+ static {
266+ Underline[] uls = new Underline[6];
267+
268+ uls[0] = new StandardUnderline(0, 1, null, USE_THICKNESS);
269+ UNDERLINES.put(TextAttribute.UNDERLINE_ON, uls[0]);
270+
271+ uls[1] = new StandardUnderline(1, 1, null, IGNORE_THICKNESS);
272+ UNDERLINES.put(TextAttribute.UNDERLINE_LOW_ONE_PIXEL, uls[1]);
273+
274+ uls[2] = new StandardUnderline(1, 2, null, IGNORE_THICKNESS);
275+ UNDERLINES.put(TextAttribute.UNDERLINE_LOW_TWO_PIXEL, uls[2]);
276+
277+ uls[3] = new StandardUnderline(1, 1, new float[] { 1, 1 }, IGNORE_THICKNESS);
278+ UNDERLINES.put(TextAttribute.UNDERLINE_LOW_DOTTED, uls[3]);
279+
280+ uls[4] = new IMGrayUnderline();
281+ UNDERLINES.put(TextAttribute.UNDERLINE_LOW_GRAY, uls[4]);
282+
283+ uls[5] = new StandardUnderline(1, 1, new float[] { 4, 4 }, IGNORE_THICKNESS);
284+ UNDERLINES.put(TextAttribute.UNDERLINE_LOW_DASHED, uls[5]);
285+
286+ UNDERLINE_LIST = uls;
287+ }
288+
289+ /**
290+ * Return the Underline for the given value of
291+ * TextAttribute.INPUT_METHOD_UNDERLINE or
292+ * TextAttribute.UNDERLINE.
293+ * If value is not an input method underline value or
294+ * TextAttribute.UNDERLINE_ON, null is returned.
295+ */
296+ static Underline getUnderline(Object value) {
297+
298+ if (value == null) {
299+ return null;
300+ }
301+
302+ return (Underline) UNDERLINES.get(value);
303+ }
304+
305+ static Underline getUnderline(int index) {
306+ return index < 0 ? null : UNDERLINE_LIST[index];
307+ }
308+}