// Testcase showing assertion failure in Cairo 1.10.0 when using CAIRO_OPERATOR_DIFFERENCE on win32 surfaces. #include #include #include #include static void paint_cairo(cairo_t *cr){ cairo_set_source_rgb(cr, 1,1,1); cairo_paint(cr); cairo_move_to(cr, 0.3, 0.3); cairo_line_to(cr, 0.7, 0.3); cairo_line_to(cr, 0.7, 0.7); // comment out the following line to get a triangle => no crash cairo_line_to(cr, 0.3, 0.7); cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); cairo_set_source_rgb(cr, 1,1,1); cairo_fill(cr); // booom! } static void on_paint(HDC hdc, long width, long height){ cairo_surface_t *surface = cairo_win32_surface_create(hdc); cairo_t *cr = cairo_create(surface); cairo_scale(cr, width, height); paint_cairo(cr); cairo_destroy(cr); cairo_surface_destroy(surface); } LRESULT CALLBACK WndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam){ PAINTSTRUCT paintStruct; HBITMAP buffer; HDC dc, bufferdc; RECT clientRect; switch(message){ case WM_ERASEBKGND: return 0; case WM_PAINT: GetClientRect(window, &clientRect); dc = BeginPaint(window, &paintStruct); bufferdc = CreateCompatibleDC(dc); buffer = CreateCompatibleBitmap(dc, clientRect.right, clientRect.bottom); SelectObject(bufferdc, buffer); on_paint(bufferdc, clientRect.right, clientRect.bottom); BitBlt(dc, 0, 0, clientRect.right, clientRect.bottom, bufferdc, 0, 0, SRCCOPY); DeleteDC(bufferdc); DeleteObject(buffer); EndPaint(window, &paintStruct); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(window, message, wParam, lParam); } INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT iCmdShow){ HWND window; MSG message; WNDCLASS window_class; RECT rect; printf("cairo version: %s\n", cairo_version_string()); DWORD windowStyle = WS_OVERLAPPEDWINDOW; const char * windowClassName = "Cairo Test"; window_class.style = CS_HREDRAW | CS_VREDRAW; window_class.lpfnWndProc = WndProc; window_class.cbClsExtra = 0; window_class.cbWndExtra = 0; window_class.hInstance = hInstance; window_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); window_class.hCursor = LoadCursor(NULL, IDC_ARROW); window_class.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH); window_class.lpszMenuName = NULL; window_class.lpszClassName = windowClassName; RegisterClass(&window_class); rect.left = 0; rect.top = 0; rect.right = 400; rect.bottom = 400; AdjustWindowRect(&rect, windowStyle, FALSE); window = CreateWindow(windowClassName, "Cairo Patterns - Test", windowStyle, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hInstance, NULL); ShowWindow(window, iCmdShow); UpdateWindow(window); while(GetMessage(&message, NULL, 0, 0)){ TranslateMessage(&message); DispatchMessage(&message); } return (int)message.wParam; }