| 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 | |
| 4 | #pragma once |
| 5 | |
| 6 | #include "graphite2/Types.h" |
| 7 | #include "graphite2/Segment.h" |
| 8 | #include "inc/Main.h" |
| 9 | #include "inc/Font.h" |
| 10 | #include "inc/Position.h" |
| 11 | |
| 12 | namespace graphite2 { |
| 13 | |
| 14 | typedef gr_attrCode attrCode; |
| 15 | |
| 16 | class GlyphFace; |
| 17 | class Segment; |
| 18 | |
| 19 | struct SlotJustify |
| 20 | { |
| 21 | static const int NUMJUSTPARAMS = 5; |
| 22 | |
| 23 | SlotJustify(const SlotJustify &); |
| 24 | SlotJustify & operator = (const SlotJustify &); |
| 25 | |
| 26 | public: |
| 27 | static size_t size_of(size_t levels) { return sizeof(SlotJustify) + ((levels > 1 ? levels : 1)*NUMJUSTPARAMS - 1)*sizeof(int16); } |
| 28 | |
| 29 | void LoadSlot(const Slot *s, const Segment *seg); |
| 30 | |
| 31 | SlotJustify *next; |
| 32 | int16 values[1]; |
| 33 | }; |
| 34 | |
| 35 | class Slot |
| 36 | { |
| 37 | enum Flag |
| 38 | { |
| 39 | DELETED = 1, |
| 40 | INSERTED = 2, |
| 41 | COPIED = 4, |
| 42 | POSITIONED = 8, |
| 43 | ATTACHED = 16 |
| 44 | }; |
| 45 | |
| 46 | public: |
| 47 | struct iterator; |
| 48 | |
| 49 | unsigned short gid() const { return m_glyphid; } |
| 50 | Position origin() const { return m_position; } |
| 51 | float advance() const { return m_advance.x; } |
| 52 | void advance(Position &val) { m_advance = val; } |
| 53 | Position advancePos() const { return m_advance; } |
| 54 | int before() const { return m_before; } |
| 55 | int after() const { return m_after; } |
| 56 | uint32 index() const { return m_index; } |
| 57 | void index(uint32 val) { m_index = val; } |
| 58 | |
| 59 | Slot(int16 *m_userAttr = NULL); |
| 60 | void set(const Slot & slot, int charOffset, size_t numUserAttr, size_t justLevels, size_t numChars); |
| 61 | Slot *next() const { return m_next; } |
| 62 | void next(Slot *s) { m_next = s; } |
| 63 | Slot *prev() const { return m_prev; } |
| 64 | void prev(Slot *s) { m_prev = s; } |
| 65 | uint16 glyph() const { return m_realglyphid ? m_realglyphid : m_glyphid; } |
| 66 | void setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph = NULL); |
| 67 | void setRealGid(uint16 realGid) { m_realglyphid = realGid; } |
| 68 | void adjKern(const Position &pos) { m_shift = m_shift + pos; m_advance = m_advance + pos; } |
| 69 | void origin(const Position &pos) { m_position = pos + m_shift; } |
| 70 | void originate(int ind) { m_original = ind; } |
| 71 | int original() const { return m_original; } |
| 72 | void before(int ind) { m_before = ind; } |
| 73 | void after(int ind) { m_after = ind; } |
| 74 | bool isBase() const { return (!m_parent); } |
| 75 | void update(int numSlots, int numCharInfo, Position &relpos); |
| 76 | Position finalise(const Segment* seg, const Font* font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal, int depth = 0); |
| 77 | bool isDeleted() const { return (m_flags & DELETED) ? true : false; } |
| 78 | void markDeleted(bool state) { if (state) m_flags |= DELETED; else m_flags &= ~DELETED; } |
| 79 | bool isCopied() const { return (m_flags & COPIED) ? true : false; } |
| 80 | void markCopied(bool state) { if (state) m_flags |= COPIED; else m_flags &= ~COPIED; } |
| 81 | bool isPositioned() const { return (m_flags & POSITIONED) ? true : false; } |
| 82 | void markPositioned(bool state) { if (state) m_flags |= POSITIONED; else m_flags &= ~POSITIONED; } |
| 83 | bool isInsertBefore() const { return !(m_flags & INSERTED); } |
| 84 | uint8 getBidiLevel() const { return m_bidiLevel; } |
| 85 | void setBidiLevel(uint8 level) { m_bidiLevel = level; } |
| 86 | int8 getBidiClass(const Segment *seg); |
| 87 | int8 getBidiClass() const { return m_bidiCls; } |
| 88 | void setBidiClass(int8 cls) { m_bidiCls = cls; } |
| 89 | int16 *userAttrs() const { return m_userAttr; } |
| 90 | void userAttrs(int16 *p) { m_userAttr = p; } |
| 91 | void markInsertBefore(bool state) { if (!state) m_flags |= INSERTED; else m_flags &= ~INSERTED; } |
| 92 | void setAttr(Segment* seg, attrCode ind, uint8 subindex, int16 val, const SlotMap & map); |
| 93 | int getAttr(const Segment *seg, attrCode ind, uint8 subindex) const; |
| 94 | int getJustify(const Segment *seg, uint8 level, uint8 subindex) const; |
| 95 | void setJustify(Segment *seg, uint8 level, uint8 subindex, int16 value); |
| 96 | bool isLocalJustify() const { return m_justs != NULL; }; |
| 97 | void attachTo(Slot *ap) { m_parent = ap; } |
| 98 | Slot *attachedTo() const { return m_parent; } |
| 99 | Position attachOffset() const { return m_attach - m_with; } |
| 100 | Slot* firstChild() const { return m_child; } |
| 101 | void firstChild(Slot *ap) { m_child = ap; } |
| 102 | bool child(Slot *ap); |
| 103 | Slot* nextSibling() const { return m_sibling; } |
| 104 | void nextSibling(Slot *ap) { m_sibling = ap; } |
| 105 | bool sibling(Slot *ap); |
| 106 | bool removeChild(Slot *ap); |
| 107 | int32 clusterMetric(const Segment* seg, uint8 metric, uint8 attrLevel, bool rtl); |
| 108 | void positionShift(Position a) { m_position += a; } |
| 109 | void floodShift(Position adj, int depth = 0); |
| 110 | float just() const { return m_just; } |
| 111 | void just(float j) { m_just = j; } |
| 112 | Slot *nextInCluster(const Slot *s) const; |
| 113 | bool isChildOf(const Slot *base) const; |
| 114 | |
| 115 | CLASS_NEW_DELETE |
| 116 | |
| 117 | private: |
| 118 | Slot *m_next; // linked list of slots |
| 119 | Slot *m_prev; |
| 120 | unsigned short m_glyphid; // glyph id |
| 121 | uint16 m_realglyphid; |
| 122 | uint32 m_original; // charinfo that originated this slot (e.g. for feature values) |
| 123 | uint32 m_before; // charinfo index of before association |
| 124 | uint32 m_after; // charinfo index of after association |
| 125 | uint32 m_index; // slot index given to this slot during finalising |
| 126 | Slot *m_parent; // index to parent we are attached to |
| 127 | Slot *m_child; // index to first child slot that attaches to us |
| 128 | Slot *m_sibling; // index to next child that attaches to our parent |
| 129 | Position m_position; // absolute position of glyph |
| 130 | Position m_shift; // .shift slot attribute |
| 131 | Position m_advance; // .advance slot attribute |
| 132 | Position m_attach; // attachment point on us |
| 133 | Position m_with; // attachment point position on parent |
| 134 | float m_just; // Justification inserted space |
| 135 | uint8 m_flags; // holds bit flags |
| 136 | byte m_attLevel; // attachment level |
| 137 | int8 m_bidiCls; // bidirectional class |
| 138 | byte m_bidiLevel; // bidirectional level |
| 139 | int16 *m_userAttr; // pointer to user attributes |
| 140 | SlotJustify *m_justs; // pointer to justification parameters |
| 141 | |
| 142 | friend class Segment; |
| 143 | }; |
| 144 | |
| 145 | } // namespace graphite2 |
| 146 | |
| 147 | struct gr_slot : public graphite2::Slot {}; |
| 148 | |