void vgaputi(int16_t x, int16_t y, uint8_t * p, int16_t w, int16_t h) { VGLBitmap *tmp; struct PendNode tmpn; struct PendNode *newn; static int pending_match = 0; tmpn.realx = virt2scrx(x); tmpn.realy = virt2scry(y); tmpn.realw = virt2scrw(w * 4); tmpn.realh = virt2scrh(h); newn = find_pending(&tmpn); if (newn == NULL) { newn = malloc(sizeof (struct PendNode)); memset(newn, 0x00, (sizeof (struct PendNode))); newn->realx = tmpn.realx; newn->realy = tmpn.realy; newn->realw = tmpn.realw; newn->realh = tmpn.realh; pendappend(newn); } else { rect_merge(newn, &tmpn); pending_match += 1; if (pending_match < 10 || pending_match % 50 == 0) { fprintf(stderr, "vgaputi: pending_match = %d\n", pending_match); } } memcpy(&tmp, p, (sizeof(VGLBitmap *))); VGLBitmapCopy(tmp, 0, 0, sVGLDisplay, tmpn.realx, tmpn.realy, tmpn.realw, tmpn.realh); }
/* * Check the path against FontBBox before drawing. The original operands * of type1execchar are still on the o-stack. * Returns exec_cont - a function, which must be called by caller after this function. */ static int bbox_draw(i_ctx_t *i_ctx_p, int (*draw)(gs_state *), op_proc_t *exec_cont) { os_ptr op = osp; gs_rect bbox; gs_font *pfont; gs_text_enum_t *penum; gs_font_base * pbfont; gs_font_type1 * pfont1; gs_type1exec_state cxs; int code; if (igs->in_cachedevice < 2) /* not caching */ return nobbox_draw(i_ctx_p, draw); if ((code = font_param(op - 3, &pfont)) < 0) return code; penum = op_show_find(i_ctx_p); if (penum == 0 || !font_uses_charstrings(pfont)) return_error(e_undefined); if ((code = gs_pathbbox(igs, &bbox)) < 0) { /* * If the matrix is singular, all user coordinates map onto a * straight line. Don't bother rendering the character at all. */ if (code == e_undefinedresult) { pop(4); gs_newpath(igs); return 0; } return code; } if (draw == gs_stroke) { /* Expand the bounding box by the line width. */ float width = gs_currentlinewidth(igs) * 1.41422; bbox.p.x -= width, bbox.p.y -= width; bbox.q.x += width, bbox.q.y += width; } pbfont = (gs_font_base *)pfont; if (rect_within(bbox, pbfont->FontBBox)) /* within bounds */ return nobbox_draw(i_ctx_p, draw); /* Enlarge the FontBBox to save work in the future. */ rect_merge(pbfont->FontBBox, bbox); /* Dismantle everything we've done, and start over. */ gs_text_retry(penum); pfont1 = (gs_font_type1 *) pfont; if ((penum->FontBBox_as_Metrics2.x == 0 && penum->FontBBox_as_Metrics2.y == 0) || gs_rootfont(igs)->WMode == 0 ) { code = zchar_get_metrics(pbfont, op - 1, cxs.sbw); if (code < 0) return code; cxs.present = code; cxs.use_FontBBox_as_Metrics2 = false; } else { cxs.sbw[0] = penum->FontBBox_as_Metrics2.x / 2; cxs.sbw[1] = penum->FontBBox_as_Metrics2.y; cxs.sbw[2] = 0; cxs.sbw[3] = -penum->FontBBox_as_Metrics2.x; /* Sic! */ cxs.use_FontBBox_as_Metrics2 = true; cxs.present = metricsSideBearingAndWidth; } code = type1_exec_init(&cxs.cis, penum, igs, pfont1); if (code < 0) return code; cxs.char_bbox = pfont1->FontBBox; code = type1exec_bbox(i_ctx_p, penum, &cxs, pfont, exec_cont); return code; }