/**
 * _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);
}
Esempio n. 3
0
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;
}