summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--html/en/drv/cairo.html9
-rw-r--r--html/en/func/init.html4
-rw-r--r--include/cdcairo.h12
-rw-r--r--mak.vc9/cdcairo.vcproj10
-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
-rw-r--r--src/cdcairo.mak5
-rw-r--r--src/config.mak3
-rw-r--r--src/drv/cd0emf.c8
14 files changed, 362 insertions, 17 deletions
diff --git a/html/en/drv/cairo.html b/html/en/drv/cairo.html
index 9632ed8..55c788a 100644
--- a/html/en/drv/cairo.html
+++ b/html/en/drv/cairo.html
@@ -24,7 +24,7 @@
implemented in the X-Windows and MS-Windows systems. The implementation uses the
<a href="http://library.gnome.org/devel/pango/">Cairo</a> and Pango functions. This driver can be
compiled and used in all systems Cairo is supported. The drivers <b>Native Window</b>,
- <b>Image</b>, <b>Printer</b> and <b>Double Buffer</b> were implemented.</p>
+ <b>Image</b>, <b>EMF</b>, <b>Printer</b> and <b>Double Buffer</b> were implemented.</p>
<p>The main motivation for the use of Cairo was transparency for all the
primitives. Beyond that we got other features like anti-aliasing, gradient
filling, transformations and other back-ends (support to rendering: PDF, PS, SVG and
@@ -39,11 +39,14 @@ for complex clipping regions.</p>
the canvas will be always a Cairo canvas. In fact the function affects primary the definitions
<font face="Courier"><strong>CD_NATIVEWINDOW</strong></font>,
<strong><span style="font-family: Courier">CD_IMAGE</span></strong>,
+ <strong><span style="font-family: Courier">CD_EMF</span></strong>,
<strong><span style="font-family: Courier">CD_PRINTER</span></strong> and <strong>
<span style="font-family: Courier">CD_DBUFFER</span></strong>, because they are
function calls and not static defines.
- <strong><span style="font-family: Courier">CD_PRINTER</span></strong> can only
- be used along with GDK base driver in UNIX.</p>
+ <strong><span style="font-family: Courier">CD_PRINTER</span></strong> can be used with
+ the GDK base driver in UNIX, or with the Win32 base driver in Windows.
+ <strong><span style="font-family: Courier">CD_EMF </span></strong> can be used
+ in Windows only, with GDK or Win32 base drivers.</p>
<p>Using Cairo it is allowed to create more that one canvas at the same time for the same Window. And they can co-exist
with a standard GDK, Win32 or X-Windows canvas.</p>
<p>To enable the use of Cairo based drivers you must call the initialization function <font face="Courier"><strong>
diff --git a/html/en/func/init.html b/html/en/func/init.html
index 32a1ab6..17092c8 100644
--- a/html/en/func/init.html
+++ b/html/en/func/init.html
@@ -124,7 +124,9 @@ cd.InitContextPlus() [in Lua]</pre>
<p>Initializes the context driver to use another context replacing the standard drivers.
This functions is only available when a library containing a &quot;ContextPlus&quot;
context driver is used. See the <a href="../drv/cairo.html">Cairo</a>,&nbsp; <a href="../drv/gdiplus.html">GDI+</a>
-and <a href="../drv/xrender.html">XRender</a> base drivers.</p>
+and <a href="../drv/xrender.html">XRender</a> base drivers. Those libraries does
+not support XOR write mode, but has support for anti-aliasing and alpha for
+transparency.</p>
<p>In Lua, when using require&quot;cdluacontextplus&quot; this function will be
automatically called.</p>
diff --git a/include/cdcairo.h b/include/cdcairo.h
index f417086..81d54dc 100644
--- a/include/cdcairo.h
+++ b/include/cdcairo.h
@@ -13,25 +13,29 @@ extern "C" {
#endif
/* Some of these context can be used directly or by cdInitContextPlus,
- as CD_NATIVEWINDOW, CD_IMAGE and CD_DBUFFER.
+ as CD_NATIVEWINDOW, CD_IMAGE, CD_EMF, CD_PRINTER and CD_DBUFFER.
The others only directly.
*/
+cdContext* cdContextCairoNativeWindow(void);
+cdContext* cdContextCairoImage(void);
+cdContext* cdContextCairoDBuffer(void);
+cdContext* cdContextCairoPrinter(void);
cdContext* cdContextCairoPS(void);
cdContext* cdContextCairoPDF(void);
cdContext* cdContextCairoSVG(void);
cdContext* cdContextCairoImageRGB(void);
-cdContext* cdContextCairoDBuffer(void);
-cdContext* cdContextCairoImage(void);
-cdContext* cdContextCairoNativeWindow(void);
+cdContext* cdContextCairoEMF(void);
#define CD_CAIRO_NATIVEWINDOW cdContextCairoNativeWindow()
#define CD_CAIRO_IMAGE cdContextCairoImage()
#define CD_CAIRO_DBUFFER cdContextCairoDBuffer()
+#define CD_CAIRO_PRINTER cdContextCairoPrinter()
#define CD_CAIRO_PS cdContextCairoPS()
#define CD_CAIRO_PDF cdContextCairoPDF()
#define CD_CAIRO_SVG cdContextCairoSVG()
#define CD_CAIRO_IMAGERGB cdContextCairoImageRGB()
+#define CD_CAIRO_EMF cdContextCairoEMF()
#ifdef __cplusplus
diff --git a/mak.vc9/cdcairo.vcproj b/mak.vc9/cdcairo.vcproj
index c1a817f..f2afddc 100644
--- a/mak.vc9/cdcairo.vcproj
+++ b/mak.vc9/cdcairo.vcproj
@@ -115,6 +115,10 @@
>
</File>
<File
+ RelativePath="..\src\cairo\cdcairoemf.c"
+ >
+ </File>
+ <File
RelativePath="..\src\cairo\cdcairoimg.c"
>
</File>
@@ -159,7 +163,7 @@
>
</File>
<File
- RelativePath="..\src\cairo\cdcairoprn.c"
+ RelativePath="..\src\cairo\cdcairoprn_unix.c"
>
<FileConfiguration
Name="Debug|Win32"
@@ -171,6 +175,10 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\cairo\cdcairoprn_win32.c"
+ >
+ </File>
+ <File
RelativePath="..\src\cairo\cdcairops.c"
>
</File>
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)
diff --git a/src/cdcairo.mak b/src/cdcairo.mak
index 6dbce6a..1d0e311 100644
--- a/src/cdcairo.mak
+++ b/src/cdcairo.mak
@@ -12,9 +12,10 @@ SRC = cdcairodbuf.c cdcairopdf.c cdcairosvg.c cdcairo.c cdcairoimg.c cdcairoplus
# cdcaironative_gdk.c
ifneq ($(findstring Win, $(TEC_SYSNAME)), )
- SRC += cdcaironative_win32.c
+ SRC += cdcaironative_win32.c cdcairoprn_win32.c cdcairoemf.c
else
- SRC += cdcaironative_x11.c
+ SRC += cdcaironative_x11.c
+ DEFINES += CAIRO_X11
endif
INCLUDES += $(GTK)/include/cairo $(GTK)/include/pango-1.0 $(GTK)/include/glib-2.0 $(GTK)/lib/glib-2.0/include
diff --git a/src/config.mak b/src/config.mak
index 384b9a7..55fe472 100644
--- a/src/config.mak
+++ b/src/config.mak
@@ -66,10 +66,11 @@ ifdef USE_GDK
USE_GTK = Yes
LIBS = pangocairo-1.0 cairo
ifeq ($(findstring Win, $(TEC_SYSNAME)), )
- SRC += cairo/cdcairoprn.c
+ SRC += cairo/cdcairoprn_unix.c
INCLUDES += /usr/include/gtk-unix-print-2.0
LIBS += freetype
else
+ SRC += cairo/cdcairoprn_win32.c cdcairoemf.c
LIBS += freetype6
endif
else
diff --git a/src/drv/cd0emf.c b/src/drv/cd0emf.c
index 13beb4c..7e05134 100644
--- a/src/drv/cd0emf.c
+++ b/src/drv/cd0emf.c
@@ -6,11 +6,19 @@
#include <stdlib.h>
#include "cd.h"
+#include "cd_private.h"
#include "cdemf.h"
cdContext* cdContextEMF(void)
{
+ if (cdUseContextPlus(CD_QUERY))
+ {
+ cdContext* ctx = cdGetContextPlus(CD_CTX_EMF);
+ if (ctx != NULL)
+ return ctx;
+ }
+
return NULL;
}