From 553cd80ed974c1dd151f902040bd942f043ac193 Mon Sep 17 00:00:00 2001 From: scuri Date: Fri, 18 Jun 2010 18:19:28 +0000 Subject: *** empty log message *** --- html/en/drv/cairo.html | 9 +- html/en/func/init.html | 4 +- include/cdcairo.h | 12 ++- mak.vc9/cdcairo.vcproj | 10 ++- src/cairo/cdcairo.c | 2 +- src/cairo/cdcairoctx.h | 5 +- src/cairo/cdcairoemf.c | 122 +++++++++++++++++++++++++++ src/cairo/cdcairoplus.c | 6 +- src/cairo/cdcairoprn.c | 190 ------------------------------------------- src/cairo/cdcairoprn_unix.c | 190 +++++++++++++++++++++++++++++++++++++++++++ src/cairo/cdcairoprn_win32.c | 190 +++++++++++++++++++++++++++++++++++++++++++ src/cairo/cdcairosvg.c | 3 +- src/cdcairo.mak | 5 +- src/config.mak | 3 +- src/drv/cd0emf.c | 8 ++ 15 files changed, 552 insertions(+), 207 deletions(-) create mode 100644 src/cairo/cdcairoemf.c delete mode 100644 src/cairo/cdcairoprn.c create mode 100644 src/cairo/cdcairoprn_unix.c create mode 100644 src/cairo/cdcairoprn_win32.c 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 Cairo and Pango functions. This driver can be compiled and used in all systems Cairo is supported. The drivers Native Window, - Image, Printer and Double Buffer were implemented.

+ Image, EMF, Printer and Double Buffer were implemented.

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.

the canvas will be always a Cairo canvas. In fact the function affects primary the definitions CD_NATIVEWINDOW, CD_IMAGE, + CD_EMF, CD_PRINTER and CD_DBUFFER, because they are function calls and not static defines. - CD_PRINTER can only - be used along with GDK base driver in UNIX.

+ CD_PRINTER can be used with + the GDK base driver in UNIX, or with the Win32 base driver in Windows. + CD_EMF can be used + in Windows only, with GDK or Win32 base drivers.

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.

To enable the use of Cairo based drivers you must call the initialization function 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]

Initializes the context driver to use another context replacing the standard drivers. This functions is only available when a library containing a "ContextPlus" context driver is used. See the CairoGDI+ -and XRender base drivers.

+and XRender base drivers. Those libraries does +not support XOR write mode, but has support for anti-aliasing and alpha for +transparency.

