/** * cairo_win32_surface_get_dc: * @surface: a #cairo_surface_t * * Returns the HDC associated with this surface, or %NULL if none. * Also returns %NULL if the surface is not a win32 surface. * * A call to cairo_surface_flush() is required before using the HDC to * ensure that all pending drawing operations are finished and to * restore any temporary modification cairo has made to its state. A * call to cairo_surface_mark_dirty() is required after the state or * the content of the HDC has been modified. * * Return value: HDC or %NULL if no HDC available. * * Since: 1.2 **/ HDC cairo_win32_surface_get_dc (cairo_surface_t *surface) { if (surface->backend->type == CAIRO_SURFACE_TYPE_WIN32) return to_win32_surface(surface)->dc; if (_cairo_surface_is_paginated (surface)) { cairo_surface_t *target = _cairo_paginated_surface_get_target (surface); if (target->backend->type == CAIRO_SURFACE_TYPE_WIN32_PRINTING) return to_win32_surface(target)->dc; } return NULL; }
static cairo_int_status_t _cairo_win32_display_surface_unmap_image (void *abstract_surface, cairo_image_surface_t *image) { cairo_win32_display_surface_t *surface = abstract_surface; /* Delay the download until the next flush, which means we also need * to make sure our sources rare flushed. */ TRACE ((stderr, "%s (surface=%d)\n", __FUNCTION__, to_win32_surface(surface)->base.unique_id)); if (surface->fallback) { cairo_rectangle_int_t r; r.x = image->base.device_transform_inverse.x0; r.y = image->base.device_transform_inverse.y0; r.width = image->width; r.height = image->height; TRACE ((stderr, "%s: adding damage (%d,%d)x(%d,%d)\n", __FUNCTION__, r.x, r.y, r.width, r.height)); surface->fallback->damage = _cairo_damage_add_rectangle (surface->fallback->damage, &r); surface = to_win32_display_surface (surface->fallback); } return _cairo_surface_unmap_image (surface->image, image); }
static cairo_status_t copy_boxes (cairo_win32_display_surface_t *dst, const cairo_pattern_t *source, cairo_boxes_t *boxes) { const cairo_surface_pattern_t *pattern; struct copy_box cb; cairo_surface_t *surface; cairo_status_t status; cairo_win32_surface_t *src; TRACE ((stderr, "%s\n", __FUNCTION__)); pattern = (const cairo_surface_pattern_t *) source; surface = _cairo_surface_get_source (pattern->surface, &cb.limit); if (surface->type == CAIRO_SURFACE_TYPE_IMAGE) { surface = to_image_surface(surface)->parent; if (surface == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; } if (surface->type != CAIRO_SURFACE_TYPE_WIN32) return CAIRO_INT_STATUS_UNSUPPORTED; if (! _cairo_matrix_is_integer_translation (&source->matrix, &cb.tx, &cb.ty)) return CAIRO_INT_STATUS_UNSUPPORTED; src = to_win32_surface(surface); if (src->format != dst->win32.format && !(src->format == CAIRO_FORMAT_ARGB32 && dst->win32.format == CAIRO_FORMAT_RGB24)) { /* forbid copy different surfaces unless it is from argb32 to * rgb (dropping alpha) */ return CAIRO_INT_STATUS_UNSUPPORTED; } cb.dst = dst->win32.dc; cb.src = src->dc; /* First check that the data is entirely within the image */ if (! _cairo_boxes_for_each_box (boxes, source_contains_box, &cb)) return CAIRO_INT_STATUS_UNSUPPORTED; status = __cairo_surface_flush (surface, 0); if (status) return status; cb.tx += cb.limit.x; cb.ty += cb.limit.y; status = CAIRO_STATUS_SUCCESS; if (! _cairo_boxes_for_each_box (boxes, copy_box, &cb)) status = CAIRO_INT_STATUS_UNSUPPORTED; _cairo_win32_display_surface_discard_fallback (dst); return status; }
static cairo_image_surface_t * _cairo_win32_display_surface_map_to_image (void *abstract_surface, const cairo_rectangle_int_t *extents) { cairo_win32_display_surface_t *surface = abstract_surface; cairo_status_t status; TRACE ((stderr, "%s (surface=%d)\n", __FUNCTION__, surface->win32.base.unique_id)); if (surface->image) goto done; if (surface->fallback == NULL) { surface->fallback = _cairo_win32_display_surface_create_for_dc (surface->win32.dc, surface->win32.format, surface->win32.extents.width, surface->win32.extents.height); if (unlikely (status = surface->fallback->status)) goto err; if (!BitBlt (to_win32_surface(surface->fallback)->dc, 0, 0, surface->win32.extents.width, surface->win32.extents.height, surface->win32.dc, 0, 0, SRCCOPY)) { status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR); goto err; } } surface = to_win32_display_surface (surface->fallback); done: GdiFlush(); return _cairo_surface_map_to_image (surface->image, extents); err: cairo_surface_destroy (surface->fallback); surface->fallback = NULL; return _cairo_image_surface_create_in_error (status); }
static cairo_int_status_t _cairo_win32_display_surface_mask (void *surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, const cairo_clip_t *clip) { cairo_win32_device_t *device = to_win32_device_from_surface (surface); TRACE ((stderr, "%s (surface=%d)\n", __FUNCTION__, to_win32_surface(surface)->base.unique_id)); if (clip == NULL && op == CAIRO_OPERATOR_SOURCE) _cairo_win32_display_surface_discard_fallback (surface); return _cairo_compositor_mask (device->compositor, surface, op, source, mask, clip); }
static cairo_int_status_t _cairo_win32_display_surface_glyphs (void *surface, cairo_operator_t op, const cairo_pattern_t *source, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, const cairo_clip_t *clip) { cairo_win32_device_t *device = to_win32_device_from_surface (surface); TRACE ((stderr, "%s (surface=%d)\n", __FUNCTION__, to_win32_surface(surface)->base.unique_id)); return _cairo_compositor_glyphs (device->compositor, surface, op, source, glyphs, num_glyphs, scaled_font, clip); }
static cairo_int_status_t _cairo_win32_display_surface_fill (void *surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, const cairo_clip_t *clip) { cairo_win32_device_t *device = to_win32_device_from_surface (surface); TRACE ((stderr, "%s (surface=%d)\n", __FUNCTION__, to_win32_surface(surface)->base.unique_id)); return _cairo_compositor_fill (device->compositor, surface, op, source, path, fill_rule, tolerance, antialias, clip); }