~ubuntu-branches/ubuntu/precise/gle-graphics/precise

« back to all changes in this revision

Viewing changes to src/gle/d_cairo.cpp

  • Committer: Package Import Robot
  • Author(s): Christian T. Steigies
  • Date: 2011-10-20 22:15:27 UTC
  • mfrom: (5.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20111020221527-sv27lrowdd221npi
Tags: 4.2.3b-1
* new upstream version
* switch from cdbs to debhelper 8
* update copyright file
* do no rely on proc on non-linux systems (closes: #644588)
* do not ship glebtool, which is a helper used only during build
* add libqt4-opengl-dev to build-depends

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
#include <cairo-pdf.h>
49
49
#include <cairo-svg.h>
50
50
 
 
51
 
 
52
/************************************************************************************
 
53
 * Fonts in Cairo:
 
54
 *
 
55
 ************************************************************************************/
 
56
 
51
57
extern struct gmodel g;
52
58
 
53
59
char *font_getname(int i);
101
107
        } else {
102
108
                g_flush();
103
109
                cairo_new_path(cr);
 
110
                GLERectangle rect(x1, y1, x2, y2);
104
111
                xdbox(x1,y1,x2,y2);
105
 
                ddfill();
 
112
                ddfill(&rect);
106
113
                cairo_new_path(cr);
107
114
        }
108
115
}
146
153
                g_flush();
147
154
                cairo_new_path(cr);
148
155
                cairo_arc(cr, x, y, zr, 0, 2*GLE_PI);
149
 
                ddfill();
 
156
                GLERectangle rect(x-zr, y-zr, x+zr, y+zr);
 
157
                ddfill(&rect);
150
158
                cairo_new_path(cr);
151
159
        }
152
160
}
166
174
}
167
175
 
168
176
void GLECairoDevice::clear(void) {
169
 
        //cout << "clear not yet implemented" << endl;
170
177
}
171
178
 
172
179
void GLECairoDevice::clip(void) {
184
191
}
185
192
 
186
193
void GLECairoDevice::dfont(char *c) {
187
 
        cout << "dfont not yet implemented" << endl;
188
194
}
189
195
 
190
196
void GLECairoDevice::ellipse_fill(double rx, double ry) {
203
209
                cairo_scale (cr, rx, ry);
204
210
                cairo_arc (cr, 0, 0, 1, 0, 2*GLE_PI);
205
211
                cairo_restore (cr);
206
 
                ddfill();
 
212
                GLERectangle rect(x-rx, y-ry, x+rx, y+ry);
 
213
                ddfill(&rect);
207
214
                cairo_new_path(cr);
208
215
        }
209
216
}
268
275
        //cairo_restore(cr);
269
276
}
270
277
 
271
 
