73
76
#define PS_JOIN_MASK (PS_JOIN_BEVEL|PS_JOIN_MITER|PS_JOIN_ROUND)
79
#define DPA 0x00A000C9 // TernaryRasterOperation
77
81
namespace Inkscape {
78
82
namespace Extension {
79
83
namespace Internal {
85
static float device_scale = DEVICESCALE;
87
static bool clipset = false;
82
89
EmfWin32::EmfWin32 (void) // The null constructor
235
243
float stroke_rgb[3];
236
244
sp_color_get_rgb_floatv(&(d->dc[d->level].style.stroke.value.color), stroke_rgb);
238
tmp_id << "\n\tid=\"" << (d->id++) << "\"";
239
*(d->outsvg) += tmp_id.str().c_str();
246
// tmp_id << "\n\tid=\"" << (d->id++) << "\"";
247
// *(d->outsvg) += tmp_id.str().c_str();
240
248
*(d->outsvg) += "\n\tstyle=\"";
241
249
if (iType == EMR_STROKEPATH || !d->dc[d->level].fill_set) {
242
250
tmp_style << "fill:none;";
338
349
double ppy = _pix_y_to_point(d, py);
340
351
double x = ppx * d->dc[d->level].worldTransform.eM11 + ppy * d->dc[d->level].worldTransform.eM21 + d->dc[d->level].worldTransform.eDx;
341
x *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : DEVICESCALE;
352
x *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : device_scale;
350
361
double ppy = _pix_y_to_point(d, py);
352
363
double y = ppx * d->dc[d->level].worldTransform.eM12 + ppy * d->dc[d->level].worldTransform.eM22 + d->dc[d->level].worldTransform.eDy;
353
y *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : DEVICESCALE;
364
y *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : device_scale;
364
375
double dx = ppx * d->dc[d->level].worldTransform.eM11 + ppy * d->dc[d->level].worldTransform.eM21;
365
dx *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : DEVICESCALE;
376
dx *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : device_scale;
366
377
double dy = ppx * d->dc[d->level].worldTransform.eM12 + ppy * d->dc[d->level].worldTransform.eM22;
367
dy *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : DEVICESCALE;
378
dy *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : device_scale;
369
380
double tmp = sqrt(dx * dx + dy * dy);
684
695
g_free(d->dc[d->level].tstyle.font_family.value);
685
696
d->dc[d->level].tstyle.font_family.value =
686
697
(gchar *) g_utf16_to_utf8( (gunichar2*) pEmr->elfw.elfLogFont.lfFaceName, -1, NULL, NULL, NULL );
687
d->dc[d->level].style.text_transform.value = ((pEmr->elfw.elfLogFont.lfEscapement + 3600) % 3600) / 10;
698
d->dc[d->level].style.baseline_shift.value = ((pEmr->elfw.elfLogFont.lfEscapement + 3600) % 3600) / 10; // use baseline_shift instead of text_transform to avoid overflow
767
778
dbg_str << "<!-- EMR_HEADER -->\n";
769
*(d->outsvg) += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
780
*(d->outdef) += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
772
*(d->outsvg) += "<!-- ";
773
*(d->outsvg) += d->pDesc;
774
*(d->outsvg) += " -->\n";
783
*(d->outdef) += "<!-- ";
784
*(d->outdef) += d->pDesc;
785
*(d->outdef) += " -->\n";
777
788
ENHMETAHEADER *pEmr = (ENHMETAHEADER *) lpEMFR;
778
tmp_outsvg << "<svg\n";
779
tmp_outsvg << " xmlns:svg=\"http://www.w3.org/2000/svg\"\n";
780
tmp_outsvg << " xmlns=\"http://www.w3.org/2000/svg\"\n";
781
tmp_outsvg << " version=\"1.0\"\n";
789
SVGOStringStream tmp_outdef;
790
tmp_outdef << "<svg\n";
791
tmp_outdef << " xmlns:svg=\"http://www.w3.org/2000/svg\"\n";
792
tmp_outdef << " xmlns=\"http://www.w3.org/2000/svg\"\n";
793
tmp_outdef << " version=\"1.0\"\n";
786
d->dc[d->level].PixelsInX = pEmr->rclFrame.right - pEmr->rclFrame.left;
787
d->dc[d->level].PixelsInY = pEmr->rclFrame.bottom - pEmr->rclFrame.top;
798
d->dc[d->level].PixelsInX = pEmr->rclFrame.right; // - pEmr->rclFrame.left;
799
d->dc[d->level].PixelsInY = pEmr->rclFrame.bottom; // - pEmr->rclFrame.top;
789
801
d->MMX = d->dc[d->level].PixelsInX / 100.0;
790
802
d->MMY = d->dc[d->level].PixelsInY / 100.0;
792
804
d->dc[d->level].PixelsOutX = d->MMX * PX_PER_MM;
793
805
d->dc[d->level].PixelsOutY = d->MMY * PX_PER_MM;
807
// calculate ratio of Inkscape dpi/device dpi
808
if (pEmr->szlMillimeters.cx && pEmr->szlDevice.cx)
809
device_scale = PX_PER_MM*pEmr->szlMillimeters.cx/pEmr->szlDevice.cx;
796
812
" width=\"" << d->MMX << "mm\"\n" <<
797
" height=\"" << d->MMY << "mm\"\n";
799
" id=\"" << (d->id++) << "\">\n";
813
" height=\"" << d->MMY << "mm\">\n";
814
*(d->outdef) += tmp_outdef.str().c_str();
815
*(d->outdef) += "<defs>"; // temporary end of header
803
" id=\"" << (d->id++) << "\">\n";
817
tmp_outsvg << "\n</defs>\n<g>\n"; // start of main body
805
819
if (pEmr->nHandles) {
806
820
d->n_obj = pEmr->nHandles;
1069
1083
d->dc[d->level].ScaleOutY = (double) d->dc[d->level].PixelsOutY / (double) d->dc[d->level].sizeView.cy;
1072
d->dc[d->level].ScaleOutX = DEVICESCALE;
1073
d->dc[d->level].ScaleOutY = DEVICESCALE;
1086
d->dc[d->level].ScaleOutX = device_scale;
1087
d->dc[d->level].ScaleOutY = device_scale;
1120
1134
d->dc[d->level].ScaleOutY = (double) d->dc[d->level].PixelsOutY / (double) d->dc[d->level].sizeView.cy;
1123
d->dc[d->level].ScaleOutX = DEVICESCALE;
1124
d->dc[d->level].ScaleOutY = DEVICESCALE;
1137
d->dc[d->level].ScaleOutX = device_scale;
1138
d->dc[d->level].ScaleOutY = device_scale;
1226
1241
dbg_str << "<!-- EMR_EXCLUDECLIPRECT -->\n";
1228
1243
case EMR_INTERSECTCLIPRECT:
1229
1245
dbg_str << "<!-- EMR_INTERSECTCLIPRECT -->\n";
1247
PEMRINTERSECTCLIPRECT pEmr = (PEMRINTERSECTCLIPRECT) lpEMFR;
1248
RECTL rc = pEmr->rclClip;
1250
if ((rc.left == rc_old.left) && (rc.top == rc_old.top) && (rc.right == rc_old.right) && (rc.bottom == rc_old.bottom))
1254
double l = pix_to_x_point( d, rc.left, rc.top );
1255
double t = pix_to_y_point( d, rc.left, rc.top );
1256
double r = pix_to_x_point( d, rc.right, rc.bottom );
1257
double b = pix_to_y_point( d, rc.right, rc.bottom );
1259
SVGOStringStream tmp_rectangle;
1260
tmp_rectangle << "\n<clipPath\n\tclipPathUnits=\"userSpaceOnUse\" ";
1261
tmp_rectangle << "\n\tid=\"clipEmfPath" << ++(d->id) << "\" >";
1262
tmp_rectangle << "\n<rect ";
1263
tmp_rectangle << "\n\tx=\"" << l << "\" ";
1264
tmp_rectangle << "\n\ty=\"" << t << "\" ";
1265
tmp_rectangle << "\n\twidth=\"" << r-l << "\" ";
1266
tmp_rectangle << "\n\theight=\"" << b-t << "\" />";
1267
tmp_rectangle << "\n</clipPath>";
1269
assert_empty_path(d, "EMR_RECTANGLE");
1271
*(d->outdef) += tmp_rectangle.str().c_str();
1231
1275
case EMR_SCALEVIEWPORTEXTEX:
1232
1276
dbg_str << "<!-- EMR_SCALEVIEWPORTEXTEX -->\n";
1558
1602
case EMR_ROUNDRECT:
1559
1604
dbg_str << "<!-- EMR_ROUNDRECT -->\n";
1606
PEMRROUNDRECT pEmr = (PEMRROUNDRECT) lpEMFR;
1607
RECTL rc = pEmr->rclBox;
1608
SIZEL corner = pEmr->szlCorner;
1609
double f = 4.*(sqrt(2) - 1)/3;
1611
double l = pix_to_x_point(d, rc.left, rc.top);
1612
double t = pix_to_y_point(d, rc.left, rc.top);
1613
double r = pix_to_x_point(d, rc.right, rc.bottom);
1614
double b = pix_to_y_point(d, rc.right, rc.bottom);
1615
double cnx = pix_to_size_point(d, corner.cx/2);
1616
double cny = pix_to_size_point(d, corner.cy/2);
1618
SVGOStringStream tmp_rectangle;
1619
tmp_rectangle << "d=\"";
1620
tmp_rectangle << "\n\tM " << l << ", " << t + cny << " ";
1621
tmp_rectangle << "\n\tC " << l << ", " << t + (1-f)*cny << " " << l + (1-f)*cnx << ", " << t << " " << l + cnx << ", " << t << " ";
1622
tmp_rectangle << "\n\tL " << r - cnx << ", " << t << " ";
1623
tmp_rectangle << "\n\tC " << r - (1-f)*cnx << ", " << t << " " << r << ", " << t + (1-f)*cny << " " << r << ", " << t + cny << " ";
1624
tmp_rectangle << "\n\tL " << r << ", " << b - cny << " ";
1625
tmp_rectangle << "\n\tC " << r << ", " << b - (1-f)*cny << " " << r - (1-f)*cnx << ", " << b << " " << r - cnx << ", " << b << " ";
1626
tmp_rectangle << "\n\tL " << l + cnx << ", " << b << " ";
1627
tmp_rectangle << "\n\tC " << l + (1-f)*cnx << ", " << b << " " << l << ", " << b - (1-f)*cny << " " << l << ", " << b - cny << " ";
1628
tmp_rectangle << "\n\tz";
1629
assert_empty_path(d, "EMR_ROUNDRECT");
1631
*(d->outsvg) += " <path ";
1632
output_style(d, lpEMFR->iType);
1633
*(d->outsvg) += "\n\t";
1634
*(d->outsvg) += tmp_rectangle.str().c_str();
1635
*(d->outsvg) += " \" /> \n";
1562
1640
dbg_str << "<!-- EMR_ARC -->\n";
1720
1798
dbg_str << "<!-- EMR_EXTSELECTCLIPRGN -->\n";
1722
1800
case EMR_BITBLT:
1723
1802
dbg_str << "<!-- EMR_BITBLT -->\n";
1804
PEMRBITBLT pEmr = (PEMRBITBLT) lpEMFR;
1805
if (pEmr->dwRop == DPA) {
1806
// should be an application of a DIBPATTERNBRUSHPT, use a solid color instead
1807
double l = pix_to_x_point( d, pEmr->xDest, pEmr->yDest);
1808
double t = pix_to_y_point( d, pEmr->xDest, pEmr->yDest);
1809
double r = pix_to_x_point( d, pEmr->xDest + pEmr->cxDest, pEmr->yDest + pEmr->cyDest);
1810
double b = pix_to_y_point( d, pEmr->xDest + pEmr->cxDest, pEmr->yDest + pEmr->cyDest);
1812
SVGOStringStream tmp_rectangle;
1813
tmp_rectangle << "d=\"";
1814
tmp_rectangle << "\n\tM " << l << " " << t << " ";
1815
tmp_rectangle << "\n\tL " << r << " " << t << " ";
1816
tmp_rectangle << "\n\tL " << r << " " << b << " ";
1817
tmp_rectangle << "\n\tL " << l << " " << b << " ";
1818
tmp_rectangle << "\n\tz";
1820
assert_empty_path(d, "EMR_BITBLT");
1822
*(d->outsvg) += " <path ";
1823
output_style(d, lpEMFR->iType);
1824
*(d->outsvg) += "\n\t";
1825
*(d->outsvg) += tmp_rectangle.str().c_str();
1826
*(d->outsvg) += " \" /> \n";
1725
1831
case EMR_STRETCHBLT:
1726
1832
dbg_str << "<!-- EMR_STRETCHBLT -->\n";
1772
1878
if (!(d->dc[d->level].textAlign & TA_BOTTOM))
1773
y1 += fabs(d->dc[d->level].style.font_size.computed);
1879
if (d->dc[d->level].style.baseline_shift.value) {
1880
x1 += std::sin(d->dc[d->level].style.baseline_shift.value*M_PI/180.0)*fabs(d->dc[d->level].style.font_size.computed);
1881
y1 += std::cos(d->dc[d->level].style.baseline_shift.value*M_PI/180.0)*fabs(d->dc[d->level].style.font_size.computed);
1884
y1 += fabs(d->dc[d->level].style.font_size.computed);
1775
1886
double x = pix_to_x_point(d, x1, y1);
1776
1887
double y = pix_to_y_point(d, x1, y1);
1781
1892
(gchar *) g_utf16_to_utf8( (gunichar2 *) wide_text, pEmr->emrtext.nChars, NULL, NULL, NULL );
1783
1894
if (ansi_text) {
1784
gchar *p = ansi_text;
1786
if (*p < 32 || *p >= 127) {
1788
ansi_text = g_strdup("");
1895
// gchar *p = ansi_text;
1897
// if (*p < 32 || *p >= 127) {
1898
// g_free(ansi_text);
1899
// ansi_text = g_strdup("");
1794
1905
SVGOStringStream ts;
1796
1907
gchar *escaped_text = g_markup_escape_text(ansi_text, -1);
1799
sp_color_get_rgb_floatv( &(d->dc[d->level].style.fill.value.color), text_rgb );
1909
// float text_rgb[3];
1910
// sp_color_get_rgb_floatv( &(d->dc[d->level].style.fill.value.color), text_rgb );
1801
if (!d->dc[d->level].textColorSet) {
1802
d->dc[d->level].textColor = RGB(SP_COLOR_F_TO_U(text_rgb[0]),
1803
SP_COLOR_F_TO_U(text_rgb[1]),
1804
SP_COLOR_F_TO_U(text_rgb[2]));
1912
// if (!d->dc[d->level].textColorSet) {
1913
// d->dc[d->level].textColor = RGB(SP_COLOR_F_TO_U(text_rgb[0]),
1914
// SP_COLOR_F_TO_U(text_rgb[1]),
1915
// SP_COLOR_F_TO_U(text_rgb[2]));
1808
1919
snprintf(tmp, 127,
1820
1931
assert_empty_path(d, "EMR_EXTTEXTOUTW");
1822
1933
ts << " <text\n";
1823
ts << " id=\"" << (d->id++) << "\"\n";
1934
// ts << " id=\"" << (d->id++) << "\"\n";
1824
1935
ts << " xml:space=\"preserve\"\n";
1825
1936
ts << " x=\"" << x << "\"\n";
1826
1937
ts << " y=\"" << y << "\"\n";
1827
if (d->dc[d->level].style.text_transform.value) {
1938
if (d->dc[d->level].style.baseline_shift.value) {
1828
1939
ts << " transform=\""
1829
<< "rotate(-" << d->dc[d->level].style.text_transform.value
1940
<< "rotate(-" << d->dc[d->level].style.baseline_shift.value
1830
1941
<< " " << x << " " << y << ")"
2073
2184
dbg_str << "<!-- EMR_CREATEMONOBRUSH -->\n";
2075
2186
case EMR_CREATEDIBPATTERNBRUSHPT:
2076
2188
dbg_str << "<!-- EMR_CREATEDIBPATTERNBRUSHPT -->\n";
2190
PEMRCREATEDIBPATTERNBRUSHPT pEmr = (PEMRCREATEDIBPATTERNBRUSHPT) lpEMFR;
2191
int index = pEmr->ihBrush;
2193
EMRCREATEDIBPATTERNBRUSHPT *pBrush =
2194
(EMRCREATEDIBPATTERNBRUSHPT *) malloc( sizeof(EMRCREATEDIBPATTERNBRUSHPT) );
2195
insert_object(d, index, EMR_CREATEDIBPATTERNBRUSHPT, (ENHMETARECORD *) pBrush);
2078
2198
case EMR_EXTCREATEPEN:
2080
2200
dbg_str << "<!-- EMR_EXTCREATEPEN -->\n";
2190
2310
d.outsvg = new Glib::ustring("");
2191
2311
d.path = new Glib::ustring("");
2312
d.outdef = new Glib::ustring("");
2193
2314
CHAR *ansi_uri = (CHAR *) local_fn;
2194
2315
gunichar2 *unicode_fn = g_utf8_to_utf16( local_fn, -1, NULL, NULL, NULL );
2353
2476
d.pDesc[lstrlen(d.pDesc)] = '#';
2356
EnumEnhMetaFile(NULL, hemf, myEnhMetaFileProc, (LPVOID) &d, NULL);
2479
// This ugly reinterpret_cast is to prevent old versions of gcc from whining about a mismatch in the const-ness of the arguments
2480
EnumEnhMetaFile(NULL, hemf, reinterpret_cast<ENHMFENUMPROC>(myEnhMetaFileProc), (LPVOID) &d, NULL);
2357
2481
DeleteEnhMetaFile(hemf);