283
void GLECairoDevice::shade(void) {
284
cout << "shade not yet implemented" << endl;
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);
291
cout << xstep << endl;
292
cout << ystep << endl;
294
cairo_surface_t *isurface;
295
cairo_pattern_t *pattern;
297
cairo_matrix_t matrix;
296
cairo_matrix_t matrix;
300
297
cairo_get_matrix(cr, &matrix);
302
isurface = cairo_surface_create_similar (surface, CAIRO_CONTENT_COLOR_ALPHA, xstep, ystep);
303
icr = cairo_create(isurface);
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));
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);
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);
308
cairo_rectangle(icr, -1, -1, (xstep+1), (ystep+1));
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);
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);
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]);
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);
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);
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);
373
pattern = cairo_pattern_create_for_surface (isurface);
374
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
376
cairo_matrix_init_scale (&matrix, 3*72, 3*72);
377
cairo_pattern_set_matrix (pattern, &matrix);
379
cairo_set_source (cr, pattern);
384
cairo_pattern_destroy (pattern);
386
cairo_surface_destroy (isurface);
391
cairo_surface_t *image;
392
cairo_pattern_t *pattern;
393
cairo_matrix_t matrix;
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);
399
pattern = cairo_pattern_create_for_surface (image);
400
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
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);
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);
413
cairo_set_source (cr, pattern);
415
//cairo_rectangle (cr, 0, 0, 256.0, 256.0);
416
cairo_fill_preserve (cr);
418
cairo_pattern_destroy (pattern);
419
cairo_surface_destroy (image);
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);
351
cairo_pattern_destroy(pattern);
353
cairo_surface_destroy(isurface);
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;
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);
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);
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()) {
379
cairo_line_to(cr, bounds->getYMax()-p*step1, bounds->getYMax());
382
cairo_line_to(cr, bounds->getXMax(), bounds->getXMax()+p*step1);
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()) {
391
cairo_line_to(cr, p*step2-bounds->getYMax(), bounds->getYMax());
394
cairo_line_to(cr, bounds->getXMin(), p*step2-bounds->getXMin());
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);
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--) {
412
cairo_move_to(cr, bounds->getXMin(), bounds->getXMin()+p*step1);
413
shadeBoundedIfThenElse1(bounds, p, step1);
415
for (int p = p1; p >= p2; p--) {
417
cairo_move_to(cr, bounds->getYMin()-p*step1, bounds->getYMin());
418
shadeBoundedIfThenElse1(bounds, p, step1);
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--) {
430
cairo_move_to(cr, bounds->getXMax(), p*step2-bounds->getXMax());
431
shadeBoundedIfThenElse2(bounds, p, step2);
433
for (int p = p1; p >= p2; p--) {
435
cairo_move_to(cr, p*step2-bounds->getYMin(), bounds->getYMin());
436
shadeBoundedIfThenElse2(bounds, p, step2);
441
void GLECairoDevice::shade(GLERectangle* bounds) {
442
if (m_FillMethod == GLE_FILL_METHOD_GLE ||
443
(m_FillMethod == GLE_FILL_METHOD_DEFAULT && bounds != NULL)) {
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);
450
col.l = m_Background;
453
cairo_fill_preserve(cr);
455
// Implemented by using path as clip and then painting strokes over the clip
458
if (g_cur_fill_color.l == GLE_COLOR_BLACK) {
459
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
461
set_color(g_cur_fill_color);
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);
423
475
void GLECairoDevice::fill_ary(int nwk,double *wkx,double *wky) {
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);
648
706
int GLECairoDevicePDF::getDeviceType() {
649
707
return GLE_DEVICE_CAIRO_PDF;
712
#include <cairo-win32.h>
714
class GLECairoDeviceEMFWinInfo {
718
GLECairoDeviceEMFWinInfo();
719
~GLECairoDeviceEMFWinInfo();
722
GLECairoDeviceEMFWinInfo::GLECairoDeviceEMFWinInfo() :
727
GLECairoDeviceEMFWinInfo::~GLECairoDeviceEMFWinInfo()
730
HENHMETAFILE meta = CloseEnhMetaFile(hdc);
731
DeleteEnhMetaFile(meta);
735
GLECairoDeviceEMF::GLECairoDeviceEMF(bool showerror) : GLECairoDevice(showerror) {
736
m_WinInfo = new GLECairoDeviceEMFWinInfo();
738
m_CopyClipboard = false;
741
GLECairoDeviceEMF::~GLECairoDeviceEMF() {
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);
756
void GLECairoDeviceEMF::opendev(double width, double height, GLEFileLocation* outputfile, const string& inputfile) throw(ParserError) {
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.
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);
778
m_WinInfo->hdc = CreateEnhMetaFile(hdcRef, m_OutputName.getFullPath().c_str(), &dim, NULL);
780
ReleaseDC(NULL, hdcRef);
781
if (m_WinInfo->hdc != NULL) {
782
m_WinInfo->shouldClose = true;
784
g_throw_parser_error("error creating EMF file: '", m_OutputName.getFullPath().c_str(), "'");
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);
806
BOOL PutEnhMetafileOnClipboard(HWND hWnd, HENHMETAFILE hEMF) {
807
BOOL bResult = false;
808
HENHMETAFILE hEMF2 = CopyEnhMetaFile(hEMF, NULL);
810
if (OpenClipboard(hWnd)) {
811
if (EmptyClipboard()) {
812
HANDLE hRes = (HENHMETAFILE)SetClipboardData(CF_ENHMETAFILE, hEMF2);
813
bResult = (hRes != NULL);
821
void GLECairoDeviceEMF::closedev(void) {
822
GLECairoDevice::closedev();
823
HENHMETAFILE meta = CloseEnhMetaFile(m_WinInfo->hdc);
827
if (m_CopyClipboard) {
828
PutEnhMetafileOnClipboard(NULL, meta);
830
DeleteEnhMetaFile(meta);
831
m_WinInfo->shouldClose = false;
834
int GLECairoDeviceEMF::getDeviceType() {
835
return GLE_DEVICE_EMF;