void GLECairoDevice::ddfill(void) {
 
278
void GLECairoDevice::ddfill(GLERectangle* bounds) {
272
279
        if (g_cur_fill.b[B_F] == 255) return; /* clear fill, do nothing */
273
280
        if (g_cur_fill.b[B_F] == 2) {
274
 
                shade();
 
281
                shade(bounds);
275
282
                return;
276
283
        }
277
284
        set_fill();                     /*because color and fill are the same*/
280
287
        set_color();
281
288
}
282
289
 
283
 
void GLECairoDevice::shade(void) {
284
 
        cout << "shade not yet implemented" << endl;
285
 
 
 
290
void GLECairoDevice::shadePattern(void) {
286
291
        int step1 = g_cur_fill.b[B_B];
287
292
        int step2 = g_cur_fill.b[B_G];
288
293
        int xstep = max(step1, step2);
289
294
        int ystep = max(step1, step2);
290
 
 
291
 
        cout << xstep << endl;
292
 
        cout << ystep << endl;
293
 
 
294
 
        cairo_surface_t *isurface;
295
 
        cairo_pattern_t *pattern;
296
 
        cairo_t *icr;
297
 
        cairo_matrix_t   matrix;
298
 
 
299
295
        cairo_save(cr);
 
296
        cairo_matrix_t matrix;
300
297
        cairo_get_matrix(cr, &matrix);
301
 
 
302
 
        isurface = cairo_surface_create_similar (surface, CAIRO_CONTENT_COLOR_ALPHA, xstep, ystep);
303
 
        icr = cairo_create(isurface);
304
 
 
305
 
        //out() << "/BBox [0 0 " << xstep << " " << ystep << "]" << endl;
306
 
        //out() << "/XStep " << xstep << endl;
307
 
        //out() << "/YStep " << ystep << endl;
308
 
        //out() << "/PaintProc" << endl;
309
 
        //out() << "{ pop" << endl;
310
 
        //out() << "1 setgray" << endl;
311
 
        cairo_set_source_rgb(icr, 255.0, 255.0, 255.0);
312
 
        //out() << "2 setlinecap" << endl;
313
 
        cairo_set_line_cap(icr, (cairo_line_cap_t)2);
314
 
        //out() << "-1 -1 " << (xstep+1) << " " << (ystep+1) << " rectfill" << endl;
315
 
        cairo_rectangle(icr, -1, -1, (xstep+1), (ystep+1));
316
 
        cairo_fill(icr);
317
 
 
 
298
        cairo_surface_t *isurface = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR_ALPHA, xstep, ystep);
 
299
        cairo_t *icr = cairo_create(isurface);
 
300
        if (m_Background != (int)GLE_FILL_CLEAR) {
 
301
                if (m_Background == (int)GLE_COLOR_WHITE) {
 
302
                        cairo_set_source_rgb(icr, 1.0, 1.0, 1.0);
 
303
                } else {
 
304
                        colortyp col;
 
305
                        col.l = m_Background;
 
306
                        cairo_set_source_rgb(icr, col.b[B_R]/255.0, col.b[B_G]/255.0, col.b[B_B]/255.0);
 
307
                }
 
308
                cairo_rectangle(icr, -1, -1, (xstep+1), (ystep+1));
 
309
                cairo_fill(icr);
 
310
        }
318
311
        if (g_cur_fill_color.l == GLE_COLOR_BLACK) {
319
 
                //out() << "0 setgray" << endl;
320
312
                cairo_set_source_rgb(icr, 0, 0, 0);
321
313
        } else {
322
 
                //set_color(g_cur_fill_color);
323
314
                cairo_set_source_rgb(icr, g_cur_fill_color.b[B_R]/255.0, g_cur_fill_color.b[B_G]/255.0, g_cur_fill_color.b[B_B]/255.0);
324
315
        }
325
 
        //out() << (int)g_cur_fill.b[B_R] << " setlinewidth" << endl;
326
316
        cairo_set_line_width(icr, (int)g_cur_fill.b[B_R]);
327
317
        if (step1 > 0) {
328
 
                //out() << "0 0 moveto" << endl;
329
318
                cairo_move_to(icr, 0, 0);
330
 
                //out() << xstep << " " << ystep << " l" << endl;
331
319
                cairo_line_to(icr, xstep, ystep);
332
 
                //out() << "stroke" << endl;
333
320
                cairo_stroke(icr);
334
321
                if (step2 == 0) {
335
 
                        //out() << xstep/2 << " " << -ystep/2 << " moveto" << endl;
336
322
                        cairo_move_to(icr, xstep/2, -ystep/2);
337
 
                        //out() << 3*xstep/2 << " " << ystep/2 << " l" << endl;
338
323
                        cairo_line_to(icr, 3*xstep/2, ystep/2);
339
 
                        //out() << "stroke" << endl;
340
324
                        cairo_stroke(icr);
341
 
                        //out() << -xstep/2 << " " << ystep/2 << " moveto" << endl;
342
325
                        cairo_move_to(icr, -xstep/2, ystep/2);
343
 
                        //out() << xstep/2 << " " << 3*ystep/2 << " l" << endl;
344
326
                        cairo_line_to(icr, xstep/2, 3*ystep/2);
345
 
                        //out() << "stroke" << endl;
346
327
                        cairo_stroke(icr);
347
328
                }
348
329
        }
349
330
        if (step2 > 0) {
350
 
                //out() << "0 " << ystep << " moveto" << endl;
351
331
                cairo_move_to(icr, 0, ystep);
352
 
                //out() << xstep << " 0 l" << endl;
353
332
                cairo_line_to(icr, xstep, 0);
354
 
                //out() << "stroke" << endl;
355
333
                cairo_stroke(icr);
356
334
                if (step1 == 0) {
357
 
                        //out() << -xstep/2 << " " << ystep/2 << " moveto" << endl;
358
335
                        cairo_move_to(icr, -xstep/2, ystep/2);
359
 
                        //out() << xstep/2 << " " << -ystep/2 << " l" << endl;
360
336
                        cairo_line_to(icr, xstep/2, -ystep/2);
361
 
                        //out() << "stroke" << endl;
362
337
                        cairo_stroke(icr);
363
 
                        //out() << xstep/2 << " " << 3*ystep/2 << " moveto" << endl;
364
338
                        cairo_move_to(icr, xstep/2, 3*ystep/2);
365
 
                        //out() << 3*xstep/2 << " " << ystep/2 << " l" << endl;
366
339
                        cairo_line_to(icr, 3*xstep/2, ystep/2);
367
 
                        //out() << "stroke" << endl;
368
340
                        cairo_stroke(icr);
369
341
                }
370
342
        }
371
343
        cairo_set_source_rgb(icr, g_cur_color.b[B_R]/255.0, g_cur_color.b[B_G]/255.0, g_cur_color.b[B_B]/255.0);
372
 
 
373
 
        pattern = cairo_pattern_create_for_surface (isurface);
374
 
        cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
375
 
 
376
 
        cairo_matrix_init_scale (&matrix, 3*72, 3*72);
377
 
        cairo_pattern_set_matrix (pattern, &matrix);
378
 
 
379
 
        cairo_set_source (cr, pattern);
380
 
 
381
 
        cairo_fill (cr);
382
 
        cairo_restore(cr);
383
 
 
384
 
        cairo_pattern_destroy (pattern);
385
 
        cairo_destroy (icr);
386
 
        cairo_surface_destroy (isurface);
387
 
 
388
 
        /*
389
 
 
390
 
        int              w, h;
391
 
        cairo_surface_t *image;
392
 
        cairo_pattern_t *pattern;
393
 
        cairo_matrix_t   matrix;
394
 
 
395
 
        image = cairo_image_surface_create_from_png ("test_shade.png");
396
 
        w = cairo_image_surface_get_width (image);
397
 
        h = cairo_image_surface_get_height (image);
398
 
 
399
 
        pattern = cairo_pattern_create_for_surface (image);
400
 
        cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
401
 
 
402
 
        cairo_save(cr);
403
 
        //cairo_translate (cr, 128.0, 128.0);
404
 
        //cairo_rotate (cr, M_PI / 4);
405
 
        //cairo_scale (cr, 1 / sqrt (2), 1 / sqrt (2));
406
 
        //cairo_translate (cr, -128.0, -128.0);
407
 
 
408
 
 
409
 
        //cairo_matrix_init_scale (&matrix, w/256.0 * 5.0, h/256.0 * 5.0);
410
 
        cairo_get_matrix(cr, &matrix);
411
 
        cairo_pattern_set_matrix (pattern, &matrix);
412
 
 
413
 
        cairo_set_source (cr, pattern);
414
 
 
415
 
        //cairo_rectangle (cr, 0, 0, 256.0, 256.0);
416
 
        cairo_fill_preserve (cr);
417
 
        cairo_restore(cr);
418
 
        cairo_pattern_destroy (pattern);
419
 
        cairo_surface_destroy (image);
420
 
*/
 
344
        cairo_pattern_t *pattern = cairo_pattern_create_for_surface(isurface);
 
345
        cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
 
346
        cairo_matrix_init_scale(&matrix, 160.0, 160.0);
 
347
        cairo_pattern_set_matrix(pattern, &matrix);
 
348
        cairo_set_source(cr, pattern);
 
349
        cairo_fill(cr);
 
350
        cairo_restore(cr);
 
351
        cairo_pattern_destroy(pattern);
 
352
        cairo_destroy(icr);
 
353
        cairo_surface_destroy(isurface);
 
354
}
 
355
 
 
356
void GLECairoDevice::shadeGLE() {
 
357
        double step1 = g_cur_fill.b[B_B]/160.0;
 
358
        double step2 = g_cur_fill.b[B_G]/160.0;
 
359
        if (step1 > 0) {
 
360
                for (double x = -40.0; x < 40.0; x += step1) {
 
361
                        cairo_move_to(cr, x, 0.0);
 
362
                        cairo_line_to(cr, 40.0+x, 40);
 
363
                        cairo_stroke(cr);
 
364
                }
 
365
        }
 
366
        if (step2 > 0) {
 
367
                for (double x = 0.0; x < 80; x += step2) {
 
368
                        cairo_move_to(cr, x, 0.0);
 
369
                        cairo_line_to(cr, x-40.0, 40);
 
370
                        cairo_stroke(cr);
 
371
                }
 
372
        }
 
373
}
 
374
 
 
375
void GLECairoDevice::shadeBoundedIfThenElse1(GLERectangle* bounds, double p, double step1) {
 
376
        // if x1+p*s > y1 then
 
377
        if (bounds->getXMax()+p*step1 > bounds->getYMax()) {
 
378
                // aline y1-p*s y1
 
379
                cairo_line_to(cr, bounds->getYMax()-p*step1, bounds->getYMax());
 
380
        } else {
 
381
                // aline x1 x1+p*s
 
382
                cairo_line_to(cr, bounds->getXMax(), bounds->getXMax()+p*step1);
 
383
        }
 
384
        cairo_stroke(cr);
 
385
}
 
386
 
 
387
void GLECairoDevice::shadeBoundedIfThenElse2(GLERectangle* bounds, double p, double step2) {
 
388
        // if p*s-y1 > x0 then
 
389
        if (p*step2-bounds->getYMax() > bounds->getXMin()) {
 
390
                // aline p*s-y1 y1
 
391
                cairo_line_to(cr, p*step2-bounds->getYMax(), bounds->getYMax());
 
392
        } else {
 
393
                // aline x0 p*s-x0
 
394
                cairo_line_to(cr, bounds->getXMin(), p*step2-bounds->getXMin());
 
395
        }
 
396
        cairo_stroke(cr);
 
397
}
 
398
 
 
399
void GLECairoDevice::shadeBounded(GLERectangle* bounds) {
 
400
        double step1 = g_cur_fill.b[B_B]/160.0;
 
401
        double step2 = g_cur_fill.b[B_G]/160.0;
 
402
        cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
 
403
        if (step1 > 0) {
 
404
                int p0 = (int)ceil((bounds->getYMax()-bounds->getXMin())/step1-1e-6);
 
405
                if (bounds->getXMin() + p0*step1 > bounds->getYMax()) p0--;
 
406
                int p1 = (int)floor((bounds->getYMin()-bounds->getXMin())/step1+1e-6);
 
407
                if (bounds->getXMin() + p1*step1 < bounds->getYMin()) p1++;
 
408
                int p2 = (int)floor((bounds->getYMin()-bounds->getXMax())/step1+1e-6);
 
409
                if (bounds->getXMax() + p2*step1 < bounds->getYMin()) p2++;
 
410
                for (int p = p0; p > p1; p--) {
 
411
                        // amove x0 x0+p*s
 
412
                        cairo_move_to(cr, bounds->getXMin(), bounds->getXMin()+p*step1);
 
413
                        shadeBoundedIfThenElse1(bounds, p, step1);
 
414
                }
 
415
                for (int p = p1; p >= p2; p--) {
 
416
                        // amove y0-p*s y0
 
417
                        cairo_move_to(cr, bounds->getYMin()-p*step1, bounds->getYMin());
 
418
                        shadeBoundedIfThenElse1(bounds, p, step1);
 
419
                }
 
420
        }
 
421
        if (step2 > 0) {
 
422
                int p0 = (int)ceil((bounds->getYMax()+bounds->getXMax())/step2-1e-6);
 
423
                if (p0*step2 - bounds->getXMin() > bounds->getYMax()) p0--;
 
424
                int p1 = (int)floor((bounds->getYMin()+bounds->getXMax())/step2+1e-6);
 
425
                if (p1*step2 - bounds->getXMax() < bounds->getYMin()) p1++;
 
426
                int p2 = (int)floor((bounds->getYMin()+bounds->getXMin())/step2+1e-6);
 
427
                if (p2*step2 - bounds->getXMax() < bounds->getYMin()) p2++;
 
428
                for (int p = p0; p > p1; p--) {
 
429
                        // amove x0 x0+p*s
 
430
                        cairo_move_to(cr, bounds->getXMax(), p*step2-bounds->getXMax());
 
431
                        shadeBoundedIfThenElse2(bounds, p, step2);
 
432
                }
 
433
                for (int p = p1; p >= p2; p--) {
 
434
                        // amove y0-p*s y0
 
435
                        cairo_move_to(cr, p*step2-bounds->getYMin(), bounds->getYMin());
 
436
                        shadeBoundedIfThenElse2(bounds, p, step2);
 
437
                }
 
438
        }
 
439
}
 
440
 
 
441
void GLECairoDevice::shade(GLERectangle* bounds) {
 
442
        if (m_FillMethod == GLE_FILL_METHOD_GLE ||
 
443
           (m_FillMethod == GLE_FILL_METHOD_DEFAULT && bounds != NULL)) {
 
444
                cairo_save(cr);
 
445
                if (m_Background != (int)GLE_FILL_CLEAR) {
 
446
                        if (m_Background == (int)GLE_COLOR_WHITE) {
 
447
                                cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
 
448
                        } else {
 
449
                                colortyp col;
 
450
                                col.l = m_Background;
 
451
                                set_color(col);
 
452
                        }
 
453
                        cairo_fill_preserve(cr);
 
454
                }
 
455
                // Implemented by using path as clip and then painting strokes over the clip
 
456
                cairo_clip(cr);
 
457
                cairo_new_path(cr);
 
458
                if (g_cur_fill_color.l == GLE_COLOR_BLACK) {
 
459
                        cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
 
460
                } else {
 
461
                        set_color(g_cur_fill_color);
 
462
                }
 
463
                cairo_set_line_width(cr, (double)(g_cur_fill.b[B_R]/160.0));
 
464
                if (m_FillMethod == GLE_FILL_METHOD_DEFAULT && bounds != NULL) {
 
465
                        shadeBounded(bounds);
 
466
                } else {
 
467
                        shadeGLE();
 
468
                }
 
469
                cairo_restore(cr);
 
470
        } else {
 
471
                shadePattern();
 
472
        }
421
473
}
422
474
 
423
475
void GLECairoDevice::fill_ary(int nwk,double *wkx,double *wky) {
448
500
}
449
501
 
450
502
void GLECairoDevice::message(char *s) {
451
 
        cout << "message not yet implemented" << endl;
 
503
        printf("%s\n",s);
452
504
}
453
505
 
454
506
void GLECairoDevice::move(double zx,double zy) {
506
558
        g_cur_fill.l = f;
507
559
}
508
560
 
 
561
void GLECairoDevice::set_background(int b) {
 
562
        m_Background = b;
 
563
}
 
564
 
 
565
void GLECairoDevice::set_fill_method(int m) {
 
566
        m_FillMethod = m;
 
567
}
 
568
 
509
569
void GLECairoDevice::set_pattern_color(int c) {
510
 
        cout << "set_pattern_color not yet implemented" << endl;
 
570
        g_cur_fill_color.l = c;
511
571
}
512
572
 
513
573
void GLECairoDevice::set_line_cap(int i) {
545
605
}
546
606
 
547
607
void GLECairoDevice::set_line_styled(double dd) {
548
 
        //cout << "set_line_styled not yet implemented" << endl;
 
608
        // no need to implement: set_line_style gets this from context
 
609
        // FIXME: rather: should call set_line_style again?
549
610
}
550
611
 
551
612
void GLECairoDevice::set_line_width(double w) {
556
617
}
557
618
 
558
619
void GLECairoDevice::set_matrix(double newmat[3][3]) {
559
 
    cairo_matrix_t matrix;
560
 
    matrix.xx = newmat[0][0];
561
 
    matrix.xy = newmat[0][1];
562
 
    matrix.yx = - newmat[1][0];
563
 
    matrix.yy = - newmat[1][1];
564
 
    matrix.x0 = newmat[0][2];
565
 
    matrix.y0 = m_height * 72 / CM_PER_INCH - newmat[1][2];
566
 
    cairo_set_matrix(cr, &matrix);
 
620
        cairo_matrix_t matrix;
 
621
        matrix.xx = newmat[0][0];
 
622
        matrix.xy = newmat[0][1];
 
623
        matrix.yx = - newmat[1][0];
 
624
        matrix.yy = - newmat[1][1];
 
625
        matrix.x0 = newmat[0][2];
 
626
        matrix.y0 = m_height * 72 / CM_PER_INCH - newmat[1][2];
 
627
        cairo_set_matrix(cr, &matrix);
567
628
}
568
629
 
569
630
void GLECairoDevice::set_path(int onoff) {
575
636
}
576
637
 
577
638
void GLECairoDevice::stroke(void) {
578
 
        //cairo_save(cr);
579
 
        //cairo_stroke(cr);
580
 
        //cairo_restore(cr);
581
639
        cairo_stroke_preserve(cr);
582
640
}
583
641
 
618
676
        m_height = height;
619
677
        m_OutputName.copy(outputfile);
620
678
        m_OutputName.addExtension("svg");
621
 
    surface = cairo_svg_surface_create(m_OutputName.getFullPath().c_str(), 72*width/CM_PER_INCH+2, 72*height/CM_PER_INCH+2);
 
679
        surface = cairo_svg_surface_create(m_OutputName.getFullPath().c_str(), 72*width/CM_PER_INCH+2, 72*height/CM_PER_INCH+2);
622
680
        cr = cairo_create(surface);
623
681
        g_scale(72.0/CM_PER_INCH, 72.0/CM_PER_INCH);
624
 
        g_translate(1.0*CM_PER_INCH/72, 1.0*CM_PER_INCH/72);
 
682
        g_translate(1.0*CM_PER_INCH/72, -1.0*CM_PER_INCH/72);
625
683
}
626
684
 
