|
1 /******************************************************************************* |
|
2 * Copyright (c) 2000, 2007 IBM Corporation and others. |
|
3 * Portion Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
4 * All rights reserved. This program and the accompanying materials |
|
5 * are made available under the terms of the Eclipse Public License v1.0 |
|
6 * which accompanies this distribution, and is available at |
|
7 * http://www.eclipse.org/legal/epl-v10.html |
|
8 * |
|
9 * Contributors: |
|
10 * IBM Corporation - initial API and implementation |
|
11 * Nokia Corporation - Qt implementation |
|
12 *******************************************************************************/ |
|
13 package org.eclipse.swt.graphics; |
|
14 |
|
15 import org.eclipse.swt.SWT; |
|
16 import org.eclipse.swt.SWTError; |
|
17 import org.eclipse.swt.SWTException; |
|
18 import org.eclipse.swt.internal.qt.OS; |
|
19 import org.eclipse.swt.internal.qt.QtSupplementaryFontData; |
|
20 |
|
21 /** |
|
22 * Instances of this class manage operating system resources that define how |
|
23 * text looks when it is displayed. Fonts may be constructed by providing a |
|
24 * device and either name, size and style information or a <code>FontData</code> |
|
25 * object which encapsulates this data. |
|
26 * <p> |
|
27 * Application code must explicitly invoke the <code>Font.dispose()</code> |
|
28 * method to release the operating system resources managed by each instance |
|
29 * when those instances are no longer required. |
|
30 * </p> |
|
31 * |
|
32 * @see FontData |
|
33 */ |
|
34 public final class Font extends Object { |
|
35 /** |
|
36 * the handle to the OS font resource (Warning: This field is platform |
|
37 * dependent) |
|
38 * <p> |
|
39 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT public API. |
|
40 * It is marked public only so that it can be shared within the packages |
|
41 * provided by SWT. It is not available on all platforms and should never be |
|
42 * accessed from application code. |
|
43 * </p> |
|
44 */ |
|
45 public int handle; |
|
46 |
|
47 Device device; |
|
48 boolean extraFontStyle; |
|
49 String xlfd; |
|
50 |
|
51 /** |
|
52 * Prevents uninitialized instances from being created outside the package. |
|
53 */ |
|
54 Font() { |
|
55 } |
|
56 |
|
57 /** |
|
58 * Constructs a new font given a device and font data which describes the |
|
59 * desired font's appearance. |
|
60 * <p> |
|
61 * You must dispose the font when it is no longer required. |
|
62 * </p> |
|
63 * |
|
64 * @param device |
|
65 * the device to create the font on |
|
66 * @param fd |
|
67 * the FontData that describes the desired font (must not be |
|
68 * null) |
|
69 * |
|
70 * @exception IllegalArgumentException |
|
71 * <ul> |
|
72 * <li>ERROR_NULL_ARGUMENT - if device is null and there is |
|
73 * no current device</li> |
|
74 * <li>ERROR_NULL_ARGUMENT - if the fd argument is null</li> |
|
75 * </ul> |
|
76 * @exception SWTError |
|
77 * <ul> |
|
78 * <li>ERROR_NO_HANDLES - if a font could not be created from |
|
79 * the given font data</li> |
|
80 * </ul> |
|
81 */ |
|
82 public Font(Device device, FontData fd) { |
|
83 if (fd == null) |
|
84 SWT.error(SWT.ERROR_NULL_ARGUMENT); |
|
85 init(device, fd.getName(), fd.getHeight(), fd.getStyle()); |
|
86 initExtraFontData(fd); |
|
87 } |
|
88 |
|
89 |
|
90 |
|
91 /** |
|
92 * Constructs a new font given a device and an array of font data which |
|
93 * describes the desired font's appearance. |
|
94 * <p> |
|
95 * You must dispose the font when it is no longer required. |
|
96 * </p> |
|
97 * |
|
98 * @param device |
|
99 * the device to create the font on |
|
100 * @param fds |
|
101 * the array of FontData that describes the desired font (must |
|
102 * not be null) |
|
103 * |
|
104 * @exception IllegalArgumentException |
|
105 * <ul> |
|
106 * <li>ERROR_NULL_ARGUMENT - if device is null and there is |
|
107 * no current device</li> |
|
108 * <li>ERROR_NULL_ARGUMENT - if the fds argument is null</li> |
|
109 * <li>ERROR_INVALID_ARGUMENT - if the length of fds is zero</li> |
|
110 * <li>ERROR_NULL_ARGUMENT - if any fd in the array is null</li> |
|
111 * </ul> |
|
112 * @exception SWTError |
|
113 * <ul> |
|
114 * <li>ERROR_NO_HANDLES - if a font could not be created from |
|
115 * the given font data</li> |
|
116 * </ul> |
|
117 * |
|
118 * @since 2.1 |
|
119 */ |
|
120 public Font(Device device, FontData[] fds) { |
|
121 if (fds == null) |
|
122 SWT.error(SWT.ERROR_NULL_ARGUMENT); |
|
123 if (fds.length == 0) |
|
124 SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
|
125 for (int i = 0; i < fds.length; i++) { |
|
126 if (fds[i] == null) |
|
127 SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
|
128 } |
|
129 FontData fd = fds[0]; |
|
130 init(device, fd.getName(), fd.getHeight(), fd.getStyle()); |
|
131 initExtraFontData(fd); |
|
132 } |
|
133 |
|
134 /** |
|
135 * Constructs a new font given a device, a font name, the height of the |
|
136 * desired font in points, and a font style. |
|
137 * <p> |
|
138 * You must dispose the font when it is no longer required. |
|
139 * </p> |
|
140 * |
|
141 * @param device |
|
142 * the device to create the font on |
|
143 * @param name |
|
144 * the name of the font (must not be null) |
|
145 * @param height |
|
146 * the font height in points |
|
147 * @param style |
|
148 * a bit or combination of NORMAL, BOLD, ITALIC |
|
149 * |
|
150 * @exception IllegalArgumentException |
|
151 * <ul> |
|
152 * <li>ERROR_NULL_ARGUMENT - if device is null and there is |
|
153 * no current device</li> |
|
154 * <li>ERROR_NULL_ARGUMENT - if the name argument is null</li> |
|
155 * <li>ERROR_INVALID_ARGUMENT - if the height is negative</li> |
|
156 * </ul> |
|
157 * @exception SWTError |
|
158 * <ul> |
|
159 * <li>ERROR_NO_HANDLES - if a font could not be created from |
|
160 * the given arguments</li> |
|
161 * </ul> |
|
162 */ |
|
163 public Font(Device device, String name, int height, int style) { |
|
164 init(device, name, height, style); |
|
165 } |
|
166 |
|
167 public void dispose() { |
|
168 if (device == null) |
|
169 return; |
|
170 if (device.isDisposed()) |
|
171 return; |
|
172 if(!OS.SwtFontCache_isCached(handle)) { |
|
173 OS.QFont_delete(handle); |
|
174 } |
|
175 handle = 0; |
|
176 if (device.tracking) |
|
177 device.dispose_Object(this); |
|
178 device = null; |
|
179 } |
|
180 |
|
181 /** |
|
182 * Compares the argument to the receiver, and returns true if they represent |
|
183 * the <em>same</em> object using a class specific comparison. |
|
184 * |
|
185 * @param object |
|
186 * the object to compare with this object |
|
187 * @return <code>true</code> if the object is the same as this object and |
|
188 * <code>false</code> otherwise |
|
189 * |
|
190 * @see #hashCode |
|
191 */ |
|
192 public boolean equals(Object object) { |
|
193 if (object == this) |
|
194 return true; |
|
195 if (!(object instanceof Font)) |
|
196 return false; |
|
197 return OS.QFont_swt_equals(handle,((Font) object).handle); |
|
198 } |
|
199 |
|
200 /** |
|
201 * Returns an array of <code>FontData</code>s representing the receiver. On |
|
202 * Windows, only one FontData will be returned per font. On X however, a |
|
203 * <code>Font</code> object <em>may</em> be composed of multiple X fonts. To |
|
204 * support this case, we return an array of font data objects. |
|
205 * |
|
206 * @return an array of font data objects describing the receiver |
|
207 * |
|
208 * @exception SWTException |
|
209 * <ul> |
|
210 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been |
|
211 * disposed</li> |
|
212 * </ul> |
|
213 */ |
|
214 public FontData[] getFontData() { |
|
215 if (isDisposed()) |
|
216 SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); |
|
217 |
|
218 String family = OS.QFont_family(handle); |
|
219 int pointSize = OS.QFont_pointSize(handle); |
|
220 int weight = OS.QFont_weight(handle); |
|
221 boolean italic = OS.QFont_italic(handle); |
|
222 |
|
223 int style = SWT.NORMAL; |
|
224 if (weight > OS.QT_FONTNORMAL) |
|
225 style |= SWT.BOLD; |
|
226 if (italic == true) |
|
227 style |= SWT.ITALIC; |
|
228 FontData data = new FontData(family, pointSize, style); |
|
229 if (xlfd != null) { |
|
230 data.xlfd = xlfd; |
|
231 } else if (extraFontStyle) { |
|
232 data.extraFontData = new QtSupplementaryFontData(); |
|
233 QtSupplementaryFontData extraData = data.extraFontData; |
|
234 extraData.underline = OS.QFont_underline(handle) == true ? 1 : 0; |
|
235 extraData.overline = OS.QFont_overline(handle) == true ? 1 : 0; |
|
236 extraData.strikeOut = OS.QFont_strikeOut(handle) == true ? 1 : 0; |
|
237 extraData.stretch = OS.QFont_stretch(handle); |
|
238 extraData.fixedPitch = OS.QFont_fixedPitch(handle) == true ? 1 : 0; |
|
239 extraData.style = OS.QFont_style(handle); |
|
240 extraData.weight = OS.QFont_weight(handle); |
|
241 extraData.styleStrategy = OS.QFont_styleStrategy(handle); |
|
242 } |
|
243 return new FontData[] { data }; |
|
244 } |
|
245 |
|
246 /** |
|
247 * Returns an integer hash code for the receiver. Any two objects that |
|
248 * return <code>true</code> when passed to <code>equals</code> must return |
|
249 * the same value for this method. |
|
250 * |
|
251 * @return the receiver's hash |
|
252 * |
|
253 * @see #equals |
|
254 */ |
|
255 public int hashCode() { |
|
256 return handle; |
|
257 } |
|
258 |
|
259 void init(Device device, String name, int height, int style) { |
|
260 extraFontStyle = false; |
|
261 xlfd = null; |
|
262 if (device == null) |
|
263 device = Device.getDevice(); |
|
264 if (device == null) |
|
265 SWT.error(SWT.ERROR_NULL_ARGUMENT); |
|
266 this.device = device; |
|
267 if (name == null) |
|
268 SWT.error(SWT.ERROR_NULL_ARGUMENT); |
|
269 if (height < 0) |
|
270 SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
|
271 |
|
272 // Keep this after dealing with all exceptions! |
|
273 if (device.tracking) |
|
274 device.new_Object(this); |
|
275 |
|
276 boolean italic = (style & SWT.ITALIC) != 0; |
|
277 int weight = OS.QT_FONTNORMAL; |
|
278 if ((style & SWT.BOLD) != 0) { |
|
279 weight = OS.QT_FONTBOLD; |
|
280 } |
|
281 handle = OS.QFont_new(name, height, weight, italic); |
|
282 } |
|
283 |
|
284 void initExtraFontData(FontData fd) { |
|
285 if (fd.xlfd != null) { |
|
286 OS.QFont_setRawName(handle, fd.xlfd); |
|
287 xlfd = fd.xlfd; |
|
288 } else if (fd.extraFontData != null) { |
|
289 QtSupplementaryFontData extraData = fd.extraFontData; |
|
290 if (extraData.underline > -1) { |
|
291 OS.QFont_setUnderline(handle, extraData.underline > 0 ? true |
|
292 : false); |
|
293 } |
|
294 if (extraData.overline > -1) { |
|
295 OS.QFont_setOverline(handle, extraData.overline > 0 ? true |
|
296 : false); |
|
297 } |
|
298 if (extraData.strikeOut > -1) { |
|
299 OS.QFont_setStrikeOut(handle, extraData.strikeOut > 0 ? true |
|
300 : false); |
|
301 } |
|
302 if (extraData.stretch > -1) { |
|
303 OS.QFont_setStretch(handle, extraData.stretch); |
|
304 } |
|
305 if (extraData.fixedPitch > -1) { |
|
306 OS.QFont_setFixedPitch(handle, extraData.fixedPitch > 0 ? true |
|
307 : false); |
|
308 } |
|
309 if (extraData.style > -1) { |
|
310 OS.QFont_setStyle(handle, extraData.style); |
|
311 } |
|
312 if (extraData.weight > -1) { |
|
313 OS.QFont_setWeight(handle, extraData.weight); |
|
314 } |
|
315 if (extraData.styleStrategy > -1) { |
|
316 OS.QFont_setStyleStrategy(handle, extraData.styleStrategy); |
|
317 } |
|
318 extraFontStyle = true; |
|
319 } |
|
320 } |
|
321 |
|
322 /** |
|
323 * Returns <code>true</code> if the font has been disposed, and |
|
324 * <code>false</code> otherwise. |
|
325 * <p> |
|
326 * This method gets the dispose state for the font. When a font has been |
|
327 * disposed, it is an error to invoke any other method using the font. |
|
328 * |
|
329 * @return <code>true</code> when the font is disposed and |
|
330 * <code>false</code> otherwise |
|
331 */ |
|
332 public boolean isDisposed() { |
|
333 return handle == 0; |
|
334 } |
|
335 |
|
336 /** |
|
337 * Returns a string containing a concise, human-readable description of the |
|
338 * receiver. |
|
339 * |
|
340 * @return a string representation of the receiver |
|
341 */ |
|
342 public String toString() { |
|
343 if (isDisposed()) |
|
344 return "Font {*DISPOSED*}"; |
|
345 return "Font {" + handle + "}"; |
|
346 } |
|
347 |
|
348 /* |
|
349 * Invokes platform specific functionality to allocate a new font. |
|
350 */ |
|
351 static Font qt_new(Device device, int handle) { |
|
352 if (handle <= 0) |
|
353 return null; |
|
354 if (device == null) |
|
355 device = Device.getDevice(); |
|
356 if (device == null) |
|
357 SWT.error(SWT.ERROR_NULL_ARGUMENT); |
|
358 Font font = new Font(); |
|
359 font.handle = handle; |
|
360 font.device = device; |
|
361 return font; |
|
362 } |
|
363 |
|
364 } |