summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/emf-win32-print.cpp
diff options
context:
space:
mode:
authorsu_v <suv-sf@users.sourceforge.net>2012-09-23 17:19:33 +0000
committer~suv <suv-sf@users.sourceforge.net>2012-09-23 17:19:33 +0000
commit89bb2602a15a830b7e2133307a8ec6a08ebd0f84 (patch)
tree9d99114076f755d5098b353b1cd26215e74abe61 /src/extension/internal/emf-win32-print.cpp
parentAdd libunicode-convert: routines for converting between Unicode and nonunicod... (diff)
downloadinkscape-89bb2602a15a830b7e2133307a8ec6a08ebd0f84.tar.gz
inkscape-89bb2602a15a830b7e2133307a8ec6a08ebd0f84.zip
Fixes bug #988601: omnibus patch for EMF input/output support (cross-platform)
(bzr r11668.1.8)
Diffstat (limited to 'src/extension/internal/emf-win32-print.cpp')
-rw-r--r--src/extension/internal/emf-win32-print.cpp942
1 files changed, 0 insertions, 942 deletions
diff --git a/src/extension/internal/emf-win32-print.cpp b/src/extension/internal/emf-win32-print.cpp
deleted file mode 100644
index 2b79fd5a4..000000000
--- a/src/extension/internal/emf-win32-print.cpp
+++ /dev/null
@@ -1,942 +0,0 @@
-/** @file
- * @brief Enhanced Metafile printing
- */
-/* Authors:
- * Ulf Erikson <ulferikson@users.sf.net>
- * Jon A. Cruz <jon@joncruz.org>
- * Abhishek Sharma
- *
- * Copyright (C) 2006-2009 Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-/*
- * References:
- * - How to Create & Play Enhanced Metafiles in Win32
- * http://support.microsoft.com/kb/q145999/
- * - INFO: Windows Metafile Functions & Aldus Placeable Metafiles
- * http://support.microsoft.com/kb/q66949/
- * - Metafile Functions
- * http://msdn.microsoft.com/library/en-us/gdi/metafile_0whf.asp
- * - Metafile Structures
- * http://msdn.microsoft.com/library/en-us/gdi/metafile_5hkj.asp
- */
-
-#ifdef WIN32
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-
-#include <2geom/pathvector.h>
-#include <2geom/rect.h>
-#include <2geom/bezier-curve.h>
-#include <2geom/hvlinesegment.h>
-#include "helper/geom.h"
-#include "helper/geom-curves.h"
-#include "sp-item.h"
-
-#include "style.h"
-#include "inkscape-version.h"
-#include "sp-root.h"
-
-#include "emf-win32-print.h"
-
-#include "unit-constants.h"
-
-#include "extension/system.h"
-#include "extension/print.h"
-#include "document.h"
-
-
-namespace Inkscape {
-namespace Extension {
-namespace Internal {
-
-static float dwDPI = 2540;
-
-
-PrintEmfWin32::PrintEmfWin32 (void):
- _width(0),
- _height(0),
- hdc(NULL),
- hbrush(NULL),
- hbrushOld(NULL),
- hpen(NULL),
- stroke_and_fill(false),
- fill_only(false),
- simple_shape(false)
-{
-}
-
-
-PrintEmfWin32::~PrintEmfWin32 (void)
-{
- if (hdc) {
- HENHMETAFILE metafile = CloseEnhMetaFile( hdc );
- if ( metafile ) {
- DeleteEnhMetaFile( metafile );
- }
- DeleteDC( hdc );
- }
-
- /* restore default signal handling for SIGPIPE */
-#if !defined(_WIN32) && !defined(__WIN32__)
- (void) signal(SIGPIPE, SIG_DFL);
-#endif
- return;
-}
-
-
-unsigned int PrintEmfWin32::setup (Inkscape::Extension::Print * /*mod*/)
-{
- return TRUE;
-}
-
-
-unsigned int PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc)
-{
- gchar const *utf8_fn = mod->get_param_string("destination");
-
- gsize bytesRead = 0;
- gsize bytesWritten = 0;
- GError* error = NULL;
- gchar *local_fn =
- g_filename_from_utf8( utf8_fn, -1, &bytesRead, &bytesWritten, &error );
-
- if (local_fn == NULL) {
- return 1;
- }
-
- CHAR *ansi_uri = (CHAR *) local_fn;
- gunichar2 *unicode_fn = g_utf8_to_utf16( local_fn, -1, NULL, NULL, NULL );
- WCHAR *unicode_uri = (WCHAR *) unicode_fn;
-
- // width and height in px
- _width = doc->getWidth();
- _height = doc->getHeight();
-
- bool pageBoundingBox;
- pageBoundingBox = mod->get_param_bool("pageBoundingBox");
-
- Geom::Rect d;
- if (pageBoundingBox) {
- d = Geom::Rect::from_xywh(0, 0, _width, _height);
- } else {
- SPItem* doc_item = doc->getRoot();
- Geom::OptRect bbox = doc_item->desktopVisualBounds();
- if (bbox) d = *bbox;
- }
-
- d *= Geom::Scale(IN_PER_PX);
-
- float dwInchesX = d.width();
- float dwInchesY = d.height();
-
- // dwInchesX x dwInchesY in .01mm units
- SetRect( &rc, 0, 0, (int) ceil(dwInchesX*2540), (int) ceil(dwInchesY*2540) );
-
- // Get a Reference DC
- HDC hScreenDC = GetDC( NULL );
-
- // Get the physical characteristics of the reference DC
- int PixelsX = GetDeviceCaps( hScreenDC, HORZRES );
- int PixelsY = GetDeviceCaps( hScreenDC, VERTRES );
- int MMX = GetDeviceCaps( hScreenDC, HORZSIZE );
- int MMY = GetDeviceCaps( hScreenDC, VERTSIZE );
-
- CHAR buff[1024];
- ZeroMemory(buff, sizeof(buff));
- snprintf(buff, sizeof(buff)-1, "Inkscape %s (%s)", Inkscape::version_string, __DATE__);
- INT len = strlen(buff);
- CHAR *p1 = strrchr(ansi_uri, '\\');
- CHAR *p2 = strrchr(ansi_uri, '/');
- CHAR *p = MAX(p1, p2);
- if (p)
- p++;
- else
- p = ansi_uri;
- snprintf(buff+len+1, sizeof(buff)-len-2, "%s", p);
-
- // Create the Metafile
- {
- WCHAR wbuff[1024];
- ZeroMemory(wbuff, sizeof(wbuff));
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buff, sizeof(buff)/sizeof(buff[0]), wbuff, sizeof(wbuff)/sizeof(wbuff[0]));
- hdc = CreateEnhMetaFileW( hScreenDC, unicode_uri, &rc, wbuff );
- }
-
- // Release the reference DC
- ReleaseDC( NULL, hScreenDC );
-
- // Did we get a good metafile?
- if (hdc == NULL)
- {
- g_free(local_fn);
- g_free(unicode_fn);
- return 1;
- }
-
- // Anisotropic mapping mode
- SetMapMode( hdc, MM_ANISOTROPIC );
-
- // Set the Windows extent
- int windowextX = (int) ceil(dwInchesX*dwDPI);
- int windowextY = (int) ceil(dwInchesY*dwDPI);
- SetWindowExtEx( hdc, windowextX, windowextY, NULL );
-
- // Set the viewport extent to reflect
- // dwInchesX" x dwInchesY" in device units
- int viewportextX = (int)((float)dwInchesX*25.4f*(float)PixelsX/(float)MMX);
- int viewportextY = (int)((float)dwInchesY*25.4f*(float)PixelsY/(float)MMY);
- SetViewportExtEx( hdc, viewportextX, viewportextY, NULL );
-
- if (1) {
- snprintf(buff, sizeof(buff)-1, "Screen=%dx%dpx, %dx%dmm", PixelsX, PixelsY, MMX, MMY);
- GdiComment(hdc, strlen(buff), (BYTE*) buff);
-
- snprintf(buff, sizeof(buff)-1, "Drawing=%.1lfx%.1lfpx, %.1lfx%.1lfmm", _width, _height, dwInchesX * MM_PER_IN, dwInchesY * MM_PER_IN);
- GdiComment(hdc, strlen(buff), (BYTE*) buff);
- }
-
- SetRect( &rc, 0, 0, (int) ceil(dwInchesX*dwDPI), (int) ceil(dwInchesY*dwDPI) );
-
- g_free(local_fn);
- g_free(unicode_fn);
-
- m_tr_stack.push( Geom::Scale(1, -1) * Geom::Translate(0, doc->getHeight())); /// @fixme hardcoded doc2dt transform
-
- return 0;
-}
-
-
-unsigned int PrintEmfWin32::finish (Inkscape::Extension::Print * /*mod*/)
-{
- if (!hdc) return 0;
-
- flush_fill(); // flush any pending fills
-
- HENHMETAFILE metafile = CloseEnhMetaFile( hdc );
- if ( metafile ) {
- DeleteEnhMetaFile( metafile );
- }
- DeleteDC( hdc );
-
- hdc = NULL;
-
- return 0;
-}
-
-
-unsigned int PrintEmfWin32::comment (Inkscape::Extension::Print * /*module*/,
- const char * /*comment*/)
-{
- if (!hdc) return 0;
-
- flush_fill(); // flush any pending fills
-
- return 0;
-}
-
-
-int PrintEmfWin32::create_brush(SPStyle const *style)
-{
- float rgb[3];
-
- if (style) {
- float opacity = SP_SCALE24_TO_FLOAT(style->fill_opacity.value);
- if (opacity <= 0.0)
- return 1;
-
- sp_color_get_rgb_floatv( &style->fill.value.color, rgb );
- hbrush = CreateSolidBrush( RGB(255*rgb[0], 255*rgb[1], 255*rgb[2]) );
- hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );
-
- SetPolyFillMode( hdc,
- style->fill_rule.computed == 0 ? WINDING :
- style->fill_rule.computed == 2 ? ALTERNATE : ALTERNATE );
- } else { // if (!style)
- hbrush = CreateSolidBrush( RGB(255, 255, 255) );
- hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );
- SetPolyFillMode( hdc, ALTERNATE );
- }
-
- return 0;
-}
-
-
-void PrintEmfWin32::destroy_brush()
-{
- SelectObject( hdc, hbrushOld );
- if (hbrush)
- DeleteObject( hbrush );
- hbrush = NULL;
- hbrushOld = NULL;
-}
-
-
-void PrintEmfWin32::create_pen(SPStyle const *style, const Geom::Affine &transform)
-{
- if (style) {
- float rgb[3];
-
- sp_color_get_rgb_floatv(&style->stroke.value.color, rgb);
-
- LOGBRUSH lb;
- ZeroMemory(&lb, sizeof(lb));
- lb.lbStyle = BS_SOLID;
- lb.lbColor = RGB( 255*rgb[0], 255*rgb[1], 255*rgb[2] );
-
- int linestyle = PS_SOLID;
- int linecap = 0;
- int linejoin = 0;
- DWORD n_dash = 0;
- DWORD *dash = NULL;
-
- using Geom::X;
- using Geom::Y;
-
- Geom::Point zero(0, 0);
- Geom::Point one(1, 1);
- Geom::Point p0(zero * transform);
- Geom::Point p1(one * transform);
- Geom::Point p(p1 - p0);
-
- double scale = sqrt( (p[X]*p[X]) + (p[Y]*p[Y]) ) / sqrt(2);
-
- DWORD linewidth = MAX( 1, (DWORD) (scale * style->stroke_width.computed * IN_PER_PX * dwDPI) );
-
- if (style->stroke_linecap.computed == 0) {
- linecap = PS_ENDCAP_FLAT;
- }
- else if (style->stroke_linecap.computed == 1) {
- linecap = PS_ENDCAP_ROUND;
- }
- else if (style->stroke_linecap.computed == 2) {
- linecap = PS_ENDCAP_SQUARE;
- }
-
- if (style->stroke_linejoin.computed == 0) {
- linejoin = PS_JOIN_MITER;
- }
- else if (style->stroke_linejoin.computed == 1) {
- linejoin = PS_JOIN_ROUND;
- }
- else if (style->stroke_linejoin.computed == 2) {
- linejoin = PS_JOIN_BEVEL;
- }
-
- if (style->stroke_dash.n_dash &&
- style->stroke_dash.dash )
- {
- int i = 0;
- while (linestyle != PS_USERSTYLE &&
- (i < style->stroke_dash.n_dash)) {
- if (style->stroke_dash.dash[i] > 0.00000001)
- linestyle = PS_USERSTYLE;
- i++;
- }
-
- if (linestyle == PS_USERSTYLE) {
- n_dash = style->stroke_dash.n_dash;
- dash = new DWORD[n_dash];
- for (i = 0; i < style->stroke_dash.n_dash; i++) {
- dash[i] = (DWORD) (style->stroke_dash.dash[i] * IN_PER_PX * dwDPI);
- }
- }
- }
-
- hpen = ExtCreatePen(
- PS_GEOMETRIC | linestyle | linecap | linejoin,
- linewidth,
- &lb,
- n_dash,
- dash );
-
- if ( !hpen && linestyle == PS_USERSTYLE ) {
- hpen = ExtCreatePen(
- PS_GEOMETRIC | PS_SOLID | linecap | linejoin,
- linewidth,
- &lb,
- 0,
- NULL );
- }
-
- if ( !hpen ) {
- hpen = CreatePen(
- PS_SOLID,
- linewidth,
- lb.lbColor );
- }
-
- hpenOld = (HPEN) SelectObject( hdc, hpen );
-
- if (linejoin == PS_JOIN_MITER) {
- float oldmiterlimit;
- float miterlimit = style->stroke_miterlimit.value; //ratio, not a pt size
-
- SetMiterLimit(
- hdc,
- miterlimit,
- &oldmiterlimit );
- }
-
- if (n_dash) {
- delete[] dash;
- }
- }
- else { // if (!style)
- hpen = CreatePen( PS_SOLID, 1, RGB(0, 0, 0) );
- hpenOld = (HPEN) SelectObject( hdc, hpen );
- }
-}
-
-
-void PrintEmfWin32::destroy_pen()
-{
- SelectObject( hdc, hpenOld );
- if (hpen)
- DeleteObject( hpen );
- hpen = NULL;
-}
-
-
-void PrintEmfWin32::flush_fill()
-{
- if (!fill_pathv.empty()) {
- stroke_and_fill = false;
- fill_only = true;
- print_pathv(fill_pathv, fill_transform);
- fill_only = false;
- if (!simple_shape)
- FillPath( hdc );
- destroy_brush();
- fill_pathv.clear();
- }
-}
-
-unsigned int PrintEmfWin32::bind(Inkscape::Extension::Print * /*mod*/, Geom::Affine const &transform, float /*opacity*/)
-{
- if (!m_tr_stack.empty()) {
- Geom::Affine tr_top = m_tr_stack.top();
- m_tr_stack.push(transform * tr_top);
- } else {
- m_tr_stack.push(transform);
- }
-
- return 1;
-}
-
-unsigned int PrintEmfWin32::release(Inkscape::Extension::Print * /*mod*/)
-{
- m_tr_stack.pop();
- return 1;
-}
-
-unsigned int PrintEmfWin32::fill(Inkscape::Extension::Print * /*mod*/,
- Geom::PathVector const &pathv, Geom::Affine const & /*transform*/, SPStyle const *style,
- Geom::OptRect const &/*pbox*/, Geom::OptRect const &/*dbox*/, Geom::OptRect const &/*bbox*/)
-{
- if (!hdc) return 0;
-
- Geom::Affine tf = m_tr_stack.top();
-
- flush_fill(); // flush any pending fills
-
- if (style->fill.isColor()) {
- if (create_brush(style))
- return 0;
- } else {
- // create_brush(NULL);
- return 0;
- }
-
- fill_pathv.clear();
- std::copy(pathv.begin(), pathv.end(), std::back_inserter(fill_pathv));
- fill_transform = tf;
-
- // postpone fill in case of stroke-and-fill
-
- return 0;
-}
-
-
-unsigned int PrintEmfWin32::stroke (Inkscape::Extension::Print * /*mod*/,
- Geom::PathVector const &pathv, const Geom::Affine &/*transform*/, const SPStyle *style,
- Geom::OptRect const &/*pbox*/, Geom::OptRect const &/*dbox*/, Geom::OptRect const &/*bbox*/)
-{
- if (!hdc) return 0;
-
- Geom::Affine tf = m_tr_stack.top();
-
- stroke_and_fill = ( pathv == fill_pathv );
-
- if (!stroke_and_fill) {
- flush_fill(); // flush any pending fills
- }
-
- if (style->stroke.isColor()) {
- create_pen(style, tf);
- } else {
- // create_pen(NULL, tf);
- return 0;
- }
-
- print_pathv(pathv, tf);
-
- if (stroke_and_fill) {
- if (!simple_shape)
- StrokeAndFillPath( hdc );
- destroy_brush();
- fill_pathv.clear();
- } else {
- if (!simple_shape)
- StrokePath( hdc );
- }
-
- destroy_pen();
-
- return 0;
-}
-
-
-bool PrintEmfWin32::print_simple_shape(Geom::PathVector const &pathv, const Geom::Affine &transform)
-{
- Geom::PathVector pv = pathv_to_linear_and_cubic_beziers( pathv * transform );
-
- int nodes = 0;
- int moves = 0;
- int lines = 0;
- int curves = 0;
-
- for (Geom::PathVector::const_iterator pit = pv.begin(); pit != pv.end(); ++pit)
- {
- moves++;
- nodes++;
-
- for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit)
- {
- nodes++;
-
- if ( is_straight_curve(*cit) ) {
- lines++;
- }
- else if (Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const*>(&*cit)) {
- cubic = cubic;
- curves++;
- }
- }
- }
-
- if (!nodes)
- return false;
-
- POINT *lpPoints = new POINT[moves + lines + curves*3];
- int i = 0;
-
- /**
- * For all Subpaths in the <path>
- */
- for (Geom::PathVector::const_iterator pit = pv.begin(); pit != pv.end(); ++pit)
- {
- using Geom::X;
- using Geom::Y;
-
- Geom::Point p0 = pit->initialPoint();
-
- p0[X] = (p0[X] * IN_PER_PX * dwDPI);
- p0[Y] = (p0[Y] * IN_PER_PX * dwDPI);
-
- LONG const x0 = (LONG) round(p0[X]);
- LONG const y0 = (LONG) round(rc.bottom-p0[Y]);
-
- lpPoints[i].x = x0;
- lpPoints[i].y = y0;
- i = i + 1;
-
- /**
- * For all segments in the subpath
- */
- for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit)
- {
- if ( is_straight_curve(*cit) )
- {
- //Geom::Point p0 = cit->initialPoint();
- Geom::Point p1 = cit->finalPoint();
-
- //p0[X] = (p0[X] * IN_PER_PX * dwDPI);
- p1[X] = (p1[X] * IN_PER_PX * dwDPI);
- //p0[Y] = (p0[Y] * IN_PER_PX * dwDPI);
- p1[Y] = (p1[Y] * IN_PER_PX * dwDPI);
-
- //LONG const x0 = (LONG) round(p0[X]);
- //LONG const y0 = (LONG) round(rc.bottom-p0[Y]);
- LONG const x1 = (LONG) round(p1[X]);
- LONG const y1 = (LONG) round(rc.bottom-p1[Y]);
-
- lpPoints[i].x = x1;
- lpPoints[i].y = y1;
- i = i + 1;
- }
- else if (Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const*>(&*cit))
- {
- std::vector<Geom::Point> points = cubic->points();
- //Geom::Point p0 = points[0];
- Geom::Point p1 = points[1];
- Geom::Point p2 = points[2];
- Geom::Point p3 = points[3];
-
- //p0[X] = (p0[X] * IN_PER_PX * dwDPI);
- p1[X] = (p1[X] * IN_PER_PX * dwDPI);
- p2[X] = (p2[X] * IN_PER_PX * dwDPI);
- p3[X] = (p3[X] * IN_PER_PX * dwDPI);
- //p0[Y] = (p0[Y] * IN_PER_PX * dwDPI);
- p1[Y] = (p1[Y] * IN_PER_PX * dwDPI);
- p2[Y] = (p2[Y] * IN_PER_PX * dwDPI);
- p3[Y] = (p3[Y] * IN_PER_PX * dwDPI);
-
- //LONG const x0 = (LONG) round(p0[X]);
- //LONG const y0 = (LONG) round(rc.bottom-p0[Y]);
- LONG const x1 = (LONG) round(p1[X]);
- LONG const y1 = (LONG) round(rc.bottom-p1[Y]);
- LONG const x2 = (LONG) round(p2[X]);
- LONG const y2 = (LONG) round(rc.bottom-p2[Y]);
- LONG const x3 = (LONG) round(p3[X]);
- LONG const y3 = (LONG) round(rc.bottom-p3[Y]);
-
- POINT pt[3];
- pt[0].x = x1;
- pt[0].y = y1;
- pt[1].x = x2;
- pt[1].y = y2;
- pt[2].x = x3;
- pt[2].y = y3;
-
- lpPoints[i].x = x1;
- lpPoints[i].y = y1;
- lpPoints[i+1].x = x2;
- lpPoints[i+1].y = y2;
- lpPoints[i+2].x = x3;
- lpPoints[i+2].y = y3;
- i = i + 3;
- }
- }
- }
-
- bool done = false;
- bool closed = (lpPoints[0].x == lpPoints[i-1].x) && (lpPoints[0].y == lpPoints[i-1].y);
- bool polygon = false;
- bool rectangle = false;
- bool ellipse = false;
-
- if (moves == 1 && moves+lines == nodes && closed) {
- polygon = true;
-// if (nodes==5) { // disable due to LP Bug 407394
-// if (lpPoints[0].x == lpPoints[3].x && lpPoints[1].x == lpPoints[2].x &&
-// lpPoints[0].y == lpPoints[1].y && lpPoints[2].y == lpPoints[3].y)
-// {
-// rectangle = true;
-// }
-// }
- }
- else if (moves == 1 && nodes == 5 && moves+curves == nodes && closed) {
-// if (lpPoints[0].x == lpPoints[1].x && lpPoints[1].x == lpPoints[11].x &&
-// lpPoints[5].x == lpPoints[6].x && lpPoints[6].x == lpPoints[7].x &&
-// lpPoints[2].x == lpPoints[10].x && lpPoints[3].x == lpPoints[9].x && lpPoints[4].x == lpPoints[8].x &&
-// lpPoints[2].y == lpPoints[3].y && lpPoints[3].y == lpPoints[4].y &&
-// lpPoints[8].y == lpPoints[9].y && lpPoints[9].y == lpPoints[10].y &&
-// lpPoints[5].y == lpPoints[1].y && lpPoints[6].y == lpPoints[0].y && lpPoints[7].y == lpPoints[11].y)
-// { // disable due to LP Bug 407394
-// ellipse = true;
-// }
- }
-
- if (polygon || ellipse) {
- HPEN hpenTmp = NULL;
- HPEN hpenOld = NULL;
- HBRUSH hbrushTmp = NULL;
- HBRUSH hbrushOld = NULL;
-
- if (!stroke_and_fill) {
- if (fill_only) {
- hpenTmp = (HPEN) GetStockObject(NULL_PEN);
- hpenOld = (HPEN) SelectObject( hdc, hpenTmp );
- }
- else { // if (stroke_only)
- hbrushTmp = (HBRUSH) GetStockObject(NULL_BRUSH);
- hbrushOld = (HBRUSH) SelectObject( hdc, hbrushTmp );
- }
- }
-
- if (polygon) {
- if (rectangle)
- Rectangle( hdc, lpPoints[0].x, lpPoints[0].y, lpPoints[2].x, lpPoints[2].y );
- else
- Polygon( hdc, lpPoints, nodes );
- }
- else if (ellipse) {
- Ellipse( hdc, lpPoints[6].x, lpPoints[3].y, lpPoints[0].x, lpPoints[9].y);
- }
-
- done = true;
-
- if (hpenOld)
- SelectObject( hdc, hpenOld );
- if (hpenTmp)
- DeleteObject( hpenTmp );
- if (hbrushOld)
- SelectObject( hdc, hbrushOld );
- if (hbrushTmp)
- DeleteObject( hbrushTmp );
- }
-
- delete[] lpPoints;
-
- return done;
-}
-
-unsigned int PrintEmfWin32::print_pathv(Geom::PathVector const &pathv, const Geom::Affine &transform)
-{
- simple_shape = print_simple_shape(pathv, transform);
-
- if (simple_shape)
- return TRUE;
-
- Geom::PathVector pv = pathv_to_linear_and_cubic_beziers( pathv * transform );
-
- BeginPath( hdc );
-
- /**
- * For all Subpaths in the <path>
- */
- for (Geom::PathVector::const_iterator pit = pv.begin(); pit != pv.end(); ++pit)
- {
- using Geom::X;
- using Geom::Y;
-
- Geom::Point p0 = pit->initialPoint();
-
- p0[X] = (p0[X] * IN_PER_PX * dwDPI);
- p0[Y] = (p0[Y] * IN_PER_PX * dwDPI);
-
- LONG const x0 = (LONG) round(p0[X]);
- LONG const y0 = (LONG) round(rc.bottom-p0[Y]);
-
- MoveToEx( hdc, x0, y0, NULL );
-
- /**
- * For all segments in the subpath
- */
- for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit)
- {
- if ( is_straight_curve(*cit) )
- {
- //Geom::Point p0 = cit->initialPoint();
- Geom::Point p1 = cit->finalPoint();
-
- //p0[X] = (p0[X] * IN_PER_PX * dwDPI);
- p1[X] = (p1[X] * IN_PER_PX * dwDPI);
- //p0[Y] = (p0[Y] * IN_PER_PX * dwDPI);
- p1[Y] = (p1[Y] * IN_PER_PX * dwDPI);
-
- //LONG const x0 = (LONG) round(p0[X]);
- //LONG const y0 = (LONG) round(rc.bottom-p0[Y]);
- LONG const x1 = (LONG) round(p1[X]);
- LONG const y1 = (LONG) round(rc.bottom-p1[Y]);
-
- LineTo( hdc, x1, y1 );
- }
- else if (Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const*>(&*cit))
- {
- std::vector<Geom::Point> points = cubic->points();
- //Geom::Point p0 = points[0];
- Geom::Point p1 = points[1];
- Geom::Point p2 = points[2];
- Geom::Point p3 = points[3];
-
- //p0[X] = (p0[X] * IN_PER_PX * dwDPI);
- p1[X] = (p1[X] * IN_PER_PX * dwDPI);
- p2[X] = (p2[X] * IN_PER_PX * dwDPI);
- p3[X] = (p3[X] * IN_PER_PX * dwDPI);
- //p0[Y] = (p0[Y] * IN_PER_PX * dwDPI);
- p1[Y] = (p1[Y] * IN_PER_PX * dwDPI);
- p2[Y] = (p2[Y] * IN_PER_PX * dwDPI);
- p3[Y] = (p3[Y] * IN_PER_PX * dwDPI);
-
- //LONG const x0 = (LONG) round(p0[X]);
- //LONG const y0 = (LONG) round(rc.bottom-p0[Y]);
- LONG const x1 = (LONG) round(p1[X]);
- LONG const y1 = (LONG) round(rc.bottom-p1[Y]);
- LONG const x2 = (LONG) round(p2[X]);
- LONG const y2 = (LONG) round(rc.bottom-p2[Y]);
- LONG const x3 = (LONG) round(p3[X]);
- LONG const y3 = (LONG) round(rc.bottom-p3[Y]);
-
- POINT pt[3];
- pt[0].x = x1;
- pt[0].y = y1;
- pt[1].x = x2;
- pt[1].y = y2;
- pt[2].x = x3;
- pt[2].y = y3;
-
- PolyBezierTo( hdc, pt, 3 );
- }
- else
- {
- g_warning("logical error, because pathv_to_linear_and_cubic_beziers was used");
- }
- }
-
- if (pit->end_default() == pit->end_closed()) {
- CloseFigure( hdc );
- }
- }
-
- EndPath( hdc );
-
- return TRUE;
-}
-
-
-bool PrintEmfWin32::textToPath(Inkscape::Extension::Print * ext)
-{
- return ext->get_param_bool("textToPath");
-}
-
-unsigned int PrintEmfWin32::text(Inkscape::Extension::Print * /*mod*/, char const *text, Geom::Point const &p,
- SPStyle const *const style)
-{
- if (!hdc) return 0;
-
- HFONT hfont = NULL;
- Geom::Affine tf = m_tr_stack.top();
- double rot = 1800.0*std::atan2(tf[1], tf[0])/M_PI; // 0.1 degree rotation
-
-#ifdef USE_PANGO_WIN32
-/*
- font_instance *tf = (font_factory::Default())->Face(style->text->font_family.value, font_style_to_pos(*style));
- if (tf) {
- LOGFONT *lf = pango_win32_font_logfont(tf->pFont);
- tf->Unref();
- hfont = CreateFontIndirect(lf);
- g_free(lf);
- }
-*/
-#endif
-
- if (!hfont) {
- LOGFONTW *lf = (LOGFONTW*)g_malloc(sizeof(LOGFONTW));
- g_assert(lf != NULL);
-
- lf->lfHeight = -style->font_size.computed * IN_PER_PX * dwDPI;
- lf->lfWidth = 0;
- lf->lfEscapement = rot;
- lf->lfOrientation = rot;
- lf->lfWeight =
- style->font_weight.computed == SP_CSS_FONT_WEIGHT_100 ? FW_THIN :
- style->font_weight.computed == SP_CSS_FONT_WEIGHT_200 ? FW_EXTRALIGHT :
- style->font_weight.computed == SP_CSS_FONT_WEIGHT_300 ? FW_LIGHT :
- style->font_weight.computed == SP_CSS_FONT_WEIGHT_400 ? FW_NORMAL :
- style->font_weight.computed == SP_CSS_FONT_WEIGHT_500 ? FW_MEDIUM :
- style->font_weight.computed == SP_CSS_FONT_WEIGHT_600 ? FW_SEMIBOLD :
- style->font_weight.computed == SP_CSS_FONT_WEIGHT_700 ? FW_BOLD :
- style->font_weight.computed == SP_CSS_FONT_WEIGHT_800 ? FW_EXTRABOLD :
- style->font_weight.computed == SP_CSS_FONT_WEIGHT_900 ? FW_HEAVY :
- FW_NORMAL;
- lf->lfItalic = (style->font_style.computed == SP_CSS_FONT_STYLE_ITALIC);
- lf->lfUnderline = style->text_decoration.underline;
- lf->lfStrikeOut = style->text_decoration.line_through;
- lf->lfCharSet = DEFAULT_CHARSET;
- lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
- lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
- lf->lfQuality = DEFAULT_QUALITY;
- lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
-
- gunichar2 *unicode_name = g_utf8_to_utf16( style->text->font_family.value, -1, NULL, NULL, NULL );
- wcsncpy(lf->lfFaceName, (wchar_t*) unicode_name, LF_FACESIZE-1);
- g_free(unicode_name);
-
- hfont = CreateFontIndirectW(lf);
-
- g_free(lf);
- }
-
- HFONT hfontOld = (HFONT) SelectObject(hdc, hfont);
-
- float rgb[3];
- sp_color_get_rgb_floatv( &style->fill.value.color, rgb );
- SetTextColor(hdc, RGB(255*rgb[0], 255*rgb[1], 255*rgb[2]));
-
- // Text alignment:
- // - (x,y) coordinates received by this filter are those of the point where the text
- // actually starts, and already takes into account the text object's alignment;
- // - for this reason, the EMF text alignment must always be TA_BASELINE|TA_LEFT.
- SetTextAlign(hdc, TA_BASELINE | TA_LEFT);
-
- // Transparent text background
- SetBkMode(hdc, TRANSPARENT);
-
- Geom::Point p2 = p * tf;
- p2[Geom::X] = (p2[Geom::X] * IN_PER_PX * dwDPI);
- p2[Geom::Y] = (p2[Geom::Y] * IN_PER_PX * dwDPI);
-
- LONG const xpos = (LONG) round(p2[Geom::X]);
- LONG const ypos = (LONG) round(rc.bottom - p2[Geom::Y]);
-
- {
- gunichar2 *unicode_text = g_utf8_to_utf16( text, -1, NULL, NULL, NULL );
- TextOutW(hdc, xpos, ypos, (WCHAR*)unicode_text, wcslen((wchar_t*)unicode_text));
- }
-
- SelectObject(hdc, hfontOld);
- DeleteObject(hfont);
-
- return 0;
-}
-
-void PrintEmfWin32::init (void)
-{
- /* EMF print */
- Inkscape::Extension::build_from_mem(
- "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
- "<name>Enhanced Metafile Print</name>\n"
- "<id>org.inkscape.print.emf.win32</id>\n"
- "<param name=\"destination\" type=\"string\"></param>\n"
- "<param name=\"textToPath\" type=\"boolean\">true</param>\n"
- "<param name=\"pageBoundingBox\" type=\"boolean\">true</param>\n"
- "<print/>\n"
- "</inkscape-extension>", new PrintEmfWin32());
-
- return;
-}
-
-unsigned int PrintEmfWin32::image(Inkscape::Extension::Print * /* module */, /** not used */
- unsigned char *px, /** array of pixel values, Gdk::Pixbuf bitmap format */
- unsigned int /*w*/, /** width of bitmap */
- unsigned int /*h*/, /** height of bitmap */
- unsigned int /*rs*/, /** row stride (normally w*4) */
- Geom::Affine const & /*tf_ignore*/, /** WRONG affine transform, use the one from m_tr_stack */
- SPStyle const * /*style*/) /** provides indirect link to image object */
-{
- free(px);
- return 0;
-}
-
-} /* namespace Internal */
-} /* namespace Extension */
-} /* namespace Inkscape */
-
-#endif /* WIN32 */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :