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
12namespace graphite2 {
13
14typedef gr_attrCode attrCode;
15
16class GlyphFace;
17class Segment;
18
19struct SlotJustify
20{
21 static const int NUMJUSTPARAMS = 5;
22
23 SlotJustify(const SlotJustify &);
24 SlotJustify & operator = (const SlotJustify &);
25
26public:
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
35class Slot
36{
37 enum Flag
38 {
39 DELETED = 1,
40 INSERTED = 2,
41 COPIED = 4,
42 POSITIONED = 8,
43 ATTACHED = 16
44 };
45
46public:
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
117private:
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
147struct gr_slot : public graphite2::Slot {};
148