627
685
int GLECairoDeviceSVG::getDeviceType() {
642
700
        surface = cairo_pdf_surface_create(m_OutputName.getFullPath().c_str(), 72*width/CM_PER_INCH+2, 72*height/CM_PER_INCH+2);
643
701
        cr = cairo_create(surface);
644
702
        g_scale(72.0/CM_PER_INCH, 72.0/CM_PER_INCH);
645
 
        g_translate(1.0*CM_PER_INCH/72, 1.0*CM_PER_INCH/72);
 
703
        g_translate(1.0*CM_PER_INCH/72, -1.0*CM_PER_INCH/72);
646
704
}
647
705
 
648
706
int GLECairoDevicePDF::getDeviceType() {
649
707
        return GLE_DEVICE_CAIRO_PDF;
650
708
}
651
709
 
 
710
#ifdef __WIN32__
 
711
 
 
712
#include <cairo-win32.h>
 
713
 
 
714
class GLECairoDeviceEMFWinInfo {
 
715
public:
 
716
        HDC hdc;
 
717
        bool shouldClose;
 
718
        GLECairoDeviceEMFWinInfo();
 
719
        ~GLECairoDeviceEMFWinInfo();
 
720
};
 
721
 
 
722
GLECairoDeviceEMFWinInfo::GLECairoDeviceEMFWinInfo() :
 
