void pdf_grow_pattern(PDF *p) { static const char fn[] = "pdf_grow_pattern"; int i; p->pattern = (pdf_pattern *) pdc_realloc(p->pdc, p->pattern, sizeof(pdf_pattern) * 2 * p->pattern_capacity, fn); for (i = p->pattern_capacity; i < 2 * p->pattern_capacity; i++) { p->pattern[i].used_on_current_page = pdc_false; p->pattern[i].obj_id = PDC_BAD_ID; } p->pattern_capacity *= 2; }
void pdc_freset(pdc_file *sfp, size_t size) { static const char fn[] = "pdc_freset"; if (sfp->wrmode && !sfp->fp) { if (size > (size_t) (sfp->limit - sfp->data)) { sfp->data = (pdc_byte *) pdc_realloc(sfp->pdc, sfp->data, size, fn); sfp->limit = sfp->data + size; } sfp->pos = sfp->data; sfp->end = sfp->data; } }
size_t pdc_fwrite(const void *ptr, size_t size, size_t nmemb, pdc_file *sfp) { static const char fn[] = "pdc_fwrite"; if (sfp->wrmode) { size_t poslen, nbytes = 0; if (sfp->fp) { size_t total = pdc__fwrite(ptr, size, nmemb, sfp->fp); if (total < size * nmemb) { pdc_set_fwrite_errmsg(sfp->pdc, sfp->filename); PDC_RETHROW(sfp->pdc); } return total; } nbytes = size * nmemb; if (sfp->pos + nbytes > sfp->limit) { poslen = (size_t) (sfp->pos - sfp->data); size = poslen + nbytes; sfp->data = (pdc_byte *) pdc_realloc(sfp->pdc, sfp->data, size, fn); sfp->pos = sfp->data + poslen; sfp->end = sfp->data + size; sfp->limit = sfp->end; } memcpy(sfp->pos, ptr, nbytes); sfp->pos += nbytes; if (sfp->pos > sfp->end) sfp->end = sfp->pos; } else { nmemb = 0; } return nmemb; }
/* * Returns the full specified path name in a new memory. * The full path name can be concatened by a path name, * file name and extension (incl. dot). */ char * pdc_file_concat(pdc_core *pdc, const char *dirname, const char *basename, const char *extension) { static const char fn[] = "pdc_file_concat"; char *pathname = pdc_file_fullname_mem(pdc, dirname, basename); size_t len = strlen(pathname) + 1; if (extension != NULL) len += strlen(extension); pathname = (char *) pdc_realloc(pdc, pathname, len, fn); if (extension != NULL) strcat(pathname, extension); return pathname; }
pdc_id pdc_alloc_id(pdc_output *out) { pdc_core *pdc = out->pdc; out->lastobj++; if (out->lastobj >= out->file_offset_capacity) { out->file_offset_capacity *= 2; out->file_offset = (long *) pdc_realloc(pdc, out->file_offset, sizeof(long) * out->file_offset_capacity, "pdc_alloc_id"); } /* only needed for verifying obj table in PDF_close() */ out->file_offset[out->lastobj] = PDC_BAD_ID; return out->lastobj; }
static void pdc_tmlist_grow(pdc_core *pdc) { static const char fn[] = "pdc_tmlist_grow"; pdc_tmpmem_list *tm_list = &pdc->pr->tm_list; static const int chunksize = 20; if (tm_list->capacity == 0) { tm_list->capacity = chunksize; tm_list->tmpmem = (pdc_tmpmem *) pdc_malloc(pdc, (size_t) (tm_list->capacity * sizeof (pdc_tmpmem)), fn); } else { tm_list->capacity += chunksize; tm_list->tmpmem = (pdc_tmpmem *) pdc_realloc(pdc, tm_list->tmpmem, (size_t) (tm_list->capacity * sizeof (pdc_tmpmem)), fn); } }
pdc_id pdc_alloc_id(pdc_output *out) { out->lastobj++; if (out->lastobj > PDF_MAXINDOBJS) pdc_error(out->pdc, PDC_E_INT_TOOMUCH_INDOBJS, pdc_errprintf(out->pdc, "%d", PDF_MAXINDOBJS), 0, 0, 0); if (out->lastobj >= out->file_offset_capacity) { out->file_offset_capacity *= 2; out->file_offset = (pdc_off_t *) pdc_realloc(out->pdc, out->file_offset, sizeof(pdc_off_t) * out->file_offset_capacity, "pdc_alloc_id"); } /* only needed for verifying obj table in PDF_close() */ out->file_offset[out->lastobj] = PDC_BAD_ID; return out->lastobj; }
static int pdf_insert_bookmark( PDF *p, const char *hypertext, pdf_outline *outline, int jndex) { static const char fn[] = "pdf_insert_bookmark"; pdf_outline *root, *self; int parent; int self_idx; int pageno = pdf_current_page(p); /* allocation */ if (p->outline_count == 0) { p->outline_capacity = OUTLINE_CHUNKSIZE; p->outlines = (pdf_outline *) pdc_calloc(p->pdc, sizeof(pdf_outline) * p->outline_capacity, fn); /* populate the root outline object */ root = &p->outlines[0]; pdf_init_outline(p, root); root->obj_id = pdc_alloc_id(p->out); root->open = pdc_true; /* set the open mode show bookmarks if we have at least one, * and the client didn't already set his own open mode. */ pdf_fix_openmode(p); } else if (p->outline_count + 1 >= p->outline_capacity) { p->outline_capacity *= 2; p->outlines = (pdf_outline *) pdc_realloc(p->pdc, p->outlines, sizeof(pdf_outline) * p->outline_capacity, fn); } /* copy */ self_idx = ++p->outline_count; self = &p->outlines[self_idx]; memcpy(self, outline, sizeof(pdf_outline)); self->obj_id = pdc_alloc_id(p->out); self->text = (char *) hypertext; self->page_id = pdf_get_page_id(p, 0); parent = self->parent; /* default destination */ if (self->action == NULL && self->dest == NULL) self->dest = pdf_init_destination(p); /* no destination */ if (self->dest != NULL && self->dest->name != NULL && !strlen(self->dest->name)) { pdf_cleanup_destination(p, self->dest); self->dest = NULL; } /* current page */ if (self->dest) { /* this ugly code is for compatibility with the ** obsolete "bookmarkdest" parameter. */ if (self->dest->pgnum == 0) self->dest->pgnum = pdf_current_page(p); if (self->dest->pgnum == 0) { self->dest->pgnum = 1; } else if (self->dest->page == PDC_BAD_ID) { self->dest->page = pdf_get_page_id(p, self->dest->pgnum); } } /* special case: empty list. */ if (FIRST(parent) == 0) { if (jndex > 0) pdc_error(p->pdc, PDC_E_OPT_ILLINTEGER, "index", pdc_errprintf(p->pdc, "%d", jndex), 0, 0); FIRST(parent) = LAST(parent) = self_idx; self->in_order = pdc_true; } else switch (jndex) { case -2: /* insert "in order" */ { /* the "natural" case: append to the end if appropriate. */ if (pageno >= search_backward(p, -1, LAST(parent))) { self->prev = LAST(parent); NEXT(LAST(parent)) = self_idx; LAST(parent) = self_idx; } else { int idx; int curr_pg = 1; int next_pg; for (idx = FIRST(parent); idx != 0; idx = NEXT(idx)) { if (!IN_ORDER(idx)) continue; next_pg = pdf_search_page_fwd(p, curr_pg, PAGE_ID(idx)); /* TODO: understand why this can happen. */ if (next_pg < 1) { idx = 0; break; } if (next_pg > pageno) { self->next = idx; self->prev = PREV(idx); PREV(idx) = self_idx; if (self->prev == 0) FIRST(parent) = self_idx; else NEXT(self->prev) = self_idx; break; } curr_pg = next_pg; } /* if there are no "in order" bookmarks yet, ** we simply append this one to the end. */ if (idx == 0) { self->prev = LAST(parent); NEXT(LAST(parent)) = self_idx; LAST(parent) = self_idx; } } self->in_order = pdc_true; break; } case -1: /* append to the end */ { self->prev = LAST(parent); NEXT(LAST(parent)) = self_idx; LAST(parent) = self_idx; self->in_order = (pageno >= search_backward(p, pageno, self->prev)); break; } case 0: /* insert at the beginning */ { self->next = FIRST(parent); PREV(FIRST(parent)) = self_idx; FIRST(parent) = self_idx; self->in_order = (pageno <= search_forward(p, pageno, self->next)); break; } default: /* insert before [1..LAST] */ { int i; int target = FIRST(parent); for (i = 0; i < jndex; ++i) { if (target == LAST(parent)) pdc_error(p->pdc, PDC_E_OPT_ILLINTEGER, "index", pdc_errprintf(p->pdc, "%d", jndex), 0, 0); target = NEXT(target); } self->next = target; self->prev = PREV(target); NEXT(self->prev) = PREV(self->next) = self_idx; self->in_order = ((pageno >= search_backward(p, pageno, self->prev)) && (pageno <= search_forward(p, pageno, self->next))); break; } } /* else switch */ /* increase the number of open sub-entries for all relevant ancestors */ do { COUNT(parent)++; } while (OPEN(parent) && (parent = PARENT(parent)) != 0); return (self_idx); /* caller may use this as handle */ }
void pdf__begin_glyph( PDF *p, const char *glyphname, pdc_scalar wx, pdc_scalar llx, pdc_scalar lly, pdc_scalar urx, pdc_scalar ury) { static const char fn[] = "pdf__begin_glyph"; pdf_font *font; pdf_t3font *t3font; pdf_t3glyph *glyph = NULL; pdc_scalar tbc; int ig; if (glyphname == NULL || *glyphname == '\0') pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "glyphname", 0, 0, 0); font = &p->fonts[p->t3slot]; t3font = font->t3font; /* error message prefix */ pdc_push_errmsg(p->pdc, PDF_E_T3_FONT_PREFIX, font->apiname, 0, 0, 0); for (ig = 0; ig < t3font->next_glyph; ig++) { glyph = &t3font->glyphs[ig]; if (!pdc_strcmp(glyph->name, glyphname)) { if (t3font->pass == glyph->pass) pdc_error(p->pdc, PDF_E_T3_GLYPH, glyphname, 0, 0, 0); else break; } } /* new glyph */ if (ig == t3font->next_glyph) { if (t3font->pass == 2) pdc_error(p->pdc, PDF_E_T3_UNKOWNGLYPH, glyphname, 0, 0, 0); pdc_check_number(p->pdc, "wx", wx); pdc_check_number(p->pdc, "llx", llx); pdc_check_number(p->pdc, "lly", lly); pdc_check_number(p->pdc, "urx", urx); pdc_check_number(p->pdc, "ury", ury); if (t3font->colorized == pdc_true && (llx != 0 || lly != 0 || urx != 0 || ury != 0)) pdc_error(p->pdc, PDF_E_T3_BADBBOX, 0, 0, 0, 0); if (urx < llx) { tbc = llx; llx = urx; urx = tbc; } if (ury < lly) { tbc = lly; lly = ury; ury = tbc; } if (ig == t3font->capacity) { t3font->capacity *= 2; t3font->glyphs = (pdf_t3glyph *) pdc_realloc(p->pdc, t3font->glyphs, t3font->capacity * sizeof (pdf_t3glyph), fn); } glyph = &t3font->glyphs[ig]; glyph->charproc_id = PDC_BAD_ID; glyph->name = pdc_strdup(p->pdc, glyphname); glyph->wx = wx; glyph->llx = llx; glyph->lly = lly; glyph->urx = urx; glyph->ury = ury; /* see comment in p_font.c for explanation */ glyph->width = 1000 * wx * font->ft.matrix.a; /* if the strdup above fails, cleanup won't touch this slot. */ t3font->next_glyph++; } glyph->pass = t3font->pass; t3font->curr_glyph = ig; pdc_logg_cond(p->pdc, 1, trc_font, "\tBegin of Type3 font glyph \"%s\"\n", glyphname); if (t3font->pass != 1) { if (t3font->pass == 2) pdc_logg_cond(p->pdc, 2, trc_font, "\t\tglyph [%d] was used in text\n", ig); glyph->charproc_id = pdc_begin_obj(p->out, PDC_NEW_ID); pdc_begin_dict(p->out); p->length_id = pdc_alloc_id(p->out); pdc_objref(p->out, "/Length", p->length_id); if (pdc_get_compresslevel(p->out)) pdc_puts(p->out, "/Filter/FlateDecode\n"); pdc_end_dict(p->out); pdc_begin_pdfstream(p->out); if (t3font->colorized == pdc_true) pdc_printf(p->out, "%f 0 d0\n", glyph->wx); else { pdc_printf(p->out, "%f 0 %f %f %f %f d1\n", glyph->wx, glyph->llx, glyph->lly, glyph->urx, glyph->ury); /* adjust the font's bounding box */ if (glyph->llx < font->ft.bbox.llx) font->ft.bbox.llx = glyph->llx; if (glyph->lly < font->ft.bbox.lly) font->ft.bbox.lly = glyph->lly; if (glyph->urx > font->ft.bbox.urx) font->ft.bbox.urx = glyph->urx; if (glyph->ury > font->ft.bbox.ury) font->ft.bbox.ury = glyph->ury; } /* we must initialize the text, graphics and color state * otherwise the user get unpredictable appearance of a * glyph because of optimizing outputting graphics properties. * Following statements were inserted due to bug #719 */ pdf_init_tstate(p); pdf_init_gstate(p); pdf_init_cstate(p); PDF_SET_STATE(p, pdf_state_glyph); } else { PDF_SET_STATE(p, pdf_state_glyphmetrics); } pdc_pop_errmsg(p->pdc); if (!p->pdc->smokerun) pdc_logg_cond(p->pdc, 1, trc_api, "[Begin glyph %d]\n", ig); }
static pdc_bool pdf_parse_afm( PDF *p, pdc_file *fp, pdf_font *font, const char *fontname, const char *filename) { static const char fn[] = "pdf_parse_afm"; fnt_font_metric *ftm = &font->ft.m; const char *afmtype = NULL; char **wordlist = NULL, *keyword, *arg1; char line[AFM_LINEBUF]; int i, cmp, lo, hi, nwords, nglyphs = 0, nline = 0; int tablen = ((sizeof keyStrings) / (sizeof (char *))); pdc_sint32 iz; double dz; pdc_scalar charwidth = -1; pdf_afmkey keynumber; fnt_glyphwidth *glw; pdc_bool toskip = pdc_false; pdc_bool is_zadbfont = !strcmp(fontname, "ZapfDingbats"); /* all new glyph names of AGL 2.0 are missing */ font->missingglyphs = 0xFFFFFFFF; /* read loop. because of Mac files we use pdc_fgetline */ while (pdc_fgetline(line, AFM_LINEBUF, fp) != NULL) { /* split line */ nline++; nwords = pdc_split_stringlist(p->pdc, line, AFM_SEPARATORS, 0, &wordlist); if (!nwords) continue; keyword = wordlist[0]; /* find keynumber */ lo = 0; hi = tablen; keynumber = NOPE; while (lo < hi) { i = (lo + hi) / 2; cmp = strcmp(keyword, keyStrings[i]); if (cmp == 0) { keynumber = (pdf_afmkey) i; break; } if (cmp < 0) hi = i; else lo = i + 1; } /* unkown key */ if (keynumber == NOPE) { pdc_warning(p->pdc, PDF_E_T1_AFMBADKEY, keyword, filename, 0,0); goto PDF_PARSECONTD; } if (keynumber == ENDDIRECTION) toskip = pdc_false; if (nwords == 1 || toskip == pdc_true) goto PDF_PARSECONTD; /* key switch */ arg1 = wordlist[1]; switch (keynumber) { case STARTDIRECTION: if (pdc_str2integer(arg1, 0, &iz) != pdc_true) goto PDF_SYNTAXERROR; if (iz) toskip = pdc_true; break; case STARTCOMPFONTMETRICS: afmtype = "ACFM"; goto PDF_SYNTAXERROR; case STARTMASTERFONTMETRICS: afmtype = "AMFM"; goto PDF_SYNTAXERROR; case ISCIDFONT: afmtype = "CID font"; if (!strcmp(arg1, "true")) goto PDF_SYNTAXERROR; break; case FONTNAME: font->ft.name = pdc_strdup(p->pdc, arg1); ftm->name = pdc_strdup(p->pdc, arg1); pdc_logg_cond(p->pdc, 1, trc_font, "\tPostScript font name: \"%s\"\n", ftm->name); break; /* Recognize Multiple Master fonts by last part of name */ case FAMILYNAME: if (!strcmp(wordlist[nwords-1], "MM")) ftm->type = fnt_MMType1; else ftm->type = fnt_Type1; break; /* Default: FontSpecific */ case ENCODINGSCHEME: if (!pdc_stricmp(arg1, "StandardEncoding") || !pdc_stricmp(arg1, "AdobeStandardEncoding")) font->ft.issymbfont = pdc_false; break; case STDHW: if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; ftm->StdHW = (int) dz; break; case STDVW: if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; ftm->StdVW = (int) dz; break; case WEIGHT: font->ft.weight = fnt_check_weight(fnt_weightname2weight(arg1)); break; case ISFIXEDPITCH: if (!pdc_stricmp(arg1, "false")) ftm->isFixedPitch = pdc_false; else ftm->isFixedPitch = pdc_true; break; /* New AFM 4.1 keyword "CharWidth" implies fixed pitch */ case CHARWIDTH: if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; charwidth = dz; ftm->isFixedPitch = pdc_true; break; case ITALICANGLE: { if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; ftm->italicAngle = dz; } break; case UNDERLINEPOSITION: if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; ftm->underlinePosition = (int) dz; break; case UNDERLINETHICKNESS: if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; ftm->underlineThickness = (int) dz; break; case FONTBBOX: { if (nwords != 5) goto PDF_SYNTAXERROR; for (i = 1; i < nwords; i++) { if (pdc_str2double(wordlist[i], &dz) != pdc_true) goto PDF_SYNTAXERROR; if (i == 1) ftm->llx = dz; else if (i == 2) ftm->lly = dz; else if (i == 3) ftm->urx = dz; else if (i == 4) ftm->ury = dz; } } break; case CAPHEIGHT: if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; ftm->capHeight = (int) dz; break; case XHEIGHT: if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; ftm->xHeight = (int) dz; break; case DESCENDER: if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; ftm->descender = (int) dz; break; case ASCENDER: if (pdc_str2double(arg1, &dz) != pdc_true) goto PDF_SYNTAXERROR; ftm->ascender = (int) dz; break; /* Character widths */ case STARTCHARMETRICS: if (pdc_str2integer(arg1, PDC_INT_UNSIGNED, (pdc_sint32 *) &nglyphs) != pdc_true || nglyphs <= 0) goto PDF_SYNTAXERROR; ftm->glw = (fnt_glyphwidth *) pdc_calloc(p->pdc, (size_t) nglyphs * sizeof(fnt_glyphwidth), fn); break; /* Character code */ case CODE: case CODEHEX: if (!nglyphs || !ftm->glw) goto PDF_SYNTAXERROR; if (font->ft.numglyphs >= nglyphs) { nglyphs++; ftm->glw = (fnt_glyphwidth *) pdc_realloc(p->pdc, ftm->glw, (size_t) nglyphs * sizeof(fnt_glyphwidth), fn); } glw = &ftm->glw[font->ft.numglyphs]; if (keynumber == CODE) { if (pdc_str2integer(arg1, 0, &iz) != pdc_true) goto PDF_SYNTAXERROR; } else { if (pdc_str2integer(arg1, PDC_INT_HEXADEC, &iz) != pdc_true) goto PDF_SYNTAXERROR; } glw->code = (pdc_short) iz; glw->unicode = 0; glw->width = (pdc_ushort) (font->opt.monospace ? font->opt.monospace : charwidth); font->ft.numglyphs++; /* Character width and name */ for (i = 2; i < nwords; i++) { if (!strcmp(wordlist[i], "WX") || !strcmp(wordlist[i], "W0X") || !strcmp(wordlist[i], "W")) { i++; if (i == nwords) goto PDF_SYNTAXERROR; if (pdc_str2double(wordlist[i], &dz) != pdc_true) goto PDF_SYNTAXERROR; glw->width = (pdc_ushort) (font->opt.monospace ? font->opt.monospace : dz); } if (!strcmp(wordlist[i], "N")) { i++; if (i == nwords) goto PDF_SYNTAXERROR; /* Unicode value by means of AGL, * internal and private table */ glw->unicode = is_zadbfont ? (pdc_ushort) pdc_zadb2unicode(wordlist[i]): pdc_insert_glyphname(p->pdc, wordlist[i]); pdc_delete_missingglyph_bit(glw->unicode, &font->missingglyphs); } } break; default: break; } PDF_PARSECONTD: pdc_cleanup_stringlist(p->pdc, wordlist); wordlist = NULL; if (keynumber == ENDFONTMETRICS) break; } /* necessary font struct members */ if (font->ft.name == NULL || ftm->glw == NULL) goto PDF_SYNTAXERROR; pdc_fclose(fp); ftm->numglwidths = font->ft.numglyphs; return pdc_true; PDF_SYNTAXERROR: pdc_fclose(fp); pdc_cleanup_stringlist(p->pdc, wordlist); if (afmtype) pdc_set_errmsg(p->pdc, PDF_E_T1_UNSUPP_FORMAT, afmtype, 0, 0, 0); else pdc_set_errmsg(p->pdc, PDC_E_IO_ILLSYNTAX, "AFM ", filename, pdc_errprintf(p->pdc, "%d", nline), 0); return pdc_false; }
int pdc_read_textfile(pdc_core *pdc, pdc_file *sfp, int flags, char ***linelist) { static const char fn[] = "pdc_read_textfile"; char buf[PDC_BUFSIZE]; char *content = NULL; char **strlist = NULL; int nlines = 0; pdc_off_t filelen; size_t len = 0, sumlen = 0, maxl = 0; pdc_bool tocont = pdc_false; int i, nbs, is = -1; /* get file length */ filelen = pdc_file_size(sfp); if (filelen) { /* allocate content array */ content = (char *) pdc_calloc(pdc, (size_t) filelen, fn); /* read loop */ while (pdc_fgetline(buf, PDC_BUFSIZE, sfp) != NULL) { /* trim white spaces */ if (tocont) pdc_strtrim(buf); else pdc_str2trim(buf); /* skip blank and comment lines */ if (buf[0] == 0 || buf[0] == '%') { tocont = pdc_false; continue; } /* register new line */ if (!tocont) { if (nlines) pdc_logg_cond(pdc, 2, trc_filesearch, "\t\tLine %d; \"%s\"\n", nlines, strlist[nlines - 1]); if (nlines >= (int) maxl) { maxl += PDC_ARGV_CHUNKSIZE; strlist = (strlist == NULL) ? (char **)pdc_malloc(pdc, maxl * sizeof(char *), fn): (char **)pdc_realloc(pdc, strlist, maxl * sizeof(char *), fn); } is += sumlen + 1; strlist[nlines] = &content[is]; nlines++; sumlen = 0; } /* process new line */ nbs = 0; len = strlen(buf); for (i = 0; i < (int) len; i++) { /* backslash found */ if (buf[i] == '\\') { nbs++; } else { /* comment sign found */ if (buf[i] == '%') { if (nbs % 2) { /* masked */ memmove(&buf[i-1], &buf[i], (size_t) (len-i)); len--; buf[len] = 0; } else { buf[i] = 0; len = strlen(buf); } } nbs = 0; } } /* continuation line */ tocont = (nbs % 2) ? pdc_true : pdc_false; if (tocont) { if (flags & PDC_FILE_KEEPLF) buf[len - 1] = '\n'; else len--; } buf[len] = '\0'; /* backslash substitution */ if (flags & PDC_FILE_BSSUBST) { len = (size_t) pdc_subst_backslash(pdc, (pdc_byte *) buf, (int) len, NULL, pdc_bytes, pdc_true); } /* concatenate line */ strcat(&content[is], buf); sumlen += len; } if (!strlist) pdc_free(pdc, content); } if (nlines) pdc_logg_cond(pdc, 2, trc_filesearch, "\t\tLine %d; \"%s\"\n", nlines, strlist[nlines - 1]); *linelist = strlist; return nlines; }
void pdf__begin_glyph( PDF *p, const char *glyphname, float wx, float llx, float lly, float urx, float ury) { static const char fn[] = "pdf__begin_glyph"; pdc_t3font *t3font; pdc_t3glyph *glyph; int i; t3font = p->t3font; if (t3font->colorized == pdc_true && (llx != (float) 0 || lly != (float) 0 || urx != (float) 0 || ury != (float) 0)) pdc_error(p->pdc, PDF_E_T3_BADBBOX, t3font->fontname, 0, 0, 0); PDF_SET_STATE(p, pdf_state_glyph); for (i = 0; i < t3font->next_glyph; ++i) { if (!strcmp(t3font->glyphs[i].name, glyphname)) { pdc_error(p->pdc, PDF_E_T3_GLYPH, glyphname, t3font->fontname, 0, 0); } } if (t3font->next_glyph == t3font->capacity) { t3font->capacity *= 2; t3font->glyphs = (pdc_t3glyph *) pdc_realloc(p->pdc, t3font->glyphs, t3font->capacity * sizeof (pdc_t3glyph), fn); } glyph = &t3font->glyphs[t3font->next_glyph]; glyph->charproc_id = pdc_begin_obj(p->out, PDC_NEW_ID); glyph->name = pdc_strdup(p->pdc, glyphname); /* see comment in p_font.c for explanation */ glyph->width = 1000 * wx * t3font->matrix.a; /* if the strdup above fails, cleanup won't touch this slot. */ ++t3font->next_glyph; p->contents = c_page; /* glyph description */ pdc_begin_dict(p->out); /* glyph description dict */ p->length_id = pdc_alloc_id(p->out); pdc_printf(p->out, "/Length %ld 0 R\n", p->length_id); if (pdc_get_compresslevel(p->out)) pdc_puts(p->out, "/Filter/FlateDecode\n"); pdc_end_dict(p->out); /* glyph description dict */ pdc_begin_pdfstream(p->out); /* glyph description stream */ p->next_content++; if (t3font->colorized == pdc_true) pdc_printf(p->out, "%f 0 d0\n", wx); else { pdc_printf(p->out, "%f 0 %f %f %f %f d1\n", wx, llx, lly, urx, ury); /* adjust the font's bounding box */ if (llx < t3font->bbox.llx) t3font->bbox.llx = llx; if (lly < t3font->bbox.lly) t3font->bbox.lly = lly; if (urx > t3font->bbox.urx) t3font->bbox.urx = urx; if (ury > t3font->bbox.ury) t3font->bbox.ury = ury; } }