diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.am | 1 | ||||
-rw-r--r-- | test/Makefile.sources | 1 | ||||
-rw-r--r-- | test/mask-glyphs.c | 175 | ||||
-rw-r--r-- | test/mask-glyphs.ref.png | bin | 0 -> 1189352 bytes |
4 files changed, 177 insertions, 0 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index ef2d875bc..3606658d0 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -461,6 +461,7 @@ REFERENCE_IMAGES = \ mask.pdf.rgb24.ref.png \ mask.quartz.ref.png \ mask.quartz.rgb24.ref.png \ + mask-glyphs.ref.png \ mask-surface-ctm.ref.png \ mask-surface-ctm.rgb24.ref.png \ mask-surface-ctm.svg11.argb32.ref.png \ diff --git a/test/Makefile.sources b/test/Makefile.sources index eeb9294e5..23596f8fd 100644 --- a/test/Makefile.sources +++ b/test/Makefile.sources @@ -105,6 +105,7 @@ test_sources = \ mask.c \ mask-alpha.c \ mask-ctm.c \ + mask-glyphs.c \ mask-surface-ctm.c \ mask-transformed-image.c \ mask-transformed-similar.c \ diff --git a/test/mask-glyphs.c b/test/mask-glyphs.c new file mode 100644 index 000000000..045dcaf8b --- /dev/null +++ b/test/mask-glyphs.c @@ -0,0 +1,175 @@ +/* + * Copyright 2009 Chris Wilson + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Chris Wilson not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Chris Wilson makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Chris Wilson <chris@chris-wilson.co.uk> + */ + +#include "cairo-test.h" + +#include <assert.h> + +static const char *png_filename = "romedalen.png"; + +#define WIDTH 800 +#define HEIGHT 600 + +static int +_image_to_glyphs (cairo_surface_t *image, + int channel, + int level, + cairo_scaled_font_t *scaled_font, + cairo_glyph_t *glyphs, + double tx, double ty) +{ + int width, height, stride; + const unsigned char *data; + cairo_format_t format; + int x, y, z, n; + + width = cairo_image_surface_get_width (image); + height = cairo_image_surface_get_height (image); + stride = cairo_image_surface_get_stride (image); + format = cairo_image_surface_get_format (image); + data = cairo_image_surface_get_data (image); + + n = 0; + for (y = 0; y < height; y++) { + const uint32_t *row = (uint32_t *) (data + y * stride); + + for (x = 0; x < width; x++) { + z = (row[x] >> channel) & 0xff; + if (z == level) { + double xx, yy, zz; + char c = n % 26 + 'a'; + int count = 1; + cairo_glyph_t *glyphs_p = &glyphs[n]; + + xx = 4 * (x - width/2.) + width/2.; + yy = 4 * (y - height/2.) + height/2.; + + zz = z / 1000.; + xx = xx + zz*(width/2. - xx); + yy = yy + zz*(height/2. - yy); + + cairo_scaled_font_text_to_glyphs (scaled_font, + tx + xx, ty + yy, + &c, 1, + &glyphs_p, &count, + NULL, NULL, + NULL); + assert (glyphs_p == &glyphs[n]); + assert (count == 1); + n++; + } + } + } + + return n; +} + +static cairo_status_t +_render_image (cairo_t *cr, + int width, int height, + cairo_surface_t *image) +{ + int ww, hh; + cairo_glyph_t *glyphs; + cairo_pattern_t *mask; + cairo_scaled_font_t *scaled_font; + double tx, ty; + const struct { + int shift; + double red; + double green; + double blue; + } channel[3] = { + { 0, 0.9, 0.3, 0.4 }, + { 8, 0.4, 0.9, 0.3 }, + { 16, 0.3, 0.4, 0.9 }, + }; + unsigned int n, i; + + ww = cairo_image_surface_get_width (image); + hh = cairo_image_surface_get_height (image); + + glyphs = cairo_glyph_allocate (ww * hh); + if (glyphs == NULL) { + cairo_surface_destroy (image); + return CAIRO_STATUS_NO_MEMORY; + } + + tx = (width - ww) / 2.; + ty = (height - hh) / 2.; + + cairo_set_font_size (cr, 5); + scaled_font = cairo_get_scaled_font (cr); + + for (i = 0; i < sizeof (channel) / sizeof (channel[0]); i++) { + cairo_push_group_with_content (cr, CAIRO_CONTENT_ALPHA); + for (n = 0; n < 256; n++) { + int num_glyphs; + + num_glyphs = _image_to_glyphs (image, channel[i].shift, n, + scaled_font, + glyphs, tx, ty); + + cairo_set_source_rgba (cr, + 0, 0, 0, + .15 + .85 * n / 255.); + cairo_show_glyphs (cr, glyphs, num_glyphs); + } + mask = cairo_pop_group (cr); + cairo_set_source_rgb (cr, + channel[i].red, + channel[i].green, + channel[i].blue); + cairo_mask (cr, mask); + cairo_pattern_destroy (mask); + } + + cairo_glyph_free (glyphs); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + const cairo_test_context_t *ctx = cairo_test_get_context (cr); + cairo_surface_t *image; + cairo_status_t status; + + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_paint (cr); + + image = cairo_test_create_surface_from_png (ctx, png_filename); + status = _render_image (cr, width, height, image); + cairo_surface_destroy (image); + + return cairo_test_status_from_status (ctx, status); +} + +CAIRO_TEST (mask_glyphs, + "Creates a mask using a distorted array of overlapping glyphs", + "XFAIL=svg,pdf mask, glyphs", /* keywords */ + NULL, /* requirements */ + WIDTH, HEIGHT, + NULL, draw) diff --git a/test/mask-glyphs.ref.png b/test/mask-glyphs.ref.png Binary files differnew file mode 100644 index 000000000..8abcc4759 --- /dev/null +++ b/test/mask-glyphs.ref.png |