Пример #1
0
void
fbGlyphs(CARD8 op,
	 PicturePtr pSrc,
	 PicturePtr pDst,
	 PictFormatPtr maskFormat,
	 INT16 xSrc,
	 INT16 ySrc, int nlist,
	 GlyphListPtr list,
	 GlyphPtr *glyphs)
{
#define N_STACK_GLYPHS 512
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    pixman_glyph_t stack_glyphs[N_STACK_GLYPHS];
    pixman_glyph_t *pglyphs = stack_glyphs;
    pixman_image_t *srcImage, *dstImage;
    int srcXoff, srcYoff, dstXoff, dstYoff;
    GlyphPtr glyph;
    int n_glyphs;
    int x, y;
    int i, n;
    int xDst = list->xOff, yDst = list->yOff;

    miCompositeSourceValidate(pSrc);

    n_glyphs = 0;
    for (i = 0; i < nlist; ++i)
	n_glyphs += list[i].len;

    if (!glyphCache)
	glyphCache = pixman_glyph_cache_create();

    pixman_glyph_cache_freeze (glyphCache);

    if (n_glyphs > N_STACK_GLYPHS) {
	if (!(pglyphs = malloc (n_glyphs * sizeof (pixman_glyph_t))))
	    goto out;
    }

    i = 0;
    x = y = 0;
    while (nlist--) {
        x += list->xOff;
        y += list->yOff;
        n = list->len;
        while (n--) {
	    const void *g;

            glyph = *glyphs++;

	    if (!(g = pixman_glyph_cache_lookup (glyphCache, glyph, NULL))) {
		pixman_image_t *glyphImage;
		PicturePtr pPicture;
		int xoff, yoff;

		pPicture = GetGlyphPicture(glyph, pScreen);
		if (!pPicture) {
		    n_glyphs--;
		    goto next;
		}

		if (!(glyphImage = image_from_pict(pPicture, FALSE, &xoff, &yoff)))
		    goto out;

		g = pixman_glyph_cache_insert(glyphCache, glyph, NULL,
					      glyph->info.x,
					      glyph->info.y,
					      glyphImage);

		free_pixman_pict(pPicture, glyphImage);

		if (!g)
		    goto out;
	    }

	    pglyphs[i].x = x;
	    pglyphs[i].y = y;
	    pglyphs[i].glyph = g;
	    i++;

	next:
            x += glyph->info.xOff;
            y += glyph->info.yOff;
	}
	list++;
    }

    if (!(srcImage = image_from_pict(pSrc, FALSE, &srcXoff, &srcYoff)))
	goto out;

    if (!(dstImage = image_from_pict(pDst, TRUE, &dstXoff, &dstYoff)))
	goto out_free_src;

    if (maskFormat) {
	pixman_format_code_t format;
	pixman_box32_t extents;

	format = maskFormat->format | (maskFormat->depth << 24);

	pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents);

	pixman_composite_glyphs(op, srcImage, dstImage, format,
				xSrc + srcXoff + extents.x1 - xDst, ySrc + srcYoff + extents.y1 - yDst,
				extents.x1, extents.y1,
				extents.x1 + dstXoff, extents.y1 + dstYoff,
				extents.x2 - extents.x1,
				extents.y2 - extents.y1,
				glyphCache, n_glyphs, pglyphs);
    }
    else {
	pixman_composite_glyphs_no_mask(op, srcImage, dstImage,
					xSrc + srcXoff - xDst, ySrc + srcYoff - yDst,
					dstXoff, dstYoff,
					glyphCache, n_glyphs, pglyphs);
    }

    free_pixman_pict(pDst, dstImage);

out_free_src:
    free_pixman_pict(pSrc, srcImage);

out:
    pixman_glyph_cache_thaw(glyphCache);
    if (pglyphs != stack_glyphs)
	free(pglyphs);
}
Пример #2
0
uint32_t
test_glyphs (int testnum, int verbose)
{
    pixman_image_t *glyph_images[MAX_GLYPHS];
    pixman_glyph_t glyphs[4 * MAX_GLYPHS];
    uint32_t crc32 = 0;
    pixman_image_t *source, *dest;
    int n_glyphs, i;
    pixman_glyph_cache_t *cache;

    lcg_srand (testnum);

    cache = pixman_glyph_cache_create ();

    source = create_image (300, formats,
			   ALLOW_CLIPPED | ALLOW_ALPHA_MAP |
			   ALLOW_SOURCE_CLIPPING |
			   ALLOW_REPEAT | ALLOW_SOLID);

    dest = create_image (128, formats,
			 ALLOW_CLIPPED | ALLOW_ALPHA_MAP |
			 ALLOW_SOURCE_CLIPPING);

    pixman_glyph_cache_freeze (cache);

    n_glyphs = lcg_rand_n (MAX_GLYPHS);
    for (i = 0; i < n_glyphs; ++i)
	glyph_images[i] = create_image (32, glyph_formats, 0);

    for (i = 0; i < 4 * n_glyphs; ++i)
    {
	int g = lcg_rand_n (n_glyphs);
	pixman_image_t *glyph_img = glyph_images[g];
	void *key1 = KEY1 (glyph_img);
	void *key2 = KEY2 (glyph_img);
	const void *glyph;

	if (!(glyph = pixman_glyph_cache_lookup (cache, key1, key2)))
	{
	    glyph =
		pixman_glyph_cache_insert (cache, key1, key2, 5, 8, glyph_img);
	}

	glyphs[i].glyph = glyph;
	glyphs[i].x = lcg_rand_n (128);
	glyphs[i].y = lcg_rand_n (128);
    }

    if (lcg_rand_n (2) == 0)
    {
	int src_x = lcg_rand_n (300) - 150;
	int src_y = lcg_rand_n (300) - 150;
	int mask_x = lcg_rand_n (64) - 32;
	int mask_y = lcg_rand_n (64) - 32;
	int dest_x = lcg_rand_n (64) - 32;
	int dest_y = lcg_rand_n (64) - 32;
	int width = lcg_rand_n (64);
	int height = lcg_rand_n (64);
	pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))];
	pixman_format_code_t format = random_format (glyph_formats);

	pixman_composite_glyphs (
	    op,
	    source, dest, format,
	    src_x, src_y,
	    mask_x, mask_y,
	    dest_x, dest_y,
	    width, height,
	    cache, 4 * n_glyphs, glyphs);
    }
    else
    {
	pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))];
	int src_x = lcg_rand_n (300) - 150;
	int src_y = lcg_rand_n (300) - 150;
	int dest_x = lcg_rand_n (64) - 32;
	int dest_y = lcg_rand_n (64) - 32;

	pixman_composite_glyphs_no_mask (
	    op, source, dest,
	    src_x, src_y,
	    dest_x, dest_y,
	    cache, 4 * n_glyphs, glyphs);
    }

    pixman_glyph_cache_thaw (cache);

    for (i = 0; i < n_glyphs; ++i)
    {
	pixman_image_t *img = glyph_images[i];
	void *key1, *key2;

	key1 = KEY1 (img);
	key2 = KEY2 (img);

	pixman_glyph_cache_remove (cache, key1, key2);
	pixman_image_unref (glyph_images[i]);
    }

    crc32 = compute_crc32_for_image (0, dest);

    pixman_image_unref (source);
    pixman_image_unref (dest);

    pixman_glyph_cache_destroy (cache);

    return crc32;
}