Beispiel #1
0
PIXMAN_EXPORT pixman_fixed_t
pixman_sample_ceil_y (pixman_fixed_t y, int n)
{
    pixman_fixed_t f = pixman_fixed_frac (y);
    pixman_fixed_t i = pixman_fixed_floor (y);

    f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
	Y_FRAC_FIRST (n);
    
    if (f > Y_FRAC_LAST (n))
    {
	if (pixman_fixed_to_int (i) == 0x7fff)
	{
	    f = 0xffff; /* saturate */
	}
	else
	{
	    f = Y_FRAC_FIRST (n);
	    i += pixman_fixed_1;
	}
    }
    return (i | f);
}
Beispiel #2
0
/*
 * Compute the largest value strictly less than y which is on a
 * grid row.
 */
PIXMAN_EXPORT pixman_fixed_t
pixman_sample_floor_y (pixman_fixed_t y,
                       int            n)
{
    pixman_fixed_t f = pixman_fixed_frac (y);
    pixman_fixed_t i = pixman_fixed_floor (y);

    f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
	Y_FRAC_FIRST (n);

    if (f < Y_FRAC_FIRST (n))
    {
	if (pixman_fixed_to_int (i) == 0x8000)
	{
	    f = 0; /* saturate */
	}
	else
	{
	    f = Y_FRAC_LAST (n);
	    i -= pixman_fixed_1;
	}
    }
    return (i | f);
}
Beispiel #3
0
/*
 * We want to detect the case where we add the same value to a long
 * span of pixels.  The triangles on the end are filled in while we
 * count how many sub-pixel scanlines contribute to the middle section.
 *
 *                 +--------------------------+
 *  fill_height =|   \                      /
 *                     +------------------+
 *                      |================|
 *                   fill_start       fill_end
 */
static void
rasterize_edges_8 (pixman_image_t *image,
                   pixman_edge_t * l,
                   pixman_edge_t * r,
                   pixman_fixed_t  t,
                   pixman_fixed_t  b)
{
    pixman_fixed_t y = t;
    uint32_t  *line;
    int fill_start = -1, fill_end = -1;
    int fill_size = 0;
    uint32_t *buf = (image)->bits.bits;
    int stride = (image)->bits.rowstride;
    int width = (image)->bits.width;

    line = buf + pixman_fixed_to_int (y) * stride;

    for (;;)
    {
        uint8_t *ap = (uint8_t *) line;
        pixman_fixed_t lx, rx;
        int lxi, rxi;

        /* clip X */
        lx = l->x;
        if (lx < 0)
	    lx = 0;

        rx = r->x;

        if (pixman_fixed_to_int (rx) >= width)
	{
	    /* Use the last pixel of the scanline, covered 100%.
	     * We can't use the first pixel following the scanline,
	     * because accessing it could result in a buffer overrun.
	     */
	    rx = pixman_int_to_fixed (width) - 1;
	}

        /* Skip empty (or backwards) sections */
        if (rx > lx)
        {
            int lxs, rxs;

            /* Find pixel bounds for span. */
            lxi = pixman_fixed_to_int (lx);
            rxi = pixman_fixed_to_int (rx);

            /* Sample coverage for edge pixels */
            lxs = RENDER_SAMPLES_X (lx, 8);
            rxs = RENDER_SAMPLES_X (rx, 8);

            /* Add coverage across row */
            if (lxi == rxi)
            {
                WRITE (image, ap + lxi,
		       clip255 (READ (image, ap + lxi) + rxs - lxs));
	    }
            else
            {
                WRITE (image, ap + lxi,
		       clip255 (READ (image, ap + lxi) + N_X_FRAC (8) - lxs));

                /* Move forward so that lxi/rxi is the pixel span */
                lxi++;

                /* Don't bother trying to optimize the fill unless
		 * the span is longer than 4 pixels. */
                if (rxi - lxi > 4)
                {
                    if (fill_start < 0)
                    {
                        fill_start = lxi;
                        fill_end = rxi;
                        fill_size++;
		    }
                    else
                    {
                        if (lxi >= fill_end || rxi < fill_start)
                        {
                            /* We're beyond what we saved, just fill it */
                            ADD_SATURATE_8 (ap + fill_start,
                                            fill_size * N_X_FRAC (8),
                                            fill_end - fill_start);
                            fill_start = lxi;
                            fill_end = rxi;
                            fill_size = 1;
			}
                        else
                        {
                            /* Update fill_start */
                            if (lxi > fill_start)
                            {
                                ADD_SATURATE_8 (ap + fill_start,
                                                fill_size * N_X_FRAC (8),
                                                lxi - fill_start);
                                fill_start = lxi;
			    }
                            else if (lxi < fill_start)
                            {
                                ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8),
                                                fill_start - lxi);
			    }

                            /* Update fill_end */
                            if (rxi < fill_end)
                            {
                                ADD_SATURATE_8 (ap + rxi,
                                                fill_size * N_X_FRAC (8),
                                                fill_end - rxi);
                                fill_end = rxi;
			    }
                            else if (fill_end < rxi)
                            {
                                ADD_SATURATE_8 (ap + fill_end,
                                                N_X_FRAC (8),
                                                rxi - fill_end);
			    }
                            fill_size++;
			}
		    }
		}
                else
                {
                    ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8), rxi - lxi);
		}

                WRITE (image, ap + rxi, clip255 (READ (image, ap + rxi) + rxs));
	    }
	}

        if (y == b)
        {
            /* We're done, make sure we clean up any remaining fill. */
            if (fill_start != fill_end)
            {
                if (fill_size == N_Y_FRAC (8))
                {
                    MEMSET_WRAPPED (image, ap + fill_start,
				    0xff, fill_end - fill_start);
		}
                else
                {
                    ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
                                    fill_end - fill_start);
		}
	    }
            break;
	}

        if (pixman_fixed_frac (y) != Y_FRAC_LAST (8))
        {
            RENDER_EDGE_STEP_SMALL (l);
            RENDER_EDGE_STEP_SMALL (r);
            y += STEP_Y_SMALL (8);
	}
        else
        {
            RENDER_EDGE_STEP_BIG (l);
            RENDER_EDGE_STEP_BIG (r);
            y += STEP_Y_BIG (8);
            if (fill_start != fill_end)
            {
                if (fill_size == N_Y_FRAC (8))
                {
                    MEMSET_WRAPPED (image, ap + fill_start,
				    0xff, fill_end - fill_start);
		}
                else
                {
                    ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
                                    fill_end - fill_start);
		}
		
                fill_start = fill_end = -1;
                fill_size = 0;
	    }
	    
            line += stride;
	}
    }
}