gfx/graphite2/src/inc/Segment.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* GRAPHITE2 LICENSING
michael@0 2
michael@0 3 Copyright 2010, SIL International
michael@0 4 All rights reserved.
michael@0 5
michael@0 6 This library is free software; you can redistribute it and/or modify
michael@0 7 it under the terms of the GNU Lesser General Public License as published
michael@0 8 by the Free Software Foundation; either version 2.1 of License, or
michael@0 9 (at your option) any later version.
michael@0 10
michael@0 11 This program is distributed in the hope that it will be useful,
michael@0 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
michael@0 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
michael@0 14 Lesser General Public License for more details.
michael@0 15
michael@0 16 You should also have received a copy of the GNU Lesser General Public
michael@0 17 License along with this library in the file named "LICENSE".
michael@0 18 If not, write to the Free Software Foundation, 51 Franklin Street,
michael@0 19 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
michael@0 20 internet at http://www.fsf.org/licenses/lgpl.html.
michael@0 21
michael@0 22 Alternatively, the contents of this file may be used under the terms of the
michael@0 23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
michael@0 24 License, as published by the Free Software Foundation, either version 2
michael@0 25 of the License or (at your option) any later version.
michael@0 26 */
michael@0 27 #pragma once
michael@0 28
michael@0 29 #include "inc/Main.h"
michael@0 30
michael@0 31 #include <cassert>
michael@0 32
michael@0 33 #include "inc/CharInfo.h"
michael@0 34 #include "inc/Face.h"
michael@0 35 #include "inc/FeatureVal.h"
michael@0 36 #include "inc/GlyphCache.h"
michael@0 37 #include "inc/GlyphFace.h"
michael@0 38 //#include "inc/Silf.h"
michael@0 39 #include "inc/Slot.h"
michael@0 40 #include "inc/Position.h"
michael@0 41 #include "inc/List.h"
michael@0 42 #include "inc/Bidi.h"
michael@0 43
michael@0 44 #define MAX_SEG_GROWTH_FACTOR 256
michael@0 45
michael@0 46 namespace graphite2 {
michael@0 47
michael@0 48 typedef Vector<Features> FeatureList;
michael@0 49 typedef Vector<Slot *> SlotRope;
michael@0 50 typedef Vector<int16 *> AttributeRope;
michael@0 51 typedef Vector<SlotJustify *> JustifyRope;
michael@0 52
michael@0 53 #ifndef GRAPHITE2_NSEGCACHE
michael@0 54 class SegmentScopeState;
michael@0 55 #endif
michael@0 56 class Font;
michael@0 57 class Segment;
michael@0 58 class Silf;
michael@0 59
michael@0 60 enum SpliceParam {
michael@0 61 /** sub-Segments longer than this are not cached
michael@0 62 * (in Unicode code points) */
michael@0 63 eMaxSpliceSize = 96
michael@0 64 };
michael@0 65
michael@0 66 enum justFlags {
michael@0 67 gr_justStartInline = 1,
michael@0 68 gr_justEndInline = 2
michael@0 69 };
michael@0 70
michael@0 71 class SegmentScopeState
michael@0 72 {
michael@0 73 private:
michael@0 74 friend class Segment;
michael@0 75 Slot * realFirstSlot;
michael@0 76 Slot * slotBeforeScope;
michael@0 77 Slot * slotAfterScope;
michael@0 78 Slot * realLastSlot;
michael@0 79 size_t numGlyphsOutsideScope;
michael@0 80 };
michael@0 81
michael@0 82 class Segment
michael@0 83 {
michael@0 84 // Prevent copying of any kind.
michael@0 85 Segment(const Segment&);
michael@0 86 Segment& operator=(const Segment&);
michael@0 87
michael@0 88 public:
michael@0 89 unsigned int slotCount() const { return m_numGlyphs; } //one slot per glyph
michael@0 90 void extendLength(int num) { m_numGlyphs += num; }
michael@0 91 Position advance() const { return m_advance; }
michael@0 92 bool runGraphite() { if (m_silf) return m_face->runGraphite(this, m_silf); else return true;};
michael@0 93 void chooseSilf(uint32 script) { m_silf = m_face->chooseSilf(script); }
michael@0 94 const Silf *silf() const { return m_silf; }
michael@0 95 unsigned int charInfoCount() const { return m_numCharinfo; }
michael@0 96 const CharInfo *charinfo(unsigned int index) const { return index < m_numCharinfo ? m_charinfo + index : NULL; }
michael@0 97 CharInfo *charinfo(unsigned int index) { return index < m_numCharinfo ? m_charinfo + index : NULL; }
michael@0 98 int8 dir() const { return m_dir; }
michael@0 99
michael@0 100 Segment(unsigned int numchars, const Face* face, uint32 script, int dir);
michael@0 101 ~Segment();
michael@0 102 #ifndef GRAPHITE2_NSEGCACHE
michael@0 103 SegmentScopeState setScope(Slot * firstSlot, Slot * lastSlot, size_t subLength);
michael@0 104 void removeScope(SegmentScopeState & state);
michael@0 105 void append(const Segment &other);
michael@0 106 void splice(size_t offset, size_t length, Slot * const startSlot,
michael@0 107 Slot * endSlot, const Slot * srcSlot,
michael@0 108 const size_t numGlyphs);
michael@0 109 #endif
michael@0 110 Slot *first() { return m_first; }
michael@0 111 void first(Slot *p) { m_first = p; }
michael@0 112 Slot *last() { return m_last; }
michael@0 113 void last(Slot *p) { m_last = p; }
michael@0 114 void appendSlot(int i, int cid, int gid, int fid, size_t coffset);
michael@0 115 Slot *newSlot();
michael@0 116 void freeSlot(Slot *);
michael@0 117 SlotJustify *newJustify();
michael@0 118 void freeJustify(SlotJustify *aJustify);
michael@0 119 Position positionSlots(const Font *font, Slot *first=0, Slot *last=0);
michael@0 120 void associateChars(int offset, int num);
michael@0 121 void linkClusters(Slot *first, Slot *last);
michael@0 122 uint16 getClassGlyph(uint16 cid, uint16 offset) const { return m_silf->getClassGlyph(cid, offset); }
michael@0 123 uint16 findClassIndex(uint16 cid, uint16 gid) const { return m_silf->findClassIndex(cid, gid); }
michael@0 124 int addFeatures(const Features& feats) { m_feats.push_back(feats); return m_feats.size() - 1; }
michael@0 125 uint32 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]); }
michael@0 126 void dir(int8 val) { m_dir = val; }
michael@0 127 unsigned int passBits() const { return m_passBits; }
michael@0 128 void mergePassBits(const unsigned int val) { m_passBits &= val; }
michael@0 129 int16 glyphAttr(uint16 gid, uint16 gattr) const { const GlyphFace * p = m_face->glyphs().glyphSafe(gid); return p ? p->attrs()[gattr] : 0; }
michael@0 130 int32 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) const;
michael@0 131 float glyphAdvance(uint16 gid) const { return m_face->glyphs().glyph(gid)->theAdvance().x; }
michael@0 132 const Rect &theGlyphBBoxTemporary(uint16 gid) const { return m_face->glyphs().glyph(gid)->theBBox(); } //warning value may become invalid when another glyph is accessed
michael@0 133 Slot *findRoot(Slot *is) const { return is->attachedTo() ? findRoot(is->attachedTo()) : is; }
michael@0 134 int numAttrs() const { return m_silf->numUser(); }
michael@0 135 int defaultOriginal() const { return m_defaultOriginal; }
michael@0 136 const Face * getFace() const { return m_face; }
michael@0 137 const Features & getFeatures(unsigned int /*charIndex*/) { assert(m_feats.size() == 1); return m_feats[0]; }
michael@0 138 void bidiPass(uint8 aBidi, int paradir, uint8 aMirror);
michael@0 139 Slot *addLineEnd(Slot *nSlot);
michael@0 140 void delLineEnd(Slot *s);
michael@0 141 bool hasJustification() const { return m_justifies.size() != 0; }
michael@0 142
michael@0 143 bool isWhitespace(const int cid) const;
michael@0 144
michael@0 145 CLASS_NEW_DELETE
michael@0 146
michael@0 147 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);
michael@0 148 bool read_text(const Face *face, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void*pStart, size_t nChars);
michael@0 149 void prepare_pos(const Font *font);
michael@0 150 void finalise(const Font *font);
michael@0 151 float justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast);
michael@0 152
michael@0 153 private:
michael@0 154 Position m_advance; // whole segment advance
michael@0 155 SlotRope m_slots; // Vector of slot buffers
michael@0 156 AttributeRope m_userAttrs; // Vector of userAttrs buffers
michael@0 157 JustifyRope m_justifies; // Slot justification info buffers
michael@0 158 FeatureList m_feats; // feature settings referenced by charinfos in this segment
michael@0 159 Slot * m_freeSlots; // linked list of free slots
michael@0 160 SlotJustify * m_freeJustifies; // Slot justification blocks free list
michael@0 161 CharInfo * m_charinfo; // character info, one per input character
michael@0 162 const Face * m_face; // GrFace
michael@0 163 const Silf * m_silf;
michael@0 164 Slot * m_first; // first slot in segment
michael@0 165 Slot * m_last; // last slot in segment
michael@0 166 unsigned int m_bufSize, // how big a buffer to create when need more slots
michael@0 167 m_numGlyphs,
michael@0 168 m_numCharinfo, // size of the array and number of input characters
michael@0 169 m_passBits; // if bit set then skip pass
michael@0 170 int m_defaultOriginal; // number of whitespace chars in the string
michael@0 171 int8 m_dir;
michael@0 172 };
michael@0 173
michael@0 174
michael@0 175
michael@0 176 inline
michael@0 177 void Segment::finalise(const Font *font)
michael@0 178 {
michael@0 179 if (!m_first) return;
michael@0 180
michael@0 181 m_advance = positionSlots(font);
michael@0 182 associateChars(0, m_numCharinfo);
michael@0 183 linkClusters(m_first, m_last);
michael@0 184 }
michael@0 185
michael@0 186 inline
michael@0 187 int32 Segment::getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) const {
michael@0 188 if (attrLevel > 0)
michael@0 189 {
michael@0 190 Slot *is = findRoot(iSlot);
michael@0 191 return is->clusterMetric(this, metric, attrLevel);
michael@0 192 }
michael@0 193 else
michael@0 194 return m_face->getGlyphMetric(iSlot->gid(), metric);
michael@0 195 }
michael@0 196
michael@0 197 inline
michael@0 198 bool Segment::isWhitespace(const int cid) const
michael@0 199 {
michael@0 200 return ((cid >= 0x0009) * (cid <= 0x000D)
michael@0 201 + (cid == 0x0020)
michael@0 202 + (cid == 0x0085)
michael@0 203 + (cid == 0x00A0)
michael@0 204 + (cid == 0x1680)
michael@0 205 + (cid == 0x180E)
michael@0 206 + (cid >= 0x2000) * (cid <= 0x200A)
michael@0 207 + (cid == 0x2028)
michael@0 208 + (cid == 0x2029)
michael@0 209 + (cid == 0x202F)
michael@0 210 + (cid == 0x205F)
michael@0 211 + (cid == 0x3000)) != 0;
michael@0 212 }
michael@0 213
michael@0 214 //inline
michael@0 215 //bool Segment::isWhitespace(const int cid) const
michael@0 216 //{
michael@0 217 // switch (cid >> 8)
michael@0 218 // {
michael@0 219 // case 0x00:
michael@0 220 // switch (cid)
michael@0 221 // {
michael@0 222 // case 0x09:
michael@0 223 // case 0x0A:
michael@0 224 // case 0x0B:
michael@0 225 // case 0x0C:
michael@0 226 // case 0x0D:
michael@0 227 // case 0x20:
michael@0 228 // return true;
michael@0 229 // default:
michael@0 230 // break;
michael@0 231 // }
michael@0 232 // break;
michael@0 233 // case 0x16:
michael@0 234 // return cid == 0x1680;
michael@0 235 // break;
michael@0 236 // case 0x18:
michael@0 237 // return cid == 0x180E;
michael@0 238 // break;
michael@0 239 // case 0x20:
michael@0 240 // switch (cid)
michael@0 241 // {
michael@0 242 // case 0x00:
michael@0 243 // case 0x01:
michael@0 244 // case 0x02:
michael@0 245 // case 0x03:
michael@0 246 // case 0x04:
michael@0 247 // case 0x05:
michael@0 248 // case 0x06:
michael@0 249 // case 0x07:
michael@0 250 // case 0x08:
michael@0 251 // case 0x09:
michael@0 252 // case 0x0A:
michael@0 253 // case 0x28:
michael@0 254 // case 0x29:
michael@0 255 // case 0x2F:
michael@0 256 // case 0x5F:
michael@0 257 // return true
michael@0 258 // default:
michael@0 259 // break;
michael@0 260 // }
michael@0 261 // break;
michael@0 262 // case 0x30:
michael@0 263 // return cid == 0x3000;
michael@0 264 // break;
michael@0 265 // }
michael@0 266 //
michael@0 267 // return false;
michael@0 268 //}
michael@0 269
michael@0 270 } // namespace graphite2
michael@0 271
michael@0 272 struct gr_segment : public graphite2::Segment {};
michael@0 273

mercurial