/** * _fallback_init: * * Acquire destination image surface needed for an image-based * fallback. * * Return value: %CAIRO_INT_STATUS_NOTHING_TO_DO if the extents are not * visible, %CAIRO_STATUS_SUCCESS if some portion is visible and all * went well, or some error status otherwise. **/ static cairo_int_status_t _fallback_init (fallback_state_t *state, cairo_surface_t *dst, int x, int y, int width, int height) { cairo_status_t status; state->extents.x = x; state->extents.y = y; state->extents.width = width; state->extents.height = height; state->dst = dst; status = _cairo_surface_acquire_dest_image (dst, &state->extents, &state->image, &state->image_rect, &state->image_extra); if (status) return status; /* XXX: This NULL value tucked away in state->image is a rather * ugly interface. Cleaner would be to push the * CAIRO_INT_STATUS_NOTHING_TO_DO value down into * _cairo_surface_acquire_dest_image and its backend * counterparts. */ if (state->image == NULL) return CAIRO_INT_STATUS_NOTHING_TO_DO; return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _test_fallback_surface_acquire_dest_image (void *abstract_surface, cairo_rectangle_int16_t *interest_rect, cairo_image_surface_t **image_out, cairo_rectangle_int16_t *image_rect_out, void **image_extra) { test_fallback_surface_t *surface = abstract_surface; return _cairo_surface_acquire_dest_image (surface->backing, interest_rect, image_out, image_rect_out, image_extra); }
static cairo_status_t _cairo_atsui_font_show_glyphs(void *abstract_font, cairo_operator_t operator, cairo_pattern_t *pattern, cairo_surface_t *generic_surface, int source_x, int source_y, int dest_x, int dest_y, unsigned int width, unsigned int height, const cairo_glyph_t *glyphs, int num_glyphs) { cairo_atsui_font_t *font = abstract_font; CGContextRef myBitmapContext; CGColorSpaceRef colorSpace; cairo_image_surface_t *destImageSurface; int i; void *extra = NULL; cairo_rectangle_t rect = {dest_x, dest_y, width, height}; _cairo_surface_acquire_dest_image(generic_surface, &rect, &destImageSurface, &rect, &extra); // Create a CGBitmapContext for the dest surface for drawing into colorSpace = CGColorSpaceCreateDeviceRGB(); myBitmapContext = CGBitmapContextCreate(destImageSurface->data, destImageSurface->width, destImageSurface->height, destImageSurface->depth / 4, destImageSurface->stride, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); CGContextTranslateCTM(myBitmapContext, 0, destImageSurface->height); CGContextScaleCTM(myBitmapContext, 1.0f, -1.0f); ATSFontRef atsFont = FMGetATSFontRefFromFont(font->fontID); CGFontRef cgFont = CGFontCreateWithPlatformFont(&atsFont); CGContextSetFont(myBitmapContext, cgFont); CGAffineTransform textTransform = CGAffineTransformMakeWithCairoFontScale(&font->scale); textTransform = CGAffineTransformScale(textTransform, 1.0f, -1.0f); CGContextSetFontSize(myBitmapContext, 1.0); CGContextSetTextMatrix(myBitmapContext, textTransform); if (pattern->type == CAIRO_PATTERN_SOLID && _cairo_pattern_is_opaque_solid(pattern)) { cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern; CGContextSetRGBFillColor(myBitmapContext, solid->color.red, solid->color.green, solid->color.blue, 1.0f); } else { CGContextSetRGBFillColor(myBitmapContext, 0.0f, 0.0f, 0.0f, 0.0f); } // TODO - bold and italic text // // We could draw the text using ATSUI and get bold, italics // etc. for free, but ATSUI does a lot of text layout work // that we don't really need... for (i = 0; i < num_glyphs; i++) { CGGlyph theGlyph = glyphs[i].index; CGContextShowGlyphsAtPoint(myBitmapContext, glyphs[i].x, glyphs[i].y, &theGlyph, 1); } CGColorSpaceRelease(colorSpace); CGContextRelease(myBitmapContext); _cairo_surface_release_dest_image(generic_surface, &rect, destImageSurface, &rect, extra); return CAIRO_STATUS_SUCCESS; }