/* Get a FontBBox parameter from a font dictionary. */ int font_bbox_param(const gs_memory_t *mem, const ref * pfdict, double bbox[4]) { ref *pbbox; /* * Pre-clear the bbox in case it's invalid. The Red Books say that * FontBBox is required, but old Adobe interpreters don't require * it, and a few user-written fonts don't supply it, or supply one * of the wrong size (!); also, PageMaker 5.0 (an Adobe product!) * sometimes emits an absurd bbox for Type 1 fonts converted from * TrueType. */ bbox[0] = bbox[1] = bbox[2] = bbox[3] = 0.0; if (dict_find_string(pfdict, "FontBBox", &pbbox) > 0) { if (!r_is_array(pbbox)) return_error(e_typecheck); if (r_size(pbbox) == 4) { const ref_packed *pbe = pbbox->value.packed; ref rbe[4]; int i; int code; float dx, dy, ratio; const float max_ratio = 12; /* From the bug 687594. */ for (i = 0; i < 4; i++) { packed_get(mem, pbe, rbe + i); pbe = packed_next(pbe); } if ((code = num_params(rbe + 3, 4, bbox)) < 0) return code; /* Require "reasonable" values. */ dx = bbox[2] - bbox[0]; dy = bbox[3] - bbox[1]; if (dx <= 0 || dy <= 0 || (ratio = dy / dx) < 1 / max_ratio || ratio > max_ratio ) bbox[0] = bbox[1] = bbox[2] = bbox[3] = 0.0; } } else if (CPSI_mode) { return_error(e_invalidfont); /* CPSI requires FontBBox */ } return 0; }
/* <ax> <ay> <string> ashow - */ static int zashow(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_text_enum_t *penum; double axy[2]; int code = num_params(op - 1, 2, axy); if (code < 0 || (code = op_show_setup(i_ctx_p, op)) != 0 || (code = gs_ashow_begin(igs, axy[0], axy[1], op->value.bytes, r_size(op), imemory, &penum)) < 0) return code; *(op_proc_t *)&penum->enum_client_data = zashow; if ((code = op_show_finish_setup(i_ctx_p, penum, 3, finish_show)) < 0) { ifree_object(penum, "op_show_enum_setup"); return code; } return op_show_continue_pop(i_ctx_p, 3); }
/* <wx> <wy> setcharwidth - */ static int zsetcharwidth(i_ctx_t *i_ctx_p) { os_ptr op = osp; double width[2]; gs_text_enum_t *penum = op_show_find(i_ctx_p); int code = num_params(op, 2, width); if (penum == 0) return_error(e_undefined); if (code < 0) return code; if (zchar_show_width_only(penum)) return op_show_return_width(i_ctx_p, 2, &width[0]); code = gs_text_setcharwidth(penum, width); if (code < 0) return code; pop(2); return 0; }
static int zmatch_page_size(const gs_memory_t *mem, const ref * pvreq, const ref * pvmed, int policy, int orient, bool roll, float *best_mismatch, gs_matrix * pmat, gs_point * pmsize) { uint nr, nm; int code; ref rv[6]; /* array_get checks array types and size. */ /* This allows normal or packed arrays to be used */ if ((code = array_get(mem, pvreq, 1, &rv[1])) < 0) return_error(code); nr = r_size(pvreq); if ((code = array_get(mem, pvmed, 1, &rv[3])) < 0) return_error(code); nm = r_size(pvmed); if (!((nm == 2 || nm == 4) && (nr == 2 || nr == nm))) return_error(e_rangecheck); { uint i; double v[6]; int code; array_get(mem, pvreq, 0, &rv[0]); for (i = 0; i < 4; ++i) array_get(mem,pvmed, i % nm, &rv[i + 2]); if ((code = num_params(rv + 5, 6, v)) < 0) return code; { gs_point request; gs_rect medium; request.x = v[0], request.y = v[1]; medium.p.x = v[2], medium.p.y = v[3], medium.q.x = v[4], medium.q.y = v[5]; return match_page_size(&request, &medium, policy, orient, roll, best_mismatch, pmat, pmsize); } } }
/* <wx> <wy> <llx> <lly> <urx> <ury> setcachedevice - */ int zsetcachedevice(i_ctx_t *i_ctx_p) { os_ptr op = osp; double wbox[6]; gs_text_enum_t *penum = op_show_find(i_ctx_p); int code = num_params(op, 6, wbox); if (penum == 0) return_error(e_undefined); if (code < 0) return code; if (zchar_show_width_only(penum)) return op_show_return_width(i_ctx_p, 6, &wbox[0]); code = gs_text_setcachedevice(penum, wbox); if (code < 0) return code; pop(6); if (code == 1) clear_pagedevice(istate); return 0; }
/* Get the vertical metrics for a character from Metrics2, if present. */ int zchar_get_metrics2(const gs_font_base * pbfont, const ref * pcnref, double pwv[4]) { const ref *pfdict = &pfont_data(gs_font_parent(pbfont))->dict; ref *pmdict; if (dict_find_string(pfdict, "Metrics2", &pmdict) > 0) { ref *pmvalue; check_type_only(*pmdict, t_dictionary); check_dict_read(*pmdict); if (dict_find(pmdict, pcnref, &pmvalue) > 0) { check_read_type_only(*pmvalue, t_array); if (r_size(pmvalue) == 4) { int code = num_params(pmvalue->value.refs + 3, 4, pwv); return (code < 0 ? code : metricsSideBearingAndWidth); } } } return metricsNone; }
/* <w0x> <w0y> <llx> <lly> <urx> <ury> <w1x> <w1y> <vx> <vy> setcachedevice2 - */ int zsetcachedevice2(i_ctx_t *i_ctx_p) { os_ptr op = osp; double wbox[10]; gs_text_enum_t *penum = op_show_find(i_ctx_p); int code = num_params(op, 10, wbox); if (penum == 0) return_error(e_undefined); if (code < 0) return code; if (zchar_show_width_only(penum)) return op_show_return_width(i_ctx_p, 10, (gs_rootfont(igs)->WMode ? &wbox[6] : &wbox[0])); code = gs_text_setcachedevice2(penum, wbox); if (code < 0) return code; pop(10); if (code == 1) clear_pagedevice(istate); return 0; }
/* <bitmap> <cid> <type32font> <str22> .makeglyph32 <<same with substr>> */ static int zmakeglyph32(i_ctx_t *i_ctx_p) { os_ptr op = osp; bool long_form; uint msize; double metrics[10]; int wx, llx, lly, urx, ury; int width, height, raster; gs_font *pfont; int code; byte *str; check_array(op[-4]); msize = r_size(op - 4); switch (msize) { case 10: long_form = true; break; case 6: long_form = false; break; default: return_error(gs_error_rangecheck); } code = num_params(op[-4].value.refs + msize - 1, msize, metrics); if (code < 0) return code; if (~code & 0x3c) /* check llx .. ury for integers */ return_error(gs_error_typecheck); check_read_type(op[-3], t_string); llx = (int)metrics[2]; lly = (int)metrics[3]; urx = (int)metrics[4]; ury = (int)metrics[5]; width = urx - llx; height = ury - lly; raster = (width + 7) >> 3; if (width < 0 || height < 0 || r_size(op - 3) != raster * height) return_error(gs_error_rangecheck); check_int_leu(op[-2], 65535); code = font_param(op - 1, &pfont); if (code < 0) return code; if (pfont->FontType != ft_CID_bitmap) return_error(gs_error_invalidfont); check_write_type(*op, t_string); if (r_size(op) < 22) return_error(gs_error_rangecheck); str = op->value.bytes; if (long_form || metrics[0] != (wx = (int)metrics[0]) || metrics[1] != 0 || height == 0 || ((wx | width | height | (llx + 128) | (lly + 128)) & ~255) != 0 ) { /* Use the long form. */ int i, n = (long_form ? 10 : 6); str[0] = 0; str[1] = long_form; for (i = 0; i < n; ++i) { int v = (int)metrics[i]; /* no floating point widths yet */ str[2 + 2 * i] = (byte)(v >> 8); str[2 + 2 * i + 1] = (byte)v; } r_set_size(op, 2 + n * 2); } else {
/* Return the number of elements to pop (>0) if OK, <0 if error. */ static int rect_get(local_rects_t * plr, os_ptr op, gs_memory_t *mem) { int format, code; uint n, count; gs_rect *pr; double rv[4]; switch (r_type(op)) { case t_array: case t_mixedarray: case t_shortarray: case t_string: code = num_array_format(op); if (code < 0) return code; format = code; count = num_array_size(op, format); if (count % 4) return_error(e_typecheck); count /= 4; break; default: /* better be 4 numbers */ code = num_params(op, 4, rv); if (code < 0) return code; plr->pr = plr->rl; plr->count = 1; plr->rl[0].q.x = (plr->rl[0].p.x = rv[0]) + rv[2]; plr->rl[0].q.y = (plr->rl[0].p.y = rv[1]) + rv[3]; return 4; } plr->count = count; if (count <= MAX_LOCAL_RECTS) pr = plr->rl; else { pr = (gs_rect *)gs_alloc_byte_array(mem, count, sizeof(gs_rect), "rect_get"); if (pr == 0) return_error(e_VMerror); } plr->pr = pr; for (n = 0; n < count; n++, pr++) { ref rnum; int i; for (i = 0; i < 4; i++) { code = num_array_get(mem, (const ref *)op, format, (n << 2) + i, &rnum); switch (code) { case t_integer: rv[i] = rnum.value.intval; break; case t_real: rv[i] = rnum.value.realval; break; default: /* code < 0 */ return code; } } pr->q.x = (pr->p.x = rv[0]) + rv[2]; pr->q.y = (pr->p.y = rv[1]) + rv[3]; } return 1; }
/* * Consult Metrics2 and CDevProc, and call setcachedevice[2]. Return * o_push_estack if we had to call a CDevProc, or if we are skipping the * rendering process (only getting the metrics). */ int zchar_set_cache(os_ptr op, const gs_font_base *pbfont, const ref *pcnref, const float psb[2], const float pwidth[2], const gs_rect *pbbox, int (*cont_fill)(P1(os_ptr)), int (*cont_stroke)(P1(os_ptr))) { const ref *pfdict = &pfont_data(pbfont)->dict; ref *pmdict; ref *pcdevproc; int have_cdevproc; ref rpop; bool metrics2 = false; int (*cont)(P1(os_ptr)); float w2[10]; gs_show_enum *penum = op_show_find(); w2[0] = pwidth[0], w2[1] = pwidth[1]; /* Adjust the bounding box for stroking if needed. */ w2[2] = pbbox->p.x, w2[3] = pbbox->p.y; w2[4] = pbbox->q.x, w2[5] = pbbox->q.y; if ( pbfont->PaintType == 0 ) cont = cont_fill; else { double expand = max(1.415, gs_currentmiterlimit(igs)) * gs_currentlinewidth(igs) / 2; w2[2] -= expand, w2[3] -= expand; w2[4] += expand, w2[5] += expand; cont = cont_stroke; } /* Check for Metrics2. */ if ( dict_find_string(pfdict, "Metrics2", &pmdict) > 0 ) { ref *pmvalue; check_type_only(*pmdict, t_dictionary); check_dict_read(*pmdict); if ( dict_find(pmdict, pcnref, &pmvalue) > 0 ) { check_read_type_only(*pmvalue, t_array); if ( r_size(pmvalue) == 4 ) { int code = num_params(pmvalue->value.refs + 3, 4, w2 + 6); if ( code < 0 ) return code; metrics2 = true; } } } /* Check for CDevProc or "short-circuiting". */ have_cdevproc = dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0; if ( have_cdevproc || gs_show_width_only(penum) ) { int i; int (*zsetc)(P1(os_ptr)); int nparams; if ( have_cdevproc ) { check_proc_only(*pcdevproc); zsetc = zsetcachedevice2; if ( !metrics2 ) { w2[6] = w2[0], w2[7] = w2[1]; w2[8] = w2[9] = 0; } nparams = 10; } else { make_oper(&rpop, 0, zpop); pcdevproc = &rpop; if ( metrics2 ) zsetc = zsetcachedevice2, nparams = 10; else zsetc = zsetcachedevice, nparams = 6; } check_estack(3); /* Push the l.s.b. for .type1addpath if necessary. */ if ( psb != 0 ) { push(nparams + 3); make_real(op - (nparams + 2), psb[0]); make_real(op - (nparams + 1), psb[1]); } else { push(nparams + 1); } for ( i = 0; i < nparams; ++i ) make_real(op - nparams + i, w2[i]); ref_assign(op, pcnref); push_op_estack(cont); push_op_estack(zsetc); ++esp; ref_assign(esp, pcdevproc); return o_push_estack; } { int code = (metrics2 ? gs_setcachedevice2(penum, igs, w2) : gs_setcachedevice(penum, igs, w2)); if ( code < 0 ) return code; } /* No metrics modification, do the stroke or fill now. */ /* Push the l.s.b. for .type1addpath if necessary. */ if ( psb != 0 ) { push(2); make_real(op - 1, psb[0]); make_real(op, psb[1]); } return cont(op); }
static BOOL kpc_bindparameter(ATOMID idfName, WORD h, LPFETCH lpFetch, int nParam, ATOMID idMode, WORD wType, OBJECTID idObj, ATOMID idSlot, BOOL bLive) { WORD wMode; WORD sqlType = SQL_LONGVARCHAR, scale = 0, nullable = SQL_NO_NULLS; DWORD colDef = RET_BUFFER_LEN - 1; LPPARAM lpParams, lpParam; LPDESC lpDesc; WORD wNumParams = 0; DWORD dwLen; RETCODE code; if (idMode == Symbol(INPUT)) wMode = SQL_PARAM_INPUT; else if (idMode == Symbol(OUTPUT)) wMode = SQL_PARAM_OUTPUT; else if (idMode == Symbol(INPUT_OUTPUT)) wMode = SQL_PARAM_INPUT_OUTPUT; code = SQLDescribeParam(lpFetch->hstmt, nParam, &sqlType, &colDef, &scale, &nullable); switch (code) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: break; case SQL_INVALID_HANDLE: return KPC_HANDLE_ERROR(IDE_INVALID_HANDLE, h); default: sql_error(idfName, SQL_NULL_HDBC, lpFetch->hstmt); if (!stricmp(sqlstate, "IM001")) { if (nParam < 1) return KPC_ERROR(IDE_OUTOF_RANGE, KppAddAtomInt(nParam)); if (!num_params(idfName, h, lpFetch->hstmt, &wNumParams)) return ERROR; if (nParam > wNumParams) return KPC_ERROR(IDE_OUTOF_RANGE, KppAddAtomInt(nParam)); sqlType = SQL_LONGVARCHAR; colDef = RET_BUFFER_LEN - 1; nullable = SQL_NO_NULLS; } else return ERROR; } if (!lpFetch->params) { if (!wNumParams && !num_params(idfName, h, lpFetch->hstmt, &wNumParams)) return ERROR; lpParams = calloc(sizeof(PARAM), wNumParams); if (!lpParams) return KPC_ERROR(IDE_OUTOF_MEMORY, NULLID); } else lpParams = lpFetch->params; lpParam = lpParams + nParam - 1; lpDesc = &lpParam->desc; lpDesc->sqlType = sqlType; lpDesc->colDef = colDef; lpDesc->scale = scale; lpDesc->nullable = nullable; if (lpFetch->wXParamRows) { lpDesc->pdwLen = calloc(sizeof(DWORD), lpFetch->wXParamRows + 1); if (!lpDesc->pdwLen) return KPC_ERROR(IDE_OUTOF_MEMORY, NULLID); } else lpDesc->pdwLen = &lpDesc->dwLen; if (!fill_bind(idfName, lpDesc, &lpParam->data, lpFetch->wXParamRows, &dwLen)) { free_params(lpParams, lpFetch->wNumParams); return ERROR; } else { lpParam->wMode = wMode; lpParam->wType = wType; lpParam->idObj = idObj; lpParam->idSlot = idSlot; lpDesc->colDef = dwLen; lpFetch->wNumParams = wNumParams; lpFetch->params = lpParams; if (bLive) { int i = -1; while (++i <= lpFetch->wXParamRows) lpDesc->pdwLen[i] = SQL_LEN_DATA_AT_EXEC(0); } else if (!set_parameter_value(idfName, lpParam, lpFetch->wXParamRows)) return ERROR; } code = SQLBindParameter(lpFetch->hstmt, nParam, wMode, lpDesc->cType, lpDesc->sqlType, lpDesc->colDef, lpDesc->scale, lpDesc->address, dwLen, lpDesc->pdwLen); switch (code) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: lpParam->bound = TRUE; return TRUE; case SQL_INVALID_HANDLE: return KPC_HANDLE_ERROR(IDE_INVALID_HANDLE, h); default: return sql_error(idfName, SQL_NULL_HDBC, lpFetch->hstmt); } }
static int bbox_finish(i_ctx_t *i_ctx_p, op_proc_t cont, op_proc_t *exec_cont) { /* Returns exec_cont - a function, which must be called by caller after this function. */ os_ptr op = osp; gs_font *pfont; int code; gs_text_enum_t *penum = op_show_find(i_ctx_p); gs_type1exec_state cxs; /* stack allocate to avoid sandbars */ gs_type1_state *const pcis = &cxs.cis; double sbxy[2]; gs_point sbpt; gs_point *psbpt = 0; os_ptr opc = op; const ref *opstr; ref other_subr; if (!r_has_type(opc, t_string)) { check_op(3); code = num_params(op, 2, sbxy); if (code < 0) return code; sbpt.x = sbxy[0]; sbpt.y = sbxy[1]; psbpt = &sbpt; opc -= 2; check_type(*opc, t_string); } code = font_param(opc - 3, &pfont); if (code < 0) return code; if (penum == 0 || !font_uses_charstrings(pfont)) return_error(e_undefined); { gs_font_type1 *const pfont1 = (gs_font_type1 *) pfont; int lenIV = pfont1->data.lenIV; if (lenIV > 0 && r_size(opc) <= lenIV) return_error(e_invalidfont); check_estack(5); /* in case we need to do a callout */ code = type1_exec_init(pcis, penum, igs, pfont1); if (code < 0) return code; if (psbpt) gs_type1_set_lsb(pcis, psbpt); } opstr = opc; icont: code = type1_continue_dispatch(i_ctx_p, &cxs, opstr, &other_subr, (psbpt ? 6 : 4)); op = osp; /* OtherSubrs might have altered it */ switch (code) { case 0: /* all done */ /* Call the continuation now. */ if (psbpt) pop(2); *exec_cont = cont; return 0; case type1_result_callothersubr: /* unknown OtherSubr */ push_op_estack(cont); /* call later */ return type1_call_OtherSubr(i_ctx_p, &cxs, bbox_continue, &other_subr); case type1_result_sbw: /* [h]sbw, just continue */ opstr = 0; goto icont; default: /* code < 0, error */ return code; } }