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)  

classifier.c
Go to the documentation of this file.
1 #include "../chaining.h"
2 
3 // Chaining substitution classifier
4 // We will merge similar subtables.
5 
6 typedef struct {
7  int gid;
9  int cls;
13  return a->gid - b->gid;
14 }
15 
16 static int classCompatible(classifier_hash **h, otl_Coverage *cov, int *past) {
17  // checks whether a coverage is compatible to a class hash.
19  if (cov->numGlyphs == 0) return 1;
20  int gid = cov->glyphs[0].index;
21  // check pass
22  HASH_FIND_INT(*h, &gid, s);
23  if (s) {
24  // the coverage has been defined into a class
25  classifier_hash *ss, *tmp;
26  for (glyphid_t j = 1; j < cov->numGlyphs; j++) {
27  int gid = cov->glyphs[j].index;
28  HASH_FIND_INT(*h, &gid, ss);
29  if (!ss || ss->cls != s->cls) return 0;
30  }
31  // reverse check: all glyphs classified are there in the coverage
32  classifier_hash *revh = NULL;
33  for (glyphid_t j = 0; j < cov->numGlyphs; j++) {
34  int gid = cov->glyphs[j].index;
35  classifier_hash *rss = NULL;
36  HASH_FIND_INT(revh, &gid, rss);
37  if (!rss) {
38  NEW(rss);
39  rss->gid = gid;
40  rss->gname = cov->glyphs[j].name;
41  rss->cls = s->cls;
42  HASH_ADD_INT(revh, gid, rss);
43  }
44  }
45 
46  bool allcheck = true;
47  foreach_hash(ss, *h) if (ss->cls == s->cls) {
48  int gid = ss->gid;
49  classifier_hash *rss;
50  HASH_FIND_INT(revh, &gid, rss);
51  if (!rss) {
52  allcheck = false;
53  break;
54  }
55  }
56  HASH_ITER(hh, revh, ss, tmp) {
57  HASH_DEL(revh, ss);
58  FREE(ss);
59  }
60  return allcheck ? s->cls : 0;
61  } else {
62  // the coverage is not defined into a class.
63  classifier_hash *ss;
64  for (glyphid_t j = 1; j < cov->numGlyphs; j++) {
65  int gid = cov->glyphs[j].index;
66  HASH_FIND_INT(*h, &gid, ss);
67  if (ss) return 0;
68  }
69  for (glyphid_t j = 0; j < cov->numGlyphs; j++) {
70  int gid = cov->glyphs[j].index;
72  HASH_FIND_INT(*h, &gid, s);
73  if (!s) {
74  NEW(s);
75  s->gid = cov->glyphs[j].index;
76  s->gname = cov->glyphs[j].name;
77  s->cls = *past + 1;
78  HASH_ADD_INT(*h, gid, s);
79  }
80  }
81  *past += 1;
82  return 1;
83  }
84 }
87  otl_ChainingRule *newRule;
88  NEW(newRule);
89  newRule->matchCount = rule->matchCount;
90  newRule->inputBegins = rule->inputBegins;
91  newRule->inputEnds = rule->inputEnds;
92  NEW(newRule->match, newRule->matchCount);
93  for (tableid_t m = 0; m < rule->matchCount; m++) {
94  NEW(newRule->match[m]);
95  newRule->match[m]->numGlyphs = 1;
96  NEW(newRule->match[m]->glyphs);
97  if (rule->match[m]->numGlyphs > 0) {
98  classifier_hash *h = (m < rule->inputBegins ? hb : m < rule->inputEnds ? hi : hf);
100  int gid = rule->match[m]->glyphs[0].index;
101  HASH_FIND_INT(h, &gid, s);
102  newRule->match[m]->glyphs[0] = Handle.fromIndex(s->cls);
103  } else {
104  newRule->match[m]->glyphs[0] = Handle.fromIndex(0);
105  }
106  }
107  newRule->applyCount = rule->applyCount;
108  NEW(newRule->apply, newRule->applyCount);
109  for (tableid_t j = 0; j < rule->applyCount; j++) {
110  newRule->apply[j].index = rule->apply[j].index;
111  newRule->apply[j].lookup = Handle.dup(rule->apply[j].lookup);
112  }
113  return newRule;
114 }
116  otl_ClassDef *cd = ClassDef.create();
119  foreach_hash(item, *h) {
120  ClassDef.push(cd, Handle.fromConsolidated(item->gid, item->gname), item->cls);
121  }
122  return cd;
123 }
125  OUT subtable_chaining **classifiedST) {
126  tableid_t compatibleCount = 0;
128  classifier_hash *hi = NULL;
130  // initialize the class hash
131  subtable_chaining *subtable0 = &(lookup->subtables.items[j]->chaining);
132  int classno_b = 0;
133  int classno_i = 0;
134  int classno_f = 0;
135 
136  otl_ChainingRule *rule0 = &subtable0->rule;
137  for (tableid_t m = 0; m < rule0->matchCount; m++) {
138  int check = 0;
139  if (m < rule0->inputBegins) {
140  check = classCompatible(&hb, rule0->match[m], &classno_b);
141  } else if (m < rule0->inputEnds) {
142  check = classCompatible(&hi, rule0->match[m], &classno_i);
143  } else {
144  check = classCompatible(&hf, rule0->match[m], &classno_f);
145  }
146  if (!check) { goto FAIL; }
147  }
148  for (tableid_t k = j + 1; k < lookup->subtables.length; k++) {
149  otl_ChainingRule *rule = &lookup->subtables.items[k]->chaining.rule;
150  bool allcheck = true;
151  for (tableid_t m = 0; m < rule->matchCount; m++) {
152  int check = 0;
153  if (m < rule->inputBegins) {
154  check = classCompatible(&hb, rule->match[m], &classno_b);
155  } else if (m < rule->inputEnds) {
156  check = classCompatible(&hi, rule->match[m], &classno_i);
157  } else {
158  check = classCompatible(&hf, rule->match[m], &classno_f);
159  }
160  if (!check) {
161  allcheck = false;
162  goto endcheck;
163  }
164  }
165  if (allcheck) { compatibleCount += 1; }
166  }
167 endcheck:
168  if (compatibleCount > 1) {
169  // We've found multiple compatible subtables;
170  NEW(subtable0);
171  subtable0->rulesCount = compatibleCount + 1;
172  NEW(subtable0->rules, compatibleCount + 1);
173 
174  subtable0->rules[0] = buildRule(rule0, hb, hi, hf);
175  // write other rules
176  tableid_t kk = 1;
177  for (tableid_t k = j + 1; k < lookup->subtables.length && kk < compatibleCount + 1; k++) {
178  otl_ChainingRule *rule = &lookup->subtables.items[k]->chaining.rule;
179  subtable0->rules[kk] = buildRule(rule, hb, hi, hf);
180  kk++;
181  }
182 
183  subtable0->type = otl_chaining_classified;
184  subtable0->bc = toClass(&hb);
185  subtable0->ic = toClass(&hi);
186  subtable0->fc = toClass(&hf);
187  *classifiedST = subtable0;
188  }
189 FAIL:;
190  if (hb) {
191  classifier_hash *s, *tmp;
192  HASH_ITER(hh, hb, s, tmp) {
193  HASH_DEL(hb, s);
194  FREE(s);
195  }
196  }
197  if (hi) {
198  classifier_hash *s, *tmp;
199  HASH_ITER(hh, hi, s, tmp) {
200  HASH_DEL(hi, s);
201  FREE(s);
202  }
203  }
204  if (hf) {
205  classifier_hash *s, *tmp;
206  HASH_ITER(hh, hf, s, tmp) {
207  HASH_DEL(hf, s);
208  FREE(s);
209  }
210  }
211 
212  if (compatibleCount > 1) {
213  return compatibleCount;
214  } else {
215  return 0;
216  }
217 }
219  OUT caryll_Buffer ***subtableBuffers,
220  MODIFY size_t *lastOffset) {
221  bool isContextual = otfcc_chainingLookupIsContextualLookup(lookup);
222  tableid_t subtablesWritten = 0;
223  NEW(*subtableBuffers, lookup->subtables.length);
224  for (tableid_t j = 0; j < lookup->subtables.length; j++) {
225  subtable_chaining *st0 = &(lookup->subtables.items[j]->chaining);
226  if (st0->type) continue;
227  subtable_chaining *st = st0;
228  // Try to classify subtables after j into j
229  j += tryClassifyAround(lookup, j, &st);
232  if (st != st0) { iSubtable_chaining.free(st); }
233  (*subtableBuffers)[subtablesWritten] = buf;
234  *lastOffset += buf->size;
235  subtablesWritten += 1;
236  }
237  return subtablesWritten;
238 }
static int hf
Definition: aptex.h:615
static halfword hb
Definition: aptex.h:614
static int item
Definition: brushtopbm.c:66
#define check(T, S)
static tableid_t tryClassifyAround(const otl_Lookup *lookup, tableid_t j, OUT subtable_chaining **classifiedST)
Definition: classifier.c:124
tableid_t otfcc_classifiedBuildChaining(const otl_Lookup *lookup, OUT caryll_Buffer ***subtableBuffers, MODIFY size_t *lastOffset)
Definition: classifier.c:218
static otl_ChainingRule * buildRule(otl_ChainingRule *rule, classifier_hash *hb, classifier_hash *hi, classifier_hash *hf)
Definition: classifier.c:85
static int by_gid_clsh(classifier_hash *a, classifier_hash *b)
Definition: classifier.c:12
static otl_ClassDef * toClass(classifier_hash **h)
Definition: classifier.c:115
static int classCompatible(classifier_hash **h, otl_Coverage *cov, int *past)
Definition: classifier.c:16
#define b
Definition: jpegint.h:372
int h
Definition: dviconv.c:9
long hh
Definition: dvi2xx.h:579
#define s
Definition: afcover.h:80
#define a(n)
Definition: gpos-common.c:148
const unsigned char FREE
Definition: image.cpp:34
@ otl_chaining_classified
Definition: otl.h:73
#define NULL
Definition: ftobjs.h:61
#define OUT(dst, src)
Definition: md5.c:184
#define NEW
Definition: gdkanji.c:77
#define buf
#define ClassDef
Definition: aliases.h:55
#define foreach_hash(id, range)
Definition: aliases.h:39
#define Handle
Definition: aliases.h:45
_Bool otfcc_chainingLookupIsContextualLookup(const otl_Lookup *lookup)
Definition: build.c:4
iSubtable_chaining
Definition: otl.d:20805
caryll_Buffer * otfcc_build_contextual(const otl_Subtable *_subtable)
Definition: build.c:233
caryll_Buffer * otfcc_build_chaining(const otl_Subtable *_subtable)
Definition: build.c:136
int k
Definition: otp-parser.c:70
#define MODIFY
Definition: ownership.h:7
uint16_t tableid_t
Definition: primitives.h:17
uint16_t glyphid_t
Definition: primitives.h:14
char * sds
Definition: sds.h:41
UT_hash_handle hh
Definition: classifier.c:10
Definition: zic.c:306
OWNING sds name
Definition: handle.h:21
glyphid_t index
Definition: handle.h:20
otfcc_LookupHandle lookup
Definition: otl.h:80
tableid_t applyCount
Definition: otl.h:87
tableid_t matchCount
Definition: otl.h:83
OWNING otl_Coverage ** match
Definition: otl.h:86
tableid_t inputBegins
Definition: otl.h:84
tableid_t inputEnds
Definition: otl.h:85
OWNING otl_ChainLookupApplication * apply
Definition: otl.h:88
otfcc_GlyphHandle * glyphs
Definition: coverage.h:8
glyphid_t numGlyphs
Definition: coverage.h:6
Definition: rule.h:21
Definition: stemdb.c:56
otl_ChainingRule rule
Definition: otl.h:93
OWNING otl_ClassDef * ic
Definition: otl.h:98
otl_chaining_type type
Definition: otl.h:91
tableid_t rulesCount
Definition: otl.h:95
OWNING otl_ClassDef * fc
Definition: otl.h:99
OWNING otl_ClassDef * bc
Definition: otl.h:97
OWNING otl_ChainingRule ** rules
Definition: otl.h:96
int j
Definition: t4ht.c:1589
m
Definition: tex4ht.c:3990
#define FAIL(ec)
#define HASH_DEL(head, delptr)
Definition: uthash.h:498
#define HASH_ITER(hh, head, el, tmp)
Definition: uthash.h:1131
#define HASH_SORT(head, cmpfcn)
Definition: uthash.h:960
#define HASH_FIND_INT(head, findint, out)
Definition: uthash.h:486
#define HASH_ADD_INT(head, intfield, add)
Definition: uthash.h:488