diff options
Diffstat (limited to 'src/cairo')
| -rw-r--r-- | src/cairo/cdcairo.c | 2 | ||||
| -rw-r--r-- | src/cairo/cdcairoctx.h | 5 | ||||
| -rw-r--r-- | src/cairo/cdcairoemf.c | 122 | ||||
| -rw-r--r-- | src/cairo/cdcairoplus.c | 6 | ||||
| -rw-r--r-- | src/cairo/cdcairoprn_unix.c (renamed from src/cairo/cdcairoprn.c) | 0 | ||||
| -rw-r--r-- | src/cairo/cdcairoprn_win32.c | 190 | ||||
| -rw-r--r-- | src/cairo/cdcairosvg.c | 3 | 
7 files changed, 323 insertions, 5 deletions
diff --git a/src/cairo/cdcairo.c b/src/cairo/cdcairo.c index 869e0ed..5443b90 100644 --- a/src/cairo/cdcairo.c +++ b/src/cairo/cdcairo.c @@ -1658,7 +1658,7 @@ static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)    cairo_identity_matrix(ctxcanvas->cr);    if (ctxcanvas->job) -    cairo_scale(ctxcanvas->cr, 0.254, 0.254); +    cairo_scale(ctxcanvas->cr, 0.25, 0.25);  /* ??? */    if (matrix)      ctxcanvas->canvas->invert_yaxis = 0; diff --git a/src/cairo/cdcairoctx.h b/src/cairo/cdcairoctx.h index 776e8a8..8d1012c 100644 --- a/src/cairo/cdcairoctx.h +++ b/src/cairo/cdcairoctx.h @@ -69,10 +69,11 @@ struct _cdCtxCanvas    int eps;  /* used in PS */ -  cdImage* image_dbuffer;       /* Used by double buffer driver */ +  cdImage* image_dbuffer;       /* Used in double buffer driver */    cdCanvas* canvas_dbuffer; -  GtkPrintJob* job;    /* used in Printer */ +  GtkPrintJob* job;    /* used in Printer (UNIX) */ +  char* printername;   /* used in Printer (Win32) */  };  #define cdCairoGetRed(_)   (((double)cdRed(_))/255.) diff --git a/src/cairo/cdcairoemf.c b/src/cairo/cdcairoemf.c new file mode 100644 index 0000000..979caa7 --- /dev/null +++ b/src/cairo/cdcairoemf.c @@ -0,0 +1,122 @@ +/** \file + * \brief EMF Printer Driver  (Win32 Only) + * + * See Copyright Notice in cd.h + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <windows.h> + +#include "cdcairoctx.h" +#include "cdprint.h" + +#include "cairo-win32.h" + + +static void cdkillcanvas(cdCtxCanvas *ctxcanvas) +{ +  cairo_surface_t* surface = cairo_get_target(ctxcanvas->cr); +  HDC hDC = cairo_win32_surface_get_dc(surface); +  HENHMETAFILE hEMF; + +  cairo_surface_finish(surface); + +  hEMF = CloseEnhMetaFile (hDC); +  DeleteEnhMetaFile (hEMF); + +  cdcairoKillCanvas(ctxcanvas); +} + +static void cdflush(cdCtxCanvas *ctxcanvas) +{ +  (void)ctxcanvas; +  /* does nothing in EMF */ +} + +static void cdcreatecanvas(cdCanvas* canvas, void *data) +{ +  cdCtxCanvas* ctxcanvas; +  char* strdata = (char*)data; +  int w = 0, h = 0; +  double xres, yres; +  FILE* file; +  char filename[10240] = ""; +  HDC ScreenDC, hDC; +  RECT rect; +  HRGN clip_hrgn; +   +  /* Inicializa parametros */ +  if (strdata == NULL)  +    return; + +  strdata += cdGetFileName(strdata, filename); +  if (filename[0] == 0) +    return; +  +  sscanf(strdata,"%dx%d", &w, &h);  +  if (w == 0 || h == 0) +    return; +   +  /* Verifica se o arquivo pode ser aberto para escrita */ +  file = fopen(filename, "wb"); +  if (file == NULL) return; +  fclose(file); +   +  ScreenDC = GetDC(NULL); +  /* LOGPIXELS can not be used for EMF */ +  xres = (double)GetDeviceCaps(ScreenDC, HORZRES) / (double)GetDeviceCaps(ScreenDC, HORZSIZE); +  yres = (double)GetDeviceCaps(ScreenDC, VERTRES) / (double)GetDeviceCaps(ScreenDC, VERTSIZE); +  /* The rectangle dimensions are given in hundredths of a millimeter */ +  rect.left = 0; +  rect.top = 0; +  rect.right = (int)(100. * w / xres); +  rect.bottom = (int)(100. * h / yres); +  hDC = CreateEnhMetaFile(ScreenDC,filename,&rect,NULL); +  ReleaseDC(NULL, ScreenDC); + +  if(!hDC) +    return; + +  canvas->w = w; +  canvas->h = h; +  canvas->xres = xres; +  canvas->yres = yres; +  canvas->w_mm = ((double)w) / xres; +  canvas->h_mm = ((double)h) / yres; +  canvas->bpp = 24; + +  /* The DC will be queried for its initial clip extents, and this will be used as the size of the cairo surface. */ +  clip_hrgn = CreateRectRgn(0, 0, canvas->w, canvas->h); +  SelectClipRgn(hDC, clip_hrgn); +  DeleteObject(clip_hrgn); + +  ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(cairo_win32_printing_surface_create(hDC))); +} + +static void cdinittable(cdCanvas* canvas) +{ +  cdcairoInitTable(canvas); +   +  canvas->cxFlush = cdflush; +  canvas->cxKillCanvas = cdkillcanvas; +} + +static cdContext cdEMFCairoContext = +{ +  CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_GETIMAGERGB | +                 CD_CAP_WRITEMODE | CD_CAP_PALETTE | CD_CAP_IMAGESRV), +  0, +  cdcreatecanvas, +  cdinittable, +  NULL, +  NULL, +}; + +cdContext* cdContextCairoEMF(void) +{ +  return &cdEMFCairoContext; +} + diff --git a/src/cairo/cdcairoplus.c b/src/cairo/cdcairoplus.c index 5da7546..a46d9f3 100644 --- a/src/cairo/cdcairoplus.c +++ b/src/cairo/cdcairoplus.c @@ -10,6 +10,7 @@  #include <stdlib.h>  #include <memory.h> +  void cdInitContextPlus(void)  {    cdContext* ctx_list[NUM_CONTEXTPLUS]; @@ -18,9 +19,12 @@ void cdInitContextPlus(void)    ctx_list[CD_CTX_NATIVEWINDOW] = cdContextCairoNativeWindow();    ctx_list[CD_CTX_IMAGE] = cdContextCairoImage();    ctx_list[CD_CTX_DBUFFER] = cdContextCairoDBuffer(); -#ifndef WIN32 +#ifndef CAIRO_X11    ctx_list[CD_CTX_PRINTER] = cdContextCairoPrinter();  #endif +#ifdef WIN32 +  ctx_list[CD_CTX_EMF] = cdContextCairoEMF(); +#endif    cdInitContextPlusList(ctx_list);  } diff --git a/src/cairo/cdcairoprn.c b/src/cairo/cdcairoprn_unix.c index b201230..b201230 100644 --- a/src/cairo/cdcairoprn.c +++ b/src/cairo/cdcairoprn_unix.c diff --git a/src/cairo/cdcairoprn_win32.c b/src/cairo/cdcairoprn_win32.c new file mode 100644 index 0000000..9869d03 --- /dev/null +++ b/src/cairo/cdcairoprn_win32.c @@ -0,0 +1,190 @@ +/** \file + * \brief Cairo/GTK Printer Driver  (Win32 Only) + * + * See Copyright Notice in cd.h + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <windows.h> + +#include "cdcairoctx.h" +#include "cdprint.h" + +#include "cairo-win32.h" + + +static void cdkillcanvas(cdCtxCanvas *ctxcanvas) +{ +  cairo_surface_t* surface = cairo_get_target(ctxcanvas->cr); +  HDC hDC = cairo_win32_surface_get_dc(surface); + +  cairo_surface_finish(surface); + +  EndDoc(hDC); +  DeleteDC(hDC); + +  if (ctxcanvas->printername) +    free(ctxcanvas->printername); + +  cdcairoKillCanvas(ctxcanvas); +} + +static void cdflush(cdCtxCanvas *ctxcanvas) +{ +  cairo_surface_t* surface = cairo_get_target(ctxcanvas->cr); +  HDC hDC = cairo_win32_surface_get_dc(surface); + +  cairo_surface_flush(surface); +  cairo_show_page(ctxcanvas->cr); + +  GdiFlush(); +  EndPage(hDC); + +  StartPage(hDC); +} + +static char* get_printername_attrib(cdCtxCanvas* ctxcanvas) +{ +  return ctxcanvas->printername; +} + +static cdAttribute printername_attrib = +{ +  "PRINTERNAME", +  NULL, +  get_printername_attrib +};  + +static void cdcreatecanvas(cdCanvas* canvas, void *data) +{ +  cdCtxCanvas* ctxcanvas; +  char *data_str = (char*) data; +  char docname[256] = "CD - Canvas Draw Document"; +  DOCINFO di; +  HDC hDC; +  int dialog = 0; +  PRINTDLG pd; +  HRGN clip_hrgn; + +  /* Inicializa parametros */ +  if (data_str == NULL)  +    return; +   +  if (data_str[0] != 0) +  { +    char *ptr = strstr(data_str, "-d"); + +    if (ptr != NULL) +      dialog = 1; + +    if (data_str[0] != '-') +    { +      strcpy(docname, data_str); + +      if (dialog) +        docname[ptr - data_str - 1] = 0; +    } +  } +   +  ZeroMemory(&pd, sizeof(PRINTDLG)); +  pd.lStructSize = sizeof(PRINTDLG); +  pd.nCopies = 1; + +  if (dialog) +  { +    pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIES | PD_COLLATE | PD_NOPAGENUMS | PD_NOSELECTION; +    pd.hwndOwner = GetForegroundWindow(); +  } +  else +  { +    pd.Flags = PD_RETURNDC | PD_RETURNDEFAULT; +  } +   +  if (!PrintDlg(&pd)) +  { +    if(pd.hDevMode)  +      GlobalFree(pd.hDevMode); +    if(pd.hDevNames)  +      GlobalFree(pd.hDevNames); +    return; +  } + +  hDC = pd.hDC;  + +  canvas->w = GetDeviceCaps(hDC, HORZRES); +  canvas->h = GetDeviceCaps(hDC, VERTRES); +  canvas->w_mm = (double)GetDeviceCaps(hDC, HORZSIZE); +  canvas->h_mm = (double)GetDeviceCaps(hDC, VERTSIZE); +  canvas->bpp = GetDeviceCaps(hDC, BITSPIXEL); +  canvas->xres = (double)canvas->w / canvas->w_mm; +  canvas->yres = (double)canvas->h / canvas->h_mm; + +  /* The DC will be queried for its initial clip extents, and this will be used as the size of the cairo surface. */ +  clip_hrgn = CreateRectRgn(0, 0, canvas->w, canvas->h); +  SelectClipRgn(hDC, clip_hrgn); +  DeleteObject(clip_hrgn); + +  ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(cairo_win32_printing_surface_create(hDC))); +   +  di.cbSize = sizeof(DOCINFO); +  di.lpszDocName = docname; +  di.lpszOutput = (LPTSTR) NULL; +  di.lpszDatatype = (LPTSTR) NULL;  +  di.fwType = 0;  + +  StartDoc(hDC, &di); +   +  StartPage(hDC); + +  if (pd.hDevNames) +  { +    unsigned char* devnames = (unsigned char*)GlobalLock(pd.hDevNames); +    DEVNAMES* dn = (DEVNAMES*)devnames; +    char* device = (char*)(devnames + dn->wDeviceOffset); + +    ctxcanvas->printername = cdStrDup(device); +    cdRegisterAttribute(canvas, &printername_attrib); + +    /* PDF Writer returns bpp=1, so we check if color is supported and overwrite this value */ +    if (canvas->bpp==1) +    { +      char* port = (char*)(devnames + dn->wOutputOffset); +      if (DeviceCapabilities(device, port, DC_COLORDEVICE, NULL, NULL)) +        canvas->bpp = 24; +    } + +    GlobalUnlock(pd.hDevNames); +  } + +  if(pd.hDevMode)  +    GlobalFree(pd.hDevMode); +  if(pd.hDevNames)  +    GlobalFree(pd.hDevNames); +} + +static void cdinittable(cdCanvas* canvas) +{ +  cdcairoInitTable(canvas); +   +  canvas->cxFlush = cdflush; +  canvas->cxKillCanvas = cdkillcanvas; +} + +static cdContext cdPrinterCairoContext = +{ +  CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_GETIMAGERGB | +                 CD_CAP_WRITEMODE | CD_CAP_PALETTE | CD_CAP_IMAGESRV), +  0, +  cdcreatecanvas, +  cdinittable, +  NULL, +  NULL, +}; + +cdContext* cdContextCairoPrinter(void) +{ +  return &cdPrinterCairoContext; +} diff --git a/src/cairo/cdcairosvg.c b/src/cairo/cdcairosvg.c index ee09b06..d97cb24 100644 --- a/src/cairo/cdcairosvg.c +++ b/src/cairo/cdcairosvg.c @@ -17,7 +17,8 @@  static void cdflush(cdCtxCanvas *ctxcanvas)  { -  (void)ctxcanvas;  /* Nothing to do */ +  (void)ctxcanvas; +  /* does nothing in SVG */  }  static void cdkillcanvas (cdCtxCanvas *ctxcanvas)  | 
