/* Save simple int array operator in DICT. */ static void saveIntArrayOp(DICT *dict, int cnt, long *array, int op) { int i; for (i = 0; i < cnt; i++) { cfwDictSaveInt(dict, array[i]); } cfwDictSaveOp(dict, op); }
/* Save real number arg in DICT. If not fractional save as integer. */ void cfwDictSaveReal(DICT *dict, float r) { char buf[50]; int value; /* Current nibble value */ int last = 0; /* Last nibble value */ int odd = 0; /* Flags odd nibble */ long i = (long)r; if (i == r) { /* Value was integer */ cfwDictSaveInt(dict, i); return; } /* Convert to string; 8 digits of precision is enough to accurately represent the matrix of a typical TrueType font using a 2048 unit em */ ctuDtostr(buf, r, 0, 8); *dnaNEXT(*dict) = cff_BCD; for (i = buf[0] == '0';; i++) { switch (buf[i]) { case '\0': /* Terminate number */ *dnaNEXT(*dict) = odd ? last << 4 | 0xf : 0xff; return; case '+': continue; case '-': value = 0xe; break; case '.': value = 0xa; break; case 'E': case 'e': value = (buf[++i] == '-') ? 0xc : 0xb; break; default: value = buf[i] - '0'; break; } if (odd) { *dnaNEXT(*dict) = last << 4 | value; } else { last = value; } odd = !odd; } }
/* Save real number arg in DICT. If not fractional save as integer. */ void cfwDictSaveReal(DICT *dict, float r) { char buf[50]; int value; /* Current nibble value */ int last = 0; /* Last nibble value */ int odd = 0; /* Flags odd nibble */ long i = (long)r; if (i == r) { /* Value was integer */ cfwDictSaveInt(dict, i); return; } ctuDtostr(buf, r, 0, 8); /* 8 places is as good as it gets when converting ASCII real numbers->float-> ASCII real numbers, as happens to all the PrivateDict values.*/ *dnaNEXT(*dict) = cff_BCD; for (i = buf[0] == '0';; i++) { switch (buf[i]) { case '\0': /* Terminate number */ *dnaNEXT(*dict) = odd ? last << 4 | 0xf : 0xff; return; case '+': continue; case '-': value = 0xe; break; case '.': value = 0xa; break; case 'E': case 'e': value = (buf[++i] == '-') ? 0xc : 0xb; break; default: value = buf[i] - '0'; break; } if (odd) { *dnaNEXT(*dict) = last << 4 | value; } else { last = value; } odd = !odd; } }
/* Fill CFF top dict. */ void cfwDictFillTop(cfwCtx g, DICT *dst, abfTopDict *top, abfFontDict *font0, long iSyntheticBase) { int embed = g->flags & (CFW_EMBED_OPT | CFW_ROM_OPT); dst->cnt = 0; if (iSyntheticBase != -1) { /* Make synthetic font dictionary */ cfwDictSaveIntOp(dst, iSyntheticBase, cff_SyntheticBase); /* FullName */ if (top->FullName.impl != SRI_UNDEF) { saveStringOp(g, dst, (SRI)top->FullName.impl, cff_FullName); } /* ItalicAngle */ if (top->ItalicAngle != cff_DFLT_ItalicAngle) { cfwDictSaveRealOp(dst, top->ItalicAngle, cff_ItalicAngle); } /* FontMatrix */ saveFontMatrix(dst, &font0->FontMatrix); return; } /* ROS */ if (top->sup.flags & ABF_CID_FONT) { cfwDictSaveInt(dst, cfwSindexAssignSID(g, (SRI)top->cid.Registry.impl)); cfwDictSaveInt(dst, cfwSindexAssignSID(g, (SRI)top->cid.Ordering.impl)); cfwDictSaveInt(dst, top->cid.Supplement); cfwDictSaveOp(dst, cff_ROS); } /* version */ if (top->version.impl != SRI_UNDEF && !embed) { saveStringOp(g, dst, (SRI)top->version.impl, cff_version); } /* Notice */ if (top->Notice.impl != SRI_UNDEF) { saveStringOp(g, dst, (SRI)top->Notice.impl, cff_Notice); } if (top->Copyright.impl != SRI_UNDEF && (!embed || top->Notice.impl == SRI_UNDEF)) { saveStringOp(g, dst, (SRI)top->Copyright.impl, cff_Copyright); } /* FullName */ if (top->FullName.impl != SRI_UNDEF && !embed) { saveStringOp(g, dst, (SRI)top->FullName.impl, cff_FullName); } /* FamilyName */ if (top->FamilyName.impl != SRI_UNDEF && !embed) { saveStringOp(g, dst, (SRI)top->FamilyName.impl, cff_FamilyName); } /* Weight */ if (top->Weight.impl != SRI_UNDEF) { saveStringOp(g, dst, (SRI)top->Weight.impl, cff_Weight); } /* isFixedPitch */ if (top->isFixedPitch != cff_DFLT_isFixedPitch && !embed) { cfwDictSaveIntOp(dst, top->isFixedPitch, cff_isFixedPitch); } /* ItalicAngle */ if (top->ItalicAngle != cff_DFLT_ItalicAngle) { cfwDictSaveRealOp(dst, top->ItalicAngle, cff_ItalicAngle); } /* UnderlinePosition */ if (top->UnderlinePosition != cff_DFLT_UnderlinePosition && !embed) { cfwDictSaveRealOp(dst, top->UnderlinePosition, cff_UnderlinePosition); } /* UnderlineThickness */ if (top->UnderlineThickness != cff_DFLT_UnderlineThickness && !embed) { cfwDictSaveRealOp(dst, top->UnderlineThickness, cff_UnderlineThickness); } /* PostScript */ if (top->PostScript.impl != SRI_UNDEF) { saveStringOp(g, dst, (SRI)top->PostScript.impl, cff_PostScript); } /* BaseFontName */ if (top->BaseFontName.impl != SRI_UNDEF) { saveStringOp(g, dst, (SRI)top->BaseFontName.impl, cff_BaseFontName); } /* BaseFontBlend */ if (top->BaseFontBlend.cnt != ABF_EMPTY_ARRAY) { saveIntDeltaOp(dst, top->BaseFontBlend.cnt, top->BaseFontBlend.array, cff_BaseFontBlend); } /* FontBBox */ if (top->FontBBox[0] != 0 || top->FontBBox[1] != 0 || top->FontBBox[2] != 0 || top->FontBBox[3] != 0) { top->FontBBox[0] = roundf(top->FontBBox[0]); top->FontBBox[1] = roundf(top->FontBBox[1]); top->FontBBox[2] = roundf(top->FontBBox[2]); top->FontBBox[3] = roundf(top->FontBBox[3]); saveRealArrayOp(dst, 4, top->FontBBox, cff_FontBBox); } if (top->sup.flags & ABF_CID_FONT) { /* FontMatrix; note default values are different from font dict */ if (top->cid.FontMatrix.cnt != ABF_EMPTY_ARRAY && (top->cid.FontMatrix.array[0] != 1.0 || top->cid.FontMatrix.array[1] != 0.0 || top->cid.FontMatrix.array[2] != 0.0 || top->cid.FontMatrix.array[3] != 1.0 || top->cid.FontMatrix.array[4] != 0.0 || top->cid.FontMatrix.array[5] != 0.0)) { saveRealArrayOp(dst, 6, top->cid.FontMatrix.array, cff_FontMatrix); } } else { /* PaintType */ if (font0->PaintType != cff_DFLT_PaintType) { cfwDictSaveIntOp(dst, font0->PaintType, cff_PaintType); } /* FontMatrix */ saveFontMatrix(dst, &font0->FontMatrix); } /* UniqueID */ if (top->UniqueID != ABF_UNSET_INT) { cfwDictSaveIntOp(dst, top->UniqueID, cff_UniqueID); } /* StrokeWidth */ if (top->StrokeWidth != cff_DFLT_StrokeWidth) { cfwDictSaveRealOp(dst, top->StrokeWidth, cff_StrokeWidth); } if (top->sup.flags & ABF_CID_FONT) { /* CIDFontVersion */ if (top->cid.CIDFontVersion != cff_DFLT_CIDFontVersion) { cfwDictSaveRealOp(dst, top->cid.CIDFontVersion, cff_CIDFontVersion); } /* CIDFontRevision */ if (top->cid.CIDFontRevision != cff_DFLT_CIDFontRevision) { cfwDictSaveIntOp(dst, top->cid.CIDFontRevision, cff_CIDFontRevision); } /* CIDCount */ if (top->cid.CIDCount != cff_DFLT_CIDCount) { cfwDictSaveIntOp(dst, top->cid.CIDCount, cff_CIDCount); } /* UIDBase */ if (top->cid.UIDBase != ABF_UNSET_INT) { cfwDictSaveIntOp(dst, top->cid.UIDBase, cff_UIDBase); } } /* XUID */ if (top->XUID.cnt != ABF_EMPTY_ARRAY) { saveIntArrayOp(dst, top->XUID.cnt, top->XUID.array, cff_XUID); } }
/* Save string in DICT. */ static void saveStringOp(cfwCtx g, DICT *dict, SRI sri, int op) { cfwDictSaveInt(dict, cfwSindexAssignSID(g, sri)); cfwDictSaveOp(dict, op); }
/* Save integer operator. */ void cfwDictSaveIntOp(DICT *dict, long i, int op) { cfwDictSaveInt(dict, i); cfwDictSaveOp(dict, op); }