723
        shouldClose(false)
 
724
{
 
725
}
 
726
 
 
727
GLECairoDeviceEMFWinInfo::~GLECairoDeviceEMFWinInfo()
 
728
{
 
729
        if (shouldClose) {
 
730
                HENHMETAFILE meta = CloseEnhMetaFile(hdc);
 
731
                DeleteEnhMetaFile(meta);
 
732
        }
 
733
}
 
734
 
 
735
GLECairoDeviceEMF::GLECairoDeviceEMF(bool showerror) : GLECairoDevice(showerror) {
 
736
        m_WinInfo = new GLECairoDeviceEMFWinInfo();
 
737
        m_DPI = 1000;
 
738
        m_CopyClipboard = false;
 
739
}
 
740
 
 
741
GLECairoDeviceEMF::~GLECairoDeviceEMF() {
 
742
        delete m_WinInfo;
 
743
}
 
744
 
 
745
void GLECairoDeviceEMF::set_matrix(double newmat[3][3]) {
 
746
    cairo_matrix_t matrix;
 
747
    matrix.xx = newmat[0][0];
 
748
    matrix.xy = newmat[0][1];
 
749
    matrix.yx = - newmat[1][0];
 
750
    matrix.yy = - newmat[1][1];
 
751
    matrix.x0 = newmat[0][2];
 
752
    matrix.y0 = m_height * m_DPI/CM_PER_INCH - newmat[1][2];
 
753
    cairo_set_matrix(cr, &matrix);
 
754
}
 
