1 /* 2 * Distributed under the Boost Software License, Version 1.0. 3 * (See accompanying file LICENSE_1_0.txt or copy at 4 * http://www.boost.org/LICENSE_1_0.txt) 5 */ 6 module pango.attributes; 7 8 import pango.utils; 9 import pango.font; 10 import pango.language; 11 import pango.gravity; 12 import pango.types; 13 import pango.c.attributes; 14 import pango.c.font; 15 import pango.c.gravity; 16 17 import glib; 18 19 import std..string; 20 import std.typecons; 21 22 23 /* Color */ 24 /** 25 * PangoColor: 26 * @red: value of red component 27 * @green: value of green component 28 * @blue: value of blue component 29 * 30 * The #PangoColor structure is used to 31 * represent a color in an uncalibrated RGB color-space. 32 */ 33 34 alias Color = PangoColor; 35 36 bool parseColor(string spec, out Color color) { 37 return cast(bool)pango_color_parse(&color, toStringz(spec)); 38 } 39 40 41 string toString(in Color color) { 42 auto str = pango_color_to_string(&color); 43 scope(exit) g_free(str); 44 return fromStringz(str).dup; 45 } 46 47 48 /** 49 * PangoAttrIterator: 50 * 51 * The #PangoAttrIterator structure is used to represent an 52 * iterator through a #PangoAttrList. A new iterator is created 53 * with pango_attr_list_get_iterator(). Once the iterator 54 * is created, it can be advanced through the style changes 55 * in the text using pango_attr_iterator_next(). At each 56 * style change, the range of the current style segment and the 57 * attributes currently in effect can be queried. 58 */ 59 /** 60 * PangoAttrList: 61 * 62 * The #PangoAttrList structure represents a list of attributes 63 * that apply to a section of text. The attributes are, in general, 64 * allowed to overlap in an arbitrary fashion, however, if the 65 * attributes are manipulated only through pango_attr_list_change(), 66 * the overlap between properties will meet stricter criteria. 67 * 68 * Since the #PangoAttrList structure is stored as a linear list, 69 * it is not suitable for storing attributes for large amounts 70 * of text. In general, you should not use a single #PangoAttrList 71 * for more than one paragraph of text. 72 */ 73 74 /** 75 * PangoAttrType: 76 * @PANGO_ATTR_INVALID: does not happen 77 * @PANGO_ATTR_LANGUAGE: language (#PangoAttrLanguage) 78 * @PANGO_ATTR_FAMILY: font family name list (#PangoAttrString) 79 * @PANGO_ATTR_STYLE: font slant style (#PangoAttrInt) 80 * @PANGO_ATTR_WEIGHT: font weight (#PangoAttrInt) 81 * @PANGO_ATTR_VARIANT: font variant (normal or small caps) (#PangoAttrInt) 82 * @PANGO_ATTR_STRETCH: font stretch (#PangoAttrInt) 83 * @PANGO_ATTR_SIZE: font size in points scaled by %PANGO_SCALE (#PangoAttrInt) 84 * @PANGO_ATTR_FONT_DESC: font description (#PangoAttrFontDesc) 85 * @PANGO_ATTR_FOREGROUND: foreground color (#PangoAttrColor) 86 * @PANGO_ATTR_BACKGROUND: background color (#PangoAttrColor) 87 * @PANGO_ATTR_UNDERLINE: whether the text has an underline (#PangoAttrInt) 88 * @PANGO_ATTR_STRIKETHROUGH: whether the text is struck-through (#PangoAttrInt) 89 * @PANGO_ATTR_RISE: baseline displacement (#PangoAttrInt) 90 * @PANGO_ATTR_SHAPE: shape (#PangoAttrShape) 91 * @PANGO_ATTR_SCALE: font size scale factor (#PangoAttrFloat) 92 * @PANGO_ATTR_FALLBACK: whether fallback is enabled (#PangoAttrInt) 93 * @PANGO_ATTR_LETTER_SPACING: letter spacing (#PangoAttrInt) 94 * @PANGO_ATTR_UNDERLINE_COLOR: underline color (#PangoAttrColor) 95 * @PANGO_ATTR_STRIKETHROUGH_COLOR: strikethrough color (#PangoAttrColor) 96 * @PANGO_ATTR_ABSOLUTE_SIZE: font size in pixels scaled by %PANGO_SCALE (#PangoAttrInt) 97 * @PANGO_ATTR_GRAVITY: base text gravity (#PangoAttrInt) 98 * @PANGO_ATTR_GRAVITY_HINT: gravity hint (#PangoAttrInt) 99 * 100 * The #PangoAttrType 101 * distinguishes between different types of attributes. Along with the 102 * predefined values, it is possible to allocate additional values 103 * for custom attributes using pango_attr_type_register(). The predefined 104 * values are given below. The type of structure used to store the 105 * attribute is listed in parentheses after the description. 106 */ 107 enum AttrType 108 { 109 Invalid = PangoAttrType.PANGO_ATTR_INVALID, /* 0 is an invalid attribute type */ 110 Language = PangoAttrType.PANGO_ATTR_LANGUAGE, /* PangoAttrLanguage */ 111 Family = PangoAttrType.PANGO_ATTR_FAMILY, /* PangoAttrString */ 112 Style = PangoAttrType.PANGO_ATTR_STYLE, /* PangoAttrInt */ 113 Weight = PangoAttrType.PANGO_ATTR_WEIGHT, /* PangoAttrInt */ 114 Variant = PangoAttrType.PANGO_ATTR_VARIANT, /* PangoAttrInt */ 115 Stretch = PangoAttrType.PANGO_ATTR_STRETCH, /* PangoAttrInt */ 116 Size = PangoAttrType.PANGO_ATTR_SIZE, /* PangoAttrSize */ 117 FontDesc = PangoAttrType.PANGO_ATTR_FONT_DESC, /* PangoAttrFontDesc */ 118 Foreground = PangoAttrType.PANGO_ATTR_FOREGROUND, /* PangoAttrColor */ 119 Background = PangoAttrType.PANGO_ATTR_BACKGROUND, /* PangoAttrColor */ 120 Underline = PangoAttrType.PANGO_ATTR_UNDERLINE, /* PangoAttrInt */ 121 Strikethrough = PangoAttrType.PANGO_ATTR_STRIKETHROUGH, /* PangoAttrInt */ 122 Rise = PangoAttrType.PANGO_ATTR_RISE, /* PangoAttrInt */ 123 Shape = PangoAttrType.PANGO_ATTR_SHAPE, /* PangoAttrShape */ 124 Scale = PangoAttrType.PANGO_ATTR_SCALE, /* PangoAttrFloat */ 125 Fallback = PangoAttrType.PANGO_ATTR_FALLBACK, /* PangoAttrInt */ 126 LetterSpacing = PangoAttrType.PANGO_ATTR_LETTER_SPACING, /* PangoAttrInt */ 127 UnderlineColor = PangoAttrType.PANGO_ATTR_UNDERLINE_COLOR, /* PangoAttrColor */ 128 StrikethroughColor = PangoAttrType.PANGO_ATTR_STRIKETHROUGH_COLOR,/* PangoAttrColor */ 129 AbsoluteSize = PangoAttrType.PANGO_ATTR_ABSOLUTE_SIZE, /* PangoAttrSize */ 130 Gravity = PangoAttrType.PANGO_ATTR_GRAVITY, /* PangoAttrInt */ 131 GravityHint = PangoAttrType.PANGO_ATTR_GRAVITY_HINT /* PangoAttrInt */ 132 } 133 134 135 @property string name(AttrType at) { 136 return fromStringz(pango_attr_type_get_name(cast(PangoAttrType)at)).idup; 137 } 138 139 /** 140 * PangoUnderline: 141 * @PANGO_UNDERLINE_NONE: no underline should be drawn 142 * @PANGO_UNDERLINE_SINGLE: a single underline should be drawn 143 * @PANGO_UNDERLINE_DOUBLE: a double underline should be drawn 144 * @PANGO_UNDERLINE_LOW: a single underline should be drawn at a position 145 * beneath the ink extents of the text being 146 * underlined. This should be used only for underlining 147 * single characters, such as for keyboard 148 * accelerators. %PANGO_UNDERLINE_SINGLE should 149 * be used for extended portions of text. 150 * @PANGO_UNDERLINE_ERROR: a wavy underline should be drawn below. 151 * This underline is typically used to indicate 152 * an error such as a possilble mispelling; in some 153 * cases a contrasting color may automatically 154 * be used. This type of underlining is available since Pango 1.4. 155 * 156 * The #PangoUnderline enumeration is used to specify 157 * whether text should be underlined, and if so, the type 158 * of underlining. 159 */ 160 enum Underline { 161 None = PangoUnderline.PANGO_UNDERLINE_NONE, 162 Single = PangoUnderline.PANGO_UNDERLINE_SINGLE, 163 Double = PangoUnderline.PANGO_UNDERLINE_DOUBLE, 164 Low = PangoUnderline.PANGO_UNDERLINE_LOW, 165 Error = PangoUnderline.PANGO_UNDERLINE_ERROR 166 } 167 168 169 170 abstract class Attribute 171 { 172 mixin NativePtrHolder!(PangoAttribute, pango_attribute_destroy); 173 174 package this (PangoAttribute *ptr, Transfer transfer) { 175 initialize(ptr, transfer); 176 } 177 178 pure @property inout(PangoAttribute)* nativePtr() inout { return nativePtr_; } 179 180 @property AttrType type() const { 181 if (!nativePtr.klass) return AttrType.Invalid; 182 return cast(AttrType) nativePtr.klass.type; 183 } 184 185 static Attribute getAttrDObject(PangoAttribute *attr, Transfer transfer) 186 { 187 if (!attr || !attr.klass) return null; 188 189 final switch(cast(AttrType)(attr.klass.type)) { 190 case AttrType.Language: 191 return getDObject!AttrLanguage(cast(PangoAttrLanguage*)attr, transfer); 192 case AttrType.Family: 193 return getDObject!AttrString(cast(PangoAttrString*)attr, transfer); 194 case AttrType.Style: 195 case AttrType.Weight: 196 case AttrType.Variant: 197 case AttrType.Stretch: 198 case AttrType.Underline: 199 case AttrType.Strikethrough: 200 case AttrType.Rise: 201 case AttrType.Fallback: 202 case AttrType.LetterSpacing: 203 case AttrType.Gravity: 204 case AttrType.GravityHint: 205 return getDObject!AttrInt(cast(PangoAttrInt*)attr, transfer); 206 case AttrType.Size: 207 case AttrType.AbsoluteSize: 208 return getDObject!AttrSize(cast(PangoAttrSize*)attr, transfer); 209 case AttrType.FontDesc: 210 return getDObject!AttrFontDesc(cast(PangoAttrFontDesc*)attr, transfer); 211 case AttrType.Foreground: 212 case AttrType.Background: 213 case AttrType.UnderlineColor: 214 case AttrType.StrikethroughColor: 215 return getDObject!AttrColor(cast(PangoAttrColor*)attr, transfer); 216 case AttrType.Shape: 217 return getDObject!AttrShape(cast(PangoAttrShape*)attr, transfer); 218 case AttrType.Scale: 219 return getDObject!AttrFloat(cast(PangoAttrFloat*)attr, transfer); 220 case AttrType.Invalid: 221 return null; 222 } 223 } 224 225 //void pango_attribute_init (PangoAttribute *attr, 226 // const(PangoAttrClass) *klass); 227 228 abstract Attribute copy() const; 229 230 pure bool equal(const(Attribute) attr) 231 { 232 if (!attr) return false; 233 return cast(bool)pango_attribute_equal(nativePtr, attr.nativePtr); 234 } 235 236 pure override bool opEquals(Object obj) const 237 { 238 if (!obj) return false; 239 auto attr = cast(const(Attribute))obj; 240 if (!attr) return false; 241 return cast(bool)pango_attribute_equal(nativePtr, attr.nativePtr); 242 } 243 244 static Attribute languageNew(Language language) { 245 return getDObject!AttrLanguage(cast(PangoAttrLanguage*) 246 pango_attr_language_new(language.nativePtr), 247 Transfer.Full); 248 } 249 250 static Attribute familyNew(string family) { 251 return getDObject!AttrString(cast(PangoAttrString*)pango_attr_family_new(toStringz(family)), Transfer.Full); 252 } 253 254 static Attribute foregroundNew(ushort red, ushort green, ushort blue) { 255 return getDObject!AttrColor(cast(PangoAttrColor*)pango_attr_foreground_new(red, green, blue), Transfer.Full); 256 } 257 258 static Attribute backgroundNew(ushort red, ushort green, ushort blue) { 259 return getDObject!AttrColor(cast(PangoAttrColor*)pango_attr_background_new(red, green, blue), Transfer.Full); 260 } 261 262 static Attribute sizeNew(int size) { 263 return getDObject!AttrSize(cast(PangoAttrSize*)pango_attr_size_new(size), Transfer.Full); 264 } 265 266 static Attribute sizeNewAbsolute(int size) { 267 return getDObject!AttrSize(cast(PangoAttrSize*)pango_attr_size_new_absolute(size), Transfer.Full); 268 } 269 270 static Attribute styleNew(Style style) { 271 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_style_new(cast(PangoStyle)style), Transfer.Full); 272 } 273 274 static Attribute weightNew(Weight weight) { 275 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_weight_new(cast(PangoWeight)weight), Transfer.Full); 276 } 277 278 static Attribute variantNew(Variant variant) { 279 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_variant_new(cast(PangoVariant)variant), Transfer.Full); 280 } 281 282 static Attribute stretchNew(Stretch stretch) { 283 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_stretch_new(cast(PangoStretch)stretch), Transfer.Full); 284 } 285 286 static Attribute fontDescNew(const(FontDescription) fontDesc) { 287 return getDObject!AttrFontDesc(cast(PangoAttrFontDesc*)pango_attr_font_desc_new(fontDesc.nativePtr), Transfer.Full); 288 } 289 290 static Attribute underlineNew(Underline underline) { 291 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_underline_new(cast(PangoUnderline)underline), Transfer.Full); 292 } 293 294 static Attribute underlineColorNew(ushort red, ushort green, ushort blue) { 295 return getDObject!AttrColor(cast(PangoAttrColor*)pango_attr_underline_color_new(red, green, blue), Transfer.Full); 296 } 297 298 static Attribute strikethroughNew(bool strikethrough) { 299 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_strikethrough_new(strikethrough), Transfer.Full); 300 } 301 302 static Attribute strikethroughColorNew(ushort red, ushort green, ushort blue) { 303 return getDObject!AttrColor(cast(PangoAttrColor*)pango_attr_strikethrough_color_new(red, green, blue), Transfer.Full); 304 } 305 306 static Attribute riseNew(int rise) { 307 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_rise_new(rise), Transfer.Full); 308 } 309 310 static Attribute scaleNew(double scaleFactor) { 311 return getDObject!AttrFloat(cast(PangoAttrFloat*)pango_attr_scale_new(scaleFactor), Transfer.Full); 312 } 313 314 static Attribute fallbackNew(bool enableFallback) { 315 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_fallback_new(enableFallback), Transfer.Full); 316 } 317 318 static Attribute letterSpacingNew(int letterSpacing) { 319 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_letter_spacing_new(letterSpacing), Transfer.Full); 320 } 321 322 static Attribute shapeNew(in Rectangle inkRect, in Rectangle logicalRect) { 323 return getDObject!AttrShape(cast(PangoAttrShape*)pango_attr_shape_new(&inkRect, &logicalRect), Transfer.Full); 324 } 325 326 //PangoAttribute *pango_attr_shape_new_with_data (const(PangoRectangle) *ink_rect, 327 // const(PangoRectangle) *logical_rect, 328 // gpointer data, 329 // PangoAttrDataCopyFunc copy_func, 330 // GDestroyNotify destroy_func); 331 332 static Attribute gravityNew(Gravity gravity) { 333 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_gravity_new(cast(PangoGravity)gravity), Transfer.Full); 334 } 335 336 static Attribute gravityHintNew(GravityHint hint) { 337 return getDObject!AttrInt(cast(PangoAttrInt*)pango_attr_gravity_hint_new(cast(PangoGravityHint)hint), Transfer.Full); 338 } 339 340 } 341 342 343 class AttrWithType(PangoAttrType) : Attribute 344 { 345 package this(PangoAttrType *attr, Transfer transfer) { 346 super(cast(PangoAttribute*)attr, transfer); 347 } 348 349 override Attribute copy() const { 350 return getDObject!(AttrWithType!(PangoAttrType)) ( 351 cast(PangoAttrType*)pango_attribute_copy(nativePtr), 352 Transfer.Full 353 ); 354 } 355 } 356 357 alias AttrLanguage = AttrWithType!PangoAttrLanguage; 358 alias AttrString = AttrWithType!PangoAttrString; 359 alias AttrInt = AttrWithType!PangoAttrInt; 360 alias AttrSize = AttrWithType!PangoAttrSize; 361 alias AttrFontDesc = AttrWithType!PangoAttrFontDesc; 362 alias AttrColor = AttrWithType!PangoAttrColor; 363 alias AttrShape = AttrWithType!PangoAttrShape; 364 alias AttrFloat = AttrWithType!PangoAttrFloat; 365 366 367 struct AttrList 368 { 369 mixin RefCountedGObj!(PangoAttrList, "pango_attr_list"); 370 371 package this(PangoAttrList *ptr, Transfer transfer) { 372 initialize(ptr, transfer); 373 } 374 375 AttrList create() { 376 return AttrList(pango_attr_list_new(), Transfer.Full); 377 } 378 379 //PangoAttrList * pango_attr_list_copy (PangoAttrList *list); 380 381 void insert(Attribute attr) { 382 pango_attr_list_insert(nativePtr, attr.nativePtr); 383 } 384 385 void insertBefore(Attribute attr) { 386 pango_attr_list_insert_before(nativePtr, attr.nativePtr); 387 } 388 389 void change(Attribute attr) { 390 pango_attr_list_change(nativePtr, attr.nativePtr); 391 } 392 393 void splice(AttrList other, int pos, int len) { 394 pango_attr_list_splice(nativePtr, other.nativePtr, pos, len); 395 } 396 397 AttrList filter(PangoAttrFilterFunc func, gpointer data) { 398 return AttrList(pango_attr_list_filter(nativePtr, func, data), Transfer.Full); 399 } 400 401 @property AttrIterator iterator() { 402 return getDObject!AttrIterator(pango_attr_list_get_iterator(nativePtr), Transfer.Full); 403 } 404 405 406 } 407 408 409 class AttrIterator 410 { 411 mixin NativePtrHolder!(PangoAttrIterator, pango_attr_iterator_destroy); 412 413 package this(PangoAttrIterator* ptr, Transfer transfer) { 414 initialize(ptr, transfer); 415 } 416 417 418 void range (out int start, out int end) { 419 pango_attr_iterator_range(nativePtr, &start, &end); 420 } 421 422 bool next() { 423 return cast(bool)pango_attr_iterator_next(nativePtr); 424 } 425 426 Attribute get(AttrType type) { 427 return Attribute.getAttrDObject(pango_attr_iterator_get(nativePtr, cast(PangoAttrType)type), Transfer.None); 428 } 429 430 //void pango_attr_iterator_get_font (PangoAttrIterator *iterator, 431 // PangoFontDescription *desc, 432 // PangoLanguage **language, 433 // GSList **extra_attrs); 434 //GSList * pango_attr_iterator_get_attrs (PangoAttrIterator *iterator); 435 } 436 437 // 438 // 439 //gboolean pango_parse_markup (const(char) *markup_text, 440 // int length, 441 // gunichar accel_marker, 442 // PangoAttrList **attr_list, 443 // char **text, 444 // gunichar *accel_char, 445 // GError **error); 446 // 447 //GMarkupParseContext * pango_markup_parser_new (gunichar accel_marker); 448 //gboolean pango_markup_parser_finish (GMarkupParseContext *context, 449 // PangoAttrList **attr_list, 450 // char **text, 451 // gunichar *accel_char, 452 // GError **error); 453 // 454