Index: extension/internal/cairo-render-context.cpp =================================================================== --- extension/internal/cairo-render-context.cpp (revision 17949) +++ extension/internal/cairo-render-context.cpp (working copy) @@ -50,6 +50,7 @@ #include "sp-pattern.h" #include "sp-mask.h" #include "sp-clippath.h" +#include "FontFactory.h" // USE_PANGO_WIN32 #include @@ -73,6 +74,10 @@ #ifdef CAIRO_HAS_FT_FONT #include #endif +#ifdef CAIRO_HAS_WIN32_FONT +#include +#include +#endif #include @@ -743,6 +748,44 @@ return ret; } +bool +CairoRenderContext::setContextTarget(cairo_t *cr, bool is_vector) +{ + if (_is_valid || !cr) + return false; + + _vector_based_target = is_vector; + + cairo_surface_t *surface = cairo_get_target (cr); + + if (surface == NULL) { + return false; + } + if (CAIRO_STATUS_SUCCESS != cairo_surface_status(surface)) { + return false; + } + + _cr = cr; + _surface = surface; + + cairo_reference (_cr); + cairo_surface_reference (_surface); + + if (_vector_based_target) { + cairo_scale(_cr, PT_PER_PX, PT_PER_PX); + } else if (cairo_surface_get_content(_surface) != CAIRO_CONTENT_ALPHA) { + // set background color on non-alpha surfaces + // TODO: bgcolor should be derived from SPDocument + cairo_set_source_rgb(_cr, 1.0, 1.0, 1.0); + cairo_rectangle(_cr, 0, 0, _width, _height); + cairo_fill(_cr); + } + + _is_valid = TRUE; + + return true; +} + bool CairoRenderContext::_finishSurfaceSetup(cairo_surface_t *surface) { @@ -1421,16 +1464,33 @@ { // create a cairo_font_face from PangoFont double size = style->font_size.computed; + cairo_font_face_t *font_face = NULL; + + FcPattern *fc_pattern = NULL; + +#ifdef USE_PANGO_WIN32 +# ifdef CAIRO_HAS_WIN32_FONT + LOGFONTA *lfa = pango_win32_font_logfont(font); + LOGFONTW lfw; + + ZeroMemory(&lfw, sizeof(LOGFONTW)); + memcpy(&lfw, lfa, sizeof(LOGFONTA)); + MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, lfa->lfFaceName, LF_FACESIZE, lfw.lfFaceName, LF_FACESIZE); + + font_face = cairo_win32_font_face_create_for_logfontw(&lfw); +# endif +#else +# ifdef CAIRO_HAS_FT_FONT PangoFcFont *fc_font = PANGO_FC_FONT(font); - FcPattern *fc_pattern = fc_font->font_pattern; - + fc_pattern = fc_font->font_pattern; + font_face = cairo_ft_font_face_create_for_pattern(fc_pattern); +# endif +#endif + cairo_save(_cr); - -#ifdef CAIRO_HAS_FT_FONT - cairo_font_face_t *font_face = cairo_ft_font_face_create_for_pattern(fc_pattern); cairo_set_font_face(_cr, font_face); - if (FcPatternGetDouble(fc_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch) + if (fc_pattern && FcPatternGetDouble(fc_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch) size = 12.0; // set the given font matrix @@ -1471,14 +1531,9 @@ cairo_restore(_cr); - cairo_font_face_destroy(font_face); -#else - (void)size; - (void)fc_pattern; + if (font_face) + cairo_font_face_destroy(font_face); - cairo_restore(_cr); -#endif - return true; } Index: extension/internal/cairo-render-context.h =================================================================== --- extension/internal/cairo-render-context.h (revision 17949) +++ extension/internal/cairo-render-context.h (working copy) @@ -86,6 +86,7 @@ bool setPsTarget(gchar const *utf8_fn); /** Set the cairo_surface_t from an external source */ bool setSurfaceTarget(cairo_surface_t *surface, bool is_vector); + bool setContextTarget(cairo_t *cr, bool is_vector); void setPSLevel(unsigned int level); unsigned int getPSLevel(void); Index: ui/dialog/print.cpp =================================================================== --- ui/dialog/print.cpp (revision 17949) +++ ui/dialog/print.cpp (working copy) @@ -28,7 +28,204 @@ #include "svg/svg-color.h" +#ifdef WIN32 +#define WIN_PRINT 1 +#endif + + +#ifdef WIN_PRINT + +#include +#include +#include +#include + +#define PRINT_DLG 1 + +static cairo_surface_t *surface; +static cairo_t *cr; + +static cairo_t * +cairo_draw_setup (HDC hdc) +{ + int x, y, x_dpi, y_dpi, x_off, y_off, depth; + XFORM xform; + + x = GetDeviceCaps (hdc, HORZRES); + y = GetDeviceCaps (hdc, VERTRES); +// printf(" x = %d y = %d\n", x, y); + + x_dpi = GetDeviceCaps (hdc, LOGPIXELSX); + y_dpi = GetDeviceCaps (hdc, LOGPIXELSY); +// printf("dpi x = %d y = %d\n", x_dpi, y_dpi); + + x_off = GetDeviceCaps (hdc, PHYSICALOFFSETX); + y_off = GetDeviceCaps (hdc, PHYSICALOFFSETY); +// printf("offset x = %d y = %d\n", x_off, y_off); + + depth = GetDeviceCaps(hdc, BITSPIXEL); +// printf("depth = %d\n", depth); + + SetGraphicsMode (hdc, GM_ADVANCED); + xform.eM11 = x_dpi/72.0; + xform.eM12 = 0; + xform.eM21 = 0; + xform.eM22 = y_dpi/72.0; + xform.eDx = -x_off; + xform.eDy = -y_off; + SetWorldTransform (hdc, &xform); + + surface = cairo_win32_printing_surface_create (hdc); + //cairo_surface_set_fallback_resolution (surface, x_dpi, y_dpi); + cr = cairo_create (surface); + //cairo_translate (cr, -x_off, -y_off); + //cairo_scale (cr, x_dpi/72.0, y_dpi/72.0); + + return cr; +} + + static void +cairo_draw_cleanup () +{ + cairo_status_t status; + + cairo_show_page (cr); + status = cairo_status (cr); + if (status) { + fprintf(stderr, "Win cr returned error status %d\n", status); + } + cairo_destroy (cr); + cairo_surface_finish (surface); + status = cairo_surface_status (surface); + if (status) + fprintf(stderr, "Win surface returned error status %d\n", status); + cairo_surface_destroy (surface); +} + +static void +cairo_draw (HDC hdc, SPDocument *doc, SPItem *base) +{ + // Render as vectors + Inkscape::Extension::Internal::CairoRenderer renderer; + Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext(); + + // ctx->setPSLevel(CAIRO_PS_LEVEL_3); + ctx->setTextToPath(false); + ctx->setFilterToBitmap(true); + ctx->setBitmapResolution(72); + + cr = NULL; + surface = NULL; + cairo_draw_setup(hdc); + + bool ret = ctx->setContextTarget (cr, true); + if (ret) { + ret = renderer.setupDocument (ctx, doc); + if (ret) { + renderer.renderItem(ctx, base); + ret = ctx->finish(); + } + else { + g_warning(_("Could not set up Document")); + } + } + else { + g_warning(_("Failed to set CairoRenderContext")); + } + + // Clean up + renderer.destroyContext(ctx); + + cairo_draw_cleanup(); +} + +static HDC +create_printer_dc () +{ + HDC hdc; + +#ifdef PRINT_DLG + PRINTDLG pd; + + pd.lStructSize = sizeof (PRINTDLG); + pd.hwndOwner = NULL; + pd.hDevMode = NULL; + pd.hDevNames = NULL; + pd.hDC = NULL; + pd.Flags = PD_ALLPAGES|PD_NOSELECTION|/*PD_PRINTTOFILE|*/PD_RETURNDC; + pd.nFromPage = 0; + pd.nToPage = 0; + pd.nMinPage = 0; + pd.nMaxPage = 0; + pd.nCopies = 1; + pd.hInstance = NULL; + pd.lCustData = 0L; + pd.lpfnPrintHook = NULL; + pd.lpfnSetupHook = NULL;; + pd.lpPrintTemplateName = NULL; + pd.lpSetupTemplateName = NULL; + pd.hPrintTemplate = NULL; + pd.hSetupTemplate = NULL; + + if (PrintDlg (&pd) == 0) + hdc = NULL; + else + hdc = pd.hDC; +#else + DWORD needed, returned; + PRINTER_INFO_4 *info4; + HANDLE printer; + DEVMODE *dev; + long size; + int i; + int n = 0; + + EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &needed, &returned); + info4 = malloc (needed); + EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, (LPBYTE) info4, needed, &needed, &returned); + for (i = 0; i < returned; i++) + printf("printer: %s\n", info4[i].pPrinterName); + + printf("\nPrinting to : %s\n", info4[n].pPrinterName); + + hdc = CreateDC (NULL, info4[n].pPrinterName, NULL, NULL); + +#endif + return hdc; +} + +bool +win_print (SPDocument *doc, SPItem *base) +{ +#ifdef PRINT_DLG + DOCINFO di = { sizeof (DOCINFO), TEXT ("Printing") }; +#else + DOCINFO di = { sizeof (DOCINFO), TEXT ("Printing"), TEXT ("cairo.ps") }; +#endif + HDC hdc; + + hdc = create_printer_dc (); + if (hdc == NULL) { +// printf("hdc == NULL\n"); + return false; + } + + StartDoc (hdc, &di); + StartPage (hdc); + cairo_draw (hdc, doc, base); + EndPage (hdc); + EndDoc (hdc); + + DeleteDC (hdc); + + return true; +} + +#endif + + +static void draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, @@ -90,7 +287,14 @@ // Render as vectors Inkscape::Extension::Internal::CairoRenderer renderer; Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext(); - bool ret = ctx->setSurfaceTarget (cairo_get_target (gtk_print_context_get_cairo_context (context)), true); + + // ctx->setPSLevel(CAIRO_PS_LEVEL_3); + ctx->setTextToPath(false); + ctx->setFilterToBitmap(true); + ctx->setBitmapResolution(72); + + cairo_t *cr = gtk_print_context_get_cairo_context (context); + bool ret = ctx->setContextTarget (cr, true); if (ret) { ret = renderer.setupDocument (ctx, junk->_doc); if (ret) { @@ -139,6 +343,11 @@ g_assert (_doc); g_assert (_base); +#ifdef WIN_PRINT + win_print(doc, base); + return; +#endif + _printop = gtk_print_operation_new (); // set up dialog title, based on document name @@ -149,13 +358,17 @@ gtk_print_operation_set_job_name (_printop, title.c_str()); // set up paper size to match the document size + gtk_print_operation_set_unit (_printop, GTK_UNIT_POINTS); GtkPageSetup *page_setup = gtk_page_setup_new(); gdouble doc_width = sp_document_width(_doc) * PT_PER_PX; gdouble doc_height = sp_document_height(_doc) * PT_PER_PX; GtkPaperSize *paper_size = gtk_paper_size_new_custom("custom", "custom", doc_width, doc_height, GTK_UNIT_POINTS); gtk_page_setup_set_paper_size (page_setup, paper_size); +#ifndef WIN32 gtk_print_operation_set_default_page_setup (_printop, page_setup); +#endif + gtk_print_operation_set_use_full_page (_printop, TRUE); // set up signals _workaround._doc = _doc;