GlyphCache.h (7415B)
1 /* GRAPHITE2 LICENSING 2 3 Copyright 2012, 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 30 #include "graphite2/Font.h" 31 #include "inc/Main.h" 32 #include "inc/Position.h" 33 #include "inc/GlyphFace.h" 34 35 namespace graphite2 { 36 37 class Face; 38 class FeatureVal; 39 class Segment; 40 41 42 struct SlantBox 43 { 44 static const SlantBox empty; 45 46 // SlantBox(float psi = 0., float pdi = 0., float psa = 0., float pda = 0.) : si(psi), di(pdi), sa(psa), da(pda) {}; 47 float width() const { return sa - si; } 48 float height() const { return da - di; } 49 float si; // min 50 float di; // min 51 float sa; // max 52 float da; // max 53 }; 54 55 56 struct BBox 57 { 58 BBox(float pxi = 0, float pyi = 0., float pxa = 0., float pya = 0.) : xi(pxi), yi(pyi), xa(pxa), ya(pya) {}; 59 float width() const { return xa - xi; } 60 float height() const { return ya - yi; } 61 float xi; // min 62 float yi; // min 63 float xa; // max 64 float ya; // max 65 }; 66 67 68 class GlyphBox 69 { 70 GlyphBox(const GlyphBox &); 71 GlyphBox & operator = (const GlyphBox &); 72 73 public: 74 GlyphBox(uint8 numsubs, unsigned short bitmap, Rect *slanted) : _num(numsubs), _bitmap(bitmap), _slant(*slanted) {}; 75 76 void addSubBox(int subindex, int boundary, Rect *val) { _subs[subindex * 2 + boundary] = *val; } 77 Rect &subVal(int subindex, int boundary) { return _subs[subindex * 2 + boundary]; } 78 const Rect &slant() const { return _slant; } 79 uint8 num() const { return _num; } 80 const Rect *subs() const { return _subs; } 81 82 private: 83 uint8 _num; 84 unsigned short _bitmap; 85 Rect _slant; 86 Rect _subs[1]; 87 }; 88 89 class GlyphCache 90 { 91 class Loader; 92 93 GlyphCache(const GlyphCache&); 94 GlyphCache& operator=(const GlyphCache&); 95 96 public: 97 GlyphCache(const Face & face, const uint32 face_options); 98 ~GlyphCache(); 99 100 unsigned short numGlyphs() const throw(); 101 unsigned short numAttrs() const throw(); 102 unsigned short unitsPerEm() const throw(); 103 104 const GlyphFace *glyph(unsigned short glyphid) const; //result may be changed by subsequent call with a different glyphid 105 const GlyphFace *glyphSafe(unsigned short glyphid) const; 106 float getBoundingMetric(unsigned short glyphid, uint8 metric) const; 107 uint8 numSubBounds(unsigned short glyphid) const; 108 float getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const; 109 const Rect & slant(unsigned short glyphid) const { return _boxes[glyphid] ? _boxes[glyphid]->slant() : _empty_slant_box; } 110 const SlantBox & getBoundingSlantBox(unsigned short glyphid) const; 111 const BBox & getBoundingBBox(unsigned short glyphid) const; 112 const SlantBox & getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const; 113 const BBox & getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const; 114 bool check(unsigned short glyphid) const; 115 bool hasBoxes() const { return _boxes != 0; } 116 117 CLASS_NEW_DELETE; 118 119 private: 120 const Rect _empty_slant_box; 121 const Loader * _glyph_loader; 122 const GlyphFace * * _glyphs; 123 GlyphBox * * _boxes; 124 unsigned short _num_glyphs, 125 _num_attrs, 126 _upem; 127 }; 128 129 inline 130 unsigned short GlyphCache::numGlyphs() const throw() 131 { 132 return _num_glyphs; 133 } 134 135 inline 136 unsigned short GlyphCache::numAttrs() const throw() 137 { 138 return _num_attrs; 139 } 140 141 inline 142 unsigned short GlyphCache::unitsPerEm() const throw() 143 { 144 return _upem; 145 } 146 147 inline 148 bool GlyphCache::check(unsigned short glyphid) const 149 { 150 return _boxes && glyphid < _num_glyphs; 151 } 152 153 inline 154 const GlyphFace *GlyphCache::glyphSafe(unsigned short glyphid) const 155 { 156 return glyphid < _num_glyphs ? glyph(glyphid) : NULL; 157 } 158 159 inline 160 float GlyphCache::getBoundingMetric(unsigned short glyphid, uint8 metric) const 161 { 162 if (glyphid >= _num_glyphs) return 0.; 163 switch (metric) { 164 case 0: return (float)(glyph(glyphid)->theBBox().bl.x); // x_min 165 case 1: return (float)(glyph(glyphid)->theBBox().bl.y); // y_min 166 case 2: return (float)(glyph(glyphid)->theBBox().tr.x); // x_max 167 case 3: return (float)(glyph(glyphid)->theBBox().tr.y); // y_max 168 case 4: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.x : 0.f); // sum_min 169 case 5: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.y : 0.f); // diff_min 170 case 6: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.x : 0.f); // sum_max 171 case 7: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.y : 0.f); // diff_max 172 default: return 0.; 173 } 174 } 175 176 inline const SlantBox &GlyphCache::getBoundingSlantBox(unsigned short glyphid) const 177 { 178 return _boxes[glyphid] ? *(SlantBox *)(&(_boxes[glyphid]->slant())) : SlantBox::empty; 179 } 180 181 inline const BBox &GlyphCache::getBoundingBBox(unsigned short glyphid) const 182 { 183 return *(BBox *)(&(glyph(glyphid)->theBBox())); 184 } 185 186 inline 187 float GlyphCache::getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const 188 { 189 GlyphBox *b = _boxes[glyphid]; 190 if (b == NULL || subindex >= b->num()) return 0; 191 192 switch (metric) { 193 case 0: return b->subVal(subindex, 0).bl.x; 194 case 1: return b->subVal(subindex, 0).bl.y; 195 case 2: return b->subVal(subindex, 0).tr.x; 196 case 3: return b->subVal(subindex, 0).tr.y; 197 case 4: return b->subVal(subindex, 1).bl.x; 198 case 5: return b->subVal(subindex, 1).bl.y; 199 case 6: return b->subVal(subindex, 1).tr.x; 200 case 7: return b->subVal(subindex, 1).tr.y; 201 default: return 0.; 202 } 203 } 204 205 inline const SlantBox &GlyphCache::getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const 206 { 207 GlyphBox *b = _boxes[glyphid]; 208 return *(SlantBox *)(b->subs() + 2 * subindex + 1); 209 } 210 211 inline const BBox &GlyphCache::getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const 212 { 213 GlyphBox *b = _boxes[glyphid]; 214 return *(BBox *)(b->subs() + 2 * subindex); 215 } 216 217 inline 218 uint8 GlyphCache::numSubBounds(unsigned short glyphid) const 219 { 220 return _boxes[glyphid] ? _boxes[glyphid]->num() : 0; 221 } 222 223 } // namespace graphite2