| 1 | /* SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later */ |
| 2 | /* Copyright 2010, SIL International, All rights reserved. */ |
| 3 | #pragma once |
| 4 | |
| 5 | #include "graphite2/Types.h" |
| 6 | #include "graphite2/Font.h" |
| 7 | |
| 8 | #ifdef __cplusplus |
| 9 | extern "C" |
| 10 | { |
| 11 | #endif |
| 12 | |
| 13 | enum gr_break_weight { |
| 14 | gr_breakNone = 0, |
| 15 | /* after break weights */ |
| 16 | gr_breakWhitespace = 10, |
| 17 | gr_breakWord = 15, |
| 18 | gr_breakIntra = 20, |
| 19 | gr_breakLetter = 30, |
| 20 | gr_breakClip = 40, |
| 21 | /* before break weights */ |
| 22 | gr_breakBeforeWhitespace = -10, |
| 23 | gr_breakBeforeWord = -15, |
| 24 | gr_breakBeforeIntra = -20, |
| 25 | gr_breakBeforeLetter = -30, |
| 26 | gr_breakBeforeClip = -40 |
| 27 | }; |
| 28 | |
| 29 | enum gr_justFlags { |
| 30 | /// Indicates that this segment is a complete line |
| 31 | gr_justCompleteLine = 0, |
| 32 | /// Indicates that the start of the slot list is not at the start of a line |
| 33 | gr_justStartInline = 1, |
| 34 | /// Indicates that the end of the slot list is not at the end of a line |
| 35 | gr_justEndInline = 2 |
| 36 | }; |
| 37 | |
| 38 | /** Used for looking up slot attributes. Most are already available in other functions **/ |
| 39 | enum gr_attrCode { |
| 40 | /// adjusted glyph advance in x direction in design units |
| 41 | gr_slatAdvX = 0, |
| 42 | /// adjusted glyph advance in y direction (usually 0) in design units |
| 43 | gr_slatAdvY, |
| 44 | /// returns 0. Deprecated. |
| 45 | gr_slatAttTo, |
| 46 | /// This slot attaches to its parent at the given design units in the x direction |
| 47 | gr_slatAttX, |
| 48 | /// This slot attaches to its parent at the given design units in the y direction |
| 49 | gr_slatAttY, |
| 50 | /// This slot attaches to its parent at the given glyph point (not implemented) |
| 51 | gr_slatAttGpt, |
| 52 | /// x-direction adjustment from the given glyph point (not implemented) |
| 53 | gr_slatAttXOff, |
| 54 | /// y-direction adjustment from the given glyph point (not implemented) |
| 55 | gr_slatAttYOff, |
| 56 | /// Where on this glyph should align with the attachment point on the parent glyph in the x-direction. |
| 57 | gr_slatAttWithX, |
| 58 | /// Where on this glyph should align with the attachment point on the parent glyph in the y-direction |
| 59 | gr_slatAttWithY, |
| 60 | /// Which glyph point on this glyph should align with the attachment point on the parent glyph (not implemented). |
| 61 | gr_slatWithGpt, |
| 62 | /// Adjustment to gr_slatWithGpt in x-direction (not implemented) |
| 63 | gr_slatAttWithXOff, |
| 64 | /// Adjustment to gr_slatWithGpt in y-direction (not implemented) |
| 65 | gr_slatAttWithYOff, |
| 66 | /// Attach at given nesting level (not implemented) |
| 67 | gr_slatAttLevel, |
| 68 | /// Line break breakweight for this glyph |
| 69 | gr_slatBreak, |
| 70 | /// Ligature component reference (not implemented) |
| 71 | gr_slatCompRef, |
| 72 | /// bidi directionality of this glyph (not implemented) |
| 73 | gr_slatDir, |
| 74 | /// Whether insertion is allowed before this glyph |
| 75 | gr_slatInsert, |
| 76 | /// Final positioned position of this glyph relative to its parent in x-direction in pixels |
| 77 | gr_slatPosX, |
| 78 | /// Final positioned position of this glyph relative to its parent in y-direction in pixels |
| 79 | gr_slatPosY, |
| 80 | /// Amount to shift glyph by in x-direction design units |
| 81 | gr_slatShiftX, |
| 82 | /// Amount to shift glyph by in y-direction design units |
| 83 | gr_slatShiftY, |
| 84 | /// attribute user1 |
| 85 | gr_slatUserDefnV1, |
| 86 | /// not implemented |
| 87 | gr_slatMeasureSol, |
| 88 | /// not implemented |
| 89 | gr_slatMeasureEol, |
| 90 | /// Amount this slot can stretch (not implemented) |
| 91 | gr_slatJStretch, |
| 92 | /// Amount this slot can shrink (not implemented) |
| 93 | gr_slatJShrink, |
| 94 | /// Granularity by which this slot can stretch or shrink (not implemented) |
| 95 | gr_slatJStep, |
| 96 | /// Justification weight for this glyph (not implemented) |
| 97 | gr_slatJWeight, |
| 98 | /// Amount this slot mush shrink or stretch in design units |
| 99 | gr_slatJWidth = 29, |
| 100 | /// SubSegment split point |
| 101 | gr_slatSegSplit = gr_slatJStretch + 29, |
| 102 | /// User defined attribute, see subattr for user attr number |
| 103 | gr_slatUserDefn, |
| 104 | /// Bidi level |
| 105 | gr_slatBidiLevel = 56, |
| 106 | /// Collision flags |
| 107 | gr_slatColFlags, |
| 108 | /// Collision constraint rectangle left (bl.x) |
| 109 | gr_slatColLimitblx, |
| 110 | /// Collision constraint rectangle lower (bl.y) |
| 111 | gr_slatColLimitbly, |
| 112 | /// Collision constraint rectangle right (tr.x) |
| 113 | gr_slatColLimittrx, |
| 114 | /// Collision constraint rectangle upper (tr.y) |
| 115 | gr_slatColLimittry, |
| 116 | /// Collision shift x |
| 117 | gr_slatColShiftx, |
| 118 | /// Collision shift y |
| 119 | gr_slatColShifty, |
| 120 | /// Collision margin |
| 121 | gr_slatColMargin, |
| 122 | /// Margin cost weight |
| 123 | gr_slatColMarginWt, |
| 124 | // Additional glyph that excludes movement near this one: |
| 125 | gr_slatColExclGlyph, |
| 126 | gr_slatColExclOffx, |
| 127 | gr_slatColExclOffy, |
| 128 | // Collision sequence enforcing attributes: |
| 129 | gr_slatSeqClass, |
| 130 | gr_slatSeqProxClass, |
| 131 | gr_slatSeqOrder, |
| 132 | gr_slatSeqAboveXoff, |
| 133 | gr_slatSeqAboveWt, |
| 134 | gr_slatSeqBelowXlim, |
| 135 | gr_slatSeqBelowWt, |
| 136 | gr_slatSeqValignHt, |
| 137 | gr_slatSeqValignWt, |
| 138 | |
| 139 | /// not implemented |
| 140 | gr_slatMax, |
| 141 | /// not implemented |
| 142 | gr_slatNoEffect = gr_slatMax + 1 |
| 143 | }; |
| 144 | |
| 145 | enum gr_bidirtl { |
| 146 | /// Underlying paragraph direction is RTL |
| 147 | gr_rtl = 1, |
| 148 | /// Set this to not run the bidi pass internally, even if the font asks for it. |
| 149 | /// This presumes that the segment is in a single direction. Most of the time |
| 150 | /// this bit should be set unless you know you are passing full paragraphs of text. |
| 151 | gr_nobidi = 2, |
| 152 | /// Disable auto mirroring for rtl text |
| 153 | gr_nomirror = 4 |
| 154 | }; |
| 155 | |
| 156 | typedef struct gr_char_info gr_char_info; |
| 157 | typedef struct gr_segment gr_segment; |
| 158 | typedef struct gr_slot gr_slot; |
| 159 | |
| 160 | /** Returns Unicode character for a charinfo. |
| 161 | * |
| 162 | * @param p Pointer to charinfo to return information on. |
| 163 | */ |
| 164 | GR2_API unsigned int gr_cinfo_unicode_char(const gr_char_info* p/*not NULL*/); |
| 165 | |
| 166 | /** Returns breakweight for a charinfo. |
| 167 | * |
| 168 | * @return Breakweight is a number between -50 and 50 indicating the cost of a |
| 169 | * break before or after this character. If the value < 0, the absolute value |
| 170 | * is this character's contribution to the overall breakweight before it. If the value |
| 171 | * > 0, then the value is this character's contribution to the overall breakweight after it. |
| 172 | * The overall breakweight between two characters is the maximum of the breakweight |
| 173 | * contributions from the characters either side of it. If a character makes no |
| 174 | * contribution to the breakweight on one side of it, the contribution is considered |
| 175 | * to be 0. |
| 176 | * @param p Pointer to charinfo to return information on. |
| 177 | */ |
| 178 | GR2_API int gr_cinfo_break_weight(const gr_char_info* p/*not NULL*/); |
| 179 | |
| 180 | /** Returns the slot index that after this character is after in the slot stream |
| 181 | * |
| 182 | * In effect each character is associated with a set of slots and this returns |
| 183 | * the index of the last slot in the segment this character is associated with. |
| 184 | * |
| 185 | * @return after slot index between 0 and gr_seg_n_slots() |
| 186 | * @param p Pointer to charinfo to return information on. |
| 187 | */ |
| 188 | GR2_API int gr_cinfo_after(const gr_char_info* p/*not NULL*/); |
| 189 | |
| 190 | /** Returns the slot index that before this character is before in the slot stream |
| 191 | * |
| 192 | * In effect each character is associated with a set of slots and this returns |
| 193 | * the index of the first slot in the segment this character is associated with. |
| 194 | * |
| 195 | * @return before slot index between 0 and gr_seg_n_slots() |
| 196 | * @param p Pointer to charinfo to return information on. |
| 197 | */ |
| 198 | GR2_API int gr_cinfo_before(const gr_char_info* p/*not NULL*/); |
| 199 | |
| 200 | /** Returns the code unit index of this character in the input string |
| 201 | * |
| 202 | * @return code unit index between 0 and the end of the string |
| 203 | * @param p Pointer to charinfo to return information on. |
| 204 | */ |
| 205 | GR2_API size_t gr_cinfo_base(const gr_char_info* p/*not NULL*/); |
| 206 | |
| 207 | /** Returns the number of unicode characters in a string. |
| 208 | * |
| 209 | * @return number of characters in the string |
| 210 | * @param enc Specifies the type of data in the string: utf8, utf16, utf32 |
| 211 | * @param buffer_begin The start of the string |
| 212 | * @param buffer_end Measure up to the first nul or when end is reached, whichever is earliest. |
| 213 | * This parameter may be NULL. |
| 214 | * @param pError If there is a structural fault in the string, the location is returned |
| 215 | * in this variable. If no error occurs, pError will contain NULL. NULL |
| 216 | * may be passed for pError if no such information is required. |
| 217 | */ |
| 218 | GR2_API size_t gr_count_unicode_characters(enum gr_encform enc, const void* buffer_begin, const void* buffer_end, const void** pError); |
| 219 | |
| 220 | /** Creates and returns a segment. |
| 221 | * |
| 222 | * @return a segment that needs seg_destroy called on it. May return NULL if bad problems |
| 223 | * in segment processing. |
| 224 | * @param font Gives the size of the font in pixels per em for final positioning. If |
| 225 | * NULL, positions are returned in design units, i.e. at a ppm of the upem |
| 226 | * of the face. |
| 227 | * @param face The face containing all the non-size dependent information. |
| 228 | * @param script This is a tag containing a script identifier that is used to choose |
| 229 | * which graphite table within the font to use. Maybe 0. Tag may be 4 chars |
| 230 | * NULL padded in LSBs or space padded in LSBs. |
| 231 | * @param pFeats Pointer to a feature values to be used for the segment. Only one |
| 232 | * feature values may be used for a segment. If NULL the default features |
| 233 | * for the font will be used. |
| 234 | * @param enc Specifies what encoding form the string is in (utf8, utf16, utf32) |
| 235 | * @param pStart Start of the string |
| 236 | * @param nChars Number of unicode characters to process in the string. The string will |
| 237 | * be processed either up to the first NULL or until nChars have been |
| 238 | * processed. nChars is also used to initialise the internal memory |
| 239 | * allocations of the segment. So it is wise not to make nChars too much |
| 240 | * greater than the actual number of characters being processed. |
| 241 | * @param dir Specifies whether the segment is processed right to left (1) or left to |
| 242 | * right (0) and whether to run the internal bidi pass, if a font requests it. |
| 243 | * See enum gr_bidirtl for details. |
| 244 | */ |
| 245 | GR2_API gr_segment* gr_make_seg(const gr_font* font, const gr_face* face, gr_uint32 script, const gr_feature_val* pFeats, enum gr_encform enc, const void* pStart, size_t nChars, int dir); |
| 246 | |
| 247 | /** Destroys a segment, freeing the memory. |
| 248 | * |
| 249 | * @param p The segment to destroy |
| 250 | */ |
| 251 | GR2_API void gr_seg_destroy(gr_segment* p); |
| 252 | |
| 253 | /** Returns the advance for the whole segment. |
| 254 | * |
| 255 | * Returns the width of the segment up to the next glyph origin after the segment |
| 256 | */ |
| 257 | GR2_API float gr_seg_advance_X(const gr_segment* pSeg/*not NULL*/); |
| 258 | |
| 259 | /** Returns the height advance for the segment. **/ |
| 260 | GR2_API float gr_seg_advance_Y(const gr_segment* pSeg/*not NULL*/); |
| 261 | |
| 262 | /** Returns the number of gr_char_infos in the segment. **/ |
| 263 | GR2_API unsigned int gr_seg_n_cinfo(const gr_segment* pSeg/*not NULL*/); |
| 264 | |
| 265 | /** Returns a gr_char_info at a given index in the segment. **/ |
| 266 | GR2_API const gr_char_info* gr_seg_cinfo(const gr_segment* pSeg/*not NULL*/, unsigned int index/*must be <number_of_CharInfo*/); |
| 267 | |
| 268 | /** Returns the number of glyph gr_slots in the segment. **/ |
| 269 | GR2_API unsigned int gr_seg_n_slots(const gr_segment* pSeg/*not NULL*/); //one slot per glyph |
| 270 | |
| 271 | /** Returns the first gr_slot in the segment. |
| 272 | * |
| 273 | * The first slot in a segment has a gr_slot_prev_in_segment() of NULL. Slots are owned |
| 274 | * by their segment and are destroyed along with the segment. |
| 275 | */ |
| 276 | GR2_API const gr_slot* gr_seg_first_slot(gr_segment* pSeg/*not NULL*/); //may give a base slot or a slot which is attached to another |
| 277 | |
| 278 | /** Returns the last gr_slot in the segment. |
| 279 | * |
| 280 | * The last slot in a segment has a gr_slot_next_in_segment() of NULL |
| 281 | */ |
| 282 | GR2_API const gr_slot* gr_seg_last_slot(gr_segment* pSeg/*not NULL*/); //may give a base slot or a slot which is attached to another |
| 283 | |
| 284 | /** Justifies a linked list of slots for a line to a given width |
| 285 | * |
| 286 | * Passed a pointer to the start of a linked list of slots corresponding to a line, as |
| 287 | * set up by gr_slot_linebreak_before, this function will position the glyphs in the line |
| 288 | * to take up the given width. It is possible to specify a subrange within the line to process. |
| 289 | * This allows skipping of line initial or final whitespace, for example. While this will ensure |
| 290 | * that the subrange fits width, the line will still be positioned with the first glyph of the |
| 291 | * line at 0. So the resulting positions may be beyond width. |
| 292 | * |
| 293 | * @return float The resulting width of the range of slots justified. |
| 294 | * @param pSeg Pointer to the segment |
| 295 | * @param pStart Pointer to the start of the line linked list (including skipped characters) |
| 296 | * @param pFont Font to use for positioning |
| 297 | * @param width Width in pixels in which to fit the line. If < 0. don't adjust natural width, just run justification passes |
| 298 | * to handle line end contextuals, if there are any. |
| 299 | * @param flags Indicates line ending types. Default is linked list is a full line |
| 300 | * @param pFirst If not NULL, the first slot in the list to be considered part of the line (so can skip) |
| 301 | * @param pLast If not NULL, the last slot to process in the line (allow say trailing whitespace to be skipped) |
| 302 | */ |
| 303 | GR2_API float gr_seg_justify(gr_segment* pSeg/*not NULL*/, const gr_slot* pStart/*not NULL*/, const gr_font *pFont, double width, enum gr_justFlags flags, const gr_slot* pFirst, const gr_slot* pLast); |
| 304 | |
| 305 | /** Returns the next slot along in the segment. |
| 306 | * |
| 307 | * Slots are held in a linked list. This returns the next in the linked list. The slot |
| 308 | * may or may not be attached to another slot. Returns NULL at the end of the segment. |
| 309 | */ |
| 310 | GR2_API const gr_slot* gr_slot_next_in_segment(const gr_slot* p); |
| 311 | |
| 312 | /** Returns the previous slot along in the segment. |
| 313 | * |
| 314 | * Slots are held in a doubly linked list. This returns the previos slot in the linked |
| 315 | * list. This slot may or may not be attached to it. Returns NULL at the start of the |
| 316 | * segment. |
| 317 | */ |
| 318 | GR2_API const gr_slot* gr_slot_prev_in_segment(const gr_slot* p); |
| 319 | |
| 320 | /** Returns the attachment parent slot of this slot. |
| 321 | * |
| 322 | * Attached slots form a tree. This returns the parent of this slot in that tree. A |
| 323 | * base glyph which is not attached to another glyph, always returns NULL. |
| 324 | */ |
| 325 | GR2_API const gr_slot* gr_slot_attached_to(const gr_slot* p); |
| 326 | |
| 327 | /** Returns the first slot attached to this slot. |
| 328 | * |
| 329 | * Attached slots form a singly linked list from the parent. This returns the first |
| 330 | * slot in that list. Note that this is a reference to another slot that is also in |
| 331 | * the main segment doubly linked list. |
| 332 | * |
| 333 | * if gr_slot_first_attachment(p) != NULL then gr_slot_attached_to(gr_slot_first_attachment(p)) == p. |
| 334 | */ |
| 335 | GR2_API const gr_slot* gr_slot_first_attachment(const gr_slot* p); |
| 336 | |
| 337 | /** Returns the next slot attached to our attachment parent. |
| 338 | * |
| 339 | * This returns the next slot in the singly linked list of slots attached to this |
| 340 | * slot's parent. If there are no more such slots, NULL is returned. If there is |
| 341 | * no parent, i.e. the passed slot is a cluster base, then the next cluster base |
| 342 | * in graphical order (ltr, even for rtl text) is returned. |
| 343 | * |
| 344 | * if gr_slot_next_sibling_attachment(p) != NULL then gr_slot_attached_to(gr_slot_next_sibling_attachment(p)) == gr_slot_attached_to(p). |
| 345 | */ |
| 346 | GR2_API const gr_slot* gr_slot_next_sibling_attachment(const gr_slot* p); |
| 347 | |
| 348 | |
| 349 | /** Returns glyph id of the slot |
| 350 | * |
| 351 | * Each slot has a glyphid which is rendered at the position given by the slot. This |
| 352 | * glyphid is the real glyph to be rendered and never a pseudo glyph. |
| 353 | */ |
| 354 | GR2_API unsigned short gr_slot_gid(const gr_slot* p); |
| 355 | |
| 356 | /** Returns X offset of glyph from start of segment **/ |
| 357 | GR2_API float gr_slot_origin_X(const gr_slot* p); |
| 358 | |
| 359 | /** Returns Y offset of glyph from start of segment **/ |
| 360 | GR2_API float gr_slot_origin_Y(const gr_slot* p); |
| 361 | |
| 362 | /** Returns the glyph advance for this glyph as adjusted for kerning |
| 363 | * |
| 364 | * @param p Slot to give results for |
| 365 | * @param face gr_face of the glyphs. May be NULL if unhinted advances used |
| 366 | * @param font gr_font to scale for pixel results. If NULL returns design |
| 367 | * units advance. If not NULL then returns pixel advance based |
| 368 | * on hinted or scaled glyph advances in the font. face must be |
| 369 | * passed for hinted advances to be used. |
| 370 | */ |
| 371 | GR2_API float gr_slot_advance_X(const gr_slot* p, const gr_face* face, const gr_font *font); |
| 372 | |
| 373 | /** Returns the vertical advance for the glyph in the slot adjusted for kerning |
| 374 | * |
| 375 | * Returns design units unless font is not NULL in which case the pixel value |
| 376 | * is returned scaled for the given font |
| 377 | */ |
| 378 | GR2_API float gr_slot_advance_Y(const gr_slot* p, const gr_face* face, const gr_font *font); |
| 379 | |
| 380 | /** Returns the gr_char_info index before us |
| 381 | * |
| 382 | * Returns the index of the gr_char_info that a cursor before this slot, would put |
| 383 | * an underlying cursor before. This may also be interpretted as each slot holding |
| 384 | * a set of char_infos that it is associated with and this function returning the |
| 385 | * index of the char_info with lowest index, from this set. |
| 386 | */ |
| 387 | GR2_API int gr_slot_before(const gr_slot* p/*not NULL*/); |
| 388 | |
| 389 | /** Returns the gr_char_info index after us |
| 390 | * |
| 391 | * Returns the index of the gr_char_info that a cursor after this slot would put an |
| 392 | * underlying cursor after. This may also be interpretted as each slot holding a set |
| 393 | * of char_infos that it is associated with and this function returning the index of |
| 394 | * the char_info with the highest index, from this set. |
| 395 | */ |
| 396 | GR2_API int gr_slot_after(const gr_slot* p/*not NULL*/); |
| 397 | |
| 398 | /** Returns the index of this slot in the segment |
| 399 | * |
| 400 | * Returns the index given to this slot during final positioning. This corresponds |
| 401 | * to the value returned br gr_cinfo_before() and gr_cinfo_after() |
| 402 | */ |
| 403 | GR2_API unsigned int gr_slot_index(const gr_slot* p/*not NULL*/); |
| 404 | |
| 405 | /** Return a slot attribute value |
| 406 | * |
| 407 | * Given a slot and an attribute along with a possible subattribute, return the |
| 408 | * corresponding value in the slot. See enum gr_attrCode for details of each attribute. |
| 409 | */ |
| 410 | GR2_API int gr_slot_attr(const gr_slot* p/*not NULL*/, const gr_segment* pSeg/*not NULL*/, enum gr_attrCode index, gr_uint8 subindex); //tbd - do we need to expose this? |
| 411 | |
| 412 | /** Returns whether text may be inserted before this glyph. |
| 413 | * |
| 414 | * This indicates whether a cursor can be put before this slot. It applies to |
| 415 | * base glyphs that have no parent as well as attached glyphs that have the |
| 416 | * .insert attribute explicitly set to true. This is the primary mechanism |
| 417 | * for identifying contiguous sequences of base plus diacritics. |
| 418 | */ |
| 419 | GR2_API int gr_slot_can_insert_before(const gr_slot* p); |
| 420 | |
| 421 | /** Returns the original gr_char_info index this slot refers to. |
| 422 | * |
| 423 | * Each Slot has a gr_char_info that it originates from. This is that gr_char_info. |
| 424 | * The index is passed to gr_seg_cinfo(). This information is useful for testing. |
| 425 | */ |
| 426 | GR2_API int gr_slot_original(const gr_slot* p/*not NULL*/); |
| 427 | |
| 428 | /** Breaks a segment into lines. |
| 429 | * |
| 430 | * Breaks the slot linked list at the given point in the linked list. It is up |
| 431 | * to the application to keep track of the first slot on each line. |
| 432 | */ |
| 433 | GR2_API void gr_slot_linebreak_before(gr_slot *p/*not NULL*/); |
| 434 | |
| 435 | #ifdef __cplusplus |
| 436 | } |
| 437 | #endif |
| 438 | |