gfx/graphite2/src/gr_face.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:fd232d710f77
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 #include "graphite2/Font.h"
28 #include "inc/Face.h"
29 #include "inc/FileFace.h"
30 #include "inc/GlyphCache.h"
31 #include "inc/CachedFace.h"
32 #include "inc/CmapCache.h"
33 #include "inc/Silf.h"
34 #include "inc/json.h"
35
36 using namespace graphite2;
37
38 #if !defined GRAPHITE2_NTRACING
39 extern json *global_log;
40 #endif
41
42 namespace
43 {
44 bool load_face(Face & face, unsigned int options)
45 {
46 #ifdef GRAPHITE2_TELEMETRY
47 telemetry::category _misc_cat(face.tele.misc);
48 #endif
49 Face::Table silf(face, Tag::Silf);
50 if (silf) options &= ~gr_face_dumbRendering;
51 else if (!(options & gr_face_dumbRendering))
52 return false;
53
54 if (!face.readGlyphs(options))
55 return false;
56
57 if (silf)
58 {
59 if (!face.readFeatures() || !face.readGraphite(silf))
60 {
61 #if !defined GRAPHITE2_NTRACING
62 if (global_log)
63 {
64 *global_log << json::object
65 << "type" << "fontload"
66 << "failure" << face.error()
67 << "context" << face.error_context()
68 << json::close;
69 }
70 #endif
71 return false;
72 }
73 else
74 return true;
75 }
76 else
77 return options & gr_face_dumbRendering;
78 }
79 }
80
81 extern "C" {
82
83 gr_face* gr_make_face_with_ops(const void* appFaceHandle/*non-NULL*/, const gr_face_ops *ops, unsigned int faceOptions)
84 //the appFaceHandle must stay alive all the time when the gr_face is alive. When finished with the gr_face, call destroy_face
85 {
86 if (ops == 0) return 0;
87
88 Face *res = new Face(appFaceHandle, *ops);
89 if (res && load_face(*res, faceOptions))
90 return static_cast<gr_face *>(res);
91
92 delete res;
93 return 0;
94 }
95
96 gr_face* gr_make_face(const void* appFaceHandle/*non-NULL*/, gr_get_table_fn tablefn, unsigned int faceOptions)
97 {
98 const gr_face_ops ops = {sizeof(gr_face_ops), tablefn, NULL};
99 return gr_make_face_with_ops(appFaceHandle, &ops, faceOptions);
100 }
101
102 #ifndef GRAPHITE2_NSEGCACHE
103 gr_face* gr_make_face_with_seg_cache_and_ops(const void* appFaceHandle/*non-NULL*/, const gr_face_ops *ops, unsigned int cacheSize, unsigned int faceOptions)
104 //the appFaceHandle must stay alive all the time when the GrFace is alive. When finished with the GrFace, call destroy_face
105 {
106 if (ops == 0) return 0;
107
108 CachedFace *res = new CachedFace(appFaceHandle, *ops);
109 if (res && load_face(*res, faceOptions)
110 && res->setupCache(cacheSize))
111 return static_cast<gr_face *>(static_cast<Face *>(res));
112
113 delete res;
114 return 0;
115 }
116
117 gr_face* gr_make_face_with_seg_cache(const void* appFaceHandle/*non-NULL*/, gr_get_table_fn getTable, unsigned int cacheSize, unsigned int faceOptions)
118 {
119 const gr_face_ops ops = {sizeof(gr_face_ops), getTable, NULL};
120 return gr_make_face_with_seg_cache_and_ops(appFaceHandle, &ops, cacheSize, faceOptions);
121 }
122 #endif
123
124 gr_uint32 gr_str_to_tag(const char *str)
125 {
126 uint32 res = 0;
127 int i = strlen(str);
128 if (i > 4) i = 4;
129 while (--i >= 0)
130 res = (res >> 8) + (str[i] << 24);
131 return res;
132 }
133
134 void gr_tag_to_str(gr_uint32 tag, char *str)
135 {
136 int i = 4;
137 while (--i >= 0)
138 {
139 str[i] = tag & 0xFF;
140 tag >>= 8;
141 }
142 }
143
144 inline
145 uint32 zeropad(const uint32 x)
146 {
147 if (x == 0x20202020) return 0;
148 if ((x & 0x00FFFFFF) == 0x00202020) return x & 0xFF000000;
149 if ((x & 0x0000FFFF) == 0x00002020) return x & 0xFFFF0000;
150 if ((x & 0x000000FF) == 0x00000020) return x & 0xFFFFFF00;
151 return x;
152 }
153
154 gr_feature_val* gr_face_featureval_for_lang(const gr_face* pFace, gr_uint32 langname/*0 means clone default*/) //clones the features. if none for language, clones the default
155 {
156 assert(pFace);
157 langname = zeropad(langname);
158 return static_cast<gr_feature_val *>(pFace->theSill().cloneFeatures(langname));
159 }
160
161
162 const gr_feature_ref* gr_face_find_fref(const gr_face* pFace, gr_uint32 featId) //When finished with the FeatureRef, call destroy_FeatureRef
163 {
164 assert(pFace);
165 featId = zeropad(featId);
166 const FeatureRef* pRef = pFace->featureById(featId);
167 return static_cast<const gr_feature_ref*>(pRef);
168 }
169
170 unsigned short gr_face_n_fref(const gr_face* pFace)
171 {
172 assert(pFace);
173 return pFace->numFeatures();
174 }
175
176 const gr_feature_ref* gr_face_fref(const gr_face* pFace, gr_uint16 i) //When finished with the FeatureRef, call destroy_FeatureRef
177 {
178 assert(pFace);
179 const FeatureRef* pRef = pFace->feature(i);
180 return static_cast<const gr_feature_ref*>(pRef);
181 }
182
183 unsigned short gr_face_n_languages(const gr_face* pFace)
184 {
185 assert(pFace);
186 return pFace->theSill().numLanguages();
187 }
188
189 gr_uint32 gr_face_lang_by_index(const gr_face* pFace, gr_uint16 i)
190 {
191 assert(pFace);
192 return pFace->theSill().getLangName(i);
193 }
194
195
196 void gr_face_destroy(gr_face *face)
197 {
198 delete face;
199 }
200
201
202 gr_uint16 gr_face_name_lang_for_locale(gr_face *face, const char * locale)
203 {
204 if (face)
205 {
206 return face->languageForLocale(locale);
207 }
208 return 0;
209 }
210
211 unsigned short gr_face_n_glyphs(const gr_face* pFace)
212 {
213 return pFace->glyphs().numGlyphs();
214 }
215
216 const gr_faceinfo *gr_face_info(const gr_face *pFace, gr_uint32 script)
217 {
218 if (!pFace) return 0;
219 const Silf *silf = pFace->chooseSilf(script);
220 if (silf) return silf->silfInfo();
221 return 0;
222 }
223
224 int gr_face_is_char_supported(const gr_face* pFace, gr_uint32 usv, gr_uint32 script)
225 {
226 const Cmap & cmap = pFace->cmap();
227 gr_uint16 gid = cmap[usv];
228 if (!gid)
229 {
230 const Silf * silf = pFace->chooseSilf(script);
231 gid = silf->findPseudo(usv);
232 }
233 return (gid != 0);
234 }
235
236 #ifndef GRAPHITE2_NFILEFACE
237 gr_face* gr_make_file_face(const char *filename, unsigned int faceOptions)
238 {
239 FileFace* pFileFace = new FileFace(filename);
240 if (*pFileFace)
241 {
242 gr_face* pRes = gr_make_face_with_ops(pFileFace, &FileFace::ops, faceOptions);
243 if (pRes)
244 {
245 pRes->takeFileFace(pFileFace); //takes ownership
246 return pRes;
247 }
248 }
249
250 //error when loading
251
252 delete pFileFace;
253 return NULL;
254 }
255
256 #ifndef GRAPHITE2_NSEGCACHE
257 gr_face* gr_make_file_face_with_seg_cache(const char* filename, unsigned int segCacheMaxSize, unsigned int faceOptions) //returns NULL on failure. //TBD better error handling
258 //when finished with, call destroy_face
259 {
260 FileFace* pFileFace = new FileFace(filename);
261 if (*pFileFace)
262 {
263 gr_face * pRes = gr_make_face_with_seg_cache_and_ops(pFileFace, &FileFace::ops, segCacheMaxSize, faceOptions);
264 if (pRes)
265 {
266 pRes->takeFileFace(pFileFace); //takes ownership
267 return pRes;
268 }
269 }
270
271 //error when loading
272
273 delete pFileFace;
274 return NULL;
275 }
276 #endif
277 #endif //!GRAPHITE2_NFILEFACE
278
279
280 } // extern "C"
281
282

mercurial