diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index 5a9eca314..7834d97ed 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -387,12 +387,15 @@ _cairo_win32_surface_create_similar_internal (void *abstract_src, { cairo_win32_surface_t *src = abstract_src; cairo_format_t format = _cairo_format_from_content (content); - cairo_win32_surface_t *new_surf; + cairo_surface_t *new_surf = NULL; /* We force a DIB always if: * - we need alpha; or * - the parent is a DIB; or * - the parent is for printing (because we don't care about the bit depth at that point) + * + * We also might end up with a DIB even if a DDB is requested if DDB creation failed + * due to out of memory. */ if (src->is_dib || (content & CAIRO_CONTENT_ALPHA) || @@ -401,30 +404,19 @@ _cairo_win32_surface_create_similar_internal (void *abstract_src, force_dib = TRUE; } - if (force_dib) { - new_surf = (cairo_win32_surface_t*) - _cairo_win32_surface_create_for_dc (src->dc, format, width, height); - } else { - /* otherwise, create a ddb */ - HBITMAP ddb = CreateCompatibleBitmap (src->dc, width, height); - HDC ddb_dc = CreateCompatibleDC (src->dc); - HBITMAP saved_dc_bitmap; - - saved_dc_bitmap = SelectObject (ddb_dc, ddb); - - new_surf = (cairo_win32_surface_t*) cairo_win32_surface_create (ddb_dc); - if (new_surf->base.status == CAIRO_STATUS_SUCCESS) { - new_surf->bitmap = ddb; - new_surf->saved_dc_bitmap = saved_dc_bitmap; - new_surf->is_dib = FALSE; - } else { - SelectObject (ddb_dc, saved_dc_bitmap); - DeleteDC (ddb_dc); - DeleteObject (ddb); - } + if (!force_dib) { + /* try to create a ddb */ + new_surf = cairo_win32_surface_create_with_ddb (src->dc, CAIRO_FORMAT_RGB24, width, height); + + if (new_surf->status != CAIRO_STATUS_SUCCESS) + new_surf = NULL; } - return (cairo_surface_t*) new_surf; + if (new_surf == NULL) { + new_surf = _cairo_win32_surface_create_for_dc (src->dc, format, width, height); + } + + return new_surf; } cairo_surface_t * @@ -1835,7 +1827,6 @@ cairo_win32_surface_create_with_ddb (HDC hdc, ddb_dc = CreateCompatibleDC (hdc); if (ddb_dc == NULL) { - _cairo_win32_print_gdi_error("CreateCompatibleDC"); new_surf = (cairo_win32_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); goto FINISH; } @@ -1846,9 +1837,9 @@ cairo_win32_surface_create_with_ddb (HDC hdc, /* Note that if an app actually does hit this out of memory * condition, it's going to have lots of other issues, as - * video memory is probably exhausted. + * video memory is probably exhausted. However, it can often + * continue using DIBs instead of DDBs. */ - _cairo_win32_print_gdi_error("CreateCompatibleBitmap"); new_surf = (cairo_win32_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); goto FINISH; }