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 }