Ejemplo n.º 1
0
/* Transform a distance with a fixed-point result. */
int
gs_distance_transform2fixed(const gs_matrix_fixed * pmat,
                            floatp dx, floatp dy, gs_fixed_point * ppt)
{
    fixed px, py, t;
    double xtemp, ytemp;
    int code;

    if ((code = CHECK_DFMUL2FIXED_VARS(px, dx, pmat->xx, xtemp)) < 0 ||
        (code = CHECK_DFMUL2FIXED_VARS(py, dy, pmat->yy, ytemp)) < 0
        )
        return code;
    FINISH_DFMUL2FIXED_VARS(px, xtemp);
    FINISH_DFMUL2FIXED_VARS(py, ytemp);
    if (!is_fzero(pmat->yx)) {
        if ((code = CHECK_DFMUL2FIXED_VARS(t, dy, pmat->yx, ytemp)) < 0)
            return code;
        FINISH_DFMUL2FIXED_VARS(t, ytemp);
        if ((code = CHECK_SET_FIXED_SUM(px, px, t)) < 0)
            return code;
    }
    if (!is_fzero(pmat->xy)) {
        if ((code = CHECK_DFMUL2FIXED_VARS(t, dx, pmat->xy, xtemp)) < 0)
            return code;
        FINISH_DFMUL2FIXED_VARS(t, xtemp);
        if ((code = CHECK_SET_FIXED_SUM(py, py, t)) < 0)
            return code;
    }
    ppt->x = px;
    ppt->y = py;
    return 0;
}
Ejemplo n.º 2
0
/* Since this is used heavily, we check for shortcuts. */
int
gs_matrix_multiply(const gs_matrix * pm1, const gs_matrix * pm2, gs_matrix * pmr)
{
    double xx1 = pm1->xx, yy1 = pm1->yy;
    double tx1 = pm1->tx, ty1 = pm1->ty;
    double xx2 = pm2->xx, yy2 = pm2->yy;
    double xy2 = pm2->xy, yx2 = pm2->yx;

    if (is_xxyy(pm1)) {
        pmr->tx = tx1 * xx2 + pm2->tx;
        pmr->ty = ty1 * yy2 + pm2->ty;
        if (is_fzero(xy2))
            pmr->xy = 0;
        else
            pmr->xy = xx1 * xy2,
                pmr->ty += tx1 * xy2;
        pmr->xx = xx1 * xx2;
        if (is_fzero(yx2))
            pmr->yx = 0;
        else
            pmr->yx = yy1 * yx2,
                pmr->tx += ty1 * yx2;
        pmr->yy = yy1 * yy2;
    } else {
        double xy1 = pm1->xy, yx1 = pm1->yx;

        pmr->xx = xx1 * xx2 + xy1 * yx2;
        pmr->xy = xx1 * xy2 + xy1 * yy2;
        pmr->yy = yx1 * xy2 + yy1 * yy2;
        pmr->yx = yx1 * xx2 + yy1 * yx2;
        pmr->tx = tx1 * xx2 + ty1 * yx2 + pm2->tx;
        pmr->ty = tx1 * xy2 + ty1 * yy2 + pm2->ty;
    }
    return 0;
}
Ejemplo n.º 3
0
/* Invert a matrix.  Return gs_error_undefinedresult if not invertible. */
int
gs_matrix_invert(const gs_matrix *pm, gs_matrix *pmr)
{	/* We have to be careful about fetch/store order, */
	/* because pm might be the same as pmr. */
	if ( is_xxyy(pm) )
	{	if ( is_fzero(pm->xx) || is_fzero(pm->yy) )
		  return_error(gs_error_undefinedresult);
		pmr->tx = - (pmr->xx = 1.0 / pm->xx) * pm->tx;
		pmr->xy = 0.0;
		pmr->yx = 0.0;
		pmr->ty = - (pmr->yy = 1.0 / pm->yy) * pm->ty;
	}
	else
	{	double det = pm->xx * pm->yy - pm->xy * pm->yx;
		double mxx = pm->xx, mtx = pm->tx;
		if ( det == 0 )
		  return_error(gs_error_undefinedresult);
		pmr->xx = pm->yy / det;
		pmr->xy = - pm->xy / det;
		pmr->yx = - pm->yx / det;
		pmr->yy = mxx / det;	/* xx is already changed */
		pmr->tx = - (mtx * pmr->xx + pm->ty * pmr->yx);
		pmr->ty = - (mtx * pmr->xy + pm->ty * pmr->yy);	/* tx ditto */
	}
	return 0;
}
Ejemplo n.º 4
0
/* Return gs_error_undefinedresult if the matrix is not invertible. */
int
gs_point_transform_inverse(floatp x, floatp y, const gs_matrix * pmat,
                           gs_point * ppt)
{
    if (is_xxyy(pmat)) {
        if (is_fzero(pmat->xx) || is_fzero(pmat->yy))
            return_error(gs_error_undefinedresult);
        ppt->x = (x - pmat->tx) / pmat->xx;
        ppt->y = (y - pmat->ty) / pmat->yy;
        return 0;
    } else if (is_xyyx(pmat)) {
        if (is_fzero(pmat->xy) || is_fzero(pmat->yx))
            return_error(gs_error_undefinedresult);
        ppt->x = (y - pmat->ty) / pmat->xy;
        ppt->y = (x - pmat->tx) / pmat->yx;
        return 0;
    } else {			/* There are faster ways to do this, */
        /* but we won't implement one unless we have to. */
        gs_matrix imat;
        int code = gs_matrix_invert(pmat, &imat);

        if (code < 0)
            return code;
        return gs_point_transform(x, y, &imat, ppt);
    }
}
Ejemplo n.º 5
0
int
gs_matrix_invert_to_double(const gs_matrix * pm, gs_matrix_double * pmr)
{				/* We have to be careful about fetch/store order, */
    /* because pm might be the same as pmr. */
    if (is_xxyy(pm)) {
        if (is_fzero(pm->xx) || is_fzero(pm->yy))
            return_error(gs_error_undefinedresult);
        pmr->tx = -(pmr->xx = 1.0 / pm->xx) * pm->tx;
        pmr->xy = 0.0;
        pmr->yx = 0.0;
        pmr->ty = -(pmr->yy = 1.0 / pm->yy) * pm->ty;
    } else {
        double mxx = pm->xx, myy = pm->yy, mxy = pm->xy, myx = pm->yx;
        double mtx = pm->tx, mty = pm->ty;
        double det = (mxx * myy) - (mxy * myx);

        /*
         * We are doing the math as floats instead of doubles to reproduce
         * the results in page 1 of CET 10-09.ps
         */
        if (det == 0)
            return_error(gs_error_undefinedresult);
        pmr->xx = myy / det;
        pmr->xy = -mxy / det;
        pmr->yx = -myx / det;
        pmr->yy = mxx / det;
        pmr->tx = (((mty * myx) - (mtx * myy))) / det;
        pmr->ty = (((mtx * mxy) - (mty * mxx))) / det;
    }
    return 0;
}
Ejemplo n.º 6
0
Archivo: gvcmeas.c Proyecto: 131/gsview
/* from Ghostscript */
int
matrix_invert(const MATRIX *pm, MATRIX *pmr)
{     /* We have to be careful about fetch/store order, */
      /* because pm might be the same as pmr. */
      if ( is_xxyy(pm) )
      {       if ( is_fzero(pm->xx) || is_fzero(pm->yy) )
                return -1 ;
              pmr->tx = (float)(- (pmr->xx = (float)(1.0 / pm->xx)) * pm->tx);
              pmr->xy = 0.0;
              pmr->yx = 0.0;
              pmr->ty = (float)(- (pmr->yy = (float)(1.0 / pm->yy)) * pm->ty);
      }
      else
      {       double det = pm->xx * pm->yy - pm->xy * pm->yx;
              double mxx = pm->xx, mtx = pm->tx;
              if ( det == 0 )
                return -1 ;
              pmr->xx = (float)(pm->yy / det);
              pmr->xy = (float)(- pm->xy / det);
              pmr->yx = (float)(- pm->yx / det);
              pmr->yy = (float)(mxx / det);    /* xx is already changed */
              pmr->tx = (float)(- (mtx * pmr->xx + pm->ty * pmr->yx));
              pmr->ty = (float)(- (mtx * pmr->xy + pm->ty * pmr->yy)); /* tx ditto */
      }
      return 0;
}
Ejemplo n.º 7
0
/* Transform a distance. */
int
gs_distance_transform(floatp dx, floatp dy, const gs_matrix *pmat,
  gs_point *pdpt)
{	pdpt->x = dx * pmat->xx;
	pdpt->y = dy * pmat->yy;
	if ( !is_fzero(pmat->yx) )
	  pdpt->x += dy * pmat->yx;
	if ( !is_fzero(pmat->xy) )
	  pdpt->y += dx * pmat->xy;
	return 0;
}
Ejemplo n.º 8
0
/* Transform a point. */
int
gs_point_transform(floatp x, floatp y, const gs_matrix *pmat,
  gs_point *ppt)
{	ppt->x = x * pmat->xx + pmat->tx;
	ppt->y = y * pmat->yy + pmat->ty;
	if ( !is_fzero(pmat->yx) )
	  ppt->x += y * pmat->yx;
	if ( !is_fzero(pmat->xy) )
	  ppt->y += x * pmat->xy;
	return 0;
}
Ejemplo n.º 9
0
/* Transform a point. */
int
gs_point_transform(floatp x, floatp y, const gs_matrix * pmat,
                   gs_point * ppt)
{
    /*
     * The float casts are there to reproduce results in CET 10-01.ps
     * page 4.
     */
    ppt->x = (float)(x * pmat->xx) + pmat->tx;
    ppt->y = (float)(y * pmat->yy) + pmat->ty;
    if (!is_fzero(pmat->yx))
        ppt->x += (float)(y * pmat->yx);
    if (!is_fzero(pmat->xy))
        ppt->y += (float)(x * pmat->xy);
    return 0;
}
Ejemplo n.º 10
0
/* Test whether an image has a default ImageMatrix. */
bool
gx_image_matrix_is_default(const gs_data_image_t *pid)
{
    return (is_xxyy(&pid->ImageMatrix) &&
	    pid->ImageMatrix.xx == pid->Width &&
	    pid->ImageMatrix.yy == -pid->Height &&
	    is_fzero(pid->ImageMatrix.tx) &&
	    pid->ImageMatrix.ty == pid->Height);
}
Ejemplo n.º 11
0
/*
 * Determine the flatness for rendering a character in an outline font.
 * This may be less than the flatness in the imager state.
 * The second argument is the default scaling for the font: 0.001 for
 * Type 1 fonts, 1.0 for TrueType fonts.
 */
