1 module pango.font; 2 3 import pango.utils; 4 import pango.gravity; 5 import pango.coverage; 6 import pango.language; 7 import pango.types; 8 import pango.fontmap; 9 import pango.fontset; 10 import pango.c; 11 12 13 import gobject; 14 import glib; 15 16 import std..string; 17 18 19 20 21 /** 22 * Style: 23 * Normal: the font is upright. 24 * Oblique: the font is slanted, but in a roman style. 25 * Italic: the font is slanted in an italic style. 26 * 27 * An enumeration specifying the various slant styles possible for a font. 28 **/ 29 enum Style { 30 Normal = PangoStyle.PANGO_STYLE_NORMAL, 31 Oblique = PangoStyle.PANGO_STYLE_OBLIQUE, 32 Italic = PangoStyle.PANGO_STYLE_ITALIC 33 } 34 35 /** 36 * PangoVariant: 37 * Normal: A normal font. 38 * SmallCaps: A font with the lower case characters 39 * replaced by smaller variants of the capital characters. 40 * 41 * An enumeration specifying capitalization variant of the font. 42 */ 43 enum Variant { 44 Normal = PangoVariant.PANGO_VARIANT_NORMAL, 45 SmallCaps = PangoVariant.PANGO_VARIANT_SMALL_CAPS 46 } 47 48 /** 49 * Weight: 50 * Thin: the thin weight (= 100; Since: 1.24) 51 * UltraLight: the ultralight weight (= 200) 52 * Light: the light weight (= 300) 53 * SemiLight: the semilight weight (= 350; Since: 1.36.7) 54 * Book: the book weight (= 380; Since: 1.24) 55 * Normal: the default weight (= 400) 56 * Medium: the normal weight (= 500; Since: 1.24) 57 * SemiBold: the semibold weight (= 600) 58 * Bold: the bold weight (= 700) 59 * UltraBold: the ultrabold weight (= 800) 60 * Heavy: the heavy weight (= 900) 61 * UltraHeavy: the ultraheavy weight (= 1000; Since: 1.24) 62 * 63 * An enumeration specifying the weight (boldness) of a font. This is a numerical 64 * value ranging from 100 to 1000, but there are some predefined values: 65 */ 66 enum Weight { 67 Thin = 100, 68 UltraLight = 200, 69 Light = 300, 70 SemiLight = 350, 71 Book = 380, 72 Normal = 400, 73 Medium = 500, 74 SemiBold = 600, 75 Bold = 700, 76 UltraBold = 800, 77 Heavy = 900, 78 UltraHeavy = 1000 79 } 80 81 /** 82 * Stretch: 83 * UltraCondensed: ultra condensed width 84 * ExtraCondesed: extra condensed width 85 * Condensed: condensed width 86 * SemiCondensed: semi condensed width 87 * Normal: the normal width 88 * SemiExpanded: semi expanded width 89 * Expanded: expanded width 90 * ExtraExpanded: extra expanded width 91 * UltraExpanded: ultra expanded width 92 * 93 * An enumeration specifying the width of the font relative to other designs 94 * within a family. 95 */ 96 enum Stretch { 97 UltraCondensed = PangoStretch.PANGO_STRETCH_ULTRA_CONDENSED, 98 ExtraCondesed = PangoStretch.PANGO_STRETCH_EXTRA_CONDENSED, 99 Condensed = PangoStretch.PANGO_STRETCH_CONDENSED, 100 SemiCondensed = PangoStretch.PANGO_STRETCH_SEMI_CONDENSED, 101 Normal = PangoStretch.PANGO_STRETCH_NORMAL, 102 SemiExpanded = PangoStretch.PANGO_STRETCH_SEMI_EXPANDED, 103 Expanded = PangoStretch.PANGO_STRETCH_EXPANDED, 104 ExtraExpanded = PangoStretch.PANGO_STRETCH_EXTRA_EXPANDED, 105 UltraExpanded = PangoStretch.PANGO_STRETCH_ULTRA_EXPANDED 106 } 107 108 /** 109 * FontMask: 110 * Family: the font family is specified. 111 * Style: the font style is specified. 112 * Variant: the font variant is specified. 113 * Weight: the font weight is specified. 114 * Stretch: the font stretch is specified. 115 * Size: the font size is specified. 116 * Gravity: the font gravity is specified (Since: 1.16.) 117 * 118 * The bits in a #PangoFontMask correspond to fields in a 119 * #PangoFontDescription that have been set. 120 */ 121 enum FontMask { 122 Family = 1 << 0, 123 Style = 1 << 1, 124 Variant = 1 << 2, 125 Weight = 1 << 3, 126 Stretch = 1 << 4, 127 Size = 1 << 5, 128 Gravity = 1 << 6 129 } 130 131 132 /** 133 * Scale: CSS scale factors (1.2 factor between each size) 134 * XXSmall: the scale factor for three shrinking steps (1 / (1.2 * 1.2 * 1.2)) 135 * XSmall: the scale factor for two shrinking steps (1 / (1.2 * 1.2)) 136 * Small: the scale factor for one shrinking steps (1 / 1.2) 137 * Medium: the scale factor for normal size (1.0)) 138 * Large: the scale factor for one magnification step (1.2) 139 * XLarge: the scale factor for two magnification steps (1.2 * 1.2) 140 * XXLarge: the scale factor for three magnification steps (1.2 * 1.2 * 1.2) 141 */ 142 enum Scale : double { 143 XXSmall = PANGO_SCALE_XX_SMALL, 144 XSmall = PANGO_SCALE_X_SMALL, 145 Small = PANGO_SCALE_SMALL, 146 Medium = PANGO_SCALE_MEDIUM, 147 Large = PANGO_SCALE_LARGE, 148 XLarge = PANGO_SCALE_X_LARGE, 149 XXLarge = PANGO_SCALE_XX_LARGE, 150 } 151 152 153 154 class FontDescription 155 { 156 mixin NativePtrHolder!(PangoFontDescription, pango_font_description_free); 157 bool owned_ = true; 158 159 package this(PangoFontDescription *ptr, Transfer transfer) 160 { 161 initialize(ptr, transfer); 162 } 163 164 this() { 165 initialize(pango_font_description_new(), Transfer.Full); 166 } 167 168 this(string str) 169 { 170 initialize(pango_font_description_from_string(toStringz(str)), Transfer.Full); 171 } 172 173 174 FontDescription copy() const 175 { 176 return getDObject!FontDescription(pango_font_description_copy(nativePtr), Transfer.Full); 177 } 178 179 FontDescription copyStatic() const 180 { 181 return getDObject!FontDescription(pango_font_description_copy_static(nativePtr), Transfer.Full); 182 } 183 184 185 pure @property uint hash() const { return pango_font_description_hash(nativePtr); } 186 187 pure bool equal(const(FontDescription) other) const { 188 return cast(bool)pango_font_description_equal(nativePtr, other.nativePtr); 189 } 190 191 192 193 @property void family(string family) { 194 pango_font_description_set_family(nativePtr, family.toStringz); 195 } 196 197 @property void familyStatic(string family) { 198 pango_font_description_set_family_static(nativePtr, family.toStringz); 199 } 200 201 pure @property string family() const { 202 const(char)* f = pango_font_description_get_family(nativePtr); 203 if (f) return fromStringz(f).idup; 204 return ""; 205 } 206 207 208 209 @property void style(Style style) { 210 pango_font_description_set_style(nativePtr_, cast(PangoStyle)style); 211 } 212 213 pure @property Style style() const { 214 return cast(Style)pango_font_description_get_style(nativePtr); 215 } 216 217 218 219 @property void variant(Variant variant) { 220 pango_font_description_set_variant(nativePtr, cast(PangoVariant)variant); 221 } 222 223 pure @property Variant variant() const { 224 return cast(Variant)pango_font_description_get_variant(nativePtr); 225 } 226 227 228 229 @property void weight(Weight weight) { 230 pango_font_description_set_weight(nativePtr, cast(PangoWeight)weight); 231 } 232 233 pure @property Weight weight() const { 234 return cast(Weight)pango_font_description_get_weight(nativePtr); 235 } 236 237 238 239 @property void stretch(Stretch stretch) { 240 pango_font_description_set_stretch(nativePtr, cast(PangoStretch)stretch); 241 } 242 243 pure @property Stretch stretch() const { 244 return cast(Stretch)pango_font_description_get_stretch(nativePtr); 245 } 246 247 248 249 @property void size(int size) { 250 pango_font_description_set_size(nativePtr, size); 251 } 252 253 pure @property int size() const { 254 return pango_font_description_get_size(nativePtr); 255 } 256 257 @property void absoluteSize(double size) { 258 pango_font_description_set_absolute_size(nativePtr, size); 259 } 260 261 pure @property bool sizeIsAbsolute() const { 262 return cast(bool)pango_font_description_get_size_is_absolute(nativePtr); 263 } 264 265 266 267 @property void gravity(Gravity gravity) { 268 pango_font_description_set_gravity(nativePtr, cast(PangoGravity)gravity); 269 } 270 271 pure @property Gravity gravity() const { 272 return cast(Gravity)pango_font_description_get_gravity(nativePtr); 273 } 274 275 276 pure @property FontMask setFields() const { 277 return cast(FontMask)pango_font_description_get_set_fields(nativePtr); 278 } 279 280 void unsetFields(FontMask toUnset) { 281 pango_font_description_unset_fields(nativePtr, cast(PangoFontMask)toUnset); 282 } 283 284 285 286 void merge(const(FontDescription) other, bool replaceExisting) 287 { 288 pango_font_description_merge(nativePtr, other.nativePtr, replaceExisting); 289 } 290 291 void mergeStatic(const(FontDescription) other, bool replaceExisting) 292 { 293 pango_font_description_merge_static(nativePtr, other.nativePtr, replaceExisting); 294 } 295 296 bool betterMatch(const(FontDescription) oldMatch, const(FontDescription) newMatch) 297 { 298 return cast(bool)pango_font_description_better_match(nativePtr, 299 oldMatch.nativePtr, 300 newMatch.nativePtr); 301 } 302 303 304 override string toString() const { 305 char *s = pango_font_description_to_string(nativePtr); 306 if (s) { 307 string res = fromStringz(s).idup; 308 g_free(s); 309 return res; 310 } 311 return ""; 312 } 313 314 string toFilename() const { 315 char *s = pango_font_description_to_filename(nativePtr); 316 if (s) { 317 string res = fromStringz(s).idup; 318 g_free(s); 319 return res; 320 } 321 return ""; 322 } 323 } 324 325 326 327 struct FontMetrics 328 { 329 mixin RefCountedGObj!(PangoFontMetrics, "pango_font_metrics"); 330 331 package this(PangoFontMetrics *ptr, Transfer transfer) { 332 initialize(ptr, transfer); 333 } 334 335 version(Backend) { 336 static FontMetrics create() { 337 return FontMetrics(pango_font_metrics_new()); 338 } 339 } 340 341 342 pure @property int ascent() { 343 return pango_font_metrics_get_ascent(nativePtr); 344 } 345 346 pure @property int descent() { 347 return pango_font_metrics_get_descent(nativePtr); 348 } 349 350 pure @property int approximateCharWidth() { 351 return pango_font_metrics_get_approximate_char_width(nativePtr); 352 } 353 354 pure @property int approximateDigitWidth() { 355 return pango_font_metrics_get_approximate_digit_width(nativePtr); 356 } 357 358 pure @property int underlinePosition() { 359 return pango_font_metrics_get_underline_position(nativePtr); 360 } 361 362 pure @property int underlineThickness() { 363 return pango_font_metrics_get_underline_thickness(nativePtr); 364 } 365 366 pure @property int strikethroughPosition() { 367 return pango_font_metrics_get_strikethrough_position(nativePtr); 368 } 369 370 pure @property int strikethroughThickness() { 371 return pango_font_metrics_get_strikethrough_thickness(nativePtr); 372 } 373 374 } 375 376 377 378 class FontFamily : D_GObject 379 { 380 mixin GObjectHolder!PangoFontFamily; 381 382 package this(PangoFontFamily *ptr, Transfer transfer) { 383 super (cast(GObject*)ptr, transfer); 384 } 385 386 FontFace[] listFaces() 387 { 388 return listGObjects!(FontFace, pango_font_family_list_faces)(nativePtr, Transfer.None); 389 } 390 391 @property string name() { 392 const(char)* n = pango_font_family_get_name(nativePtr); 393 if (n) { 394 return fromStringz(n).idup; 395 } 396 return ""; 397 } 398 399 @property bool monospace() { 400 return cast(bool)pango_font_family_is_monospace(nativePtr); 401 } 402 } 403 404 405 406 407 class FontFace : D_GObject 408 { 409 mixin GObjectHolder!PangoFontFace; 410 411 package this(PangoFontFace *ptr, Transfer transfer) { 412 super (cast(GObject*)ptr, transfer); 413 } 414 415 FontDescription describe() { 416 return getDObject!FontDescription(pango_font_face_describe(nativePtr), Transfer.Full); 417 } 418 419 @property string faceName() { 420 const(char)* fn = pango_font_face_get_face_name(nativePtr); 421 if (fn) { 422 return fromStringz(fn).idup; 423 } 424 return ""; 425 } 426 427 int[] listSizes() 428 { 429 return listValues!(int, pango_font_face_list_sizes)(nativePtr); 430 } 431 432 @property bool isSynthesized() { 433 return cast(bool)pango_font_face_is_synthesized(nativePtr); 434 } 435 436 } 437 438 439 abstract class Font : D_GObject { 440 441 mixin GObjectHolder!PangoFont; 442 443 package this(PangoFont *ptr, Transfer transfer) { 444 super (cast(GObject*) ptr, transfer); 445 } 446 447 FontDescription describe() { 448 return getDObject!FontDescription(pango_font_describe(nativePtr), Transfer.Full); 449 } 450 451 FontDescription describeWithAbsoluteSize() { 452 return getDObject!FontDescription(pango_font_describe_with_absolute_size(nativePtr), Transfer.Full); 453 } 454 455 Coverage coverage(Language language) { 456 return getDObject!Coverage(pango_font_get_coverage(nativePtr, language.nativePtr), Transfer.Full); 457 } 458 459 460 version (Backend) { 461 // FIXME: should not be in Backend version 462 //PangoEngineShape * pango_font_find_shaper (PangoFont *font, 463 // PangoLanguage *language, 464 // guint32 ch); 465 } 466 467 FontMetrics metrics(Language language) { 468 return getDObject!FontMetrics(pango_font_get_metrics(nativePtr, language.nativePtr), Transfer.Full); 469 } 470 471 void glyphExtents(Glyph glyph, out Rectangle inkRect, out Rectangle logicalRect) { 472 pango_font_get_glyph_extents(nativePtr, glyph, &inkRect, &logicalRect); 473 } 474 475 476 @property FontMap fontMap() { 477 return cast(FontMap)getExistingDObject(pango_font_get_font_map(nativePtr), Transfer.None); 478 } 479 480 } 481 482 483 484 interface FontFactory { 485 486 FontMap getFontMap(PangoFontMap *ptr, Transfer transfer); 487 488 FontSet getFontSet(PangoFontset *ptr, Transfer transfer); 489 490 Font getFont(PangoFont *ptr, Transfer transfer); 491 } 492 493 494 class NullFontFactory : FontFactory { 495 496 FontMap getFontMap(PangoFontMap *ptr, Transfer transfer) { 497 return null; 498 } 499 500 FontSet getFontSet(PangoFontset *ptr, Transfer transfer) { 501 return null; 502 } 503 504 Font getFont(PangoFont *ptr, Transfer transfer) { 505 return null; 506 } 507 } 508 509 510 class ThrowFontFactory : FontFactory { 511 512 FontMap getFontMap(PangoFontMap *ptr, Transfer transfer) { 513 throw new Error("ThrowFontFactory.getFontMap"); 514 } 515 516 FontSet getFontSet(PangoFontset *ptr, Transfer transfer) { 517 throw new Error("ThrowFontFactory.getFontSet"); 518 } 519 520 Font getFont(PangoFont *ptr, Transfer transfer) { 521 throw new Error("ThrowFontFactory.getFont"); 522 } 523 } 524 525 526 @property FontFactory defaultFontFactory() { 527 static FontFactory inst; 528 if (!inst) inst = new ThrowFontFactory; 529 return inst; 530 } 531 532 533 mixin template FontFactoryHolder() 534 { 535 private FontFactory fontFactory_; 536 537 invariant() { 538 assert(fontFactory_ !is null); 539 } 540 541 @property inout(FontFactory) fontFactory() inout { 542 return fontFactory_; 543 } 544 545 @property void fontFactory(FontFactory ff) { 546 fontFactory_ = ff; 547 } 548 }