File Coverage

third_party/modest/source/myfont/glyf.c
Criterion Covered Total %
statement 0 134 0.0
branch 0 70 0.0
condition n/a
subroutine n/a
pod n/a
total 0 204 0.0


line stmt bran cond sub pod time code
1             /*
2             Copyright (C) 2016-2017 Alexander Borisov
3            
4             This library is free software; you can redistribute it and/or
5             modify it under the terms of the GNU Lesser General Public
6             License as published by the Free Software Foundation; either
7             version 2.1 of the License, or (at your option) any later version.
8            
9             This library is distributed in the hope that it will be useful,
10             but WITHOUT ANY WARRANTY; without even the implied warranty of
11             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12             Lesser General Public License for more details.
13            
14             You should have received a copy of the GNU Lesser General Public
15             License along with this library; if not, write to the Free Software
16             Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17            
18             Author: lex.borisov@gmail.com (Alexander Borisov)
19             */
20              
21             #include "myfont/glyf.h"
22              
23 0           mystatus_t myfont_load_table_glyf(myfont_font_t* mf, uint8_t* font_data, size_t data_size)
24             {
25 0           memset(&mf->table_glyf, 0, sizeof(myfont_table_glyf_t));
26            
27 0 0         if(mf->cache.tables_offset[MyFONT_TKEY_glyf] == 0)
28 0           return MyFONT_STATUS_OK;
29            
30 0 0         if(mf->table_maxp.numGlyphs == 0)
31 0           return MyFONT_STATUS_OK;
32            
33 0           myfont_table_glyph_t *glyphs = (myfont_table_glyph_t*)myfont_calloc(mf, mf->table_maxp.numGlyphs, sizeof(myfont_table_glyph_t));
34            
35 0 0         if(glyphs == NULL)
36 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
37            
38 0 0         for(uint16_t i = 0; i < mf->table_maxp.numGlyphs; i++)
39             {
40 0           uint32_t offset = mf->cache.tables_offset[MyFONT_TKEY_glyf] + mf->table_loca.offsets[i];
41 0           mystatus_t status = myfont_glyf_load_data(mf, &glyphs[i], font_data, data_size, offset);
42            
43 0 0         if(status)
44 0           return status;
45             }
46            
47 0           mf->table_glyf.cache = glyphs;
48            
49 0           return MyFONT_STATUS_OK;
50             }
51              
52 0           mystatus_t myfont_glyf_load(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t* font_data, size_t data_size, uint16_t glyph_index)
53             {
54 0           memset(glyph, 0, sizeof(myfont_table_glyph_t));
55            
56 0 0         if(mf->table_maxp.numGlyphs == 0)
57 0           return MyFONT_STATUS_OK;
58            
59 0           uint16_t offset = myfont_loca_get_offset(mf, glyph_index);
60 0           offset += mf->cache.tables_offset[MyFONT_TKEY_glyf];
61            
62 0           return myfont_glyf_load_data(mf, glyph, font_data, data_size, offset);
63             }
64              
65 0           mystatus_t myfont_glyf_load_data(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t* font_data, size_t data_size, uint32_t offset)
66             {
67 0           memset(&glyph->head, 0, sizeof(myfont_table_glyf_head_t));
68            
69             /* get current data */
70 0           uint8_t *data = &font_data[offset];
71            
72             // load head
73 0           offset += 10;
74 0 0         if(offset > data_size)
75 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
76            
77 0           glyph->head.numberOfContours = myfont_read_16(&data);
78 0           glyph->head.xMin = myfont_read_16(&data);
79 0           glyph->head.yMin = myfont_read_16(&data);
80 0           glyph->head.xMax = myfont_read_16(&data);
81 0           glyph->head.yMax = myfont_read_16(&data);
82            
83 0 0         if(glyph->head.numberOfContours > 0)
84 0           return myfont_glyf_load_simple(mf, glyph, data, data_size, offset);
85            
86 0           return MyFONT_STATUS_OK;
87             }
88              
89 0           mystatus_t myfont_glyf_load_simple(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, size_t data_size, uint32_t offset)
90             {
91 0           uint16_t *endPtsOfContours = (uint16_t *)myfont_calloc(mf, glyph->head.numberOfContours, sizeof(uint16_t));
92            
93 0 0         if(endPtsOfContours == NULL)
94 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
95            
96 0           offset = offset + (glyph->head.numberOfContours * 2) + 2;
97            
98 0 0         if(offset > data_size)
99 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
100            
101 0 0         for(uint16_t i = 0; i < glyph->head.numberOfContours; i++) {
102 0           endPtsOfContours[i] = myfont_read_u16(&data);
103             }
104            
105 0           glyph->simple.endPtsOfContours = endPtsOfContours;
106 0           glyph->simple.instructionLength = myfont_read_u16(&data);
107 0           glyph->pointCount = endPtsOfContours[(glyph->head.numberOfContours - 1)] + 1;
108            
109             /* instruction */
110 0           offset += glyph->simple.instructionLength;
111 0 0         if(offset > data_size)
112 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
113            
114 0 0         if(glyph->simple.instructionLength) {
115 0           glyph->simple.instructions = (uint8_t *)myfont_calloc(mf, glyph->simple.instructionLength, sizeof(uint8_t));
116            
117 0 0         if(glyph->simple.instructions == NULL)
118 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
119            
120 0           memcpy(glyph->simple.instructions, data, glyph->simple.instructionLength);
121 0           data += glyph->simple.instructionLength;
122             }
123            
124 0           return myfont_glyf_load_simple_flags(mf, glyph, data, data_size, offset);
125             }
126              
127 0           mystatus_t myfont_glyf_load_simple_flags(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, size_t data_size, uint32_t offset)
128             {
129 0           uint8_t *flags = (uint8_t *)myfont_calloc(mf, glyph->pointCount, sizeof(uint8_t));
130            
131 0 0         if(flags == NULL)
132 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
133            
134 0           uint16_t i = 0;
135 0 0         while(i < glyph->pointCount)
136             {
137 0 0         if(offset >= data_size) {
138 0           myfont_free(mf, flags);
139 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
140             }
141            
142 0           flags[i] = myfont_read_u8(&data); offset++;
143            
144 0 0         if(flags[i] & MyFONT_GLYF_SML_FLAGS_repeat)
145             {
146 0 0         if(offset >= data_size) {
147 0           myfont_free(mf, flags);
148 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
149             }
150            
151 0           uint8_t repeat = myfont_read_u8(&data); offset++;
152 0           uint8_t curr = flags[i];
153            
154 0 0         if(repeat > (glyph->pointCount - i)) {
155 0           myfont_free(mf, flags);
156 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
157             }
158            
159 0 0         while(repeat--) {
160 0           i++;
161            
162 0           flags[i] = curr;
163             }
164             }
165            
166 0           i++;
167             }
168            
169 0           glyph->simple.flags = flags;
170            
171 0           return myfont_glyf_load_simple_coordinates(mf, glyph, data, data_size, offset);
172             }
173              
174 0           mystatus_t myfont_glyf_load_simple_coordinates(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, size_t data_size, uint32_t offset)
175             {
176             /* alloc resources */
177 0           int16_t *xCoordinates = (int16_t *)myfont_calloc(mf, glyph->pointCount, sizeof(int16_t));
178 0 0         if(xCoordinates == NULL)
179 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
180            
181 0           int16_t *yCoordinates = (int16_t *)myfont_calloc(mf, glyph->pointCount, sizeof(int16_t));
182 0 0         if(yCoordinates == NULL) {
183 0           myfont_free(mf, xCoordinates);
184 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
185             }
186            
187 0           uint8_t *flags = glyph->simple.flags;
188            
189 0           int32_t in_before = 0;
190            
191 0 0         for(uint16_t i = 0; i < glyph->pointCount; i++)
192             {
193 0 0         if(flags[i] & MyFONT_GLYF_SML_FLAGS_x_ShortVector)
194             {
195 0 0         if(offset >= data_size) {
196 0           myfont_free(mf, xCoordinates);
197 0           myfont_free(mf, yCoordinates);
198 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
199             }
200            
201 0 0         if(flags[i] & MyFONT_GLYF_SML_FLAGS_p_x_ShortVector) {
202 0           xCoordinates[i] = in_before + myfont_read_u8(&data); offset++;
203             }
204             else {
205 0           xCoordinates[i] = in_before - myfont_read_u8(&data); offset++;
206             }
207             }
208             else
209             {
210 0           offset++;
211            
212 0 0         if(offset >= data_size) {
213 0           myfont_free(mf, xCoordinates);
214 0           myfont_free(mf, yCoordinates);
215 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
216             }
217            
218 0 0         if(flags[i] & MyFONT_GLYF_SML_FLAGS_p_x_ShortVector) {
219 0           xCoordinates[i] = in_before;
220             }
221             else {
222 0           xCoordinates[i] = in_before + myfont_read_16(&data); offset++;
223             }
224             }
225            
226 0           in_before = xCoordinates[i];
227             }
228            
229 0           in_before = 0;
230            
231 0 0         for(uint16_t i = 0; i < glyph->pointCount; i++)
232             {
233 0 0         if(flags[i] & MyFONT_GLYF_SML_FLAGS_y_ShortVector)
234             {
235 0 0         if(offset >= data_size) {
236 0           myfont_free(mf, xCoordinates);
237 0           myfont_free(mf, yCoordinates);
238 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
239             }
240            
241 0 0         if(flags[i] & MyFONT_GLYF_SML_FLAGS_p_y_ShortVector) {
242 0           yCoordinates[i] = in_before + myfont_read_u8(&data); offset++;
243             }
244             else {
245 0           yCoordinates[i] = in_before - myfont_read_u8(&data); offset++;
246             }
247             }
248             else {
249 0           offset++;
250            
251 0 0         if(offset >= data_size) {
252 0           myfont_free(mf, xCoordinates);
253 0           myfont_free(mf, yCoordinates);
254 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
255             }
256            
257 0 0         if(flags[i] & MyFONT_GLYF_SML_FLAGS_p_y_ShortVector) {
258 0           yCoordinates[i] = in_before;
259             }
260             else {
261 0           yCoordinates[i] = in_before + myfont_read_16(&data); offset += 2;
262             }
263             }
264            
265 0           in_before = yCoordinates[i];
266             }
267            
268 0           glyph->simple.xCoordinates = xCoordinates;
269 0           glyph->simple.yCoordinates = yCoordinates;
270            
271 0           return MyFONT_STATUS_OK;
272             }
273              
274