1 : /* GRAPHITE2 LICENSING
2 :
3 : Copyright 2010, SIL International
4 : All rights reserved.
5 :
6 : This library is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU Lesser General Public License as published
8 : by the Free Software Foundation; either version 2.1 of License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Lesser General Public License for more details.
15 :
16 : You should also have received a copy of the GNU Lesser General Public
17 : License along with this library in the file named "LICENSE".
18 : If not, write to the Free Software Foundation, 51 Franklin Street,
19 : Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
20 : internet at http://www.fsf.org/licenses/lgpl.html.
21 :
22 : Alternatively, the contents of this file may be used under the terms of the
23 : Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
24 : License, as published by the Free Software Foundation, either version 2
25 : of the License or (at your option) any later version.
26 : */
27 : #pragma once
28 :
29 : #include "inc/Main.h"
30 :
31 : #include <cassert>
32 :
33 : #include "inc/Slot.h"
34 : #include "inc/CharInfo.h"
35 : #include "inc/FeatureVal.h"
36 : #include "inc/Silf.h"
37 :
38 : #include "inc/List.h"
39 :
40 : #define MAX_SEG_GROWTH_FACTOR 256
41 :
42 : namespace graphite2 {
43 :
44 : typedef Vector<Features> FeatureList;
45 : typedef Vector<Slot *> SlotRope;
46 : typedef Vector<int16 *> AttributeRope;
47 :
48 : #ifndef GRAPHITE2_NSEGCACHE
49 : class SegmentScopeState;
50 : #endif
51 : class Segment;
52 :
53 : enum SpliceParam {
54 : /** sub-Segments longer than this are not cached
55 : * (in Unicode code points) */
56 : eMaxSpliceSize = 16
57 : };
58 :
59 : enum justFlags {
60 : gr_justStartInline = 1,
61 : gr_justEndInline = 2
62 : };
63 :
64 : class SegmentScopeState
65 : {
66 : private:
67 : friend class Segment;
68 : Slot * realFirstSlot;
69 : Slot * slotBeforeScope;
70 : Slot * slotAfterScope;
71 : Slot * realLastSlot;
72 : size_t numGlyphsOutsideScope;
73 : };
74 :
75 : class Segment
76 : {
77 : public:
78 0 : unsigned int slotCount() const { return m_numGlyphs; } //one slot per glyph
79 0 : void extendLength(int num) { m_numGlyphs += num; }
80 0 : Position advance() const { return m_advance; }
81 0 : bool runGraphite() { if (m_silf) return m_face->runGraphite(this, m_silf); else return true;};
82 : void chooseSilf(uint32 script) { m_silf = m_face->chooseSilf(script); }
83 0 : const Silf *silf() const { return m_silf; }
84 0 : unsigned int charInfoCount() const { return m_numCharinfo; }
85 0 : const CharInfo *charinfo(unsigned int index) const { return index < m_numCharinfo ? m_charinfo + index : NULL; }
86 0 : CharInfo *charinfo(unsigned int index) { return index < m_numCharinfo ? m_charinfo + index : NULL; }
87 0 : int8 dir() const { return m_dir; }
88 :
89 : Segment(unsigned int numchars, const Face* face, uint32 script, int dir);
90 : ~Segment();
91 : #ifndef GRAPHITE2_NSEGCACHE
92 : SegmentScopeState setScope(Slot * firstSlot, Slot * lastSlot, size_t subLength);
93 : void removeScope(SegmentScopeState & state);
94 : void append(const Segment &other);
95 : void splice(size_t offset, size_t length, Slot * startSlot, Slot * endSlot,
96 : const Slot * firstSpliceSlot, size_t numGlyphs);
97 : #endif
98 0 : Slot *first() { return m_first; }
99 0 : void first(Slot *p) { m_first = p; }
100 0 : Slot *last() { return m_last; }
101 0 : void last(Slot *p) { m_last = p; }
102 : void appendSlot(int i, int cid, int gid, int fid, size_t coffset);
103 : Slot *newSlot();
104 : void freeSlot(Slot *);
105 : Position positionSlots(const Font *font, Slot *first=0, Slot *last=0);
106 : void linkClusters(Slot *first, Slot *last);
107 0 : uint16 getClassGlyph(uint16 cid, uint16 offset) const { return m_silf->getClassGlyph(cid, offset); }
108 0 : uint16 findClassIndex(uint16 cid, uint16 gid) const { return m_silf->findClassIndex(cid, gid); }
109 0 : int addFeatures(const Features& feats) { m_feats.push_back(feats); return m_feats.size() - 1; }
110 0 : uint16 getFeature(int index, uint8 findex) const { const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex); if (!pFR) return 0; else return pFR->getFeatureVal(m_feats[index]); }
111 : void dir(int8 val) { m_dir = val; }
112 0 : uint16 glyphAttr(uint16 gid, uint8 gattr) const { return m_face->glyphAttr(gid, gattr); }
113 0 : uint16 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) const {
114 0 : if (attrLevel > 0)
115 : {
116 0 : Slot *is = findRoot(iSlot);
117 0 : return is->clusterMetric(this, metric, attrLevel);
118 : }
119 : else
120 0 : return m_face->getGlyphMetric(iSlot->gid(), metric);
121 : }
122 0 : float glyphAdvance(uint16 gid) const { return m_face->getAdvance(gid, 1.0); }
123 0 : const Rect &theGlyphBBoxTemporary(uint16 gid) const { return m_face->theBBoxTemporary(gid); } //warning value may become invalid when another glyph is accessed
124 0 : Slot *findRoot(Slot *is) const { return is->attachedTo() ? findRoot(is->attachedTo()) : is; }
125 0 : int numAttrs() const { return m_silf->numUser(); }
126 0 : int defaultOriginal() const { return m_defaultOriginal; }
127 0 : const Face * getFace() const { return m_face; }
128 : const Features & getFeatures(unsigned int /*charIndex*/) { assert(m_feats.size() == 1); return m_feats[0]; }
129 : void bidiPass(uint8 aBidi, int paradir, uint8 aMirror);
130 :
131 0 : CLASS_NEW_DELETE
132 :
133 : public: //only used by: GrSegment* makeAndInitialize(const GrFont *font, const GrFace *face, uint32 script, const FeaturesHandle& pFeats/*must not be IsNull*/, encform enc, const void* pStart, size_t nChars, int dir);
134 : void read_text(const Face *face, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void*pStart, size_t nChars);
135 : void prepare_pos(const Font *font);
136 : void finalise(const Font *font);
137 : void justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast);
138 :
139 : private:
140 : SlotRope m_slots; // std::vector of slot buffers
141 : Slot *m_freeSlots; // linked list of free slots
142 : Slot *m_first; // first slot in segment
143 : Slot *m_last; // last slot in segment
144 : unsigned int m_bufSize; // how big a buffer to create when need more slots
145 : unsigned int m_numGlyphs;
146 : unsigned int m_numCharinfo; // size of the array and number of input characters
147 : int m_defaultOriginal; // CharInfo index used if all slots have been deleted
148 : AttributeRope m_userAttrs; // std::vector of userAttrs buffers
149 : CharInfo *m_charinfo; // character info, one per input character
150 :
151 : const Face *m_face; // GrFace
152 : const Silf *m_silf;
153 : Position m_advance; // whole segment advance
154 : Rect m_bbox; // ink box of the segment
155 : int8 m_dir;
156 : FeatureList m_feats; // feature settings referenced by charinfos in this segment
157 :
158 : private: //defensive on m_charinfo
159 : Segment(const Segment&);
160 : Segment& operator=(const Segment&);
161 : };
162 :
163 : } // namespace graphite2
164 :
165 0 : struct gr_segment : public graphite2::Segment {};
166 :
|