/* Save FSType in PostScript string. */ static void saveFSType(cfwCtx g, abfTopDict *dst) { dictCtx h = g->ctx.dict; char buf[50]; if (dst->PostScript.ptr != ABF_UNSET_PTR) { if (strstr(dst->PostScript.ptr, "/FSType") != NULL) { return; /* PostScript string already has /FSType */ } /* Copy string to tmp buf */ /* 64-bit warning fixed by cast here */ strcpy(dnaEXTEND(h->tmp, (long)strlen(dst->PostScript.ptr)), dst->PostScript.ptr); } /* Append /FSType to tmp buf */ sprintf(buf, "/FSType %ld def", dst->FSType); /* 64-bit warning fixed by cast here */ strcpy(dnaEXTEND(h->tmp, (long)strlen(buf)), buf); /* Set PostScript string to tmp buf */ dst->PostScript.ptr = h->tmp.array; }
/* Add metric data */ static unsigned addMetric(MMFXCtx h, long id, FWord *metric) { Metric *dst; size_t index; MetricLookup met; char cstr[64]; int found; met.ctx = h; met.cstr = cstr; met.length = hotMakeMetric(h->g, metric, met.cstr); found = ctuLookup(&met, h->metrics.array, h->metrics.cnt, sizeof(Metric), matchMetric, &index, h); if (id == -1) { /* Unnamed metric */ if (found) { /* Already in list; return its id */ return h->metrics.array[index].id; } else { /* Not in list; allocate id */ id = h->nextUnnamedId++; } } /* Insert id in list */ dst = INSERT(h->metrics, index); dst->id = (unsigned short)id; dst->length = met.length; if (found) { /* Record index of charstring already in pool */ dst->index = h->metrics.array[index].index; } else { /* Add new charstring to pool */ dst->index = h->cstrs.cnt; memcpy(dnaEXTEND(h->cstrs, met.length), met.cstr, met.length); } return (unsigned)id; }
/* Save OrigFontType in PostScript string. */ static void saveOrigFontType(cfwCtx g, abfTopDict *dst) { dictCtx h = g->ctx.dict; char buf[50]; char *OrigFontType = NULL; /* Suppress optimizer warning */ switch (dst->OrigFontType) { case abfOrigFontTypeType1: OrigFontType = "Type1"; break; case abfOrigFontTypeCID: OrigFontType = "CID"; break; case abfOrigFontTypeTrueType: OrigFontType = "TrueType"; break; case abfOrigFontTypeOCF: OrigFontType = "OCF"; break; default: switch (dst->sup.srcFontType) { case abfSrcFontTypeType1Name: case abfSrcFontTypeCFFName: if (!(dst->sup.flags & ABF_CID_FONT)) { return; /* Nothing to save */ } OrigFontType = "Type1"; /* Name-keyed to cid-keyed conversion */ break; case abfSrcFontTypeType1CID: case abfSrcFontTypeCFFCID: if (dst->sup.flags & ABF_CID_FONT) { return; /* Nothing to save */ } OrigFontType = "CID"; /* CID-keyed to name-keyed conversion */ break; case abfSrcFontTypeSVGName: OrigFontType = "SVG"; break; case abfSrcFontTypeUFOName: OrigFontType = "UFO"; break; case abfSrcFontTypeTrueType: /* TrueType to name-keyed or cid-keyed conversion */ OrigFontType = "TrueType"; break; default: return; } break; } if (dst->PostScript.ptr != ABF_UNSET_PTR) { if (strstr(dst->PostScript.ptr, "/OrigFontType") != NULL) { return; /* PostScript string already has /OrigFontType */ } /* Copy string to tmp buf */ /* 64-bit warning fixed by cast here */ strcpy(dnaEXTEND(h->tmp, (long)strlen(dst->PostScript.ptr)), dst->PostScript.ptr); } /* Append /OrigFontType to tmp buf */ sprintf(buf, "/OrigFontType /%s def", OrigFontType); /* 64-bit warning fixed by cast here */ strcpy(dnaEXTEND(h->tmp, (long)strlen(buf)), buf); /* Set PostScript string to tmp buf */ dst->PostScript.ptr = h->tmp.array; }
/* Save integer number arg in DICT. */ void cfwDictSaveInt(DICT *dict, long i) { char *arg = dnaEXTEND(*dict, 5); dict->cnt -= 5 - cfwEncInt(i, (unsigned char *)arg); }
/* Fill font set from PostScript font files */ static void fillSet(tcCtx g) { tcprivCtx h = g->ctx.tcpriv; int duplicate; int i; Font *last; /* Sort set by font name */ qsort(h->set.array, h->set.cnt, sizeof(Font), cmpFontNames); /* Check for duplicate fonts */ duplicate = 0; last = &h->set.array[0]; for (i = 1; i < h->set.cnt; i++) { Font *curr = &h->set.array[i]; if (strcmp(curr->FontName, last->FontName) == 0) { if (g->cb.message != NULL) { /* Report duplicate FontNames */ char text[513]; sprintf(text, "--- duplicate FontName: %s, files:", curr->FontName); g->cb.message(g->cb.ctx, tcERROR, text); g->cb.message(g->cb.ctx, tcERROR, last->filename); g->cb.message(g->cb.ctx, tcERROR, curr->filename); } duplicate = 1; } last = curr; } if (duplicate) { if (g->cb.message != NULL) { g->cb.message(g->cb.ctx, tcFATAL, "aborting because of errors"); } g->cb.fatal(g->cb.ctx); } /* Handle synthetic fonts */ for (i = 0; i < h->set.cnt; i++) { Font *font = &h->set.array[i]; if (font->flags & FONT_SYNTHETIC) { Font *base = (Font *)bsearch(font->synthetic.baseName, h->set.array, h->set.cnt, sizeof(Font), matchFontName); font->iEncoding = font->synthetic.iEncoding; if (base == NULL) { /* No synthetic base font; make conventional font */ dnaFREE(font->synthetic.dict); font->flags &= ~FONT_SYNTHETIC; } else { /* Synthetic base found: make synthetic font */ csFreeFont(g, font); dnaFREE(font->Private); font->Private.cnt = 0; /* Build new dict with SyntheticBase op first */ font->dict.cnt = 0; dictSaveInt(&font->dict, base - h->set.array); DICTSAVEOP(font->dict, cff_SyntheticBase); /* Append the other synthetic ops to dict */ COPY(dnaEXTEND(font->dict, font->synthetic.dict.cnt), font->synthetic.dict.array, font->synthetic.dict.cnt); dnaFREE(font->synthetic.dict); } MEM_FREE(g, font->synthetic.baseName); } } #if TC_SUBR_SUPPORT if (g->flags & TC_SUBRIZE) { subrSubrize(g, h->set.cnt, h->set.array); } #endif /* TC_SUBR_SUPPORT */ if (t13CheckAuth(g, &h->set.array[0]) && h->set.cnt != 1) { tcFatal(g, "authentication applied to multiple fonts"); } h->size.encodings = encodingFill(g); h->size.charsets = charsetFill(g); h->size.strings = sindexSize(g); h->size.FDSelects = fdselectFill(g); fillOffsets(h); h->FontSet.size = h->offset.copyright + ((h->copyright == NULL) ? 0 : strlen(h->copyright)); }