Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Enumerations | Functions | Variables
cairo-win32-surface.c File Reference
#include <stdio.h>
#include "cairoint.h"
#include "cairo-win32-private.h"

Go to the source code of this file.

Classes

struct  BLENDFUNCTION

Defines

#define AC_SRC_OVER   0x00
#define AC_SRC_ALPHA   0x01

Typedefs

typedef int nXOriginDest
typedef int int nYOriginDest
typedef int int int nWidthDest
typedef int int int int hHeightDest
typedef int int int int HDC hdcSrc
typedef int int int int HDC int nXOriginSrc
typedef int int int int HDC int int nYOriginSrc
typedef int int int int HDC
int int int 
nWidthSrc
typedef int int int int HDC
int int int int 
nHeightSrc
typedef int int int int HDC
int int int int BLENDFUNCTION 
blendFunction

Enumerations

enum  

Functions

cairo_status_t _cairo_win32_print_gdi_error (const char *context)
 _cairo_win32_print_gdi_error: : context string to display along with the error
static cairo_status_t _create_dc_and_bitmap (cairo_win32_surface_t *surface, HDC original_dc, cairo_format_t format, int width, int height, char **bits_out, int *rowstride_out)
static cairo_surface_t * _cairo_win32_surface_create_for_dc (HDC original_dc, cairo_format_t format, int width, int height)
static cairo_surface_t * _cairo_win32_surface_create_similar (void *abstract_src, cairo_content_t content, int width, int height)
cairo_surface_t * _cairo_win32_surface_create_dib (cairo_format_t format, int width, int height)
 _cairo_win32_surface_create_dib: : format of pixels in the surface to create : width of the surface, in pixels : height of the surface, in pixels
