File Coverage

third_party/modest/source/myfont/cmap.c
Criterion Covered Total %
statement 0 151 0.0
branch 0 82 0.0
condition n/a
subroutine n/a
pod n/a
total 0 233 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/cmap.h"
22              
23 0           mystatus_t myfont_table_cmap_format_0(myfont_font_t *mf, myfont_tcmap_entry_t *entry, uint8_t* font_data, size_t data_size, size_t offset)
24             {
25 0 0         if(data_size < (offset + 260)) {
26 0           entry->header = NULL;
27 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
28             }
29            
30 0           myfont_tcmap_format_0_t *f0 = (myfont_tcmap_format_0_t*)myfont_calloc(mf, 1, sizeof(myfont_tcmap_format_0_t));
31            
32 0 0         if(f0 == NULL) {
33 0           entry->header = NULL;
34 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
35             }
36            
37 0           uint8_t *data = &font_data[offset];
38            
39 0           f0->length = myfont_read_u16(&data);
40 0           f0->language = myfont_read_u16(&data);
41            
42 0           memcpy(f0->glyphIdArray, data, 256);
43            
44 0           entry->header = (void *)f0;
45            
46 0           return MyFONT_STATUS_OK;
47             }
48              
49 0           mystatus_t myfont_table_cmap_format_4(myfont_font_t *mf, myfont_tcmap_entry_t *entry, uint8_t* font_data, size_t data_size, size_t offset)
50             {
51 0           uint8_t *data = &font_data[offset];
52            
53 0           myfont_tcmap_format_4_t *f4 = (myfont_tcmap_format_4_t*)myfont_calloc(mf, 1, sizeof(myfont_tcmap_format_4_t));
54            
55 0 0         if(f4 == NULL)
56 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
57            
58 0           offset += MyFONT_TCMAP_FORMAT_4_FIRST_LENGTH;
59            
60 0 0         if(data_size < offset) {
61 0           myfont_free(mf, f4);
62 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
63             }
64            
65 0           f4->length = myfont_read_u16(&data);
66 0           f4->language = myfont_read_u16(&data);
67 0           f4->segCountX2 = myfont_read_u16(&data);
68 0           f4->searchRange = myfont_read_u16(&data);
69 0           f4->entrySelector = myfont_read_u16(&data);
70 0           f4->rangeShift = myfont_read_u16(&data);
71            
72 0           f4->segCount = f4->segCountX2 / 2;
73 0           f4->numGlyphId = ((f4->length - (16L + 8L * f4->segCount)) & 0xffff) / 2;
74            
75 0           offset += sizeof(uint16_t) * (f4->segCount * 5);
76 0 0         if(data_size < offset)
77 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
78            
79             /* init mem */
80 0 0         if((f4->endCount = (uint16_t *)myfont_calloc(mf, f4->segCount, sizeof(uint16_t))) == NULL)
81 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
82            
83 0 0         if((f4->startCount = (uint16_t *)myfont_calloc(mf, f4->segCount, sizeof(uint16_t))) == NULL) {
84 0           myfont_free(mf, f4->endCount); f4->endCount = NULL;
85 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
86             }
87            
88 0 0         if((f4->idDelta = (int16_t *)myfont_calloc(mf, f4->segCount, sizeof(int16_t))) == NULL) {
89 0           myfont_free(mf, f4->endCount); f4->endCount = NULL;
90 0           myfont_free(mf, f4->startCount); f4->startCount = NULL;
91            
92 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
93             }
94            
95 0 0         if((f4->idRangeOffset = (uint16_t *)myfont_calloc(mf, f4->segCount, sizeof(uint16_t))) == NULL) {
96 0           myfont_free(mf, f4->endCount); f4->endCount = NULL;
97 0           myfont_free(mf, f4->startCount); f4->startCount = NULL;
98 0           myfont_free(mf, f4->idDelta); f4->idDelta = NULL;
99            
100 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
101             }
102            
103 0 0         if((f4->glyphIdArray = (uint16_t *)myfont_calloc(mf, f4->numGlyphId, sizeof(uint16_t))) == NULL) {
104 0           myfont_free(mf, f4->endCount); f4->endCount = NULL;
105 0           myfont_free(mf, f4->startCount); f4->startCount = NULL;
106 0           myfont_free(mf, f4->idDelta); f4->idDelta = NULL;
107 0           myfont_free(mf, f4->idRangeOffset); f4->idRangeOffset = NULL;
108            
109 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
110             }
111            
112             /* read data */
113 0 0         for(uint16_t i = 0; i < f4->segCount; i++) {
114 0           f4->endCount[i] = myfont_read_u16(&data);
115             }
116            
117 0           f4->reservedPad = myfont_read_u16(&data);
118            
119 0 0         for(uint16_t i = 0; i < f4->segCount; i++) {
120 0           f4->startCount[i] = myfont_read_u16(&data);
121             }
122            
123 0 0         for(uint16_t i = 0; i < f4->segCount; i++) {
124 0           f4->idDelta[i] = myfont_read_16(&data);
125             }
126            
127 0 0         for(uint16_t i = 0; i < f4->segCount; i++) {
128 0           f4->idRangeOffset[i] = myfont_read_u16(&data);
129             }
130            
131 0 0         for(uint16_t i = 0; i < f4->numGlyphId; i++) {
132 0           f4->glyphIdArray[i] = myfont_read_u16(&data);
133             }
134            
135 0           entry->header = (void *)f4;
136            
137 0           return MyFONT_STATUS_OK;
138             }
139              
140 0           uint16_t myfont_glyph_index_by_code_format_0(myfont_tcmap_format_0_t *f0, unsigned long codepoint, mystatus_t* status)
141             {
142 0 0         if(status)
143 0           *status = MyFONT_STATUS_OK;
144            
145 0 0         if(codepoint < 256)
146 0           return (uint16_t)f0->glyphIdArray[codepoint];
147            
148 0 0         if(status)
149 0           *status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
150            
151 0           return 0;
152             }
153              
154 0           uint16_t myfont_glyph_index_by_code_format_4(myfont_tcmap_format_4_t *f4, unsigned long codepoint, mystatus_t* status)
155             {
156             uint16_t i;
157            
158 0 0         if(status)
159 0           *status = MyFONT_STATUS_OK;
160            
161 0 0         for(i = 0; i < f4->segCount; i++)
162 0 0         if(codepoint <= f4->endCount[i])
163 0           break;
164            
165 0 0         if(i >= f4->segCount || codepoint < f4->startCount[i]) {
    0          
166 0 0         if(status)
167 0           *status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
168            
169 0           return 0;
170             }
171            
172 0 0         if(f4->idRangeOffset[i] == 0) {
173 0           return (codepoint + (uint16_t)f4->idDelta[i]) & 0xFFFF;
174             }
175             else {
176 0           uint16_t index = (f4->idRangeOffset[i] / 2) + (codepoint - f4->startCount[i]) - (f4->segCount - i);
177            
178 0 0         if(index < f4->numGlyphId) {
179 0 0         if(f4->glyphIdArray[index] != 0)
180 0           return (f4->glyphIdArray[index] + (uint16_t)f4->idDelta[i]) & 0xFFFF;
181             }
182             }
183            
184 0 0         if(status)
185 0           *status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
186            
187 0           return 0;
188             }
189              
190 0           uint16_t myfont_glyph_index_by_codepoint(myfont_font_t *mf, unsigned long codepoint, mystatus_t* status)
191             {
192 0           uint16_t i, index = 0, tcout = mf->table_cmap.header.numTables;
193             mystatus_t mf_status;
194            
195 0 0         for(i = 0; i < tcout; i++)
196             {
197 0           myfont_tcmap_entry_t *entry = &mf->table_cmap.entries[i];
198            
199 0           switch (entry->format) {
200             case 0:
201 0           index = myfont_glyph_index_by_code_format_0((myfont_tcmap_format_0_t *)(entry->header), codepoint, &mf_status);
202 0           break;
203            
204             case 4:
205 0           index = myfont_glyph_index_by_code_format_4((myfont_tcmap_format_4_t *)(entry->header), codepoint, &mf_status);
206 0           break;
207            
208             default:
209 0           mf_status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
210 0           break;
211             };
212            
213 0 0         if(mf_status == MyFONT_STATUS_OK) {
214 0 0         if(status)
215 0           *status = MyFONT_STATUS_OK;
216            
217 0           return index;
218             }
219             }
220            
221 0 0         if(status)
222 0           *status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
223            
224 0           return 0;
225             }
226              
227 0           mystatus_t myfont_load_table_cmap(myfont_font_t *mf, uint8_t* font_data, size_t data_size)
228             {
229 0           myfont_table_cmap_t *tcmap = &mf->table_cmap;
230 0           const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_cmap];
231            
232 0 0         if(table_offset == 0)
233 0           return MyFONT_STATUS_OK;
234            
235 0 0         if((table_offset + 4) > data_size)
236 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
237            
238             /* get current data */
239 0           uint8_t *data = &font_data[table_offset];
240            
241             /* get header */
242 0           tcmap->header.version = myfont_read_u16(&data);
243 0           tcmap->header.numTables = myfont_read_u16(&data);
244            
245 0 0         if(tcmap->header.numTables == 0)
246 0           return MyFONT_STATUS_OK;
247            
248 0           size_t size_records = sizeof(myfont_tcmap_record_t) * tcmap->header.numTables;
249 0           size_t size_entries = sizeof(myfont_tcmap_entry_t) * tcmap->header.numTables;
250            
251 0 0         if(data_size < (size_records + size_entries))
252 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
253            
254 0 0         if((tcmap->records = (myfont_tcmap_record_t *)myfont_malloc(mf, size_records)) == NULL)
255 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
256            
257 0 0         if((tcmap->entries = (myfont_tcmap_entry_t *)myfont_malloc(mf, size_entries)) == NULL) {
258 0           tcmap->records = NULL;
259 0           myfont_free(mf, tcmap->records);
260            
261 0           return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
262             }
263            
264 0 0         for(uint16_t i = 0; i < tcmap->header.numTables; i++) {
265 0           tcmap->records[i].platformID = myfont_read_u16(&data);
266 0           tcmap->records[i].encodingID = myfont_read_u16(&data);
267 0           tcmap->records[i].offset = myfont_read_u32(&data);
268             }
269            
270 0 0         for(uint16_t i = 0; i < tcmap->header.numTables; i++)
271             {
272 0           uint32_t offset = tcmap->records[i].offset + table_offset;
273            
274 0 0         if(data_size <= offset)
275 0           return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
276            
277 0           data = &font_data[offset];
278 0           tcmap->entries[i].format = myfont_read_u16(&data);
279            
280 0           switch (tcmap->entries[i].format) {
281             case 0:
282 0           myfont_table_cmap_format_0(mf, &tcmap->entries[i], font_data, data_size, (offset + 2));
283 0           break;
284            
285             case 4:
286 0           myfont_table_cmap_format_4(mf, &tcmap->entries[i], font_data, data_size, (offset + 2));
287 0           break;
288            
289             default:
290 0           break;
291             }
292             }
293            
294 0           return MyFONT_STATUS_OK;
295             }
296              
297              
298