Lines 1-5
Link Here
|
1 |
/******************************************************************************* |
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2000, 2005 IBM Corporation and others. |
2 |
* Copyright (c) 2000, 2007 IBM Corporation and others. |
3 |
* All rights reserved. This program and the accompanying materials |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
5 |
* which accompanies this distribution, and is available at |
5 |
* which accompanies this distribution, and is available at |
Lines 15-36
Link Here
|
15 |
|
15 |
|
16 |
import org.eclipse.swt.SWT; |
16 |
import org.eclipse.swt.SWT; |
17 |
import org.eclipse.swt.graphics.Font; |
17 |
import org.eclipse.swt.graphics.Font; |
|
|
18 |
import org.eclipse.swt.graphics.FontMetrics; |
19 |
import org.eclipse.swt.graphics.Rectangle; |
18 |
import org.eclipse.swt.graphics.TextLayout; |
20 |
import org.eclipse.swt.graphics.TextLayout; |
19 |
import org.eclipse.swt.widgets.Display; |
21 |
import org.eclipse.swt.widgets.Display; |
20 |
|
22 |
|
21 |
import org.eclipse.draw2d.FigureUtilities; |
23 |
import org.eclipse.draw2d.FigureUtilities; |
|
|
24 |
import org.eclipse.draw2d.geometry.Dimension; |
22 |
|
25 |
|
23 |
/** |
26 |
/** |
24 |
* Utility class for FlowFigures. |
27 |
* Utility class for FlowFigures. |
25 |
* @author hudsonr |
28 |
* @author hudsonr |
26 |
* @since 2.1 |
29 |
* @since 2.1 |
27 |
*/ |
30 |
*/ |
28 |
class FlowUtilities |
31 |
public class FlowUtilities |
29 |
extends FigureUtilities |
|
|
30 |
{ |
32 |
{ |
31 |
|
33 |
|
32 |
interface LookAhead { |
34 |
interface LookAhead { |
33 |
int getWidth(); |
35 |
int getWidth(); |
34 |
} |
36 |
} |
35 |
private static int ELLIPSIS_SIZE; |
37 |
private static int ELLIPSIS_SIZE; |
36 |
private static final BreakIterator INTERNAL_LINE_BREAK = BreakIterator.getLineInstance(); |
38 |
private static final BreakIterator INTERNAL_LINE_BREAK = BreakIterator.getLineInstance(); |
Lines 39-102
Link Here
|
39 |
static final BreakIterator LINE_BREAK = BreakIterator.getLineInstance(); |
41 |
static final BreakIterator LINE_BREAK = BreakIterator.getLineInstance(); |
40 |
|
42 |
|
41 |
static boolean canBreakAfter(char c) { |
43 |
static boolean canBreakAfter(char c) { |
42 |
boolean result = Character.isWhitespace(c) || c == '-'; |
44 |
boolean result = Character.isWhitespace(c) || c == '-'; |
43 |
if (!result && (c < 'a' || c > 'z')) { |
45 |
if (!result && (c < 'a' || c > 'z')) { |
44 |
// chinese characters and such would be caught in here |
46 |
// chinese characters and such would be caught in here |
45 |
// LINE_BREAK is used here because INTERNAL_LINE_BREAK might be in use |
47 |
// LINE_BREAK is used here because INTERNAL_LINE_BREAK might be in use |
46 |
LINE_BREAK.setText(c + "a"); //$NON-NLS-1$ |
48 |
LINE_BREAK.setText(c + "a"); //$NON-NLS-1$ |
47 |
result = LINE_BREAK.isBoundary(1); |
49 |
result = LINE_BREAK.isBoundary(1); |
48 |
} |
50 |
} |
49 |
return result; |
51 |
return result; |
50 |
} |
52 |
} |
51 |
|
53 |
|
52 |
private static int findFirstDelimeter(String string) { |
54 |
private static int findFirstDelimeter(String string) { |
53 |
int macNL = string.indexOf('\r'); |
55 |
int macNL = string.indexOf('\r'); |
54 |
int unixNL = string.indexOf('\n'); |
56 |
int unixNL = string.indexOf('\n'); |
55 |
|
57 |
|
56 |
if (macNL == -1) |
58 |
if (macNL == -1) |
57 |
macNL = Integer.MAX_VALUE; |
59 |
macNL = Integer.MAX_VALUE; |
58 |
if (unixNL == -1) |
60 |
if (unixNL == -1) |
59 |
unixNL = Integer.MAX_VALUE; |
61 |
unixNL = Integer.MAX_VALUE; |
60 |
|
62 |
|
61 |
return Math.min(macNL, unixNL); |
63 |
return Math.min(macNL, unixNL); |
62 |
} |
64 |
} |
63 |
|
65 |
|
64 |
private static float getAverageCharWidth(TextFragmentBox fragment, Font font) { |
66 |
/** |
65 |
if (fragment.getWidth() > 0 && fragment.length != 0) |
67 |
* Gets the average character width. |
66 |
return fragment.getWidth() / (float)fragment.length; |
68 |
* |
67 |
return getFontMetrics(font).getAverageCharWidth(); |
69 |
* @param fragment the supplied TextFragmentBox to use for calculation. |
|
|
70 |
* if the length is 0 or if the width is or below 0, |
71 |
* the average character width is taken from standard |
72 |
* font metrics. |
73 |
* @param font the font to use in case the TextFragmentBox conditions |
74 |
* above are true. |
75 |
* @return the average character width |
76 |
*/ |
77 |
protected float getAverageCharWidth(TextFragmentBox fragment, Font font) { |
78 |
if (fragment.getWidth() > 0 && fragment.length != 0) |
79 |
return fragment.getWidth() / (float)fragment.length; |
80 |
return FigureUtilities.getFontMetrics(font).getAverageCharWidth(); |
68 |
} |
81 |
} |
69 |
|
82 |
|
70 |
static int getBorderAscent(InlineFlow owner) { |
83 |
static int getBorderAscent(InlineFlow owner) { |
71 |
if (owner.getBorder() instanceof FlowBorder) { |
84 |
if (owner.getBorder() instanceof FlowBorder) { |
72 |
FlowBorder border = (FlowBorder)owner.getBorder(); |
85 |
FlowBorder border = (FlowBorder)owner.getBorder(); |
73 |
return border.getInsets(owner).top; |
86 |
return border.getInsets(owner).top; |
74 |
} |
87 |
} |
75 |
return 0; |
88 |
return 0; |
76 |
} |
89 |
} |
77 |
|
90 |
|
78 |
static int getBorderAscentWithMargin(InlineFlow owner) { |
91 |
static int getBorderAscentWithMargin(InlineFlow owner) { |
79 |
if (owner.getBorder() instanceof FlowBorder) { |
92 |
if (owner.getBorder() instanceof FlowBorder) { |
80 |
FlowBorder border = (FlowBorder)owner.getBorder(); |
93 |
FlowBorder border = (FlowBorder)owner.getBorder(); |
81 |
return border.getTopMargin() + border.getInsets(owner).top; |
94 |
return border.getTopMargin() + border.getInsets(owner).top; |
82 |
} |
95 |
} |
83 |
return 0; |
96 |
return 0; |
84 |
} |
97 |
} |
85 |
|
98 |
|
86 |
static int getBorderDescent(InlineFlow owner) { |
99 |
static int getBorderDescent(InlineFlow owner) { |
87 |
if (owner.getBorder() instanceof FlowBorder) { |
100 |
if (owner.getBorder() instanceof FlowBorder) { |
88 |
FlowBorder border = (FlowBorder)owner.getBorder(); |
101 |
FlowBorder border = (FlowBorder)owner.getBorder(); |
89 |
return border.getInsets(owner).bottom; |
102 |
return border.getInsets(owner).bottom; |
90 |
} |
103 |
} |
91 |
return 0; |
104 |
return 0; |
92 |
} |
105 |
} |
93 |
|
106 |
|
94 |
static int getBorderDescentWithMargin(InlineFlow owner) { |
107 |
static int getBorderDescentWithMargin(InlineFlow owner) { |
95 |
if (owner.getBorder() instanceof FlowBorder) { |
108 |
if (owner.getBorder() instanceof FlowBorder) { |
96 |
FlowBorder border = (FlowBorder)owner.getBorder(); |
109 |
FlowBorder border = (FlowBorder)owner.getBorder(); |
97 |
return border.getBottomMargin() + border.getInsets(owner).bottom; |
110 |
return border.getBottomMargin() + border.getInsets(owner).bottom; |
98 |
} |
111 |
} |
99 |
return 0; |
112 |
return 0; |
100 |
} |
113 |
} |
101 |
|
114 |
|
102 |
/** |
115 |
/** |
Lines 108-117
Link Here
|
108 |
* @since 3.1 |
121 |
* @since 3.1 |
109 |
*/ |
122 |
*/ |
110 |
static TextLayout getTextLayout() { |
123 |
static TextLayout getTextLayout() { |
111 |
if (layout == null) |
124 |
if (layout == null) |
112 |
layout = new TextLayout(Display.getDefault()); |
125 |
layout = new TextLayout(Display.getDefault()); |
113 |
layout.setOrientation(SWT.LEFT_TO_RIGHT); |
126 |
layout.setOrientation(SWT.LEFT_TO_RIGHT); |
114 |
return layout; |
127 |
return layout; |
115 |
} |
128 |
} |
116 |
|
129 |
|
117 |
/** |
130 |
/** |
Lines 121-162
Link Here
|
121 |
* @since 3.1 |
134 |
* @since 3.1 |
122 |
*/ |
135 |
*/ |
123 |
private static void initBidi(TextFragmentBox frag, String string, Font font) { |
136 |
private static void initBidi(TextFragmentBox frag, String string, Font font) { |
124 |
if (frag.requiresBidi()) { |
137 |
if (frag.requiresBidi()) { |
125 |
TextLayout textLayout = getTextLayout(); |
138 |
TextLayout textLayout = getTextLayout(); |
126 |
textLayout.setFont(font); |
139 |
textLayout.setFont(font); |
127 |
//$TODO need to insert overrides in front of string. |
140 |
//$TODO need to insert overrides in front of string. |
128 |
textLayout.setText(string); |
141 |
textLayout.setText(string); |
129 |
} |
142 |
} |
130 |
} |
143 |
} |
131 |
|
144 |
|
132 |
private static int measureString(TextFragmentBox frag, String string, int guess, Font font) { |
145 |
private int measureString(TextFragmentBox frag, String string, int guess, Font font) { |
133 |
if (frag.requiresBidi()) { |
146 |
if (frag.requiresBidi()) { |
134 |
// The text and/or could have changed if the lookAhead was invoked. This will |
147 |
// The text and/or could have changed if the lookAhead was invoked. This will |
135 |
// happen at most once. |
148 |
// happen at most once. |
136 |
TextLayout layout = getTextLayout(); |
149 |
return getTextLayoutBounds(string, font, 0, guess - 1).width; |
137 |
layout.setText(string); |
150 |
} else |
138 |
layout.setFont(font); |
151 |
return getStringExtents(string.substring(0, guess), font).width; |
139 |
return layout.getBounds(0, guess - 1).width; |
152 |
} |
140 |
} else |
153 |
|
141 |
return getStringDimension(string.substring(0, guess), font).x; |
154 |
void setupFragment(TextFragmentBox frag, Font f, String s) { |
142 |
} |
155 |
if (frag.getWidth() == -1 || frag.isTruncated()) { |
143 |
|
156 |
int width; |
144 |
static void setupFragment(TextFragmentBox frag, Font f, String s) { |
157 |
if (s.length() == 0 || frag.length == 0) |
145 |
if (frag.getWidth() == -1 || frag.isTruncated()) { |
158 |
width = 0; |
146 |
int width; |
159 |
else if (frag.requiresBidi()) { |
147 |
if (s.length() == 0 || frag.length == 0) |
160 |
width = getTextLayoutBounds(s, f, 0, frag.length - 1).width; |
148 |
width = 0; |
161 |
} else |
149 |
else if (frag.requiresBidi()) { |
162 |
width = getStringExtents(s.substring(0, frag.length), f).width; |
150 |
TextLayout textLayout = getTextLayout(); |
163 |
if (frag.isTruncated()) |
151 |
textLayout.setFont(f); |
164 |
width += ELLIPSIS_SIZE; |
152 |
textLayout.setText(s); |
165 |
frag.setWidth(width); |
153 |
width = textLayout.getBounds(0, frag.length - 1).width; |
166 |
} |
154 |
} else |
|
|
155 |
width = getStringDimension(s.substring(0, frag.length), f).x; |
156 |
if (frag.isTruncated()) |
157 |
width += ELLIPSIS_SIZE; |
158 |
frag.setWidth(width); |
159 |
} |
160 |
} |
167 |
} |
161 |
|
168 |
|
162 |
/** |
169 |
/** |
Lines 172-302
Link Here
|
172 |
* @return the number of characters that will fit in the given space; can be 0 (eg., when |
179 |
* @return the number of characters that will fit in the given space; can be 0 (eg., when |
173 |
* the first character of the given string is a newline) |
180 |
* the first character of the given string is a newline) |
174 |
*/ |
181 |
*/ |
175 |
public static int wrapFragmentInContext(TextFragmentBox frag, String string, |
182 |
public int wrapFragmentInContext(TextFragmentBox frag, String string, |
176 |
FlowContext context, LookAhead lookahead, Font font, int wrapping) { |
183 |
FlowContext context, LookAhead lookahead, Font font, int wrapping) { |
177 |
frag.setTruncated(false); |
184 |
frag.setTruncated(false); |
178 |
int strLen = string.length(); |
185 |
int strLen = string.length(); |
179 |
if (strLen == 0) { |
186 |
if (strLen == 0) { |
180 |
frag.setWidth(-1); |
187 |
frag.setWidth(-1); |
181 |
frag.length = 0; |
188 |
frag.length = 0; |
182 |
setupFragment(frag, font, string); |
189 |
setupFragment(frag, font, string); |
183 |
context.addToCurrentLine(frag); |
190 |
context.addToCurrentLine(frag); |
184 |
return 0; |
191 |
return 0; |
185 |
} |
192 |
} |
186 |
|
193 |
|
187 |
INTERNAL_LINE_BREAK.setText(string); |
194 |
INTERNAL_LINE_BREAK.setText(string); |
188 |
|
195 |
|
189 |
initBidi(frag, string, font); |
196 |
initBidi(frag, string, font); |
190 |
float avgCharWidth = getAverageCharWidth(frag, font); |
197 |
float avgCharWidth = getAverageCharWidth(frag, font); |
191 |
frag.setWidth(-1); |
198 |
frag.setWidth(-1); |
192 |
|
199 |
|
193 |
/* |
200 |
/* |
194 |
* Setup initial boundaries within the string. |
201 |
* Setup initial boundaries within the string. |
195 |
*/ |
202 |
*/ |
196 |
int absoluteMin = 0; |
203 |
int absoluteMin = 0; |
197 |
int max, min = 1; |
204 |
int max, min = 1; |
198 |
if (wrapping == ParagraphTextLayout.WORD_WRAP_HARD) { |
205 |
if (wrapping == ParagraphTextLayout.WORD_WRAP_HARD) { |
199 |
absoluteMin = INTERNAL_LINE_BREAK.next(); |
206 |
absoluteMin = INTERNAL_LINE_BREAK.next(); |
200 |
while (absoluteMin > 0 && Character.isWhitespace(string.charAt(absoluteMin - 1))) |
207 |
while (absoluteMin > 0 && Character.isWhitespace(string.charAt(absoluteMin - 1))) |
201 |
absoluteMin--; |
208 |
absoluteMin--; |
202 |
min = Math.max(absoluteMin, 1); |
209 |
min = Math.max(absoluteMin, 1); |
203 |
} |
210 |
} |
204 |
int firstDelimiter = findFirstDelimeter(string); |
211 |
int firstDelimiter = findFirstDelimeter(string); |
205 |
if (firstDelimiter == 0) |
212 |
if (firstDelimiter == 0) |
206 |
min = max = 0; |
213 |
min = max = 0; |
207 |
else |
214 |
else |
208 |
max = Math.min(strLen, firstDelimiter) + 1; |
215 |
max = Math.min(strLen, firstDelimiter) + 1; |
209 |
|
216 |
|
210 |
|
217 |
|
211 |
int availableWidth = context.getRemainingLineWidth(); |
218 |
int availableWidth = context.getRemainingLineWidth(); |
212 |
int guess = 0, guessSize = 0; |
219 |
int guess = 0, guessSize = 0; |
213 |
|
220 |
|
214 |
while (true) { |
221 |
while (true) { |
215 |
if ((max - min) <= 1) { |
222 |
if ((max - min) <= 1) { |
216 |
if (min == absoluteMin |
223 |
if (min == absoluteMin |
217 |
&& context.isCurrentLineOccupied() |
224 |
&& context.isCurrentLineOccupied() |
218 |
&& !context.getContinueOnSameLine() |
225 |
&& !context.getContinueOnSameLine() |
219 |
&& availableWidth < measureString(frag, string, min, font) |
226 |
&& availableWidth < measureString(frag, string, min, font) |
220 |
+ ((min == strLen && lookahead != null) ? lookahead.getWidth() : 0) |
227 |
+ ((min == strLen && lookahead != null) ? lookahead.getWidth() : 0) |
221 |
) { |
228 |
) { |
222 |
context.endLine(); |
229 |
context.endLine(); |
223 |
availableWidth = context.getRemainingLineWidth(); |
230 |
availableWidth = context.getRemainingLineWidth(); |
224 |
max = Math.min(strLen, firstDelimiter) + 1; |
231 |
max = Math.min(strLen, firstDelimiter) + 1; |
225 |
if ((max - min) <= 1) |
232 |
if ((max - min) <= 1) |
226 |
break; |
233 |
break; |
227 |
} else |
234 |
} else |
228 |
break; |
235 |
break; |
229 |
} |
236 |
} |
230 |
// Pick a new guess size |
237 |
// Pick a new guess size |
231 |
// New guess is the last guess plus the missing width in pixels |
238 |
// New guess is the last guess plus the missing width in pixels |
232 |
// divided by the average character size in pixels |
239 |
// divided by the average character size in pixels |
233 |
guess += 0.5f + (availableWidth - guessSize) / avgCharWidth; |
240 |
guess += 0.5f + (availableWidth - guessSize) / avgCharWidth; |
234 |
|
241 |
|
235 |
if (guess >= max) guess = max - 1; |
242 |
if (guess >= max) guess = max - 1; |
236 |
if (guess <= min) guess = min + 1; |
243 |
if (guess <= min) guess = min + 1; |
237 |
|
244 |
|
238 |
guessSize = measureString(frag, string, guess, font); |
245 |
guessSize = measureString(frag, string, guess, font); |
239 |
|
246 |
|
240 |
if (guess == strLen |
247 |
if (guess == strLen |
241 |
&& lookahead != null |
248 |
&& lookahead != null |
242 |
&& !canBreakAfter(string.charAt(strLen - 1)) |
249 |
&& !canBreakAfter(string.charAt(strLen - 1)) |
243 |
&& guessSize + lookahead.getWidth() > availableWidth) { |
250 |
&& guessSize + lookahead.getWidth() > availableWidth) { |
244 |
max = guess; |
251 |
max = guess; |
245 |
continue; |
252 |
continue; |
246 |
} |
253 |
} |
247 |
|
254 |
|
248 |
if (guessSize <= availableWidth) { |
255 |
if (guessSize <= availableWidth) { |
249 |
min = guess; |
256 |
min = guess; |
250 |
frag.setWidth(guessSize); |
257 |
frag.setWidth(guessSize); |
251 |
if (guessSize == availableWidth) |
258 |
if (guessSize == availableWidth) |
252 |
max = guess + 1; |
259 |
max = guess + 1; |
253 |
} else |
260 |
} else |
254 |
max = guess; |
261 |
max = guess; |
255 |
} |
262 |
} |
256 |
|
263 |
|
257 |
int result = min; |
264 |
int result = min; |
258 |
boolean continueOnLine = false; |
265 |
boolean continueOnLine = false; |
259 |
if (min == strLen) { |
266 |
if (min == strLen) { |
260 |
//Everything fits |
267 |
//Everything fits |
261 |
if (string.charAt(strLen - 1) == ' ') { |
268 |
if (string.charAt(strLen - 1) == ' ') { |
262 |
if (frag.getWidth() == -1) { |
269 |
if (frag.getWidth() == -1) { |
263 |
frag.length = result; |
270 |
frag.length = result; |
264 |
frag.setWidth(measureString(frag, string, result, font)); |
271 |
frag.setWidth(measureString(frag, string, result, font)); |
265 |
} |
272 |
} |
266 |
if (lookahead.getWidth() > availableWidth - frag.getWidth()) { |
273 |
if (lookahead.getWidth() > availableWidth - frag.getWidth()) { |
267 |
frag.length = result - 1; |
274 |
frag.length = result - 1; |
268 |
frag.setWidth(-1); |
275 |
frag.setWidth(-1); |
269 |
} else |
276 |
} else |
270 |
frag.length = result; |
277 |
frag.length = result; |
271 |
} else { |
278 |
} else { |
272 |
continueOnLine = !canBreakAfter(string.charAt(strLen - 1)); |
279 |
continueOnLine = !canBreakAfter(string.charAt(strLen - 1)); |
273 |
frag.length = result; |
280 |
frag.length = result; |
274 |
} |
281 |
} |
275 |
} else if (min == firstDelimiter) { |
282 |
} else if (min == firstDelimiter) { |
276 |
//move result past the delimiter |
283 |
//move result past the delimiter |
277 |
frag.length = result; |
284 |
frag.length = result; |
278 |
if (string.charAt(min) == '\r') { |
285 |
if (string.charAt(min) == '\r') { |
279 |
result++; |
286 |
result++; |
280 |
if (++min < strLen && string.charAt(min) == '\n') |
287 |
if (++min < strLen && string.charAt(min) == '\n') |
281 |
result++; |
288 |
result++; |
282 |
} else if (string.charAt(min) == '\n') |
289 |
} else if (string.charAt(min) == '\n') |
283 |
result++; |
290 |
result++; |
284 |
} else if (string.charAt(min) == ' ' |
291 |
} else if (string.charAt(min) == ' ' |
285 |
|| canBreakAfter(string.charAt(min - 1)) |
292 |
|| canBreakAfter(string.charAt(min - 1)) |
286 |
|| INTERNAL_LINE_BREAK.isBoundary(min)) { |
293 |
|| INTERNAL_LINE_BREAK.isBoundary(min)) { |
287 |
frag.length = min; |
294 |
frag.length = min; |
288 |
if (string.charAt(min) == ' ') |
295 |
if (string.charAt(min) == ' ') |
289 |
result++; |
296 |
result++; |
290 |
else if (string.charAt(min - 1) == ' ') { |
297 |
else if (string.charAt(min - 1) == ' ') { |
291 |
frag.length--; |
298 |
frag.length--; |
292 |
frag.setWidth(-1); |
299 |
frag.setWidth(-1); |
293 |
} |
300 |
} |
294 |
} else out: { |
301 |
} else out: { |
295 |
// In the middle of an unbreakable offset |
302 |
// In the middle of an unbreakable offset |
296 |
result = INTERNAL_LINE_BREAK.preceding(min); |
303 |
result = INTERNAL_LINE_BREAK.preceding(min); |
297 |
if (result == 0) { |
304 |
if (result == 0) { |
298 |
switch (wrapping) { |
305 |
switch (wrapping) { |
299 |
case ParagraphTextLayout.WORD_WRAP_TRUNCATE : |
306 |
case ParagraphTextLayout.WORD_WRAP_TRUNCATE : |
300 |
ELLIPSIS_SIZE = FigureUtilities |
307 |
ELLIPSIS_SIZE = FigureUtilities |
301 |
.getStringExtents(TextFlow.ELLIPSIS, font).width; |
308 |
.getStringExtents(TextFlow.ELLIPSIS, font).width; |
302 |
int truncatedWidth = availableWidth - ELLIPSIS_SIZE; |
309 |
int truncatedWidth = availableWidth - ELLIPSIS_SIZE; |
Lines 312-335
Link Here
|
312 |
} else |
319 |
} else |
313 |
frag.length = 0; |
320 |
frag.length = 0; |
314 |
frag.setTruncated(true); |
321 |
frag.setTruncated(true); |
315 |
result = INTERNAL_LINE_BREAK.following(max - 1); |
322 |
result = INTERNAL_LINE_BREAK.following(max - 1); |
316 |
break out; |
323 |
break out; |
|
|
324 |
|
325 |
default: |
326 |
result = min; |
327 |
break; |
328 |
} |
329 |
} |
330 |
frag.length = result; |
331 |
if (string.charAt(result - 1) == ' ') |
332 |
frag.length--; |
333 |
frag.setWidth(-1); |
334 |
} |
335 |
|
336 |
setupFragment(frag, font, string); |
337 |
context.addToCurrentLine(frag); |
338 |
context.setContinueOnSameLine(continueOnLine); |
339 |
return result; |
340 |
} |
317 |
|
341 |
|
318 |
default: |
342 |
/** |
319 |
result = min; |
343 |
* Returns the Dimensions of <i>s</i> in Font <i>f</i>. |
320 |
break; |
344 |
* |
321 |
} |
345 |
* @param s the string |
322 |
} |
346 |
* @param f the font |
323 |
frag.length = result; |
347 |
* @return the dimensions of the given string |
324 |
if (string.charAt(result - 1) == ' ') |
348 |
* @since 2.0 |
325 |
frag.length--; |
349 |
*/ |
326 |
frag.setWidth(-1); |
350 |
public Dimension getStringExtents(String s, Font f) { |
327 |
} |
351 |
return FigureUtilities.getStringExtents(s, f); |
328 |
|
352 |
} |
329 |
setupFragment(frag, font, string); |
353 |
|
330 |
context.addToCurrentLine(frag); |
354 |
/** |
331 |
context.setContinueOnSameLine(continueOnLine); |
355 |
* @see TextLayout#getBounds() |
332 |
return result; |
356 |
*/ |
|
|
357 |
protected Rectangle getTextLayoutBounds(String s, Font f, int start, int end) { |
358 |
TextLayout textLayout = getTextLayout(); |
359 |
textLayout.setFont(f); |
360 |
textLayout.setText(s); |
361 |
return textLayout.getBounds(start, end); |
362 |
} |
363 |
|
364 |
/** |
365 |
* Gets the font's ascent. |
366 |
* @param font |
367 |
* @return the font's ascent |
368 |
*/ |
369 |
public int getAscent(Font font) { |
370 |
FontMetrics fm = FigureUtilities.getFontMetrics(font); |
371 |
return fm.getHeight() - fm.getDescent(); |
372 |
} |
373 |
|
374 |
/** |
375 |
* Gets the font's descent. |
376 |
* @param font |
377 |
* @return the font's descent |
378 |
*/ |
379 |
public int getDescent(Font font) { |
380 |
return FigureUtilities.getFontMetrics(font).getDescent(); |
333 |
} |
381 |
} |
334 |
|
382 |
|
335 |
} |
383 |
} |