static cairo_status_t _cairo_win32_surface_finish (void *abstract_surface)
static cairo_status_t _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface, int x, int y, int width, int height, cairo_win32_surface_t **local_out)
static cairo_status_t _cairo_win32_surface_acquire_source_image (void *abstract_surface, cairo_image_surface_t **image_out, void **image_extra)
static void _cairo_win32_surface_release_source_image (void *abstract_surface, cairo_image_surface_t *image, void *image_extra)
static cairo_status_t _cairo_win32_surface_acquire_dest_image (void *abstract_surface, cairo_rectangle_t *interest_rect, cairo_image_surface_t **image_out, cairo_rectangle_t *image_rect, void **image_extra)
static void _cairo_win32_surface_release_dest_image (void *abstract_surface, cairo_rectangle_t *interest_rect, cairo_image_surface_t *image, cairo_rectangle_t *image_rect, void *image_extra)
typedef BOOL (WINAPI *cairo_alpha_blend_func_t)(HDC hdcDest
static cairo_int_status_t _composite_alpha_blend (cairo_win32_surface_t *dst, cairo_win32_surface_t *src, int alpha, int src_x, int src_y, int dst_x, int dst_y, int width, int height)
static cairo_int_status_t _cairo_win32_surface_composite (cairo_operator_t operator, cairo_pattern_t *pattern, cairo_pattern_t *mask_pattern, void *abstract_dst, int src_x, int src_y, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, unsigned int height)
static enum { ... }  categorize_solid_dest_operator (cairo_operator_t operator, unsigned short alpha)
static cairo_int_status_t _cairo_win32_surface_fill_rectangles (void *abstract_surface, cairo_operator_t operator, const cairo_color_t *color, cairo_rectangle_t *rects, int num_rects)
static cairo_int_status_t _cairo_win32_surface_set_clip_region (void *abstract_surface, pixman_region16_t *region)
static cairo_int_status_t _cairo_win32_surface_get_extents (void *abstract_surface, cairo_rectangle_t *rectangle)
static cairo_status_t _cairo_win32_surface_flush (void *abstract_surface)
cairo_surface_t * cairo_win32_surface_create (HDC hdc)
int _cairo_surface_is_win32 (cairo_surface_t *surface)
 _cairo_surface_is_win32: : a #cairo_surface_t

Variables

static const
cairo_surface_backend_t 
cairo_win32_surface_backend
 DO_CLEAR
 DO_SOURCE
 DO_NOTHING
 DO_UNSUPPORTED
CRITICAL_SECTION cairo_toy_font_face_hash_table_mutex
CRITICAL_SECTION cairo_scaled_font_map_mutex
CRITICAL_SECTION cairo_ft_unscaled_font_map_mutex
CRITICAL_SECTION _global_image_glyph_cache_mutex

Class Documentation

struct BLENDFUNCTION

Definition at line 540 of file cairo-win32-surface.c.

Class Members
BYTE AlphaFormat
BYTE BlendFlags
BYTE BlendOp
BYTE SourceConstantAlpha

Define Documentation

#define AC_SRC_ALPHA   0x01

Definition at line 551 of file cairo-win32-surface.c.

#define AC_SRC_OVER   0x00

Definition at line 538 of file cairo-win32-surface.c.


Typedef Documentation

Definition at line 555 of file cairo-win32-surface.c.

typedef int int int int HDC hdcSrc

Definition at line 555 of file cairo-win32-surface.c.

Definition at line 555 of file cairo-win32-surface.c.

Definition at line 555 of file cairo-win32-surface.c.

typedef int int int nWidthDest

Definition at line 555 of file cairo-win32-surface.c.

typedef int int int int HDC int int int nWidthSrc

Definition at line 555 of file cairo-win32-surface.c.

typedef int nXOriginDest

Definition at line 555 of file cairo-win32-surface.c.

typedef int int int int HDC int nXOriginSrc

Definition at line 555 of file cairo-win32-surface.c.

typedef int int nYOriginDest

Definition at line 555 of file cairo-win32-surface.c.

typedef int int int int HDC int int nYOriginSrc

Definition at line 555 of file cairo-win32-surface.c.


Enumeration Type Documentation

anonymous enum

Function Documentation

int _cairo_surface_is_win32 ( cairo_surface_t *  surface)

_cairo_surface_is_win32: : a #cairo_surface_t

Checks if a surface is an cairo_win32_surface_t

Return value: True if the surface is an win32 surface

Definition at line 1038 of file cairo-win32-surface.c.

{
    return surface->backend == &cairo_win32_surface_backend;
}

Here is the caller graph for this function:

_cairo_win32_print_gdi_error: : context string to display along with the error

Helper function to dump out a human readable form of the current error code.

Return value: A cairo status code for the error code

Definition at line 52 of file cairo-win32-surface.c.

{
    void *lpMsgBuf;
    DWORD last_error = GetLastError ();

    if (!FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                      FORMAT_MESSAGE_FROM_SYSTEM,
                      NULL,
                      last_error,
                      MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
                      (LPTSTR) &lpMsgBuf,
                      0, NULL)) {
       fprintf (stderr, "%s: Unknown GDI error", context);
    } else {
       fprintf (stderr, "%s: %s", context, (char *)lpMsgBuf);
       
       LocalFree (lpMsgBuf);
    }

    /* We should switch off of last_status, but we'd either return
     * CAIRO_STATUS_NO_MEMORY or CAIRO_STATUS_UNKNOWN_ERROR and there
     * is no CAIRO_STATUS_UNKNOWN_ERROR.
     */

    return CAIRO_STATUS_NO_MEMORY;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_win32_surface_acquire_dest_image ( void abstract_surface,
cairo_rectangle_t interest_rect,
cairo_image_surface_t **  image_out,
cairo_rectangle_t image_rect,
void **  image_extra 
) [static]

Definition at line 448 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *surface = abstract_surface;
    cairo_win32_surface_t *local = NULL;
    cairo_status_t status;
    RECT clip_box;
    int x1, y1, x2, y2;
        
    if (surface->dst_image) {
       image_rect->x = 0;
       image_rect->y = 0;
       image_rect->width = surface->clip_rect.width;
       image_rect->height = surface->clip_rect.height;

       *image_out = (cairo_image_surface_t *)surface->dst_image;
       *image_extra = NULL;

       return CAIRO_STATUS_SUCCESS;
    }

    if (GetClipBox (surface->dc, &clip_box) == ERROR)
       return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");
    
    x1 = clip_box.left;
    x2 = clip_box.right;
    y1 = clip_box.top;
    y2 = clip_box.bottom;
    
    if (interest_rect->x > x1)
       x1 = interest_rect->x;
    if (interest_rect->y > y1)
       y1 = interest_rect->y;
    if (interest_rect->x + interest_rect->width < x2)
       x2 = interest_rect->x + interest_rect->width;
    if (interest_rect->y + interest_rect->height < y2)
       y2 = interest_rect->y + interest_rect->height;
    
    if (x1 >= x2 || y1 >= y2) {
       *image_out = NULL;
       *image_extra = NULL;
       
       return CAIRO_STATUS_SUCCESS;
    }
       
    status = _cairo_win32_surface_get_subimage (abstract_surface, 
                                          x1, y1, x2 - x1, y2 - y1,
                                          &local);
    if (status)
       return status;

    *image_out = (cairo_image_surface_t *)local->dst_image;
    *image_extra = local;
    
    image_rect->x = x1;
    image_rect->y = y1;
    image_rect->width = x2 - x1;
    image_rect->height = y2 - y1;

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

static cairo_status_t _cairo_win32_surface_acquire_source_image ( void abstract_surface,
cairo_image_surface_t **  image_out,
void **  image_extra 
) [static]

Definition at line 409 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *surface = abstract_surface;
    cairo_win32_surface_t *local = NULL;
    cairo_status_t status;

    if (surface->src_image) {
       *image_out = (cairo_image_surface_t *)surface->src_image;
       *image_extra = NULL;

       return CAIRO_STATUS_SUCCESS;
    }

    status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0,
                                          surface->clip_rect.width,
                                          surface->clip_rect.height, &local);
    if (status)
       return status;

    *image_out = (cairo_image_surface_t *)local->src_image;
    *image_extra = local;

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

