cairo_win32_printing_surface_create work bad after upgrade version

Kęstutis dbtopas at dbtopas.lt
Thu Jan 11 15:07:33 UTC 2024


Hello,

We are using cairolib some years. We use recording surfaces extensively: 
we build report page as recording surface, then we are making pdf 
(create_pdf_surface) from this surface, preview it and print it 
(create_win32_printing_surface). It worked fine with cairo version 1.10

Now we are trying to migrate to version 1.18, 
create_win32_printing_surface shows incomplete information on screen and 
printed. Does someone has recipe to avoid this.

Example attached (Compile msys and mingw32)

Kestutisp.s. I guess that there is some transform issue, because I write object 
sizes and placements in 10 micrometers in recording surface, and 
therefore transformation matrix is 72/2540, 0, 0, 72/2540, 0, 0 for pdf 
and GetDeviceCaps(hDC, LOGPIXELSX)/2540, 0, 0, GetDeviceCaps(hDC, 
LOGPIXELSY)/2540, 0, 0 p.s. I register issues in 
https://gitlab.freedesktop.org/cairo/cairo/-/issues/817
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.cairographics.org/archives/cairo/attachments/20240111/8ce6bff0/attachment.htm>
-------------- next part --------------
#include <windows.h>
#include <cairo/cairo.h>
#include <cairo/cairo-pdf.h>
#include <cairo/cairo-win32.h>

LRESULT CALLBACK MainWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
void DoSurface(cairo_surface_t * hSurf, int nDPI);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  WNDCLASS wc;
  LPCTSTR MainWndClass = TEXT("BugCairo");
  HWND hWnd;
  MSG msg;

  ZeroMemory(&wc,sizeof(wc));
  wc.lpfnWndProc   = &MainWndProc; 
  wc.hInstance     = hInstance;
  wc.lpszClassName = MainWndClass;
  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  wc.hCursor       = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));

  if (! RegisterClass(&wc))
  {
    MessageBox(NULL, TEXT("Error registering window class."), TEXT("Error"), MB_ICONERROR | MB_OK);
    return 0;
  }

  // Create instance of main window.
  hWnd = CreateWindow(MainWndClass, cairo_version_string(), WS_OVERLAPPEDWINDOW,
                      100, 50, 1000, 500, NULL, NULL, hInstance, NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  while(GetMessage(&msg, NULL, 0, 0) > 0)
  {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
  }
  return (int)msg.wParam;
}

LRESULT CALLBACK MainWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
  switch (uMsg) 
   { 
    case WM_CREATE: 
      HMENU hMenu = CreateMenu();
      AppendMenu(hMenu, MF_STRING | MF_ENABLED, 301, "MakePDF");
      AppendMenu(hMenu, MF_STRING | MF_ENABLED, 302, "Print");
      SetMenu(hWnd, hMenu);
      return 0; 
 
    case WM_COMMAND: 
     switch (wParam)
       {
         case 301:
           cairo_surface_t * hSurf;
           hSurf = cairo_pdf_surface_create("cairo_bug.pdf",  297 * 72 / 25.40, 210 * 72 / 25.40);
           DoSurface(hSurf, 72); 
           MessageBox(NULL, TEXT("Pdf created"), TEXT("Info"),  MB_OK);
         return 0;
         case 302:
           HDC  hDC;
           hDC = CreateDC(NULL,"Microsoft Print to PDF",NULL,NULL);
           if(hDC==NULL)
           {
             MessageBox(NULL, TEXT("Invalide printer name"), TEXT("Error"),  MB_ICONERROR|MB_OK);
           }
           else
           {
             DOCINFOA sDI;
             ZeroMemory(&sDI,sizeof(sDI));
             sDI.cbSize      = sizeof(sDI);
             sDI.lpszDocName = "Cairo Bug";
             StartDoc(hDC, &sDI);
             StartPage(hDC); 
             hSurf = cairo_win32_printing_surface_create(hDC);
             DoSurface(hSurf,GetDeviceCaps(hDC, LOGPIXELSX)); 
             EndPage(hDC);
             EndDoc(hDC);
             DeleteDC(hDC);
           }
         return 0;
       }
     return 0;

    case WM_PAINT: 
       HDC             hDC;
       cairo_surface_t * hSurf;
       PAINTSTRUCT     sPS;

       hDC   = BeginPaint(hWnd, &sPS);
       hSurf = cairo_win32_printing_surface_create(hDC); //
       DoSurface(hSurf, GetDeviceCaps(hDC, LOGPIXELSX)); 
       EndPaint(hWnd, &sPS);
      return 0; 

    case WM_DESTROY: 
      PostQuitMessage(1);
      return 0; 

    default: 
      return DefWindowProc(hWnd, uMsg, wParam, lParam); 
   } 
   return 0; 
}

void DoSurface(cairo_surface_t * hSurf, int nDPI){
  cairo_t             * hC; 
  cairo_surface_t     * hRecSurf;
  cairo_rectangle_t   sRect;
  cairo_matrix_t      sMatrix;

  sRect.x      = 0;
  sRect.y      = 0;
  sRect.width  = 120000;
  sRect.height = 32000;

  hRecSurf = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, &sRect);
  hC = cairo_create(hRecSurf);
  cairo_set_source_rgb(hC, 0, 0, 0);
  cairo_select_font_face(hC, "Times New Roman",0,0);
  cairo_set_font_size(hC, 2500);
  cairo_move_to(hC, 1000, 5000);
  cairo_show_text(hC, "Some text size 2500");
  cairo_stroke(hC);

  cairo_set_font_size(hC, 3000);
  cairo_move_to(hC, 1000, 10000);
  cairo_show_text(hC, "Some text size 3000");
  cairo_stroke(hC);
  cairo_destroy(hC);

  hC = cairo_create(hSurf);
  sMatrix.xx = nDPI / 2540.0 ;
  sMatrix.yx = 0;
  sMatrix.xy = 0;
  sMatrix.yy = nDPI / 2540.0 ;
  sMatrix.x0 = 0;
  sMatrix.y0 = 0;
  
  cairo_transform(hC, &sMatrix);
  cairo_set_source_surface(hC, hRecSurf, 0, 0);
  cairo_paint(hC);
  cairo_destroy(hC);
  cairo_surface_destroy(hSurf);
  cairo_surface_destroy(hRecSurf);
  return;
}


More information about the cairo mailing list