755
 
 
756
void GLECairoDeviceEMF::opendev(double width, double height, GLEFileLocation* outputfile, const string& inputfile) throw(ParserError) {
 
757
        m_width = width;
 
758
        m_height = height;
 
759
        m_OutputName.copy(outputfile);
 
760
        m_OutputName.addExtension("emf");
 
761
        double myWidth = width + 2.0/72.0*CM_PER_INCH;
 
762
        double myHeight = height + 2.0/72.0*CM_PER_INCH;
 
763
        HDC hdcRef = GetDC(NULL);
 
764
        int iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE);    // iWidthMM is the display width in millimeters.
 
765
        int iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE);   // iHeightMM is the display height in millimeters.
 
766
        int iWidthPels = GetDeviceCaps(hdcRef, HORZRES);   // iWidthPels is the display width in pixels.
 
767
        int iHeightPels = GetDeviceCaps(hdcRef, VERTRES);  // iHeightPels is the display height in pixels.
 
768
        RECT dim;
 
769
        dim.left = 0;
 
770
        dim.top = 0;
 
771
        dim.right = (int)floor(1000.0 * myWidth + 0.5);
 
772
        dim.bottom = (int)floor(1000.0 * myHeight + 0.5);
 
773
        // cout << "dim.right = " << dim.right << endl;
 