static cairo_int_status_t _cairo_win32_surface_composite ( cairo_operator_t  operator,
cairo_pattern_t *  pattern,
cairo_pattern_t *  mask_pattern,
void abstract_dst,
int  src_x,
int  src_y,
int  mask_x,
int  mask_y,
int  dst_x,
int  dst_y,
unsigned int  width,
unsigned int  height 
) [static]

Definition at line 627 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *dst = abstract_dst;
    cairo_win32_surface_t *src;
    cairo_surface_pattern_t *src_surface_pattern;
    int alpha;
    int integer_transform;
    int itx, ity;

    if (pattern->type != CAIRO_PATTERN_SURFACE ||
       pattern->extend != CAIRO_EXTEND_NONE)
       return CAIRO_INT_STATUS_UNSUPPORTED;

    if (mask_pattern) {
       /* FIXME: When we fully support RENDER style 4-channel
        * masks we need to check r/g/b != 1.0.
        */
       if (mask_pattern->type != CAIRO_PATTERN_SOLID)
           return CAIRO_INT_STATUS_UNSUPPORTED;

       alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8;
    } else {
        alpha = 255;
    }

    src_surface_pattern = (cairo_surface_pattern_t *)pattern;
    src = (cairo_win32_surface_t *)src_surface_pattern->surface;

    if (src->base.backend != dst->base.backend)
       return CAIRO_INT_STATUS_UNSUPPORTED;
    
    integer_transform = _cairo_matrix_is_integer_translation (&pattern->matrix, &itx, &ity);
    if (!integer_transform)
       return CAIRO_INT_STATUS_UNSUPPORTED;

    if (alpha == 255 &&
       src->format == dst->format &&
       (operator == CAIRO_OPERATOR_SOURCE ||
        (src->format == CAIRO_FORMAT_RGB24 && operator == CAIRO_OPERATOR_OVER))) {
       
       if (!BitBlt (dst->dc,
                   dst_x, dst_y,
                   width, height,
                   src->dc,
                   src_x + itx, src_y + ity,
                   SRCCOPY))
           return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");

       return CAIRO_STATUS_SUCCESS;
       
    } else if (integer_transform &&
              (src->format == CAIRO_FORMAT_RGB24 || src->format == CAIRO_FORMAT_ARGB32) &&
              dst->format == CAIRO_FORMAT_RGB24 &&
              operator == CAIRO_OPERATOR_OVER) {

       return _composite_alpha_blend (dst, src, alpha,
                                   src_x + itx, src_y + ity,
                                   dst_x, dst_y, width, height);
    }
    
    return CAIRO_INT_STATUS_UNSUPPORTED;
}

Here is the call graph for this function:

cairo_surface_t* _cairo_win32_surface_create_dib ( cairo_format_t  format,
int  width,
int  height 
)

_cairo_win32_surface_create_dib: : format of pixels in the surface to create : width of the surface, in pixels : height of the surface, in pixels

Creates a device-independent-bitmap surface not associated with any particular existing surface or device context. The created bitmap will be unititialized.

Return value: the newly created surface, or NULL if it couldn't be created (probably because of lack of memory)

Definition at line 335 of file cairo-win32-surface.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_surface_t* _cairo_win32_surface_create_for_dc ( HDC  original_dc,
cairo_format_t  format,
int  width,
int  height 
) [static]

Definition at line 241 of file cairo-win32-surface.c.

