Line data Source code
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 0 : GlyphBox(uint8 numsubs, unsigned short bitmap, Rect *slanted) : _num(numsubs), _bitmap(bitmap), _slant(*slanted) {};
75 :
76 0 : 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 0 : const Rect &slant() const { return _slant; }
79 0 : uint8 num() const { return _num; }
80 0 : 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 0 : bool hasBoxes() const { return _boxes != 0; }
116 :
117 0 : 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 0 : unsigned short GlyphCache::numGlyphs() const throw()
131 : {
132 0 : return _num_glyphs;
133 : }
134 :
135 : inline
136 0 : unsigned short GlyphCache::numAttrs() const throw()
137 : {
138 0 : return _num_attrs;
139 : }
140 :
141 : inline
142 0 : unsigned short GlyphCache::unitsPerEm() const throw()
143 : {
144 0 : return _upem;
145 : }
146 :
147 : inline
148 0 : bool GlyphCache::check(unsigned short glyphid) const
149 : {
150 0 : return _boxes && glyphid < _num_glyphs;
151 : }
152 :
153 : inline
154 0 : const GlyphFace *GlyphCache::glyphSafe(unsigned short glyphid) const
155 : {
156 0 : 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 0 : inline const SlantBox &GlyphCache::getBoundingSlantBox(unsigned short glyphid) const
177 : {
178 0 : return _boxes[glyphid] ? *(SlantBox *)(&(_boxes[glyphid]->slant())) : SlantBox::empty;
179 : }
180 :
181 0 : inline const BBox &GlyphCache::getBoundingBBox(unsigned short glyphid) const
182 : {
183 0 : 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 0 : inline const SlantBox &GlyphCache::getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const
206 : {
207 0 : GlyphBox *b = _boxes[glyphid];
208 0 : return *(SlantBox *)(b->subs() + 2 * subindex + 1);
209 : }
210 :
211 0 : inline const BBox &GlyphCache::getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const
212 : {
213 0 : GlyphBox *b = _boxes[glyphid];
214 0 : return *(BBox *)(b->subs() + 2 * subindex);
215 : }
216 :
217 : inline
218 0 : uint8 GlyphCache::numSubBounds(unsigned short glyphid) const
219 : {
220 0 : return _boxes[glyphid] ? _boxes[glyphid]->num() : 0;
221 : }
222 :
223 : } // namespace graphite2
|