w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

gpos-mark-to-ligature.c
Go to the documentation of this file.
2 #include "gpos-common.h"
3 
5  Handle.dispose(&entry->glyph);
6  if (entry->anchors) {
7  for (glyphid_t k = 0; k < entry->componentCount; k++)
8  FREE(entry->anchors[k]);
9  FREE(entry->anchors);
10  }
11 }
13  .init = NULL, .copy = NULL, .dispose = deleteLigArrayItem};
14 
17 
19  otl_iMarkArray.init(&subtable->markArray);
20  otl_iLigatureArray.init(&subtable->ligArray);
21 }
23  otl_iMarkArray.dispose(&subtable->markArray);
24  otl_iLigatureArray.dispose(&subtable->ligArray);
25 }
26 
29 
31  uint32_t offset, const glyphid_t maxGlyphs,
32  const otfcc_Options *options) {
34  otl_Coverage *marks = NULL;
36  if (tableLength < offset + 12) goto FAIL;
37 
38  marks = Coverage.read(data, tableLength, offset + read_16u(data + offset + 2));
39  bases = Coverage.read(data, tableLength, offset + read_16u(data + offset + 4));
40  if (!marks || marks->numGlyphs == 0 || !bases || bases->numGlyphs == 0) goto FAIL;
41  subtable->classCount = read_16u(data + offset + 6);
42 
43  uint32_t markArrayOffset = offset + read_16u(data + offset + 8);
44  otl_readMarkArray(&subtable->markArray, marks, data, tableLength, markArrayOffset);
45 
46  uint32_t ligArrayOffset = offset + read_16u(data + offset + 10);
47  checkLength(ligArrayOffset + 2 + 2 * bases->numGlyphs);
48  if (read_16u(data + ligArrayOffset) != bases->numGlyphs) goto FAIL;
49 
50  for (glyphid_t j = 0; j < bases->numGlyphs; j++) {
52  lig.glyph = Handle.dup(bases->glyphs[j]);
53  uint32_t ligAttachOffset = ligArrayOffset + read_16u(data + ligArrayOffset + 2 + j * 2);
54  checkLength(ligAttachOffset + 2);
55  lig.componentCount = read_16u(data + ligAttachOffset);
56 
57  checkLength(ligAttachOffset + 2 + 2 * lig.componentCount * subtable->classCount);
58  NEW(lig.anchors, lig.componentCount);
59 
60  uint32_t _offset = ligAttachOffset + 2;
61  for (glyphid_t k = 0; k < lig.componentCount; k++) {
62  NEW(lig.anchors[k], subtable->classCount);
63  for (glyphclass_t m = 0; m < subtable->classCount; m++) {
64  uint32_t anchorOffset = read_16u(data + _offset);
65  if (anchorOffset) {
66  lig.anchors[k][m] =
67  otl_read_anchor(data, tableLength, ligAttachOffset + anchorOffset);
68  } else {
69  lig.anchors[k][m] = otl_anchor_absent();
70  }
71  _offset += 2;
72  }
73  }
74  otl_iLigatureArray.push(&subtable->ligArray, lig);
75  }
76  if (marks) Coverage.free(marks);
77  if (bases) Coverage.free(bases);
78  return (otl_Subtable *)subtable;
79 FAIL:
80  if (marks) Coverage.free(marks);
81  if (bases) Coverage.free(bases);
82  iSubtable_gpos_markToLigature.free(subtable);
83  return NULL;
84 }
85 
87  const subtable_gpos_markToLigature *subtable = &(st->gpos_markToLigature);
88  json_value *_subtable = json_object_new(3);
89  json_value *_marks = json_object_new(subtable->markArray.length);
90  json_value *_bases = json_object_new(subtable->ligArray.length);
91  for (glyphid_t j = 0; j < subtable->markArray.length; j++) {
92  json_value *_mark = json_object_new(3);
93  sds markClassName = sdscatfmt(sdsempty(), "ac_%i", subtable->markArray.items[j].markClass);
94  json_object_push(_mark, "class",
95  json_string_new_length((uint32_t)sdslen(markClassName), markClassName));
96  sdsfree(markClassName);
97  json_object_push(_mark, "x", json_integer_new(subtable->markArray.items[j].anchor.x));
98  json_object_push(_mark, "y", json_integer_new(subtable->markArray.items[j].anchor.y));
99  json_object_push(_marks, subtable->markArray.items[j].glyph.name, preserialize(_mark));
100  }
101  for (glyphid_t j = 0; j < subtable->ligArray.length; j++) {
102  otl_LigatureBaseRecord *base = &subtable->ligArray.items[j];
103  json_value *_base = json_array_new(base->componentCount);
104  for (glyphid_t k = 0; k < base->componentCount; k++) {
105  json_value *_bk = json_object_new(subtable->classCount);
106  for (glyphclass_t m = 0; m < subtable->classCount; m++) {
107  if (base->anchors[k][m].present) {
108  json_value *_anchor = json_object_new(2);
109  json_object_push(_anchor, "x", json_integer_new(base->anchors[k][m].x));
110  json_object_push(_anchor, "y", json_integer_new(base->anchors[k][m].y));
111  sds markClassName = sdscatfmt(sdsempty(), "ac_%i", m);
112  json_object_push_length(_bk, (uint32_t)sdslen(markClassName), markClassName,
113  _anchor);
114  sdsfree(markClassName);
115  }
116  }
117  json_array_push(_base, _bk);
118  }
119  json_object_push(_bases, base->glyph.name, preserialize(_base));
120  }
121  json_object_push(_subtable, "classCount", json_integer_new(subtable->classCount));
122  json_object_push(_subtable, "marks", _marks);
123  json_object_push(_subtable, "bases", _bases);
124  return _subtable;
125 }
126 
127 static void parseBases(json_value *_bases, subtable_gpos_markToLigature *subtable,
129  glyphclass_t classCount = HASH_COUNT(*h);
130 
131  for (glyphid_t j = 0; j < _bases->u.object.length; j++) {
132  char *gname = _bases->u.object.values[j].name;
134  lig.componentCount = 0;
135  lig.anchors = NULL;
136  lig.glyph = Handle.fromName(
137  sdsnewlen(_bases->u.object.values[j].name, _bases->u.object.values[j].name_length));
138 
139  json_value *baseRecord = _bases->u.object.values[j].value;
140  if (!baseRecord || baseRecord->type != json_array) {
141  otl_iLigatureArray.push(&subtable->ligArray, lig);
142  continue;
143  }
144  lig.componentCount = baseRecord->u.array.length;
145 
146  NEW(lig.anchors, lig.componentCount);
147 
148  for (glyphid_t k = 0; k < lig.componentCount; k++) {
149  json_value *_componentRecord = baseRecord->u.array.values[k];
150  NEW(lig.anchors[k], classCount);
151  for (glyphclass_t m = 0; m < classCount; m++) {
152  lig.anchors[k][m] = otl_anchor_absent();
153  }
154  if (!_componentRecord || _componentRecord->type != json_object) { continue; }
155  for (glyphclass_t m = 0; m < _componentRecord->u.object.length; m++) {
156  sds className = sdsnewlen(_componentRecord->u.object.values[m].name,
157  _componentRecord->u.object.values[m].name_length);
159  HASH_FIND_STR(*h, className, s);
160  if (!s) {
161  logWarning("[OTFCC-fea] Invalid anchor class name <%s> for /%s. This base "
162  "anchor is ignored.\n",
163  className, gname);
164  goto NEXT;
165  }
166  lig.anchors[k][s->classID] =
167  otl_parse_anchor(_componentRecord->u.object.values[m].value);
168 
169  NEXT:
170  sdsfree(className);
171  }
172  }
173  otl_iLigatureArray.push(&subtable->ligArray, lig);
174  }
175 }
177  const otfcc_Options *options) {
178  json_value *_marks = json_obj_get_type(_subtable, "marks", json_object);
179  json_value *_bases = json_obj_get_type(_subtable, "bases", json_object);
180  if (!_marks || !_bases) return NULL;
183  otl_parseMarkArray(_marks, &st->markArray, &h, options);
184  st->classCount = HASH_COUNT(h);
185  parseBases(_bases, st, &h, options);
186 
187  otl_ClassnameHash *s, *tmp;
188  HASH_ITER(hh, h, s, tmp) {
189  HASH_DEL(h, s);
190  sdsfree(s->className);
191  FREE(s);
192  }
193 
194  return (otl_Subtable *)st;
195 }
196 
198  const subtable_gpos_markToLigature *subtable = &(_subtable->gpos_markToLigature);
199  otl_Coverage *marks = Coverage.create();
200  for (glyphid_t j = 0; j < subtable->markArray.length; j++) {
201  Coverage.push(marks, Handle.dup(subtable->markArray.items[j].glyph));
202  }
203  otl_Coverage *bases = Coverage.create();
204  for (glyphid_t j = 0; j < subtable->ligArray.length; j++) {
205  Coverage.push(bases, Handle.dup(subtable->ligArray.items[j].glyph));
206  }
207 
208  bk_Block *root = bk_new_Block(b16, 1, // format
209  p16, bk_newBlockFromBuffer(Coverage.build(marks)), // markCoverage
210  p16, bk_newBlockFromBuffer(Coverage.build(bases)), // baseCoverage
211  b16, subtable->classCount, // classCont
212  bkover);
213 
214  bk_Block *markArray = bk_new_Block(b16, subtable->markArray.length, // markCount
215  bkover);
216  for (glyphid_t j = 0; j < subtable->markArray.length; j++) {
217  bk_push(markArray, // markArray item
218  b16, subtable->markArray.items[j].markClass, // markClass
219  p16, bkFromAnchor(subtable->markArray.items[j].anchor), // Anchor
220  bkover);
221  }
222 
223  bk_Block *ligatureArray = bk_new_Block(b16, subtable->ligArray.length, bkover);
224  for (glyphid_t j = 0; j < subtable->ligArray.length; j++) {
225  bk_Block *attach =
226  bk_new_Block(b16, subtable->ligArray.items[j].componentCount, // componentCount
227  bkover);
228  for (glyphid_t k = 0; k < subtable->ligArray.items[j].componentCount; k++) {
229  for (glyphclass_t m = 0; m < subtable->classCount; m++) {
230  bk_push(attach, p16, bkFromAnchor(subtable->ligArray.items[j].anchors[k][m]),
231  bkover);
232  }
233  }
234  bk_push(ligatureArray, p16, attach, bkover);
235  }
236 
237  bk_push(root, p16, markArray, p16, ligatureArray, bkover);
238  Coverage.free(marks);
239  Coverage.free(bases);
240  return bk_build_Block(root);
241 }
NEXT
Definition: action.c:17
static uint16_t read_16u(const uint8_t *src)
Definition: bin-io.h:121
bk_Block * bk_newBlockFromBuffer(MOVE caryll_Buffer *buf)
Definition: bkblock.c:98
bk_Block * bk_new_Block(int type0,...)
Definition: bkblock.c:72
bk_Block * bk_push(bk_Block *b, int type0,...)
Definition: bkblock.c:81
@ b16
Definition: bkblock.h:17
@ p16
Definition: bkblock.h:19
@ bkover
Definition: bkblock.h:15
caryll_Buffer * bk_build_Block(bk_Block *root)
Definition: bkgraph.c:396
int h
Definition: dviconv.c:9
long hh
Definition: dvi2xx.h:579
struct rect data
Definition: dvipdfm.c:64
#define s
Definition: afcover.h:80
bk_Block * bkFromAnchor(otl_Anchor a)
Definition: gpos-common.c:134
otl_Anchor otl_parse_anchor(json_value *v)
Definition: gpos-common.c:125
void otl_parseMarkArray(json_value *_marks, otl_MarkArray *array, otl_ClassnameHash **h, const otfcc_Options *options)
Definition: gpos-common.c:37
void otl_readMarkArray(otl_MarkArray *array, otl_Coverage *cov, font_file_pointer data, uint32_t tableLength, uint32_t offset)
Definition: gpos-common.c:11
otl_Anchor otl_read_anchor(font_file_pointer data, uint32_t tableLength, uint32_t offset)
Definition: gpos-common.c:102
otl_Anchor otl_anchor_absent()
Definition: gpos-common.c:98
otl_Subtable * otl_gpos_parse_markToLigature(const json_value *_subtable, const otfcc_Options *options)
json_value * otl_gpos_dump_markToLigature(const otl_Subtable *st)
caryll_standardVectorImpl(otl_LigatureArray, otl_LigatureBaseRecord, la_typeinfo, otl_iLigatureArray)
static INLINE void initMarkToLigature(subtable_gpos_markToLigature *subtable)
caryll_standardRefType(subtable_gpos_markToLigature, iSubtable_gpos_markToLigature, initMarkToLigature, disposeMarkToLigature)
static void deleteLigArrayItem(otl_LigatureBaseRecord *entry)
static caryll_ElementInterface(otl_LigatureBaseRecord)
otl_Subtable * otl_read_gpos_markToLigature(const font_file_pointer data, uint32_t tableLength, uint32_t offset, const glyphid_t maxGlyphs, const otfcc_Options *options)
static void parseBases(json_value *_bases, subtable_gpos_markToLigature *subtable, otl_ClassnameHash **h, const otfcc_Options *options)
static INLINE void disposeMarkToLigature(subtable_gpos_markToLigature *subtable)
caryll_Buffer * otfcc_build_gpos_markToLigature(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics)
int base
Definition: gsftopk.c:1502
const unsigned char FREE
Definition: image.cpp:34
json_value * json_array_new(size_t length)
json_value * json_string_new_length(unsigned int length, const char *)
json_value * json_array_push(json_value *array, json_value *)
json_value * json_object_push(json_value *object, const char *name, json_value *)
json_value * json_integer_new(int64_t)
json_value * json_object_new(size_t length)
json_value * json_object_push_length(json_value *object, unsigned int name_length, const char *name, json_value *)
static json_value * preserialize(MOVE json_value *x)
Definition: json-funcs.h:187
static json_value * json_obj_get_type(const json_value *obj, const char *key, const json_type type)
Definition: json-funcs.h:34
#define NULL
Definition: ftobjs.h:61
#define NEW
Definition: gdkanji.c:77
unsigned int uint32_t
Definition: stdint.h:80
#define INLINE
Definition: port.h:26
pdf_obj * entry
Definition: pdfdoc.c:64
#define root
Definition: ctangleboot.c:69
#define logWarning(...)
Definition: aliases.h:14
#define Handle
Definition: aliases.h:45
uint8_t * font_file_pointer
Definition: aliases.h:41
#define Coverage
Definition: aliases.h:58
otl_iLigatureArray
Definition: otl.d:20873
otl_iMarkArray
Definition: otl.d:20851
otl_BuildHeuristics
Definition: otl.d:20979
iSubtable_gpos_markToLigature
Definition: otl.d:20880
int k
Definition: otp-parser.c:70
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst st
static int offset
Definition: ppmtogif.c:642
uint16_t glyphid_t
Definition: primitives.h:14
uint16_t glyphclass_t
Definition: primitives.h:15
@ json_array
Definition: json.h:86
@ json_object
Definition: json.h:85
#define checkLength(offset)
Definition: common.h:13
sds sdsnewlen(const void *init, size_t initlen)
void sdsfree(sds s)
static size_t sdslen(const sds s)
Definition: sds.h:91
sds sdscatfmt(sds s, char const *fmt,...)
char * sds
Definition: sds.h:41
sds sdsempty(void)
unsigned int name_length
Definition: json.h:103
char * name
Definition: json.h:102
struct _json_value * value
Definition: json.h:105
json_type type
Definition: json.h:113
unsigned int length
Definition: json.h:123
struct _json_value::@1795::@1798 object
json_object_entry * values
Definition: json.h:132
union _json_value::@1795 u
struct _json_value::@1795::@1799 array
Definition: afm2pl.c:139
OWNING sds name
Definition: handle.h:21
pos_t x
Definition: otl.h:123
pos_t y
Definition: otl.h:124
glyphid_t numGlyphs
Definition: coverage.h:6
size_t length
Definition: otl.d:20872
otl_LigatureBaseRecord * items
Definition: otl.d:20872
glyphid_t componentCount
Definition: otl.h:167
OWNING otfcc_GlyphHandle glyph
Definition: otl.h:166
OWNING otl_Anchor ** anchors
Definition: otl.h:168
otl_MarkRecord * items
Definition: otl.d:20850
size_t length
Definition: otl.d:20850
OWNING otfcc_GlyphHandle glyph
Definition: otl.h:144
glyphclass_t markClass
Definition: otl.h:145
otl_Anchor anchor
Definition: otl.h:146
Definition: stemdb.c:56
otl_LigatureArray ligArray
Definition: otl.h:176
OWNING otl_MarkArray markArray
Definition: otl.h:175
glyphclass_t classCount
Definition: otl.h:174
int j
Definition: t4ht.c:1589
m
Definition: tex4ht.c:3990
struct _lig lig
Definition: ttf2tfm.h:48
subtable_gpos_markToLigature gpos_markToLigature
Definition: otl.h:196
#define FAIL(ec)
#define HASH_FIND_STR(head, findstr, out)
Definition: uthash.h:480
#define HASH_DEL(head, delptr)
Definition: uthash.h:498
#define HASH_ITER(hh, head, el, tmp)
Definition: uthash.h:1131
#define HASH_COUNT(head)
Definition: uthash.h:1137