{
    cairo_status_t status;
    cairo_win32_surface_t *surface;
    char *bits;
    int rowstride;

    surface = malloc (sizeof (cairo_win32_surface_t));
    if (surface == NULL) {
       _cairo_error (CAIRO_STATUS_NO_MEMORY);
       return &_cairo_surface_nil;
    }

    status = _create_dc_and_bitmap (surface, original_dc, format,
                                width, height,
                                &bits, &rowstride);
    if (status)
       goto FAIL;

    surface->src_image = cairo_image_surface_create_for_data (bits, format,
                                                              width, height, rowstride);
    if (surface->src_image->status) {
       status = CAIRO_STATUS_NO_MEMORY;
       goto FAIL;
    }

    surface->dst_image = cairo_image_surface_create_for_data (bits, format,
                                                              width, height, rowstride);
    if (surface->dst_image->status) {
       status = CAIRO_STATUS_NO_MEMORY;
       goto FAIL;
    }
    
    surface->format = format;
    
    surface->clip_rect.x = 0;
    surface->clip_rect.y = 0;
    surface->clip_rect.width = width;
    surface->clip_rect.height = height;

    surface->set_clip = 0;
    surface->saved_clip = NULL;
    
    _cairo_surface_init (&surface->base, &cairo_win32_surface_backend);

    return (cairo_surface_t *)surface;

 FAIL:
    if (surface->bitmap) {
       SelectObject (surface->dc, surface->saved_dc_bitmap);
       DeleteObject (surface->bitmap);
        DeleteDC (surface->dc);
    }
    if (surface)
       free (surface);

    if (status == CAIRO_STATUS_NO_MEMORY) {
       _cairo_error (CAIRO_STATUS_NO_MEMORY);
       return &_cairo_surface_nil;
    } else {
       _cairo_error (status);
       return &_cairo_surface_nil;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_surface_t* _cairo_win32_surface_create_similar ( void abstract_src,
cairo_content_t  content,
int  width,
int  height 
) [static]

Definition at line 310 of file cairo-win32-surface.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_int_status_t _cairo_win32_surface_fill_rectangles ( void abstract_surface,
cairo_operator_t  operator,
const cairo_color_t *  color,
cairo_rectangle_t rects,
int  num_rects 
) [static]

Definition at line 780 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *surface = abstract_surface;
    cairo_status_t status;
    COLORREF new_color;
    HBRUSH new_brush;
    int i;

    /* If we have a local image, use the fallback code; it will be as fast
     * as calling out to GDI.
     */
    if (surface->dst_image)
       return CAIRO_INT_STATUS_UNSUPPORTED;

    /* Optimize for no destination alpha (surface->pixman_image is non-NULL for all
     * surfaces with alpha.)
     */
    switch (categorize_solid_dest_operator (operator, color->alpha_short)) {
    case DO_CLEAR:
       new_color = RGB (0, 0, 0);
       break; 
    case DO_SOURCE:
       new_color = RGB (color->red_short >> 8, color->green_short >> 8, color->blue_short >> 8);
       break;
    case DO_NOTHING:
       return CAIRO_STATUS_SUCCESS;
    case DO_UNSUPPORTED:
    default:
       return CAIRO_INT_STATUS_UNSUPPORTED;
    }
    
    new_brush = CreateSolidBrush (new_color);
    if (!new_brush)
       return _cairo_win32_print_gdi_error ("_cairo_win32_surface_fill_rectangles");
    
    for (i = 0; i < num_rects; i++) {
       RECT rect;

       rect.left = rects[i].x;
       rect.top = rects[i].y;
       rect.right = rects[i].x + rects[i].width;
       rect.bottom = rects[i].y + rects[i].height;

       if (!FillRect (surface->dc, &rect, new_brush))
           goto FAIL;
    }

    DeleteObject (new_brush);
    
    return CAIRO_STATUS_SUCCESS;

 FAIL:
    status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_fill_rectangles");
    
    DeleteObject (new_brush);
    
    return status;
}

Here is the call graph for this function:

static cairo_status_t _cairo_win32_surface_finish ( void abstract_surface) [static]

Definition at line 343 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *surface = abstract_surface;

    if (surface->src_image)
       cairo_surface_destroy (surface->src_image);

    if (surface->dst_image)
       cairo_surface_destroy (surface->dst_image);

    if (surface->saved_clip) {
       DeleteObject (surface->saved_clip);
    }

    /* If we created the Bitmap and DC, destroy them */
    if (surface->bitmap) {
       SelectObject (surface->dc, surface->saved_dc_bitmap);
       DeleteObject (surface->bitmap);
        DeleteDC (surface->dc);
    }

    return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t _cairo_win32_surface_flush ( void abstract_surface) [static]

Definition at line 982 of file cairo-win32-surface.c.

{
    return _cairo_surface_reset_clip (abstract_surface);
}

Here is the call graph for this function:

static cairo_int_status_t _cairo_win32_surface_get_extents ( void abstract_surface,
cairo_rectangle_t rectangle 
) [static]

Definition at line 964 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *surface = abstract_surface;
    RECT clip_box;

    if (GetClipBox (surface->dc, &clip_box) == ERROR)
       return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");

    rectangle->x = clip_box.left;
    rectangle->y = clip_box.top;
    rectangle->width  = clip_box.right  - clip_box.left;
    rectangle->height = clip_box.bottom - clip_box.top;

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

static cairo_status_t _cairo_win32_surface_get_subimage ( cairo_win32_surface_t surface,
int  x,
int  y,
int  width,
int  height,
cairo_win32_surface_t **  local_out 
) [static]

Definition at line 368 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *local;
    cairo_status_t status;
    cairo_content_t content = _cairo_content_from_format (surface->format);

    local = 
       (cairo_win32_surface_t *) _cairo_win32_surface_create_similar (surface,
                                                               content,
                                                               width,
                                                               height);
    if (local->base.status)
       return CAIRO_STATUS_NO_MEMORY;
    
    if (!BitBlt (local->dc, 
               0, 0,
               width, height,
               surface->dc,
               x, y,
               SRCCOPY))
       goto FAIL;

    *local_out = local;
    
    return CAIRO_STATUS_SUCCESS;

 FAIL:
    status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_get_subimage");

    if (local)
       cairo_surface_destroy (&local->base);

    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_win32_surface_release_dest_image ( void abstract_surface,
cairo_rectangle_t interest_rect,
cairo_image_surface_t *  image,
cairo_rectangle_t image_rect,
void image_extra 
) [static]

Definition at line 514 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *surface = abstract_surface;
    cairo_win32_surface_t *local = image_extra;
    
    if (!local)
       return;

    if (!BitBlt (surface->dc,
               image_rect->x, image_rect->y,
               image_rect->width, image_rect->height,
               local->dc,
               0, 0,
               SRCCOPY))
       _cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image");

    cairo_surface_destroy ((cairo_surface_t *)local);
}

