2
* Enhanced Metafile Printing.
6
* Ulf Erikson <ulferikson@users.sf.net>
8
* Copyright (C) 2006 Authors
10
* Released under GNU GPL, read the file 'COPYING' for more information
14
* - How to Create & Play Enhanced Metafiles in Win32
15
* http://support.microsoft.com/kb/q145999/
16
* - INFO: Windows Metafile Functions & Aldus Placeable Metafiles
17
* http://support.microsoft.com/kb/q66949/
18
* - Metafile Functions
19
* http://msdn.microsoft.com/library/en-us/gdi/metafile_0whf.asp
20
* - Metafile Structures
21
* http://msdn.microsoft.com/library/en-us/gdi/metafile_5hkj.asp
34
#include "libnr/n-art-bpath.h"
35
#include "libnr/nr-point-matrix-ops.h"
36
#include "libnr/nr-rect.h"
37
#include "libnr/nr-matrix.h"
38
#include "libnr/nr-matrix-fns.h"
39
#include "libnr/nr-path.h"
40
#include "libnr/nr-pixblock.h"
41
#include "display/canvas-bpath.h"
45
#include "gtk/gtkdialog.h"
46
#include "gtk/gtkbox.h"
47
#include "gtk/gtkstock.h"
49
#include "glibmm/i18n.h"
53
#include "sp-paint-server.h"
54
#include "inkscape_version.h"
57
#include "emf-win32-print.h"
59
#include "unit-constants.h"
61
#include "extension/extension.h"
62
#include "extension/system.h"
63
#include "extension/print.h"
69
#define WIN32_LEAN_AND_MEAN
76
static float dwDPI = 2540;
79
PrintEmfWin32::PrintEmfWin32 (void):
88
PrintEmfWin32::~PrintEmfWin32 (void)
91
HENHMETAFILE metafile = CloseEnhMetaFile( hdc );
93
DeleteEnhMetaFile( metafile );
98
/* restore default signal handling for SIGPIPE */
99
#if !defined(_WIN32) && !defined(__WIN32__)
100
(void) signal(SIGPIPE, SIG_DFL);
107
PrintEmfWin32::setup (Inkscape::Extension::Print *mod)
114
PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc)
116
gchar const *utf8_fn = mod->get_param_string("destination");
119
gsize bytesWritten = 0;
120
GError* error = NULL;
122
g_filename_from_utf8( utf8_fn, -1, &bytesRead, &bytesWritten, &error );
124
if (local_fn == NULL) {
128
CHAR *ansi_uri = (CHAR *) local_fn;
129
gunichar2 *unicode_fn = g_utf8_to_utf16( local_fn, -1, NULL, NULL, NULL );
130
WCHAR *unicode_uri = (WCHAR *) unicode_fn;
132
// width and height in px
133
_width = sp_document_width(doc);
134
_height = sp_document_height(doc);
137
bool pageBoundingBox;
138
pageBoundingBox = mod->get_param_bool("pageBoundingBox");
139
if (pageBoundingBox) {
144
SPItem* doc_item = SP_ITEM(sp_document_root(doc));
145
sp_item_invoke_bbox(doc_item, &d, sp_item_i2r_affine(doc_item), TRUE);
153
float dwInchesX = (d.x1 - d.x0);
154
float dwInchesY = (d.y1 - d.y0);
156
// dwInchesX x dwInchesY in .01mm units
157
SetRect( &rc, 0, 0, (int) ceil(dwInchesX*2540), (int) ceil(dwInchesY*2540) );
159
// Get a Reference DC
160
HDC hScreenDC = GetDC( NULL );
162
// Get the physical characteristics of the reference DC
163
float PixelsX = (float) GetDeviceCaps( hScreenDC, HORZRES );
164
float PixelsY = (float) GetDeviceCaps( hScreenDC, VERTRES );
165
float MMX = (float) GetDeviceCaps( hScreenDC, HORZSIZE );
166
float MMY = (float) GetDeviceCaps( hScreenDC, VERTSIZE );
168
// Create the Metafile
169
if (PrintWin32::is_os_wide())
170
hdc = CreateEnhMetaFileW( hScreenDC, unicode_uri, &rc, NULL );
172
hdc = CreateEnhMetaFileA( hScreenDC, ansi_uri, &rc, NULL );
174
// Release the reference DC
175
ReleaseDC( NULL, hScreenDC );
177
// Did we get a good metafile?
185
// Anisotropic mapping mode
186
SetMapMode( hdc, MM_ANISOTROPIC );
188
// Set the Windows extent
189
SetWindowExtEx( hdc, (int) (dwInchesX*dwDPI), (int) (dwInchesY*dwDPI), NULL );
191
// Set the viewport extent to reflect
192
// dwInchesX" x dwInchesY" in device units
193
SetViewportExtEx( hdc,
194
(int) ((float) dwInchesX*25.4f*PixelsX/MMX),
195
(int) ((float) dwInchesY*25.4f*PixelsY/MMY),
198
SetRect( &rc, 0, 0, (int) ceil(dwInchesX*dwDPI), (int) ceil(dwInchesY*dwDPI) );
208
PrintEmfWin32::finish (Inkscape::Extension::Print *mod)
212
flush_fill(); // flush any pending fills
214
HENHMETAFILE metafile = CloseEnhMetaFile( hdc );
216
DeleteEnhMetaFile( metafile );
227
PrintEmfWin32::comment (Inkscape::Extension::Print * module,
232
flush_fill(); // flush any pending fills
239
PrintEmfWin32::create_brush(SPStyle const *style)
244
sp_color_get_rgb_floatv( &style->fill.value.color, rgb );
245
hbrush = CreateSolidBrush( RGB(255*rgb[0], 255*rgb[1], 255*rgb[2]) );
246
hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );
248
SetPolyFillMode( hdc,
249
style->fill_rule.computed == 0 ? WINDING :
250
style->fill_rule.computed == 2 ? ALTERNATE : ALTERNATE );
251
} else { // if (!style)
252
hbrush = CreateSolidBrush( RGB(255, 255, 255) );
253
hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );
254
SetPolyFillMode( hdc, ALTERNATE );
260
PrintEmfWin32::destroy_brush()
262
SelectObject( hdc, hbrushOld );
264
DeleteObject( hbrush );
270
PrintEmfWin32::create_pen(SPStyle const *style)
275
sp_color_get_rgb_floatv(&style->stroke.value.color, rgb);
278
lb.lbStyle = BS_SOLID;
279
lb.lbColor = RGB( 255*rgb[0], 255*rgb[1], 255*rgb[2] );
281
int linestyle = PS_SOLID;
288
DWORD linewidth = MAX( 1, (DWORD) (style->stroke_width.computed * IN_PER_PX * dwDPI) );
290
if (style->stroke_linecap.computed == 0) {
291
linecap = PS_ENDCAP_FLAT;
293
else if (style->stroke_linecap.computed == 1) {
294
linecap = PS_ENDCAP_ROUND;
296
else if (style->stroke_linecap.computed == 2) {
297
linecap = PS_ENDCAP_SQUARE;
300
if (style->stroke_linejoin.computed == 0) {
301
linejoin = PS_JOIN_MITER;
303
else if (style->stroke_linejoin.computed == 1) {
304
linejoin = PS_JOIN_ROUND;
306
else if (style->stroke_linejoin.computed == 2) {
307
linejoin = PS_JOIN_BEVEL;
310
if (style->stroke_dash.n_dash &&
311
style->stroke_dash.dash )
314
while (linestyle != PS_USERSTYLE &&
315
(i < style->stroke_dash.n_dash)) {
316
if (style->stroke_dash.dash[i] > 0.00000001)
317
linestyle = PS_USERSTYLE;
321
if (linestyle == PS_USERSTYLE) {
322
n_dash = style->stroke_dash.n_dash;
323
dash = new DWORD[n_dash];
324
for (i = 0; i < style->stroke_dash.n_dash; i++) {
325
dash[i] = (DWORD) (style->stroke_dash.dash[i] * IN_PER_PX * dwDPI);
331
PS_GEOMETRIC | linestyle | linecap | linejoin,
337
if ( !hpen && linestyle == PS_USERSTYLE ) {
339
PS_GEOMETRIC | PS_SOLID | linecap | linejoin,
353
hpenOld = (HPEN) SelectObject( hdc, hpen );
355
if (linejoin == PS_JOIN_MITER) {
356
float miterlimit = style->stroke_miterlimit.value;
361
miterlimit * IN_PER_PX * dwDPI,
369
else { // if (!style)
370
hpen = CreatePen( PS_SOLID, 1, RGB(0, 0, 0) );
371
hpenOld = (HPEN) SelectObject( hdc, hpen );
377
PrintEmfWin32::destroy_pen()
379
SelectObject( hdc, hpenOld );
381
DeleteObject( hpen );
387
PrintEmfWin32::flush_fill()
390
print_bpath(fill_path, &fill_transform, &fill_pbox);
400
PrintEmfWin32::copy_bpath(const NArtBpath *bp)
402
NArtBpath *tmp = (NArtBpath *) bp;
405
while (tmp->code != NR_END) {
410
tmp = new NArtBpath[num];
420
PrintEmfWin32::cmp_bpath(const NArtBpath *bp1, const NArtBpath *bp2)
426
while (bp1->code != NR_END && bp2->code != NR_END) {
427
if (bp1->code != bp2->code) {
431
if ( fabs(bp1->x1 - bp2->x1) > 0.00000001 ||
432
fabs(bp1->y1 - bp2->y1) > 0.00000001 ||
433
fabs(bp1->x2 - bp2->x2) > 0.00000001 ||
434
fabs(bp1->y2 - bp2->y2) > 0.00000001 ||
435
fabs(bp1->x3 - bp2->x3) > 0.00000001 ||
436
fabs(bp1->y3 - bp2->y3) > 0.00000001 )
445
return bp1->code != NR_END || bp2->code != NR_END;
450
PrintEmfWin32::fill(Inkscape::Extension::Print *mod,
451
NRBPath const *bpath, NRMatrix const *transform, SPStyle const *style,
452
NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
456
flush_fill(); // flush any pending fills
458
if (style->fill.type == SP_PAINT_TYPE_COLOR) {
461
// create_brush(NULL);
465
fill_path = copy_bpath( bpath->path );
466
fill_transform = *transform;
469
// postpone fill in case of stroke-and-fill
476
PrintEmfWin32::stroke (Inkscape::Extension::Print *mod,
477
const NRBPath *bpath, const NRMatrix *transform, const SPStyle *style,
478
const NRRect *pbox, const NRRect *dbox, const NRRect *bbox)
482
bool stroke_and_fill = ( cmp_bpath( bpath->path, fill_path ) == 0 );
484
if (!stroke_and_fill) {
485
flush_fill(); // flush any pending fills
488
if (style->stroke.type == SP_PAINT_TYPE_COLOR) {
495
print_bpath(bpath->path, transform, pbox);
497
if (stroke_and_fill) {
498
StrokeAndFillPath( hdc );
513
PrintEmfWin32::print_bpath(const NArtBpath *bp, const NRMatrix *transform, NRRect const *pbox)
516
NR::Matrix tf = *transform;
520
while (bp->code != NR_END) {
524
NR::Point p1(bp->c(1) * tf);
525
NR::Point p2(bp->c(2) * tf);
526
NR::Point p3(bp->c(3) * tf);
528
p1[X] = (p1[X] * IN_PER_PX * dwDPI);
529
p2[X] = (p2[X] * IN_PER_PX * dwDPI);
530
p3[X] = (p3[X] * IN_PER_PX * dwDPI);
531
p1[Y] = (p1[Y] * IN_PER_PX * dwDPI);
532
p2[Y] = (p2[Y] * IN_PER_PX * dwDPI);
533
p3[Y] = (p3[Y] * IN_PER_PX * dwDPI);
535
LONG const x1 = (LONG) round(p1[X]);
536
LONG const y1 = (LONG) round(rc.bottom-p1[Y]);
537
LONG const x2 = (LONG) round(p2[X]);
538
LONG const y2 = (LONG) round(rc.bottom-p2[Y]);
539
LONG const x3 = (LONG) round(p3[X]);
540
LONG const y3 = (LONG) round(rc.bottom-p3[Y]);
548
MoveToEx( hdc, x3, y3, NULL );
555
MoveToEx( hdc, x3, y3, NULL );
558
LineTo( hdc, x3, y3 );
570
PolyBezierTo( hdc, pt, 3 );
588
PrintEmfWin32::textToPath(Inkscape::Extension::Print * ext)
590
return ext->get_param_bool("textToPath");
595
PrintEmfWin32::init (void)
597
Inkscape::Extension::Extension * ext;
600
ext = Inkscape::Extension::build_from_mem(
601
"<inkscape-extension>\n"
602
"<name>Enhanced Metafile Print</name>\n"
603
"<id>org.inkscape.print.emf.win32</id>\n"
604
"<param name=\"destination\" type=\"string\"></param>\n"
605
"<param name=\"textToPath\" type=\"boolean\">TRUE</param>\n"
606
"<param name=\"pageBoundingBox\" type=\"boolean\">TRUE</param>\n"
608
"</inkscape-extension>", new PrintEmfWin32());
614
} /* namespace Internal */
615
} /* namespace Extension */
616
} /* namespace Inkscape */
623
c-file-style:"stroustrup"
624
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
629
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
2
* Enhanced Metafile Printing.
6
* Ulf Erikson <ulferikson@users.sf.net>
8
* Copyright (C) 2006 Authors
10
* Released under GNU GPL, read the file 'COPYING' for more information
14
* - How to Create & Play Enhanced Metafiles in Win32
15
* http://support.microsoft.com/kb/q145999/
16
* - INFO: Windows Metafile Functions & Aldus Placeable Metafiles
17
* http://support.microsoft.com/kb/q66949/
18
* - Metafile Functions
19
* http://msdn.microsoft.com/library/en-us/gdi/metafile_0whf.asp
20
* - Metafile Structures
21
* http://msdn.microsoft.com/library/en-us/gdi/metafile_5hkj.asp
34
#include "libnr/n-art-bpath.h"
35
#include "libnr/nr-point-matrix-ops.h"
36
#include "libnr/nr-rect.h"
37
#include "libnr/nr-matrix.h"
38
#include "libnr/nr-matrix-fns.h"
39
#include "libnr/nr-path.h"
40
#include "libnr/nr-pixblock.h"
41
#include "display/canvas-bpath.h"
45
#include "gtk/gtkdialog.h"
46
#include "gtk/gtkbox.h"
47
#include "gtk/gtkstock.h"
49
#include "glibmm/i18n.h"
53
#include "sp-paint-server.h"
54
#include "inkscape_version.h"
56
#include "FontFactory.h"
57
#include "libnrtype/font-instance.h"
58
#include "libnrtype/font-style-to-pos.h"
61
#include "emf-win32-print.h"
63
#include "unit-constants.h"
65
#include "extension/extension.h"
66
#include "extension/system.h"
67
#include "extension/print.h"
73
#define WIN32_LEAN_AND_MEAN
80
static float dwDPI = 2540;
83
PrintEmfWin32::PrintEmfWin32 (void):
93
PrintEmfWin32::~PrintEmfWin32 (void)
96
HENHMETAFILE metafile = CloseEnhMetaFile( hdc );
98
DeleteEnhMetaFile( metafile );
103
/* restore default signal handling for SIGPIPE */
104
#if !defined(_WIN32) && !defined(__WIN32__)
105
(void) signal(SIGPIPE, SIG_DFL);
112
PrintEmfWin32::setup (Inkscape::Extension::Print *mod)
119
PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc)
121
gchar const *utf8_fn = mod->get_param_string("destination");
124
gsize bytesWritten = 0;
125
GError* error = NULL;
127
g_filename_from_utf8( utf8_fn, -1, &bytesRead, &bytesWritten, &error );
129
if (local_fn == NULL) {
133
CHAR *ansi_uri = (CHAR *) local_fn;
134
gunichar2 *unicode_fn = g_utf8_to_utf16( local_fn, -1, NULL, NULL, NULL );
135
WCHAR *unicode_uri = (WCHAR *) unicode_fn;
137
// width and height in px
138
_width = sp_document_width(doc);
139
_height = sp_document_height(doc);
142
bool pageBoundingBox;
143
pageBoundingBox = mod->get_param_bool("pageBoundingBox");
144
if (pageBoundingBox) {
149
SPItem* doc_item = SP_ITEM(sp_document_root(doc));
150
sp_item_invoke_bbox(doc_item, &d, sp_item_i2r_affine(doc_item), TRUE);
158
float dwInchesX = (d.x1 - d.x0);
159
float dwInchesY = (d.y1 - d.y0);
161
// dwInchesX x dwInchesY in .01mm units
162
SetRect( &rc, 0, 0, (int) ceil(dwInchesX*2540), (int) ceil(dwInchesY*2540) );
164
// Get a Reference DC
165
HDC hScreenDC = GetDC( NULL );
167
// Get the physical characteristics of the reference DC
168
float PixelsX = (float) GetDeviceCaps( hScreenDC, HORZRES );
169
float PixelsY = (float) GetDeviceCaps( hScreenDC, VERTRES );
170
float MMX = (float) GetDeviceCaps( hScreenDC, HORZSIZE );
171
float MMY = (float) GetDeviceCaps( hScreenDC, VERTSIZE );
173
// Create the Metafile
174
if (PrintWin32::is_os_wide())
175
hdc = CreateEnhMetaFileW( hScreenDC, unicode_uri, &rc, NULL );
177
hdc = CreateEnhMetaFileA( hScreenDC, ansi_uri, &rc, NULL );
179
// Release the reference DC
180
ReleaseDC( NULL, hScreenDC );
182
// Did we get a good metafile?
190
// Anisotropic mapping mode
191
SetMapMode( hdc, MM_ANISOTROPIC );
193
// Set the Windows extent
194
SetWindowExtEx( hdc, (int) (dwInchesX*dwDPI), (int) (dwInchesY*dwDPI), NULL );
196
// Set the viewport extent to reflect
197
// dwInchesX" x dwInchesY" in device units
198
SetViewportExtEx( hdc,
199
(int) ((float) dwInchesX*25.4f*PixelsX/MMX),
200
(int) ((float) dwInchesY*25.4f*PixelsY/MMY),
203
SetRect( &rc, 0, 0, (int) ceil(dwInchesX*dwDPI), (int) ceil(dwInchesY*dwDPI) );
213
PrintEmfWin32::finish (Inkscape::Extension::Print *mod)
217
flush_fill(); // flush any pending fills
219
HENHMETAFILE metafile = CloseEnhMetaFile( hdc );
221
DeleteEnhMetaFile( metafile );
232
PrintEmfWin32::comment (Inkscape::Extension::Print * module,
237
flush_fill(); // flush any pending fills
244
PrintEmfWin32::create_brush(SPStyle const *style)
249
float opacity = SP_SCALE24_TO_FLOAT(style->fill_opacity.value);
253
sp_color_get_rgb_floatv( &style->fill.value.color, rgb );
254
hbrush = CreateSolidBrush( RGB(255*rgb[0], 255*rgb[1], 255*rgb[2]) );
255
hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );
257
SetPolyFillMode( hdc,
258
style->fill_rule.computed == 0 ? WINDING :
259
style->fill_rule.computed == 2 ? ALTERNATE : ALTERNATE );
260
} else { // if (!style)
261
hbrush = CreateSolidBrush( RGB(255, 255, 255) );
262
hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );
263
SetPolyFillMode( hdc, ALTERNATE );
271
PrintEmfWin32::destroy_brush()
273
SelectObject( hdc, hbrushOld );
275
DeleteObject( hbrush );
282
PrintEmfWin32::create_pen(SPStyle const *style, const NRMatrix *transform)
287
sp_color_get_rgb_floatv(&style->stroke.value.color, rgb);
290
lb.lbStyle = BS_SOLID;
291
lb.lbColor = RGB( 255*rgb[0], 255*rgb[1], 255*rgb[2] );
293
int linestyle = PS_SOLID;
303
NR::Matrix tf = *transform;
305
NR::Point zero(0, 0);
307
NR::Point p0(zero * tf);
308
NR::Point p1(one * tf);
309
NR::Point p(p1 - p0);
311
double scale = sqrt( (p[X]*p[X]) + (p[Y]*p[Y]) ) / sqrt(2);
313
DWORD linewidth = MAX( 1, (DWORD) (scale * style->stroke_width.computed * IN_PER_PX * dwDPI) );
315
if (style->stroke_linecap.computed == 0) {
316
linecap = PS_ENDCAP_FLAT;
318
else if (style->stroke_linecap.computed == 1) {
319
linecap = PS_ENDCAP_ROUND;
321
else if (style->stroke_linecap.computed == 2) {
322
linecap = PS_ENDCAP_SQUARE;
325
if (style->stroke_linejoin.computed == 0) {
326
linejoin = PS_JOIN_MITER;
328
else if (style->stroke_linejoin.computed == 1) {
329
linejoin = PS_JOIN_ROUND;
331
else if (style->stroke_linejoin.computed == 2) {
332
linejoin = PS_JOIN_BEVEL;
335
if (style->stroke_dash.n_dash &&
336
style->stroke_dash.dash )
339
while (linestyle != PS_USERSTYLE &&
340
(i < style->stroke_dash.n_dash)) {
341
if (style->stroke_dash.dash[i] > 0.00000001)
342
linestyle = PS_USERSTYLE;
346
if (linestyle == PS_USERSTYLE) {
347
n_dash = style->stroke_dash.n_dash;
348
dash = new DWORD[n_dash];
349
for (i = 0; i < style->stroke_dash.n_dash; i++) {
350
dash[i] = (DWORD) (style->stroke_dash.dash[i] * IN_PER_PX * dwDPI);
356
PS_GEOMETRIC | linestyle | linecap | linejoin,
362
if ( !hpen && linestyle == PS_USERSTYLE ) {
364
PS_GEOMETRIC | PS_SOLID | linecap | linejoin,
378
hpenOld = (HPEN) SelectObject( hdc, hpen );
380
if (linejoin == PS_JOIN_MITER) {
381
float miterlimit = style->stroke_miterlimit.value;
386
miterlimit * IN_PER_PX * dwDPI,
394
else { // if (!style)
395
hpen = CreatePen( PS_SOLID, 1, RGB(0, 0, 0) );
396
hpenOld = (HPEN) SelectObject( hdc, hpen );
402
PrintEmfWin32::destroy_pen()
404
SelectObject( hdc, hpenOld );
406
DeleteObject( hpen );
412
PrintEmfWin32::flush_fill()
415
print_bpath(fill_path, &fill_transform, &fill_pbox);
425
PrintEmfWin32::copy_bpath(const NArtBpath *bp)
427
NArtBpath *tmp = (NArtBpath *) bp;
430
while (tmp->code != NR_END) {
435
tmp = new NArtBpath[num];
445
PrintEmfWin32::cmp_bpath(const NArtBpath *bp1, const NArtBpath *bp2)
451
while (bp1->code != NR_END && bp2->code != NR_END) {
452
if (bp1->code != bp2->code) {
456
if ( fabs(bp1->x1 - bp2->x1) > 0.00000001 ||
457
fabs(bp1->y1 - bp2->y1) > 0.00000001 ||
458
fabs(bp1->x2 - bp2->x2) > 0.00000001 ||
459
fabs(bp1->y2 - bp2->y2) > 0.00000001 ||
460
fabs(bp1->x3 - bp2->x3) > 0.00000001 ||
461
fabs(bp1->y3 - bp2->y3) > 0.00000001 )
470
return bp1->code != NR_END || bp2->code != NR_END;
474
PrintEmfWin32::bind(Inkscape::Extension::Print *mod, NRMatrix const *transform, float opacity)
476
text_transform = *transform;
481
PrintEmfWin32::release(Inkscape::Extension::Print *mod)
487
PrintEmfWin32::fill(Inkscape::Extension::Print *mod,
488
NRBPath const *bpath, NRMatrix const *transform, SPStyle const *style,
489
NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
493
flush_fill(); // flush any pending fills
495
if (style->fill.isColor()) {
496
if (create_brush(style))
499
// create_brush(NULL);
503
fill_path = copy_bpath( bpath->path );
504
fill_transform = *transform;
507
// postpone fill in case of stroke-and-fill
514
PrintEmfWin32::stroke (Inkscape::Extension::Print *mod,
515
const NRBPath *bpath, const NRMatrix *transform, const SPStyle *style,
516
const NRRect *pbox, const NRRect *dbox, const NRRect *bbox)
520
bool stroke_and_fill = ( cmp_bpath( bpath->path, fill_path ) == 0 );
522
if (!stroke_and_fill) {
523
flush_fill(); // flush any pending fills
526
if (style->stroke.isColor()) {
527
create_pen(style, transform);
529
// create_pen(NULL, transform);
533
print_bpath(bpath->path, transform, pbox);
535
if (stroke_and_fill) {
536
StrokeAndFillPath( hdc );
551
PrintEmfWin32::print_bpath(const NArtBpath *bp, const NRMatrix *transform, NRRect const *pbox)
554
NR::Matrix tf = *transform;
558
while (bp->code != NR_END) {
562
NR::Point p1(bp->c(1) * tf);
563
NR::Point p2(bp->c(2) * tf);
564
NR::Point p3(bp->c(3) * tf);
566
p1[X] = (p1[X] * IN_PER_PX * dwDPI);
567
p2[X] = (p2[X] * IN_PER_PX * dwDPI);
568
p3[X] = (p3[X] * IN_PER_PX * dwDPI);
569
p1[Y] = (p1[Y] * IN_PER_PX * dwDPI);
570
p2[Y] = (p2[Y] * IN_PER_PX * dwDPI);
571
p3[Y] = (p3[Y] * IN_PER_PX * dwDPI);
573
LONG const x1 = (LONG) round(p1[X]);
574
LONG const y1 = (LONG) round(rc.bottom-p1[Y]);
575
LONG const x2 = (LONG) round(p2[X]);
576
LONG const y2 = (LONG) round(rc.bottom-p2[Y]);
577
LONG const x3 = (LONG) round(p3[X]);
578
LONG const y3 = (LONG) round(rc.bottom-p3[Y]);
586
MoveToEx( hdc, x3, y3, NULL );
593
MoveToEx( hdc, x3, y3, NULL );
596
LineTo( hdc, x3, y3 );
608
PolyBezierTo( hdc, pt, 3 );
626
PrintEmfWin32::textToPath(Inkscape::Extension::Print * ext)
628
return ext->get_param_bool("textToPath");
632
PrintEmfWin32::text(Inkscape::Extension::Print *mod, char const *text, NR::Point p,
633
SPStyle const *const style)
639
#ifdef USE_PANGO_WIN32
641
font_instance *tf = (font_factory::Default())->Face(style->text->font_family.value, font_style_to_pos(*style));
643
LOGFONT *lf = pango_win32_font_logfont(tf->pFont);
645
hfont = CreateFontIndirect(lf);
652
if (PrintWin32::is_os_wide()) {
653
LOGFONTW *lf = (LOGFONTW*)g_malloc(sizeof(LOGFONTW));
654
g_assert(lf != NULL);
656
lf->lfHeight = style->font_size.computed * IN_PER_PX * dwDPI;
658
lf->lfEscapement = 0;
659
lf->lfOrientation = 0;
661
style->font_weight.value == SP_CSS_FONT_WEIGHT_100 ? FW_THIN :
662
style->font_weight.value == SP_CSS_FONT_WEIGHT_200 ? FW_EXTRALIGHT :
663
style->font_weight.value == SP_CSS_FONT_WEIGHT_300 ? FW_LIGHT :
664
style->font_weight.value == SP_CSS_FONT_WEIGHT_400 ? FW_NORMAL :
665
style->font_weight.value == SP_CSS_FONT_WEIGHT_500 ? FW_MEDIUM :
666
style->font_weight.value == SP_CSS_FONT_WEIGHT_600 ? FW_SEMIBOLD :
667
style->font_weight.value == SP_CSS_FONT_WEIGHT_700 ? FW_BOLD :
668
style->font_weight.value == SP_CSS_FONT_WEIGHT_800 ? FW_EXTRABOLD :
669
style->font_weight.value == SP_CSS_FONT_WEIGHT_900 ? FW_HEAVY :
670
style->font_weight.value == SP_CSS_FONT_WEIGHT_NORMAL ? FW_NORMAL :
671
style->font_weight.value == SP_CSS_FONT_WEIGHT_BOLD ? FW_BOLD :
672
style->font_weight.value == SP_CSS_FONT_WEIGHT_LIGHTER ? FW_EXTRALIGHT :
673
style->font_weight.value == SP_CSS_FONT_WEIGHT_BOLDER ? FW_EXTRABOLD :
675
lf->lfItalic = (style->font_style.value == SP_CSS_FONT_STYLE_ITALIC);
676
lf->lfUnderline = style->text_decoration.underline;
677
lf->lfStrikeOut = style->text_decoration.line_through;
678
lf->lfCharSet = DEFAULT_CHARSET;
679
lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
680
lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
681
lf->lfQuality = DEFAULT_QUALITY;
682
lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
684
gunichar2 *unicode_name = g_utf8_to_utf16( style->text->font_family.value, -1, NULL, NULL, NULL );
685
wcsncpy(lf->lfFaceName, (wchar_t*) unicode_name, LF_FACESIZE-1);
686
g_free(unicode_name);
688
hfont = CreateFontIndirectW(lf);
693
LOGFONTA *lf = (LOGFONTA*)g_malloc(sizeof(LOGFONTA));
694
g_assert(lf != NULL);
696
lf->lfHeight = style->font_size.computed * IN_PER_PX * dwDPI;
698
lf->lfEscapement = 0;
699
lf->lfOrientation = 0;
701
style->font_weight.value == SP_CSS_FONT_WEIGHT_100 ? FW_THIN :
702
style->font_weight.value == SP_CSS_FONT_WEIGHT_200 ? FW_EXTRALIGHT :
703
style->font_weight.value == SP_CSS_FONT_WEIGHT_300 ? FW_LIGHT :
704
style->font_weight.value == SP_CSS_FONT_WEIGHT_400 ? FW_NORMAL :
705
style->font_weight.value == SP_CSS_FONT_WEIGHT_500 ? FW_MEDIUM :
706
style->font_weight.value == SP_CSS_FONT_WEIGHT_600 ? FW_SEMIBOLD :
707
style->font_weight.value == SP_CSS_FONT_WEIGHT_700 ? FW_BOLD :
708
style->font_weight.value == SP_CSS_FONT_WEIGHT_800 ? FW_EXTRABOLD :
709
style->font_weight.value == SP_CSS_FONT_WEIGHT_900 ? FW_HEAVY :
710
style->font_weight.value == SP_CSS_FONT_WEIGHT_NORMAL ? FW_NORMAL :
711
style->font_weight.value == SP_CSS_FONT_WEIGHT_BOLD ? FW_BOLD :
712
style->font_weight.value == SP_CSS_FONT_WEIGHT_LIGHTER ? FW_EXTRALIGHT :
713
style->font_weight.value == SP_CSS_FONT_WEIGHT_BOLDER ? FW_EXTRABOLD :
715
lf->lfItalic = (style->font_style.value == SP_CSS_FONT_STYLE_ITALIC);
716
lf->lfUnderline = style->text_decoration.underline;
717
lf->lfStrikeOut = style->text_decoration.line_through;
718
lf->lfCharSet = DEFAULT_CHARSET;
719
lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
720
lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
721
lf->lfQuality = DEFAULT_QUALITY;
722
lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
724
strncpy(lf->lfFaceName, (char*) style->text->font_family.value, LF_FACESIZE-1);
726
hfont = CreateFontIndirectA(lf);
732
HFONT hfontOld = (HFONT) SelectObject(hdc, hfont);
735
sp_color_get_rgb_floatv( &style->fill.value.color, rgb );
736
SetTextColor(hdc, RGB(255*rgb[0], 255*rgb[1], 255*rgb[2]));
739
style->text_align.value == SP_CSS_TEXT_ALIGN_RIGHT ? TA_RIGHT :
740
style->text_align.value == SP_CSS_TEXT_ALIGN_CENTER ? TA_CENTER : TA_LEFT;
741
SetTextAlign(hdc, TA_BASELINE | align);
743
p = p * text_transform;
744
p[NR::X] = (p[NR::X] * IN_PER_PX * dwDPI);
745
p[NR::Y] = (p[NR::Y] * IN_PER_PX * dwDPI);
747
if (PrintWin32::is_os_wide()) {
748
gunichar2 *unicode_text = g_utf8_to_utf16( text, -1, NULL, NULL, NULL );
749
TextOutW(hdc, p[NR::X], p[NR::Y], (WCHAR*)unicode_text, wcslen((wchar_t*)unicode_text));
752
TextOutA(hdc, p[NR::X], p[NR::Y], (CHAR*)text, strlen((char*)text));
755
SelectObject(hdc, hfontOld);
766
PrintEmfWin32::init (void)
768
Inkscape::Extension::Extension * ext;
771
ext = Inkscape::Extension::build_from_mem(
772
"<inkscape-extension>\n"
773
"<name>Enhanced Metafile Print</name>\n"
774
"<id>org.inkscape.print.emf.win32</id>\n"
775
"<param name=\"destination\" type=\"string\"></param>\n"
776
"<param name=\"textToPath\" type=\"boolean\">TRUE</param>\n"
777
"<param name=\"pageBoundingBox\" type=\"boolean\">TRUE</param>\n"
779
"</inkscape-extension>", new PrintEmfWin32());
785
} /* namespace Internal */
786
} /* namespace Extension */
787
} /* namespace Inkscape */
794
c-file-style:"stroustrup"
795
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
800
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :