Exemplo n.º 1
0
static cairo_uint64_t
point_distance_sq (const cairo_point_t *p1,
		   const cairo_point_t *p2)
{
    int32_t dx = p1->x - p2->x;
    int32_t dy = p1->y - p2->y;
    return _cairo_int64_add(_cairo_int32x32_64_mul (dx, dx), _cairo_int32x32_64_mul (dy, dy));
}
static cairo_int64_t
distance_along_face (const cairo_stroke_face_t *face,
		    const cairo_point_t *p)
{
    int32_t dx = (p->x - face->point.x);
    int32_t dy = (p->y - face->point.y);
    return _cairo_int64_add (_cairo_int32x32_64_mul (dx, face->dev_vector.dx),
			     _cairo_int32x32_64_mul (dy, face->dev_vector.dy));
}
Exemplo n.º 3
0
static cairo_always_inline cairo_time_t
_cairo_time_from_large_integer (LARGE_INTEGER t)
{
    cairo_int64_t r;

    r = _cairo_int64_lsl (_cairo_int32_to_int64 (t.HighPart), 32);
    r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.LowPart));

    return r;
}
Exemplo n.º 4
0
cairo_time_t
_cairo_time_get (void)
{
    QWORD t;
    cairo_int64_t r;

    DosTmrQueryTime (&t);

    r = _cairo_int64_lsl (_cairo_int32_to_int64 (t.ulHi), 32);
    r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.ulLo));

    return r;
}
Exemplo n.º 5
0
cairo_time_t
_cairo_time_get (void)
{
    struct timeval t;
    cairo_time_t r;

    gettimeofday (&t, NULL);

    r = _cairo_double_to_int64 (_cairo_time_1s ());
    r = _cairo_int64_mul (r, _cairo_int32_to_int64 (t.tv_sec));
    r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.tv_usec));

    return r;
}
Exemplo n.º 6
0
cairo_time_t
_cairo_time_get (void)
{
    struct timespec t;
    cairo_time_t r;

    clock_gettime (CAIRO_CLOCK, &t);

    r = _cairo_double_to_int64 (_cairo_time_1s ());
    r = _cairo_int64_mul (r, _cairo_int32_to_int64 (t.tv_sec));
    r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.tv_nsec));

    return r;
}
Exemplo n.º 7
0
static inline cairo_int64_t
_slope_length (cairo_slope_t *slope)
{
    return _cairo_int64_add (_cairo_int32x32_64_mul (slope->dx, slope->dx),
			     _cairo_int32x32_64_mul (slope->dy, slope->dy));
}
Exemplo n.º 8
0
static int
_line_segs_intersect_ceil (cairo_line_t *l1, cairo_line_t *l2, cairo_fixed_t *y_intersection)
{
    cairo_fixed_16_16_t	dx1, dx2, dy1, dy2;
    cairo_fixed_32_32_t	den_det;
    cairo_fixed_32_32_t	l1_det, l2_det;
    cairo_fixed_64_64_t num_det;
    cairo_fixed_32_32_t	intersect_32_32;
    cairo_fixed_48_16_t	intersect_48_16;
    cairo_fixed_16_16_t	intersect_16_16;
    cairo_quorem128_t	qr;

    dx1 = l1->p1.x - l1->p2.x;
    dy1 = l1->p1.y - l1->p2.y;
    dx2 = l2->p1.x - l2->p2.x;
    dy2 = l2->p1.y - l2->p2.y;
    den_det = _det16_32 (dx1, dy1,
			 dx2, dy2);
    
    if (_cairo_int64_eq (den_det, _cairo_int32_to_int64(0)))
	return 0;

    l1_det = _det16_32 (l1->p1.x, l1->p1.y,
			l1->p2.x, l1->p2.y);
    l2_det = _det16_32 (l2->p1.x, l2->p1.y,
			l2->p2.x, l2->p2.y);

    
    num_det = _det32_64 (l1_det, _fixed_16_16_to_fixed_32_32 (dy1),
			 l2_det, _fixed_16_16_to_fixed_32_32 (dy2));
    
    /*
     * Ok, this one is a bit tricky in fixed point, the denominator
     * needs to be left with 32-bits of fraction so that the
     * result of the divide ends up with 32-bits of fraction (64 - 32 = 32)
     */
    qr = _cairo_int128_divrem (num_det, _cairo_int64_to_int128 (den_det));
    
    intersect_32_32 = _cairo_int128_to_int64 (qr.quo);
    
    /*
     * Find the ceiling of the quotient -- divrem returns
     * the quotient truncated towards zero, so if the
     * quotient should be positive (num_den and den_det have same sign)
     * bump the quotient up by one.
     */
    
    if (_cairo_int128_ne (qr.rem, _cairo_int32_to_int128 (0)) &&
	(_cairo_int128_ge (num_det, _cairo_int32_to_int128 (0)) ==
	 _cairo_int64_ge (den_det, _cairo_int32_to_int64 (0))))
    {
	intersect_32_32 = _cairo_int64_add (intersect_32_32,
					    _cairo_int32_to_int64 (1));
    }
	
    /* 
     * Now convert from 32.32 to 48.16 and take the ceiling;
     * this requires adding in 15 1 bits and shifting the result
     */

    intersect_32_32 = _cairo_int64_add (intersect_32_32,
					_cairo_int32_to_int64 ((1 << 16) - 1));
    intersect_48_16 = _cairo_int64_rsa (intersect_32_32, 16);
    
    /*
     * And drop the top bits
     */
    intersect_16_16 = _cairo_int64_to_int32 (intersect_48_16);
    
    *y_intersection = intersect_16_16;

    return 1;
}
Exemplo n.º 9
0
/* Compute the intersection of two lines as defined by two edges. The
 * result is provided as a coordinate pair of 128-bit integers.
 *
 * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection or
 * %CAIRO_BO_STATUS_PARALLEL if the two lines are exactly parallel.
 */
