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)  

CFF.c
Go to the documentation of this file.
1 #include "CFF.h"
2 
3 #include "support/util.h"
4 #include "libcff/libcff.h"
5 #include "libcff/charstring-il.h"
6 #include "libcff/subr.h"
7 
8 
9 const double DEFAULT_BLUE_SCALE = 0.039625;
10 const double DEFAULT_BLUE_SHIFT = 7;
11 const double DEFAULT_BLUE_FUZZ = 1;
12 const double DEFAULT_EXPANSION_FACTOR = 0.06;
13 
16  NEW(pd);
17  pd->blueFuzz = DEFAULT_BLUE_FUZZ;
18  pd->blueScale = DEFAULT_BLUE_SCALE;
19  pd->blueShift = DEFAULT_BLUE_SHIFT;
20  pd->expansionFactor = DEFAULT_EXPANSION_FACTOR;
21  return pd;
22 }
23 
24 static INLINE void initFD(table_CFF *fd) {
25  memset(fd, 0, sizeof(*fd));
26  fd->underlinePosition = -100;
27  fd->underlineThickness = 50;
28 }
30  if (!priv) return;
31  FREE(priv->blueValues);
32  FREE(priv->otherBlues);
33  FREE(priv->familyBlues);
34 
35  FREE(priv->familyOtherBlues);
36  FREE(priv->stemSnapH);
37  FREE(priv->stemSnapV);
38  FREE(priv);
39 }
41  if (!fm) return;
42  iVQ.dispose(&fm->x);
43  iVQ.dispose(&fm->y);
44 }
45 static INLINE void disposeFD(table_CFF *fd) {
46  sdsfree(fd->version);
47  sdsfree(fd->notice);
48  sdsfree(fd->copyright);
49  sdsfree(fd->fullName);
50  sdsfree(fd->familyName);
51  sdsfree(fd->weight);
52 
53  sdsfree(fd->fontName);
54  sdsfree(fd->cidRegistry);
55  sdsfree(fd->cidOrdering);
57  FREE(fd->fontMatrix);
59  if (fd->fdArray) {
60  for (tableid_t j = 0; j < fd->fdArrayCount; j++) {
61  table_iCFF.free(fd->fdArray[j]);
62  }
63  FREE(fd->fdArray);
64  }
65 }
66 
68 
69 typedef struct {
76 static void callback_extract_private(uint32_t op, uint8_t top, cff_Value *stack, void *_context) {
78  table_CFF *meta = context->meta;
79  if (context->fdArrayIndex >= 0 && context->fdArrayIndex < meta->fdArrayCount) {
80  meta = meta->fdArray[context->fdArrayIndex];
81  }
83  switch (op) {
84  // DELTAs
85  case op_BlueValues: {
86  pd->blueValuesCount = top;
87  NEW(pd->blueValues, pd->blueValuesCount);
88  for (arity_t j = 0; j < pd->blueValuesCount; j++) {
89  pd->blueValues[j] = cffnum(stack[j]);
90  }
91  break;
92  }
93  case op_OtherBlues: {
94  pd->otherBluesCount = top;
95  NEW(pd->otherBlues, pd->otherBluesCount);
96  for (arity_t j = 0; j < pd->otherBluesCount; j++) {
97  pd->otherBlues[j] = cffnum(stack[j]);
98  }
99  break;
100  }
101  case op_FamilyBlues: {
102  pd->familyBluesCount = top;
103  NEW(pd->familyBlues, pd->familyBluesCount);
104  for (arity_t j = 0; j < pd->familyBluesCount; j++) {
105  pd->familyBlues[j] = cffnum(stack[j]);
106  }
107  break;
108  }
109  case op_FamilyOtherBlues: {
110  pd->familyOtherBluesCount = top;
111  NEW(pd->familyOtherBlues, pd->familyOtherBluesCount);
112  for (arity_t j = 0; j < pd->familyOtherBluesCount; j++) {
113  pd->familyOtherBlues[j] = cffnum(stack[j]);
114  }
115  break;
116  }
117  case op_StemSnapH: {
118  pd->stemSnapHCount = top;
119  NEW(pd->stemSnapH, pd->stemSnapHCount);
120  for (arity_t j = 0; j < pd->stemSnapHCount; j++) {
121  pd->stemSnapH[j] = cffnum(stack[j]);
122  }
123  break;
124  }
125  case op_StemSnapV: {
126  pd->stemSnapVCount = top;
127  NEW(pd->stemSnapV, pd->stemSnapVCount);
128  for (arity_t j = 0; j < pd->stemSnapVCount; j++) {
129  pd->stemSnapV[j] = cffnum(stack[j]);
130  }
131  break;
132  }
133  // Numbers
134  case op_BlueScale:
135  if (top) { pd->blueScale = cffnum(stack[top - 1]); }
136  break;
137  case op_BlueShift:
138  if (top) { pd->blueShift = cffnum(stack[top - 1]); }
139  break;
140  case op_BlueFuzz:
141  if (top) { pd->blueFuzz = cffnum(stack[top - 1]); }
142  break;
143  case op_StdHW:
144  if (top) { pd->stdHW = cffnum(stack[top - 1]); }
145  break;
146  case op_StdVW:
147  if (top) { pd->stdVW = cffnum(stack[top - 1]); }
148  break;
149  case op_ForceBold:
150  if (top) { pd->forceBold = cffnum(stack[top - 1]); }
151  break;
152  case op_LanguageGroup:
153  if (top) { pd->languageGroup = cffnum(stack[top - 1]); }
154  break;
155  case op_ExpansionFactor:
156  if (top) { pd->expansionFactor = cffnum(stack[top - 1]); }
157  break;
159  if (top) { pd->initialRandomSeed = cffnum(stack[top - 1]); }
160  break;
161  case op_defaultWidthX:
162  if (top) { pd->defaultWidthX = cffnum(stack[top - 1]); }
163  break;
164  case op_nominalWidthX:
165  if (top) { pd->nominalWidthX = cffnum(stack[top - 1]); }
166  break;
167  }
168 }
169 
170 static void callback_extract_fd(uint32_t op, uint8_t top, cff_Value *stack, void *_context) {
172  cff_File *file = context->cffFile;
173  table_CFF *meta = context->meta;
174  if (context->fdArrayIndex >= 0 && context->fdArrayIndex < meta->fdArrayCount) {
175  meta = meta->fdArray[context->fdArrayIndex];
176  }
177  switch (op) {
178  case op_version:
179  if (top) { meta->version = sdsget_cff_sid(stack[top - 1].i, file->string); }
180  break;
181  case op_Notice:
182  if (top) { meta->notice = sdsget_cff_sid(stack[top - 1].i, file->string); }
183  break;
184  case op_Copyright:
185  if (top) { meta->copyright = sdsget_cff_sid(stack[top - 1].i, file->string); }
186  break;
187  case op_FontName:
188  if (top) { meta->fontName = sdsget_cff_sid(stack[top - 1].i, file->string); }
189  break;
190  case op_FullName:
191  if (top) { meta->fullName = sdsget_cff_sid(stack[top - 1].i, file->string); }
192  break;
193  case op_FamilyName:
194  if (top) { meta->familyName = sdsget_cff_sid(stack[top - 1].i, file->string); }
195  break;
196  case op_Weight:
197  if (top) { meta->weight = sdsget_cff_sid(stack[top - 1].i, file->string); }
198  break;
199  case op_FontBBox:
200  if (top >= 4) {
201  meta->fontBBoxLeft = cffnum(stack[top - 4]);
202  meta->fontBBoxBottom = cffnum(stack[top - 3]);
203  meta->fontBBoxRight = cffnum(stack[top - 2]);
204  meta->fontBBoxTop = cffnum(stack[top - 1]);
205  }
206  break;
207  case op_FontMatrix:
208  if (top >= 6) {
209  NEW(meta->fontMatrix);
210  meta->fontMatrix->a = cffnum(stack[top - 6]);
211  meta->fontMatrix->b = cffnum(stack[top - 5]);
212  meta->fontMatrix->c = cffnum(stack[top - 4]);
213  meta->fontMatrix->d = cffnum(stack[top - 3]);
214  meta->fontMatrix->x = iVQ.createStill(cffnum(stack[top - 2]));
215  meta->fontMatrix->y = iVQ.createStill(cffnum(stack[top - 1]));
216  }
217  break;
218  case op_isFixedPitch:
219  if (top) { meta->isFixedPitch = (bool)cffnum(stack[top - 1]); }
220  break;
221  case op_ItalicAngle:
222  if (top) { meta->italicAngle = cffnum(stack[top - 1]); }
223  break;
225  if (top) { meta->underlinePosition = cffnum(stack[top - 1]); }
226  break;
228  if (top) { meta->underlineThickness = cffnum(stack[top - 1]); }
229  break;
230  case op_StrokeWidth:
231  if (top) { meta->strokeWidth = cffnum(stack[top - 1]); }
232  break;
233 
234  // Private
235  case op_Private:
236  if (top >= 2) {
237  uint32_t privateLength = cffnum(stack[top - 2]);
238  uint32_t privateOffset = cffnum(stack[top - 1]);
240  cff_iDict.parseToCallback(file->raw_data + privateOffset, privateLength, context,
242  }
243  break;
244  // CID
245  case op_ROS:
246  if (top >= 3) {
247  meta->isCID = true;
248  meta->cidRegistry = sdsget_cff_sid(stack[top - 3].i, file->string);
249  meta->cidOrdering = sdsget_cff_sid(stack[top - 2].i, file->string);
250  meta->cidSupplement = cffnum(stack[top - 1]);
251  }
252  break;
253  }
254 }
255 
256 typedef struct {
268 
269 static void callback_draw_setwidth(void *_context, double width) {
271  iVQ.replace(&context->g->advanceWidth, iVQ.createStill(width + context->nominalWidthX));
272 }
273 static void callback_draw_next_contour(void *_context) {
275  glyf_Contour c;
276  glyf_iContour.init(&c);
277  glyf_iContourList.push(&context->g->contours, c);
278  context->jContour = context->g->contours.length;
279  context->jPoint = 0;
280 }
281 static void callback_draw_lineto(void *_context, double x1, double y1) {
283  if (context->jContour) {
284  glyf_Contour *contour = &context->g->contours.items[context->jContour - 1];
285  glyf_Point z;
286  glyf_iPoint.init(&z);
287  z.onCurve = true;
288  iVQ.copyReplace(&z.x, iVQ.createStill(x1));
289  iVQ.copyReplace(&z.y, iVQ.createStill(y1));
290  glyf_iContour.push(contour, z);
291  context->jPoint += 1;
292  }
293 }
294 static void callback_draw_curveto(void *_context, double x1, double y1, double x2, double y2,
295  double x3, double y3) {
297  if (context->jContour) {
298  glyf_Contour *contour = &context->g->contours.items[context->jContour - 1];
299  {
300  glyf_Point z;
301  glyf_iPoint.init(&z);
302  z.onCurve = false;
303  iVQ.copyReplace(&z.x, iVQ.createStill(x1));
304  iVQ.copyReplace(&z.y, iVQ.createStill(y1));
305  glyf_iContour.push(contour, z);
306  }
307  {
308  glyf_Point z;
309  glyf_iPoint.init(&z);
310  z.onCurve = false;
311  iVQ.copyReplace(&z.x, iVQ.createStill(x2));
312  iVQ.copyReplace(&z.y, iVQ.createStill(y2));
313  glyf_iContour.push(contour, z);
314  }
315  {
316  glyf_Point z;
317  glyf_iPoint.init(&z);
318  z.onCurve = true;
319  iVQ.copyReplace(&z.x, iVQ.createStill(x3));
320  iVQ.copyReplace(&z.y, iVQ.createStill(y3));
321  glyf_iContour.push(contour, z);
322  }
323  context->jPoint += 3;
324  }
325 }
326 static void callback_draw_sethint(void *_context, bool isVertical, double position, double width) {
328  glyf_iStemDefList.push((isVertical ? &context->g->stemV : &context->g->stemH), //
330  .position = position,
331  .width = width,
332  }));
333 }
334 static void callback_draw_setmask(void *_context, bool isContourMask, bool *maskArray) {
336  glyf_MaskList *maskList = isContourMask ? &context->g->contourMasks : &context->g->hintMasks;
338 
339  if (context->jContour) {
340  mask.contoursBefore = context->jContour - 1;
341  } else {
342  mask.contoursBefore = 0;
343  }
344  mask.pointsBefore = context->jPoint;
345 
346  for (shapeid_t j = 0; j < 0x100; j++) {
347  mask.maskH[j] = j < context->g->stemH.length ? maskArray[j] : 0;
348  mask.maskV[j] = j < context->g->stemV.length ? maskArray[j + context->g->stemH.length] : 0;
349  }
350 
351  FREE(maskArray);
352  if (maskList->length > 0 &&
353  maskList->items[maskList->length - 1].contoursBefore == mask.contoursBefore &&
354  maskList->items[maskList->length - 1].pointsBefore == mask.pointsBefore) {
355  // two masks are stacking together
356  // simply replace maskH and maskV
357  for (shapeid_t j = 0; j < 0x100; j++) {
358  maskList->items[maskList->length - 1].maskH[j] = mask.maskH[j];
359  maskList->items[maskList->length - 1].maskV[j] = mask.maskV[j];
360  }
361  } else {
362  glyf_iMaskList.push(maskList, mask);
363  if (isContourMask) {
364  context->definedContourMasks += 1;
365  } else {
366  context->definedHintMasks += 1;
367  }
368  }
369 }
370 
371 static double callback_draw_getrand(void *_context) {
372  // xorshift64* PRNG to double53
374  uint64_t x = context->randx;
375  x ^= x >> 12;
376  x ^= x << 25;
377  x ^= x >> 27;
378  context->randx = x;
379  union {
380  uint64_t u;
381  double d;
382  } a;
383  a.u = x * UINT64_C(2685821657736338717);
384  a.u = (a.u >> 12) | UINT64_C(0x3FF0000000000000);
385  double q = (a.u & 2048) ? (1.0 - (2.2204460492503131E-16 / 2.0)) : 1.0;
386  return a.d - q;
387 }
388 
390  .newContour = callback_draw_next_contour,
391  .lineTo = callback_draw_lineto,
392  .curveTo = callback_draw_curveto,
393  .setHint = callback_draw_sethint,
394  .setMask = callback_draw_setmask,
395  .getrand = callback_draw_getrand};
396 
398  cff_File *f = context->cffFile;
400  context->glyphs->items[i] = g;
401  uint64_t seed = context->seed;
402 
403  cff_Index localSubrs;
404  cff_iIndex.init(&localSubrs);
405 
407  stack.max = 0x10000;
408  NEW(stack.stack, stack.max);
409  stack.index = 0;
410  stack.stem = 0;
411 
412  outline_builder_context bc = {g, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0};
413 
414  // Determine used FD index and subroutine list
415  uint8_t fd = 0;
416  if (f->fdselect.t != cff_FDSELECT_UNSPECED)
417  fd = cff_parseSubr(i, f->raw_data, f->font_dict, f->fdselect, &localSubrs);
418  else
419  fd = cff_parseSubr(i, f->raw_data, f->top_dict, f->fdselect, &localSubrs);
420 
421  g->fdSelect = Handle.fromIndex(fd);
422 
423  // Decide default and nominal width
424  if (context->meta->fdArray && fd < context->meta->fdArrayCount &&
425  context->meta->fdArray[fd]->privateDict) {
426  bc.defaultWidthX = context->meta->fdArray[fd]->privateDict->defaultWidthX;
427  bc.nominalWidthX = context->meta->fdArray[fd]->privateDict->nominalWidthX;
428  } else if (context->meta->privateDict) {
429  bc.defaultWidthX = context->meta->privateDict->defaultWidthX;
430  bc.nominalWidthX = context->meta->privateDict->nominalWidthX;
431  }
432  iVQ.replace(&g->advanceWidth, iVQ.createStill(bc.defaultWidthX));
433 
434  // Get charstring
435  uint8_t *charStringPtr = f->char_strings.data + f->char_strings.offset[i] - 1;
436  uint32_t charStringLength = f->char_strings.offset[i + 1] - f->char_strings.offset[i];
437 
438  // Draw points
439  stack.index = 0;
440  stack.stem = 0;
441  bc.jContour = 0;
442  bc.jPoint = 0;
443  bc.randx = seed;
444 
445  cff_parseOutline(charStringPtr, charStringLength, f->global_subr, localSubrs, &stack, &bc,
446  drawPass, options);
447 
448  // Turn deltas into absolute coordinates
449  VQ cx = iVQ.neutral(), cy = iVQ.neutral();
450  for (shapeid_t j = 0; j < g->contours.length; j++) {
451  glyf_Contour *contour = &g->contours.items[j];
452  for (shapeid_t k = 0; k < contour->length; k++) {
453  glyf_Point *z = &contour->items[k];
454  iVQ.inplacePlus(&cx, z->x);
455  iVQ.inplacePlus(&cy, z->y);
456  iVQ.copyReplace(&z->x, cx);
457  iVQ.copyReplace(&z->y, cy);
458  }
459  if (!iVQ.compare(contour->items[0].x, contour->items[contour->length - 1].x) &&
460  !iVQ.compare(contour->items[0].y, contour->items[contour->length - 1].y) &&
461  (contour->items[0].onCurve && contour->items[contour->length - 1].onCurve)) {
462  // We found a duplicate knot at the beginning and end of a curve
463  // mainly due to curveto. We can remove that. This is unnecessary.
464  glyf_iContour.pop(contour);
465  }
466  glyf_iContour.shrinkToFit(contour);
467  }
468  glyf_iContourList.shrinkToFit(&g->contours);
469  iVQ.dispose(&cx), iVQ.dispose(&cy);
470 
471  cff_iIndex.dispose(&localSubrs);
472  FREE(stack.stack);
473  context->seed = bc.randx;
474 }
475 
477  return sdscatprintf(sdsnew("CID"), "%d", cid);
478 }
479 
481  cff_File *cffFile = context->cffFile;
482  table_glyf *glyphs = context->glyphs;
483  cff_Charset *charset = &cffFile->charsets;
484  if (context->meta->isCID) {
485  switch (charset->t) {
486  case cff_CHARSET_FORMAT0: {
487  for (glyphid_t j = 0; j < charset->s; j++) {
488  cffsid_t sid = charset->f0.glyph[j];
489  sds glyphname = sdsget_cff_sid(sid, cffFile->string);
490  if (glyphname) {
491  glyphs->items[j + 1]->name = glyphname;
492  glyphs->items[j + 1]->cid = sid;
493  }
494  }
495  break;
496  }
497  case cff_CHARSET_FORMAT1: {
498  uint32_t glyphsNamedSofar = 1;
499  for (glyphid_t j = 0; j < charset->s; j++) {
500  cffsid_t first = charset->f1.range1[j].first;
501  for (glyphid_t k = 0; k <= charset->f1.range1[j].nleft; k++) {
502  cffsid_t sid = first + k;
504  if (glyphsNamedSofar < glyphs->length && glyphname) {
505  glyphs->items[glyphsNamedSofar]->name = glyphname;
506  glyphs->items[glyphsNamedSofar]->cid = sid;
507  }
508  glyphsNamedSofar++;
509  }
510  }
511  break;
512  }
513  case cff_CHARSET_FORMAT2: {
514  uint32_t glyphsNamedSofar = 1;
515  for (glyphid_t j = 0; j < charset->s; j++) {
516  cffsid_t first = charset->f2.range2[j].first;
517  for (glyphid_t k = 0; k <= charset->f2.range2[j].nleft; k++) {
518  cffsid_t sid = first + k;
520  if (glyphsNamedSofar < glyphs->length && glyphname) {
521  glyphs->items[glyphsNamedSofar]->name = glyphname;
522  glyphs->items[glyphsNamedSofar]->cid = sid;
523  }
524  glyphsNamedSofar++;
525  }
526  }
527  break;
528  }
529  }
530  } else {
531  switch (charset->t) {
532  case cff_CHARSET_FORMAT0: {
533  for (glyphid_t j = 0; j < charset->s; j++) {
534  cffsid_t sid = charset->f0.glyph[j];
535  sds glyphname = sdsget_cff_sid(sid, cffFile->string);
536  if (glyphname) { glyphs->items[j + 1]->name = glyphname; }
537  }
538  break;
539  }
540  case cff_CHARSET_FORMAT1: {
541  uint32_t glyphsNamedSofar = 1;
542  for (glyphid_t j = 0; j < charset->s; j++) {
543  glyphid_t first = charset->f1.range1[j].first;
544  for (glyphid_t k = 0; k <= charset->f1.range1[j].nleft; k++) {
545  cffsid_t sid = first + k;
546  sds glyphname = sdsget_cff_sid(sid, cffFile->string);
547  if (glyphsNamedSofar < glyphs->length && glyphname) {
548  glyphs->items[glyphsNamedSofar]->name = glyphname;
549  }
550  glyphsNamedSofar++;
551  }
552  }
553  break;
554  }
555  case cff_CHARSET_FORMAT2: {
556  uint32_t glyphsNamedSofar = 1;
557  for (glyphid_t j = 0; j < charset->s; j++) {
558  glyphid_t first = charset->f2.range2[j].first;
559  for (glyphid_t k = 0; k <= charset->f2.range2[j].nleft; k++) {
560  cffsid_t sid = first + k;
561  sds glyphname = sdsget_cff_sid(sid, cffFile->string);
562  if (glyphsNamedSofar < glyphs->length && glyphname) {
563  glyphs->items[glyphsNamedSofar]->name = glyphname;
564  }
565  glyphsNamedSofar++;
566  }
567  }
568  break;
569  }
570  }
571  }
572 }
573 
574 static double qround(const double x) {
576 }
577 static void applyCffMatrix(table_CFF *CFF_, table_glyf *glyf, const table_head *head) {
578  for (glyphid_t jj = 0; jj < glyf->length; jj++) {
579  glyf_Glyph *g = glyf->items[jj];
580  table_CFF *fd = CFF_;
581  if (fd->fdArray && g->fdSelect.index < fd->fdArrayCount) {
582  fd = fd->fdArray[g->fdSelect.index];
583  }
584  if (fd->fontMatrix) {
585  scale_t a = qround(head->unitsPerEm * fd->fontMatrix->a);
586  scale_t b = qround(head->unitsPerEm * fd->fontMatrix->b);
587  scale_t c = qround(head->unitsPerEm * fd->fontMatrix->c);
588  scale_t d = qround(head->unitsPerEm * fd->fontMatrix->d);
589  VQ x = iVQ.scale(fd->fontMatrix->x, head->unitsPerEm);
590  x.kernel = qround(x.kernel);
591  VQ y = iVQ.scale(fd->fontMatrix->y, head->unitsPerEm);
592  y.kernel = qround(y.kernel);
593  for (shapeid_t j = 0; j < g->contours.length; j++) {
594  glyf_Contour *contour = &g->contours.items[j];
595  for (shapeid_t k = 0; k < contour->length; k++) {
596  VQ zx = iVQ.dup(contour->items[k].x);
597  VQ zy = iVQ.dup(contour->items[k].y);
598  iVQ.replace(&contour->items[k].x, iVQ.pointLinearTfm(x, a, zx, b, zy));
599  iVQ.replace(&contour->items[k].y, iVQ.pointLinearTfm(y, c, zx, d, zy));
600  iVQ.dispose(&zx), iVQ.dispose(&zy);
601  }
602  }
603  iVQ.dispose(&x), iVQ.dispose(&y);
604  }
605  }
606 }
607 
609  const table_head *head) {
611  ret.meta = NULL;
612  ret.glyphs = NULL;
613 
615  context.fdArrayIndex = -1;
616  context.meta = NULL;
617  context.glyphs = NULL;
618  context.cffFile = NULL;
619  FOR_TABLE(OTFCC_CHR('C','F','F',' '), table) {
621  uint32_t length = table.length;
622  cff_File *cffFile = cff_openStream(data, length, options);
623  context.cffFile = cffFile;
624  context.meta = table_iCFF.create();
625 
626  // Extract data in TOP DICT
627  cff_iDict.parseToCallback(cffFile->top_dict.data,
628  cffFile->top_dict.offset[1] - cffFile->top_dict.offset[0],
630 
631  if (!context.meta->fontName) {
632  context.meta->fontName = sdsget_cff_sid(391, cffFile->name);
633  }
634 
635  // We have FDArray
636  if (cffFile->font_dict.count) {
637  context.meta->fdArrayCount = cffFile->font_dict.count;
638  NEW(context.meta->fdArray, context.meta->fdArrayCount);
639  for (tableid_t j = 0; j < context.meta->fdArrayCount; j++) {
640  context.meta->fdArray[j] = table_iCFF.create();
641  context.fdArrayIndex = j;
642  cff_iDict.parseToCallback(
643  cffFile->font_dict.data + cffFile->font_dict.offset[j] - 1,
644  cffFile->font_dict.offset[j + 1] - cffFile->font_dict.offset[j], &context,
646  if (!context.meta->fdArray[j]->fontName) {
647  context.meta->fdArray[j]->fontName = sdscatprintf(sdsempty(), "_Subfont%d", j);
648  }
649  }
650  }
651  ret.meta = context.meta;
652 
653  // Extract data of outlines
654  context.seed = 0x1234567887654321;
655  if (context.meta->privateDict) {
656  context.seed =
657  (uint64_t)context.meta->privateDict->initialRandomSeed ^ 0x1234567887654321;
658  }
659  table_glyf *glyphs = table_iGlyf.createN(cffFile->char_strings.count);
660  context.glyphs = glyphs;
661  for (glyphid_t j = 0; j < glyphs->length; j++) {
663  }
664 
665  applyCffMatrix(context.meta, context.glyphs, head);
666 
667  // Name glyphs according charset
669 
670  ret.glyphs = context.glyphs;
671  cff_close(cffFile);
672  }
673  return ret;
674 }
675 
676 static void pdDeltaToJson(json_value *target, const char *field, arity_t count, double *values) {
677  if (!count || !values) return;
679  for (arity_t j = 0; j < count; j++) {
681  }
683 }
684 
686  json_value *_pd = json_object_new(24);
687  pdDeltaToJson(_pd, "blueValues", pd->blueValuesCount, pd->blueValues);
688  pdDeltaToJson(_pd, "otherBlues", pd->otherBluesCount, pd->otherBlues);
689  pdDeltaToJson(_pd, "familyBlues", pd->familyBluesCount, pd->familyBlues);
690  pdDeltaToJson(_pd, "familyOtherBlues", pd->familyOtherBluesCount, pd->familyOtherBlues);
691  pdDeltaToJson(_pd, "stemSnapH", pd->stemSnapHCount, pd->stemSnapH);
692  pdDeltaToJson(_pd, "stemSnapV", pd->stemSnapVCount, pd->stemSnapV);
693  if (pd->blueScale != DEFAULT_BLUE_SCALE)
694  json_object_push(_pd, "blueScale", json_double_new(pd->blueScale));
695  if (pd->blueShift != DEFAULT_BLUE_SHIFT)
696  json_object_push(_pd, "blueShift", json_double_new(pd->blueShift));
697  if (pd->blueFuzz != DEFAULT_BLUE_FUZZ)
698  json_object_push(_pd, "blueFuzz", json_double_new(pd->blueFuzz));
699  if (pd->stdHW) json_object_push(_pd, "stdHW", json_double_new(pd->stdHW));
700  if (pd->stdVW) json_object_push(_pd, "stdVW", json_double_new(pd->stdVW));
701  if (pd->forceBold) json_object_push(_pd, "forceBold", json_boolean_new(pd->forceBold));
702  if (pd->languageGroup)
703  json_object_push(_pd, "languageGroup", json_double_new(pd->languageGroup));
704  if (pd->expansionFactor != DEFAULT_EXPANSION_FACTOR)
705  json_object_push(_pd, "expansionFactor", json_double_new(pd->expansionFactor));
706  if (pd->initialRandomSeed)
707  json_object_push(_pd, "initialRandomSeed", json_double_new(pd->initialRandomSeed));
708  if (pd->defaultWidthX)
709  json_object_push(_pd, "defaultWidthX", json_double_new(pd->defaultWidthX));
710  if (pd->nominalWidthX)
711  json_object_push(_pd, "nominalWidthX", json_double_new(pd->nominalWidthX));
712  return _pd;
713 }
715  json_value *_CFF_ = json_object_new(24);
716 
717  if (table->isCID) json_object_push(_CFF_, "isCID", json_boolean_new(table->isCID));
718 
719  if (table->version) json_object_push(_CFF_, "version", json_from_sds(table->version));
720  if (table->notice) json_object_push(_CFF_, "notice", json_from_sds(table->notice));
721  if (table->copyright) json_object_push(_CFF_, "copyright", json_from_sds(table->copyright));
722  if (table->fontName) json_object_push(_CFF_, "fontName", json_from_sds(table->fontName));
723  if (table->fullName) json_object_push(_CFF_, "fullName", json_from_sds(table->fullName));
724  if (table->familyName) json_object_push(_CFF_, "familyName", json_from_sds(table->familyName));
725  if (table->weight) json_object_push(_CFF_, "weight", json_from_sds(table->weight));
726 
727  if (table->isFixedPitch)
728  json_object_push(_CFF_, "isFixedPitch", json_boolean_new(table->isFixedPitch));
729  if (table->italicAngle)
730  json_object_push(_CFF_, "italicAngle", json_double_new(table->italicAngle));
731  if (table->underlinePosition != -100)
732  json_object_push(_CFF_, "underlinePosition", json_double_new(table->underlinePosition));
733  if (table->underlineThickness != 50)
734  json_object_push(_CFF_, "underlineThickness", json_double_new(table->underlineThickness));
735  if (table->strokeWidth)
736  json_object_push(_CFF_, "strokeWidth", json_double_new(table->strokeWidth));
737  if (table->fontBBoxLeft)
738  json_object_push(_CFF_, "fontBBoxLeft", json_double_new(table->fontBBoxLeft));
739  if (table->fontBBoxBottom)
740  json_object_push(_CFF_, "fontBBoxBottom", json_double_new(table->fontBBoxBottom));
741  if (table->fontBBoxRight)
742  json_object_push(_CFF_, "fontBBoxRight", json_double_new(table->fontBBoxRight));
743  if (table->fontBBoxTop)
744  json_object_push(_CFF_, "fontBBoxTop", json_double_new(table->fontBBoxTop));
745 
746  if (table->fontMatrix) {
747  json_value *_fontMatrix = json_object_new(6);
748  json_object_push(_fontMatrix, "a", json_double_new(table->fontMatrix->a));
749  json_object_push(_fontMatrix, "b", json_double_new(table->fontMatrix->b));
750  json_object_push(_fontMatrix, "c", json_double_new(table->fontMatrix->c));
751  json_object_push(_fontMatrix, "d", json_double_new(table->fontMatrix->d));
752  json_object_push(_fontMatrix, "x", json_new_VQ(table->fontMatrix->x, NULL));
753  json_object_push(_fontMatrix, "y", json_new_VQ(table->fontMatrix->y, NULL));
754  json_object_push(_CFF_, "fontMatrix", _fontMatrix);
755  }
756  if (table->privateDict) { json_object_push(_CFF_, "privates", pdToJson(table->privateDict)); }
757 
758  if (table->cidRegistry && table->cidOrdering) {
759  json_object_push(_CFF_, "cidRegistry", json_from_sds(table->cidRegistry));
760  json_object_push(_CFF_, "cidOrdering", json_from_sds(table->cidOrdering));
761  json_object_push(_CFF_, "cidSupplement", json_integer_new(table->cidSupplement));
762  }
763  if (table->fdArray) {
764  json_value *_fdArray = json_object_new(table->fdArrayCount);
765  for (tableid_t j = 0; j < table->fdArrayCount; j++) {
766  sds name = table->fdArray[j]->fontName;
767  table->fdArray[j]->fontName = NULL;
768  json_object_push(_fdArray, name, fdToJson(table->fdArray[j]));
769  table->fdArray[j]->fontName = name;
770  }
771  json_object_push(_CFF_, "fdArray", _fdArray);
772  }
773  return _CFF_;
774 }
775 
777  if (!table) return;
778  loggedStep("CFF") {
779  json_object_push(root, "CFF_", fdToJson(table));
780  }
781 }
782 
783 static void pdDeltaFromJson(json_value *dump, arity_t *count, double **array) {
784  if (!dump || dump->type != json_array) return;
785  *count = dump->u.array.length;
786  NEW(*array, *count);
787  for (arity_t j = 0; j < *count; j++) {
788  (*array)[j] = json_numof(dump->u.array.values[j]);
789  }
790 }
792  if (!dump || dump->type != json_object) return NULL;
794  pdDeltaFromJson(json_obj_get(dump, "blueValues"), &(pd->blueValuesCount), &(pd->blueValues));
795  pdDeltaFromJson(json_obj_get(dump, "otherBlues"), &(pd->otherBluesCount), &(pd->otherBlues));
796  pdDeltaFromJson(json_obj_get(dump, "familyBlues"), &(pd->familyBluesCount), &(pd->familyBlues));
797  pdDeltaFromJson(json_obj_get(dump, "familyOtherBlues"), &(pd->familyOtherBluesCount),
798  &(pd->familyOtherBlues));
799  pdDeltaFromJson(json_obj_get(dump, "stemSnapH"), &(pd->stemSnapHCount), &(pd->stemSnapH));
800  pdDeltaFromJson(json_obj_get(dump, "stemSnapV"), &(pd->stemSnapVCount), &(pd->stemSnapV));
801 
802  pd->blueScale = json_obj_getnum_fallback(dump, "blueScale", DEFAULT_BLUE_SCALE);
803  pd->blueShift = json_obj_getnum_fallback(dump, "blueShift", DEFAULT_BLUE_SHIFT);
804  pd->blueFuzz = json_obj_getnum_fallback(dump, "blueFuzz", DEFAULT_BLUE_FUZZ);
805  pd->stdHW = json_obj_getnum(dump, "stdHW");
806  pd->stdVW = json_obj_getnum(dump, "stdVW");
807  pd->forceBold = json_obj_getbool(dump, "forceBold");
808  pd->languageGroup = json_obj_getnum(dump, "languageGroup");
809  pd->expansionFactor =
811  pd->initialRandomSeed = json_obj_getnum(dump, "initialRandomSeed");
812  // Not used -- they will be automatically calculated
813  // pd->defaultWidthX = json_obj_getnum(dump, "defaultWidthX");
814  // pd->nominalWidthX = json_obj_getnum(dump, "nominalWidthX");
815 
816  return pd;
817 }
818 static table_CFF *fdFromJson(const json_value *dump, const otfcc_Options *options, bool topLevel) {
819  table_CFF *table = table_iCFF.create();
820  if (!dump || dump->type != json_object) return table;
821  // Names
822  table->version = json_obj_getsds(dump, "version");
823  table->notice = json_obj_getsds(dump, "notice");
824  table->copyright = json_obj_getsds(dump, "copyright");
825  table->fontName = json_obj_getsds(dump, "fontName");
826  table->fullName = json_obj_getsds(dump, "fullName");
827  table->familyName = json_obj_getsds(dump, "familyName");
828  table->weight = json_obj_getsds(dump, "weight");
829 
830  // Metrics
831  table->isFixedPitch = json_obj_getbool(dump, "isFixedPitch");
832  table->italicAngle = json_obj_getnum(dump, "italicAngle");
833  table->underlinePosition = json_obj_getnum_fallback(dump, "underlinePosition", -100.0);
834  table->underlineThickness = json_obj_getnum_fallback(dump, "underlineThickness", 50.0);
835  table->strokeWidth = json_obj_getnum(dump, "strokeWidth");
836  table->fontBBoxLeft = json_obj_getnum(dump, "fontBBoxLeft");
837  table->fontBBoxBottom = json_obj_getnum(dump, "fontBBoxBottom");
838  table->fontBBoxRight = json_obj_getnum(dump, "fontBBoxRight");
839  table->fontBBoxTop = json_obj_getnum(dump, "fontBBoxTop");
840 
841  // fontMatrix
842  // Need?
843  /*
844  json_value *fmatdump = json_obj_get_type(dump, "fontMatrix", json_object);
845  if (fmatdump) {
846  NEW(table->fontMatrix);
847  table->fontMatrix->a = json_obj_getnum(fmatdump, "a");
848  table->fontMatrix->b = json_obj_getnum(fmatdump, "b");
849  table->fontMatrix->c = json_obj_getnum(fmatdump, "c");
850  table->fontMatrix->d = json_obj_getnum(fmatdump, "d");
851  table->fontMatrix->x = json_obj_getnum(fmatdump, "x");
852  table->fontMatrix->y = json_obj_getnum(fmatdump, "y");
853  }
854  */
855 
856  // privates
857  table->privateDict = pdFromJson(json_obj_get_type(dump, "privates", json_object));
858 
859  // CID
860  table->cidRegistry = json_obj_getsds(dump, "cidRegistry");
861  table->cidOrdering = json_obj_getsds(dump, "cidOrdering");
862  table->cidSupplement = json_obj_getint(dump, "cidSupplement");
863  table->UIDBase = json_obj_getint(dump, "UIDBase");
864  table->cidCount = json_obj_getint(dump, "cidCount");
865  table->cidFontVersion = json_obj_getnum(dump, "cidFontVersion");
866  table->cidFontRevision = json_obj_getnum(dump, "cidFontRevision");
867 
868  // fdArray
869  json_value *fdarraydump = json_obj_get_type(dump, "fdArray", json_object);
870  if (fdarraydump) {
871  table->isCID = true;
872  table->fdArrayCount = fdarraydump->u.object.length;
873  NEW(table->fdArray, table->fdArrayCount);
874  for (tableid_t j = 0; j < table->fdArrayCount; j++) {
875  table->fdArray[j] = fdFromJson(fdarraydump->u.object.values[j].value, options, false);
876  if (table->fdArray[j]->fontName) { sdsfree(table->fdArray[j]->fontName); }
877  table->fdArray[j]->fontName = sdsnewlen(fdarraydump->u.object.values[j].name,
878  fdarraydump->u.object.values[j].name_length);
879  }
880  }
881  if (!table->fontName) table->fontName = sdsnew("CARYLL_CFFFONT");
882  if (!table->privateDict) table->privateDict = otfcc_newCff_private();
883  // Deal with force-cid
884  if (topLevel && options->force_cid && !table->fdArray) {
885  table->fdArrayCount = 1;
886  NEW(table->fdArray, table->fdArrayCount);
887  table->fdArray[0] = table_iCFF.create();
888  table_CFF *fd0 = table->fdArray[0];
889  fd0->privateDict = table->privateDict;
890  table->privateDict = otfcc_newCff_private();
891  fd0->fontName = sdscat(sdsdup(table->fontName), "-subfont0");
892  table->isCID = true;
893  }
894  if (table->isCID && !table->cidRegistry) { table->cidRegistry = sdsnew("CARYLL"); }
895  if (table->isCID && !table->cidOrdering) { table->cidOrdering = sdsnew("OTFCCAUTOCID"); }
896  return table;
897 }
900  if (!dump) {
901  return NULL;
902  } else {
903  table_CFF *cff = NULL;
904  loggedStep("CFF") {
905  cff = fdFromJson(dump, options, true);
906  }
907  return cff;
908  }
909 }
910 
911 typedef struct {
918 typedef struct {
922 
924  caryll_Buffer **gs, caryll_Buffer **ls) {
925  if (context->glyf->length == 0) { return; }
926  for (glyphid_t j = 0; j < context->glyf->length; j++) {
927  cff_CharstringIL *il = cff_compileGlyphToIL(context->glyf->items[j], context->defaultWidth,
928  context->nominalWidthX);
929  cff_optimizeIL(il, context->options);
930  cff_insertILToGraph(&context->graph, il);
931  FREE(il->instr);
932  FREE(il);
933  }
934  cff_ilGraphToBuffers(&context->graph, s, gs, ls, context->options);
935 }
936 
937 // String table management
938 typedef struct {
939  int sid;
940  char *str;
942 } cff_sid_entry;
943 
944 static int sidof(cff_sid_entry **h, sds s) {
946  HASH_FIND_STR(*h, s, item);
947  if (item) {
948  return 391 + item->sid;
949  } else {
950  NEW(item);
951  item->sid = HASH_COUNT(*h);
952  item->str = sdsdup(s);
953  HASH_ADD_STR(*h, str, item);
954  return 391 + item->sid;
955  }
956 }
957 
959  dict->count++;
960  RESIZE(dict->ents, dict->count);
961  return &(dict->ents[dict->count - 1]);
962 }
963 static void cffdict_input(cff_Dict *dict, uint32_t op, cff_Value_Type t, arity_t arity, ...) {
965  last->op = op;
966  last->cnt = arity;
967  NEW(last->vals, arity);
968 
969  va_list ap;
970  va_start(ap, arity);
971  for (arity_t j = 0; j < arity; j++) {
972  if (t == cff_DOUBLE) {
973  double x = va_arg(ap, double);
974  if (x == round(x)) {
975  last->vals[j].t = cff_INTEGER;
976  last->vals[j].i = round(x);
977  } else {
978  last->vals[j].t = cff_DOUBLE;
979  last->vals[j].d = x;
980  }
981  } else {
982  int x = va_arg(ap, int);
983  last->vals[j].t = t;
984  last->vals[j].i = x;
985  }
986  }
987  va_end(ap);
988 }
990  double *arr) {
991  if (!arity || !arr) return;
993  last->op = op;
994  last->cnt = arity;
995  NEW(last->vals, arity);
996  for (arity_t j = 0; j < arity; j++) {
997  double x = arr[j];
998  if (t == cff_DOUBLE) {
999  if (x == round(x)) {
1000  last->vals[j].t = cff_INTEGER;
1001  last->vals[j].i = round(x);
1002  } else {
1003  last->vals[j].t = cff_DOUBLE;
1004  last->vals[j].d = x;
1005  }
1006  } else {
1007  last->vals[j].t = t;
1008  last->vals[j].i = round(x);
1009  }
1010  }
1011 }
1012 
1014  cff_Dict *dict = cff_iDict.create();
1015  // ROS
1016  if (fd->cidRegistry && fd->cidOrdering) {
1018  sidof(h, fd->cidOrdering), fd->cidSupplement);
1019  }
1020 
1021  // CFF Names
1022  if (fd->version) cffdict_input(dict, op_version, cff_INTEGER, 1, sidof(h, fd->version));
1023  if (fd->notice) cffdict_input(dict, op_Notice, cff_INTEGER, 1, sidof(h, fd->notice));
1024  if (fd->copyright) cffdict_input(dict, op_Copyright, cff_INTEGER, 1, sidof(h, fd->copyright));
1025  if (fd->fullName) cffdict_input(dict, op_FullName, cff_INTEGER, 1, sidof(h, fd->fullName));
1026  if (fd->familyName)
1028  if (fd->weight) cffdict_input(dict, op_Weight, cff_INTEGER, 1, sidof(h, fd->weight));
1029 
1030  // CFF Metrics
1032  fd->fontBBoxRight, fd->fontBBoxTop);
1038  if (fd->fontMatrix) {
1040  fd->fontMatrix->a, fd->fontMatrix->b,
1041  fd->fontMatrix->c, fd->fontMatrix->d,
1042  iVQ.getStill(fd->fontMatrix->x), iVQ.getStill(fd->fontMatrix->y));
1043  }
1044 
1045  // CID specific
1046  if (fd->fontName) cffdict_input(dict, op_FontName, cff_INTEGER, 1, sidof(h, fd->fontName));
1047  if (fd->cidFontVersion)
1049  if (fd->cidFontRevision)
1051  if (fd->cidCount) cffdict_input(dict, op_CIDCount, cff_INTEGER, 1, fd->cidCount);
1052  if (fd->UIDBase) cffdict_input(dict, op_UIDBase, cff_INTEGER, 1, fd->UIDBase);
1053  return dict;
1054 }
1055 
1057  cff_Dict *dict;
1058  NEW(dict);
1059  if (!pd) return dict;
1060  // DELTA arrays
1061  cffdict_input_array(dict, op_BlueValues, cff_DOUBLE, pd->blueValuesCount, pd->blueValues);
1062  cffdict_input_array(dict, op_OtherBlues, cff_DOUBLE, pd->otherBluesCount, pd->otherBlues);
1063  cffdict_input_array(dict, op_FamilyBlues, cff_DOUBLE, pd->familyBluesCount, pd->familyBlues);
1064  cffdict_input_array(dict, op_FamilyOtherBlues, cff_DOUBLE, pd->familyOtherBluesCount,
1065  pd->familyOtherBlues);
1066  cffdict_input_array(dict, op_StemSnapH, cff_DOUBLE, pd->stemSnapHCount, pd->stemSnapH);
1067  cffdict_input_array(dict, op_StemSnapV, cff_DOUBLE, pd->stemSnapVCount, pd->stemSnapV);
1068 
1069  // Private scalars
1070  cffdict_input(dict, op_BlueScale, cff_DOUBLE, 1, pd->blueScale);
1071  cffdict_input(dict, op_BlueShift, cff_DOUBLE, 1, pd->blueShift);
1072  cffdict_input(dict, op_BlueFuzz, cff_DOUBLE, 1, pd->blueFuzz);
1073  cffdict_input(dict, op_StdHW, cff_DOUBLE, 1, pd->stdHW);
1074  cffdict_input(dict, op_StdVW, cff_DOUBLE, 1, pd->stdVW);
1075  cffdict_input(dict, op_ForceBold, cff_INTEGER, 1, (int)pd->forceBold);
1076  cffdict_input(dict, op_LanguageGroup, cff_INTEGER, 1, pd->languageGroup);
1077  cffdict_input(dict, op_ExpansionFactor, cff_DOUBLE, 1, pd->expansionFactor);
1078  cffdict_input(dict, op_initialRandomSeed, cff_DOUBLE, 1, pd->initialRandomSeed);
1079 
1080  // op_nominalWidthX are currently not used
1081  cffdict_input(dict, op_defaultWidthX, cff_DOUBLE, 1, pd->defaultWidthX);
1082  cffdict_input(dict, op_nominalWidthX, cff_DOUBLE, 1, pd->nominalWidthX);
1083 
1084  return dict;
1085 }
1086 
1088  return a->sid - b->sid;
1089 }
1091  caryll_Buffer **blobs = context;
1092  return blobs[i];
1093 }
1095  HASH_SORT(*h, by_sid);
1096  caryll_Buffer **blobs;
1097  uint32_t n = HASH_COUNT(*h);
1098  NEW(blobs, n);
1099  uint32_t j = 0;
1100  cff_sid_entry *item, *tmp;
1101  HASH_ITER(hh, *h, item, tmp) {
1102  blobs[j] = bufnew();
1103  bufwrite_sds(blobs[j], item->str);
1104  HASH_DEL(*h, item);
1105  sdsfree(item->str);
1106  FREE(item);
1107  j++;
1108  }
1109 
1110  cff_Index *strings = cff_iIndex.fromCallback(blobs, n, callback_makestringindex);
1111  FREE(blobs);
1112  caryll_Buffer *final_blob = cff_iIndex.build(strings);
1113  cff_iIndex.free(strings);
1114  final_blob->cursor = final_blob->size;
1115  return final_blob;
1116 }
1117 
1119  cff_Index *nameIndex = cff_iIndex.create();
1120  nameIndex->count = 1;
1121  nameIndex->offSize = 4;
1122  NEW(nameIndex->offset, 2);
1123  if (!cff->fontName) { cff->fontName = sdsnew("Caryll-CFF-FONT"); }
1124  nameIndex->offset[0] = 1;
1125  nameIndex->offset[1] = (uint32_t)(sdslen(cff->fontName) + 1);
1126  NEW(nameIndex->data, 1 + sdslen(cff->fontName));
1127  memcpy(nameIndex->data, cff->fontName, sdslen(cff->fontName));
1128  // CFF Name INDEX
1129  caryll_Buffer *buf = cff_iIndex.build(nameIndex);
1130  cff_iIndex.free(nameIndex);
1131  if (cff->fontName) {
1132  sdsfree(cff->fontName);
1133  cff->fontName = NULL;
1134  }
1135  return buf;
1136 }
1137 
1139  cff_sid_entry **stringHash) {
1141  NEW(charset);
1142  if (glyf->length > 1) { // At least two glyphs
1144  charset->s = 1; // One segment only
1145  charset->f2.format = 2;
1146  NEW(charset->f2.range2);
1147  if (cff->isCID) {
1148  charset->f2.range2[0].first = 1;
1149  charset->f2.range2[0].nleft = glyf->length - 2;
1150  } else {
1151  for (glyphid_t j = 1; j < glyf->length; j++) {
1152  sidof(stringHash, glyf->items[j]->name);
1153  }
1154  charset->f2.range2[0].first = sidof(stringHash, glyf->items[1]->name);
1155  charset->f2.range2[0].nleft = glyf->length - 2;
1156  }
1157  } else {
1159  }
1161  if (charset->t == cff_CHARSET_FORMAT2) { FREE(charset->f2.range2); }
1162  FREE(charset);
1163  return c;
1164 }
1165 
1167  if (!cff->isCID) return bufnew();
1168  // We choose format 3 here
1169  uint32_t ranges = 1;
1170  uint8_t current = 0;
1171  cff_FDSelect *fds;
1172  NEW(fds);
1173  fds->t = cff_FDSELECT_UNSPECED;
1174  if (!glyf->length) goto done;
1175  uint8_t fdi0 = glyf->items[0]->fdSelect.index;
1176  if (fdi0 > cff->fdArrayCount) fdi0 = 0;
1177  current = fdi0;
1178  for (glyphid_t j = 1; j < glyf->length; j++) {
1179  uint8_t fdi = glyf->items[j]->fdSelect.index;
1180  if (fdi > cff->fdArrayCount) fdi = 0;
1181  if (fdi != current) {
1182  current = fdi;
1183  ranges++;
1184  }
1185  }
1186  NEW(fds->f3.range3, ranges);
1187  fds->f3.range3[0].first = 0;
1188  fds->f3.range3[0].fd = current = fdi0;
1189  for (glyphid_t j = 1; j < glyf->length; j++) {
1190  uint8_t fdi = glyf->items[j]->fdSelect.index;
1191  if (fdi > cff->fdArrayCount) fdi = 0;
1192  if (glyf->items[j]->fdSelect.index != current) {
1193  current = fdi;
1194  fds->s++;
1195  fds->f3.range3[fds->s].first = j;
1196  fds->f3.range3[fds->s].fd = current;
1197  }
1198  }
1199  fds->t = cff_FDSELECT_FORMAT3;
1200  fds->s = ranges;
1201  fds->f3.format = 3;
1202  fds->f3.nranges = ranges;
1203  fds->f3.sentinel = glyf->length;
1204 done:;
1206  cff_close_FDSelect(*fds);
1207  FREE(fds);
1208  return e;
1209 }
1210 
1211 typedef struct {
1215 static caryll_Buffer *callback_makefd(void *_context, uint32_t i) {
1217  cff_Dict *fd = cff_make_fd_dict(context->fdArray[i], context->stringHash);
1218  caryll_Buffer *blob = cff_iDict.build(fd);
1219  bufwrite_bufdel(blob, cff_buildOffset(0xEEEEEEEE));
1220  bufwrite_bufdel(blob, cff_buildOffset(0xFFFFFFFF));
1222  cff_iDict.build(fd);
1223  return blob;
1224 }
1225 static cff_Index *cff_make_fdarray(tableid_t fdArrayCount, table_CFF **fdArray,
1226  cff_sid_entry **stringHash) {
1228  context.fdArray = fdArray;
1229  context.stringHash = stringHash;
1230 
1231  return cff_iIndex.fromCallback(&context, fdArrayCount, callback_makefd);
1232 }
1233 
1235  const otfcc_Options *options) {
1236  caryll_Buffer *blob = bufnew();
1237  // The Strings hashtable
1238  cff_sid_entry *stringHash = NULL;
1239 
1240  // CFF Header
1243 
1244  // cff top DICT
1245  cff_Dict *top = cff_make_fd_dict(cff, &stringHash);
1246  caryll_Buffer *t = cff_iDict.build(top);
1247  cff_iDict.free(top);
1248 
1249  // cff top PRIVATE
1250  cff_Dict *top_pd = cff_make_private_dict(cff->privateDict);
1251  caryll_Buffer *p = cff_iDict.build(top_pd);
1252  bufwrite_bufdel(p, cff_buildOffset(0xFFFFFFFF));
1254  cff_iDict.free(top_pd);
1255 
1256  // FDSelect
1258 
1259  // FDArray
1260  cff_Index *fdArrayIndex = NULL;
1261  caryll_Buffer *r;
1262  if (cff->isCID) {
1263  fdArrayIndex = cff_make_fdarray(cff->fdArrayCount, cff->fdArray, &stringHash);
1264  r = cff_iIndex.build(fdArrayIndex);
1265  } else {
1266  NEW(r);
1267  }
1268 
1269  // cff charset : Allocate string index terms for glyph names
1270  caryll_Buffer *c = cff_make_charset(cff, glyf, &stringHash);
1271 
1272  // CFF String Index
1273  caryll_Buffer *i = cffstrings_to_indexblob(&stringHash);
1274 
1275  // CFF Charstrings
1276  caryll_Buffer *s;
1277  caryll_Buffer *gs;
1278  caryll_Buffer *ls;
1279  {
1280  cff_charstring_builder_context g2cContext;
1281  g2cContext.glyf = glyf;
1282  g2cContext.defaultWidth = cff->privateDict->defaultWidthX;
1283  g2cContext.nominalWidthX = cff->privateDict->nominalWidthX;
1284  g2cContext.options = options;
1285  cff_iSubrGraph.init(&g2cContext.graph);
1286  g2cContext.graph.doSubroutinize = options->cff_doSubroutinize;
1287 
1288  cff_make_charstrings(&g2cContext, &s, &gs, &ls);
1289 
1290  cff_iSubrGraph.dispose(&g2cContext.graph);
1291  }
1292 
1293  // Merge these data
1294  uint32_t additionalTopDictOpsSize = 0;
1295  uint32_t off = (uint32_t)(h->size + n->size + 11 + t->size);
1296  if (c->size != 0) additionalTopDictOpsSize += 6; // op_charset
1297  if (e->size != 0) additionalTopDictOpsSize += 7; // op_FDSelect
1298  if (s->size != 0) additionalTopDictOpsSize += 6; // op_CharStrings
1299  if (p->size != 0) additionalTopDictOpsSize += 11; // op_Private
1300  if (r->size != 0) additionalTopDictOpsSize += 7; // op_FDArray
1301 
1302  // Start building CFF table
1303  bufwrite_bufdel(blob, h); // header
1304  bufwrite_bufdel(blob, n); // name index
1305  int32_t delta_size = (uint32_t)(t->size + additionalTopDictOpsSize + 1);
1306  bufwrite_bufdel(blob, bufninit(11, 0, 1, // top dict index headerone item
1307  4, // four bytes per offset
1308  0, 0, 0, 1, // offset 1
1309  (delta_size >> 24) & 0xff, (delta_size >> 16) & 0xff,
1310  (delta_size >> 8) & 0xff,
1311  delta_size & 0xff) // offset 2
1312  );
1313 
1314  bufwrite_bufdel(blob, t); // top dict body
1315 
1316  // top dict offsets
1317  off += additionalTopDictOpsSize + i->size + gs->size;
1318  if (c->size != 0) {
1321  off += c->size;
1322  }
1323  if (e->size != 0) {
1326  off += e->size;
1327  }
1328  if (s->size != 0) {
1331  off += s->size;
1332  }
1333  if (p->size != 0) {
1334  bufwrite_bufdel(blob, cff_buildOffset((uint32_t)(p->size)));
1337  off += p->size;
1338  }
1339  if (r->size != 0) {
1342  off += r->size;
1343  }
1344 
1345  bufwrite_bufdel(blob, i); // string index
1346  bufwrite_bufdel(blob, gs); // gsubr
1347  bufwrite_bufdel(blob, c); // charset
1348  bufwrite_bufdel(blob, e); // fdselect
1349  bufwrite_bufdel(blob, s); // charstring
1350  size_t *startingPositionOfPrivates;
1351  NEW(startingPositionOfPrivates, 1 + cff->fdArrayCount);
1352  startingPositionOfPrivates[0] = blob->cursor;
1353  bufwrite_bufdel(blob, p); // top private
1354  size_t *endingPositionOfPrivates;
1355  NEW(endingPositionOfPrivates, 1 + cff->fdArrayCount);
1356  endingPositionOfPrivates[0] = blob->cursor;
1357  if (cff->isCID) { // fdarray and fdarray privates
1358  uint32_t fdArrayPrivatesStartOffset = off;
1359  caryll_Buffer **fdArrayPrivates;
1360  NEW(fdArrayPrivates, cff->fdArrayCount);
1361  for (tableid_t j = 0; j < cff->fdArrayCount; j++) {
1362  cff_Dict *pd = cff_make_private_dict(cff->fdArray[j]->privateDict);
1363  caryll_Buffer *p = cff_iDict.build(pd);
1364  bufwrite_bufdel(p, cff_buildOffset(0xFFFFFFFF));
1366  cff_iDict.free(pd);
1367  fdArrayPrivates[j] = p;
1368  uint8_t *privateLengthPtr = &(fdArrayIndex->data[fdArrayIndex->offset[j + 1] - 11]);
1369  privateLengthPtr[0] = (p->size >> 24) & 0xFF;
1370  privateLengthPtr[1] = (p->size >> 16) & 0xFF;
1371  privateLengthPtr[2] = (p->size >> 8) & 0xFF;
1372  privateLengthPtr[3] = (p->size >> 0) & 0xFF;
1373  uint8_t *privateOffsetPtr = &(fdArrayIndex->data[fdArrayIndex->offset[j + 1] - 6]);
1374  privateOffsetPtr[0] = (fdArrayPrivatesStartOffset >> 24) & 0xFF;
1375  privateOffsetPtr[1] = (fdArrayPrivatesStartOffset >> 16) & 0xFF;
1376  privateOffsetPtr[2] = (fdArrayPrivatesStartOffset >> 8) & 0xFF;
1377  privateOffsetPtr[3] = (fdArrayPrivatesStartOffset >> 0) & 0xFF;
1378  fdArrayPrivatesStartOffset += p->size;
1379  }
1380  buffree(r); // fdarray
1381  r = cff_iIndex.build(fdArrayIndex);
1382  cff_iIndex.free(fdArrayIndex);
1383  bufwrite_bufdel(blob, r);
1384  for (tableid_t j = 0; j < cff->fdArrayCount; j++) {
1385  startingPositionOfPrivates[j + 1] = blob->cursor;
1386  bufwrite_bufdel(blob, fdArrayPrivates[j]);
1387  endingPositionOfPrivates[j + 1] = blob->cursor;
1388  }
1389  FREE(fdArrayPrivates);
1390  } else {
1391  bufwrite_bufdel(blob, r);
1392  }
1393  size_t positionOfLocalSubroutines = blob->cursor;
1394  bufwrite_bufdel(blob, ls);
1395  for (tableid_t j = 0; j < cff->fdArrayCount + 1; j++) {
1396  size_t lsOffset = positionOfLocalSubroutines - startingPositionOfPrivates[j];
1397  uint8_t *ptr = &(blob->data[endingPositionOfPrivates[j] - 5]);
1398  ptr[0] = (lsOffset >> 24) & 0xFF;
1399  ptr[1] = (lsOffset >> 16) & 0xFF;
1400  ptr[2] = (lsOffset >> 8) & 0xFF;
1401  ptr[3] = (lsOffset >> 0) & 0xFF;
1402  }
1403  FREE(startingPositionOfPrivates);
1404  FREE(endingPositionOfPrivates);
1405  // finish
1406  return blob;
1407 }
1408 
1410  return writecff_CIDKeyed(cffAndGlyf.meta, cffAndGlyf.glyphs, options);
1411 }
static void buildOutline(glyphid_t i, cff_extract_context *context, const otfcc_Options *options)
Definition: CFF.c:397
static void applyCffMatrix(table_CFF *CFF_, table_glyf *glyf, const table_head *head)
Definition: CFF.c:577
static table_CFF * fdFromJson(const json_value *dump, const otfcc_Options *options, bool topLevel)
Definition: CFF.c:818
static caryll_Buffer * writecff_CIDKeyed(table_CFF *cff, table_glyf *glyf, const otfcc_Options *options)
Definition: CFF.c:1234
table_CFF * otfcc_parseCFF(const json_value *root, const otfcc_Options *options)
Definition: CFF.c:898
void otfcc_dumpCFF(const table_CFF *table, json_value *root, const otfcc_Options *options)
Definition: CFF.c:776
const double DEFAULT_BLUE_FUZZ
Definition: CFF.c:11
static caryll_Buffer * callback_makefd(void *_context, uint32_t i)
Definition: CFF.c:1215
static void pdDeltaFromJson(json_value *dump, arity_t *count, double **array)
Definition: CFF.c:783
static void cff_make_charstrings(cff_charstring_builder_context *context, caryll_Buffer **s, caryll_Buffer **gs, caryll_Buffer **ls)
Definition: CFF.c:923
static void callback_draw_setwidth(void *_context, double width)
Definition: CFF.c:269
static caryll_Buffer * cffstrings_to_indexblob(cff_sid_entry **h)
Definition: CFF.c:1094
static void callback_draw_next_contour(void *_context)
Definition: CFF.c:273
static cff_Index * cff_make_fdarray(tableid_t fdArrayCount, table_CFF **fdArray, cff_sid_entry **stringHash)
Definition: CFF.c:1225
static double qround(const double x)
Definition: CFF.c:574
static int sidof(cff_sid_entry **h, sds s)
Definition: CFF.c:944
static void cffdict_input_array(cff_Dict *dict, uint32_t op, cff_Value_Type t, arity_t arity, double *arr)
Definition: CFF.c:989
static cff_DictEntry * cffdict_givemeablank(cff_Dict *dict)
Definition: CFF.c:958
caryll_standardRefType(table_CFF, table_iCFF, initFD, disposeFD)
static cff_IOutlineBuilder drawPass
Definition: CFF.c:389
table_CFFAndGlyf otfcc_readCFFAndGlyfTables(const otfcc_Packet packet, const otfcc_Options *options, const table_head *head)
Definition: CFF.c:608
static void pdDeltaToJson(json_value *target, const char *field, arity_t count, double *values)
Definition: CFF.c:676
const double DEFAULT_EXPANSION_FACTOR
Definition: CFF.c:12
static int by_sid(cff_sid_entry *a, cff_sid_entry *b)
Definition: CFF.c:1087
static caryll_Buffer * cff_compile_nameindex(table_CFF *cff)
Definition: CFF.c:1118
static void nameGlyphsAccordingToCFF(cff_extract_context *context)
Definition: CFF.c:480
static void callback_extract_fd(uint32_t op, uint8_t top, cff_Value *stack, void *_context)
Definition: CFF.c:170
static void callback_draw_curveto(void *_context, double x1, double y1, double x2, double y2, double x3, double y3)
Definition: CFF.c:294
static double callback_draw_getrand(void *_context)
Definition: CFF.c:371
static cff_Dict * cff_make_private_dict(cff_PrivateDict *pd)
Definition: CFF.c:1056
static cff_Dict * cff_make_fd_dict(table_CFF *fd, cff_sid_entry **h)
Definition: CFF.c:1013
static cff_PrivateDict * otfcc_newCff_private()
Definition: CFF.c:14
caryll_Buffer * otfcc_buildCFF(const table_CFFAndGlyf cffAndGlyf, const otfcc_Options *options)
Definition: CFF.c:1409
static json_value * pdToJson(const cff_PrivateDict *pd)
Definition: CFF.c:685
static caryll_Buffer * cff_make_fdselect(table_CFF *cff, table_glyf *glyf)
Definition: CFF.c:1166
static caryll_Buffer * cff_make_charset(table_CFF *cff, table_glyf *glyf, cff_sid_entry **stringHash)
Definition: CFF.c:1138
static sds formCIDString(cffsid_t cid)
Definition: CFF.c:476
static void otfcc_delete_privatedict(cff_PrivateDict *priv)
Definition: CFF.c:29
const double DEFAULT_BLUE_SHIFT
Definition: CFF.c:10
static json_value * fdToJson(const table_CFF *table)
Definition: CFF.c:714
static void callback_draw_setmask(void *_context, bool isContourMask, bool *maskArray)
Definition: CFF.c:334
static caryll_Buffer * callback_makestringindex(void *context, uint32_t i)
Definition: CFF.c:1090
static void callback_extract_private(uint32_t op, uint8_t top, cff_Value *stack, void *_context)
Definition: CFF.c:76
static INLINE void disposeFontMatrix(cff_FontMatrix *fm)
Definition: CFF.c:40
static void cffdict_input(cff_Dict *dict, uint32_t op, cff_Value_Type t, arity_t arity,...)
Definition: CFF.c:963
static INLINE void initFD(table_CFF *fd)
Definition: CFF.c:24
const double DEFAULT_BLUE_SCALE
Definition: CFF.c:9
static cff_PrivateDict * pdFromJson(json_value *dump)
Definition: CFF.c:791
static void callback_draw_sethint(void *_context, bool isVertical, double position, double width)
Definition: CFF.c:326
static INLINE void disposeFD(table_CFF *fd)
Definition: CFF.c:45
static void callback_draw_lineto(void *_context, double x1, double y1)
Definition: CFF.c:281
q
Definition: afm2pl.c:2287
struct @88 table[500]
#define width(a)
Definition: aptex-macros.h:198
#define x3
#define count(a)
Definition: aptex-macros.h:781
#define name
#define y3
#define bool
Definition: autosp.c:101
static char * options
Definition: bmeps.c:236
static int item
Definition: brushtopbm.c:66
#define OTFCC_CHR(a, b, c, d)
Definition: caryll-font.c:7
caryll_Buffer * cff_build_Charset(cff_Charset cset)
Definition: cff-charset.c:65
@ cff_CHARSET_FORMAT2
Definition: cff-charset.h:19
@ cff_CHARSET_ISOADOBE
Definition: cff-charset.h:13
@ cff_CHARSET_FORMAT0
Definition: cff-charset.h:17
@ cff_CHARSET_FORMAT1
Definition: cff-charset.h:18
caryll_Buffer * cff_encodeCffOperator(int32_t val)
Definition: cff-codecs.c:22
cff_iDict
Definition: cff-dict.h:30
caryll_Buffer * cff_build_FDSelect(cff_FDSelect fd)
Definition: cff-fdselect.c:16
void cff_close_FDSelect(cff_FDSelect fds)
Definition: cff-fdselect.c:3
@ cff_FDSELECT_FORMAT3
Definition: cff-fdselect.h:14
@ cff_FDSELECT_UNSPECED
Definition: cff-fdselect.h:15
cff_iIndex
Definition: cff-index.h:31
uint8_t cff_parseSubr(uint16_t idx, uint8_t *raw, cff_Index fdarray, cff_FDSelect select, cff_Index *subr)
Definition: cff-parser.c:249
cff_File * cff_openStream(uint8_t *data, uint32_t len, const otfcc_Options *options)
Definition: cff-parser.c:201
void cff_parseOutline(uint8_t *data, uint32_t len, cff_Index gsubr, cff_Index lsubr, cff_Stack *stack, void *outline, cff_IOutlineBuilder methods, const otfcc_Options *options)
Definition: cff-parser.c:342
sds sdsget_cff_sid(uint16_t idx, cff_Index str)
Definition: cff-string.c:402
@ op_FontMatrix
Definition: cff-util.h:20
@ op_CIDFontRevision
Definition: cff-util.h:45
@ op_FamilyName
Definition: cff-util.h:16
@ op_LanguageGroup
Definition: cff-util.h:30
@ op_StemSnapH
Definition: cff-util.h:25
@ op_BlueValues
Definition: cff-util.h:19
@ op_Weight
Definition: cff-util.h:17
@ op_Subrs
Definition: cff-util.h:32
@ op_FullName
Definition: cff-util.h:15
@ op_ROS
Definition: cff-util.h:43
@ op_initialRandomSeed
Definition: cff-util.h:32
@ op_StdHW
Definition: cff-util.h:23
@ op_FDArray
Definition: cff-util.h:49
@ op_CIDFontVersion
Definition: cff-util.h:44
@ op_ItalicAngle
Definition: cff-util.h:15
@ op_FontName
Definition: cff-util.h:51
@ op_UnderlinePosition
Definition: cff-util.h:16
@ op_StemSnapV
Definition: cff-util.h:26
@ op_FontBBox
Definition: cff-util.h:18
@ op_FDSelect
Definition: cff-util.h:50
@ op_Copyright
Definition: cff-util.h:13
@ op_CharStrings
Definition: cff-util.h:30
@ op_nominalWidthX
Definition: cff-util.h:34
@ op_BlueScale
Definition: cff-util.h:22
@ op_StdVW
Definition: cff-util.h:24
@ op_FamilyOtherBlues
Definition: cff-util.h:22
@ op_BlueShift
Definition: cff-util.h:23
@ op_version
Definition: cff-util.h:13
@ op_BlueFuzz
Definition: cff-util.h:24
@ op_isFixedPitch
Definition: cff-util.h:14
@ op_ForceBold
Definition: cff-util.h:27
@ op_FamilyBlues
Definition: cff-util.h:21
@ op_UnderlineThickness
Definition: cff-util.h:17
@ op_Private
Definition: cff-util.h:31
@ op_StrokeWidth
Definition: cff-util.h:21
@ op_Notice
Definition: cff-util.h:14
@ op_CIDCount
Definition: cff-util.h:47
@ op_charset
Definition: cff-util.h:28
@ op_defaultWidthX
Definition: cff-util.h:33
@ op_UIDBase
Definition: cff-util.h:48
@ op_ExpansionFactor
Definition: cff-util.h:31
@ op_OtherBlues
Definition: cff-util.h:20
double cffnum(cff_Value val)
Definition: cff-value.c:3
cff_Value_Type
Definition: cff-value.h:10
@ cff_INTEGER
Definition: cff-value.h:13
@ cff_DOUBLE
Definition: cff-value.h:15
caryll_Buffer * cff_buildHeader(void)
Definition: cff-writer.c:15
caryll_Buffer * cff_buildOffset(int32_t val)
Definition: cff-writer.c:58
cff_CharstringIL * cff_compileGlyphToIL(glyf_Glyph *g, uint16_t defaultWidth, uint16_t nominalWidth)
void cff_optimizeIL(cff_CharstringIL *il, const otfcc_Options *options)
#define n
Definition: t4ht.c:1290
#define b
Definition: jpegint.h:372
#define ap
void glyphs(int opcode)
Definition: disdvi.c:775
int z
Definition: dviconv.c:26
int h
Definition: dviconv.c:9
long hh
Definition: dvi2xx.h:579
char * strings
Definition: dvidvi.c:141
struct rect data
Definition: dvipdfm.c:64
FcObject field
Definition: fcdefault.c:32
mpz_t * f
Definition: gen-fib.c:34
#define s
Definition: afcover.h:80
#define t
Definition: afcover.h:96
glyf_iPoint
Definition: glyf.d:18025
glyf_iContour
Definition: glyf.d:18027
glyf_iMaskList
Definition: glyf.d:18050
table_iGlyf
Definition: glyf.d:18133
glyf_iContourList
Definition: glyf.d:18030
glyf_iStemDefList
Definition: glyf.d:18040
#define c(n)
Definition: gpos-common.c:150
#define a(n)
Definition: gpos-common.c:148
#define d(n)
Definition: gpos-common.c:151
#define bc
Definition: gsftopk.c:501
#define memcpy(d, s, n)
Definition: gsftopk.c:64
const unsigned char FREE
Definition: image.cpp:34
json_value * json_boolean_new(int)
json_value * json_array_new(size_t length)
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_double_new(double)
static double json_numof(const json_value *cv)
Definition: json-funcs.h:62
static json_value * json_obj_get(const json_value *obj, const char *key)
Definition: json-funcs.h:26
static double json_obj_getnum(const json_value *obj, const char *key)
Definition: json-funcs.h:81
static json_value * json_obj_get_type(const json_value *obj, const char *key, const json_type type)
Definition: json-funcs.h:34
static int32_t json_obj_getint(const json_value *obj, const char *key)
Definition: json-funcs.h:93
static sds json_obj_getsds(const json_value *obj, const char *key)
Definition: json-funcs.h:40
static bool json_obj_getbool(const json_value *obj, const char *key)
Definition: json-funcs.h:135
static json_value * json_from_sds(const sds str)
Definition: json-funcs.h:159
json_value * json_new_VQ(const VQ z, const table_fvar *fvar)
Definition: fvar.c:233
static double json_obj_getnum_fallback(const json_value *obj, const char *key, double fallback)
Definition: json-funcs.h:105
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
FT_UInt sid
Definition: cffcmap.c:138
CFF_Font cff
Definition: cffdrivr.c:701
kerning y
Definition: ttdriver.c:212
int int cy
Definition: gdfx.h:13
int int double double double char double char * top
Definition: gdfx.h:19
int cx
Definition: gdfx.h:12
#define NEW
Definition: gdkanji.c:77
unsigned short uint16_t
Definition: stdint.h:79
unsigned int uint32_t
Definition: stdint.h:80
#define UINT64_C(val)
Definition: stdint.h:238
signed int int32_t
Definition: stdint.h:77
unsigned char uint8_t
Definition: stdint.h:78
unsigned __int64 uint64_t
Definition: stdint.h:90
#define INLINE
Definition: port.h:26
void cff_close(cff_font *cff)
Definition: cff.c:192
#define buf
void dump(const char *start, const char *end)
Definition: pdfparse.c:74
static int ret
Definition: convert.c:72
#define length(c)
Definition: ctangleboot.c:65
#define root
Definition: ctangleboot.c:69
#define Handle
Definition: aliases.h:45
uint8_t * font_file_pointer
Definition: aliases.h:41
#define FOR_TABLE(name, table)
Definition: aliases.h:33
#define loggedStep(...)
Definition: aliases.h:6
glyf_Glyph * otfcc_newGlyf_glyph(void)
Definition: glyf.d:20959
#define target(code, i)
Definition: lpeg.c:1165
float x
Definition: cordic.py:15
dictionary off
Definition: fc-lang.py:226
#define RESIZE(ptr, n)
Definition: otfcc-alloc.h:77
int k
Definition: otp-parser.c:70
#define round(a)
Definition: pbmtopk.c:22
static struct Point current
Definition: picttoppm.c:134
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 base endif endm macro PF ptr
static int32_t last
Definition: ppagelist.c:29
static int32_t first
Definition: ppagelist.c:29
int g
Definition: ppmqvga.c:68
int r
Definition: ppmqvga.c:68
uint32_t arity_t
Definition: primitives.h:21
uint16_t tableid_t
Definition: primitives.h:17
uint16_t shapeid_t
Definition: primitives.h:19
uint16_t glyphid_t
Definition: primitives.h:14
double otfcc_from_fixed(const f16dot16 x)
Definition: primitives.c:14
double scale_t
Definition: primitives.h:25
uint16_t cffsid_t
Definition: primitives.h:20
f16dot16 otfcc_to_fixed(const double x)
Definition: primitives.c:17
bstring c int memset(void *s, int c, int length)
static struct pd pd
Definition: pswl.c:17
#define x1
#define y1
#define y2
#define x2
static char * glyphname
Definition: splineoverlap.c:78
charset
Definition: charset.h:51
#define mask(n)
Definition: lbitlib.c:93
caryll_Buffer * bufninit(uint32_t n,...)
Definition: buffer.c:112
void buffree(caryll_Buffer *buf)
Definition: buffer.c:10
void bufwrite_bufdel(caryll_Buffer *buf, caryll_Buffer *that)
Definition: buffer.c:163
caryll_Buffer * bufnew(void)
Definition: buffer.c:4
void bufwrite_sds(caryll_Buffer *buf, sds str)
Definition: buffer.c:133
@ json_array
Definition: json.h:86
@ json_object
Definition: json.h:85
sds sdsnewlen(const void *init, size_t initlen)
sds sdscatprintf(sds s, const char *fmt,...)
void sdsfree(sds s)
static size_t sdslen(const sds s)
Definition: sds.h:91
sds sdsnew(const char *init)
sds sdscat(sds s, const char *t)
sds sdsdup(const sds s)
char * sds
Definition: sds.h:41
sds sdsempty(void)
#define str(s)
Definition: sh6.c:399
ShellFileEnvironment e
Definition: sh6.c:388
#define uint32_t
Definition: stdint.in.h:168
#define uint64_t
Definition: stdint.in.h:215
Definition: vq.h:37
unsigned int name_length
Definition: json.h:103
char * name
Definition: json.h:102
struct _json_value * value
Definition: json.h:105
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
Definition: CFF.h:45
uint32_t cidSupplement
Definition: CFF.h:72
double fontBBoxBottom
Definition: CFF.h:62
sds cidRegistry
Definition: CFF.h:70
sds cidOrdering
Definition: CFF.h:71
sds notice
Definition: CFF.h:52
double underlineThickness
Definition: CFF.h:60
double strokeWidth
Definition: CFF.h:65
double fontBBoxTop
Definition: CFF.h:61
bool isFixedPitch
Definition: CFF.h:57
double underlinePosition
Definition: CFF.h:59
double fontBBoxRight
Definition: CFF.h:64
sds weight
Definition: CFF.h:56
OWNING cff_FontMatrix * fontMatrix
Definition: CFF.h:67
double fontBBoxLeft
Definition: CFF.h:63
OWNING table_CFF ** fdArray
Definition: CFF.h:79
sds fullName
Definition: CFF.h:54
OWNING cff_PrivateDict * privateDict
Definition: CFF.h:66
double cidFontRevision
Definition: CFF.h:74
uint32_t UIDBase
Definition: CFF.h:76
sds copyright
Definition: CFF.h:53
double cidFontVersion
Definition: CFF.h:73
sds fontName
Definition: CFF.h:47
sds version
Definition: CFF.h:51
tableid_t fdArrayCount
Definition: CFF.h:78
bool isCID
Definition: CFF.h:50
uint32_t cidCount
Definition: CFF.h:75
sds familyName
Definition: CFF.h:55
double italicAngle
Definition: CFF.h:58
size_t cursor
Definition: buffer.h:11
uint8_t * data
Definition: buffer.h:14
size_t size
Definition: buffer.h:12
cff_CharstringInstruction * instr
Definition: charstring-il.h:27
cff_DictEntry * ents
Definition: cff-dict.h:19
uint32_t count
Definition: cff-dict.h:18
cff_FDSelectRangeFormat3 * range3
Definition: cff-fdselect.h:31
cff_FDSelectFormat3 f3
Definition: cff-fdselect.h:40
uint32_t t
Definition: cff-fdselect.h:36
uint32_t s
Definition: cff-fdselect.h:37
cff_Index string
Definition: libcff.h:103
cff_Index top_dict
Definition: libcff.h:102
cff_Index font_dict
Definition: libcff.h:110
cff_Index name
Definition: libcff.h:101
cff_Charset charsets
Definition: libcff.h:107
cff_Index char_strings
Definition: libcff.h:109
scale_t a
Definition: CFF.h:9
scale_t b
Definition: CFF.h:10
scale_t d
Definition: CFF.h:12
scale_t c
Definition: CFF.h:11
void(* setWidth)(void *context, double width)
Definition: libcff.h:116
uint32_t * offset
Definition: cff-index.h:19
uint8_t offSize
Definition: cff-index.h:18
arity_t count
Definition: cff-index.h:17
uint8_t * data
Definition: cff-index.h:20
OWNING double * familyBlues
Definition: CFF.h:23
OWNING double * stemSnapV
Definition: CFF.h:34
OWNING double * otherBlues
Definition: CFF.h:21
OWNING double * blueValues
Definition: CFF.h:19
OWNING double * stemSnapH
Definition: CFF.h:32
OWNING double * familyOtherBlues
Definition: CFF.h:25
bool doSubroutinize
Definition: subr.h:46
caryll_Buffer * charStrings
Definition: CFF.c:919
caryll_Buffer * subroutines
Definition: CFF.c:920
cff_SubrGraph graph
Definition: CFF.c:916
const otfcc_Options * options
Definition: CFF.c:915
uint64_t seed
Definition: CFF.c:74
int32_t fdArrayIndex
Definition: CFF.c:70
cff_File * cffFile
Definition: CFF.c:73
table_glyf * glyphs
Definition: CFF.c:72
table_CFF * meta
Definition: CFF.c:71
Definition: CFF.c:938
int sid
Definition: CFF.c:939
char * str
Definition: CFF.c:940
UT_hash_handle hh
Definition: CFF.c:941
Definition: pt1.h:140
table_CFF ** fdArray
Definition: CFF.c:1212
cff_sid_entry ** stringHash
Definition: CFF.c:1213
Definition: filedef.h:30
sds name
Definition: glyf.h:91
otfcc_FDHandle fdSelect
Definition: glyf.h:117
size_t length
Definition: glyf.d:18049
glyf_PostscriptHintMask * items
Definition: glyf.d:18049
bool maskH[0x100]
Definition: glyf.h:39
uint16_t contoursBefore
Definition: glyf.h:38
bool maskV[0x100]
Definition: glyf.h:40
uint16_t pointsBefore
Definition: glyf.h:37
Definition: ttf.h:354
Definition: sh.h:1226
glyphid_t index
Definition: handle.h:20
double nominalWidthX
Definition: CFF.c:261
shapeid_t jPoint
Definition: CFF.c:259
uint64_t randx
Definition: CFF.c:266
double defaultWidthX
Definition: CFF.c:260
uint8_t definedHStems
Definition: CFF.c:262
shapeid_t jContour
Definition: CFF.c:258
glyf_Glyph * g
Definition: CFF.c:257
uint8_t definedHintMasks
Definition: CFF.c:264
uint8_t definedVStems
Definition: CFF.c:263
uint8_t definedContourMasks
Definition: CFF.c:265
Definition: ps.h:43
Definition: spc_misc.c:56
dpx_stack stack
Definition: spc_misc.c:59
Definition: dvips.h:235
OWNING table_CFF * meta
Definition: CFF.h:86
OWNING table_glyf * glyphs
Definition: CFF.h:87
glyf_GlyphPtr * items
Definition: glyf.d:18132
size_t length
Definition: glyf.d:18132
Definition: head.h:6
Definition: table.h:30
void cff_insertILToGraph(cff_SubrGraph *g, cff_CharstringIL *il)
Definition: subr.c:439
void cff_ilGraphToBuffers(cff_SubrGraph *g, caryll_Buffer **s, caryll_Buffer **gs, caryll_Buffer **ls, const otfcc_Options *options)
Definition: subr.c:589
int j
Definition: t4ht.c:1589
op
Definition: tex4ht.c:3129
#define stack
Definition: stack.c:10
#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
#define HASH_SORT(head, cmpfcn)
Definition: uthash.h:960
#define HASH_ADD_STR(head, strfield, add)
Definition: uthash.h:482
#define va_start(pvar)
Definition: varargs.h:30
#define va_arg(pvar, type)
Definition: varargs.h:35
#define va_end(pvar)
Definition: varargs.h:38
char * va_list
Definition: varargs.h:22
iVQ
Definition: vq.h:60
#define position
Definition: xmlparse.c:605