Tweak themes for more color consistency.
[ntk.git] / src / Fl_Cairo_Graphics_Driver.cxx
blob93bc66aa476e2bfb59bb5b6560a05abd11e037b5
2 /*******************************************************************************/
3 /* Copyright (C) 2012 Jonathan Moore Liles */
4 /* */
5 /* This program is free software; you can redistribute it and/or modify it */
6 /* under the terms of the GNU Library General Public License as published */
7 /* by the Free Software Foundation; either version 2 of the License, or (at */
8 /* your option) any later version. */
9 /* */
10 /* This program is distributed in the hope that it will be useful, but WITHOUT */
11 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
12 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
13 /* more details. */
14 /* */
15 /* You should have received a copy of the GNU General Public License along */
16 /* with This program; see the file COPYING. If not,write to the Free Software */
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /*******************************************************************************/
21 /* This class emulates the FLTK graphics drawing API using the Cairo
22 * library. The advantage of doing this is that it provides
23 * antialiasing and transparency on X11 for all FLTK widgets.
25 * The implementation inherits from the Xlib driver and attempts to
26 * keep colors, clipping, and matrix transformations in sync, so that
27 * calls to the base Xlib and Cairo routines can be mixed with the
28 * expected results.
30 * Fonts are still rendered using XFT. And since the FLTK image
31 * drawing implementation already uses XRender, there would seem to be
32 * little advantage to using Cairo for that either.
34 * Alpha values can be encoded into Fl_Color values by using the new
35 * fl_color_add_alpha function--with the caveat that 100% transparency
36 * (an Alpha of 0) is unsupported. This allows existing boxes and
37 * widgets to be drawn with transparency simply by setting their
38 * color() to one with an alpha value encoded.
40 * Antialiasing can be turned on and off with the new
41 * fl_set_antialias() function. However, it should be noted that, even
42 * with antialiasing disabled drawing complex lines and polygons is
43 * still significantly slower with Cairo than with the base FLTK
44 * routines.
48 #include <config.h>
49 #include <FL/Fl.H>
51 double fl_hxo = 0.0;
52 double fl_hyo = 0.5;
53 double fl_vxo = 0.5;
54 double fl_vyo = 0.0;
55 double fl_vho = 1.0;
56 double fl_hwo = 1.0;
58 #define HXO(n) ( n + fl_hxo )
59 #define HYO(n) ( n + fl_hyo )
60 #define VXO(n) ( n + fl_vxo )
61 #define VYO(n) ( n + fl_vyo )
62 #define VHO(n) ( n + fl_vho )
63 #define HWO(n) ( n + fl_hwo )
65 #define BSCALE 0.00392156862f
67 Fl_Color fl_color_add_alpha ( Fl_Color c, uchar alpha )
69 if ( !( c & 0xFFFFFF00 ) )
71 /* this is an indexed color or black */
72 if ( c & 0x000000FF )
74 /* this is an indexed color */
75 uchar r,g,b;
77 Fl::get_color( c, r, g, b );
79 c = fl_rgb_color( r, g, b );
81 else
83 /* this is black */
84 if ( 0 == alpha )
86 /* sorry, you can't have zero opacity because we don't
87 * have enough bits and it doesn't make much sense anyway */
88 alpha = 255;
90 /* hack to represent black */
91 c = 0x01010100;
95 return ( c & 0xFFFFFF00 ) | alpha;
98 #include <FL/x.H>
99 #include <cairo/cairo.h>
100 #include <FL/Fl_Cairo.H>
101 #include <FL/fl_draw.H>
102 #include <math.h>
103 #include <FL/Fl_Device.H>
105 static double lw = 1;
106 static double hlw;
107 //static cairo_antialias_t aa = CAIRO_ANTIALIAS_GRAY;
109 static int npoints = 0;
111 cairo_matrix_t Fl_Cairo_Graphics_Driver::m;
112 cairo_matrix_t Fl_Cairo_Graphics_Driver::stack[FL_MATRIX_STACK_SIZE];
113 int Fl_Cairo_Graphics_Driver::sptr;
115 #define cairo_set_antialias( cr, aa )
117 Fl_Cairo_Graphics_Driver::Fl_Cairo_Graphics_Driver ( ) : Fl_Xlib_Graphics_Driver ()
119 // rstackptr = 0;
122 /* void Fl_Cairo_Graphics_Driver::set_current ( void ) */
123 /* { */
124 /* Window root; */
126 /* int x, y; */
127 /* unsigned int w, h, bw, d; */
129 /* XGetGeometry( fl_display, fl_window, &root, &x, &y, &w, &h, &bw, &d ); */
131 /* fl_cairo_surface = cairo_create_surface( fl_gc, w, h ); */
133 /* /\* FIXME: how are we going to free this? *\/ */
134 /* fl_cairo_context = cairo_create( fl_cairo_surface ); */
136 /* cairo_surface_destroy( fl_cairo_surface ); */
138 /* fl_cairo_surface = 0; */
139 /* } */
142 #define set_cairo_matrix() \
144 cairo_t *cr = fl_cairo_context; \
145 if ( sptr ) \
146 cairo_set_matrix( cr, &m ); \
147 else \
148 cairo_identity_matrix( cr ); \
151 #define restore_cairo_matrix() \
153 cairo_t *cr = fl_cairo_context; \
154 cairo_identity_matrix( cr ); \
158 void Fl_Cairo_Graphics_Driver::push_matrix ( void )
160 cairo_t *cr = Fl::cairo_cc();
162 cairo_get_matrix( cr, &m );
164 if (sptr==FL_MATRIX_STACK_SIZE)
165 Fl::error("fl_push_matrix(): matrix stack overflow.");
166 else
167 stack[sptr++] = m;
170 void Fl_Cairo_Graphics_Driver::pop_matrix ( void )
172 if (sptr==0)
173 Fl::error("fl_pop_matrix(): matrix stack underflow.");
174 else
175 m = stack[--sptr];
177 set_cairo_matrix();
180 void Fl_Cairo_Graphics_Driver::translate ( double x, double y )
182 cairo_matrix_translate( &m, x, y );
184 set_cairo_matrix();
187 void Fl_Cairo_Graphics_Driver::scale ( double x, double y )
189 cairo_matrix_scale( &m, x, y );
191 set_cairo_matrix();
194 void Fl_Cairo_Graphics_Driver::rotate ( double a )
196 cairo_matrix_rotate( &m, a * ( M_PI / 180.0 ) );
198 set_cairo_matrix();
201 void Fl_Cairo_Graphics_Driver::mult_matrix ( double a, double b, double c, double d, double x, double y )
203 cairo_matrix_t m2;
205 cairo_matrix_init( &m2, a, b, c, d, x, y );
207 cairo_matrix_multiply( &m, &m2, &m );
209 set_cairo_matrix();
212 void Fl_Cairo_Graphics_Driver::line_style ( int style, int t, char* )
214 cairo_t *cr = Fl::cairo_cc();
216 if ( t == 0 || t == 1 )
218 double w1, w2;
219 w1 = w2 = 1.0;
220 cairo_device_to_user_distance (cr, &w1, &w2);
221 lw = w1 > w2 ? w1 : w2;
223 else
224 lw = t;
226 hlw = lw / 2.0;
228 cairo_set_line_width( cr, lw );
230 cairo_set_line_cap( cr, CAIRO_LINE_CAP_BUTT );
232 if ( style & FL_DASH )
234 const double dash[] = { lw, lw };
235 int len = sizeof(dash) / sizeof(dash[0]);
237 cairo_set_dash( cr, dash, len, 0 );
239 else if ( style & FL_DOT )
241 const double dash[] = { lw, lw };
242 int len = sizeof(dash) / sizeof(dash[0]);
244 cairo_set_dash( cr, dash, len, 0 );
246 cairo_set_line_cap( cr, CAIRO_LINE_CAP_ROUND );
248 else
250 cairo_set_dash( cr, NULL, 0, 0 );
254 void Fl_Cairo_Graphics_Driver::color ( Fl_Color c )
256 uchar r,g,b;
258 Fl_Xlib_Graphics_Driver::color( c );
260 if ( ( c & 0x000000ff ) && ! ( c & 0xFFFFFF00 ) )
262 /* color is indexed, get the RGB value */
263 Fl::get_color( c, r, g, b );
265 /* FIXME: temp! */
266 color( r, g, b );
267 /* color( 255, 0, 0, 50 ); */
269 else
271 Fl::get_color( c & 0xFFFFFF00, r, g, b );
273 /* lower 8 bits become alpha. */
274 uchar a = c & 0x000000ff;
276 if ( ! a )
277 a = 255;
279 /* /\* HACK to represent black *\/ */
280 /* if ( ( c & 0xFFFFFF00 ) == 0x01010100 ) */
281 /* r = g = b = 0; */
283 color( r, g, b, a );
287 void Fl_Cairo_Graphics_Driver::color ( uchar r, uchar g, uchar b )
289 cairo_t *cr = Fl::cairo_cc();
291 Fl_Xlib_Graphics_Driver::color( r, g, b );
293 if ( ! cr )
294 return;
296 cairo_set_source_rgb( cr, r * BSCALE, g * BSCALE, b * BSCALE );
299 void fl_set_antialias ( int v )
301 switch ( v )
303 case FL_ANTIALIAS_DEFAULT:
304 cairo_set_antialias( cr, aa = CAIRO_ANTIALIAS_DEFAULT );
305 break;
306 case FL_ANTIALIAS_ON:
307 cairo_set_antialias( cr, aa = CAIRO_ANTIALIAS_GRAY );
308 break;
309 case FL_ANTIALIAS_OFF:
310 cairo_set_antialias( cr, aa = CAIRO_ANTIALIAS_NONE );
311 break;
316 void Fl_Cairo_Graphics_Driver::color ( Fl_Color c, uchar a )
318 uchar r,g,b;
320 Fl::get_color( c, r, g, b );
322 Fl_Xlib_Graphics_Driver::color( c );
324 color( r, g, b, a);
327 void Fl_Cairo_Graphics_Driver::color (uchar r, uchar g, uchar b, uchar a )
329 cairo_t *cr = Fl::cairo_cc();
331 // Fl_Xlib_Graphics_Driver::color( r, g, b );
333 if ( ! cr )
334 return;
336 cairo_set_source_rgba( cr, r * BSCALE, g * BSCALE, b * BSCALE, a * BSCALE );
339 void Fl_Cairo_Graphics_Driver::circle( double x, double y, double r )
341 cairo_t *cr = Fl::cairo_cc();
343 cairo_arc( cr, x, y, r, 0, 2.0f * M_PI );
345 restore_cairo_matrix();
347 if ( what == POLYGON )
348 cairo_fill( cr );
349 else
350 cairo_stroke( cr );
352 set_cairo_matrix();
355 /* static void add_arc( int x, int y, int w, int h, double a1, double a2 ) */
356 /* { */
357 /* cairo_t *cr = Fl::cairo_cc(); */
359 /* /\* const double line_width = cairo_get_line_width( cr ); *\/ */
361 /* const double cx = x + ( 0.5f * w ); */
362 /* const double cy = y + ( 0.5f * h ); */
364 /* /\* cairo_save( cr ); *\/ */
365 /* /\* cairo_translate( cr, cx, cy ); *\/ */
366 /* /\* cairo_scale( cr, w, h ); *\/ */
368 /* /\* if ( a1 > a2 ) *\/ */
369 /* /\* cairo_arc( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 )); *\/ */
370 /* /\* else *\/ */
371 /* /\* cairo_arc_negative( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 )); *\/ */
374 /* cairo_save( cr ); */
375 /* cairo_translate( cr, cx, cy ); */
376 /* cairo_scale( cr, w - 1, h - 1 ); */
378 /* if ( a1 > a2 ) */
379 /* cairo_arc( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 )); */
380 /* else */
381 /* cairo_arc_negative( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 )); */
384 /* cairo_restore( cr ); */
385 /* } */
387 static void add_arc( int x, int y, int w, int h, double a1, double a2, bool pie )
389 cairo_t *cr = Fl::cairo_cc();
391 double a1R = a1 * ( M_PI / 180.0 );
392 double a2R = a2 * ( M_PI / 180.0 );
394 double cx = x + 0.5 * w, cy = y + 0.5 * h;
396 cairo_save( cr );
398 cairo_translate( cr, cx, cy );
399 // cairo_scale( cr, (w - lw), 0 - ((h - lw) ));
400 cairo_scale( cr, w, 0 - h );
402 if ( a1 > a2 )
403 cairo_arc_negative( cr, 0.0, 0.0, 0.5, a1R, a2R );
404 else
405 cairo_arc( cr, 0.0, 0.0, 0.5, a1R, a2R );
407 if ( pie )
409 cairo_line_to( cr, 0, 0 );
410 cairo_close_path( cr );
413 cairo_restore( cr );
416 void Fl_Cairo_Graphics_Driver::arc( int x, int y, int w, int h, double a1, double a2 )
418 cairo_t *cr = Fl::cairo_cc();
420 add_arc( x, y, w, h, a1, a2, false );
422 restore_cairo_matrix();
424 cairo_stroke( cr );
426 set_cairo_matrix();
429 void Fl_Cairo_Graphics_Driver::arc( double x, double y, double r, double a1, double a2 )
431 cairo_t *cr = Fl::cairo_cc();
433 cairo_close_path( cr );
435 cairo_arc( cr, x, y, r, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 ));
438 void Fl_Cairo_Graphics_Driver::pie( int x, int y, int w, int h, double a1, double a2 )
440 cairo_t *cr = Fl::cairo_cc();
442 add_arc( x, y, w, h, a1, a2, true );
444 restore_cairo_matrix();
446 cairo_fill( cr );
448 set_cairo_matrix();
451 void Fl_Cairo_Graphics_Driver::line( int x1, int y1, int x2, int y2 )
453 cairo_t *cr = Fl::cairo_cc();
455 cairo_set_line_width( cr, lw );
457 // restore_cairo_matrix();
459 if ( x1 == x2 )
461 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
462 /* vertical line */
464 if ( y1 > y2 )
466 int t = y2;
467 y2 = y1;
468 y1 = t;
471 cairo_move_to( cr, VXO( x1 ), VYO( y1 ) );
472 cairo_line_to( cr, VXO( x2 ), VHO( y2 ) );
474 else if ( y1 == y2 )
476 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
477 /* horizontal line */
478 cairo_move_to( cr, HXO( x1 ), HYO( y1 ) );
479 cairo_line_to( cr, HWO( x2 ), HYO( y2 ) );
481 else
483 /* diagonal line */
484 cairo_move_to( cr, x1 , y1 );
485 cairo_line_to( cr, x2 , y2 );
488 cairo_stroke( cr );
490 // set_cairo_matrix();
492 cairo_set_antialias( cr, aa );
495 void Fl_Cairo_Graphics_Driver::line( int x1, int y1, int x2, int y2, int x3, int y3 )
497 cairo_t *cr = Fl::cairo_cc();
499 cairo_set_line_width( cr, lw );
501 if ( lw <= 1 )
503 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
506 // restore_cairo_matrix();
508 cairo_move_to( cr, x1 , y1 );
509 cairo_line_to( cr, x2 , y2 );
510 cairo_line_to( cr, x3 , y3 );
512 cairo_stroke( cr );
514 // set_cairo_matrix();
516 cairo_set_antialias( cr, aa );
520 void Fl_Cairo_Graphics_Driver::rect ( int x, int y, int w, int h )
522 cairo_t *cr = Fl::cairo_cc();
524 cairo_set_line_width( cr, lw );
526 /* cairo draws lines half inside and half outside of the path... */
528 /* const double line_width = cairo_get_line_width( cr ); */
529 /* const double o = line_width / 2.0; */
531 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
533 // restore_cairo_matrix();
535 // cairo_rectangle( cr, x + hlw, y + hlw, w - lw - 1, h - lw - 1);
536 cairo_rectangle( cr, VXO( x ), HYO( y ), w - 1, h - 1 );
539 cairo_stroke( cr );
541 // set_cairo_matrix();
543 cairo_set_antialias( cr, aa );
546 void Fl_Cairo_Graphics_Driver::rectf ( int x, int y, int w, int h )
548 cairo_t *cr = Fl::cairo_cc();
550 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
552 // restore_cairo_matrix();
554 /* cairo fills the inside of the path... */
555 cairo_rectangle( cr, x, y, w, h );
557 cairo_fill( cr );
559 // set_cairo_matrix();
561 cairo_set_antialias( cr, aa );
565 void Fl_Cairo_Graphics_Driver::begin_line ( void )
567 what = LINE;
568 npoints = 0;
571 void Fl_Cairo_Graphics_Driver::begin_points ( void )
573 what = POINT_;
574 npoints = 0;
577 void Fl_Cairo_Graphics_Driver::begin_polygon ( void )
579 what = POLYGON;
580 npoints = 0;
583 void Fl_Cairo_Graphics_Driver::begin_loop ( void )
585 what = LOOP;
586 npoints = 0;
589 void Fl_Cairo_Graphics_Driver::begin_complex_polygon ( void )
591 what = POLYGON;
592 npoints = 0;
595 void Fl_Cairo_Graphics_Driver::end_line ( void )
597 cairo_t *cr = Fl::cairo_cc();
599 if ( lw <= 1 )
601 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
604 cairo_set_line_width( cr, lw );
606 restore_cairo_matrix();
608 cairo_stroke( cr );
610 set_cairo_matrix();
612 cairo_set_antialias( cr, aa );
615 void Fl_Cairo_Graphics_Driver::end_points ( void )
617 cairo_t *cr = Fl::cairo_cc();
619 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
621 cairo_fill( cr );
623 cairo_set_antialias( cr, aa );
626 void Fl_Cairo_Graphics_Driver::end_loop ( void )
628 if ( npoints < 3 )
630 end_line();
631 return;
634 cairo_t *cr = Fl::cairo_cc();
635 cairo_close_path( cr );
636 end_line();
640 /* static double last_vertex_x; */
641 /* static double last_vertex_y; */
643 void Fl_Cairo_Graphics_Driver::vertex ( double x, double y )
645 cairo_t *cr = Fl::cairo_cc();
647 if ( !npoints )
648 cairo_move_to( cr, x, y );
649 else
650 cairo_line_to( cr, x, y );
652 ++npoints;
655 void Fl_Cairo_Graphics_Driver::gap ( void )
657 npoints = 0;
660 void Fl_Cairo_Graphics_Driver::end_complex_polygon ( void )
662 if ( npoints < 3 )
664 end_line();
665 return;
668 cairo_t *cr = Fl::cairo_cc();
670 cairo_close_path( cr );
672 restore_cairo_matrix();
674 cairo_fill( cr );
676 set_cairo_matrix();
679 void Fl_Cairo_Graphics_Driver::end_polygon ( void )
681 if ( npoints < 3 )
683 end_line();
684 return;
687 cairo_t *cr = Fl::cairo_cc();
689 cairo_close_path( cr );
691 restore_cairo_matrix();
693 cairo_fill( cr );
695 set_cairo_matrix();
698 void Fl_Cairo_Graphics_Driver::curve( double x, double y, double x1, double y1, double x2, double y2, double x3, double y3 )
700 cairo_t *cr = Fl::cairo_cc();
702 cairo_move_to( cr, x, y );
703 cairo_curve_to( cr, x1, y1, x2, y2, x3, y3 );
706 void Fl_Cairo_Graphics_Driver::polygon ( int x, int y, int x1, int y1, int x2, int y2 )
708 cairo_t *cr = Fl::cairo_cc();
710 cairo_move_to( cr, x , y );
711 cairo_line_to( cr, x1 , y1 );
712 cairo_line_to( cr, x2 , y2 );
713 cairo_close_path( cr );
714 cairo_fill( cr );
717 void Fl_Cairo_Graphics_Driver::polygon ( int x, int y, int x1, int y1, int x2, int y2, int x3, int y3 )
719 cairo_t *cr = Fl::cairo_cc();
721 cairo_move_to( cr, x , y );
722 cairo_line_to( cr, x1 , y1 );
723 cairo_line_to( cr, x2 , y2 );
724 cairo_line_to( cr, x3 , y3 );
725 cairo_close_path( cr );
726 cairo_fill( cr );
729 void Fl_Cairo_Graphics_Driver::loop ( int x, int y, int x1, int y1, int x2, int y2 )
731 cairo_t *cr = Fl::cairo_cc();
733 cairo_move_to( cr, x , y );
734 cairo_line_to( cr, x1 , y1 );
735 cairo_line_to( cr, x2 , y2 );
736 cairo_close_path( cr );
737 cairo_stroke( cr );
740 void Fl_Cairo_Graphics_Driver::loop ( int x, int y, int x1, int y1, int x2, int y2, int x3, int y3 )
742 cairo_t *cr = Fl::cairo_cc();
744 cairo_move_to( cr, x , y );
745 cairo_line_to( cr, x1 , y1 );
746 cairo_line_to( cr, x2 , y2 );
747 cairo_line_to( cr, x3 , y3 );
748 cairo_close_path( cr );
749 cairo_stroke( cr );
753 void Fl_Cairo_Graphics_Driver::xyline ( int x, int y, int x1 )
755 cairo_t *cr = Fl::cairo_cc();
757 cairo_set_line_width( cr, lw );
760 if ( lw <= 1 )
762 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
765 cairo_move_to( cr, HXO( x ), HYO( y ) );
766 cairo_line_to( cr, HWO( x1 ), HYO( y ) );
768 cairo_stroke( cr );
770 cairo_set_antialias( cr, aa );
773 void Fl_Cairo_Graphics_Driver::xyline ( int x, int y, int x1, int y2 )
775 cairo_t *cr = Fl::cairo_cc();
777 cairo_set_line_width( cr, lw );
779 if ( lw <= 1 )
781 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
784 /* horizontal line */
785 cairo_move_to( cr, HXO( x ) , HYO( y ) );
786 cairo_line_to( cr, HWO( x1 ), HYO( y ) );
787 /* then vertical line */
788 cairo_line_to( cr, HWO( x1 ) , VYO( y2 ) );
790 cairo_stroke( cr );
792 cairo_set_antialias( cr, aa );
796 void Fl_Cairo_Graphics_Driver::xyline ( int x, int y, int x1, int y2, int x3 )
798 cairo_t *cr = Fl::cairo_cc();
800 if ( lw <= 1 )
802 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
805 cairo_move_to( cr, x , y );
806 cairo_line_to( cr, x1 , y );
807 cairo_line_to( cr, x1 , y2 );
808 cairo_line_to( cr, x3 , y2 );
810 cairo_stroke( cr );
812 cairo_set_antialias( cr, aa );
815 void Fl_Cairo_Graphics_Driver::yxline ( int x, int y, int y1 )
817 cairo_t *cr = Fl::cairo_cc();
819 cairo_set_line_width( cr, lw );
821 if ( lw <= 1 )
823 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
826 cairo_move_to( cr, VXO( x ), VHO( y ) );
827 cairo_line_to( cr, VXO( x ), VYO( y1 ) );
829 cairo_stroke( cr );
831 cairo_set_antialias( cr, aa );
834 void Fl_Cairo_Graphics_Driver::yxline ( int x, int y, int y1, int x2 )
836 cairo_t *cr = Fl::cairo_cc();
838 if ( lw <= 1 )
840 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
843 cairo_move_to( cr, x , y );
844 cairo_line_to( cr, x, y1 );
845 cairo_line_to( cr, x2, y1 );
847 cairo_stroke( cr );
849 cairo_set_antialias( cr, aa );
852 void Fl_Cairo_Graphics_Driver::yxline ( int x, int y, int y1, int x2, int y3 )
854 cairo_t *cr = Fl::cairo_cc();
856 if ( lw <= 1 )
858 cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
861 cairo_move_to( cr, x , y );
862 cairo_line_to( cr, x , y1 );
863 cairo_line_to( cr, x2 , y1 );
864 cairo_line_to( cr, x2 , y3 );
866 cairo_stroke( cr );
868 cairo_set_antialias( cr, aa );
871 static int start(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy,
872 int &X, int &Y, int &W, int &H)
874 fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
876 cx += X-XP; cy += Y-YP;
877 // clip the box down to the size of image, quit if empty:
878 if (cx < 0) {W += cx; X -= cx; cx = 0;}
879 if (cx+W > w) W = w-cx;
880 if (W <= 0) return 1;
881 if (cy < 0) {H += cy; Y -= cy; cy = 0;}
882 if (cy+H > h) H = h-cy;
883 if (H <= 0) return 1;
885 return 0;
888 void
889 Fl_Cairo_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy)
891 int X, Y, W, H;
893 // Don't draw an empty image...
894 if (!img->d() || !img->array) {
895 // img->draw_empty(XP, YP);
896 return;
899 if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) {
900 return;
903 /* if (!img->id_) { */
904 /* img->id_ = fl_create_offscreen(img->w(), img->h()); */
905 /* if ((img->d() == 2 || img->d() == 4) ) { */
906 /* fl_begin_offscreen((Fl_Offscreen)img->id_); */
907 /* fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d()|FL_IMAGE_WITH_ALPHA, img->ld()); */
908 /* fl_end_offscreen(); */
909 /* } */
910 /* } */
912 cairo_t *cr = Fl::cairo_cc();
914 cairo_format_t fmt = CAIRO_FORMAT_ARGB32;
916 switch (img->d() )
918 case 4:
919 fmt = CAIRO_FORMAT_ARGB32;
920 break;
921 case 3:
922 fmt = CAIRO_FORMAT_RGB24;
923 break;
924 case 1:
925 fmt = CAIRO_FORMAT_A8;
926 break;
929 /* cairo_save( cr ); */
931 /* cairo_reset_clip( cr ); */
933 cairo_surface_t *image = cairo_image_surface_create_for_data( (unsigned char *)img->array, fmt, img->w(), img->h( ),
934 cairo_format_stride_for_width( fmt, img->w() ) );
936 /* cairo_surface_t *image = cairo_image_surface_create_for_data( (unsigned char *)img->array, fmt, img->w(), img->h(), img->ld() ); */
939 /* cairo_patter_t *pat = cairo_surface_pattern( image ); */
941 /* cairo_matrix_t matr; */
943 /* cairo_matrix_scale( &matr, */
945 cairo_set_source_surface( cr, image, X - cx, Y - cy );
947 cairo_rectangle( cr, X, Y, W, H );
949 cairo_fill(cr);
951 cairo_surface_destroy( image );
953 /* cairo_restore( cr ); */