Here is the call graph for this function:

static void _cairo_win32_surface_release_source_image ( void abstract_surface,
cairo_image_surface_t *  image,
void image_extra 
) [static]

Definition at line 437 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *local = image_extra;
    
    if (local)
       cairo_surface_destroy ((cairo_surface_t *)local);
}
static cairo_int_status_t _cairo_win32_surface_set_clip_region ( void abstract_surface,
pixman_region16_t *  region 
) [static]

Definition at line 844 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *surface = abstract_surface;
    cairo_status_t status;

    /* If we are in-memory, then we set the clip on the image surface
     * as well as on the underlying GDI surface.
     */
    if (surface->dst_image) {
       unsigned int serial;

       serial = _cairo_surface_allocate_clip_serial (surface->dst_image);
       _cairo_surface_set_clip_region (surface->dst_image, region, serial);
    }

    /* The semantics we want is that any clip set by cairo combines
     * is intersected with the clip on device context that the
     * surface was created for. To implement this, we need to
     * save the original clip when first setting a clip on surface.
     */

    if (region == NULL) {
       /* Clear any clip set by cairo, return to the original */
       
       if (surface->set_clip) {
           if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
              return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");

           if (surface->saved_clip) {
              DeleteObject (surface->saved_clip);
              surface->saved_clip = NULL;
           }

           surface->set_clip = 0;
       }
           
       return CAIRO_STATUS_SUCCESS;
    
    } else {
       pixman_box16_t *boxes = pixman_region_rects (region);
       int num_boxes = pixman_region_num_rects (region);
       pixman_box16_t *extents = pixman_region_extents (region);
       RGNDATA *data;
       size_t data_size;
       RECT *rects;
       int i;
       HRGN gdi_region;

       /* Create a GDI region for the cairo region */

       data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT);
       data = malloc (data_size);
       if (!data)
           return CAIRO_STATUS_NO_MEMORY;
       rects = (RECT *)data->Buffer;

       data->rdh.dwSize = sizeof (RGNDATAHEADER);
       data->rdh.iType = RDH_RECTANGLES;
       data->rdh.nCount = num_boxes;
       data->rdh.nRgnSize = num_boxes * sizeof (RECT);
       data->rdh.rcBound.left = extents->x1;
       data->rdh.rcBound.top = extents->y1;
       data->rdh.rcBound.right = extents->x2;
       data->rdh.rcBound.bottom = extents->y2;

       for (i = 0; i < num_boxes; i++) {
           rects[i].left = boxes[i].x1;
           rects[i].top = boxes[i].y1;
           rects[i].right = boxes[i].x2;
           rects[i].bottom = boxes[i].y2;
       }

       gdi_region = ExtCreateRegion (NULL, data_size, data);
       free (data);
       
       if (!gdi_region)
           return CAIRO_STATUS_NO_MEMORY;

       if (surface->set_clip) {
           /* Combine the new region with the original clip */
           
           if (surface->saved_clip) {
              if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR)
                  goto FAIL;
           }

           if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
              goto FAIL;
              
       } else {
           /* Save the the current region */

           surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
           if (!surface->saved_clip) {
              goto FAIL;        }

           /* This function has no error return! */
           if (GetClipRgn (surface->dc, surface->saved_clip) == 0) { /* No clip */
              DeleteObject (surface->saved_clip);
              surface->saved_clip = NULL;
           }
              
           if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR)
              goto FAIL;

           surface->set_clip = 1;
       }

       DeleteObject (gdi_region);
       return CAIRO_STATUS_SUCCESS;

    FAIL:
       status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
       DeleteObject (gdi_region);
       return status;
    }
}

