diff --git a/README.md b/README.md index ebe3f99e1..2bd26068b 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ system pixman. #### Windows backend -- Microsoft Windows 2000 or newer. +- Microsoft Windows Vista or newer. #### XCB backend diff --git a/boilerplate/cairo-boilerplate-win32-printing.c b/boilerplate/cairo-boilerplate-win32-printing.c index e8fcdcef5..9177480fc 100644 --- a/boilerplate/cairo-boilerplate-win32-printing.c +++ b/boilerplate/cairo-boilerplate-win32-printing.c @@ -36,51 +36,6 @@ #include -#if !defined(POSTSCRIPT_IDENTIFY) -# define POSTSCRIPT_IDENTIFY 0x1015 -#endif - -#if !defined(PSIDENT_GDICENTRIC) -# define PSIDENT_GDICENTRIC 0x0000 -#endif - -#if !defined(GET_PS_FEATURESETTING) -# define GET_PS_FEATURESETTING 0x1019 -#endif - -#if !defined(FEATURESETTING_PSLEVEL) -# define FEATURESETTING_PSLEVEL 0x0002 -#endif - -static cairo_status_t -_cairo_win32_print_gdi_error (const char *context) -{ - void *lpMsgBuf; - DWORD last_error = GetLastError (); - - if (!FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - last_error, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPWSTR) &lpMsgBuf, - 0, NULL)) { - fprintf (stderr, "%s: Unknown GDI error", context); - } else { - fprintf (stderr, "%s: %S", context, (wchar_t *)lpMsgBuf); - - LocalFree (lpMsgBuf); - } - - fflush (stderr); - - /* 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; -} - static cairo_user_data_key_t win32_closure_key; typedef struct _win32_target_closure { @@ -174,7 +129,7 @@ create_printer_dc (win32_target_closure_t *ptc) xform.eDx = 0; xform.eDy = printable_height - ptc->height*y_dpi/72.0; if (!SetWorldTransform (ptc->dc, &xform)) { - _cairo_win32_print_gdi_error ("cairo-boilerplate-win32-printing:SetWorldTransform"); + fprintf (stderr, "%s:%s\n", "cairo-boilerplate-win32-printing", "SetWorldTransform"); return; } diff --git a/meson.build b/meson.build index 162b2927c..de89fb235 100644 --- a/meson.build +++ b/meson.build @@ -2,6 +2,7 @@ project('cairo', 'c', meson_version: '>= 1.3.0', version: run_command(find_program('version.py'), check: true).stdout().strip(), default_options: ['c_std=gnu11,c11', + 'cpp_std=gnu++11,c++11', 'warning_level=2'], ) diff --git a/src/win32/cairo-dwrite-font.cpp b/src/win32/cairo-dwrite-font.cpp index 491b6d60d..4e8970fdc 100644 --- a/src/win32/cairo-dwrite-font.cpp +++ b/src/win32/cairo-dwrite-font.cpp @@ -110,6 +110,7 @@ _cairo_dwrite_error (HRESULT hr, const char *context) void *lpMsgBuf; if (!FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, @@ -136,8 +137,9 @@ public: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" #endif + HMODULE d2d1 = _cairo_win32_load_library_from_system32 (L"d2d1.dll"); D2D1CreateFactoryFunc createD2DFactory = (D2D1CreateFactoryFunc) - GetProcAddress(LoadLibraryW(L"d2d1.dll"), "D2D1CreateFactory"); + GetProcAddress(d2d1, "D2D1CreateFactory"); #ifdef __GNUC__ #pragma GCC diagnostic pop #endif diff --git a/src/win32/cairo-dwrite-private.hpp b/src/win32/cairo-dwrite-private.hpp index 19c666da5..7834485f3 100644 --- a/src/win32/cairo-dwrite-private.hpp +++ b/src/win32/cairo-dwrite-private.hpp @@ -84,8 +84,9 @@ public: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" #endif + HMODULE dwrite = _cairo_win32_load_library_from_system32 (L"dwrite.dll"); DWriteCreateFactoryFunc createDWriteFactory = (DWriteCreateFactoryFunc) - GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"); + GetProcAddress(dwrite, "DWriteCreateFactory"); #ifdef __GNUC__ #pragma GCC diagnostic pop #endif diff --git a/src/win32/cairo-win32-device.c b/src/win32/cairo-win32-device.c index e000b11f6..91ef74588 100644 --- a/src/win32/cairo-win32-device.c +++ b/src/win32/cairo-win32-device.c @@ -76,54 +76,11 @@ static const cairo_device_backend_t _cairo_win32_device_backend = { _cairo_win32_device_destroy, }; -#if 0 -D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, - D2D1::PixelFormat( - DXGI_FORMAT_B8G8R8A8_UNORM, - D2D1_ALPHA_MODE_IGNORE), - 0, - 0, - D2D1_RENDER_TARGET_USAGE_NONE, - D2D1_FEATURE_LEVEL_DEFAULT - ); - -hr = m_pD2DFactory->CreateDCRenderTarget(&props, &device->d2d); -#endif - -static cairo_bool_t is_win98 (void) -{ - OSVERSIONINFO os; - - os.dwOSVersionInfoSize = sizeof (os); - GetVersionEx (&os); - - return (VER_PLATFORM_WIN32_WINDOWS == os.dwPlatformId && - os.dwMajorVersion == 4 && - os.dwMinorVersion == 10); -} - -static void * -_cairo_win32_device_get_alpha_blend (cairo_win32_device_t *device) -{ - void *func = NULL; - - if (is_win98 ()) - return NULL; - - device->msimg32_dll = LoadLibraryW (L"msimg32"); - if (device->msimg32_dll) - func = GetProcAddress (device->msimg32_dll, "AlphaBlend"); - - return func; -} - cairo_device_t * _cairo_win32_device_get (void) { cairo_win32_device_t *device; - CAIRO_MUTEX_INITIALIZE (); - if (__cairo_win32_device) return cairo_device_reference (__cairo_win32_device); @@ -133,9 +90,6 @@ _cairo_win32_device_get (void) device->compositor = _cairo_win32_gdi_compositor_get (); - device->msimg32_dll = NULL; - device->alpha_blend = _cairo_win32_device_get_alpha_blend (device); - if (_cairo_atomic_ptr_cmpxchg ((cairo_atomic_intptr_t *)&__cairo_win32_device, NULL, device)) return cairo_device_reference(&device->base); diff --git a/src/win32/cairo-win32-display-surface.c b/src/win32/cairo-win32-display-surface.c index 2800052bc..7f0770b4f 100644 --- a/src/win32/cairo-win32-display-surface.c +++ b/src/win32/cairo-win32-display-surface.c @@ -56,10 +56,6 @@ #include #include -#if defined(__MINGW32__) && !defined(ETO_PDY) -# define ETO_PDY 0x2000 -#endif - #define PELS_72DPI ((LONG)(72. / 0.0254)) /** @@ -99,8 +95,6 @@ _create_dc_and_bitmap (cairo_win32_display_surface_t *surface, unsigned char **bits_out, int *rowstride_out) { - cairo_status_t status; - BITMAPINFO *bitmap_info = NULL; struct { BITMAPINFOHEADER bmiHeader; @@ -205,16 +199,20 @@ _create_dc_and_bitmap (cairo_win32_display_surface_t *surface, } surface->win32.dc = CreateCompatibleDC (original_dc); - if (!surface->win32.dc) + if (!surface->win32.dc) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "CreateCompatibleDC"); goto FAIL; + } surface->bitmap = CreateDIBSection (surface->win32.dc, bitmap_info, DIB_RGB_COLORS, &bits, NULL, 0); - if (!surface->bitmap) + if (!surface->bitmap) { + _cairo_win32_print_api_error (__FUNCTION__, "CreateDIBSection"); goto FAIL; + } surface->is_dib = TRUE; @@ -222,8 +220,10 @@ _create_dc_and_bitmap (cairo_win32_display_surface_t *surface, surface->saved_dc_bitmap = SelectObject (surface->win32.dc, surface->bitmap); - if (!surface->saved_dc_bitmap) + if (!surface->saved_dc_bitmap) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SelectObject"); goto FAIL; + } if (bitmap_info && num_palette > 2) free (bitmap_info); @@ -260,8 +260,6 @@ _create_dc_and_bitmap (cairo_win32_display_surface_t *surface, return CAIRO_STATUS_SUCCESS; FAIL: - status = _cairo_win32_print_gdi_error (__FUNCTION__); - if (bitmap_info && num_palette > 2) free (bitmap_info); @@ -280,7 +278,7 @@ _create_dc_and_bitmap (cairo_win32_display_surface_t *surface, surface->win32.dc = NULL; } - return status; + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); } static cairo_surface_t * @@ -551,7 +549,7 @@ _cairo_win32_display_surface_flush (void *abstract_surface, unsigned flags) fallback->win32.dc, surface->win32.extents.x, surface->win32.extents.y, SRCCOPY)) - status = _cairo_win32_print_gdi_error (__FUNCTION__); + status = _cairo_win32_print_api_error (__FUNCTION__, "BitBlt"); } else if (damage->region) { int n = cairo_region_num_rectangles (damage->region), i; for (i = 0; i < n; i++) { @@ -568,7 +566,7 @@ _cairo_win32_display_surface_flush (void *abstract_surface, unsigned flags) fallback->win32.dc, rect.x, rect.y, SRCCOPY)) { - status = _cairo_win32_print_gdi_error (__FUNCTION__); + status = _cairo_win32_print_api_error (__FUNCTION__, "BitBlt"); break; } } @@ -619,7 +617,7 @@ _cairo_win32_save_initial_clip (HDC hdc, cairo_win32_display_surface_t *surface) clipBoxType = GetClipBox (hdc, &rect); if (clipBoxType == ERROR) { - _cairo_win32_print_gdi_error (__FUNCTION__); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetClipBox"); SetGraphicsMode (hdc, gm); /* XXX: Can we make a more reasonable guess at the error cause here? */ return _cairo_error (CAIRO_STATUS_DEVICE_ERROR); @@ -752,8 +750,10 @@ _cairo_win32_display_surface_set_clip (cairo_win32_display_surface_t *surface, /* AND the new region into our DC */ status = CAIRO_STATUS_SUCCESS; - if (ExtSelectClipRgn (surface->win32.dc, gdi_region, RGN_AND) == ERROR) - status = _cairo_win32_print_gdi_error (__FUNCTION__); + if (ExtSelectClipRgn (surface->win32.dc, gdi_region, RGN_AND) == ERROR) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "ExtSelectClipRgn"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } DeleteObject (gdi_region); diff --git a/src/win32/cairo-win32-font.c b/src/win32/cairo-win32-font.c index 3ad4f7ff4..1412c8bbc 100644 --- a/src/win32/cairo-win32-font.c +++ b/src/win32/cairo-win32-font.c @@ -45,19 +45,6 @@ #include -#ifndef SPI_GETFONTSMOOTHINGTYPE -#define SPI_GETFONTSMOOTHINGTYPE 0x200a -#endif -#ifndef FE_FONTSMOOTHINGCLEARTYPE -#define FE_FONTSMOOTHINGCLEARTYPE 2 -#endif -#ifndef CLEARTYPE_QUALITY -#define CLEARTYPE_QUALITY 5 -#endif -#ifndef TT_PRIM_CSPLINE -#define TT_PRIM_CSPLINE 3 -#endif - #define CMAP_TAG 0x70616d63 /** @@ -172,12 +159,12 @@ _get_global_font_dc (void) if (!hdc) { hdc = CreateCompatibleDC (NULL); if (!hdc) { - _cairo_win32_print_gdi_error ("_get_global_font_dc"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "CreateCompatibleDC"); return NULL; } if (!SetGraphicsMode (hdc, GM_ADVANCED)) { - _cairo_win32_print_gdi_error ("_get_global_font_dc"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SetGraphicsMode"); DeleteDC (hdc); return NULL; } @@ -271,7 +258,7 @@ _have_cleartype_quality (void) version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (!GetVersionEx (&version_info)) { - _cairo_win32_print_gdi_error ("_have_cleartype_quality"); + _cairo_win32_print_api_error (__FUNCTION__, "GetVersionEx"); return FALSE; } @@ -287,7 +274,7 @@ cairo_win32_get_system_text_quality (void) UINT smoothing_type; if (!SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) { - _cairo_win32_print_gdi_error ("_get_system_quality"); + _cairo_win32_print_api_error (__FUNCTION__, "SystemParametersInfo"); return DEFAULT_QUALITY; } @@ -295,7 +282,7 @@ cairo_win32_get_system_text_quality (void) if (_have_cleartype_quality ()) { if (!SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE, 0, &smoothing_type, 0)) { - _cairo_win32_print_gdi_error ("_get_system_quality"); + _cairo_win32_print_api_error (__FUNCTION__, "SystemParametersInfo"); return DEFAULT_QUALITY; } @@ -422,8 +409,10 @@ _win32_scaled_font_set_world_transform (cairo_win32_scaled_font_t *scaled_font, _cairo_matrix_to_win32_xform (&scaled_font->logical_to_device, &xform); - if (!SetWorldTransform (hdc, &xform)) - return _cairo_win32_print_gdi_error ("_win32_scaled_font_set_world_transform"); + if (!SetWorldTransform (hdc, &xform)) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SetWorldTransform"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } return CAIRO_STATUS_SUCCESS; } @@ -431,8 +420,10 @@ _win32_scaled_font_set_world_transform (cairo_win32_scaled_font_t *scaled_font, static cairo_status_t _win32_scaled_font_set_identity_transform (HDC hdc) { - if (!ModifyWorldTransform (hdc, NULL, MWT_IDENTITY)) - return _cairo_win32_print_gdi_error ("_win32_scaled_font_set_identity_transform"); + if (!ModifyWorldTransform (hdc, NULL, MWT_IDENTITY)) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "ModifyWorldTransform"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } return CAIRO_STATUS_SUCCESS; } @@ -450,8 +441,10 @@ _win32_scaled_font_get_scaled_hfont (cairo_win32_scaled_font_t *scaled_font, logfont.lfQuality = scaled_font->quality; scaled_font->scaled_hfont = CreateFontIndirectW (&logfont); - if (!scaled_font->scaled_hfont) - return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_scaled_hfont"); + if (!scaled_font->scaled_hfont) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "CreateFontIndirect"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } } *hfont_out = scaled_font->scaled_hfont; @@ -475,25 +468,30 @@ _win32_scaled_font_get_unscaled_hfont (cairo_win32_scaled_font_t *scaled_font, if (status) return status; - if (! SelectObject (hdc, scaled_hfont)) - return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:SelectObject"); + if (! SelectObject (hdc, scaled_hfont)) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SelectObject"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } otm_size = GetOutlineTextMetrics (hdc, 0, NULL); - if (! otm_size) - return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics"); + if (! otm_size) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetOutlineTextMetrics"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } otm = _cairo_malloc (otm_size); if (otm == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); if (! GetOutlineTextMetrics (hdc, otm_size, otm)) { - status = _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics"); - free (otm); - return status; + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetOutlineTextMetrics"); + free (otm); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); } scaled_font->em_square = otm->otmEMSquare; free (otm); + otm = NULL; logfont = scaled_font->logfont; logfont.lfHeight = -scaled_font->em_square; @@ -503,8 +501,10 @@ _win32_scaled_font_get_unscaled_hfont (cairo_win32_scaled_font_t *scaled_font, logfont.lfQuality = scaled_font->quality; scaled_font->unscaled_hfont = CreateFontIndirectW (&logfont); - if (! scaled_font->unscaled_hfont) - return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:CreateIndirect"); + if (! scaled_font->unscaled_hfont) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "CreateFontIndirect"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } } *hfont_out = scaled_font->unscaled_hfont; @@ -524,8 +524,10 @@ _cairo_win32_scaled_font_select_unscaled_font (cairo_scaled_font_t *scaled_font, return status; old_hfont = SelectObject (hdc, hfont); - if (!old_hfont) - return _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_select_unscaled_font"); + if (!old_hfont) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "CreateSolidBrush"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } status = _win32_scaled_font_set_identity_transform (hdc); if (status) { @@ -664,7 +666,7 @@ _cairo_win32_scaled_font_ucs4_to_index (void *abstract_font, unicode[0] = ucs4; unicode[1] = 0; if (GetGlyphIndicesW (hdc, unicode, 1, &glyph_index, 0) == GDI_ERROR) { - _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_ucs4_to_index:GetGlyphIndicesW"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetGlyphIndices"); glyph_index = 0; } @@ -694,7 +696,8 @@ _cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font) return status; if (!GetTextMetrics (hdc, &metrics)) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_set_metrics:GetTextMetrics"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetTextMetrics"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); } cairo_win32_scaled_font_done_font (&scaled_font->base); @@ -779,7 +782,8 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f return status; if (!GetCharWidth32(hdc, charIndex, charIndex, &width)) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetCharWidth32"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetCharWidth32"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); width = 0; } cairo_win32_scaled_font_done_font (&scaled_font->base); @@ -978,7 +982,8 @@ _flush_glyphs (cairo_glyph_state_t *state) elements, state->glyphs.num_elements, dx_elements)) { - return _cairo_win32_print_gdi_error ("_flush_glyphs"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "CreateSolidBrush"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); } _cairo_array_truncate (&state->glyphs, 0); @@ -1058,8 +1063,10 @@ _draw_glyphs_on_surface (cairo_win32_surface_t *surface, cairo_status_t status, status2; int i; - if (!SaveDC (surface->dc)) - return _cairo_win32_print_gdi_error ("_draw_glyphs_on_surface:SaveDC"); + if (!SaveDC (surface->dc)) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SaveDC"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } status = cairo_win32_scaled_font_select_font (&scaled_font->base, surface->dc); if (status) @@ -1180,8 +1187,8 @@ _cairo_win32_scaled_font_index_to_ucs4 (void *abstract_font, res = GetFontUnicodeRanges(hdc, NULL); if (res == 0) { - status = _cairo_win32_print_gdi_error ( - "_cairo_win32_scaled_font_index_to_ucs4:GetFontUnicodeRanges"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetFontUnicodeRanges"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto exit1; } @@ -1193,8 +1200,8 @@ _cairo_win32_scaled_font_index_to_ucs4 (void *abstract_font, res = GetFontUnicodeRanges(hdc, glyph_set); if (res == 0) { - status = _cairo_win32_print_gdi_error ( - "_cairo_win32_scaled_font_index_to_ucs4:GetFontUnicodeRanges"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetFontUnicodeRanges"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto exit1; } @@ -1219,8 +1226,8 @@ _cairo_win32_scaled_font_index_to_ucs4 (void *abstract_font, utf16[j] = 0; if (GetGlyphIndicesW (hdc, utf16, num_glyphs, glyph_indices, 0) == GDI_ERROR) { - status = _cairo_win32_print_gdi_error ( - "_cairo_win32_scaled_font_index_to_ucs4:GetGlyphIndicesW"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetGlyphIndices"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto exit2; } @@ -1489,7 +1496,8 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font &metrics, 0, NULL, &matrix); if (bytesGlyph == GDI_ERROR) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetGlyphOutline"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto CLEANUP_FONT; } @@ -1502,7 +1510,8 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph), GGO_NATIVE | GGO_GLYPH_INDEX, &metrics, bytesGlyph, buffer, &matrix) == GDI_ERROR) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GetGlyphOutline"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto CLEANUP_BUFFER; } @@ -2000,14 +2009,16 @@ cairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font, return status; old_hfont = SelectObject (hdc, hfont); - if (!old_hfont) - return _cairo_win32_print_gdi_error ("cairo_win32_scaled_font_select_font:SelectObject"); + if (!old_hfont) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SelectObject"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } old_mode = SetGraphicsMode (hdc, GM_ADVANCED); if (!old_mode) { - status = _cairo_win32_print_gdi_error ("cairo_win32_scaled_font_select_font:SetGraphicsMode"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SetGraphicsMode"); SelectObject (hdc, old_hfont); - return status; + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); } status = _win32_scaled_font_set_world_transform ((cairo_win32_scaled_font_t *)scaled_font, hdc); diff --git a/src/win32/cairo-win32-gdi-compositor.c b/src/win32/cairo-win32-gdi-compositor.c index bc1f69e70..347cd7ed5 100644 --- a/src/win32/cairo-win32-gdi-compositor.c +++ b/src/win32/cairo-win32-gdi-compositor.c @@ -55,23 +55,6 @@ #include "cairo-surface-inline.h" #include "cairo-surface-offset-private.h" -#if !defined(AC_SRC_OVER) -#define AC_SRC_OVER 0x00 -#pragma pack(1) -typedef struct { - BYTE BlendOp; - BYTE BlendFlags; - BYTE SourceConstantAlpha; - BYTE AlphaFormat; -}BLENDFUNCTION; -#pragma pack() -#endif - -/* for compatibility with VC++ 6 */ -#ifndef AC_SRC_ALPHA -#define AC_SRC_ALPHA 0x01 -#endif - #define PELS_72DPI ((LONG)(72. / 0.0254)) /* the low-level interface */ @@ -105,7 +88,6 @@ struct copy_box { int tx, ty; HDC dst, src; BLENDFUNCTION bf; - cairo_win32_alpha_blend_func_t alpha_blend; }; static cairo_bool_t copy_box (cairo_box_t *box, void *closure) @@ -131,9 +113,9 @@ static cairo_bool_t alpha_box (cairo_box_t *box, void *closure) int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y); TRACE ((stderr, "%s\n", __FUNCTION__)); - return cb->alpha_blend (cb->dst, x, y, width, height, - cb->src, x + cb->tx, y + cb->ty, width, height, - cb->bf); + return AlphaBlend (cb->dst, x, y, width, height, + cb->src, x + cb->tx, y + cb->ty, width, height, + cb->bf); } struct upload_box { @@ -184,8 +166,10 @@ fill_boxes (cairo_win32_display_surface_t *dst, fb.dc = dst->win32.dc; fb.brush = CreateSolidBrush (color_to_rgb(color)); - if (!fb.brush) - return _cairo_win32_print_gdi_error (__FUNCTION__); + if (!fb.brush) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "CreateSolidBrush"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } if (! _cairo_boxes_for_each_box (boxes, fill_box, &fb)) status = CAIRO_INT_STATUS_UNSUPPORTED; @@ -382,7 +366,6 @@ alpha_blend_boxes (cairo_win32_display_surface_t *dst, cb.bf.BlendFlags = 0; cb.bf.SourceConstantAlpha = alpha; cb.bf.AlphaFormat = (src->win32.format == CAIRO_FORMAT_ARGB32) ? AC_SRC_ALPHA : 0; - cb.alpha_blend = to_win32_device(dst->win32.base.device)->alpha_blend; cb.tx += cb.limit.x; cb.ty += cb.limit.y; @@ -397,10 +380,7 @@ alpha_blend_boxes (cairo_win32_display_surface_t *dst, static cairo_bool_t can_alpha_blend (cairo_win32_display_surface_t *dst) { - if ((dst->win32.flags & CAIRO_WIN32_SURFACE_CAN_ALPHABLEND) == 0) - return FALSE; - - return to_win32_device(dst->win32.base.device)->alpha_blend != NULL; + return (dst->win32.flags & CAIRO_WIN32_SURFACE_CAN_ALPHABLEND) != 0; } static cairo_status_t diff --git a/src/win32/cairo-win32-printing-surface.c b/src/win32/cairo-win32-printing-surface.c index 8305ede9c..c5b5f5cab 100644 --- a/src/win32/cairo-win32-printing-surface.c +++ b/src/win32/cairo-win32-printing-surface.c @@ -477,8 +477,10 @@ _cairo_win32_printing_surface_select_solid_brush (cairo_win32_printing_surface_t color = _cairo_win32_printing_surface_flatten_transparency (surface, &pattern->color); surface->brush = CreateSolidBrush (color); - if (!surface->brush) - return _cairo_win32_print_gdi_error ("_cairo_win32_surface_select_solid_brush(CreateSolidBrush)"); + if (!surface->brush) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "CreateSolidBrush"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } surface->old_brush = SelectObject (surface->win32.dc, surface->brush); return CAIRO_STATUS_SUCCESS; @@ -501,13 +503,17 @@ _cairo_win32_printing_surface_get_ctm_clip_box (cairo_win32_printing_surface_t * XFORM xform; _cairo_matrix_to_win32_xform (&surface->ctm, &xform); - if (!ModifyWorldTransform (surface->win32.dc, &xform, MWT_LEFTMULTIPLY)) - return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_get_clip_box:ModifyWorldTransform"); + if (!ModifyWorldTransform (surface->win32.dc, &xform, MWT_LEFTMULTIPLY)) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "ModifyWorldTransform"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } GetClipBox (surface->win32.dc, clip); _cairo_matrix_to_win32_xform (&surface->gdi_ctm, &xform); - if (!SetWorldTransform (surface->win32.dc, &xform)) - return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_get_clip_box:SetWorldTransform"); + if (!SetWorldTransform (surface->win32.dc, &xform)) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SetWorldTransform"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } return CAIRO_STATUS_SUCCESS; } @@ -887,7 +893,8 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_printing_surface_ _cairo_matrix_to_win32_xform (&m, &xform); if (! SetWorldTransform (surface->win32.dc, &xform)) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_paint_image_pattern"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SetWorldTransform"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto CLEANUP_OPAQUE_IMAGE; } @@ -922,7 +929,8 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_printing_surface_ DIB_RGB_COLORS, SRCCOPY)) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_paint(StretchDIBits)"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "StretchDIBits"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto CLEANUP_OPAQUE_IMAGE; } } @@ -996,8 +1004,10 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_printing_surface _cairo_matrix_to_win32_xform (&mat, &xform); - if (!SetWorldTransform (surface->win32.dc, &xform)) - return _cairo_win32_print_gdi_error ("_win32_printing_surface_paint_linear_pattern:SetWorldTransform2"); + if (!SetWorldTransform (surface->win32.dc, &xform)) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SetWorldTransform"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } GetClipBox (surface->win32.dc, &clip); @@ -1086,7 +1096,10 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_printing_surface vert, total_verts, rect, total_rects, GRADIENT_FILL_RECT_H)) - return _cairo_win32_print_gdi_error ("_win32_printing_surface_paint_linear_pattern:GradientFill"); + { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "GradientFill"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } free (rect); free (vert); @@ -1556,13 +1569,15 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, style->num_dashes, dash_array); if (pen == NULL) { - status = _cairo_win32_print_gdi_error ("_win32_surface_stroke:ExtCreatePen"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "ExtCreatePen"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto cleanup_composite; } obj = SelectObject (surface->win32.dc, pen); if (obj == NULL) { - status = _cairo_win32_print_gdi_error ("_win32_surface_stroke:SelectObject"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SelectObject"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto cleanup_composite; } @@ -1582,7 +1597,8 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, xform.eDy = 0.0f; if (!ModifyWorldTransform (surface->win32.dc, &xform, MWT_LEFTMULTIPLY)) { - status = _cairo_win32_print_gdi_error ("_win32_surface_stroke:SetWorldTransform"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "ModifyWorldTransform"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto cleanup_composite; } @@ -1590,18 +1606,21 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, StrokePath (surface->win32.dc); } else { if (!WidenPath (surface->win32.dc)) { - status = _cairo_win32_print_gdi_error ("_win32_surface_stroke:WidenPath"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "WidenPath"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto cleanup_composite; } if (!SelectClipPath (surface->win32.dc, RGN_AND)) { - status = _cairo_win32_print_gdi_error ("_win32_surface_stroke:SelectClipPath"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SelectClipPath"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto cleanup_composite; } /* Return to device space to paint the pattern */ _cairo_matrix_to_win32_xform (&surface->gdi_ctm, &xform); if (!SetWorldTransform (surface->win32.dc, &xform)) { - status = _cairo_win32_print_gdi_error ("_win32_surface_stroke:ModifyWorldTransform"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "SetWorldTransform"); + status = _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); goto cleanup_composite; } status = _cairo_win32_printing_surface_paint_pattern (surface, source, &extents.bounded); @@ -2102,8 +2121,10 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface) surface->ctm.x0 = xform.eDx; surface->ctm.y0 = xform.eDy; cairo_matrix_init_identity (&surface->gdi_ctm); - if (!ModifyWorldTransform (surface->win32.dc, NULL, MWT_IDENTITY)) - return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_start_page:ModifyWorldTransform"); + if (!ModifyWorldTransform (surface->win32.dc, NULL, MWT_IDENTITY)) { + fprintf (stderr, "%s:%s\n", __FUNCTION__, "ModifyWorldTransform"); + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); + } } surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm); diff --git a/src/win32/cairo-win32-private.h b/src/win32/cairo-win32-private.h index 6af09c0e1..ae8dc52c3 100644 --- a/src/win32/cairo-win32-private.h +++ b/src/win32/cairo-win32-private.h @@ -44,13 +44,6 @@ #include "cairo-surface-clipper-private.h" #include "cairo-surface-private.h" -#ifndef SHADEBLENDCAPS -#define SHADEBLENDCAPS 120 -#endif -#ifndef SB_NONE -#define SB_NONE 0 -#endif - #define WIN32_FONT_LOGICAL_SCALE 32 CAIRO_BEGIN_DECLS @@ -168,26 +161,10 @@ typedef struct _cairo_win32_printing_surface { } cairo_win32_printing_surface_t; #define to_win32_printing_surface(S) ((cairo_win32_printing_surface_t *)(S)) -typedef BOOL (WINAPI *cairo_win32_alpha_blend_func_t) (HDC hdcDest, - int nXOriginDest, - int nYOriginDest, - int nWidthDest, - int hHeightDest, - HDC hdcSrc, - int nXOriginSrc, - int nYOriginSrc, - int nWidthSrc, - int nHeightSrc, - BLENDFUNCTION blendFunction); - typedef struct _cairo_win32_device { cairo_device_t base; - HMODULE msimg32_dll; - const cairo_compositor_t *compositor; - - cairo_win32_alpha_blend_func_t alpha_blend; } cairo_win32_device_t; #define to_win32_device(D) ((cairo_win32_device_t *)(D)) #define to_win32_device_from_surface(S) to_win32_device(((cairo_surface_t *)(S))->device) @@ -199,7 +176,7 @@ const cairo_compositor_t * _cairo_win32_gdi_compositor_get (void); cairo_status_t -_cairo_win32_print_gdi_error (const char *context); +_cairo_win32_print_api_error (const char *context, const char *api); cairo_bool_t _cairo_surface_is_win32 (const cairo_surface_t *surface); @@ -260,6 +237,9 @@ _cairo_win32_scaled_font_is_bitmap (cairo_scaled_font_t *scaled_font); cairo_public BYTE cairo_win32_get_system_text_quality (void); +HMODULE +_cairo_win32_load_library_from_system32 (const wchar_t *name); + #if CAIRO_HAS_DWRITE_FONT cairo_int_status_t diff --git a/src/win32/cairo-win32-surface.c b/src/win32/cairo-win32-surface.c index ca5c9d823..e1ac51558 100644 --- a/src/win32/cairo-win32-surface.c +++ b/src/win32/cairo-win32-surface.c @@ -53,10 +53,6 @@ #include #include -#if defined(__MINGW32__) && !defined(ETO_PDY) -# define ETO_PDY 0x2000 -#endif - /** * SECTION:cairo-win32 * @Title: Win32 Surfaces @@ -83,40 +79,6 @@ * Since: 1.0 **/ -/** - * _cairo_win32_print_gdi_error: - * @context: 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 - **/ -cairo_status_t -_cairo_win32_print_gdi_error (const char *context) -{ - void *lpMsgBuf; - DWORD last_error = GetLastError (); - - if (!FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - last_error, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPWSTR) &lpMsgBuf, - 0, NULL)) { - fprintf (stderr, "%s: Unknown GDI error", context); - } else { - fprintf (stderr, "%s: %S", context, (wchar_t *)lpMsgBuf); - - LocalFree (lpMsgBuf); - } - - fflush (stderr); - - return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); -} - cairo_bool_t _cairo_win32_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) @@ -322,7 +284,7 @@ _cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst, num_glyphs, dxy_buf); if (!win_result) { - _cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)"); + fprintf (stderr, "%s:%s\n", __FUNCTION__, "ExtTextOut"); } RestoreDC(dst->dc, -1); diff --git a/src/win32/cairo-win32-system.c b/src/win32/cairo-win32-system.c index 01bbe89df..c5ef24e8d 100644 --- a/src/win32/cairo-win32-system.c +++ b/src/win32/cairo-win32-system.c @@ -44,37 +44,129 @@ * And no other function should live here. */ - #include "cairoint.h" -#if CAIRO_MUTEX_IMPL_WIN32 -#if !CAIRO_WIN32_STATIC_BUILD - #include -/* declare to avoid "no previous prototype for 'DllMain'" warning */ -BOOL WINAPI -DllMain (HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved); - -BOOL WINAPI -DllMain (HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) +/** + * _cairo_win32_print_api_error: + * @context: context string to display along with the error + * @api: name of the failing api + * + * Helper function to dump out a human readable form of the + * current error code. + * + * Return value: A cairo status code for the error code + **/ +cairo_status_t +_cairo_win32_print_api_error (const char *context, const char *api) { - switch (fdwReason) { + const DWORD lang_id = MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT); + const DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM; + const DWORD last_error = GetLastError (); + void *lpMsgBuf = NULL; + + if (!FormatMessageW (flags, NULL, last_error, lang_id, (LPWSTR) &lpMsgBuf, 0, NULL)) { + fprintf (stderr, "%s: %s failed with error code %lu\n", context, api, last_error); + } + else { + fprintf (stderr, "%s: %s failed - %S\n", context, api, (wchar_t *)lpMsgBuf); + LocalFree (lpMsgBuf); + } + + return _cairo_error (CAIRO_STATUS_WIN32_GDI_ERROR); +} + +/** + * _cairo_win32_load_library_from_system32: + * @name: name of the module to load from System32 + * + * Helper function to load system modules in the System32 + * folder. + * + * Return value: An module HANDLE, NULL on error. + **/ +HMODULE +_cairo_win32_load_library_from_system32 (const wchar_t *name) +{ + HMODULE module_handle; + + module_handle = LoadLibraryExW (name, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (module_handle == NULL) { + DWORD code = GetLastError(); + if (code == ERROR_INVALID_PARAMETER) { + /* Support for flag LOAD_LIBRARY_SEARCH_SYSTEM32 was backported + * to Windows Vista / 7 with Update KB2533623. If the flag is + * not supported, simply use LoadLibrary */ + return LoadLibraryW (name); + } + } + + return module_handle; +} + +#if CAIRO_MUTEX_IMPL_WIN32 + +static void NTAPI +cairo_win32_tls_callback (PVOID hinstance, DWORD dwReason, PVOID lpvReserved) +{ + switch (dwReason) { case DLL_PROCESS_ATTACH: CAIRO_MUTEX_INITIALIZE (); break; case DLL_PROCESS_DETACH: - CAIRO_MUTEX_FINALIZE (); + if (lpvReserved == NULL) { + CAIRO_MUTEX_FINALIZE (); + } break; } - - return TRUE; } +#ifdef _MSC_VER + +#ifdef _M_IX86 +# define SYMBOL_PREFIX "_" +#else +# define SYMBOL_PREFIX "" #endif + +#ifdef __cplusplus +# define EXTERN_C_BEGIN extern "C" { +# define EXTERN_C_END } +# define EXTERN_CONST extern const +#else +# define EXTERN_C_BEGIN +# define EXTERN_C_END +# define EXTERN_CONST const #endif + +#define DEFINE_TLS_CALLBACK(func) \ +__pragma (section (".CRT$XLD", long, read)) \ + \ +static void NTAPI func (PVOID, DWORD, PVOID); \ + \ +EXTERN_C_BEGIN \ +__declspec (allocate (".CRT$XLD")) \ +EXTERN_CONST PIMAGE_TLS_CALLBACK _ptr_##func = func; \ +EXTERN_C_END \ + \ +__pragma (comment (linker, "/INCLUDE:" SYMBOL_PREFIX "_tls_used")) \ +__pragma (comment (linker, "/INCLUDE:" SYMBOL_PREFIX "_ptr_" #func)) + +#else /* _MSC_VER */ + +#define DEFINE_TLS_CALLBACK(func) \ +static void NTAPI func (PVOID, DWORD, PVOID); \ + \ +__attribute__ ((used, section (".CRT$XLD"))) \ +static const PIMAGE_TLS_CALLBACK _ptr_##func = func; + + +#endif /* !_MSC_VER */ + +DEFINE_TLS_CALLBACK (cairo_win32_tls_callback); + +#endif /* CAIRO_MUTEX_IMPL_WIN32 */