示例#1
0
/* 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;
}
示例#2
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);
}
示例#3
0
/* <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;
}
示例#4
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);
	}
    }
}
示例#5
0
/* <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;
}
示例#6
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;
}
示例#7
0
/* <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;
}
示例#8
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 {
示例#9
0
/* 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;
}
示例#10
0
/*
 * 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);
}
示例#11
0
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);
    }          
}
示例#12
0
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;
    }
}