void pdf_setcolor(pdf_csi *csi, int what, float *v) { pdf_gstate *gs = csi->gstate + csi->gtop; pdf_material *mat; int i; pdf_flushtext(csi); mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; switch (mat->kind) { case PDF_MPATTERN: case PDF_MCOLOR: if (!strcmp(mat->colorspace->name, "Lab")) { mat->v[0] = v[0] / 100; mat->v[1] = (v[1] + 100) / 200; mat->v[2] = (v[2] + 100) / 200; } for (i = 0; i < mat->colorspace->n; i++) mat->v[i] = v[i]; break; default: fz_warn("color incompatible with material"); } }
fz_error * pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs) { pdf_gstate *gs = csi->gstate + csi->gtop; fz_error *error; pdf_material *mat; error = pdf_flushtext(csi); if (error) return fz_rethrow(error, "cannot finish text node (state change)"); mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; fz_dropcolorspace(mat->cs); mat->kind = PDF_MCOLOR; mat->cs = fz_keepcolorspace(cs); mat->v[0] = 0; /* FIXME: default color */ mat->v[1] = 0; /* FIXME: default color */ mat->v[2] = 0; /* FIXME: default color */ mat->v[3] = 1; /* FIXME: default color */ if (!strcmp(cs->name, "Indexed")) { mat->kind = PDF_MINDEXED; mat->indexed = (pdf_indexed*)cs; mat->cs = mat->indexed->base; } if (!strcmp(cs->name, "Lab")) mat->kind = PDF_MLAB; return fz_okay; }
fz_error * pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v) { pdf_gstate *gs = csi->gstate + csi->gtop; fz_error *error; pdf_material *mat; error = pdf_flushtext(csi); if (error) return fz_rethrow(error, "cannot finish text node (state change)"); mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; if (mat->pattern) pdf_droppattern(mat->pattern); mat->kind = PDF_MPATTERN; if (pat) mat->pattern = pdf_keeppattern(pat); else mat->pattern = nil; if (v) { error = pdf_setcolor(csi, what, v); if (error) return fz_rethrow(error, "cannot set color"); } return fz_okay; }
fz_error * pdf_setcolor(pdf_csi *csi, int what, float *v) { pdf_gstate *gs = csi->gstate + csi->gtop; fz_error *error; pdf_indexed *ind; pdf_material *mat; int i, k; error = pdf_flushtext(csi); if (error) return fz_rethrow(error, "cannot finish text node (state change)"); mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; switch (mat->kind) { case PDF_MPATTERN: if (!strcmp(mat->cs->name, "Lab")) goto Llab; if (!strcmp(mat->cs->name, "Indexed")) goto Lindexed; /* fall through */ case PDF_MCOLOR: for (i = 0; i < mat->cs->n; i++) mat->v[i] = v[i]; break; case PDF_MLAB: Llab: mat->v[0] = v[0] / 100.0; mat->v[1] = (v[1] + 100) / 200.0; mat->v[2] = (v[2] + 100) / 200.0; break; case PDF_MINDEXED: Lindexed: ind = mat->indexed; i = CLAMP(v[0], 0, ind->high); for (k = 0; k < ind->base->n; k++) mat->v[k] = ind->lookup[ind->base->n * i + k] / 255.0; break; default: return fz_throw("color incompatible with material"); } return fz_okay; }
void pdf_setshade(pdf_csi *csi, int what, fz_shade *shade) { pdf_gstate *gs = csi->gstate + csi->gtop; pdf_material *mat; pdf_flushtext(csi); mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; if (mat->shade) fz_dropshade(mat->shade); mat->kind = PDF_MSHADE; mat->shade = fz_keepshade(shade); }
void pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *colorspace) { pdf_gstate *gs = csi->gstate + csi->gtop; pdf_material *mat; pdf_flushtext(csi); mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; fz_dropcolorspace(mat->colorspace); mat->kind = PDF_MCOLOR; mat->colorspace = fz_keepcolorspace(colorspace); mat->v[0] = 0; mat->v[1] = 0; mat->v[2] = 0; mat->v[3] = 1; }
fz_error * pdf_setshade(pdf_csi *csi, int what, fz_shade *shade) { pdf_gstate *gs = csi->gstate + csi->gtop; fz_error *error; pdf_material *mat; error = pdf_flushtext(csi); if (error) return fz_rethrow(error, "cannot finish text node (state change)"); mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; if (mat->shade) fz_dropshade(mat->shade); mat->kind = PDF_MSHADE; mat->shade = fz_keepshade(shade); return fz_okay; }
void pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v) { pdf_gstate *gs = csi->gstate + csi->gtop; pdf_material *mat; pdf_flushtext(csi); mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; if (mat->pattern) pdf_droppattern(mat->pattern); mat->kind = PDF_MPATTERN; if (pat) mat->pattern = pdf_keeppattern(pat); else mat->pattern = nil; if (v) pdf_setcolor(csi, what, v); }
static void pdf_showglyph(pdf_csi *csi, int cid) { pdf_gstate *gstate = csi->gstate + csi->gtop; pdf_fontdesc *fontdesc = gstate->font; fz_matrix tsm, trm; float w0, w1, tx, ty; pdf_hmtx h; pdf_vmtx v; int gid; int ucsbuf[8]; int ucslen; int i; tsm.a = gstate->size * gstate->scale; tsm.b = 0; tsm.c = 0; tsm.d = gstate->size; tsm.e = 0; tsm.f = gstate->rise; ucslen = 0; if (fontdesc->tounicode) ucslen = pdf_lookupcmapfull(fontdesc->tounicode, cid, ucsbuf); if (ucslen == 0 && cid < fontdesc->ncidtoucs) { ucsbuf[0] = fontdesc->cidtoucs[cid]; ucslen = 1; } if (ucslen == 0 || (ucslen == 1 && ucsbuf[0] == 0)) { ucsbuf[0] = '?'; ucslen = 1; } gid = pdf_fontcidtogid(fontdesc, cid); if (fontdesc->wmode == 1) { v = pdf_getvmtx(fontdesc, cid); tsm.e -= v.x * gstate->size * 0.001f; tsm.f -= v.y * gstate->size * 0.001f; } trm = fz_concat(tsm, csi->tm); /* flush buffered text if face or matrix or rendermode has changed */ if (!csi->text || fontdesc->font != csi->text->font || fontdesc->wmode != csi->text->wmode || fabsf(trm.a - csi->text->trm.a) > FLT_EPSILON || fabsf(trm.b - csi->text->trm.b) > FLT_EPSILON || fabsf(trm.c - csi->text->trm.c) > FLT_EPSILON || fabsf(trm.d - csi->text->trm.d) > FLT_EPSILON || gstate->render != csi->textmode) { pdf_flushtext(csi); csi->text = fz_newtext(fontdesc->font, trm, fontdesc->wmode); csi->text->trm.e = 0; csi->text->trm.f = 0; csi->textmode = gstate->render; } /* add glyph to textobject */ fz_addtext(csi->text, gid, ucsbuf[0], trm.e, trm.f); /* add filler glyphs for one-to-many unicode mapping */ for (i = 1; i < ucslen; i++) fz_addtext(csi->text, -1, ucsbuf[i], trm.e, trm.f); if (fontdesc->wmode == 0) { h = pdf_gethmtx(fontdesc, cid); w0 = h.w * 0.001f; tx = (w0 * gstate->size + gstate->charspace) * gstate->scale; csi->tm = fz_concat(fz_translate(tx, 0), csi->tm); } if (fontdesc->wmode == 1) { w1 = v.w * 0.001f; ty = w1 * gstate->size + gstate->charspace; csi->tm = fz_concat(fz_translate(0, ty), csi->tm); } }
fz_error * showglyph(pdf_csi *csi, int cid) { pdf_gstate *gstate = csi->gstate + csi->gtop; pdf_font *font = gstate->font; fz_error *error; fz_matrix tsm, trm; float w0, w1, tx, ty; fz_hmtx h; fz_vmtx v; tsm.a = gstate->size * gstate->scale; tsm.b = 0; tsm.c = 0; tsm.d = gstate->size; tsm.e = 0; tsm.f = gstate->rise; if (font->super.wmode == 1) { v = fz_getvmtx((fz_font*)font, cid); tsm.e -= v.x * gstate->size / 1000.0; tsm.f -= v.y * gstate->size / 1000.0; } trm = fz_concat(tsm, csi->tm); /* flush buffered text if face or matrix or rendermode has changed */ if (!csi->text || ((fz_font*)font) != csi->text->font || fabs(trm.a - csi->text->trm.a) > FLT_EPSILON || fabs(trm.b - csi->text->trm.b) > FLT_EPSILON || fabs(trm.c - csi->text->trm.c) > FLT_EPSILON || fabs(trm.d - csi->text->trm.d) > FLT_EPSILON || gstate->render != csi->textmode) { error = pdf_flushtext(csi); if (error) return fz_rethrow(error, "cannot finish text node (face/matrix change)"); error = fz_newtextnode(&csi->text, (fz_font*)font); if (error) return fz_rethrow(error, "cannot create text node"); csi->text->trm = trm; csi->text->trm.e = 0; csi->text->trm.f = 0; csi->textmode = gstate->render; } /* add glyph to textobject */ error = fz_addtext(csi->text, cid, trm.e, trm.f); if (error) return fz_rethrow(error, "cannot add glyph to text node"); if (font->super.wmode == 0) { h = fz_gethmtx((fz_font*)font, cid); w0 = h.w / 1000.0; tx = (w0 * gstate->size + gstate->charspace) * gstate->scale; csi->tm = fz_concat(fz_translate(tx, 0), csi->tm); } else { w1 = v.w / 1000.0; ty = w1 * gstate->size + gstate->charspace; csi->tm = fz_concat(fz_translate(0, ty), csi->tm); } return fz_okay; }