Fix OTS warning about `maxp.maxSizeOfInstructions`.
[ttfautohint.git] / lib / taloca.c
blob002fc4415dab0cfdf1b67de2ce307f08ed0cbcc0
1 /* taloca.c */
3 /*
4 * Copyright (C) 2011-2022 by Werner Lemberg.
6 * This file is part of the ttfautohint library, and may only be used,
7 * modified, and distributed under the terms given in `COPYING'. By
8 * continuing to use, modify, or distribute this file you indicate that you
9 * have read `COPYING' and understand and accept it fully.
11 * The file `COPYING' mentioned in the previous paragraph is distributed
12 * with the ttfautohint library.
16 #include "ta.h"
19 FT_Error
20 TA_sfnt_build_loca_table(SFNT* sfnt,
21 FONT* font)
23 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
24 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
25 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
27 glyf_Data* data = (glyf_Data*)glyf_table->data;
28 GLYPH* glyph;
30 FT_ULong offset;
31 FT_Byte loca_format;
32 FT_Byte* buf_new;
33 FT_Byte* p;
34 FT_UShort i;
37 if (loca_table->processed)
38 return TA_Err_Ok;
40 /* get largest offset */
41 offset = 0;
42 glyph = data->glyphs;
44 for (i = 0; i < data->num_glyphs; i++, glyph++)
46 /* glyph records should have offsets which are multiples of 4 */
47 offset = (offset + 3) & ~3U;
48 offset += glyph->len1 + glyph->len2
49 + glyph->ins_extra_len + glyph->ins_len;
50 /* add two bytes for the instructionLength field */
51 if (glyph->len2 || glyph->ins_len)
52 offset += 2;
55 /* to make the short format of the `loca' table always work, */
56 /* the `glyf' table's length is adjusted to an even value */
57 offset = (offset + 1) & ~1U;
59 if (offset > 0xFFFF * 2)
60 loca_format = 1;
61 else
62 loca_format = 0;
64 /* fill table */
65 if (loca_format)
67 loca_table->len = (data->num_glyphs + 1) * 4;
68 buf_new = (FT_Byte*)realloc(loca_table->buf, loca_table->len);
69 if (!buf_new)
70 return FT_Err_Out_Of_Memory;
71 else
72 loca_table->buf = buf_new;
74 p = loca_table->buf;
75 offset = 0;
76 glyph = data->glyphs;
78 for (i = 0; i < data->num_glyphs; i++, glyph++)
80 offset = (offset + 3) & ~3U;
82 *(p++) = BYTE1(offset);
83 *(p++) = BYTE2(offset);
84 *(p++) = BYTE3(offset);
85 *(p++) = BYTE4(offset);
87 offset += glyph->len1 + glyph->len2
88 + glyph->ins_extra_len + glyph->ins_len;
89 if (glyph->len2 || glyph->ins_len)
90 offset += 2;
93 /* last element holds the size of the `glyf' table */
94 offset = (offset + 1) & ~1U;
95 *(p++) = BYTE1(offset);
96 *(p++) = BYTE2(offset);
97 *(p++) = BYTE3(offset);
98 *(p++) = BYTE4(offset);
100 else
102 loca_table->len = (data->num_glyphs + 1) * 2;
103 buf_new = (FT_Byte*)realloc(loca_table->buf,
104 (loca_table->len + 3) & ~3U);
105 if (!buf_new)
106 return FT_Err_Out_Of_Memory;
107 else
108 loca_table->buf = buf_new;
110 p = loca_table->buf;
111 offset = 0;
112 glyph = data->glyphs;
114 for (i = 0; i < data->num_glyphs; i++, glyph++)
116 offset = (offset + 1) & ~1U;
118 *(p++) = HIGH(offset);
119 *(p++) = LOW(offset);
121 offset += (glyph->len1 + glyph->len2
122 + glyph->ins_extra_len + glyph->ins_len + 1) >> 1;
123 if (glyph->len2 || glyph->ins_len)
124 offset += 1;
127 /* last element holds the size of the `glyf' table -- */
128 /* this value must *not* be aligned to a multiple of 4 */
129 *(p++) = HIGH(offset);
130 *(p++) = LOW(offset);
132 /* pad `loca' table to make its length a multiple of 4 */
133 if (loca_table->len % 4 == 2)
135 *(p++) = 0;
136 *(p++) = 0;
140 loca_table->checksum = TA_table_compute_checksum(loca_table->buf,
141 loca_table->len);
142 loca_table->processed = 1;
144 head_table->buf[LOCA_FORMAT_OFFSET] = loca_format;
146 return TA_Err_Ok;
149 /* end of taloca.c */