/* * Copyright © 2005 Red Hat, Inc. * * 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 * Red Hat, Inc. not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. Red Hat, Inc. makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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: Lutz Mueller */ #include #if CAIRO_HAS_TRANSFORM_SURFACE #include #endif #if CAIRO_HAS_PDF_SURFACE #include #endif #if CAIRO_HAS_PS_SURFACE #include #endif #include "cairo-test.h" #include #define WIDTH_IN_INCHES 3 #define HEIGHT_IN_INCHES 3 #define WIDTH_IN_POINTS (WIDTH_IN_INCHES * 72.) #define HEIGHT_IN_POINTS (HEIGHT_IN_INCHES * 72.) #if CAIRO_HAS_TRANSFORM_SURFACE static void draw (cairo_t *cr, double width, double height, double smile_ratio) { #define STROKE_WIDTH .04 double size; double theta = M_PI / 4 * smile_ratio; double dx = sqrt (0.005) * cos (theta); double dy = sqrt (0.005) * sin (theta); cairo_save (cr); if (width > height) size = height; else size = width; cairo_translate (cr, (width - size) / 2.0, (height - size) / 2.0); cairo_scale (cr, size, size); /* Fill face */ cairo_arc (cr, 0.5, 0.5, 0.5 - STROKE_WIDTH, 0, 2 * M_PI); cairo_set_source_rgb (cr, 1, 1, 0); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); /* Stroke face */ cairo_set_line_width (cr, STROKE_WIDTH / 2.0); cairo_stroke (cr); /* Eyes */ cairo_set_line_width (cr, STROKE_WIDTH); cairo_arc (cr, 0.3, 0.4, STROKE_WIDTH, 0, 2 * M_PI); cairo_fill (cr); cairo_arc (cr, 0.7, 0.4, STROKE_WIDTH, 0, 2 * M_PI); cairo_fill (cr); /* Mouth */ cairo_move_to (cr, 0.35 - dx, 0.75 - dy); cairo_curve_to (cr, 0.35 + dx, 0.75 + dy, 0.65 - dx, 0.75 + dy, 0.65 + dx, 0.75 - dy); cairo_stroke (cr); cairo_restore (cr); cairo_show_page (cr); } #define NUM_FRAMES 5 static void draw_title_page (cairo_surface_t *surface, const char *title) { cairo_t *cr; cr = cairo_create (surface); cairo_save (cr); cairo_select_font_face (cr, "Bitstream Vera Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 12); cairo_translate (cr, 20., HEIGHT_IN_POINTS / 10.); cairo_set_source_rgb (cr, 0, 0, 0); cairo_show_text (cr, title); cairo_restore (cr); cairo_close_path (cr); cairo_show_page (cr); cairo_destroy (cr); } static void draw_some_pages (cairo_surface_t *surface) { cairo_t *cr; int i; cr = cairo_create (surface); for (i = 0; i < NUM_FRAMES; i++) draw (cr, WIDTH_IN_POINTS, HEIGHT_IN_POINTS, (double) i / (NUM_FRAMES - 2)); cairo_destroy (cr); } static cairo_test_status_t test_plain (cairo_surface_t **in, cairo_surface_t **out) { cairo_status_t status; *out = *in = cairo_transform_surface_create (); status = cairo_surface_status (*in); if (status) { cairo_test_log ("Failed to create transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } return CAIRO_TEST_SUCCESS; } static cairo_test_status_t test_reverse (cairo_surface_t **in, cairo_surface_t **out) { cairo_status_t s; unsigned int pages[NUM_FRAMES], i; for (i = NUM_FRAMES; i > 0; i--) pages[i - 1] = NUM_FRAMES - i; *out = *in = cairo_transform_surface_create (); if ((s = cairo_surface_status (*in))) { cairo_test_log ("Failed to create transform surface: %s\n", cairo_status_to_string (s)); return CAIRO_TEST_FAILURE; } s = cairo_transform_surface_set_pages (*in, pages, NUM_FRAMES, 0); if (s) { cairo_test_log ("Failed to define order: %s\n", cairo_status_to_string (s)); return CAIRO_TEST_FAILURE; } return CAIRO_TEST_SUCCESS; } static cairo_test_status_t test_odd (cairo_surface_t **in, cairo_surface_t **out) { cairo_status_t s; unsigned int n = (int) ((NUM_FRAMES + 1) / 2); unsigned int pages[(int) ((NUM_FRAMES + 1) / 2)], i; for (i = 0; i < n; i++) pages[i] = 2 * i; *out = *in = cairo_transform_surface_create (); if ((s = cairo_surface_status (*in))) { cairo_test_log ("Failed to create transform surface: %s\n", cairo_status_to_string (s)); return CAIRO_TEST_FAILURE; } if ((s = cairo_transform_surface_set_pages (*in, pages, n, 0))) { cairo_test_log ("Failed to define order: %s\n", cairo_status_to_string (s)); return CAIRO_TEST_FAILURE; } return CAIRO_TEST_SUCCESS; } static cairo_test_status_t test_4_to_1 (cairo_surface_t **in, cairo_surface_t **out) { cairo_surface_t *s[4]; cairo_status_t status; cairo_matrix_t matrix; unsigned int i, j, n = (NUM_FRAMES + 3) / 4; unsigned int pages[(NUM_FRAMES + 3) / 4]; *in = cairo_transform_surface_create (); if ((status = cairo_surface_status (*in))) { cairo_test_log ("Failed to create transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } cairo_matrix_init_scale (&matrix, 0.5, 0.5); cairo_transform_surface_set_matrix (*in, &matrix); *out = cairo_transform_surface_create (); if ((status = cairo_surface_status (*out))) { cairo_test_log ("Failed to create transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } for (i = 0; i < 4; i++) { s[i] = cairo_transform_surface_create (); if ((status = cairo_surface_status (s[i]))) { cairo_test_log ("Failed to create transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } if ((status = cairo_transform_surface_insert_surface (*in, 0, s[i]))) { cairo_test_log ("Failed to insert transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } if ((status = cairo_transform_surface_insert_surface (s[i], 0, *out))) { cairo_test_log ("Failed to insert transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } for (j = 0; j < n; j++) pages[j] = 4 * j + i; cairo_transform_surface_set_pages (s[i], pages, n, 0); cairo_surface_destroy (s[i]); } cairo_matrix_init_translate (&matrix, WIDTH_IN_POINTS / 2., 0); cairo_transform_surface_set_matrix (s[1], &matrix); cairo_matrix_init_translate (&matrix, 0, HEIGHT_IN_POINTS / 2.); cairo_transform_surface_set_matrix (s[2], &matrix); cairo_matrix_init_translate (&matrix, WIDTH_IN_POINTS / 2., HEIGHT_IN_POINTS / 2.); cairo_transform_surface_set_matrix (s[3], &matrix); for (i = 0; i < n; i++) pages[i] = 4 * i + 3; cairo_transform_surface_set_pages (*out, pages, n, 1); cairo_surface_destroy (*out); return CAIRO_TEST_SUCCESS; } static cairo_test_status_t test_1_to_4 (cairo_surface_t **in, cairo_surface_t **out) { cairo_surface_t *s[4]; cairo_status_t status; cairo_matrix_t matrix; unsigned int i; *in = cairo_transform_surface_create (); if ((status = cairo_surface_status (*in))) { cairo_test_log ("Failed to create transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } cairo_matrix_init_scale (&matrix, 2., 2.); cairo_transform_surface_set_matrix (*in, &matrix); cairo_transform_surface_set_buffer (*in, 1); *out = cairo_transform_surface_create (); if ((status = cairo_surface_status (*out))) { cairo_test_log ("Failed to create transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } for (i = 0; i < 4; i++) { s[i] = cairo_transform_surface_create (); if ((status = cairo_surface_status (s[i]))) { cairo_test_log ("Failed to create transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } if ((status = cairo_transform_surface_insert_surface (*in, 0, s[i]))) { cairo_test_log ("Failed to insert transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } if ((status = cairo_transform_surface_insert_surface (s[i], 0, *out))) { cairo_test_log ("Failed to insert transform surface: %s\n", cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } cairo_surface_destroy (s[i]); } cairo_matrix_init_translate (&matrix, -WIDTH_IN_POINTS, 0); cairo_transform_surface_set_matrix (s[2], &matrix); cairo_matrix_init_translate (&matrix, 0, -HEIGHT_IN_POINTS); cairo_transform_surface_set_matrix (s[1], &matrix); cairo_matrix_init_translate (&matrix, -WIDTH_IN_POINTS, -HEIGHT_IN_POINTS); cairo_transform_surface_set_matrix (s[0], &matrix); cairo_surface_destroy (*out); return CAIRO_TEST_SUCCESS; } #endif int main (void) { cairo_surface_t *in, *out, *pdf_surface = NULL, *ps_surface = NULL; cairo_status_t status; cairo_test_status_t test_status; char *filename; #if CAIRO_HAS_PDF_SURFACE filename = "transform-surface.pdf"; pdf_surface = cairo_pdf_surface_create (filename, WIDTH_IN_POINTS, HEIGHT_IN_POINTS); status = cairo_surface_status (pdf_surface); if (status) { cairo_test_log ("Failed to create PDF surface for file %s: %s\n", filename, cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } #endif #if CAIRO_HAS_PS_SURFACE filename = "transform-surface.ps"; ps_surface = cairo_ps_surface_create (filename, WIDTH_IN_POINTS, HEIGHT_IN_POINTS); status = cairo_surface_status (ps_surface); if (status) { cairo_test_log ("Failed to create PostScript surface for file %s: %s\n", filename, cairo_status_to_string (status)); return CAIRO_TEST_FAILURE; } #endif #if CAIRO_HAS_TRANSFORM_SURFACE if ((test_status = test_plain (&in, &out))) return test_status; if (pdf_surface) { draw_title_page (pdf_surface, "Plain"); cairo_transform_surface_insert_surface (out, 0, pdf_surface); } if (ps_surface) { draw_title_page (ps_surface, "Plain"); cairo_transform_surface_insert_surface (out, 0, ps_surface); } draw_some_pages (in); cairo_surface_destroy (in); if ((test_status = test_reverse (&in, &out))) return test_status; if (pdf_surface) { draw_title_page (pdf_surface, "Reverse"); cairo_transform_surface_insert_surface (out, 0, pdf_surface); } if (ps_surface) { draw_title_page (ps_surface, "Reverse"); cairo_transform_surface_insert_surface (out, 0, ps_surface); } draw_some_pages (in); cairo_surface_destroy (in); if ((test_status = test_odd (&in, &out))) return test_status; if (pdf_surface) { draw_title_page (pdf_surface, "Odd pages"); cairo_transform_surface_insert_surface (out, 0, pdf_surface); } if (ps_surface) { draw_title_page (ps_surface, "Even pages"); cairo_transform_surface_insert_surface (out, 0, ps_surface); } draw_some_pages (in); cairo_surface_destroy (in); if ((test_status = test_4_to_1 (&in, &out))) return test_status; if (pdf_surface) { draw_title_page (pdf_surface, "4 pages on 1 page"); cairo_transform_surface_insert_surface (out, 0, pdf_surface); } if (ps_surface) { draw_title_page (ps_surface, "4 pages on 1 page"); cairo_transform_surface_insert_surface (out, 0, ps_surface); } draw_some_pages (in); cairo_surface_destroy (in); if ((test_status = test_1_to_4 (&in, &out))) return test_status; if (pdf_surface) { draw_title_page (pdf_surface, "1 page on 4 pages"); cairo_transform_surface_insert_surface (out, 0, pdf_surface); } if (ps_surface) { draw_title_page (ps_surface, "1 page on 4 pages"); cairo_transform_surface_insert_surface (out, 0, ps_surface); } draw_some_pages (in); cairo_surface_destroy (in); if (pdf_surface) cairo_surface_destroy (pdf_surface); if (ps_surface) cairo_surface_destroy (ps_surface); printf ("transform-surface.[pdf,ps]: Please check contents.\n"); #endif return CAIRO_TEST_SUCCESS; }