1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#include "head.h"
#include "support/util.h"
static INLINE void initHead(table_head *head) {
memset(head, 0, sizeof(*head));
head->magicNumber = 0x5f0f3cf5;
head->unitsPerEm = 1000;
}
static INLINE void disposeHead(table_head *head) {
// trivial
}
caryll_standardRefType(table_head, table_iHead, initHead, disposeHead);
table_head *otfcc_readHead(const otfcc_Packet packet, const otfcc_Options *options) {
FOR_TABLE(OTFCC_CHR('h','e','a','d'), table) {
font_file_pointer data = table.data;
uint32_t length = table.length;
if (length < 54) {
logWarning("table 'head' corrupted.\n");
} else {
table_head *head;
NEW(head);
head->version = read_32s(data);
head->fontRevision = read_32u(data + 4);
head->checkSumAdjustment = read_32u(data + 8);
head->magicNumber = read_32u(data + 12);
head->flags = read_16u(data + 16);
head->unitsPerEm = read_16u(data + 18);
head->created = read_64u(data + 20);
head->modified = read_64u(data + 28);
head->xMin = read_16u(data + 36);
head->yMin = read_16u(data + 38);
head->xMax = read_16u(data + 40);
head->yMax = read_16u(data + 42);
head->macStyle = read_16u(data + 44);
head->lowestRecPPEM = read_16u(data + 46);
head->fontDirectoryHint = read_16u(data + 48);
head->indexToLocFormat = read_16u(data + 50);
head->glyphDataFormat = read_16u(data + 52);
return head;
}
}
return NULL;
}
static const char *headFlagsLabels[] = {"baselineAtY_0",
"lsbAtX_0",
"instrMayDependOnPointSize",
"alwaysUseIntegerSize",
"instrMayAlterAdvanceWidth",
"designedForVertical",
"_reserved1",
"designedForComplexScript",
"hasMetamorphosisEffects",
"containsStrongRTL",
"containsIndicRearrangement",
"fontIsLossless",
"fontIsConverted",
"optimizedForCleartype",
"lastResortFont",
NULL};
static const char *macStyleLabels[] = {"bold", "italic", "underline", "outline",
"shadow", "condensed", "extended", NULL};
void otfcc_dumpHead(const table_head *table, json_value *root, const otfcc_Options *options) {
if (!table) return;
loggedStep("head") {
json_value *head = json_object_new(15);
json_object_push(head, "version", json_double_new(otfcc_from_fixed(table->version)));
json_object_push(head, "fontRevision",
json_double_new(otfcc_from_fixed(table->fontRevision)));
json_object_push(head, "flags", otfcc_dump_flags(table->flags, headFlagsLabels));
json_object_push(head, "unitsPerEm", json_integer_new(table->unitsPerEm));
json_object_push(head, "created", json_integer_new(table->created));
json_object_push(head, "modified", json_integer_new(table->modified));
json_object_push(head, "xMin", json_integer_new(table->xMin));
json_object_push(head, "xMax", json_integer_new(table->xMax));
json_object_push(head, "yMin", json_integer_new(table->yMin));
json_object_push(head, "yMax", json_integer_new(table->yMax));
json_object_push(head, "macStyle", otfcc_dump_flags(table->macStyle, macStyleLabels));
json_object_push(head, "lowestRecPPEM", json_integer_new(table->lowestRecPPEM));
json_object_push(head, "fontDirectoryHint", json_integer_new(table->fontDirectoryHint));
json_object_push(head, "indexToLocFormat", json_integer_new(table->indexToLocFormat));
json_object_push(head, "glyphDataFormat", json_integer_new(table->glyphDataFormat));
json_object_push(root, "head", head);
}
}
table_head *otfcc_parseHead(const json_value *root, const otfcc_Options *options) {
table_head *head = table_iHead.create();
json_value *table = NULL;
if ((table = json_obj_get_type(root, "head", json_object))) {
loggedStep("head") {
head->version = otfcc_to_fixed(json_obj_getnum_fallback(table, "version", 0));
head->fontRevision = otfcc_to_fixed(json_obj_getnum_fallback(table, "fontRevision", 0));
head->flags = otfcc_parse_flags(json_obj_get(table, "flags"), headFlagsLabels);
head->unitsPerEm = json_obj_getnum_fallback(table, "unitsPerEm", 0);
head->created = json_obj_getnum_fallback(table, "created", 0);
head->modified = json_obj_getnum_fallback(table, "modified", 0);
head->xMin = json_obj_getnum_fallback(table, "xMin", 0);
head->xMax = json_obj_getnum_fallback(table, "xMax", 0);
head->yMin = json_obj_getnum_fallback(table, "yMin", 0);
head->yMax = json_obj_getnum_fallback(table, "yMax", 0);
head->macStyle = otfcc_parse_flags(json_obj_get(table, "macStyle"), macStyleLabels);
head->lowestRecPPEM = json_obj_getnum_fallback(table, "lowestRecPPEM", 0);
head->fontDirectoryHint = json_obj_getnum_fallback(table, "fontDirectoryHint", 0);
head->indexToLocFormat = json_obj_getnum_fallback(table, "indexToLocFormat", 0);
head->glyphDataFormat = json_obj_getnum_fallback(table, "glyphDataFormat", 0);
}
}
return head;
}
caryll_Buffer *otfcc_buildHead(const table_head *head, const otfcc_Options *options) {
if (!head) return NULL;
caryll_Buffer *buf = bufnew();
bufwrite32b(buf, head->version);
bufwrite32b(buf, head->fontRevision);
bufwrite32b(buf, head->checkSumAdjustment);
bufwrite32b(buf, head->magicNumber);
bufwrite16b(buf, head->flags);
bufwrite16b(buf, head->unitsPerEm);
bufwrite64b(buf, head->created);
bufwrite64b(buf, head->modified);
bufwrite16b(buf, head->xMin);
bufwrite16b(buf, head->yMin);
bufwrite16b(buf, head->xMax);
bufwrite16b(buf, head->yMax);
bufwrite16b(buf, head->macStyle);
bufwrite16b(buf, head->lowestRecPPEM);
bufwrite16b(buf, head->fontDirectoryHint);
bufwrite16b(buf, head->indexToLocFormat);
bufwrite16b(buf, head->glyphDataFormat);
return buf;
}
|