Here is the call graph for this function:

static cairo_int_status_t _composite_alpha_blend ( cairo_win32_surface_t dst,
cairo_win32_surface_t src,
int  alpha,
int  src_x,
int  src_y,
int  dst_x,
int  dst_y,
int  width,
int  height 
) [static]

Definition at line 567 of file cairo-win32-surface.c.

{
    static unsigned alpha_blend_checked = FALSE;
    static cairo_alpha_blend_func_t alpha_blend = NULL;

    BLENDFUNCTION blend_function;

    /* Check for AlphaBlend dynamically to allow compiling on
     * MSVC 6 and use on older windows versions
     */
    if (!alpha_blend_checked) {
       OSVERSIONINFO os;
    
       os.dwOSVersionInfoSize = sizeof (os);
       GetVersionEx (&os);
       
       /* If running on Win98, disable using AlphaBlend()
        * to avoid Win98 AlphaBlend() bug */
       if (VER_PLATFORM_WIN32_WINDOWS != os.dwPlatformId ||
           os.dwMajorVersion != 4 || os.dwMinorVersion != 10)
       {
           HMODULE msimg32_dll = LoadLibrary ("msimg32");
           
           if (msimg32_dll != NULL)
              alpha_blend = (cairo_alpha_blend_func_t)GetProcAddress (msimg32_dll,
                                                               "AlphaBlend");
       }
           
       alpha_blend_checked = TRUE;
    }

    if (alpha_blend == NULL)
       return CAIRO_INT_STATUS_UNSUPPORTED;
    
    blend_function.BlendOp = AC_SRC_OVER;
    blend_function.BlendFlags = 0;
    blend_function.SourceConstantAlpha = alpha;
    blend_function.AlphaFormat = src->format == CAIRO_FORMAT_ARGB32 ? AC_SRC_ALPHA : 0;

    if (!alpha_blend (dst->dc,
                    dst_x, dst_y,
                    width, height,
                    src->dc,
                    src_x, src_y,
                    width, height,
                    blend_function))
       return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
    
    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _create_dc_and_bitmap ( cairo_win32_surface_t surface,
HDC  original_dc,
cairo_format_t  format,
int  width,
int  height,
char **  bits_out,
int rowstride_out 
) [static]

Definition at line 80 of file cairo-win32-surface.c.

{
    cairo_status_t status;

    BITMAPINFO *bitmap_info = NULL;
    struct {
       BITMAPINFOHEADER bmiHeader;
       RGBQUAD bmiColors[2];
    } bmi_stack;
    void *bits;

    int num_palette = 0;    /* Quiet GCC */
    int i;

    surface->dc = NULL;
    surface->bitmap = NULL;

    switch (format) {
    case CAIRO_FORMAT_ARGB32:
    case CAIRO_FORMAT_RGB24:
       num_palette = 0;
       break;
       
    case CAIRO_FORMAT_A8:
       num_palette = 256;
       break;
       
    case CAIRO_FORMAT_A1:
       num_palette = 2;
       break;
    }

    if (num_palette > 2) {
       bitmap_info = malloc (sizeof (BITMAPINFOHEADER) + num_palette * sizeof (RGBQUAD));
       if (!bitmap_info)
           return CAIRO_STATUS_NO_MEMORY;
    } else {
       bitmap_info = (BITMAPINFO *)&bmi_stack;
    }

    bitmap_info->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
    bitmap_info->bmiHeader.biWidth = width == 0 ? 1 : width;
    bitmap_info->bmiHeader.biHeight = height == 0 ? -1 : - height; /* top-down */
    bitmap_info->bmiHeader.biSizeImage = 0;
    bitmap_info->bmiHeader.biXPelsPerMeter = 72. / 0.0254; /* unused here */
    bitmap_info->bmiHeader.biYPelsPerMeter = 72. / 0.0254; /* unused here */
    bitmap_info->bmiHeader.biPlanes = 1;
    
    switch (format) {
    case CAIRO_FORMAT_ARGB32:
    case CAIRO_FORMAT_RGB24:
       bitmap_info->bmiHeader.biBitCount = 32;
       bitmap_info->bmiHeader.biCompression = BI_RGB;
       bitmap_info->bmiHeader.biClrUsed = 0;     /* unused */
       bitmap_info->bmiHeader.biClrImportant = 0;
       break;
       
    case CAIRO_FORMAT_A8:
       bitmap_info->bmiHeader.biBitCount = 8;
       bitmap_info->bmiHeader.biCompression = BI_RGB;
       bitmap_info->bmiHeader.biClrUsed = 256;
       bitmap_info->bmiHeader.biClrImportant = 0;

       for (i = 0; i < 256; i++) {
           bitmap_info->bmiColors[i].rgbBlue = i;
           bitmap_info->bmiColors[i].rgbGreen = i;
           bitmap_info->bmiColors[i].rgbRed = i;
           bitmap_info->bmiColors[i].rgbReserved = 0;
       }
       
       break;
       
    case CAIRO_FORMAT_A1:
       bitmap_info->bmiHeader.biBitCount = 1;
       bitmap_info->bmiHeader.biCompression = BI_RGB;
       bitmap_info->bmiHeader.biClrUsed = 2;
       bitmap_info->bmiHeader.biClrImportant = 0;

       for (i = 0; i < 2; i++) {
           bitmap_info->bmiColors[i].rgbBlue = i * 255;
           bitmap_info->bmiColors[i].rgbGreen = i * 255;
           bitmap_info->bmiColors[i].rgbRed = i * 255;
           bitmap_info->bmiColors[i].rgbReserved = 0;
           break;
       }
    }

    surface->dc = CreateCompatibleDC (original_dc);
    if (!surface->dc)
       goto FAIL;

    surface->bitmap = CreateDIBSection (surface->dc,
                                     bitmap_info,
                                     DIB_RGB_COLORS,
                                     &bits,
                                     NULL, 0);
    if (!surface->bitmap)
       goto FAIL;

    surface->saved_dc_bitmap = SelectObject (surface->dc,
                                        surface->bitmap);
    if (!surface->saved_dc_bitmap)
       goto FAIL;
    
    if (bitmap_info && num_palette > 2)
       free (bitmap_info);

    if (bits_out)
       *bits_out = bits;

    if (rowstride_out) {
       /* Windows bitmaps are padded to 32-bit (dword) boundaries */
       switch (format) {
       case CAIRO_FORMAT_ARGB32:
       case CAIRO_FORMAT_RGB24:
           *rowstride_out = 4 * width;
           break;
           
       case CAIRO_FORMAT_A8:
           *rowstride_out = (width + 3) & ~3;
           break;
       
       case CAIRO_FORMAT_A1:
           *rowstride_out = ((width + 31) & ~31) / 8;
           break;
       }
    }

    return CAIRO_STATUS_SUCCESS;

 FAIL:
    status = _cairo_win32_print_gdi_error ("_create_dc_and_bitmap");
    
    if (bitmap_info && num_palette > 2)
       free (bitmap_info);

    if (surface->saved_dc_bitmap) {
       SelectObject (surface->dc, surface->saved_dc_bitmap);
       surface->saved_dc_bitmap = NULL;
    }
    
    if (surface->bitmap) {
       DeleteObject (surface->bitmap);
       surface->bitmap = NULL;
    }
    
    if (surface->dc) {
       DeleteDC (surface->dc);
       surface->dc = NULL;
    }
 
    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

typedef BOOL ( WINAPI *  cairo_alpha_blend_func_t)
cairo_surface_t* cairo_win32_surface_create ( HDC  hdc)

Definition at line 988 of file cairo-win32-surface.c.

{
    cairo_win32_surface_t *surface;
    RECT rect;

    /* Try to figure out the drawing bounds for the Device context
     */
    if (GetClipBox (hdc, &rect) == ERROR) {
       _cairo_win32_print_gdi_error ("cairo_win32_surface_create");
       /* XXX: Can we make a more reasonable guess at the error cause here? */
       _cairo_error (CAIRO_STATUS_NO_MEMORY);
       return &_cairo_surface_nil;
    }
    
    surface = malloc (sizeof (cairo_win32_surface_t));
    if (surface == NULL) {
       _cairo_error (CAIRO_STATUS_NO_MEMORY);
       return &_cairo_surface_nil;
    }

    surface->src_image = NULL;
    surface->dst_image = NULL;
    surface->format = CAIRO_FORMAT_RGB24;
    
    surface->dc = hdc;
    surface->bitmap = NULL;
    surface->saved_dc_bitmap = NULL;
    
    surface->clip_rect.x = rect.left;
    surface->clip_rect.y = rect.top;
    surface->clip_rect.width = rect.right - rect.left;
    surface->clip_rect.height = rect.bottom - rect.top;

    surface->set_clip = 0;
    surface->saved_clip = NULL;

    _cairo_surface_init (&surface->base, &cairo_win32_surface_backend);

    return (cairo_surface_t *)surface;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static enum @327 categorize_solid_dest_operator ( cairo_operator_t  operator,
unsigned short  alpha 
) [static]

Definition at line 708 of file cairo-win32-surface.c.

{
    enum { SOURCE_TRANSPARENT, SOURCE_LIGHT, SOURCE_SOLID, SOURCE_OTHER } source;

    if (alpha >= 0xff00)
       source = SOURCE_SOLID;
    else if (alpha < 0x100)
       source = SOURCE_TRANSPARENT;
    else
       source = SOURCE_OTHER;
    
    switch (operator) {
    case CAIRO_OPERATOR_CLEAR:    /* 0                 0 */
    case CAIRO_OPERATOR_OUT:      /* 1 - Ab            0 */
       return DO_CLEAR;
       break;
       
    case CAIRO_OPERATOR_SOURCE:   /* 1                 0 */
    case CAIRO_OPERATOR_IN:       /* Ab                0 */
       return DO_SOURCE;
       break;

    case CAIRO_OPERATOR_OVER:     /* 1            1 - Aa */
    case CAIRO_OPERATOR_ATOP:     /* Ab           1 - Aa */
       if (source == SOURCE_SOLID)
           return DO_SOURCE;
       else if (source == SOURCE_TRANSPARENT)
           return DO_NOTHING;
       else
           return DO_UNSUPPORTED;
       break;
       
    case CAIRO_OPERATOR_DEST_OUT: /* 0            1 - Aa */
    case CAIRO_OPERATOR_XOR:      /* 1 - Ab       1 - Aa */
       if (source == SOURCE_SOLID)
           return DO_CLEAR;
       else if (source == SOURCE_TRANSPARENT)
           return DO_NOTHING;
       else
           return DO_UNSUPPORTED;
       break;
       
    case CAIRO_OPERATOR_DEST:     /* 0                 1 */
    case CAIRO_OPERATOR_DEST_OVER:/* 1 - Ab            1 */
    case CAIRO_OPERATOR_SATURATE: /* min(1,(1-Ab)/Aa)  1 */
       return DO_NOTHING;
       break;

    case CAIRO_OPERATOR_DEST_IN:  /* 0                Aa */
    case CAIRO_OPERATOR_DEST_ATOP:/* 1 - Ab           Aa */
       if (source == SOURCE_SOLID)
           return DO_NOTHING;
       else if (source == SOURCE_TRANSPARENT)
           return DO_CLEAR;
       else
           return DO_UNSUPPORTED;
       break;
       
    case CAIRO_OPERATOR_ADD:         /* 1                1 */
       if (source == SOURCE_TRANSPARENT)
           return DO_NOTHING;
       else
           return DO_UNSUPPORTED;
       break;
    }  

    ASSERT_NOT_REACHED;
    return DO_UNSUPPORTED;
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 1076 of file cairo-win32-surface.c.

Definition at line 1075 of file cairo-win32-surface.c.

Definition at line 1074 of file cairo-win32-surface.c.

Definition at line 1073 of file cairo-win32-surface.c.

Definition at line 710 of file cairo-win32-surface.c.

Definition at line 710 of file cairo-win32-surface.c.

Definition at line 710 of file cairo-win32-surface.c.

Definition at line 710 of file cairo-win32-surface.c.