In Lua, when using require"cdluacontextplus" this function will be automatically called.

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 @@ -114,6 +114,10 @@ RelativePath="..\src\cairo\cdcairodbuf.c" > + + @@ -159,7 +163,7 @@ > + + 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 +#include +#include + +#include + +#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 #include + 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.c deleted file mode 100644 index b201230..0000000 --- a/src/cairo/cdcairoprn.c +++ /dev/null @@ -1,190 +0,0 @@ -/** \file - * \brief Cairo/GTK Printer Driver (UNIX Only) - * - * See Copyright Notice in cd.h - */ - -#include -#include -#include - -#include - -#include "cdcairoctx.h" -#include "cdprint.h" - -static gboolean print_enum(GtkPrinter *printer, GtkPrinter **ret_printer) -{ - if (gtk_printer_is_default(printer)) - { - *ret_printer = printer; - g_object_ref(printer); - return TRUE; - } - return FALSE; -} - -static void finish_send(GtkPrintJob *job, GMainLoop* loop, GError *error) -{ - if (error != NULL) - { - GtkWidget *edialog; - edialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Error printing"); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (edialog), "%s", error->message); - gtk_window_set_modal (GTK_WINDOW (edialog), TRUE); - g_signal_connect(edialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); - - gtk_window_present(GTK_WINDOW(edialog)); - } - - g_main_loop_quit(loop); -} - -static void cdkillcanvas(cdCtxCanvas *ctxcanvas) -{ - GMainLoop* loop = g_main_loop_new (NULL, FALSE); - - cairo_surface_finish(cairo_get_target(ctxcanvas->cr)); - - gtk_print_job_send(ctxcanvas->job, (GtkPrintJobCompleteFunc)finish_send, loop, NULL); - - g_main_loop_run(loop); - g_main_loop_unref(loop); - - cdcairoKillCanvas(ctxcanvas); -} - -static char* get_printername_attrib(cdCtxCanvas* ctxcanvas) -{ - return (char*)gtk_printer_get_name(gtk_print_job_get_printer(ctxcanvas->job)); -} - -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"; - GtkPrintUnixDialog* dialog = NULL; - GtkPrinter* printer; - GtkPrintSettings* settings; - GtkPageSetup* page_setup; - GtkPrintJob* job; - int show_dialog = 0; - - /* Starting parameters */ - if (data_str == NULL) - return; - - if (data_str[0] != 0) - { - char *ptr = strstr(data_str, "-d"); - - if (ptr != NULL) - show_dialog = 1; - - if (data_str[0] != '-') - { - strcpy(docname, data_str); - - if (show_dialog) - docname[ptr - data_str - 1] = 0; - } - } - - if (show_dialog) - { - int response; - - dialog = (GtkPrintUnixDialog*)gtk_print_unix_dialog_new(NULL, NULL); - - gtk_print_unix_dialog_set_manual_capabilities(dialog, - GTK_PRINT_CAPABILITY_PAGE_SET | - GTK_PRINT_CAPABILITY_COPIES | - GTK_PRINT_CAPABILITY_COLLATE | - GTK_PRINT_CAPABILITY_REVERSE | - GTK_PRINT_CAPABILITY_SCALE); - - gtk_widget_realize(GTK_WIDGET(dialog)); - - response = gtk_dialog_run(GTK_DIALOG(dialog)); - - if (response == GTK_RESPONSE_CANCEL) - { - gtk_widget_destroy(GTK_WIDGET(dialog)); - return; - } - - printer = gtk_print_unix_dialog_get_selected_printer(dialog); - settings = gtk_print_unix_dialog_get_settings(dialog); - page_setup = gtk_print_unix_dialog_get_page_setup(dialog); - } - else - { - printer = NULL; - gtk_enumerate_printers((GtkPrinterFunc)print_enum, &printer, NULL, TRUE); - if (!printer) - return; - page_setup = gtk_printer_get_default_page_size(printer); - if (!page_setup) - page_setup = gtk_page_setup_new(); /* ?????? */ - - settings = gtk_print_settings_new(); /* ?????? */ - } - - job = gtk_print_job_new(docname, printer, settings, page_setup); - - canvas->w_mm = (int)gtk_page_setup_get_page_width(page_setup, GTK_UNIT_MM); - canvas->h_mm = (int)gtk_page_setup_get_page_height(page_setup, GTK_UNIT_MM); - canvas->bpp = 24; - canvas->xres = (double)gtk_print_settings_get_resolution_x(settings) / 25.4; - canvas->yres = (double)gtk_print_settings_get_resolution_y(settings) / 25.4; - canvas->w = cdRound(canvas->w_mm*canvas->xres); - canvas->h = cdRound(canvas->h_mm*canvas->yres); - - ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(gtk_print_job_get_surface(job, NULL))); - ctxcanvas->job = job; - - cairo_identity_matrix(ctxcanvas->cr); - cairo_scale(ctxcanvas->cr, 0.25, 0.25); /* TODO: why this is needed? */ - - cdRegisterAttribute(canvas, &printername_attrib); - - if (dialog) - gtk_widget_destroy(GTK_WIDGET(dialog)); - - g_object_unref(settings); -} - -static void cdinittable(cdCanvas* canvas) -{ - cdcairoInitTable(canvas); - - 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/cdcairoprn_unix.c b/src/cairo/cdcairoprn_unix.c new file mode 100644 index 0000000..b201230 --- /dev/null +++ b/src/cairo/cdcairoprn_unix.c @@ -0,0 +1,190 @@ +/** \file + * \brief Cairo/GTK Printer Driver (UNIX Only) + * + * See Copyright Notice in cd.h + */ + +#include +#include +#include + +#include + +#include "cdcairoctx.h" +#include "cdprint.h" + +static gboolean print_enum(GtkPrinter *printer, GtkPrinter **ret_printer) +{ + if (gtk_printer_is_default(printer)) + { + *ret_printer = printer; + g_object_ref(printer); + return TRUE; + } + return FALSE; +} + +static void finish_send(GtkPrintJob *job, GMainLoop* loop, GError *error) +{ + if (error != NULL) + { + GtkWidget *edialog; + edialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Error printing"); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (edialog), "%s", error->message); + gtk_window_set_modal (GTK_WINDOW (edialog), TRUE); + g_signal_connect(edialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); + + gtk_window_present(GTK_WINDOW(edialog)); + } + + g_main_loop_quit(loop); +} + +static void cdkillcanvas(cdCtxCanvas *ctxcanvas) +{ + GMainLoop* loop = g_main_loop_new (NULL, FALSE); + + cairo_surface_finish(cairo_get_target(ctxcanvas->cr)); + + gtk_print_job_send(ctxcanvas->job, (GtkPrintJobCompleteFunc)finish_send, loop, NULL); + + g_main_loop_run(loop); + g_main_loop_unref(loop); + + cdcairoKillCanvas(ctxcanvas); +} + +static char* get_printername_attrib(cdCtxCanvas* ctxcanvas) +{ + return (char*)gtk_printer_get_name(gtk_print_job_get_printer(ctxcanvas->job)); +} + +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"; + GtkPrintUnixDialog* dialog = NULL; + GtkPrinter* printer; + GtkPrintSettings* settings; + GtkPageSetup* page_setup; + GtkPrintJob* job; + int show_dialog = 0; + + /* Starting parameters */ + if (data_str == NULL) + return; + + if (data_str[0] != 0) + { + char *ptr = strstr(data_str, "-d"); + + if (ptr != NULL) + show_dialog = 1; + + if (data_str[0] != '-') + { + strcpy(docname, data_str); + + if (show_dialog) + docname[ptr - data_str - 1] = 0; + } + } + + if (show_dialog) + { + int response; + + dialog = (GtkPrintUnixDialog*)gtk_print_unix_dialog_new(NULL, NULL); + + gtk_print_unix_dialog_set_manual_capabilities(dialog, + GTK_PRINT_CAPABILITY_PAGE_SET | + GTK_PRINT_CAPABILITY_COPIES | + GTK_PRINT_CAPABILITY_COLLATE | + GTK_PRINT_CAPABILITY_REVERSE | + GTK_PRINT_CAPABILITY_SCALE); + + gtk_widget_realize(GTK_WIDGET(dialog)); + + response = gtk_dialog_run(GTK_DIALOG(dialog)); + + if (response == GTK_RESPONSE_CANCEL) + { + gtk_widget_destroy(GTK_WIDGET(dialog)); + return; + } + + printer = gtk_print_unix_dialog_get_selected_printer(dialog); + settings = gtk_print_unix_dialog_get_settings(dialog); + page_setup = gtk_print_unix_dialog_get_page_setup(dialog); + } + else + { + printer = NULL; + gtk_enumerate_printers((GtkPrinterFunc)print_enum, &printer, NULL, TRUE); + if (!printer) + return; + page_setup = gtk_printer_get_default_page_size(printer); + if (!page_setup) + page_setup = gtk_page_setup_new(); /* ?????? */ + + settings = gtk_print_settings_new(); /* ?????? */ + } + + job = gtk_print_job_new(docname, printer, settings, page_setup); + + canvas->w_mm = (int)gtk_page_setup_get_page_width(page_setup, GTK_UNIT_MM); + canvas->h_mm = (int)gtk_page_setup_get_page_height(page_setup, GTK_UNIT_MM); + canvas->bpp = 24; + canvas->xres = (double)gtk_print_settings_get_resolution_x(settings) / 25.4; + canvas->yres = (double)gtk_print_settings_get_resolution_y(settings) / 25.4; + canvas->w = cdRound(canvas->w_mm*canvas->xres); + canvas->h = cdRound(canvas->h_mm*canvas->yres); + + ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(gtk_print_job_get_surface(job, NULL))); + ctxcanvas->job = job; + + cairo_identity_matrix(ctxcanvas->cr); + cairo_scale(ctxcanvas->cr, 0.25, 0.25); /* TODO: why this is needed? */ + + cdRegisterAttribute(canvas, &printername_attrib); + + if (dialog) + gtk_widget_destroy(GTK_WIDGET(dialog)); + + g_object_unref(settings); +} + +static void cdinittable(cdCanvas* canvas) +{ + cdcairoInitTable(canvas); + + 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/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 +#include +#include + +#include + +#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 #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; } -- cgit v1.2.3