static cairo_bool_t
intersect_lines (cairo_bo_edge_t		*a,
		 cairo_bo_edge_t		*b,
		 cairo_bo_intersect_point_t	*intersection)
{
    cairo_int64_t a_det, b_det;

    /* XXX: We're assuming here that dx and dy will still fit in 32
     * bits. That's not true in general as there could be overflow. We
     * should prevent that before the tessellation algorithm begins.
     * What we're doing to mitigate this is to perform clamping in
     * cairo_bo_tessellate_polygon().
     */
    int32_t dx1 = a->edge.line.p1.x - a->edge.line.p2.x;
    int32_t dy1 = a->edge.line.p1.y - a->edge.line.p2.y;

    int32_t dx2 = b->edge.line.p1.x - b->edge.line.p2.x;
    int32_t dy2 = b->edge.line.p1.y - b->edge.line.p2.y;

    cairo_int64_t den_det;
    cairo_int64_t R;
    cairo_quorem64_t qr;

    den_det = det32_64 (dx1, dy1, dx2, dy2);

     /* Q: Can we determine that the lines do not intersect (within range)
      * much more cheaply than computing the intersection point i.e. by
      * avoiding the division?
      *
      *   X = ax + t * adx = bx + s * bdx;
      *   Y = ay + t * ady = by + s * bdy;
      *   ∴ t * (ady*bdx - bdy*adx) = bdx * (by - ay) + bdy * (ax - bx)
      *   => t * L = R
      *
      * Therefore we can reject any intersection (under the criteria for
      * valid intersection events) if:
      *   L^R < 0 => t < 0, or
      *   L<R => t > 1
      *
      * (where top/bottom must at least extend to the line endpoints).
      *
      * A similar substitution can be performed for s, yielding:
      *   s * (ady*bdx - bdy*adx) = ady * (ax - bx) - adx * (ay - by)
      */
    R = det32_64 (dx2, dy2,
		  b->edge.line.p1.x - a->edge.line.p1.x,
		  b->edge.line.p1.y - a->edge.line.p1.y);
    if (_cairo_int64_negative (den_det)) {
	if (_cairo_int64_ge (den_det, R))
	    return FALSE;
    } else {
	if (_cairo_int64_le (den_det, R))
	    return FALSE;
    }

    R = det32_64 (dy1, dx1,
		  a->edge.line.p1.y - b->edge.line.p1.y,
		  a->edge.line.p1.x - b->edge.line.p1.x);
    if (_cairo_int64_negative (den_det)) {
	if (_cairo_int64_ge (den_det, R))
	    return FALSE;
    } else {
	if (_cairo_int64_le (den_det, R))
	    return FALSE;
    }

    /* We now know that the two lines should intersect within range. */

    a_det = det32_64 (a->edge.line.p1.x, a->edge.line.p1.y,
		      a->edge.line.p2.x, a->edge.line.p2.y);
    b_det = det32_64 (b->edge.line.p1.x, b->edge.line.p1.y,
		      b->edge.line.p2.x, b->edge.line.p2.y);

    /* x = det (a_det, dx1, b_det, dx2) / den_det */
    qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dx1,
						       b_det, dx2),
					 den_det);
    if (_cairo_int64_eq (qr.rem, den_det))
	return FALSE;
#if 0
    intersection->x.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT;
#else
    intersection->x.exactness = EXACT;
    if (! _cairo_int64_is_zero (qr.rem)) {
	if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem))
	    qr.rem = _cairo_int64_negate (qr.rem);
	qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2));
	if (_cairo_int64_ge (qr.rem, den_det)) {
	    qr.quo = _cairo_int64_add (qr.quo,
				       _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1));
	} else
	    intersection->x.exactness = INEXACT;
    }
#endif
    intersection->x.ordinate = _cairo_int64_to_int32 (qr.quo);

    /* y = det (a_det, dy1, b_det, dy2) / den_det */
    qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dy1,
						       b_det, dy2),
					 den_det);
    if (_cairo_int64_eq (qr.rem, den_det))
	return FALSE;
#if 0
    intersection->y.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT;
#else
    intersection->y.exactness = EXACT;
    if (! _cairo_int64_is_zero (qr.rem)) {
	if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem))
	    qr.rem = _cairo_int64_negate (qr.rem);
	qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2));
	if (_cairo_int64_ge (qr.rem, den_det)) {
	    qr.quo = _cairo_int64_add (qr.quo,
				       _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1));
	} else
	    intersection->y.exactness = INEXACT;
    }
#endif
    intersection->y.ordinate = _cairo_int64_to_int32 (qr.quo);

    return TRUE;
}