svg_status_t _svg_android_set_pattern (svg_android_t *svg_android, svg_element_t *pattern_element, svg_android_render_type_t type) { svg_pattern_t *pattern = svg_element_pattern (pattern_element); jobject pattern_bitmap; jobject pattern_shader; double x_px, y_px, width_px, height_px; jobject path; _svg_android_length_to_pixel (svg_android, &pattern->x, &x_px); _svg_android_length_to_pixel (svg_android, &pattern->y, &y_px); _svg_android_length_to_pixel (svg_android, &pattern->width, &width_px); _svg_android_length_to_pixel (svg_android, &pattern->height, &height_px); /* OK. We've got the final path to be filled/stroked inside the * android context right now. But we're also going to re-use that * same context to draw the pattern. And since the path is no * longer in the graphics state, android_save/restore will not help * us here. * * Currently we deal with this by manually saving/restoring the * path. * * It might be simpler to just use a new cairo_t for drawing the * pattern. */ path = svg_android->state->path; //cairo_copy_path (svg_android->cr); svg_android->state->path = ANDROID_PATH_CREATE(svg_android); // cairo_new_path (svg_android->cr); ANDROID_SAVE(svg_android); pattern_bitmap = ANDROID_CREATE_BITMAP(svg_android, (int) (width_px + 0.5), (int) (height_px + 0.5)); #if 0 pattern_surface = cairo_surface_create_similar (cairo_get_target (svg_android->cr), CAIRO_FORMAT_ARGB32, (int) (width_px + 0.5), (int) (height_px + 0.5)); #endif _svg_android_push_state (svg_android, pattern_bitmap); svg_android->state->matrix = ANDROID_IDENTITY_MATRIX(svg_android); //cairo_identity_matrix (svg_android->cr); svg_android->state->fill_paint.type = SVG_PAINT_TYPE_NONE; svg_android->state->stroke_paint.type = SVG_PAINT_TYPE_NONE; svg_element_render (pattern->group_element, &SVG_ANDROID_RENDER_ENGINE, svg_android); _svg_android_pop_state (svg_android); ANDROID_RESTORE(svg_android); svg_android->state->path = path ; #if 0 cairo_new_path (svg_android->cr); cairo_append_path (svg_android->cr, path); cairo_path_destroy (path); #endif pattern_shader = ANDROID_CREATE_BITMAP_SHADER(svg_android, pattern_bitmap); ANDROID_PAINT_SET_SHADER(svg_android, pattern_shader); #if 0 surface_pattern = cairo_pattern_create_for_surface (pattern_surface); cairo_surface_destroy (pattern_surface); cairo_pattern_set_extend (surface_pattern, CAIRO_EXTEND_REPEAT); cairo_set_source (svg_android->cr, surface_pattern); cairo_pattern_destroy (surface_pattern); #endif return SVG_STATUS_SUCCESS; }
static PyObject * pycairo_get_target (PycairoContext *o) { return PycairoSurface_FromSurface ( cairo_surface_reference (cairo_get_target (o->ctx)), NULL); }
void status_render(struct status *status, cairo_t *cairo) { cairo_font_extents_t exfont; cairo_text_extents_t extext; color_t color; double size; int width, height; const char *font; char *text; font = settings_get_string("status.font"); size = settings_get_double("status.font.size"); cairo_reset_clip(cairo); cairo_identity_matrix(cairo); cairo_select_font_face(cairo, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cairo, size); cairo_font_extents(cairo, &exfont); width = cairo_image_surface_get_width(cairo_get_target(cairo)); height = cairo_image_surface_get_height(cairo_get_target(cairo)); if (!settings_get_bool("status.transparent")) { color = settings_get_color("status.color"); cairo_set_source_rgb(cairo, color.r, color.g, color.b); cairo_rectangle(cairo, 0, height - exfont.height - 10, width, exfont.height + 10); cairo_fill(cairo); } color = settings_get_color("status.text.color"); cairo_set_source_rgb(cairo, color.r, color.g, color.b); cairo_text_extents(cairo, status->info, &extext); cairo_move_to(cairo, width - extext.x_advance - 5, height - exfont.descent - 5); cairo_show_text(cairo, status->info); cairo_rectangle(cairo, 0, height - exfont.height - 10, width - extext.x_advance - 10, exfont.height + 10); cairo_clip(cairo); if (status->is_error) { color = settings_get_color("status.error.color"); cairo_set_source_rgb(cairo, color.r, color.g, color.b); } cairo_move_to(cairo, 5, height - exfont.descent - 5); cairo_show_text(cairo, status->text); if (status->cursor_pos > -1) { text = xstrndup(status->text, (size_t)status->cursor_pos); cairo_text_extents(cairo, text, &extext); cairo_move_to(cairo, extext.x_advance + 5, height - exfont.descent - 5); cairo_show_text(cairo, "_"); free(text); } }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_surface_t *surface; cairo_t *cr2; cairo_rectangle_list_t *rectangle_list; const char *phase; cairo_bool_t uses_clip_rects; surface = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_COLOR, 100, 100); /* don't use cr accidentally */ cr = NULL; cr2 = cairo_create (surface); cairo_surface_destroy (surface); /* Check the surface type so we ignore cairo_copy_clip_rectangle_list failures * on surface types that don't use rectangle lists for clipping. * Default to FALSE for the internal surface types, (meta, test-fallback, etc.) */ switch (cairo_surface_get_type (surface)) { case CAIRO_SURFACE_TYPE_IMAGE: case CAIRO_SURFACE_TYPE_XLIB: case CAIRO_SURFACE_TYPE_XCB: case CAIRO_SURFACE_TYPE_GLITZ: case CAIRO_SURFACE_TYPE_WIN32: case CAIRO_SURFACE_TYPE_BEOS: case CAIRO_SURFACE_TYPE_DIRECTFB: uses_clip_rects = TRUE; break; case CAIRO_SURFACE_TYPE_QUARTZ: case CAIRO_SURFACE_TYPE_PDF: case CAIRO_SURFACE_TYPE_PS: case CAIRO_SURFACE_TYPE_SVG: case CAIRO_SURFACE_TYPE_OS2: default: uses_clip_rects = FALSE; break; } /* first, test basic stuff. This should not be clipped, it should return the surface rectangle. */ phase = "No clip set"; rectangle_list = cairo_copy_clip_rectangle_list (cr2); if (!check_count (phase, uses_clip_rects, rectangle_list, 1) || !check_clip_extents (phase, cr2, 0, 0, 100, 100) || !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 0, 0, 100, 100)) { cairo_rectangle_list_destroy (rectangle_list); return CAIRO_TEST_FAILURE; } cairo_rectangle_list_destroy (rectangle_list); /* Test simple clip rect. */ phase = "Simple clip rect"; cairo_save (cr2); cairo_rectangle (cr2, 10, 10, 80, 80); cairo_clip (cr2); rectangle_list = cairo_copy_clip_rectangle_list (cr2); if (!check_count (phase, uses_clip_rects, rectangle_list, 1) || !check_clip_extents (phase, cr2, 10, 10, 80, 80) || !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 10, 10, 80, 80)) { cairo_rectangle_list_destroy (rectangle_list); return CAIRO_TEST_FAILURE; } cairo_rectangle_list_destroy (rectangle_list); cairo_restore (cr2); /* Test everything clipped out. */ phase = "All clipped out"; cairo_save (cr2); cairo_clip (cr2); rectangle_list = cairo_copy_clip_rectangle_list (cr2); if (!check_count (phase, uses_clip_rects, rectangle_list, 0)) { cairo_rectangle_list_destroy (rectangle_list); return CAIRO_TEST_FAILURE; } cairo_rectangle_list_destroy (rectangle_list); cairo_restore (cr2); /* test two clip rects */ phase = "Two clip rects"; cairo_save (cr2); cairo_rectangle (cr2, 10, 10, 10, 10); cairo_rectangle (cr2, 20, 20, 10, 10); cairo_clip (cr2); cairo_rectangle (cr2, 15, 15, 10, 10); cairo_clip (cr2); rectangle_list = cairo_copy_clip_rectangle_list (cr2); if (!check_count (phase, uses_clip_rects, rectangle_list, 2) || !check_clip_extents (phase, cr2, 15, 15, 10, 10) || !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 15, 15, 5, 5) || !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 20, 20, 5, 5)) { cairo_rectangle_list_destroy (rectangle_list); return CAIRO_TEST_FAILURE; } cairo_rectangle_list_destroy (rectangle_list); cairo_restore (cr2); /* test non-rectangular clip */ phase = "Nonrectangular clip"; cairo_save (cr2); cairo_move_to (cr2, 0, 0); cairo_line_to (cr2, 100, 100); cairo_line_to (cr2, 100, 0); cairo_close_path (cr2); cairo_clip (cr2); rectangle_list = cairo_copy_clip_rectangle_list (cr2); /* can't get this in one tight user-space rectangle */ if (!check_unrepresentable (phase, rectangle_list) || !check_clip_extents (phase, cr2, 0, 0, 100, 100)) { cairo_rectangle_list_destroy (rectangle_list); return CAIRO_TEST_FAILURE; } cairo_rectangle_list_destroy (rectangle_list); cairo_restore (cr2); phase = "User space, simple scale, getting clip with same transform"; cairo_save (cr2); cairo_scale (cr2, 2, 2); cairo_rectangle (cr2, 5, 5, 40, 40); cairo_clip (cr2); rectangle_list = cairo_copy_clip_rectangle_list (cr2); if (!check_count (phase, uses_clip_rects, rectangle_list, 1) || !check_clip_extents (phase, cr2, 5, 5, 40, 40) || !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 5, 5, 40, 40)) { cairo_rectangle_list_destroy (rectangle_list); return CAIRO_TEST_FAILURE; } cairo_rectangle_list_destroy (rectangle_list); cairo_restore (cr2); phase = "User space, simple scale, getting clip with no transform"; cairo_save (cr2); cairo_save (cr2); cairo_scale (cr2, 2, 2); cairo_rectangle (cr2, 5, 5, 40, 40); cairo_restore (cr2); cairo_clip (cr2); rectangle_list = cairo_copy_clip_rectangle_list (cr2); if (!check_count (phase, uses_clip_rects, rectangle_list, 1) || !check_clip_extents (phase, cr2, 10, 10, 80, 80) || !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 10, 10, 80, 80)) { cairo_rectangle_list_destroy (rectangle_list); return CAIRO_TEST_FAILURE; } cairo_rectangle_list_destroy (rectangle_list); cairo_restore (cr2); phase = "User space, rotation, getting clip with no transform"; cairo_save (cr2); cairo_save (cr2); cairo_rotate (cr2, 12); cairo_rectangle (cr2, 5, 5, 40, 40); cairo_restore (cr2); cairo_clip (cr2); rectangle_list = cairo_copy_clip_rectangle_list (cr2); if (!check_unrepresentable (phase, rectangle_list)) { cairo_rectangle_list_destroy (rectangle_list); return CAIRO_TEST_FAILURE; } cairo_rectangle_list_destroy (rectangle_list); cairo_restore (cr2); cairo_destroy (cr2); return CAIRO_TEST_SUCCESS; }