summaryrefslogtreecommitdiff
path: root/src/cairo
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo')
-rw-r--r--src/cairo/cdcairo.c2
-rw-r--r--src/cairo/cdcairoctx.h5
-rw-r--r--src/cairo/cdcairoemf.c122
-rw-r--r--src/cairo/cdcairoplus.c6
-rw-r--r--src/cairo/cdcairoprn_unix.c (renamed from src/cairo/cdcairoprn.c)0
-rw-r--r--src/cairo/cdcairoprn_win32.c190
-rw-r--r--src/cairo/cdcairosvg.c3
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)