static void fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate) { fz_drawdevice *dev = user; fz_colorspace *model = dev->dest->colorspace; fz_bbox bbox; fz_pixmap *mask, *dest; fz_matrix tm, trm; fz_pixmap *glyph; int i, x, y, gid; /* If accumulate == 0 then this text object is guaranteed complete */ /* If accumulate == 1 then this text object is the first (or only) in a sequence */ /* If accumulate == 2 then this text object is a continuation */ if (dev->top == STACKSIZE) { fz_warn("assert: too many buffers on stack"); return; } if (accumulate == 0) { /* make the mask the exact size needed */ bbox = fz_roundrect(fz_boundtext(text, ctm)); bbox = fz_intersectbbox(bbox, dev->scissor); } else { /* be conservative about the size of the mask needed */ bbox = dev->scissor; } if (accumulate == 0 || accumulate == 1) { mask = fz_newpixmapwithrect(nil, bbox); dest = fz_newpixmapwithrect(model, bbox); fz_clearpixmap(mask, 0); fz_clearpixmap(dest, 0); dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = mask; dev->stack[dev->top].dest = dev->dest; dev->scissor = bbox; dev->dest = dest; dev->top++; } else { mask = dev->stack[dev->top-1].mask; } if (!fz_isemptyrect(bbox)) { tm = text->trm; for (i = 0; i < text->len; i++) { gid = text->els[i].gid; if (gid < 0) continue; tm.e = text->els[i].x; tm.f = text->els[i].y; trm = fz_concat(tm, ctm); x = floorf(trm.e); y = floorf(trm.f); trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); glyph = fz_renderglyph(dev->cache, text->font, gid, trm); if (glyph) { drawglyph(nil, mask, glyph, x, y, bbox); fz_droppixmap(glyph); } } } }
fz_error fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *destcs, fz_pixmap *dest) { unsigned char clut[256][3]; unsigned char *s, *d; fz_error error; fz_pixmap *temp; float rgb[3]; float tri[3][MAXN]; fz_point p; int i, j, k, n; assert(dest->n == 4); ctm = fz_concat(shade->matrix, ctm); if (shade->usefunction) { n = 3; error = fz_newpixmap(&temp, dest->x, dest->y, dest->w, dest->h, 2); if (error) return error; } else if (shade->cs != destcs) { n = 2 + shade->cs->n; error = fz_newpixmap(&temp, dest->x, dest->y, dest->w, dest->h, shade->cs->n + 1); if (error) return error; } else { n = 2 + shade->cs->n; temp = dest; } fz_clearpixmap(temp); for (i = 0; i < shade->meshlen; i++) { for (k = 0; k < 3; k++) { p.x = shade->mesh[(i * 3 + k) * n + 0]; p.y = shade->mesh[(i * 3 + k) * n + 1]; p = fz_transformpoint(ctm, p); if (isnan(p.y) || isnan(p.x)) // How is this happening? goto baddata; tri[k][0] = p.x; tri[k][1] = p.y; for (j = 2; j < n; j++) tri[k][j] = shade->mesh[( i * 3 + k) * n + j] * 255; } fz_drawtriangle(temp, tri[0], tri[1], tri[2], n); baddata: ; } if (shade->usefunction) { for (i = 0; i < 256; i++) { fz_convertcolor(shade->cs, shade->function[i], destcs, rgb); clut[i][0] = rgb[0] * 255; clut[i][1] = rgb[1] * 255; clut[i][2] = rgb[2] * 255; } n = temp->w * temp->h; s = temp->samples; d = dest->samples; while (n--) { d[0] = s[0]; d[1] = fz_mul255(s[0], clut[s[1]][0]); d[2] = fz_mul255(s[0], clut[s[1]][1]); d[3] = fz_mul255(s[0], clut[s[1]][2]); s += 2; d += 4; } fz_droppixmap(temp); } else if (shade->cs != destcs) { fz_convertpixmap(shade->cs, temp, destcs, dest); fz_droppixmap(temp); } return fz_okay; }
static fz_error * renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm) { fz_error *error; float flatness; fz_irect gbox; fz_irect clip; float expansion = fz_matrixexpansion(ctm); flatness = 0.3 / expansion; if (flatness < 0.1) flatness = 0.1; fz_resetgel(gc->gel, gc->clip); if (path->paint == FZ_STROKE) { float lw = path->linewidth; /* Check for hairline */ if (lw * expansion < 0.1) { lw = 1.0f / expansion; } if (path->dash) error = fz_dashpath(gc->gel, path, ctm, flatness, lw); else error = fz_strokepath(gc->gel, path, ctm, flatness, lw); } else error = fz_fillpath(gc->gel, path, ctm, flatness); if (error) return error; fz_sortgel(gc->gel); gbox = fz_boundgel(gc->gel); clip = fz_intersectirects(gc->clip, gbox); if (fz_isemptyrect(clip)) return fz_okay; DEBUG("path %s;\n", path->paint == FZ_STROKE ? "stroke" : "fill"); if (gc->flag & FRGB) { DEBUG(" path rgb %d %d %d %d, %d %d %d\n", gc->argb[0], gc->argb[1], gc->argb[2], gc->argb[3], gc->argb[4], gc->argb[5], gc->argb[6]); return fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, clip, gc->over, gc->argb, 1); } else if (gc->flag & FOVER) { return fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, clip, gc->over, nil, 1); } else { error = fz_newpixmapwithrect(&gc->dest, clip, 1); if (error) return error; fz_clearpixmap(gc->dest); return fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, clip, gc->dest, nil, 0); } }
static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage) { char buf[256]; fz_error error; fz_device *idev, *tdev, *mdev; fz_displaylist *list; fz_matrix ctm; fz_bbox bbox; fz_obj *obj; if (loadpage) { wincursor(app, WAIT); if (app->page) pdf_droppage(app->page); app->page = nil; //code change by kakai kno_clearselect(app); //code change by kakai pdf_flushxref(app->xref, 0); obj = pdf_getpageobject(app->xref, app->pageno); error = pdf_loadpage(&app->page, app->xref, obj); if (error) pdfapp_error(app, error); sprintf(buf, "%s - %d/%d", app->doctitle, app->pageno, app->pagecount); wintitle(app, buf); } if (drawpage) { wincursor(app, WAIT); ctm = pdfapp_viewctm(app); bbox = fz_roundrect(fz_transformrect(ctm, app->page->mediabox)); list = fz_newdisplaylist(); mdev = fz_newlistdevice(list); error = pdf_runcontentstream(mdev, fz_identity(), app->xref, app->page->resources, app->page->contents); if (error) pdfapp_error(app, error); fz_freedevice(mdev); if (app->image) fz_droppixmap(app->image); app->image = fz_newpixmapwithrect(pdf_devicergb, bbox); fz_clearpixmap(app->image, 0xFF); idev = fz_newdrawdevice(app->cache, app->image); fz_executedisplaylist(list, idev, ctm); fz_freedevice(idev); if (app->text) fz_freetextspan(app->text); app->text = fz_newtextspan(); tdev = fz_newtextdevice(app->text); fz_executedisplaylist(list, tdev, ctm); fz_freedevice(tdev); fz_freedisplaylist(list); //code change by kakai kno_allocselection(app); kno_applyselect(app); //code change by kakai winconvert(app, app->image); } pdfapp_panview(app, app->panx, app->pany); if (app->shrinkwrap) { int w = app->image->w; int h = app->image->h; if (app->winw == w) app->panx = 0; if (app->winh == h) app->pany = 0; if (w > app->scrw * 90 / 100) w = app->scrw * 90 / 100; if (h > app->scrh * 90 / 100) h = app->scrh * 90 / 100; if (w != app->winw || h != app->winh) winresize(app, w, h); } winrepaint(app); wincursor(app, ARROW); }