774
        // cout << "dim.bottom = " << dim.bottom << endl;
 
775
        if (m_CopyClipboard) {
 
776
                m_WinInfo->hdc = CreateEnhMetaFile(hdcRef, NULL, &dim, NULL);
 
777
        } else {
 
778
                m_WinInfo->hdc = CreateEnhMetaFile(hdcRef, m_OutputName.getFullPath().c_str(), &dim, NULL);
 
779
        }
 
780
        ReleaseDC(NULL, hdcRef);
 
781
        if (m_WinInfo->hdc != NULL) {
 
782
                m_WinInfo->shouldClose = true;
 
783
        } else {
 
784
                g_throw_parser_error("error creating EMF file: '", m_OutputName.getFullPath().c_str(), "'");
 
785
        }
 
786
        // cout << "Width = " << iWidthMM << " mm = " << iWidthPels << " pixels" << endl;
 
787
        // cout << "Height = " << iHeightMM << " mm = " << iHeightPels << " pixels" << endl;
 
788
        int viewportWidth = (int)floor(10.0 * myWidth * iWidthPels / iWidthMM + 0.5);
 
789
        int viewportHeight = (int)floor(10.0 * myHeight * iHeightPels / iHeightMM + 0.5);
 
790
        // cout << "Viewport width in pixels = " << viewportWidth << endl;
 
