void gfxContext::PushGroupAndCopyBackground(gfxASurface::gfxContentType content) { if (content == gfxASurface::CONTENT_COLOR_ALPHA && !(GetFlags() & FLAG_DISABLE_COPY_BACKGROUND)) { nsRefPtr<gfxASurface> s = CurrentSurface(); if ((s->GetAllowUseAsSource() || s->GetType() == gfxASurface::SurfaceTypeTee) && (s->GetContentType() == gfxASurface::CONTENT_COLOR || s->GetOpaqueRect().Contains(GetRoundOutDeviceClipExtents(this)))) { cairo_push_group_with_content(mCairo, CAIRO_CONTENT_COLOR); nsRefPtr<gfxASurface> d = CurrentSurface(); if (d->GetType() == gfxASurface::SurfaceTypeTee) { NS_ASSERTION(s->GetType() == gfxASurface::SurfaceTypeTee, "Mismatched types"); nsAutoTArray<nsRefPtr<gfxASurface>,2> ss; nsAutoTArray<nsRefPtr<gfxASurface>,2> ds; static_cast<gfxTeeSurface*>(s.get())->GetSurfaces(&ss); static_cast<gfxTeeSurface*>(d.get())->GetSurfaces(&ds); NS_ASSERTION(ss.Length() == ds.Length(), "Mismatched lengths"); gfxPoint translation = d->GetDeviceOffset() - s->GetDeviceOffset(); for (PRUint32 i = 0; i < ss.Length(); ++i) { CopySurface(ss[i], ds[i], translation); } } else { CopySurface(s, d, gfxPoint(0, 0)); } d->SetOpaqueRect(s->GetOpaqueRect()); return; } } cairo_push_group_with_content(mCairo, (cairo_content_t) content); }
static VALUE cr_push_group (int argc, VALUE *argv, VALUE self) { VALUE result = Qnil; VALUE content, pop_to_source; rb_scan_args (argc, argv, "02", &content, &pop_to_source); if (NIL_P(content)) cairo_push_group (_SELF); else cairo_push_group_with_content (_SELF, RVAL2CRCONTENT(content)); cr_check_status (_SELF); if (rb_block_given_p ()) { int state = 0; if (NIL_P (pop_to_source)) pop_to_source = Qtrue; result = rb_protect (rb_yield, self, &state); if (cairo_status(_SELF) == CAIRO_STATUS_SUCCESS) { if (RVAL2CBOOL (pop_to_source)) cr_pop_group_to_source (self); else result = cr_pop_group (self); } if (state) rb_jump_tag (state); } return result; }
static cairo_bool_t cairo_test_target_has_similar (const cairo_test_t *test, cairo_boilerplate_target_t *target) { cairo_surface_t *surface; cairo_bool_t has_similar = FALSE; /* ignore image intermediate targets */ if (target->expected_type == CAIRO_SURFACE_TYPE_IMAGE) return FALSE; if (getenv ("CAIRO_TEST_IGNORE_SIMILAR")) return FALSE; surface = (target->create_surface) (test->name, target->content, test->width, test->height, CAIRO_BOILERPLATE_MODE_TEST, &target->closure); if (surface != NULL) { cairo_t * cr = cairo_create (surface); cairo_surface_t *similar; cairo_push_group_with_content (cr, target->content); similar = cairo_get_group_target (cr); has_similar = cairo_surface_get_type (similar) == cairo_surface_get_type (surface); cairo_destroy (cr); cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (target->closure); } return has_similar; }
static int cairo_push_group_with_content_l( lua_State* L ) { lua_cairo_t* lc = lua_cairo_check( L, 1 ); cairo_push_group_with_content( lc->cairo, luaL_checkoption( L, 2, "color", cairo_content_lst ) ); return( 0 ); }
static int cr_push_group (lua_State *L) { cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT); cairo_content_t content = CAIRO_CONTENT_COLOR_ALPHA; if (!lua_isnoneornil(L, 2)) content = content_from_lua(L, 2); cairo_push_group_with_content(*obj, content); return 0; }
static PyObject * pycairo_push_group_with_content (PycairoContext *o, PyObject *args) { cairo_content_t content; if (!PyArg_ParseTuple(args, "i:Context.push_group_with_content", &content)) return NULL; cairo_push_group_with_content (o->ctx, content); RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); Py_RETURN_NONE; }
static cairo_test_status_t draw_func (cairo_t *cr, int width, int height) { cairo_rectangle_t region[4]; const cairo_test_context_t *ctx; int i, j; ctx = cairo_test_get_context (cr); cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR); draw (ctx, cr, NULL, 0); for (i = 0; i < NLOOPS; i++) { for (j = 0; j < NLOOPS; j++) { region[0].x = i * SIZE / NLOOPS; region[0].y = i * SIZE / NLOOPS; region[0].width = SIZE / 4; region[0].height = SIZE / 4; region[1].x = j * SIZE / NLOOPS; region[1].y = j * SIZE / NLOOPS; region[1].width = SIZE / 4; region[1].height = SIZE / 4; region[2].x = i * SIZE / NLOOPS; region[2].y = j * SIZE / NLOOPS; region[2].width = SIZE / 4; region[2].height = SIZE / 4; region[3].x = j * SIZE / NLOOPS; region[3].y = i * SIZE / NLOOPS; region[3].width = SIZE / 4; region[3].height = SIZE / 4; draw (ctx, cr, region, 4); } } cairo_pop_group_to_source (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); return CAIRO_TEST_SUCCESS; }
static void selection_render_mask (Selection *selection) { cairo_t *cr; cr = gdk_cairo_create (gtk_widget_get_window (selection->shell->canvas)); cairo_push_group_with_content (cr, CAIRO_CONTENT_ALPHA); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); cairo_set_line_width (cr, 1.0); gimp_cairo_add_segments (cr, selection->segs_in, selection->n_segs_in); cairo_stroke (cr); selection->segs_in_mask = cairo_pop_group (cr); cairo_destroy (cr); }
static cairo_test_status_t draw_with_extend (cairo_t *cr, int w, int h, cairo_extend_t extend) { cairo_pattern_t *pattern; cairo_set_source_rgb (cr, 1,1,1); cairo_paint (cr); cairo_save (cr); /* When the destination surface is created by cairo-test-suite to * test device-offset, it is bigger than w x h. This test expects * the group to have a size which is exactly w x h, so it must * clip to the this rectangle to guarantee that the group will * have the correct size. */ cairo_rectangle (cr, 0, 0, w, h); cairo_clip (cr); cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR); { /* A two by two checkerboard with black, red and yellow * cells. */ cairo_set_source_rgb (cr, 1,0,0); cairo_rectangle (cr, w/2, 0, w-w/2, h/2); cairo_fill (cr); cairo_set_source_rgb (cr, 1,1,0); cairo_rectangle (cr, 0, h/2, w/2, h-h/2); cairo_fill (cr); } pattern = cairo_pop_group (cr); cairo_pattern_set_extend(pattern, extend); cairo_restore (cr); cairo_scale (cr, 0.5, 0.5); cairo_set_source (cr, pattern); cairo_paint (cr); cairo_pattern_destroy (pattern); return CAIRO_TEST_SUCCESS; }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_pattern_t *gradient, *image; cairo_set_source_rgb (cr, 1,1,1); cairo_paint (cr); cairo_translate (cr, PAD, PAD); /* clip to the unit size */ cairo_rectangle (cr, 0, 0, UNIT_SIZE, UNIT_SIZE); cairo_clip (cr); cairo_rectangle (cr, 0, 0, UNIT_SIZE, UNIT_SIZE); cairo_set_source_rgba (cr, 0, 0, 0, 1); cairo_set_line_width (cr, 2); cairo_stroke (cr); /* start a group */ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR); /* draw a gradient background */ cairo_save (cr); cairo_translate (cr, INNER_PAD, INNER_PAD); cairo_new_path (cr); cairo_rectangle (cr, 0, 0, UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2)); gradient = cairo_pattern_create_linear (UNIT_SIZE - (INNER_PAD*2), 0, UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2)); cairo_pattern_add_color_stop_rgba (gradient, 0.0, 0.3, 0.3, 0.3, 1.0); cairo_pattern_add_color_stop_rgba (gradient, 1.0, 1.0, 1.0, 1.0, 1.0); cairo_set_source (cr, gradient); cairo_pattern_destroy (gradient); cairo_fill (cr); cairo_restore (cr); /* draw diamond */ cairo_move_to (cr, UNIT_SIZE / 2, 0); cairo_line_to (cr, UNIT_SIZE , UNIT_SIZE / 2); cairo_line_to (cr, UNIT_SIZE / 2, UNIT_SIZE); cairo_line_to (cr, 0 , UNIT_SIZE / 2); cairo_close_path (cr); cairo_set_source_rgba (cr, 0, 0, 1, 1); cairo_fill (cr); /* draw circle */ cairo_arc (cr, UNIT_SIZE / 2, UNIT_SIZE / 2, UNIT_SIZE / 3.5, 0, M_PI * 2); cairo_set_source_rgba (cr, 1, 0, 0, 1); cairo_fill (cr); /* and put the image on top */ cairo_translate (cr, UNIT_SIZE/2 - 8, UNIT_SIZE/2 - 8); image = argb32_source (); cairo_set_source (cr, image); cairo_pattern_destroy (image); cairo_paint (cr); cairo_pop_group_to_source (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); return CAIRO_TEST_SUCCESS; }
IoObject *IoCairoContext_pushGroupWithContent(IoCairoContext *self, IoObject *locals, IoMessage *m) { cairo_push_group_with_content(CONTEXT(self), IoMessage_locals_intArgAt_(m, locals, 0)); CHECK_STATUS(self); return self; }
/* adapted from pdf2png.c */ static const char * _poppler_render_page (const char *filename, const char *page_label, cairo_surface_t **surface_out) { PopplerDocument *document; PopplerPage *page; double width, height; GError *error = NULL; gchar *absolute, *uri; cairo_surface_t *surface; cairo_t *cr; cairo_status_t status; if (g_path_is_absolute (filename)) { absolute = g_strdup (filename); } else { gchar *dir = g_get_current_dir (); absolute = g_build_filename (dir, filename, (gchar *) 0); g_free (dir); } uri = g_filename_to_uri (absolute, NULL, &error); g_free (absolute); if (uri == NULL) return error->message; /* XXX g_error_free (error) */ document = poppler_document_new_from_file (uri, NULL, &error); g_free (uri); if (document == NULL) return error->message; /* XXX g_error_free (error) */ page = poppler_document_get_page_by_label (document, page_label); g_object_unref (document); if (page == NULL) return "page not found"; poppler_page_get_size (page, &width, &height); surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); cr = cairo_create (surface); cairo_set_source_rgb (cr, 1., 1., 1.); cairo_paint (cr); cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA); poppler_page_render (page, cr); g_object_unref (page); cairo_pop_group_to_source (cr); cairo_paint (cr); status = cairo_status (cr); cairo_destroy (cr); if (status) { cairo_surface_destroy (surface); return cairo_status_to_string (status); } *surface_out = surface; return NULL; }
void cairo_perf_run (cairo_perf_t *perf, const char *name, cairo_perf_func_t perf_func, cairo_count_func_t count_func) { static cairo_bool_t first_run = TRUE; unsigned int i, similar, has_similar; cairo_time_t *times; cairo_stats_t stats = {0.0, 0.0}; int low_std_dev_count; if (perf->list_only) { printf ("%s\n", name); return; } if (first_run) { if (perf->raw) { printf ("[ # ] %s.%-s %s %s %s ...\n", "backend", "content", "test-size", "ticks-per-ms", "time(ticks)"); } if (perf->summary) { fprintf (perf->summary, "[ # ] %8s.%-4s %28s %8s %8s %5s %5s %s %s\n", "backend", "content", "test-size", "min(ticks)", "min(ms)", "median(ms)", "stddev.", "iterations", "overhead"); } first_run = FALSE; } times = perf->times; if (getenv ("CAIRO_PERF_OUTPUT") != NULL) { /* check output */ char *filename; cairo_status_t status; xasprintf (&filename, "%s.%s.%s.%d.out.png", name, perf->target->name, _content_to_string (perf->target->content, 0), perf->size); cairo_save (perf->cr); perf_func (perf->cr, perf->size, perf->size, 1); cairo_restore (perf->cr); status = cairo_surface_write_to_png (cairo_get_target (perf->cr), filename); if (status) { fprintf (stderr, "Failed to generate output check '%s': %s\n", filename, cairo_status_to_string (status)); return; } free (filename); } has_similar = cairo_perf_has_similar (perf); for (similar = 0; similar <= has_similar; similar++) { unsigned loops; if (perf->summary) { fprintf (perf->summary, "[%3d] %8s.%-5s %26s.%-3d ", perf->test_number, perf->target->name, _content_to_string (perf->target->content, similar), name, perf->size); fflush (perf->summary); } /* We run one iteration in advance to warm caches and calibrate. */ cairo_perf_yield (); if (similar) cairo_push_group_with_content (perf->cr, cairo_boilerplate_content (perf->target->content)); else cairo_save (perf->cr); perf_func (perf->cr, perf->size, perf->size, 1); loops = cairo_perf_calibrate (perf, perf_func); if (similar) cairo_pattern_destroy (cairo_pop_group (perf->cr)); else cairo_restore (perf->cr); low_std_dev_count = 0; for (i =0; i < perf->iterations; i++) { cairo_perf_yield (); if (similar) cairo_push_group_with_content (perf->cr, cairo_boilerplate_content (perf->target->content)); else cairo_save (perf->cr); times[i] = perf_func (perf->cr, perf->size, perf->size, loops) ; if (similar) cairo_pattern_destroy (cairo_pop_group (perf->cr)); else cairo_restore (perf->cr); if (perf->raw) { if (i == 0) printf ("[*] %s.%s %s.%d %g", perf->target->name, _content_to_string (perf->target->content, similar), name, perf->size, _cairo_time_to_double (_cairo_time_from_s (1.)) / 1000.); printf (" %lld", (long long) (times[i] / (double) loops)); } else if (! perf->exact_iterations) { if (i > 0) { _cairo_stats_compute (&stats, times, i+1); if (stats.std_dev <= CAIRO_PERF_LOW_STD_DEV) { low_std_dev_count++; if (low_std_dev_count >= CAIRO_PERF_STABLE_STD_DEV_COUNT) break; } else { low_std_dev_count = 0; } } } } if (perf->raw) printf ("\n"); if (perf->summary) { _cairo_stats_compute (&stats, times, i); if (count_func != NULL) { double count = count_func (perf->cr, perf->size, perf->size); fprintf (perf->summary, "%.3f [%10lld/%d] %#8.3f %#8.3f %#5.2f%% %3d: %.2f\n", stats.min_ticks /(double) loops, (long long) stats.min_ticks, loops, _cairo_time_to_s (stats.min_ticks) * 1000.0 / loops, _cairo_time_to_s (stats.median_ticks) * 1000.0 / loops, stats.std_dev * 100.0, stats.iterations, count / _cairo_time_to_s (stats.min_ticks)); } else { fprintf (perf->summary, "%.3f [%10lld/%d] %#8.3f %#8.3f %#5.2f%% %3d\n", stats.min_ticks /(double) loops, (long long) stats.min_ticks, loops, _cairo_time_to_s (stats.min_ticks) * 1000.0 / loops, _cairo_time_to_s (stats.median_ticks) * 1000.0 / loops, stats.std_dev * 100.0, stats.iterations); } fflush (perf->summary); } perf->test_number++; } }
void CairoGroup::push_with_content(cairo_content_t content) { cairo_push_group_with_content(ct, content); pushed = true; }
static cairo_test_status_t cairo_test_for_target (cairo_test_t *test, cairo_boilerplate_target_t *target, int dev_offset, cairo_bool_t similar) { cairo_test_status_t status; cairo_surface_t *surface = NULL; cairo_t *cr; char *png_name, *ref_name, *diff_name, *offset_str; cairo_test_status_t ret = CAIRO_TEST_SUCCESS; cairo_content_t expected_content; cairo_font_options_t *font_options; const char *format; /* Get the strings ready that we'll need. */ format = cairo_boilerplate_content_name (target->content); if (dev_offset) xasprintf (&offset_str, "-%d", dev_offset); else offset_str = strdup(""); xasprintf (&png_name, "%s-%s-%s%s%s%s", test->name, target->name, format, similar ? "-similar" : "", offset_str, CAIRO_TEST_PNG_SUFFIX); ref_name = cairo_ref_name_for_test_target_format (test->name, target->name, format); xasprintf (&diff_name, "%s-%s-%s%s%s%s", test->name, target->name, format, similar ? "-similar" : "", offset_str, CAIRO_TEST_DIFF_SUFFIX); if (target->is_vector) { int i; for (i = 0; vector_ignored_tests[i] != NULL; i++) if (strcmp (test->name, vector_ignored_tests[i]) == 0) { cairo_test_log ("Error: Skipping for vector target %s\n", target->name); ret = CAIRO_TEST_UNTESTED; goto UNWIND_STRINGS; } } if (ret == CAIRO_TEST_SUCCESS) { /* Run the actual drawing code. */ if (test->width && test->height) { test->width += dev_offset; test->height += dev_offset; } surface = (target->create_surface) (test->name, target->content, test->width, test->height, CAIRO_BOILERPLATE_MODE_TEST, &target->closure); if (test->width && test->height) { test->width -= dev_offset; test->height -= dev_offset;; } } if (surface == NULL) { cairo_test_log ("Error: Failed to set %s target\n", target->name); ret = CAIRO_TEST_UNTESTED; goto UNWIND_STRINGS; } /* Check that we created a surface of the expected type. */ if (cairo_surface_get_type (surface) != target->expected_type) { cairo_test_log ("Error: Created surface is of type %d (expected %d)\n", cairo_surface_get_type (surface), target->expected_type); ret = CAIRO_TEST_FAILURE; goto UNWIND_SURFACE; } /* Check that we created a surface of the expected content, * (ignore the articifical * CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED value). */ expected_content = target->content; if (expected_content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) expected_content = CAIRO_CONTENT_COLOR_ALPHA; if (cairo_surface_get_content (surface) != expected_content) { cairo_test_log ("Error: Created surface has content %d (expected %d)\n", cairo_surface_get_content (surface), expected_content); ret = CAIRO_TEST_FAILURE; goto UNWIND_SURFACE; } cairo_surface_set_device_offset (surface, dev_offset, dev_offset); cr = cairo_create (surface); if (similar) cairo_push_group_with_content (cr, target->content); /* Clear to transparent (or black) depending on whether the target * surface supports alpha. */ cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_restore (cr); /* Set all components of font_options to avoid backend differences * and reduce number of needed reference images. */ font_options = cairo_font_options_create (); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY); cairo_set_font_options (cr, font_options); cairo_font_options_destroy (font_options); cairo_save (cr); status = (test->draw) (cr, test->width, test->height); cairo_restore (cr); /* Then, check all the different ways it could fail. */ if (status) { cairo_test_log ("Error: Function under test failed\n"); ret = status; goto UNWIND_CAIRO; } if (similar) { cairo_pop_group_to_source (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); } if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_test_log ("Error: Function under test left cairo status in an error state: %s\n", cairo_status_to_string (cairo_status (cr))); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } /* Skip image check for tests with no image (width,height == 0,0) */ if (test->width != 0 && test->height != 0) { buffer_diff_result_t result; cairo_status_t diff_status; xunlink (png_name); (target->write_to_png) (surface, png_name); cairo_test_log ("OUTPUT: %s\n", png_name); if (!ref_name) { cairo_test_log ("Error: Cannot find reference image for %s/%s-%s-%s%s\n",srcdir, test->name, target->name, format, CAIRO_TEST_REF_SUFFIX); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } cairo_test_log ("REFERENCE: %s\n", ref_name); cairo_test_log ("DIFFERENCE: %s\n", diff_name); if (target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) { diff_status= image_diff_flattened (png_name, ref_name, diff_name, dev_offset, dev_offset, 0, 0, &result); } else { diff_status = image_diff (png_name, ref_name, diff_name, dev_offset, dev_offset, 0, 0, &result); } if (diff_status) { cairo_test_log ("Error: Failed to compare images: %s\n", cairo_status_to_string (diff_status)); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } if (result.pixels_changed && result.max_diff > target->error_tolerance) { ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } } UNWIND_CAIRO: cairo_destroy (cr); UNWIND_SURFACE: cairo_surface_destroy (surface); cairo_debug_reset_static_data (); if (target->cleanup) target->cleanup (target->closure); UNWIND_STRINGS: if (png_name) free (png_name); if (ref_name) free (ref_name); if (diff_name) free (diff_name); if (offset_str) free (offset_str); return ret; }
void cairo_perf_run (cairo_perf_t *perf, const char *name, cairo_perf_func_t perf_func) { static cairo_bool_t first_run = TRUE; unsigned int i, similar, has_similar; cairo_perf_ticks_t *times; cairo_stats_t stats = {0.0, 0.0}; int low_std_dev_count; if (perf->list_only) { printf ("%s\n", name); return; } if (first_run) { if (perf->raw) printf ("[ # ] %s-%-s %s %s %s ...\n", "backend", "content", "test-size", "ticks-per-ms", "time(ticks)"); else printf ("[ # ] %8s-%-4s %28s %8s %8s %5s %5s %s\n", "backend", "content", "test-size", "min(ticks)", "min(ms)", "median(ms)", "stddev.", "iterations"); first_run = FALSE; } times = perf->times; has_similar = cairo_perf_has_similar (perf); for (similar = 0; similar <= has_similar; similar++) { /* We run one iteration in advance to warm caches, etc. */ cairo_perf_yield (); if (similar) cairo_push_group_with_content (perf->cr, cairo_boilerplate_content (perf->target->content)); (perf_func) (perf->cr, perf->size, perf->size); if (similar) cairo_pattern_destroy (cairo_pop_group (perf->cr)); low_std_dev_count = 0; for (i =0; i < perf->iterations; i++) { cairo_perf_yield (); if (similar) cairo_push_group_with_content (perf->cr, cairo_boilerplate_content (perf->target->content)); times[i] = (perf_func) (perf->cr, perf->size, perf->size); if (similar) cairo_pattern_destroy (cairo_pop_group (perf->cr)); if (perf->raw) { if (i == 0) printf ("[*] %s-%s %s-%d %g", perf->target->name, _content_to_string (perf->target->content, similar), name, perf->size, cairo_perf_ticks_per_second () / 1000.0); printf (" %lld", (long long) times[i]); } else if (! perf->exact_iterations) { if (i > 0) { _cairo_stats_compute (&stats, times, i+1); if (stats.std_dev <= CAIRO_PERF_LOW_STD_DEV) { low_std_dev_count++; if (low_std_dev_count >= CAIRO_PERF_STABLE_STD_DEV_COUNT) break; } else { low_std_dev_count = 0; } } } } if (perf->raw) { printf ("\n"); } else { _cairo_stats_compute (&stats, times, i); printf ("[%3d] %8s-%-5s %26s-%-3d ", perf->test_number, perf->target->name, _content_to_string (perf->target->content, similar), name, perf->size); printf ("%10lld %#8.3f %#8.3f %#5.2f%% %3d\n", (long long) stats.min_ticks, (stats.min_ticks * 1000.0) / cairo_perf_ticks_per_second (), (stats.median_ticks * 1000.0) / cairo_perf_ticks_per_second (), stats.std_dev * 100.0, stats.iterations); } perf->test_number++; } }
void Context::pushGroupWithContent( int32_t content ) { cairo_push_group_with_content( mCairo, static_cast<cairo_content_t>( content ) ); }
cairo_test_similar_t cairo_test_target_has_similar (const cairo_test_context_t *ctx, const cairo_boilerplate_target_t *target) { cairo_surface_t *surface; cairo_test_similar_t has_similar; cairo_t * cr; cairo_surface_t *similar; cairo_status_t status; void *closure; char *path; /* ignore image intermediate targets */ if (target->expected_type == CAIRO_SURFACE_TYPE_IMAGE) return DIRECT; if (getenv ("CAIRO_TEST_IGNORE_SIMILAR")) return DIRECT; xasprintf (&path, "%s/%s", _cairo_test_mkdir (ctx->output) ? ctx->output : ".", ctx->test_name); has_similar = DIRECT; do { do { surface = (target->create_surface) (path, target->content, ctx->test->width, ctx->test->height, ctx->test->width + 25 * NUM_DEVICE_OFFSETS, ctx->test->height + 25 * NUM_DEVICE_OFFSETS, CAIRO_BOILERPLATE_MODE_TEST, &closure); if (surface == NULL) goto out; } while (cairo_test_malloc_failure (ctx, cairo_surface_status (surface))); if (cairo_surface_status (surface)) goto out; cr = cairo_create (surface); cairo_push_group_with_content (cr, cairo_boilerplate_content (target->content)); similar = cairo_get_group_target (cr); status = cairo_surface_status (similar); if (cairo_surface_get_type (similar) == cairo_surface_get_type (surface)) has_similar = SIMILAR; else has_similar = DIRECT; cairo_destroy (cr); cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); } while (! has_similar && cairo_test_malloc_failure (ctx, status)); out: free (path); return has_similar; }
void lime_cairo_push_group_with_content (double handle, int content) { cairo_push_group_with_content ((cairo_t*)(intptr_t)handle, (cairo_content_t)content); }
static cairo_test_status_t cairo_test_for_target (cairo_test_context_t *ctx, const cairo_boilerplate_target_t *target, int dev_offset, cairo_bool_t similar) { cairo_test_status_t status; cairo_surface_t *surface = NULL; cairo_t *cr; const char *empty_str = ""; char *offset_str; char *base_name, *base_path; char *out_png_path; char *ref_path = NULL, *ref_png_path, *cmp_png_path = NULL; char *new_path = NULL, *new_png_path; char *xfail_path = NULL, *xfail_png_path; char *base_ref_png_path; char *base_new_png_path; char *base_xfail_png_path; char *diff_png_path; char *test_filename = NULL, *pass_filename = NULL, *fail_filename = NULL; cairo_test_status_t ret; cairo_content_t expected_content; cairo_font_options_t *font_options; const char *format; cairo_bool_t have_output = FALSE; cairo_bool_t have_result = FALSE; void *closure; double width, height; cairo_bool_t have_output_dir; #if HAVE_MEMFAULT int malloc_failure_iterations = ctx->malloc_failure; int last_fault_count = 0; #endif /* Get the strings ready that we'll need. */ format = cairo_boilerplate_content_name (target->content); if (dev_offset) xasprintf (&offset_str, ".%d", dev_offset); else offset_str = (char *) empty_str; xasprintf (&base_name, "%s.%s.%s%s%s", ctx->test_name, target->name, format, similar ? ".similar" : "", offset_str); if (offset_str != empty_str) free (offset_str); ref_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_REF_SUFFIX, CAIRO_TEST_PNG_EXTENSION); new_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_NEW_SUFFIX, CAIRO_TEST_PNG_EXTENSION); xfail_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_XFAIL_SUFFIX, CAIRO_TEST_PNG_EXTENSION); base_ref_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, NULL, NULL, format, CAIRO_TEST_REF_SUFFIX, CAIRO_TEST_PNG_EXTENSION); base_new_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, NULL, NULL, format, CAIRO_TEST_NEW_SUFFIX, CAIRO_TEST_PNG_EXTENSION); base_xfail_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, NULL, NULL, format, CAIRO_TEST_XFAIL_SUFFIX, CAIRO_TEST_PNG_EXTENSION); if (target->file_extension != NULL) { ref_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_REF_SUFFIX, target->file_extension); new_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_NEW_SUFFIX, target->file_extension); xfail_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_XFAIL_SUFFIX, target->file_extension); } have_output_dir = _cairo_test_mkdir (ctx->output); xasprintf (&base_path, "%s/%s", have_output_dir ? ctx->output : ".", base_name); xasprintf (&out_png_path, "%s" CAIRO_TEST_OUT_PNG, base_path); xasprintf (&diff_png_path, "%s" CAIRO_TEST_DIFF_PNG, base_path); if (ctx->test->requirements != NULL) { const char *required; required = target->is_vector ? "target=raster" : "target=vector"; if (strstr (ctx->test->requirements, required) != NULL) { cairo_test_log (ctx, "Error: Skipping for %s target %s\n", target->is_vector ? "vector" : "raster", target->name); ret = CAIRO_TEST_UNTESTED; goto UNWIND_STRINGS; } required = target->is_recording ? "target=!recording" : "target=recording"; if (strstr (ctx->test->requirements, required) != NULL) { cairo_test_log (ctx, "Error: Skipping for %s target %s\n", target->is_recording ? "recording" : "non-recording", target->name); ret = CAIRO_TEST_UNTESTED; goto UNWIND_STRINGS; } } width = ctx->test->width; height = ctx->test->height; if (width && height) { width += dev_offset; height += dev_offset; } #if HAVE_MEMFAULT REPEAT: MEMFAULT_CLEAR_FAULTS (); MEMFAULT_RESET_LEAKS (); ctx->last_fault_count = 0; last_fault_count = MEMFAULT_COUNT_FAULTS (); /* Pre-initialise fontconfig so that the configuration is loaded without * malloc failures (our primary goal is to test cairo fault tolerance). */ #if HAVE_FCINIT FcInit (); #endif MEMFAULT_ENABLE_FAULTS (); #endif have_output = FALSE; have_result = FALSE; /* Run the actual drawing code. */ ret = CAIRO_TEST_SUCCESS; surface = (target->create_surface) (base_path, target->content, width, height, ctx->test->width + 25 * NUM_DEVICE_OFFSETS, ctx->test->height + 25 * NUM_DEVICE_OFFSETS, CAIRO_BOILERPLATE_MODE_TEST, &closure); if (surface == NULL) { cairo_test_log (ctx, "Error: Failed to set %s target\n", target->name); ret = CAIRO_TEST_UNTESTED; goto UNWIND_STRINGS; } #if HAVE_MEMFAULT if (ctx->malloc_failure && MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY) { goto REPEAT; } #endif if (cairo_surface_status (surface)) { MF (MEMFAULT_PRINT_FAULTS ()); cairo_test_log (ctx, "Error: Created an error surface: %s\n", cairo_status_to_string (cairo_surface_status (surface))); ret = CAIRO_TEST_FAILURE; goto UNWIND_STRINGS; } /* Check that we created a surface of the expected type. */ if (cairo_surface_get_type (surface) != target->expected_type) { MF (MEMFAULT_PRINT_FAULTS ()); cairo_test_log (ctx, "Error: Created surface is of type %d (expected %d)\n", cairo_surface_get_type (surface), target->expected_type); ret = CAIRO_TEST_UNTESTED; goto UNWIND_SURFACE; } /* Check that we created a surface of the expected content, * (ignore the artificial CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED value). */ expected_content = cairo_boilerplate_content (target->content); if (cairo_surface_get_content (surface) != expected_content) { MF (MEMFAULT_PRINT_FAULTS ()); cairo_test_log (ctx, "Error: Created surface has content %d (expected %d)\n", cairo_surface_get_content (surface), expected_content); ret = CAIRO_TEST_FAILURE; goto UNWIND_SURFACE; } if (cairo_surface_set_user_data (surface, &cairo_boilerplate_output_basename_key, base_path, NULL)) { #if HAVE_MEMFAULT cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); goto REPEAT; #else ret = CAIRO_TEST_FAILURE; goto UNWIND_SURFACE; #endif } cairo_surface_set_device_offset (surface, dev_offset, dev_offset); cr = cairo_create (surface); if (cairo_set_user_data (cr, &_cairo_test_context_key, (void*) ctx, NULL)) { #if HAVE_MEMFAULT cairo_destroy (cr); cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); goto REPEAT; #else ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; #endif } if (similar) cairo_push_group_with_content (cr, expected_content); /* Clear to transparent (or black) depending on whether the target * surface supports alpha. */ cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_restore (cr); /* Set all components of font_options to avoid backend differences * and reduce number of needed reference images. */ font_options = cairo_font_options_create (); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY); cairo_set_font_options (cr, font_options); cairo_font_options_destroy (font_options); cairo_save (cr); alarm (ctx->timeout); status = (ctx->test->draw) (cr, ctx->test->width, ctx->test->height); alarm (0); cairo_restore (cr); if (similar) { cairo_pop_group_to_source (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); } #if HAVE_MEMFAULT MEMFAULT_DISABLE_FAULTS (); /* repeat test after malloc failure injection */ if (ctx->malloc_failure && MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && (status == CAIRO_TEST_NO_MEMORY || cairo_status (cr) == CAIRO_STATUS_NO_MEMORY || cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY)) { cairo_destroy (cr); cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); cairo_debug_reset_static_data (); #if HAVE_FCFINI FcFini (); #endif if (MEMFAULT_COUNT_LEAKS () > 0) { MEMFAULT_PRINT_FAULTS (); MEMFAULT_PRINT_LEAKS (); } goto REPEAT; } #endif /* Then, check all the different ways it could fail. */ if (status) { cairo_test_log (ctx, "Error: Function under test failed\n"); ret = status; goto UNWIND_CAIRO; } #if HAVE_MEMFAULT if (MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && MEMFAULT_HAS_FAULTS ()) { VALGRIND_PRINTF ("Unreported memfaults..."); MEMFAULT_PRINT_FAULTS (); } #endif if (target->finish_surface != NULL) { #if HAVE_MEMFAULT /* We need to re-enable faults as most recording-surface processing * is done during cairo_surface_finish(). */ MEMFAULT_CLEAR_FAULTS (); last_fault_count = MEMFAULT_COUNT_FAULTS (); MEMFAULT_ENABLE_FAULTS (); #endif /* also check for infinite loops whilst replaying */ alarm (ctx->timeout); status = target->finish_surface (surface); alarm (0); #if HAVE_MEMFAULT MEMFAULT_DISABLE_FAULTS (); if (ctx->malloc_failure && MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && status == CAIRO_STATUS_NO_MEMORY) { cairo_destroy (cr); cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); cairo_debug_reset_static_data (); #if HAVE_FCFINI FcFini (); #endif if (MEMFAULT_COUNT_LEAKS () > 0) { MEMFAULT_PRINT_FAULTS (); MEMFAULT_PRINT_LEAKS (); } goto REPEAT; } #endif if (status) { cairo_test_log (ctx, "Error: Failed to finish surface: %s\n", cairo_status_to_string (status)); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } } /* Skip image check for tests with no image (width,height == 0,0) */ if (ctx->test->width != 0 && ctx->test->height != 0) { cairo_surface_t *ref_image; cairo_surface_t *test_image; cairo_surface_t *diff_image; buffer_diff_result_t result; cairo_status_t diff_status; if (ref_png_path == NULL) { cairo_test_log (ctx, "Error: Cannot find reference image for %s\n", base_name); /* we may be running this test to generate reference images */ _xunlink (ctx, out_png_path); /* be more generous as we may need to use external renderers */ alarm (4 * ctx->timeout); test_image = target->get_image_surface (surface, 0, ctx->test->width, ctx->test->height); alarm (0); diff_status = cairo_surface_write_to_png (test_image, out_png_path); cairo_surface_destroy (test_image); if (diff_status) { if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS) ret = CAIRO_TEST_CRASHED; else ret = CAIRO_TEST_FAILURE; cairo_test_log (ctx, "Error: Failed to write output image: %s\n", cairo_status_to_string (diff_status)); } have_output = TRUE; ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } if (target->file_extension != NULL) { /* compare vector surfaces */ char *filenames[] = { ref_png_path, ref_path, new_png_path, new_path, xfail_png_path, xfail_path, base_ref_png_path, base_new_png_path, base_xfail_png_path, }; xasprintf (&test_filename, "%s.out%s", base_path, target->file_extension); xasprintf (&pass_filename, "%s.pass%s", base_path, target->file_extension); xasprintf (&fail_filename, "%s.fail%s", base_path, target->file_extension); if (cairo_test_file_is_older (pass_filename, filenames, ARRAY_SIZE (filenames))) { _xunlink (ctx, pass_filename); } if (cairo_test_file_is_older (fail_filename, filenames, ARRAY_SIZE (filenames))) { _xunlink (ctx, fail_filename); } if (cairo_test_files_equal (out_png_path, ref_path)) { cairo_test_log (ctx, "Vector surface matches reference.\n"); have_output = FALSE; ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, new_path)) { cairo_test_log (ctx, "Vector surface matches current failure.\n"); have_output = FALSE; ret = CAIRO_TEST_NEW; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, xfail_path)) { cairo_test_log (ctx, "Vector surface matches known failure.\n"); have_output = FALSE; ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } if (cairo_test_files_equal (test_filename, pass_filename)) { /* identical output as last known PASS */ cairo_test_log (ctx, "Vector surface matches last pass.\n"); have_output = TRUE; ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (test_filename, fail_filename)) { /* identical output as last known FAIL, fail */ cairo_test_log (ctx, "Vector surface matches last fail.\n"); have_result = TRUE; /* presume these were kept around as well */ have_output = TRUE; ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } } /* be more generous as we may need to use external renderers */ alarm (4 * ctx->timeout); test_image = target->get_image_surface (surface, 0, ctx->test->width, ctx->test->height); alarm (0); if (cairo_surface_status (test_image)) { cairo_test_log (ctx, "Error: Failed to extract image: %s\n", cairo_status_to_string (cairo_surface_status (test_image))); if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS) ret = CAIRO_TEST_CRASHED; else ret = CAIRO_TEST_FAILURE; cairo_surface_destroy (test_image); goto UNWIND_CAIRO; } _xunlink (ctx, out_png_path); diff_status = cairo_surface_write_to_png (test_image, out_png_path); if (diff_status) { cairo_test_log (ctx, "Error: Failed to write output image: %s\n", cairo_status_to_string (diff_status)); cairo_surface_destroy (test_image); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } have_output = TRUE; /* binary compare png files (no decompression) */ if (target->file_extension == NULL) { char *filenames[] = { ref_png_path, new_png_path, xfail_png_path, base_ref_png_path, base_new_png_path, base_xfail_png_path, }; xasprintf (&test_filename, "%s", out_png_path); xasprintf (&pass_filename, "%s.pass.png", base_path); xasprintf (&fail_filename, "%s.fail.png", base_path); if (cairo_test_file_is_older (pass_filename, filenames, ARRAY_SIZE (filenames))) { _xunlink (ctx, pass_filename); } if (cairo_test_file_is_older (fail_filename, filenames, ARRAY_SIZE (filenames))) { _xunlink (ctx, fail_filename); } if (cairo_test_files_equal (test_filename, pass_filename)) { cairo_test_log (ctx, "PNG file exactly matches last pass.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, ref_png_path)) { cairo_test_log (ctx, "PNG file exactly matches reference image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, new_png_path)) { cairo_test_log (ctx, "PNG file exactly matches current failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_NEW; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, xfail_png_path)) { cairo_test_log (ctx, "PNG file exactly matches known failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } if (cairo_test_files_equal (test_filename, fail_filename)) { cairo_test_log (ctx, "PNG file exactly matches last fail.\n"); have_result = TRUE; /* presume these were kept around as well */ cairo_surface_destroy (test_image); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } } else { if (cairo_test_files_equal (out_png_path, ref_png_path)) { cairo_test_log (ctx, "PNG file exactly matches reference image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, new_png_path)) { cairo_test_log (ctx, "PNG file exactly matches current failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_NEW; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, xfail_png_path)) { cairo_test_log (ctx, "PNG file exactly matches known failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } } if (cairo_test_files_equal (out_png_path, base_ref_png_path)) { cairo_test_log (ctx, "PNG file exactly reference image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, base_new_png_path)) { cairo_test_log (ctx, "PNG file exactly current failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_NEW; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, base_xfail_png_path)) { cairo_test_log (ctx, "PNG file exactly known failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } /* first compare against the ideal reference */ ref_image = cairo_test_get_reference_image (ctx, base_ref_png_path, target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED); if (cairo_surface_status (ref_image)) { cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n", base_ref_png_path, cairo_status_to_string (cairo_surface_status (ref_image))); cairo_surface_destroy (test_image); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } diff_image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ctx->test->width, ctx->test->height); cmp_png_path = base_ref_png_path; diff_status = image_diff (ctx, test_image, ref_image, diff_image, &result); _xunlink (ctx, diff_png_path); if (diff_status || image_diff_is_failure (&result, target->error_tolerance)) { /* that failed, so check against the specific backend */ ref_image = cairo_test_get_reference_image (ctx, ref_png_path, target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED); if (cairo_surface_status (ref_image)) { cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n", ref_png_path, cairo_status_to_string (cairo_surface_status (ref_image))); cairo_surface_destroy (test_image); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } cmp_png_path = ref_png_path; diff_status = image_diff (ctx, test_image, ref_image, diff_image, &result); if (diff_status) { cairo_test_log (ctx, "Error: Failed to compare images: %s\n", cairo_status_to_string (diff_status)); ret = CAIRO_TEST_FAILURE; } else if (image_diff_is_failure (&result, target->error_tolerance)) { ret = CAIRO_TEST_FAILURE; diff_status = cairo_surface_write_to_png (diff_image, diff_png_path); if (diff_status) { cairo_test_log (ctx, "Error: Failed to write differences image: %s\n", cairo_status_to_string (diff_status)); } else { have_result = TRUE; } cairo_test_copy_file (test_filename, fail_filename); } else { /* success */ cairo_test_copy_file (test_filename, pass_filename); } } else { /* success */ cairo_test_copy_file (test_filename, pass_filename); } /* If failed, compare against the current image output, * and attempt to detect systematic failures. */ if (ret == CAIRO_TEST_FAILURE) { char *image_out_path; image_out_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, "image", "image", format, CAIRO_TEST_OUT_SUFFIX, CAIRO_TEST_PNG_EXTENSION); if (image_out_path != NULL) { if (cairo_test_files_equal (out_png_path, image_out_path)) { ret = CAIRO_TEST_XFAILURE; } else { ref_image = cairo_image_surface_create_from_png (image_out_path); if (cairo_surface_status (ref_image) == CAIRO_STATUS_SUCCESS) { diff_status = image_diff (ctx, test_image, ref_image, diff_image, &result); if (diff_status == CAIRO_STATUS_SUCCESS && !image_diff_is_failure (&result, target->error_tolerance)) { ret = CAIRO_TEST_XFAILURE; } cairo_surface_destroy (ref_image); } } free (image_out_path); } } cairo_surface_destroy (test_image); cairo_surface_destroy (diff_image); } if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_test_log (ctx, "Error: Function under test left cairo status in an error state: %s\n", cairo_status_to_string (cairo_status (cr))); ret = CAIRO_TEST_ERROR; goto UNWIND_CAIRO; } UNWIND_CAIRO: free (test_filename); free (fail_filename); free (pass_filename); test_filename = fail_filename = pass_filename = NULL; #if HAVE_MEMFAULT if (ret == CAIRO_TEST_FAILURE) MEMFAULT_PRINT_FAULTS (); #endif cairo_destroy (cr); UNWIND_SURFACE: cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); #if HAVE_MEMFAULT cairo_debug_reset_static_data (); #if HAVE_FCFINI FcFini (); #endif if (MEMFAULT_COUNT_LEAKS () > 0) { if (ret != CAIRO_TEST_FAILURE) MEMFAULT_PRINT_FAULTS (); MEMFAULT_PRINT_LEAKS (); } if (ret == CAIRO_TEST_SUCCESS && --malloc_failure_iterations > 0) goto REPEAT; #endif if (have_output) cairo_test_log (ctx, "OUTPUT: %s\n", out_png_path); if (have_result) { if (cmp_png_path == NULL) { /* XXX presume we matched the normal ref last time */ cmp_png_path = ref_png_path; } cairo_test_log (ctx, "REFERENCE: %s\nDIFFERENCE: %s\n", cmp_png_path, diff_png_path); } UNWIND_STRINGS: free (out_png_path); free (ref_png_path); free (base_ref_png_path); free (ref_path); free (new_png_path); free (base_new_png_path); free (new_path); free (xfail_png_path); free (base_xfail_png_path); free (xfail_path); free (diff_png_path); free (base_path); free (base_name); return ret; }
void lime_cairo_push_group_with_content (value handle, int content) { cairo_push_group_with_content ((cairo_t*)val_data (handle), (cairo_content_t)content); }
void gfxContext::PushGroup(gfxASurface::gfxContentType content) { cairo_push_group_with_content(mCairo, (cairo_content_t) content); }