1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  * Port to the D programming language:
11  *     Frank Benoit <benoit@tionex.de>
12  *******************************************************************************/
13 module org.eclipse.swt.graphics.FontData;
14 
15 import java.lang.all;
16 
17 import org.eclipse.swt.SWT;
18 
19 version(Tango){
20     import tango.util.Convert;
21 } else { // Phobos
22     import std.conv;
23 }
24 
25 /**
26  * Instances of this class describe operating system fonts.
27  * <p>
28  * For platform-independent behaviour, use the get and set methods
29  * corresponding to the following properties:
30  * <dl>
31  * <dt>height</dt><dd>the height of the font in points</dd>
32  * <dt>name</dt><dd>the face name of the font, which may include the foundry</dd>
33  * <dt>style</dt><dd>A bitwise combination of NORMAL, ITALIC and BOLD</dd>
34  * </dl>
35  * If extra, platform-dependent functionality is required:
36  * <ul>
37  * <li>On <em>Windows</em>, the data member of the <code>FontData</code>
38  * corresponds to a Windows <code>LOGFONT</code> structure whose fields
39  * may be retrieved and modified.</li>
40  * <li>On <em>X</em>, the fields of the <code>FontData</code> correspond
41  * to the entries in the font's XLFD name and may be retrieved and modified.
42  * </ul>
43  * Application code does <em>not</em> need to explicitly release the
44  * resources managed by each instance when those instances are no longer
45  * required, and thus no <code>dispose()</code> method is provided.
46  *
47  * @see Font
48  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
49  */
50 public final class FontData {
51     /**
52      * the font name
53      * (Warning: This field is platform dependent)
54      * <p>
55      * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
56      * public API. It is marked public only so that it can be shared
57      * within the packages provided by SWT. It is not available on all
58      * platforms and should never be accessed from application code.
59      * </p>
60      */
61     public String name;
62 
63     /**
64      * The height of the font data in points
65      * (Warning: This field is platform dependent)
66      * <p>
67      * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
68      * public API. It is marked public only so that it can be shared
69      * within the packages provided by SWT. It is not available on all
70      * platforms and should never be accessed from application code.
71      * </p>
72      */
73     public float height = 0;
74 
75     /**
76      * the font style
77      * (Warning: This field is platform dependent)
78      * <p>
79      * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
80      * public API. It is marked public only so that it can be shared
81      * within the packages provided by SWT. It is not available on all
82      * platforms and should never be accessed from application code.
83      * </p>
84      */
85     public int style;
86 
87     /**
88      * the Pango string
89      * (Warning: This field is platform dependent)
90      * <p>
91      * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
92      * public API. It is marked public only so that it can be shared
93      * within the packages provided by SWT. It is not available on all
94      * platforms and should never be accessed from application code.
95      * </p>
96      */
97     public String str;
98 
99     /**
100      * The locales of the font
101      */
102     String lang, country, variant;
103 
104 /**
105  * Constructs a new uninitialized font data.
106  */
107 public this () {
108     this("", 12, SWT.NORMAL);
109 }
110 
111 /**
112  * Constructs a new FontData given a string representation
113  * in the form generated by the <code>FontData.toString</code>
114  * method.
115  * <p>
116  * Note that the representation varies between platforms,
117  * and a FontData can only be created from a string that was
118  * generated on the same platform.
119  * </p>
120  *
121  * @param string the string representation of a <code>FontData</code> (must not be null)
122  *
123  * @exception IllegalArgumentException <ul>
124  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
125  *    <li>ERROR_INVALID_ARGUMENT - if the argument does not represent a valid description</li>
126  * </ul>
127  *
128  * @see #toString
129  */
130 public this(String str) {
131     if (str is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
132     int start = 0;
133     auto end = indexOf( str, '|' );
134     if (end is -1 ) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
135     String version1 = str[ start .. end ];
136     try {
137         if (Integer.parseInt(version1) !is 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
138     } catch (NumberFormatException e) {
139         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
140     }
141 
142     start = end + 1;
143     end = indexOf( str, '|', start );
144     if (end is -1 ) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
145     String name = str[start .. end ];
146 
147     start = end + 1;
148     end = indexOf( str, '|', start );
149     if (end is -1 ) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
150     float height = 0;
151     try {
152         height = Float.parseFloat(str[start .. end]);
153     } catch (NumberFormatException e) {
154         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
155     }
156 
157     start = end + 1;
158     end = indexOf( str, '|', start );
159     if (end is -1 ) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
160     int style = 0;
161     try {
162         style = Integer.parseInt( str[start .. end ]);
163     } catch (NumberFormatException e) {
164         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
165     }
166 
167     start = end + 1;
168     end = indexOf( str, '|', start );
169     setName(name);
170     setHeight(height);
171     setStyle(style);
172     if (end is -1) return;
173     String platform = str[ start .. end ];
174 
175     start = end + 1;
176     end = indexOf( str, '|', start );
177     if (end is -1) return;
178     String version2 = str[ start .. end ];
179 
180     if (platform.equals("GTK") && version2.equals("1")) {
181         return;
182     }
183 }
184 
185 /**
186  * Constructs a new font data given a font name,
187  * the height of the desired font in points,
188  * and a font style.
189  *
190  * @param name the name of the font (must not be null)
191  * @param height the font height in points
192  * @param style a bit or combination of NORMAL, BOLD, ITALIC
193  *
194  * @exception IllegalArgumentException <ul>
195  *    <li>ERROR_NULL_ARGUMENT - when the font name is null</li>
196  *    <li>ERROR_INVALID_ARGUMENT - if the height is negative</li>
197  * </ul>
198  */
199 public this(String name, int height, int style) {
200     setName(name);
201     setHeight(height);
202     setStyle(style);
203 }
204 
205 /*public*/ this(String name, float height, int style) {
206     setName(name);
207     setHeight(height);
208     setStyle(style);
209 }
210 
211 /**
212  * Compares the argument to the receiver, and returns true
213  * if they represent the <em>same</em> object using a class
214  * specific comparison.
215  *
216  * @param object the object to compare with this object
217  * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
218  *
219  * @see #hashCode
220  */
221 public override equals_t opEquals (Object object) {
222     if (object is this) return true;
223     if( auto data = cast(FontData)object ){
224         return name.equals(data.name) && height is data.height && style is data.style;
225     }
226     return false;
227 }
228 
229 /**
230  * Returns the height of the receiver in points.
231  *
232  * @return the height of this FontData
233  *
234  * @see #setHeight(int)
235  */
236 public int getHeight() {
237     return cast(int)(0.5f + height);
238 }
239 
240 /*public*/ float getHeightF() {
241     return height;
242 }
243 
244 /**
245  * Returns the locale of the receiver.
246  * <p>
247  * The locale determines which platform character set this
248  * font is going to use. Widgets and graphics operations that
249  * use this font will convert UNICODE strings to the platform
250  * character set of the specified locale.
251  * </p>
252  * <p>
253  * On platforms where there are multiple character sets for a
254  * given language/country locale, the variant portion of the
255  * locale will determine the character set.
256  * </p>
257  *
258  * @return the <code>String</code> representing a Locale object
259  * @since 3.0
260  */
261 public String getLocale () {
262     String result;
263     const char sep = '_';
264     if (lang !is null) {
265         result ~= lang;
266         result ~= sep;
267     }
268     if (country !is null) {
269         result ~= country;
270         result ~= sep;
271     }
272     if (variant !is null) {
273         result ~= variant;
274     }
275 
276     if (result) {
277         if (result[$-1] is sep) {
278             result = result[0 .. $ - 1];
279         }
280     }
281 getDwtLogger().trace( __FILE__, __LINE__,  "getLocal {}", result );
282     return result;
283 }
284 
285 /**
286  * Returns the name of the receiver.
287  * On platforms that support font foundries, the return value will
288  * be the foundry followed by a dash ("-") followed by the face name.
289  *
290  * @return the name of this <code>FontData</code>
291  *
292  * @see #setName
293  */
294 public String getName() {
295     return name;
296 }
297 
298 /**
299  * Returns the style of the receiver which is a bitwise OR of
300  * one or more of the <code>SWT</code> constants NORMAL, BOLD
301  * and ITALIC.
302  *
303  * @return the style of this <code>FontData</code>
304  *
305  * @see #setStyle
306  */
307 public int getStyle() {
308     return style;
309 }
310 
311 /**
312  * Returns an integer hash code for the receiver. Any two
313  * objects that return <code>true</code> when passed to
314  * <code>equals</code> must return the same value for this
315  * method.
316  *
317  * @return the receiver's hash
318  *
319  * @see #equals
320  */
321 public override hash_t toHash () {
322     return typeid(String).getHash(&name) ^ cast(int)(0.5f + height) ^ style;
323 }
324 
325 /**
326  * Sets the height of the receiver. The parameter is
327  * specified in terms of points, where a point is one
328  * seventy-second of an inch.
329  *
330  * @param height the height of the <code>FontData</code>
331  *
332  * @exception IllegalArgumentException <ul>
333  *    <li>ERROR_INVALID_ARGUMENT - if the height is negative</li>
334  * </ul>
335  *
336  * @see #getHeight
337  */
338 public void setHeight(int height) {
339     if (height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
340     this.height = height;
341     this.str = null;
342 }
343 
344 /*public*/ void setHeight(float height) {
345     if (height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
346     this.height = height;
347     this.str = null;
348 }
349 
350 /**
351  * Sets the locale of the receiver.
352  * <p>
353  * The locale determines which platform character set this
354  * font is going to use. Widgets and graphics operations that
355  * use this font will convert UNICODE strings to the platform
356  * character set of the specified locale.
357  * </p>
358  * <p>
359  * On platforms where there are multiple character sets for a
360  * given language/country locale, the variant portion of the
361  * locale will determine the character set.
362  * </p>
363  *
364  * @param locale the <code>String</code> representing a Locale object
365  * @see java.util.Locale#toString
366  */
367 public void setLocale(String locale) {
368 getDwtLogger().trace( __FILE__, __LINE__,  "setLocal {}", locale );
369     lang = country = variant = null;
370     if (locale !is null) {
371         char sep = '_';
372         auto length = locale.length;
373         typeof(length) firstSep, secondSep;
374 
375         firstSep = indexOf( locale, sep );
376         if (firstSep is -1 ) {
377             firstSep = secondSep = length;
378         } else {
379             secondSep = indexOf( locale, sep, cast(int)/*64bit*/firstSep + 1);
380             if (secondSep is -1 ) secondSep = length;
381         }
382         if (firstSep > 0) lang = locale[0 .. firstSep];
383         if (secondSep > firstSep + 1) country = locale[firstSep + 1 .. secondSep ];
384         if (length > secondSep + 1) variant = locale[secondSep + 1 .. $ ];
385     }
386 }
387 
388 /**
389  * Sets the name of the receiver.
390  * <p>
391  * Some platforms support font foundries. On these platforms, the name
392  * of the font specified in setName() may have one of the following forms:
393  * <ol>
394  * <li>a face name (for example, "courier")</li>
395  * <li>a foundry followed by a dash ("-") followed by a face name (for example, "adobe-courier")</li>
396  * </ol>
397  * In either case, the name returned from getName() will include the
398  * foundry.
399  * </p>
400  * <p>
401  * On platforms that do not support font foundries, only the face name
402  * (for example, "courier") is used in <code>setName()</code> and
403  * <code>getName()</code>.
404  * </p>
405  *
406  * @param name the name of the font data (must not be null)
407  * @exception IllegalArgumentException <ul>
408  *    <li>ERROR_NULL_ARGUMENT - when the font name is null</li>
409  * </ul>
410  *
411  * @see #getName
412  */
413 public void setName(String name) {
414     if (name is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
415     this.name = name;
416     this.str = null;
417 }
418 
419 /**
420  * Sets the style of the receiver to the argument which must
421  * be a bitwise OR of one or more of the <code>SWT</code>
422  * constants NORMAL, BOLD and ITALIC.  All other style bits are
423  * ignored.
424  *
425  * @param style the new style for this <code>FontData</code>
426  *
427  * @see #getStyle
428  */
429 public void setStyle(int style) {
430     this.style = style;
431     this.str = null;
432 }
433 
434 /**
435  * Returns a string representation of the receiver which is suitable
436  * for constructing an equivalent instance using the
437  * <code>FontData(String)</code> constructor.
438  *
439  * @return a string representation of the FontData
440  *
441  * @see FontData
442  */
443 public override String toString() {
444     return Format( "1|{}|{}|{}|GTK|1|", getName, getHeightF, getStyle );
445 }
446 
447 }