791
        // cout << "Viewport height in pixels = " << viewportHeight << endl;
 
792
        int windowWidth = (int)floor(myWidth * m_DPI / CM_PER_INCH + 0.5);
 
793
        int windowHeight = (int)floor(myHeight * m_DPI / CM_PER_INCH + 0.5);
 
794
        // cout << "Window width in pixels = " << windowWidth << endl;
 
795
        // cout << "Window height in pixels = " << windowHeight << endl;
 
796
        SetMapMode(m_WinInfo->hdc, MM_ANISOTROPIC);
 
797
        SetWindowOrgEx(m_WinInfo->hdc, 0, 0, NULL);
 
798
        SetWindowExtEx(m_WinInfo->hdc, windowWidth, windowHeight, NULL);
 
799
        SetViewportExtEx(m_WinInfo->hdc, viewportWidth, viewportHeight, NULL);
 
800
        surface = cairo_win32_printing_surface_create(m_WinInfo->hdc);
 
801
        cr = cairo_create(surface);
 
802
        g_scale(m_DPI/CM_PER_INCH, m_DPI/CM_PER_INCH);
 
803
        g_translate(1.0*CM_PER_INCH/72, 1.0*CM_PER_INCH/72);
 
804
}
 
805
 
 
806
BOOL PutEnhMetafileOnClipboard(HWND hWnd, HENHMETAFILE hEMF) {
 
807
        BOOL bResult = false;
 
808
        HENHMETAFILE hEMF2 = CopyEnhMetaFile(hEMF, NULL);
 
809
        if (hEMF2 != NULL) {
 
810
                if (OpenClipboard(hWnd)) {
 
811
                        if (EmptyClipboard()) {
 
812
                                HANDLE hRes = (HENHMETAFILE)SetClipboardData(CF_ENHMETAFILE, hEMF2);
 
813
                                bResult = (hRes != NULL);
 
814
                        }
 
815
                        CloseClipboard();
 
816
                }
 
817
        }
 
818
        return bResult;
 
819
}
 
820
 
 
821
void GLECairoDeviceEMF::closedev(void) {
 
822
        GLECairoDevice::closedev();
 
823
        HENHMETAFILE meta = CloseEnhMetaFile(m_WinInfo->hdc);
 
824
        if (meta == NULL) {
 
825
                return;
 
826
        }
 
827
        if (m_CopyClipboard) {
 
828
                PutEnhMetafileOnClipboard(NULL, meta);
 
829
        }
 
830
        DeleteEnhMetaFile(meta);
 
831
        m_WinInfo->shouldClose = false;
 
832
}
 
833
 
 
834
int GLECairoDeviceEMF::getDeviceType() {
 
835
        return GLE_DEVICE_EMF;
 
836
}
 
837
 
 
838
#endif
 
839
 
652
840
#endif