double
gs_char_flatness(const gs_imager_state *pis, floatp default_scale)
{
    /*
     * Set the flatness to a value that is likely to produce reasonably
     * good-looking curves, regardless of its current value in the
     * graphics state.  If the character is very small, set the flatness
     * to zero, which will produce very accurate curves.
     */
    double cxx = fabs(pis->ctm.xx), cyy = fabs(pis->ctm.yy);

    if (is_fzero(cxx) || (cyy < cxx && !is_fzero(cyy)))
	cxx = cyy;
    if (!is_xxyy(&pis->ctm)) {
	double cxy = fabs(pis->ctm.xy), cyx = fabs(pis->ctm.yx);

	if (is_fzero(cxx) || (cxy < cxx && !is_fzero(cxy)))
	    cxx = cxy;
	if (is_fzero(cxx) || (cyx < cxx && !is_fzero(cyx)))
	    cxx = cyx;
    }
    /* Correct for the default scaling. */
    cxx *= 0.001 / default_scale;
    /* Don't let the flatness be worse than the default. */
    if (cxx > pis->flatness)
	cxx = pis->flatness;
    /* If the character is tiny, force accurate curves. */
    if (cxx < 0.2)
	cxx = 0;
    return cxx;
}
Ejemplo n.º 12
0
/* Invert a matrix.  Return gs_error_undefinedresult if not invertible. */
int
gs_matrix_invert(const gs_matrix * pm, gs_matrix * pmr)
{				/* We have to be careful about fetch/store order, */
    /* because pm might be the same as pmr. */
    if (is_xxyy(pm)) {
        if (is_fzero(pm->xx) || is_fzero(pm->yy))
            return_error(gs_error_undefinedresult);
        pmr->tx = -(pmr->xx = 1.0 / pm->xx) * pm->tx;
        pmr->xy = 0.0;
        pmr->yx = 0.0;
        pmr->ty = -(pmr->yy = 1.0 / pm->yy) * pm->ty;
    } else {
        float mxx = pm->xx, myy = pm->yy, mxy = pm->xy, myx = pm->yx;
        float mtx = pm->tx, mty = pm->ty;
        /* we declare det as double since on at least some computer (i.e. peeves)
           declaring it as a float results in different values for pmr depending
           on whether or not optimization is turned on.  I believe this is caused
           by the compiler keeping the det value in an internal register when
           optimization is enable.  As evidence of this if you add a debugging
           statement to print out det the optimized code acts the same as the
           unoptimized code.  declearing det as double does not change the CET 10-09.ps
           output. */
        double det = (float)(mxx * myy) - (float)(mxy * myx);

        /*
         * We are doing the math as floats instead of doubles to reproduce
         * the results in page 1 of CET 10-09.ps
         */
        if (det == 0)
            return_error(gs_error_undefinedresult);
        pmr->xx = myy / det;
        pmr->xy = -mxy / det;
        pmr->yx = -myx / det;
        pmr->yy = mxx / det;
        pmr->tx = (((float)(mty * myx) - (float)(mtx * myy))) / det;
        pmr->ty = (((float)(mtx * mxy) - (float)(mty * mxx))) / det;
    }
    return 0;
}
Ejemplo n.º 13
0
/* Return gs_error_undefinedresult if the matrix is not invertible. */
int
gs_distance_transform_inverse(floatp dx, floatp dy,
                              const gs_matrix * pmat, gs_point * pdpt)
{
    if (is_xxyy(pmat)) {
        if (is_fzero(pmat->xx) || is_fzero(pmat->yy))
            return_error(gs_error_undefinedresult);
        pdpt->x = dx / pmat->xx;
        pdpt->y = dy / pmat->yy;
    } else if (is_xyyx(pmat)) {
        if (is_fzero(pmat->xy) || is_fzero(pmat->yx))
            return_error(gs_error_undefinedresult);
        pdpt->x = dy / pmat->xy;
        pdpt->y = dx / pmat->yx;
    } else {
        double det = pmat->xx * pmat->yy - pmat->xy * pmat->yx;

        if (det == 0)
            return_error(gs_error_undefinedresult);
        pdpt->x = (dx * pmat->yy - dy * pmat->yx) / det;
        pdpt->y = (dy * pmat->xx - dx * pmat->xy) / det;
    }
    return 0;
}
Ejemplo n.º 14
0
/* Transform a point with a fixed-point result. */
int
gs_point_transform2fixed(const gs_matrix_fixed * pmat,
                         floatp x, floatp y, gs_fixed_point * ppt)
{
    fixed px, py, t;
    double xtemp, ytemp;
    int code;

    if (!pmat->txy_fixed_valid) {	/* The translation is out of range.  Do the */
        /* computation in floating point, and convert to */
        /* fixed at the end. */
        gs_point fpt;

        gs_point_transform(x, y, (const gs_matrix *)pmat, &fpt);
        if (!(f_fits_in_fixed(fpt.x) && f_fits_in_fixed(fpt.y)))
            return_error(gs_error_limitcheck);
        ppt->x = float2fixed(fpt.x);
        ppt->y = float2fixed(fpt.y);
        return 0;
    }
    if (!is_fzero(pmat->xy)) {	/* Hope for 90 degree rotation */
        if ((code = CHECK_DFMUL2FIXED_VARS(px, y, pmat->yx, xtemp)) < 0 ||
            (code = CHECK_DFMUL2FIXED_VARS(py, x, pmat->xy, ytemp)) < 0
            )
            return code;
        FINISH_DFMUL2FIXED_VARS(px, xtemp);
        FINISH_DFMUL2FIXED_VARS(py, ytemp);
        if (!is_fzero(pmat->xx)) {
            if ((code = CHECK_DFMUL2FIXED_VARS(t, x, pmat->xx, xtemp)) < 0)
                return code;
            FINISH_DFMUL2FIXED_VARS(t, xtemp);
            if ((code = CHECK_SET_FIXED_SUM(px, px, t)) < 0)
                return code;
        }
        if (!is_fzero(pmat->yy)) {
            if ((code = CHECK_DFMUL2FIXED_VARS(t, y, pmat->yy, ytemp)) < 0)
                return code;
            FINISH_DFMUL2FIXED_VARS(t, ytemp);
            if ((code = CHECK_SET_FIXED_SUM(py, py, t)) < 0)
                return code;
        }
    } else {
        if ((code = CHECK_DFMUL2FIXED_VARS(px, x, pmat->xx, xtemp)) < 0 ||
            (code = CHECK_DFMUL2FIXED_VARS(py, y, pmat->yy, ytemp)) < 0
            )
            return code;
        FINISH_DFMUL2FIXED_VARS(px, xtemp);
        FINISH_DFMUL2FIXED_VARS(py, ytemp);
        if (!is_fzero(pmat->yx)) {
            if ((code = CHECK_DFMUL2FIXED_VARS(t, y, pmat->yx, ytemp)) < 0)
                return code;
            FINISH_DFMUL2FIXED_VARS(t, ytemp);
            if ((code = CHECK_SET_FIXED_SUM(px, px, t)) < 0)
                return code;
        }
    }
    if (((code = CHECK_SET_FIXED_SUM(ppt->x, px, pmat->tx_fixed)) < 0) ||
        ((code = CHECK_SET_FIXED_SUM(ppt->y, py, pmat->ty_fixed)) < 0) )
        return code;
    return 0;
}
Ejemplo n.º 15
0
/* We should cache the coefficients with the ctm.... */
int
gx_matrix_to_fixed_coeff(const gs_matrix * pmat, register fixed_coeff * pfc,
                         int max_bits)
{
    gs_matrix ctm;
    int scale = -10000;
    int expt, shift;

    ctm = *pmat;
    pfc->skewed = 0;
    if (!is_fzero(ctm.xx)) {
        discard(frexp(ctm.xx, &scale));
    }
    if (!is_fzero(ctm.xy)) {
        discard(frexp(ctm.xy, &expt));
        if (expt > scale)
            scale = expt;
        pfc->skewed = 1;
    }
    if (!is_fzero(ctm.yx)) {
        discard(frexp(ctm.yx, &expt));
        if (expt > scale)
            scale = expt;
        pfc->skewed = 1;
    }
    if (!is_fzero(ctm.yy)) {
        discard(frexp(ctm.yy, &expt));
        if (expt > scale)
            scale = expt;
    }
    /*
     * There are two multiplications in fixed_coeff_mult: one involves a
     * factor that may have max_bits significant bits, the other may have
     * fixed_fraction_bits (_fixed_shift) bits.  Ensure that neither one
     * will overflow.
     */
    if (max_bits < fixed_fraction_bits)
        max_bits = fixed_fraction_bits;
    scale = sizeof(long) * 8 - 1 - max_bits - scale;

    shift = scale - _fixed_shift;
    if (shift > 0) {
        pfc->shift = shift;
        pfc->round = (fixed) 1 << (shift - 1);
    } else {
        pfc->shift = 0;
        pfc->round = 0;
        scale -= shift;
    }
#define SET_C(c)\
  if ( is_fzero(ctm.c) ) pfc->c = 0;\
  else pfc->c = (long)ldexp(ctm.c, scale)
    SET_C(xx);
    SET_C(xy);
    SET_C(yx);
    SET_C(yy);
#undef SET_C
#ifdef DEBUG
    if (gs_debug_c('x')) {
        dlprintf6("[x]ctm: [%6g %6g %6g %6g %6g %6g]\n",
                  ctm.xx, ctm.xy, ctm.yx, ctm.yy, ctm.tx, ctm.ty);
        dlprintf6("   scale=%d fc: [0x%lx 0x%lx 0x%lx 0x%lx] shift=%d\n",
                  scale, pfc->xx, pfc->xy, pfc->yx, pfc->yy,
                  pfc->shift);
    }
#endif
    pfc->max_bits = max_bits;
    return 0;
}