From 3374f3441209c6f20cb62ffaa7f20cc6489cb5ed Mon Sep 17 00:00:00 2001 From: ulferikson Date: Wed, 10 Sep 2008 14:54:40 +0000 Subject: [PATCH] 2geomify, remove warnings and other fixes --- src/extension/internal/emf-win32-inout.cpp | 597 ++++++++++++--------- src/extension/internal/emf-win32-inout.h | 1 - src/extension/internal/emf-win32-print.cpp | 461 ++++++++-------- src/extension/internal/emf-win32-print.h | 22 +- 4 files changed, 590 insertions(+), 491 deletions(-) diff --git a/src/extension/internal/emf-win32-inout.cpp b/src/extension/internal/emf-win32-inout.cpp index 977b0eb64..d0e2e8810 100644 --- a/src/extension/internal/emf-win32-inout.cpp +++ b/src/extension/internal/emf-win32-inout.cpp @@ -27,43 +27,47 @@ # include "config.h" #endif -#include "win32.h" -#include "emf-win32-print.h" -#include "emf-win32-inout.h" -#include "inkscape.h" +//#include "inkscape.h" #include "sp-path.h" #include "style.h" -#include "color.h" -#include "display/curve.h" -#include "libnr/nr-point-matrix-ops.h" -#include "gtk/gtk.h" +//#include "color.h" +//#include "display/curve.h" +//#include "libnr/nr-point-matrix-ops.h" +//#include "gtk/gtk.h" #include "print.h" -#include "glibmm/i18n.h" -#include "extension/extension.h" +//#include "glibmm/i18n.h" +//#include "extension/extension.h" #include "extension/system.h" #include "extension/print.h" #include "extension/db.h" #include "extension/output.h" -#include "document.h" +//#include "document.h" #include "display/nr-arena.h" #include "display/nr-arena-item.h" -#include "libnr/nr-rect.h" -#include "libnr/nr-matrix.h" -#include "libnr/nr-pixblock.h" +//#include "libnr/nr-rect.h" +//#include "libnr/nr-matrix.h" +//#include "libnr/nr-pixblock.h" -#include -#include +//#include +//#include -#include -#include +//#include +//#include -#include "io/sys.h" +//#include "io/sys.h" #include "unit-constants.h" #include "clear-n_.h" +#define WIN32_LEAN_AND_MEAN +#include + +#include "win32.h" +#include "emf-win32-print.h" +#include "emf-win32-inout.h" + #define PRINT_EMF_WIN32 "org.inkscape.print.emf.win32" @@ -90,7 +94,7 @@ EmfWin32::~EmfWin32 (void) //The destructor bool -EmfWin32::check (Inkscape::Extension::Extension * module) +EmfWin32::check (Inkscape::Extension::Extension * /*module*/) { if (NULL == Inkscape::Extension::db.get(PRINT_EMF_WIN32)) return FALSE; @@ -172,28 +176,20 @@ EmfWin32::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar * typedef struct { int type; + int level; ENHMETARECORD *lpEMFR; } EMF_OBJECT, *PEMF_OBJECT; -typedef struct emf_callback_data { - Glib::ustring *outsvg; - Glib::ustring *path; +typedef struct emf_device_context { struct SPStyle style; class SPTextStyle tstyle; bool stroke_set; bool fill_set; - double xDPI, yDPI; - bool pathless_stroke; - bool inpath; SIZEL sizeWnd; SIZEL sizeView; float PixelsInX, PixelsInY; float PixelsOutX, PixelsOutY; - float MMX; - float MMY; - float dwInchesX; - float dwInchesY; POINTL winorg; POINTL vieworg; double ScaleInX, ScaleInY; @@ -202,6 +198,27 @@ typedef struct emf_callback_data { bool textColorSet; DWORD textAlign; XFORM worldTransform; + POINTL cur; +} EMF_DEVICE_CONTEXT, *PEMF_DEVICE_CONTEXT; + +#define EMF_MAX_DC 128 + +typedef struct emf_callback_data { + Glib::ustring *outsvg; + Glib::ustring *path; + + EMF_DEVICE_CONTEXT dc[EMF_MAX_DC+1]; // FIXME: This should be dynamic.. + int level; + + double xDPI, yDPI; + bool pathless_stroke; + bool inpath; + + float MMX; + float MMY; + float dwInchesX; + float dwInchesY; + unsigned int id; CHAR *pDesc; @@ -218,15 +235,15 @@ output_style(PEMF_CALLBACK_DATA d, int iType) char tmp[1024] = {0}; float fill_rgb[3]; - sp_color_get_rgb_floatv( &(d->style.fill.value.color), fill_rgb ); + sp_color_get_rgb_floatv( &(d->dc[d->level].style.fill.value.color), fill_rgb ); float stroke_rgb[3]; - sp_color_get_rgb_floatv(&(d->style.stroke.value.color), stroke_rgb); + sp_color_get_rgb_floatv(&(d->dc[d->level].style.stroke.value.color), stroke_rgb); tmp_id << "\n\tid=\"" << (d->id++) << "\""; *(d->outsvg) += tmp_id.str().c_str(); *(d->outsvg) += "\n\tstyle=\""; - if (iType == EMR_STROKEPATH || !d->fill_set) { + if (iType == EMR_STROKEPATH || !d->dc[d->level].fill_set) { tmp_style << "fill:none;"; } else { snprintf(tmp, 1023, @@ -237,18 +254,18 @@ output_style(PEMF_CALLBACK_DATA d, int iType) tmp_style << tmp; snprintf(tmp, 1023, "fill-rule:%s;", - d->style.fill_rule.value == 0 ? "evenodd" : "nonzero"); + d->dc[d->level].style.fill_rule.value == 0 ? "evenodd" : "nonzero"); tmp_style << tmp; tmp_style << "fill-opacity:1;"; - if (d->fill_set && d->stroke_set && d->style.stroke_width.value == 1 && + if (d->dc[d->level].fill_set && d->dc[d->level].stroke_set && d->dc[d->level].style.stroke_width.value == 1 && fill_rgb[0]==stroke_rgb[0] && fill_rgb[1]==stroke_rgb[1] && fill_rgb[2]==stroke_rgb[2]) { - d->stroke_set = false; + d->dc[d->level].stroke_set = false; } } - if (iType == EMR_FILLPATH || !d->stroke_set) { + if (iType == EMR_FILLPATH || !d->dc[d->level].stroke_set) { tmp_style << "stroke:none;"; } else { snprintf(tmp, 1023, @@ -259,33 +276,33 @@ output_style(PEMF_CALLBACK_DATA d, int iType) tmp_style << tmp; tmp_style << "stroke-width:" << - MAX( 0.001, d->style.stroke_width.value ) << "px;"; + MAX( 0.001, d->dc[d->level].style.stroke_width.value ) << "px;"; tmp_style << "stroke-linecap:" << - (d->style.stroke_linecap.computed == 0 ? "butt" : - d->style.stroke_linecap.computed == 1 ? "round" : - d->style.stroke_linecap.computed == 2 ? "square" : + (d->dc[d->level].style.stroke_linecap.computed == 0 ? "butt" : + d->dc[d->level].style.stroke_linecap.computed == 1 ? "round" : + d->dc[d->level].style.stroke_linecap.computed == 2 ? "square" : "unknown") << ";"; tmp_style << "stroke-linejoin:" << - (d->style.stroke_linejoin.computed == 0 ? "miter" : - d->style.stroke_linejoin.computed == 1 ? "round" : - d->style.stroke_linejoin.computed == 2 ? "bevel" : + (d->dc[d->level].style.stroke_linejoin.computed == 0 ? "miter" : + d->dc[d->level].style.stroke_linejoin.computed == 1 ? "round" : + d->dc[d->level].style.stroke_linejoin.computed == 2 ? "bevel" : "unknown") << ";"; - if (d->style.stroke_linejoin.computed == 0) { + if (d->dc[d->level].style.stroke_linejoin.computed == 0) { tmp_style << "stroke-miterlimit:" << - MAX( 0.01, d->style.stroke_miterlimit.value ) << ";"; + MAX( 0.01, d->dc[d->level].style.stroke_miterlimit.value ) << ";"; } - if (d->style.stroke_dasharray_set && - d->style.stroke_dash.n_dash && d->style.stroke_dash.dash) + if (d->dc[d->level].style.stroke_dasharray_set && + d->dc[d->level].style.stroke_dash.n_dash && d->dc[d->level].style.stroke_dash.dash) { tmp_style << "stroke-dasharray:"; - for (int i=0; istyle.stroke_dash.n_dash; i++) { + for (int i=0; idc[d->level].style.stroke_dash.n_dash; i++) { if (i) tmp_style << ","; - tmp_style << d->style.stroke_dash.dash[i]; + tmp_style << d->dc[d->level].style.stroke_dash.dash[i]; } tmp_style << ";"; tmp_style << "stroke-dashoffset:0;"; @@ -303,18 +320,18 @@ output_style(PEMF_CALLBACK_DATA d, int iType) static double _pix_x_to_point(PEMF_CALLBACK_DATA d, double px) { - double tmp = px - d->winorg.x; - tmp *= d->ScaleInX ? d->ScaleInX : 1.0; - tmp += d->vieworg.x; + double tmp = px - d->dc[d->level].winorg.x; + tmp *= d->dc[d->level].ScaleInX ? d->dc[d->level].ScaleInX : 1.0; + tmp += d->dc[d->level].vieworg.x; return tmp; } static double _pix_y_to_point(PEMF_CALLBACK_DATA d, double px) { - double tmp = px - d->winorg.y; - tmp *= d->ScaleInY ? d->ScaleInY : 1.0; - tmp += d->vieworg.y; + double tmp = px - d->dc[d->level].winorg.y; + tmp *= d->dc[d->level].ScaleInY ? d->dc[d->level].ScaleInY : 1.0; + tmp += d->dc[d->level].vieworg.y; return tmp; } @@ -325,8 +342,8 @@ pix_to_x_point(PEMF_CALLBACK_DATA d, double px, double py) double ppx = _pix_x_to_point(d, px); double ppy = _pix_y_to_point(d, py); - double x = ppx * d->worldTransform.eM11 + ppy * d->worldTransform.eM21 + d->worldTransform.eDx; - x *= d->ScaleOutX ? d->ScaleOutX : DEVICESCALE; + double x = ppx * d->dc[d->level].worldTransform.eM11 + ppy * d->dc[d->level].worldTransform.eM21 + d->dc[d->level].worldTransform.eDx; + x *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : DEVICESCALE; return x; } @@ -337,8 +354,8 @@ pix_to_y_point(PEMF_CALLBACK_DATA d, double px, double py) double ppx = _pix_x_to_point(d, px); double ppy = _pix_y_to_point(d, py); - double y = ppx * d->worldTransform.eM12 + ppy * d->worldTransform.eM22 + d->worldTransform.eDy; - y *= d->ScaleOutY ? d->ScaleOutY : DEVICESCALE; + double y = ppx * d->dc[d->level].worldTransform.eM12 + ppy * d->dc[d->level].worldTransform.eM22 + d->dc[d->level].worldTransform.eDy; + y *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : DEVICESCALE; return y; } @@ -346,8 +363,14 @@ pix_to_y_point(PEMF_CALLBACK_DATA d, double px, double py) static double pix_to_size_point(PEMF_CALLBACK_DATA d, double px) { - double dx = pix_to_x_point(d, px, 0); - double dy = pix_to_y_point(d, px, 0); + double ppx = px * (d->dc[d->level].ScaleInX ? d->dc[d->level].ScaleInX : 1.0); + double ppy = 0; + + double dx = ppx * d->dc[d->level].worldTransform.eM11 + ppy * d->dc[d->level].worldTransform.eM21; + dx *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : DEVICESCALE; + double dy = ppx * d->dc[d->level].worldTransform.eM12 + ppy * d->dc[d->level].worldTransform.eM22; + dy *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : DEVICESCALE; + double tmp = sqrt(dx * dx + dy * dy); return tmp; } @@ -372,32 +395,32 @@ select_pen(PEMF_CALLBACK_DATA d, int index) { int i = 0; int penstyle = (pEmr->lopn.lopnStyle & PS_STYLE_MASK); - d->style.stroke_dash.n_dash = + d->dc[d->level].style.stroke_dash.n_dash = penstyle == PS_DASHDOTDOT ? 6 : penstyle == PS_DASHDOT ? 4 : 2; - if (d->style.stroke_dash.dash) - delete[] d->style.stroke_dash.dash; - d->style.stroke_dash.dash = new double[d->style.stroke_dash.n_dash]; + if (d->dc[d->level].style.stroke_dash.dash && (d->level==0 || (d->level>0 && d->dc[d->level].style.stroke_dash.dash!=d->dc[d->level-1].style.stroke_dash.dash))) + delete[] d->dc[d->level].style.stroke_dash.dash; + d->dc[d->level].style.stroke_dash.dash = new double[d->dc[d->level].style.stroke_dash.n_dash]; if (penstyle==PS_DASH || penstyle==PS_DASHDOT || penstyle==PS_DASHDOTDOT) { - d->style.stroke_dash.dash[i++] = 3; - d->style.stroke_dash.dash[i++] = 1; + d->dc[d->level].style.stroke_dash.dash[i++] = 3; + d->dc[d->level].style.stroke_dash.dash[i++] = 1; } if (penstyle==PS_DOT || penstyle==PS_DASHDOT || penstyle==PS_DASHDOTDOT) { - d->style.stroke_dash.dash[i++] = 1; - d->style.stroke_dash.dash[i++] = 1; + d->dc[d->level].style.stroke_dash.dash[i++] = 1; + d->dc[d->level].style.stroke_dash.dash[i++] = 1; } if (penstyle==PS_DASHDOTDOT) { - d->style.stroke_dash.dash[i++] = 1; - d->style.stroke_dash.dash[i++] = 1; + d->dc[d->level].style.stroke_dash.dash[i++] = 1; + d->dc[d->level].style.stroke_dash.dash[i++] = 1; } - d->style.stroke_dasharray_set = 1; + d->dc[d->level].style.stroke_dasharray_set = 1; break; } case PS_SOLID: default: { - d->style.stroke_dasharray_set = 0; + d->dc[d->level].style.stroke_dasharray_set = 0; break; } } @@ -405,18 +428,18 @@ select_pen(PEMF_CALLBACK_DATA d, int index) switch (pEmr->lopn.lopnStyle & PS_ENDCAP_MASK) { case PS_ENDCAP_ROUND: { - d->style.stroke_linecap.computed = 1; + d->dc[d->level].style.stroke_linecap.computed = 1; break; } case PS_ENDCAP_SQUARE: { - d->style.stroke_linecap.computed = 2; + d->dc[d->level].style.stroke_linecap.computed = 2; break; } case PS_ENDCAP_FLAT: default: { - d->style.stroke_linecap.computed = 0; + d->dc[d->level].style.stroke_linecap.computed = 0; break; } } @@ -424,39 +447,47 @@ select_pen(PEMF_CALLBACK_DATA d, int index) switch (pEmr->lopn.lopnStyle & PS_JOIN_MASK) { case PS_JOIN_BEVEL: { - d->style.stroke_linejoin.computed = 2; + d->dc[d->level].style.stroke_linejoin.computed = 2; break; } case PS_JOIN_MITER: { - d->style.stroke_linejoin.computed = 0; + d->dc[d->level].style.stroke_linejoin.computed = 0; break; } case PS_JOIN_ROUND: default: { - d->style.stroke_linejoin.computed = 1; + d->dc[d->level].style.stroke_linejoin.computed = 1; break; } } - d->stroke_set = true; + d->dc[d->level].stroke_set = true; if (pEmr->lopn.lopnStyle == PS_NULL) { - d->style.stroke_width.value = 0; - d->stroke_set = false; + d->dc[d->level].style.stroke_width.value = 0; + d->dc[d->level].stroke_set = false; } else if (pEmr->lopn.lopnWidth.x) { - d->style.stroke_width.value = pix_to_size_point( d, pEmr->lopn.lopnWidth.x ); + int cur_level = d->level; + d->level = d->emf_obj[index].level; + double pen_width = pix_to_size_point( d, pEmr->lopn.lopnWidth.x ); + d->level = cur_level; + d->dc[d->level].style.stroke_width.value = pen_width; } else { // this stroke should always be rendered as 1 pixel wide, independent of zoom level (can that be done in SVG?) - //d->style.stroke_width.value = 1.0; - d->style.stroke_width.value = pix_to_size_point( d, 1 ); + //d->dc[d->level].style.stroke_width.value = 1.0; + int cur_level = d->level; + d->level = d->emf_obj[index].level; + double pen_width = pix_to_size_point( d, 1 ); + d->level = cur_level; + d->dc[d->level].style.stroke_width.value = pen_width; } double r, g, b; r = SP_COLOR_U_TO_F( GetRValue(pEmr->lopn.lopnColor) ); g = SP_COLOR_U_TO_F( GetGValue(pEmr->lopn.lopnColor) ); b = SP_COLOR_U_TO_F( GetBValue(pEmr->lopn.lopnColor) ); - d->style.stroke.value.color.set( r, g, b ); + d->dc[d->level].style.stroke.value.color.set( r, g, b ); } @@ -475,16 +506,20 @@ select_extpen(PEMF_CALLBACK_DATA d, int index) case PS_USERSTYLE: { if (pEmr->elp.elpNumEntries) { - d->style.stroke_dash.n_dash = pEmr->elp.elpNumEntries; - if (d->style.stroke_dash.dash) - delete[] d->style.stroke_dash.dash; - d->style.stroke_dash.dash = new double[pEmr->elp.elpNumEntries]; + d->dc[d->level].style.stroke_dash.n_dash = pEmr->elp.elpNumEntries; + if (d->dc[d->level].style.stroke_dash.dash && (d->level==0 || (d->level>0 && d->dc[d->level].style.stroke_dash.dash!=d->dc[d->level-1].style.stroke_dash.dash))) + delete[] d->dc[d->level].style.stroke_dash.dash; + d->dc[d->level].style.stroke_dash.dash = new double[pEmr->elp.elpNumEntries]; for (unsigned int i=0; ielp.elpNumEntries; i++) { - d->style.stroke_dash.dash[i] = pix_to_size_point( d, pEmr->elp.elpStyleEntry[i] ); + int cur_level = d->level; + d->level = d->emf_obj[index].level; + double dash_length = pix_to_size_point( d, pEmr->elp.elpStyleEntry[i] ); + d->level = cur_level; + d->dc[d->level].style.stroke_dash.dash[i] = dash_length; } - d->style.stroke_dasharray_set = 1; + d->dc[d->level].style.stroke_dasharray_set = 1; } else { - d->style.stroke_dasharray_set = 0; + d->dc[d->level].style.stroke_dasharray_set = 0; } break; } @@ -496,32 +531,32 @@ select_extpen(PEMF_CALLBACK_DATA d, int index) { int i = 0; int penstyle = (pEmr->elp.elpPenStyle & PS_STYLE_MASK); - d->style.stroke_dash.n_dash = + d->dc[d->level].style.stroke_dash.n_dash = penstyle == PS_DASHDOTDOT ? 6 : penstyle == PS_DASHDOT ? 4 : 2; - if (d->style.stroke_dash.dash) - delete[] d->style.stroke_dash.dash; - d->style.stroke_dash.dash = new double[d->style.stroke_dash.n_dash]; + if (d->dc[d->level].style.stroke_dash.dash && (d->level==0 || (d->level>0 && d->dc[d->level].style.stroke_dash.dash!=d->dc[d->level-1].style.stroke_dash.dash))) + delete[] d->dc[d->level].style.stroke_dash.dash; + d->dc[d->level].style.stroke_dash.dash = new double[d->dc[d->level].style.stroke_dash.n_dash]; if (penstyle==PS_DASH || penstyle==PS_DASHDOT || penstyle==PS_DASHDOTDOT) { - d->style.stroke_dash.dash[i++] = 3; - d->style.stroke_dash.dash[i++] = 2; + d->dc[d->level].style.stroke_dash.dash[i++] = 3; + d->dc[d->level].style.stroke_dash.dash[i++] = 2; } if (penstyle==PS_DOT || penstyle==PS_DASHDOT || penstyle==PS_DASHDOTDOT) { - d->style.stroke_dash.dash[i++] = 1; - d->style.stroke_dash.dash[i++] = 2; + d->dc[d->level].style.stroke_dash.dash[i++] = 1; + d->dc[d->level].style.stroke_dash.dash[i++] = 2; } if (penstyle==PS_DASHDOTDOT) { - d->style.stroke_dash.dash[i++] = 1; - d->style.stroke_dash.dash[i++] = 2; + d->dc[d->level].style.stroke_dash.dash[i++] = 1; + d->dc[d->level].style.stroke_dash.dash[i++] = 2; } - d->style.stroke_dasharray_set = 1; + d->dc[d->level].style.stroke_dasharray_set = 1; break; } case PS_SOLID: default: { - d->style.stroke_dasharray_set = 0; + d->dc[d->level].style.stroke_dasharray_set = 0; break; } } @@ -529,18 +564,18 @@ select_extpen(PEMF_CALLBACK_DATA d, int index) switch (pEmr->elp.elpPenStyle & PS_ENDCAP_MASK) { case PS_ENDCAP_ROUND: { - d->style.stroke_linecap.computed = 1; + d->dc[d->level].style.stroke_linecap.computed = 1; break; } case PS_ENDCAP_SQUARE: { - d->style.stroke_linecap.computed = 2; + d->dc[d->level].style.stroke_linecap.computed = 2; break; } case PS_ENDCAP_FLAT: default: { - d->style.stroke_linecap.computed = 0; + d->dc[d->level].style.stroke_linecap.computed = 0; break; } } @@ -548,32 +583,40 @@ select_extpen(PEMF_CALLBACK_DATA d, int index) switch (pEmr->elp.elpPenStyle & PS_JOIN_MASK) { case PS_JOIN_BEVEL: { - d->style.stroke_linejoin.computed = 2; + d->dc[d->level].style.stroke_linejoin.computed = 2; break; } case PS_JOIN_MITER: { - d->style.stroke_linejoin.computed = 0; + d->dc[d->level].style.stroke_linejoin.computed = 0; break; } case PS_JOIN_ROUND: default: { - d->style.stroke_linejoin.computed = 1; + d->dc[d->level].style.stroke_linejoin.computed = 1; break; } } - d->stroke_set = true; + d->dc[d->level].stroke_set = true; if (pEmr->elp.elpPenStyle == PS_NULL) { - d->style.stroke_width.value = 0; - d->stroke_set = false; + d->dc[d->level].style.stroke_width.value = 0; + d->dc[d->level].stroke_set = false; } else if (pEmr->elp.elpWidth) { - d->style.stroke_width.value = pix_to_size_point( d, pEmr->elp.elpWidth ); + int cur_level = d->level; + d->level = d->emf_obj[index].level; + double pen_width = pix_to_size_point( d, pEmr->elp.elpWidth ); + d->level = cur_level; + d->dc[d->level].style.stroke_width.value = pen_width; } else { // this stroke should always be rendered as 1 pixel wide, independent of zoom level (can that be done in SVG?) - //d->style.stroke_width.value = 1.0; - d->style.stroke_width.value = pix_to_size_point( d, 1 ); + //d->dc[d->level].style.stroke_width.value = 1.0; + int cur_level = d->level; + d->level = d->emf_obj[index].level; + double pen_width = pix_to_size_point( d, 1 ); + d->level = cur_level; + d->dc[d->level].style.stroke_width.value = pen_width; } double r, g, b; @@ -581,7 +624,7 @@ select_extpen(PEMF_CALLBACK_DATA d, int index) g = SP_COLOR_U_TO_F( GetGValue(pEmr->elp.elpColor) ); b = SP_COLOR_U_TO_F( GetBValue(pEmr->elp.elpColor) ); - d->style.stroke.value.color.set( r, g, b ); + d->dc[d->level].style.stroke.value.color.set( r, g, b ); } @@ -601,10 +644,10 @@ select_brush(PEMF_CALLBACK_DATA d, int index) r = SP_COLOR_U_TO_F( GetRValue(pEmr->lb.lbColor) ); g = SP_COLOR_U_TO_F( GetGValue(pEmr->lb.lbColor) ); b = SP_COLOR_U_TO_F( GetBValue(pEmr->lb.lbColor) ); - d->style.fill.value.color.set( r, g, b ); + d->dc[d->level].style.fill.value.color.set( r, g, b ); } - d->fill_set = true; + d->dc[d->level].fill_set = true; } @@ -619,8 +662,12 @@ select_font(PEMF_CALLBACK_DATA d, int index) if (!pEmr) return; - d->style.font_size.computed = pix_to_size_point( d, pEmr->elfw.elfLogFont.lfHeight ); - d->style.font_weight.value = + int cur_level = d->level; + d->level = d->emf_obj[index].level; + double font_size = pix_to_size_point( d, pEmr->elfw.elfLogFont.lfHeight ); + d->level = cur_level; + d->dc[d->level].style.font_size.computed = font_size; + d->dc[d->level].style.font_weight.value = pEmr->elfw.elfLogFont.lfWeight == FW_THIN ? SP_CSS_FONT_WEIGHT_100 : pEmr->elfw.elfLogFont.lfWeight == FW_EXTRALIGHT ? SP_CSS_FONT_WEIGHT_200 : pEmr->elfw.elfLogFont.lfWeight == FW_LIGHT ? SP_CSS_FONT_WEIGHT_300 : @@ -635,13 +682,14 @@ select_font(PEMF_CALLBACK_DATA d, int index) pEmr->elfw.elfLogFont.lfWeight == FW_EXTRALIGHT ? SP_CSS_FONT_WEIGHT_LIGHTER : pEmr->elfw.elfLogFont.lfWeight == FW_EXTRABOLD ? SP_CSS_FONT_WEIGHT_BOLDER : FW_NORMAL; - d->style.font_style.value = (pEmr->elfw.elfLogFont.lfItalic ? SP_CSS_FONT_STYLE_ITALIC : SP_CSS_FONT_STYLE_NORMAL); - d->style.text_decoration.underline = pEmr->elfw.elfLogFont.lfUnderline; - d->style.text_decoration.line_through = pEmr->elfw.elfLogFont.lfStrikeOut; - if (d->tstyle.font_family.value) - g_free(d->tstyle.font_family.value); - d->tstyle.font_family.value = + d->dc[d->level].style.font_style.value = (pEmr->elfw.elfLogFont.lfItalic ? SP_CSS_FONT_STYLE_ITALIC : SP_CSS_FONT_STYLE_NORMAL); + d->dc[d->level].style.text_decoration.underline = pEmr->elfw.elfLogFont.lfUnderline; + d->dc[d->level].style.text_decoration.line_through = pEmr->elfw.elfLogFont.lfStrikeOut; + if (d->dc[d->level].tstyle.font_family.value) + g_free(d->dc[d->level].tstyle.font_family.value); + d->dc[d->level].tstyle.font_family.value = (gchar *) g_utf16_to_utf8( (gunichar2*) pEmr->elfw.elfLogFont.lfFaceName, -1, NULL, NULL, NULL ); + d->dc[d->level].style.text_transform.value = ((pEmr->elfw.elfLogFont.lfEscapement + 3600) % 3600) / 10; } static void @@ -662,12 +710,13 @@ insert_object(PEMF_CALLBACK_DATA d, int index, int type, ENHMETARECORD *pObj) if (index >= 0 && index < d->n_obj) { delete_object(d, index); d->emf_obj[index].type = type; + d->emf_obj[index].level = d->level; d->emf_obj[index].lpEMFR = pObj; } } static void -assert_empty_path(PEMF_CALLBACK_DATA d, const char *fun) +assert_empty_path(PEMF_CALLBACK_DATA d, const char * /*fun*/) { if (!d->path->empty()) { // g_debug("emf-win32-inout: assert_empty_path failed for %s\n", fun); @@ -689,7 +738,7 @@ assert_empty_path(PEMF_CALLBACK_DATA d, const char *fun) static int CALLBACK -myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData) +myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD *lpEMFR, int /*nObj*/, LPARAM lpData) { PEMF_CALLBACK_DATA d; SVGOStringStream tmp_outsvg; @@ -739,14 +788,14 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb d->xDPI = 2540; d->yDPI = 2540; - d->PixelsInX = pEmr->rclFrame.right - pEmr->rclFrame.left; - d->PixelsInY = pEmr->rclFrame.bottom - pEmr->rclFrame.top; + d->dc[d->level].PixelsInX = pEmr->rclFrame.right - pEmr->rclFrame.left; + d->dc[d->level].PixelsInY = pEmr->rclFrame.bottom - pEmr->rclFrame.top; - d->MMX = d->PixelsInX / 100.0; - d->MMY = d->PixelsInY / 100.0; + d->MMX = d->dc[d->level].PixelsInX / 100.0; + d->MMY = d->dc[d->level].PixelsInY / 100.0; - d->PixelsOutX = d->MMX * PX_PER_MM; - d->PixelsOutY = d->MMY * PX_PER_MM; + d->dc[d->level].PixelsOutX = d->MMX * PX_PER_MM; + d->dc[d->level].PixelsOutY = d->MMY * PX_PER_MM; tmp_outsvg << " width=\"" << d->MMX << "mm\"\n" << @@ -766,7 +815,7 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb // dynamic allocation succeeded. if ( d->emf_obj != NULL ) { - for( unsigned int i=0; i < d->n_obj; ++i ) + for( int i=0; i < d->n_obj; ++i ) d->emf_obj[i].lpEMFR = NULL; } //if @@ -994,39 +1043,39 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb PEMRSETWINDOWEXTEX pEmr = (PEMRSETWINDOWEXTEX) lpEMFR; - d->sizeWnd = pEmr->szlExtent; + d->dc[d->level].sizeWnd = pEmr->szlExtent; - if (!d->sizeWnd.cx || !d->sizeWnd.cy) { - d->sizeWnd = d->sizeView; - if (!d->sizeWnd.cx || !d->sizeWnd.cy) { - d->sizeWnd.cx = d->PixelsOutX; - d->sizeWnd.cy = d->PixelsOutY; + if (!d->dc[d->level].sizeWnd.cx || !d->dc[d->level].sizeWnd.cy) { + d->dc[d->level].sizeWnd = d->dc[d->level].sizeView; + if (!d->dc[d->level].sizeWnd.cx || !d->dc[d->level].sizeWnd.cy) { + d->dc[d->level].sizeWnd.cx = d->dc[d->level].PixelsOutX; + d->dc[d->level].sizeWnd.cy = d->dc[d->level].PixelsOutY; } } - if (!d->sizeView.cx || !d->sizeView.cy) { - d->sizeView = d->sizeWnd; + if (!d->dc[d->level].sizeView.cx || !d->dc[d->level].sizeView.cy) { + d->dc[d->level].sizeView = d->dc[d->level].sizeWnd; } - d->PixelsInX = d->sizeWnd.cx; - d->PixelsInY = d->sizeWnd.cy; + d->dc[d->level].PixelsInX = d->dc[d->level].sizeWnd.cx; + d->dc[d->level].PixelsInY = d->dc[d->level].sizeWnd.cy; - if (d->PixelsInX && d->PixelsInY) { - d->ScaleInX = (double) d->sizeView.cx / (double) d->PixelsInX; - d->ScaleInY = (double) d->sizeView.cy / (double) d->PixelsInY; + if (d->dc[d->level].PixelsInX && d->dc[d->level].PixelsInY) { + d->dc[d->level].ScaleInX = (double) d->dc[d->level].sizeView.cx / (double) d->dc[d->level].PixelsInX; + d->dc[d->level].ScaleInY = (double) d->dc[d->level].sizeView.cy / (double) d->dc[d->level].PixelsInY; } else { - d->ScaleInX = 1; - d->ScaleInY = 1; + d->dc[d->level].ScaleInX = 1; + d->dc[d->level].ScaleInY = 1; } - if (d->sizeView.cx && d->sizeView.cy) { - d->ScaleOutX = (double) d->PixelsOutX / (double) d->sizeView.cx; - d->ScaleOutY = (double) d->PixelsOutY / (double) d->sizeView.cy; + if (d->dc[d->level].sizeView.cx && d->dc[d->level].sizeView.cy) { + d->dc[d->level].ScaleOutX = (double) d->dc[d->level].PixelsOutX / (double) d->dc[d->level].sizeView.cx; + d->dc[d->level].ScaleOutY = (double) d->dc[d->level].PixelsOutY / (double) d->dc[d->level].sizeView.cy; } else { - d->ScaleOutX = DEVICESCALE; - d->ScaleOutY = DEVICESCALE; + d->dc[d->level].ScaleOutX = DEVICESCALE; + d->dc[d->level].ScaleOutY = DEVICESCALE; } break; @@ -1036,7 +1085,7 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb dbg_str << "\n"; PEMRSETWINDOWORGEX pEmr = (PEMRSETWINDOWORGEX) lpEMFR; - d->winorg = pEmr->ptlOrigin; + d->dc[d->level].winorg = pEmr->ptlOrigin; break; } case EMR_SETVIEWPORTEXTEX: @@ -1045,39 +1094,39 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb PEMRSETVIEWPORTEXTEX pEmr = (PEMRSETVIEWPORTEXTEX) lpEMFR; - d->sizeView = pEmr->szlExtent; + d->dc[d->level].sizeView = pEmr->szlExtent; - if (!d->sizeView.cx || !d->sizeView.cy) { - d->sizeView = d->sizeWnd; - if (!d->sizeView.cx || !d->sizeView.cy) { - d->sizeView.cx = d->PixelsOutX; - d->sizeView.cy = d->PixelsOutY; + if (!d->dc[d->level].sizeView.cx || !d->dc[d->level].sizeView.cy) { + d->dc[d->level].sizeView = d->dc[d->level].sizeWnd; + if (!d->dc[d->level].sizeView.cx || !d->dc[d->level].sizeView.cy) { + d->dc[d->level].sizeView.cx = d->dc[d->level].PixelsOutX; + d->dc[d->level].sizeView.cy = d->dc[d->level].PixelsOutY; } } - if (!d->sizeWnd.cx || !d->sizeWnd.cy) { - d->sizeWnd = d->sizeView; + if (!d->dc[d->level].sizeWnd.cx || !d->dc[d->level].sizeWnd.cy) { + d->dc[d->level].sizeWnd = d->dc[d->level].sizeView; } - d->PixelsInX = d->sizeWnd.cx; - d->PixelsInY = d->sizeWnd.cy; + d->dc[d->level].PixelsInX = d->dc[d->level].sizeWnd.cx; + d->dc[d->level].PixelsInY = d->dc[d->level].sizeWnd.cy; - if (d->PixelsInX && d->PixelsInY) { - d->ScaleInX = (double) d->sizeView.cx / (double) d->PixelsInX; - d->ScaleInY = (double) d->sizeView.cy / (double) d->PixelsInY; + if (d->dc[d->level].PixelsInX && d->dc[d->level].PixelsInY) { + d->dc[d->level].ScaleInX = (double) d->dc[d->level].sizeView.cx / (double) d->dc[d->level].PixelsInX; + d->dc[d->level].ScaleInY = (double) d->dc[d->level].sizeView.cy / (double) d->dc[d->level].PixelsInY; } else { - d->ScaleInX = 1; - d->ScaleInY = 1; + d->dc[d->level].ScaleInX = 1; + d->dc[d->level].ScaleInY = 1; } - if (d->sizeView.cx && d->sizeView.cy) { - d->ScaleOutX = (double) d->PixelsOutX / (double) d->sizeView.cx; - d->ScaleOutY = (double) d->PixelsOutY / (double) d->sizeView.cy; + if (d->dc[d->level].sizeView.cx && d->dc[d->level].sizeView.cy) { + d->dc[d->level].ScaleOutX = (double) d->dc[d->level].PixelsOutX / (double) d->dc[d->level].sizeView.cx; + d->dc[d->level].ScaleOutY = (double) d->dc[d->level].PixelsOutY / (double) d->dc[d->level].sizeView.cy; } else { - d->ScaleOutX = DEVICESCALE; - d->ScaleOutY = DEVICESCALE; + d->dc[d->level].ScaleOutX = DEVICESCALE; + d->dc[d->level].ScaleOutY = DEVICESCALE; } break; @@ -1087,7 +1136,7 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb dbg_str << "\n"; PEMRSETVIEWPORTORGEX pEmr = (PEMRSETVIEWPORTORGEX) lpEMFR; - d->vieworg = pEmr->ptlOrigin; + d->dc[d->level].vieworg = pEmr->ptlOrigin; break; } case EMR_SETBRUSHORGEX: @@ -1119,7 +1168,7 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb dbg_str << "\n"; PEMRSETPOLYFILLMODE pEmr = (PEMRSETPOLYFILLMODE) lpEMFR; - d->style.fill_rule.value = + d->dc[d->level].style.fill_rule.value = (pEmr->iMode == ALTERNATE ? 0 : pEmr->iMode == WINDING ? 1 : 0); break; @@ -1135,7 +1184,7 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb dbg_str << "\n"; PEMRSETTEXTALIGN pEmr = (PEMRSETTEXTALIGN) lpEMFR; - d->textAlign = pEmr->iMode; + d->dc[d->level].textAlign = pEmr->iMode; break; } case EMR_SETCOLORADJUSTMENT: @@ -1146,8 +1195,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb dbg_str << "\n"; PEMRSETTEXTCOLOR pEmr = (PEMRSETTEXTCOLOR) lpEMFR; - d->textColor = pEmr->crColor; - d->textColorSet = true; + d->dc[d->level].textColor = pEmr->crColor; + d->dc[d->level].textColorSet = true; break; } case EMR_SETBKCOLOR: @@ -1167,6 +1216,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb *(d->path) = "d=\""; } + d->dc[d->level].cur = pEmr->ptl; + tmp_path << "\n\tM " << pix_to_x_point( d, pEmr->ptl.x, pEmr->ptl.y ) << " " << @@ -1190,16 +1241,39 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb break; case EMR_SAVEDC: dbg_str << "\n"; + + if (d->level < EMF_MAX_DC) { + d->dc[d->level + 1] = d->dc[d->level]; + d->level = d->level + 1; + } break; case EMR_RESTOREDC: + { dbg_str << "\n"; + + PEMRRESTOREDC pEmr = (PEMRRESTOREDC) lpEMFR; + int old_level = d->level; + if (pEmr->iRelative >= 0) { + if (pEmr->iRelative < d->level) + d->level = pEmr->iRelative; + } + else { + if (d->level + pEmr->iRelative >= 0) + d->level = d->level + pEmr->iRelative; + } + while (old_level > d->level) { + if (d->dc[old_level].style.stroke_dash.dash && (old_level==0 || (old_level>0 && d->dc[old_level].style.stroke_dash.dash!=d->dc[old_level-1].style.stroke_dash.dash))) + delete[] d->dc[old_level].style.stroke_dash.dash; + old_level--; + } break; + } case EMR_SETWORLDTRANSFORM: { dbg_str << "\n"; PEMRSETWORLDTRANSFORM pEmr = (PEMRSETWORLDTRANSFORM) lpEMFR; - d->worldTransform = pEmr->xform; + d->dc[d->level].worldTransform = pEmr->xform; break; } case EMR_MODIFYWORLDTRANSFORM: @@ -1210,16 +1284,16 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb switch (pEmr->iMode) { case MWT_IDENTITY: - d->worldTransform.eM11 = 1.0; - d->worldTransform.eM12 = 0.0; - d->worldTransform.eM21 = 0.0; - d->worldTransform.eM22 = 1.0; - d->worldTransform.eDx = 0.0; - d->worldTransform.eDy = 0.0; + d->dc[d->level].worldTransform.eM11 = 1.0; + d->dc[d->level].worldTransform.eM12 = 0.0; + d->dc[d->level].worldTransform.eM21 = 0.0; + d->dc[d->level].worldTransform.eM22 = 1.0; + d->dc[d->level].worldTransform.eDx = 0.0; + d->dc[d->level].worldTransform.eDy = 0.0; break; case MWT_LEFTMULTIPLY: { -// d->worldTransform = pEmr->xform * worldTransform; +// d->dc[d->level].worldTransform = pEmr->xform * worldTransform; float a11 = pEmr->xform.eM11; float a12 = pEmr->xform.eM12; @@ -1231,14 +1305,14 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb float a32 = pEmr->xform.eDy; float a33 = 1.0; - float b11 = d->worldTransform.eM11; - float b12 = d->worldTransform.eM12; + float b11 = d->dc[d->level].worldTransform.eM11; + float b12 = d->dc[d->level].worldTransform.eM12; //float b13 = 0.0; - float b21 = d->worldTransform.eM21; - float b22 = d->worldTransform.eM22; + float b21 = d->dc[d->level].worldTransform.eM21; + float b22 = d->dc[d->level].worldTransform.eM22; //float b23 = 0.0; - float b31 = d->worldTransform.eDx; - float b32 = d->worldTransform.eDy; + float b31 = d->dc[d->level].worldTransform.eDx; + float b32 = d->dc[d->level].worldTransform.eDy; //float b33 = 1.0; float c11 = a11*b11 + a12*b21 + a13*b31;; @@ -1251,27 +1325,27 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb float c32 = a31*b12 + a32*b22 + a33*b32;; //float c33 = a31*b13 + a32*b23 + a33*b33;; - d->worldTransform.eM11 = c11;; - d->worldTransform.eM12 = c12;; - d->worldTransform.eM21 = c21;; - d->worldTransform.eM22 = c22;; - d->worldTransform.eDx = c31; - d->worldTransform.eDy = c32; + d->dc[d->level].worldTransform.eM11 = c11;; + d->dc[d->level].worldTransform.eM12 = c12;; + d->dc[d->level].worldTransform.eM21 = c21;; + d->dc[d->level].worldTransform.eM22 = c22;; + d->dc[d->level].worldTransform.eDx = c31; + d->dc[d->level].worldTransform.eDy = c32; break; } case MWT_RIGHTMULTIPLY: { -// d->worldTransform = worldTransform * pEmr->xform; +// d->dc[d->level].worldTransform = worldTransform * pEmr->xform; - float a11 = d->worldTransform.eM11; - float a12 = d->worldTransform.eM12; + float a11 = d->dc[d->level].worldTransform.eM11; + float a12 = d->dc[d->level].worldTransform.eM12; float a13 = 0.0; - float a21 = d->worldTransform.eM21; - float a22 = d->worldTransform.eM22; + float a21 = d->dc[d->level].worldTransform.eM21; + float a22 = d->dc[d->level].worldTransform.eM22; float a23 = 0.0; - float a31 = d->worldTransform.eDx; - float a32 = d->worldTransform.eDy; + float a31 = d->dc[d->level].worldTransform.eDx; + float a32 = d->dc[d->level].worldTransform.eDy; float a33 = 1.0; float b11 = pEmr->xform.eM11; @@ -1294,18 +1368,18 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb float c32 = a31*b12 + a32*b22 + a33*b32;; //float c33 = a31*b13 + a32*b23 + a33*b33;; - d->worldTransform.eM11 = c11;; - d->worldTransform.eM12 = c12;; - d->worldTransform.eM21 = c21;; - d->worldTransform.eM22 = c22;; - d->worldTransform.eDx = c31; - d->worldTransform.eDy = c32; + d->dc[d->level].worldTransform.eM11 = c11;; + d->dc[d->level].worldTransform.eM12 = c12;; + d->dc[d->level].worldTransform.eM21 = c21;; + d->dc[d->level].worldTransform.eM22 = c22;; + d->dc[d->level].worldTransform.eDx = c31; + d->dc[d->level].worldTransform.eDy = c32; break; } // case MWT_SET: default: - d->worldTransform = pEmr->xform; + d->dc[d->level].worldTransform = pEmr->xform; break; } break; @@ -1321,7 +1395,7 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb index -= ENHMETA_STOCK_OBJECT; switch (index) { case NULL_BRUSH: - d->fill_set = false; + d->dc[d->level].fill_set = false; break; case BLACK_BRUSH: case DKGRAY_BRUSH: @@ -1347,23 +1421,23 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb val = 255.0 / 255.0; break; } - d->style.fill.value.color.set( val, val, val ); + d->dc[d->level].style.fill.value.color.set( val, val, val ); - d->fill_set = true; + d->dc[d->level].fill_set = true; break; } case NULL_PEN: - d->stroke_set = false; + d->dc[d->level].stroke_set = false; break; case BLACK_PEN: case WHITE_PEN: { float val = index == BLACK_PEN ? 0 : 1; - d->style.stroke_dasharray_set = 0; - d->style.stroke_width.value = 1.0; - d->style.stroke.value.color.set( val, val, val ); + d->dc[d->level].style.stroke_dasharray_set = 0; + d->dc[d->level].style.stroke_width.value = 1.0; + d->dc[d->level].style.stroke.value.color.set( val, val, val ); - d->stroke_set = true; + d->dc[d->level].stroke_set = true; break; } @@ -1547,11 +1621,12 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb dbg_str << "\n"; PEMRSETMITERLIMIT pEmr = (PEMRSETMITERLIMIT) lpEMFR; - d->style.stroke_miterlimit.value = pix_to_size_point( d, pEmr->eMiterLimit ); - - if (d->style.stroke_miterlimit.value < 1) - d->style.stroke_miterlimit.value = 1.0; + float miterlimit = pEmr->eMiterLimit; + miterlimit = miterlimit * 4.0 / 10.0; + d->dc[d->level].style.stroke_miterlimit.value = pix_to_size_point( d, miterlimit ); + if (d->dc[d->level].style.stroke_miterlimit.value < 1) + d->dc[d->level].style.stroke_miterlimit.value = 4.0; break; } case EMR_BEGINPATH: @@ -1678,7 +1753,6 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb (EMREXTCREATEFONTINDIRECTW *) malloc( sizeof(EMREXTCREATEFONTINDIRECTW) ); pFont->elfw = pEmr->elfw; insert_object(d, index, EMR_EXTCREATEFONTINDIRECTW, (ENHMETARECORD *) pFont); - break; } case EMR_EXTTEXTOUTA: @@ -1695,8 +1769,13 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb double x1 = pEmr->emrtext.ptlReference.x; double y1 = pEmr->emrtext.ptlReference.y; - if (!(d->textAlign & TA_BOTTOM)) - y1 += fabs(d->style.font_size.computed); + if (d->dc[d->level].textAlign & TA_UPDATECP) { + x1 = d->dc[d->level].cur.x; + y1 = d->dc[d->level].cur.y; + } + + if (!(d->dc[d->level].textAlign & TA_BOTTOM)) + y1 += fabs(d->dc[d->level].style.font_size.computed); double x = pix_to_x_point(d, x1, y1); double y = pix_to_y_point(d, x1, y1); @@ -1722,10 +1801,10 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb gchar *escaped_text = g_markup_escape_text(ansi_text, -1); float text_rgb[3]; - sp_color_get_rgb_floatv( &(d->style.fill.value.color), text_rgb ); + sp_color_get_rgb_floatv( &(d->dc[d->level].style.fill.value.color), text_rgb ); - if (!d->textColorSet) { - d->textColor = RGB(SP_COLOR_F_TO_U(text_rgb[0]), + if (!d->dc[d->level].textColorSet) { + d->dc[d->level].textColor = RGB(SP_COLOR_F_TO_U(text_rgb[0]), SP_COLOR_F_TO_U(text_rgb[1]), SP_COLOR_F_TO_U(text_rgb[2])); } @@ -1733,15 +1812,15 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb char tmp[128]; snprintf(tmp, 127, "fill:#%02x%02x%02x;", - GetRValue(d->textColor), - GetGValue(d->textColor), - GetBValue(d->textColor)); + GetRValue(d->dc[d->level].textColor), + GetGValue(d->dc[d->level].textColor), + GetBValue(d->dc[d->level].textColor)); - bool i = (d->style.font_style.value == SP_CSS_FONT_STYLE_ITALIC); - //bool o = (d->style.font_style.value == SP_CSS_FONT_STYLE_OBLIQUE); - bool b = (d->style.font_weight.value == SP_CSS_FONT_WEIGHT_BOLD) || - (d->style.font_weight.value >= SP_CSS_FONT_WEIGHT_500 && d->style.font_weight.value <= SP_CSS_FONT_WEIGHT_900); - int lcr = ((d->textAlign & TA_CENTER) == TA_CENTER) ? 2 : ((d->textAlign & TA_RIGHT) == TA_RIGHT) ? 1 : 0; + bool i = (d->dc[d->level].style.font_style.value == SP_CSS_FONT_STYLE_ITALIC); + //bool o = (d->dc[d->level].style.font_style.value == SP_CSS_FONT_STYLE_OBLIQUE); + bool b = (d->dc[d->level].style.font_weight.value == SP_CSS_FONT_WEIGHT_BOLD) || + (d->dc[d->level].style.font_weight.value >= SP_CSS_FONT_WEIGHT_500 && d->dc[d->level].style.font_weight.value <= SP_CSS_FONT_WEIGHT_900); + int lcr = ((d->dc[d->level].textAlign & TA_CENTER) == TA_CENTER) ? 2 : ((d->dc[d->level].textAlign & TA_RIGHT) == TA_RIGHT) ? 1 : 0; assert_empty_path(d, "EMR_EXTTEXTOUTW"); @@ -1750,14 +1829,20 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb ts << " xml:space=\"preserve\"\n"; ts << " x=\"" << x << "\"\n"; ts << " y=\"" << y << "\"\n"; + if (d->dc[d->level].style.text_transform.value) { + ts << " transform=\"" + << "rotate(-" << d->dc[d->level].style.text_transform.value + << " " << x << " " << y << ")" + << "\"\n"; + } ts << " style=\"" - << "font-size:" << fabs(d->style.font_size.computed) << "px;" + << "font-size:" << fabs(d->dc[d->level].style.font_size.computed) << "px;" << tmp << "font-style:" << (i ? "italic" : "normal") << ";" << "font-weight:" << (b ? "bold" : "normal") << ";" << "text-align:" << (lcr==2 ? "center" : lcr==1 ? "end" : "start") << ";" << "text-anchor:" << (lcr==2 ? "middle" : lcr==1 ? "end" : "start") << ";" - << "font-family:" << d->tstyle.font_family.value << ";" + << "font-family:" << d->dc[d->level].tstyle.font_family.value << ";" << "\"\n"; ts << " >"; ts << escaped_text; @@ -2058,7 +2143,7 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } static int CALLBACK -myMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, METARECORD *lpMFR, int nObj, LPARAM lpData) +myMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, METARECORD * /*lpMFR*/, int /*nObj*/, LPARAM /*lpData*/) { g_warning("Unable to import Windows Meta File.\n"); return 0; @@ -2084,18 +2169,18 @@ typedef struct SPDocument * -EmfWin32::open( Inkscape::Extension::Input *mod, const gchar *uri ) +EmfWin32::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) { EMF_CALLBACK_DATA d; memset(&d, 0, sizeof(d)); - d.worldTransform.eM11 = 1.0; - d.worldTransform.eM12 = 0.0; - d.worldTransform.eM21 = 0.0; - d.worldTransform.eM22 = 1.0; - d.worldTransform.eDx = 0.0; - d.worldTransform.eDy = 0.0; + d.dc[0].worldTransform.eM11 = 1.0; + d.dc[0].worldTransform.eM12 = 0.0; + d.dc[0].worldTransform.eM21 = 0.0; + d.dc[0].worldTransform.eM22 = 1.0; + d.dc[0].worldTransform.eDx = 0.0; + d.dc[0].worldTransform.eDy = 0.0; gsize bytesRead = 0; gsize bytesWritten = 0; @@ -2298,8 +2383,8 @@ EmfWin32::open( Inkscape::Extension::Input *mod, const gchar *uri ) delete[] d.emf_obj; } - if (d.style.stroke_dash.dash) - delete[] d.style.stroke_dash.dash; + if (d.dc[0].style.stroke_dash.dash) + delete[] d.dc[0].style.stroke_dash.dash; if (local_fn) g_free(local_fn); diff --git a/src/extension/internal/emf-win32-inout.h b/src/extension/internal/emf-win32-inout.h index 6220c2190..01aa91bdc 100644 --- a/src/extension/internal/emf-win32-inout.h +++ b/src/extension/internal/emf-win32-inout.h @@ -15,7 +15,6 @@ #ifdef WIN32 #include "extension/implementation/implementation.h" -#include "style.h" namespace Inkscape { namespace Extension { diff --git a/src/extension/internal/emf-win32-print.cpp b/src/extension/internal/emf-win32-print.cpp index f9b65875a..e53eda81c 100644 --- a/src/extension/internal/emf-win32-print.cpp +++ b/src/extension/internal/emf-win32-print.cpp @@ -27,56 +27,62 @@ # include "config.h" #endif -#include -#include -#include - -#include "libnr/n-art-bpath.h" -#include "libnr/nr-point-matrix-ops.h" -#include "libnr/nr-rect.h" -#include "libnr/nr-matrix.h" +//#include +//#include +//#include + +//#include "libnr/n-art-bpath.h" +//#include "libnr/nr-point-matrix-ops.h" +//#include "libnr/nr-rect.h" +//#include "libnr/nr-matrix.h" #include "libnr/nr-matrix-ops.h" -#include "libnr/nr-matrix-scale-ops.h" -#include "libnr/nr-matrix-translate-ops.h" +//#include "libnr/nr-matrix-scale-ops.h" +//#include "libnr/nr-matrix-translate-ops.h" #include "libnr/nr-scale-translate-ops.h" -#include "libnr/nr-translate-scale-ops.h" -#include "libnr/nr-matrix-fns.h" -#include "libnr/nr-pixblock.h" -#include -#include "display/canvas-bpath.h" +//#include "libnr/nr-translate-scale-ops.h" +//#include "libnr/nr-matrix-fns.h" +//#include "libnr/nr-pixblock.h" +#include "libnr/n-art-bpath-2geom.h" +#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 "display/canvas-bpath.h" #include "sp-item.h" -#include "glib.h" -#include "gtk/gtkdialog.h" -#include "gtk/gtkbox.h" -#include "gtk/gtkstock.h" +//#include "glib.h" +//#include "gtk/gtkdialog.h" +//#include "gtk/gtkbox.h" +//#include "gtk/gtkstock.h" -#include "glibmm/i18n.h" -#include "enums.h" -#include "document.h" +//#include "glibmm/i18n.h" +//#include "enums.h" +//#include "document.h" #include "style.h" -#include "sp-paint-server.h" +//#include "sp-paint-server.h" #include "inkscape_version.h" -#include "libnrtype/FontFactory.h" -#include "libnrtype/font-instance.h" -#include "libnrtype/font-style-to-pos.h" +//#include "libnrtype/FontFactory.h" +//#include "libnrtype/font-instance.h" +//#include "libnrtype/font-style-to-pos.h" + +#define WIN32_LEAN_AND_MEAN +#include #include "win32.h" #include "emf-win32-print.h" #include "unit-constants.h" -#include "extension/extension.h" +//#include "extension/extension.h" #include "extension/system.h" #include "extension/print.h" -#include "io/sys.h" +//#include "io/sys.h" -#include "macros.h" - -#define WIN32_LEAN_AND_MEAN -#include +//#include "macros.h" namespace Inkscape { namespace Extension { @@ -90,7 +96,6 @@ PrintEmfWin32::PrintEmfWin32 (void): hbrush(NULL), hbrushOld(NULL), hpen(NULL), - fill_path(NULL), stroke_and_fill(false), fill_only(false), simple_shape(false) @@ -117,7 +122,7 @@ PrintEmfWin32::~PrintEmfWin32 (void) unsigned int -PrintEmfWin32::setup (Inkscape::Extension::Print *mod) +PrintEmfWin32::setup (Inkscape::Extension::Print * /*mod*/) { return TRUE; } @@ -247,7 +252,7 @@ PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc) unsigned int -PrintEmfWin32::finish (Inkscape::Extension::Print *mod) +PrintEmfWin32::finish (Inkscape::Extension::Print * /*mod*/) { if (!hdc) return 0; @@ -266,8 +271,8 @@ PrintEmfWin32::finish (Inkscape::Extension::Print *mod) unsigned int -PrintEmfWin32::comment (Inkscape::Extension::Print * module, - const char *comment) +PrintEmfWin32::comment (Inkscape::Extension::Print * /*module*/, + const char * /*comment*/) { if (!hdc) return 0; @@ -316,14 +321,15 @@ PrintEmfWin32::destroy_brush() void -PrintEmfWin32::create_pen(SPStyle const *style, const Geom::Matrix *transform) +PrintEmfWin32::create_pen(SPStyle const *style, const Geom::Matrix &transform) { if (style) { float rgb[3]; sp_color_get_rgb_floatv(&style->stroke.value.color, rgb); - LOGBRUSH lb = {0}; + LOGBRUSH lb; + ZeroMemory(&lb, sizeof(lb)); lb.lbStyle = BS_SOLID; lb.lbColor = RGB( 255*rgb[0], 255*rgb[1], 255*rgb[2] ); @@ -332,17 +338,14 @@ PrintEmfWin32::create_pen(SPStyle const *style, const Geom::Matrix *transform) int linejoin = 0; DWORD n_dash = 0; DWORD *dash = NULL; - float oldmiterlimit; using Geom::X; using Geom::Y; - Geom::Matrix tf = *transform; - Geom::Point zero(0, 0); Geom::Point one(1, 1); - Geom::Point p0(zero * tf); - Geom::Point p1(one * tf); + 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); @@ -415,12 +418,18 @@ PrintEmfWin32::create_pen(SPStyle const *style, const Geom::Matrix *transform) hpenOld = (HPEN) SelectObject( hdc, hpen ); if (linejoin == PS_JOIN_MITER) { + float oldmiterlimit; float miterlimit = style->stroke_miterlimit.value; + + miterlimit = miterlimit * 10.0 / 4.0; if (miterlimit < 1) - miterlimit = 4.0; + miterlimit = 10.0; + + miterlimit = miterlimit * IN_PER_PX * dwDPI; + SetMiterLimit( hdc, - miterlimit * IN_PER_PX * dwDPI, + miterlimit, &oldmiterlimit ); } @@ -448,71 +457,20 @@ PrintEmfWin32::destroy_pen() void PrintEmfWin32::flush_fill() { - if (fill_path) { + if (!fill_pathv.empty()) { stroke_and_fill = false; fill_only = true; - print_bpath(fill_path, fill_transform); + print_pathv(fill_pathv, fill_transform); fill_only = false; if (!simple_shape) FillPath( hdc ); destroy_brush(); - delete[] fill_path; - fill_path = NULL; - } -} - - -NArtBpath * -PrintEmfWin32::copy_bpath(const NArtBpath *bp) -{ - NArtBpath *tmp = (NArtBpath *) bp; - int num = 1; - - while (tmp->code != NR_END) { - num++; - tmp += 1; + fill_pathv.clear(); } - - tmp = new NArtBpath[num]; - while (num--) { - tmp[num] = bp[num]; - } - - return tmp; -} - - -int -PrintEmfWin32::cmp_bpath(const NArtBpath *bp1, const NArtBpath *bp2) -{ - if (!bp1 || !bp2) { - return 1; - } - - while (bp1->code != NR_END && bp2->code != NR_END) { - if (bp1->code != bp2->code) { - return 1; - } - - if ( fabs(bp1->x1 - bp2->x1) > 0.00000001 || - fabs(bp1->y1 - bp2->y1) > 0.00000001 || - fabs(bp1->x2 - bp2->x2) > 0.00000001 || - fabs(bp1->y2 - bp2->y2) > 0.00000001 || - fabs(bp1->x3 - bp2->x3) > 0.00000001 || - fabs(bp1->y3 - bp2->y3) > 0.00000001 ) - { - return 1; - } - - bp1 += 1; - bp2 += 1; - } - - return bp1->code != NR_END || bp2->code != NR_END; } unsigned int -PrintEmfWin32::bind(Inkscape::Extension::Print *mod, Geom::Matrix const *transform, float opacity) +PrintEmfWin32::bind(Inkscape::Extension::Print * /*mod*/, Geom::Matrix const *transform, float /*opacity*/) { Geom::Matrix tr = *transform; @@ -527,16 +485,16 @@ PrintEmfWin32::bind(Inkscape::Extension::Print *mod, Geom::Matrix const *transfo } unsigned int -PrintEmfWin32::release(Inkscape::Extension::Print *mod) +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::Matrix const *transform, SPStyle const *style, - NRRect const *pbox, NRRect const *dbox, NRRect const *bbox) +PrintEmfWin32::fill(Inkscape::Extension::Print * /*mod*/, + Geom::PathVector const &pathv, Geom::Matrix const * /*transform*/, SPStyle const *style, + NRRect const * /*pbox*/, NRRect const * /*dbox*/, NRRect const * /*bbox*/) { if (!hdc) return 0; @@ -552,9 +510,8 @@ PrintEmfWin32::fill(Inkscape::Extension::Print *mod, return 0; } - NArtBpath * bpath = BPath_from_2GeomPath(pathv); - fill_path = copy_bpath( bpath ); - g_free(bpath); + 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 @@ -564,43 +521,39 @@ PrintEmfWin32::fill(Inkscape::Extension::Print *mod, unsigned int -PrintEmfWin32::stroke (Inkscape::Extension::Print *mod, - Geom::PathVector const &pathv, const Geom::Matrix *transform, const SPStyle *style, - const NRRect *pbox, const NRRect *dbox, const NRRect *bbox) +PrintEmfWin32::stroke (Inkscape::Extension::Print * /*mod*/, + Geom::PathVector const &pathv, const Geom::Matrix * /*transform*/, const SPStyle *style, + const NRRect * /*pbox*/, const NRRect * /*dbox*/, const NRRect * /*bbox*/) { if (!hdc) return 0; Geom::Matrix tf = m_tr_stack.top(); - NArtBpath * bpath = BPath_from_2GeomPath(pathv); - - stroke_and_fill = ( cmp_bpath( bpath, fill_path ) == 0 ); + stroke_and_fill = ( pathv == fill_pathv ); if (!stroke_and_fill) { flush_fill(); // flush any pending fills } if (style->stroke.isColor()) { - create_pen(style, &tf); + create_pen(style, tf); } else { - // create_pen(NULL, &tf); + // create_pen(NULL, tf); return 0; } - print_bpath(bpath, tf); + print_pathv(pathv, tf); if (stroke_and_fill) { if (!simple_shape) StrokeAndFillPath( hdc ); destroy_brush(); - delete[] fill_path; - fill_path = NULL; + fill_pathv.clear(); } else { if (!simple_shape) StrokePath( hdc ); } - g_free(bpath); destroy_pen(); return 0; @@ -608,31 +561,32 @@ PrintEmfWin32::stroke (Inkscape::Extension::Print *mod, bool -PrintEmfWin32::print_simple_shape(const NArtBpath *bpath, const Geom::Matrix &transform) +PrintEmfWin32::print_simple_shape(Geom::PathVector const &pathv, const Geom::Matrix &transform) { - NR::Matrix tf = transform; - const NArtBpath *bp = bpath; + Geom::PathVector pv = pathv_to_linear_and_cubic_beziers( pathv * transform ); int nodes = 0; int moves = 0; int lines = 0; int curves = 0; - while (bp->code != NR_END) { + for (Geom::PathVector::const_iterator pit = pv.begin(); pit != pv.end(); ++pit) + { + moves++; nodes++; - switch (bp->code) { - case NR_MOVETO: - case NR_MOVETO_OPEN: - moves++; - break; - case NR_LINETO: + + for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit) + { + nodes++; + + if ( is_straight_curve(*cit) ) { lines++; - break; - case NR_CURVETO: + } + else if (Geom::CubicBezier const *cubic = dynamic_cast(&*cit)) { + cubic = cubic; curves++; - break; + } } - bp += 1; } if (!nodes) @@ -640,39 +594,85 @@ PrintEmfWin32::print_simple_shape(const NArtBpath *bpath, const Geom::Matrix &tr POINT *lpPoints = new POINT[moves + lines + curves*3]; int i = 0; - bp = bpath; - while (bp->code != NR_END) + + /** + * For all Subpaths in the + */ + for (Geom::PathVector::const_iterator pit = pv.begin(); pit != pv.end(); ++pit) { using Geom::X; using Geom::Y; - Geom::Point p1(bp->c(1) * tf); - Geom::Point p2(bp->c(2) * tf); - Geom::Point p3(bp->c(3) * tf); - - p1[X] = (p1[X] * IN_PER_PX * dwDPI); - p2[X] = (p2[X] * IN_PER_PX * dwDPI); - p3[X] = (p3[X] * 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 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]); - - switch (bp->code) { - case NR_MOVETO: - case NR_MOVETO_OPEN: - case NR_LINETO: - lpPoints[i].x = x3; - lpPoints[i].y = y3; + 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; - break; - case NR_CURVETO: + } + else if (Geom::CubicBezier const *cubic = dynamic_cast(&*cit)) + { + std::vector 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; @@ -680,10 +680,8 @@ PrintEmfWin32::print_simple_shape(const NArtBpath *bpath, const Geom::Matrix &tr lpPoints[i+2].x = x3; lpPoints[i+2].y = y3; i = i + 3; - break; + } } - - bp += 1; } bool done = false; @@ -766,60 +764,83 @@ PrintEmfWin32::print_simple_shape(const NArtBpath *bpath, const Geom::Matrix &tr } unsigned int -PrintEmfWin32::print_bpath(NArtBpath const *bp, Geom::Matrix const &transform) +PrintEmfWin32::print_pathv(Geom::PathVector const &pathv, const Geom::Matrix &transform) { - unsigned int closed; - NR::Matrix tf = transform; - - simple_shape = print_simple_shape(bp, 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 ); - closed = FALSE; - while (bp->code != NR_END) { + + /** + * For all Subpaths in the + */ + for (Geom::PathVector::const_iterator pit = pv.begin(); pit != pv.end(); ++pit) + { using Geom::X; using Geom::Y; - Geom::Point p1(bp->c(1) * tf); - Geom::Point p2(bp->c(2) * tf); - Geom::Point p3(bp->c(3) * tf); - - p1[X] = (p1[X] * IN_PER_PX * dwDPI); - p2[X] = (p2[X] * IN_PER_PX * dwDPI); - p3[X] = (p3[X] * 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 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]); - - switch (bp->code) { - case NR_MOVETO: - if (closed) { - CloseFigure( hdc ); - } - closed = TRUE; - MoveToEx( hdc, x3, y3, NULL ); - break; - case NR_MOVETO_OPEN: - if (closed) { - CloseFigure( hdc ); - } - closed = FALSE; - MoveToEx( hdc, x3, y3, NULL ); - break; - case NR_LINETO: - LineTo( hdc, x3, y3 ); - break; - case NR_CURVETO: + 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(&*cit)) + { + std::vector 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; @@ -829,19 +850,21 @@ PrintEmfWin32::print_bpath(NArtBpath const *bp, Geom::Matrix const &transform) pt[2].y = y3; PolyBezierTo( hdc, pt, 3 ); - break; } - default: - break; + else + { + g_warning("logical error, because pathv_to_linear_and_cubic_beziers was used"); + } + } + + if (pit->end_default() == pit->end_closed()) { + CloseFigure( hdc ); } - bp += 1; - } - if (closed) { - CloseFigure( hdc ); } + EndPath( hdc ); - return closed; + return TRUE; } @@ -852,8 +875,8 @@ PrintEmfWin32::textToPath(Inkscape::Extension::Print * ext) } unsigned int -PrintEmfWin32::text(Inkscape::Extension::Print *mod, char const *text, Geom::Point p, - SPStyle const *const style) +PrintEmfWin32::text(Inkscape::Extension::Print * /*mod*/, char const *text, Geom::Point p, + SPStyle const *const style) { if (!hdc) return 0; diff --git a/src/extension/internal/emf-win32-print.h b/src/extension/internal/emf-win32-print.h index c4a7f4990..374aaef45 100644 --- a/src/extension/internal/emf-win32-print.h +++ b/src/extension/internal/emf-win32-print.h @@ -19,16 +19,12 @@ #endif #include "extension/implementation/implementation.h" -#include "extension/extension.h" +//#include "extension/extension.h" -#include "svg/stringstream.h" -#include "libnr/nr-matrix.h" -#include "libnr/nr-rect.h" +//#include "libnr/nr-matrix.h" +//#include "libnr/nr-rect.h" #include <2geom/pathvector.h> -#define WIN32_LEAN_AND_MEAN -#include - #include namespace Inkscape { @@ -46,15 +42,14 @@ class PrintEmfWin32 : public Inkscape::Extension::Implementation::Implementation HPEN hpen, hpenOld; std::stack m_tr_stack; - NArtBpath *fill_path; + Geom::PathVector fill_pathv; Geom::Matrix fill_transform; -// Geom::Matrix text_transform; bool stroke_and_fill; bool fill_only; bool simple_shape; - unsigned int print_bpath (const NArtBpath *bp, const Geom::Matrix &transform); - bool print_simple_shape (const NArtBpath *bp, const Geom::Matrix &transform); + unsigned int print_pathv (Geom::PathVector const &pathv, const Geom::Matrix &transform); + bool print_simple_shape (Geom::PathVector const &pathv, const Geom::Matrix &transform); public: PrintEmfWin32 (void); @@ -87,15 +82,12 @@ protected: void destroy_brush(); - void create_pen(SPStyle const *style, const Geom::Matrix *transform); + void create_pen(SPStyle const *style, const Geom::Matrix &transform); void destroy_pen(); void flush_fill(); - NArtBpath *copy_bpath(const NArtBpath *bp); - int cmp_bpath(const NArtBpath *bp1, const NArtBpath *bp2); - }; } /* namespace Internal */ -- 2.30.2