Browse Source

Cleanup Cairo support and improve drawing alignment.

tags/v1.3.1000
Jonathan Moore Liles 13 years ago
parent
commit
a95122a573
12 changed files with 364 additions and 179 deletions
  1. +2
    -0
      FL/Enumerations.H
  2. +2
    -14
      FL/Fl.H
  3. +3
    -39
      FL/Fl_Cairo.H
  4. +0
    -2
      FL/Fl_Cairo_Window.H
  5. +23
    -16
      FL/Fl_Device.H
  6. +1
    -1
      FL/fl_draw.H
  7. +5
    -6
      src/Fl_Cairo.cxx
  8. +261
    -88
      src/Fl_Cairo_Graphics_Driver.cxx
  9. +28
    -8
      src/Fl_Device.cxx
  10. +12
    -0
      src/Fl_arg.cxx
  11. +27
    -2
      src/Fl_x.cxx
  12. +0
    -3
      test/cairo_test.cxx

+ 2
- 0
FL/Enumerations.H View File

@@ -822,6 +822,8 @@ FL_EXPORT Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg);


FL_EXPORT Fl_Color fl_color_average(Fl_Color c1, Fl_Color c2, float weight); FL_EXPORT Fl_Color fl_color_average(Fl_Color c1, Fl_Color c2, float weight);


FL_EXPORT Fl_Color fl_color_add_alpha( Fl_Color c, uchar alpha );

/** Returns a lighter version of the specified color. */ /** Returns a lighter version of the specified color. */
inline Fl_Color fl_lighter(Fl_Color c) { return fl_color_average(c, FL_WHITE, .67f); } inline Fl_Color fl_lighter(Fl_Color c) { return fl_color_average(c, FL_WHITE, .67f); }




+ 2
- 14
FL/Fl.H View File

@@ -1057,27 +1057,15 @@ public:
You can use Fl::cairo_cc() to get the current cairo context anytime. You can use Fl::cairo_cc() to get the current cairo context anytime.
\note Only available when configure has the --enable-cairo option \note Only available when configure has the --enable-cairo option
*/ */
static void cairo_autolink_context(bool alink) {cairo_state_.autolink(alink);}
/**
Gets the current autolink mode for cairo support.
\retval false if no cairo context autolink is made for each window.
\retval true if any fltk window is attached a cairo context when it
is current. \see void cairo_autolink_context(bool alink)
\note Only available when configure has the --enable-cairo option
*/
static bool cairo_autolink_context() {return cairo_state_.autolink();}
/** Gets the current cairo context linked with a fltk window. */ /** Gets the current cairo context linked with a fltk window. */
static cairo_t * cairo_cc() { return cairo_state_.cc(); }
static cairo_t * cairo_cc() { return fl_cairo_context; }
/** Sets the current cairo context to \p c. /** Sets the current cairo context to \p c.
Set \p own to true if you want fltk to handle this cc deletion. Set \p own to true if you want fltk to handle this cc deletion.
\note Only available when configure has the --enable-cairo option \note Only available when configure has the --enable-cairo option
*/ */
static void cairo_cc(cairo_t * c, bool own=false){ cairo_state_.cc(c, own); }
// static void cairo_cc(cairo_t * c, bool own=false){ cairo_state_.cc(c, own); }


private: private:
/* static cairo_t * cairo_make_current(void* gc); */
/* static cairo_t * cairo_make_current(void* gc, int W, int H); */
static Fl_Cairo_State cairo_state_;
public: public:
/** @} */ /** @} */




+ 3
- 39
FL/Fl_Cairo.H View File

@@ -48,46 +48,10 @@
# error Cairo is not supported on that platform. # error Cairo is not supported on that platform.
# endif # endif


/**
\addtogroup group_cairo
@{
*/

/**
Contains all the necessary info on the current cairo context.
A private internal & unique corresponding object is created to
permit cairo context state handling while keeping it opaque.
For internal use only.
\note Only available when configure has the --enable-cairo option
*/
class FL_EXPORT Fl_Cairo_State {
public:
Fl_Cairo_State() : cc_(0), own_cc_(false), autolink_(true), window_(0), gc_(0) {}

// access attributes
cairo_t* cc() const {return cc_;} ///< Gets the current cairo context
bool autolink() const {return autolink_;} ///< Gets the autolink option. See Fl::cairo_autolink_context(bool)
/** Sets the current cairo context, \p own indicates cc deletion is handle externally by user */
void cc(cairo_t* c, bool own=true) {
if (cc_ && own_cc_) cairo_destroy(cc_);
cc_=c;
if (!cc_) window_=0;
own_cc_=own;
}
void autolink(bool b); ///< Sets the autolink option, only available with --enable-cairoext
void window(void* w) {window_=w;} ///< Sets the window \p w to keep track on
void* window() const {return window_;} ///< Gets the last window attached to a cc
void gc(void* c) {gc_=c;} ///< Sets the gc \p c to keep track on
void* gc() const {return gc_;} ///< Gets the last gc attached to a cc

private:
cairo_t * cc_; // contains the unique autoupdated cairo context
bool own_cc_; // indicates whether we must delete the cc, useful for internal cleanup
bool autolink_; // true by default, permits to prevent the automatic cairo mapping on fltk windows for custom cairo implementations
void* window_, *gc_; // for keeping track internally of last win+gc treated
};
FL_EXPORT extern cairo_surface_t *fl_cairo_surface;
FL_EXPORT extern cairo_t *fl_cairo_context;


/** @} */
cairo_surface_t * cairo_create_surface(void * gc, int W, int H);


# endif // FLTK_HAVE_CAIRO # endif // FLTK_HAVE_CAIRO




+ 0
- 2
FL/Fl_Cairo_Window.H View File

@@ -64,8 +64,6 @@ protected:
void draw() { void draw() {
Fl_Double_Window::draw(); Fl_Double_Window::draw();
// manual method ? if yes explicitly get a cairo_context here // manual method ? if yes explicitly get a cairo_context here
if (!Fl::cairo_autolink_context())
Fl::cairo_make_current(this);
if (draw_cb_) draw_cb_(this, Fl::cairo_cc()); if (draw_cb_) draw_cb_(this, Fl::cairo_cc());
} }




+ 23
- 16
FL/Fl_Device.H View File

@@ -116,28 +116,34 @@ public:
struct matrix {double a, b, c, d, x, y;}; struct matrix {double a, b, c, d, x, y;};
private: private:
static const matrix m0; static const matrix m0;
Fl_Font font_; // current font
Fl_Fontsize size_; // current font size
Fl_Color color_; // current color
int sptr;
static Fl_Font font_; // current font
static Fl_Fontsize size_; // current font size
static Fl_Color color_; // current color
static int sptr;
static const int matrix_stack_size = FL_MATRIX_STACK_SIZE; static const int matrix_stack_size = FL_MATRIX_STACK_SIZE;
matrix stack[FL_MATRIX_STACK_SIZE];
matrix m;
static matrix stack[FL_MATRIX_STACK_SIZE];
static matrix m;
protected: protected:
enum {LINE, LOOP, POLYGON, POINT_}; enum {LINE, LOOP, POLYGON, POINT_};
int n, p_size, gap_;
XPOINT *p;
int what;
static int n;
static int p_size;
static int gap_;
static XPOINT *p;
static int what;
private: private:
int fl_clip_state_number;
int rstackptr;
static int fl_clip_state_number;
static int rstackptr;
static const int region_stack_max = FL_REGION_STACK_SIZE - 1; static const int region_stack_max = FL_REGION_STACK_SIZE - 1;
Fl_Region rstack[FL_REGION_STACK_SIZE];
static Fl_Region rstack[FL_REGION_STACK_SIZE];
#ifdef WIN32 #ifdef WIN32
int numcount; int numcount;
int counts[20]; int counts[20];
#endif #endif
Fl_Font_Descriptor *font_descriptor_; Fl_Font_Descriptor *font_descriptor_;

public:

static matrix *fl_matrix; /**< Points to the current coordinate transformation matrix */
protected: protected:
void transformed_vertex0(COORD_T x, COORD_T y); void transformed_vertex0(COORD_T x, COORD_T y);
@@ -221,8 +227,6 @@ protected:
friend FL_EXPORT void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D); friend FL_EXPORT void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D);
friend FL_EXPORT void gl_start(); friend FL_EXPORT void gl_start();


matrix *fl_matrix; /**< Points to the current coordinate transformation matrix */

/** \brief The constructor. */ /** \brief The constructor. */
Fl_Graphics_Driver(); Fl_Graphics_Driver();
/** \brief see fl_rect(int x, int y, int w, int h). */ /** \brief see fl_rect(int x, int y, int w, int h). */
@@ -498,12 +502,13 @@ public:
}; };


#if FLTK_USE_CAIRO #if FLTK_USE_CAIRO
FL_EXPORT Fl_Color fl_color_add_alpha ( Fl_Color c, uchar alpha );


class Fl_Cairo_Graphics_Driver : public Fl_Xlib_Graphics_Driver { class Fl_Cairo_Graphics_Driver : public Fl_Xlib_Graphics_Driver {


public: public:


// void set_current(void);

Fl_Cairo_Graphics_Driver ( ); Fl_Cairo_Graphics_Driver ( );


/* static const char *class_id; */ /* static const char *class_id; */
@@ -574,6 +579,7 @@ public:
class FL_EXPORT Fl_Surface_Device : public Fl_Device { class FL_EXPORT Fl_Surface_Device : public Fl_Device {
/** \brief The graphics driver in use by this surface. */ /** \brief The graphics driver in use by this surface. */
Fl_Graphics_Driver *_driver; Fl_Graphics_Driver *_driver;
public:
static Fl_Surface_Device *_surface; // the surface that currently receives graphics output static Fl_Surface_Device *_surface; // the surface that currently receives graphics output
protected: protected:
/** \brief Constructor that sets the graphics driver to use for the created surface. */ /** \brief Constructor that sets the graphics driver to use for the created surface. */
@@ -596,7 +602,8 @@ public:
\brief A display to which the computer can draw. \brief A display to which the computer can draw.
*/ */
class FL_EXPORT Fl_Display_Device : public Fl_Surface_Device { class FL_EXPORT Fl_Display_Device : public Fl_Surface_Device {
static Fl_Display_Device *_display; // the platform display device
public:
static Fl_Display_Device *_display; // the platform display device
public: public:
static const char *class_id; static const char *class_id;
const char *class_name() {return class_id;}; const char *class_name() {return class_id;};


+ 1
- 1
FL/fl_draw.H View File

@@ -200,7 +200,7 @@ enum {
FL_JOIN_BEVEL = 0x3000 ///< join style: line join is tidied FL_JOIN_BEVEL = 0x3000 ///< join style: line join is tidied
}; };


#if FLTK_USE_CAIRO
#if FLTK_HAVE_CAIRO
FL_EXPORT Fl_Color fl_color_add_alpha ( Fl_Color c, uchar alpha ); FL_EXPORT Fl_Color fl_color_add_alpha ( Fl_Color c, uchar alpha );
#endif #endif




+ 5
- 6
src/Fl_Cairo.cxx View File

@@ -35,14 +35,11 @@
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#endif #endif


// static Fl module initialization :
Fl_Cairo_State Fl::cairo_state_; ///< contains all necesary info for current cairo context mapping

/* /*
Creates transparently a cairo_surface_t object. Creates transparently a cairo_surface_t object.
gc is an HDC context in WIN32, a CGContext* in Quartz, a display on X11 gc is an HDC context in WIN32, a CGContext* in Quartz, a display on X11
*/ */
static cairo_surface_t * cairo_create_surface(void * gc, int W, int H) {
cairo_surface_t * cairo_create_surface(void * gc, int W, int H) {
# if defined(USE_X11) # if defined(USE_X11)
return cairo_xlib_surface_create(fl_display, fl_window, fl_visual->visual, W, H); return cairo_xlib_surface_create(fl_display, fl_window, fl_visual->visual, W, H);
# elif defined(WIN32) # elif defined(WIN32)
@@ -54,6 +51,8 @@ static cairo_surface_t * cairo_create_surface(void * gc, int W, int H) {
# endif # endif
} }


cairo_surface_t *fl_cairo_surface;
cairo_t *fl_cairo_context;


cairo_t * cairo_t *
Fl::cairo_make_current(Fl_Window* wi) { Fl::cairo_make_current(Fl_Window* wi) {
@@ -67,9 +66,9 @@ Fl::cairo_make_current(Fl_Window* wi) {
// cairo_surface_destroy( s ); // cairo_surface_destroy( s );
} }


cairo_state_.window(wi);
fl_cairo_surface = wi->i->cs;
fl_cairo_context = wi->i->cc;


Fl::cairo_cc( wi->i->cc );
return wi->i->cc; return wi->i->cc;
} }




+ 261
- 88
src/Fl_Cairo_Graphics_Driver.cxx View File

@@ -46,10 +46,55 @@
*/ */


#include <config.h> #include <config.h>
#include <FL/Fl.H>

double fl_hxo = 0.0;
double fl_hyo = 0.5;
double fl_vxo = 0.5;
double fl_vyo = 0.0;
double fl_vho = 1.0;
double fl_hwo = 1.0;

#define HXO(n) ( n + fl_hxo )
#define HYO(n) ( n + fl_hyo )
#define VXO(n) ( n + fl_vxo )
#define VYO(n) ( n + fl_vyo )
#define VHO(n) ( n + fl_vho )
#define HWO(n) ( n + fl_hwo )

Fl_Color fl_color_add_alpha ( Fl_Color c, uchar alpha )
{
if ( !( c & 0xFFFFFF00 ) )
{
/* this is an indexed color or black */
if ( c & 0x000000FF )
{
/* this is an indexed color */
uchar r,g,b;

Fl::get_color( c, r, g, b );

c = fl_rgb_color( r, g, b );
}
else
{
/* this is black */
if ( 0 == alpha )
{
/* sorry, you can't have zero opacity because we don't
* have enough bits and it doesn't make much sense anyway */
alpha = 255;
}
/* hack to represent black */
c = 0x01010100;
}
}

return ( c & 0xFFFFFF00 ) | alpha;
}


#if FLTK_USE_CAIRO #if FLTK_USE_CAIRO


#include <FL/Fl.H>
#include <FL/x.H> #include <FL/x.H>
#include <cairo/cairo.h> #include <cairo/cairo.h>
#include <FL/Fl_Cairo.H> #include <FL/Fl_Cairo.H>
@@ -59,13 +104,34 @@


static double lw = 1; static double lw = 1;
static double hlw; static double hlw;
static cairo_antialias_t aa = CAIRO_ANTIALIAS_GRAY;


#define cairo_set_antialias( cr, aa )


Fl_Cairo_Graphics_Driver::Fl_Cairo_Graphics_Driver ( ) : Fl_Xlib_Graphics_Driver () Fl_Cairo_Graphics_Driver::Fl_Cairo_Graphics_Driver ( ) : Fl_Xlib_Graphics_Driver ()
{ {
// rstackptr = 0; // rstackptr = 0;
} }


/* void Fl_Cairo_Graphics_Driver::set_current ( void ) */
/* { */
/* Window root; */
/* int x, y; */
/* unsigned int w, h, bw, d; */

/* XGetGeometry( fl_display, fl_window, &root, &x, &y, &w, &h, &bw, &d ); */

/* fl_cairo_surface = cairo_create_surface( fl_gc, w, h ); */

/* /\* FIXME: how are we going to free this? *\/ */
/* fl_cairo_context = cairo_create( fl_cairo_surface ); */

/* cairo_surface_destroy( fl_cairo_surface ); */
/* fl_cairo_surface = 0; */
/* } */

void Fl_Cairo_Graphics_Driver::restore_clip ( void ) void Fl_Cairo_Graphics_Driver::restore_clip ( void )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();
@@ -75,10 +141,10 @@ void Fl_Cairo_Graphics_Driver::restore_clip ( void )


Fl_Xlib_Graphics_Driver::restore_clip(); Fl_Xlib_Graphics_Driver::restore_clip();


Fl_Region r = clip_region();

cairo_reset_clip( cr ); cairo_reset_clip( cr );


Fl_Region r = clip_region();

if ( r ) if ( r )
{ {
XRectangle rect; XRectangle rect;
@@ -130,19 +196,25 @@ void Fl_Cairo_Graphics_Driver::color ( Fl_Color c )
{ {
/* color is indexed, get the RGB value */ /* color is indexed, get the RGB value */
Fl::get_color( c, r, g, b ); Fl::get_color( c, r, g, b );

/* FIXME: temp! */
color( r, g, b ); color( r, g, b );
/* color( 255, 0, 0, 50 ); */
} }
else else
{ {
/* lower 8 bits become alpha. */
// if (i & 0xffffff00) {
Fl::get_color( c, r, g, b );
Fl::get_color( c & 0xFFFFFF00, r, g, b );


/* lower 8 bits become alpha. */
uchar a = c & 0x000000ff; uchar a = c & 0x000000ff;


if ( ! a ) if ( ! a )
a = 255; a = 255;


/* /\* HACK to represent black *\/ */
/* if ( ( c & 0xFFFFFF00 ) == 0x01010100 ) */
/* r = g = b = 0; */

color( r, g, b, a ); color( r, g, b, a );
} }
} }
@@ -166,45 +238,17 @@ void fl_set_antialias ( int v )
switch ( v ) switch ( v )
{ {
case FL_ANTIALIAS_DEFAULT: case FL_ANTIALIAS_DEFAULT:
cairo_set_antialias( cr, CAIRO_ANTIALIAS_DEFAULT );
cairo_set_antialias( cr, aa = CAIRO_ANTIALIAS_DEFAULT );
break; break;
case FL_ANTIALIAS_ON: case FL_ANTIALIAS_ON:
cairo_set_antialias( cr, CAIRO_ANTIALIAS_GRAY );
cairo_set_antialias( cr, aa = CAIRO_ANTIALIAS_GRAY );
break; break;
case FL_ANTIALIAS_OFF: case FL_ANTIALIAS_OFF:
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
cairo_set_antialias( cr, aa = CAIRO_ANTIALIAS_NONE );
break; break;
} }
} }


Fl_Color fl_color_add_alpha ( Fl_Color c, uchar alpha )
{
if ( !( c & 0xFFFFFF00 ) )
{
/* this is an indexed color, or black */
if ( c & 0x000000FF )
{
/* this is an indexed color */
uchar r,g,b;

Fl::get_color( c, r, g, b );

c = fl_rgb_color( r, g, b );
}
else
{
/* this is black */
if ( 0 == alpha )
{
/* sorry, you can't have zero opacity because we don't
* have enough bits and it doesn't make much sense anyway */
alpha = 255;
}
}
}

return ( c & 0xFFFFFF00 ) & alpha;
}


void Fl_Cairo_Graphics_Driver::color ( Fl_Color c, uchar a ) void Fl_Cairo_Graphics_Driver::color ( Fl_Color c, uchar a )
{ {
@@ -221,7 +265,7 @@ void Fl_Cairo_Graphics_Driver::color (uchar r, uchar g, uchar b, uchar a )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();


Fl_Xlib_Graphics_Driver::color( r, g, b );
// Fl_Xlib_Graphics_Driver::color( r, g, b );


if ( ! cr ) if ( ! cr )
return; return;
@@ -265,14 +309,25 @@ static void add_arc( int x, int y, int w, int h, double a1, double a2 )
const double cx = x + ( 0.5f * w ); const double cx = x + ( 0.5f * w );
const double cy = y + ( 0.5f * h ); const double cy = y + ( 0.5f * h );


/* cairo_save( cr ); */
/* cairo_translate( cr, cx, cy ); */
/* cairo_scale( cr, w, h ); */

/* if ( a1 > a2 ) */
/* cairo_arc( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 )); */
/* else */
/* cairo_arc_negative( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 )); */


cairo_save( cr ); cairo_save( cr );
cairo_translate( cr, cx, cy ); cairo_translate( cr, cx, cy );
cairo_scale( cr, w, h );
cairo_scale( cr, w - 1, h - 1 );


if ( a1 > a2 ) if ( a1 > a2 )
cairo_arc( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 )); cairo_arc( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 ));
else else
cairo_arc_negative( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 )); cairo_arc_negative( cr, 0.0, 0.0, 0.5, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 ));

cairo_restore( cr ); cairo_restore( cr );
} }
@@ -290,6 +345,8 @@ void Fl_Cairo_Graphics_Driver::arc( double x, double y, double r, double a1, dou
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();


cairo_close_path( cr );

cairo_arc( cr, x, y, r, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 )); cairo_arc( cr, x, y, r, a1 * ( -M_PI / 180.0 ), a2 * ( -M_PI / 180.0 ));
} }


@@ -300,7 +357,7 @@ void Fl_Cairo_Graphics_Driver::pie( int x, int y, int w, int h, double a1, doubl
double a1R = a1 * ( M_PI / 180.0 ); double a1R = a1 * ( M_PI / 180.0 );
double a2R = a2 * ( M_PI / 180.0 ); double a2R = a2 * ( M_PI / 180.0 );


float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f;
float cx = x + 0.5 * w - 0.5f, cy = y + 0.5 * h - 0.5f;
cairo_save( cr ); cairo_save( cr );
cairo_translate( cr, cx, cy ); cairo_translate( cr, cx, cy );
@@ -317,19 +374,60 @@ void Fl_Cairo_Graphics_Driver::line( int x1, int y1, int x2, int y2 )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();


cairo_move_to( cr, x1 + 0.5, y1 + 0.5 );
cairo_line_to( cr, x2 + 0.5, y2 + 0.5 );
cairo_set_line_width( cr, lw );

if ( x1 == x2 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
/* vertical line */
if ( y1 > y2 )
{
int t = y2;
y2 = y1;
y1 = t;
}

cairo_move_to( cr, VXO( x1 ), VYO( y1 ) );
cairo_line_to( cr, VXO( x2 ), VHO( y2 ) );
}
else if ( y1 == y2 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
/* horizontal line */
cairo_move_to( cr, HXO( x1 ), HYO( y1 ) );
cairo_line_to( cr, HWO( x2 ), HYO( y2 ) );
}
else
{
/* diagonal line */
cairo_move_to( cr, x1 , y1 );
cairo_line_to( cr, x2 , y2 );
}

cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );
} }


void Fl_Cairo_Graphics_Driver::line( int x1, int y1, int x2, int y2, int x3, int y3 ) void Fl_Cairo_Graphics_Driver::line( int x1, int y1, int x2, int y2, int x3, int y3 )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();


cairo_move_to( cr, x1 + 0.5, y1 + 0.5 );
cairo_line_to( cr, x2 + 0.5, y2 + 0.5);
cairo_line_to( cr, x3 + 0.5, y3 + 0.5 );
cairo_set_line_width( cr, lw );

if ( lw <= 1 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
}

cairo_move_to( cr, x1 , y1 );
cairo_line_to( cr, x2 , y2 );
cairo_line_to( cr, x3 , y3 );
cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );
} }




@@ -337,23 +435,33 @@ void Fl_Cairo_Graphics_Driver::rect ( int x, int y, int w, int h )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();


cairo_set_line_width( cr, lw );

/* cairo draws lines half inside and half outside of the path... */ /* cairo draws lines half inside and half outside of the path... */


/* const double line_width = cairo_get_line_width( cr ); */ /* const double line_width = cairo_get_line_width( cr ); */
/* const double o = line_width / 2.0; */ /* const double o = line_width / 2.0; */


cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
// cairo_rectangle( cr, x + hlw, y + hlw, w - lw - 1, h - lw - 1); // cairo_rectangle( cr, x + hlw, y + hlw, w - lw - 1, h - lw - 1);
cairo_rectangle( cr, x + 0.5, y + 0.5, w, h );
cairo_rectangle( cr, VXO( x ), HYO( y ), w - 1, h - 1 );
cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );
} }


void Fl_Cairo_Graphics_Driver::rectf ( int x, int y, int w, int h ) void Fl_Cairo_Graphics_Driver::rectf ( int x, int y, int w, int h )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();


cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );

/* cairo fills the inside of the path... */ /* cairo fills the inside of the path... */
cairo_rectangle( cr, x + 0.5, y + 0.5, w, h );
cairo_rectangle( cr, x, y, w, h );
cairo_fill( cr ); cairo_fill( cr );

cairo_set_antialias( cr, aa );
} }


void Fl_Cairo_Graphics_Driver::end_line ( void ) void Fl_Cairo_Graphics_Driver::end_line ( void )
@@ -366,22 +474,35 @@ void Fl_Cairo_Graphics_Driver::end_line ( void )
return; return;
} }


cairo_move_to( cr, p[0].x + 0.5, p[0].y + 0.5 );
if ( lw <= 1 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
}

cairo_set_line_width( cr, lw );

cairo_move_to( cr, p[0].x + 0.5 , p[0].y + 0.5 );


for (int i=1; i<n; i++) for (int i=1; i<n; i++)
cairo_line_to( cr, p[i].x + 0.5, p[i].y + 0.5 );
cairo_line_to( cr, p[i].x + 0.5 , p[i].y + 0.5 );


cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );
} }


void Fl_Cairo_Graphics_Driver::end_points ( void ) void Fl_Cairo_Graphics_Driver::end_points ( void )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();


cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );

for (int i=0; i<n; i++) for (int i=0; i<n; i++)
cairo_rectangle( cr, p[1].x + 0.5, p[1].y + 0.5, 1, 1 );
cairo_rectangle( cr, p[1].x , p[1].y , 1, 1 );


cairo_fill( cr ); cairo_fill( cr );

cairo_set_antialias( cr, aa );
} }


void Fl_Cairo_Graphics_Driver::end_loop ( void ) void Fl_Cairo_Graphics_Driver::end_loop ( void )
@@ -407,10 +528,10 @@ void Fl_Cairo_Graphics_Driver::end_complex_polygon ( void )
return; return;
} }


cairo_move_to( cr, p[0].x + 0.5, p[0].y + 0.5);
cairo_move_to( cr, p[0].x , p[0].y );


for (int i=1; i<n; i++) for (int i=1; i<n; i++)
cairo_line_to( cr, p[i].x + 0.5, p[i].y + 0.5);
cairo_line_to( cr, p[i].x , p[i].y );


cairo_close_path( cr ); cairo_close_path( cr );


@@ -429,10 +550,10 @@ void Fl_Cairo_Graphics_Driver::end_polygon ( void )
return; return;
} }


cairo_move_to( cr, p[0].x + 0.5, p[0].y + 0.5 );
cairo_move_to( cr, p[0].x , p[0].y );


for (int i=1; i<n; i++) for (int i=1; i<n; i++)
cairo_line_to( cr, p[i].x + 0.5, p[i].y + 0.5 );
cairo_line_to( cr, p[i].x , p[i].y );


cairo_close_path( cr ); cairo_close_path( cr );
cairo_fill( cr ); cairo_fill( cr );
@@ -450,9 +571,9 @@ void Fl_Cairo_Graphics_Driver::polygon ( int x, int y, int x1, int y1, int x2, i
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();
cairo_move_to( cr, x + 0.5, y + 0.5 );
cairo_line_to( cr, x1 + 0.5, y1 + 0.5 );
cairo_line_to( cr, x2 + 0.5, y2 + 0.5 );
cairo_move_to( cr, x , y );
cairo_line_to( cr, x1 , y1 );
cairo_line_to( cr, x2 , y2 );
cairo_close_path( cr ); cairo_close_path( cr );
cairo_fill( cr ); cairo_fill( cr );
} }
@@ -461,10 +582,10 @@ void Fl_Cairo_Graphics_Driver::polygon ( int x, int y, int x1, int y1, int x2, i
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();
cairo_move_to( cr, x + 0.5, y + 0.5 );
cairo_line_to( cr, x1 + 0.5, y1 + 0.5 );
cairo_line_to( cr, x2 + 0.5, y2 + 0.5 );
cairo_line_to( cr, x3 + 0.5, y3 + 0.5 );
cairo_move_to( cr, x , y );
cairo_line_to( cr, x1 , y1 );
cairo_line_to( cr, x2 , y2 );
cairo_line_to( cr, x3 , y3 );
cairo_close_path( cr ); cairo_close_path( cr );
cairo_fill( cr ); cairo_fill( cr );
} }
@@ -473,9 +594,9 @@ void Fl_Cairo_Graphics_Driver::loop ( int x, int y, int x1, int y1, int x2, int
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();
cairo_move_to( cr, x + 0.5, y + 0.5 );
cairo_line_to( cr, x1 + 0.5, y1 + 0.5 );
cairo_line_to( cr, x2 + 0.5, y2 + 0.5 );
cairo_move_to( cr, x , y );
cairo_line_to( cr, x1 , y1 );
cairo_line_to( cr, x2 , y2 );
cairo_close_path( cr ); cairo_close_path( cr );
cairo_stroke( cr ); cairo_stroke( cr );
} }
@@ -484,10 +605,10 @@ void Fl_Cairo_Graphics_Driver::loop ( int x, int y, int x1, int y1, int x2, int
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();
cairo_move_to( cr, x + 0.5, y + 0.5 );
cairo_line_to( cr, x1 + 0.5, y1 + 0.5 );
cairo_line_to( cr, x2 + 0.5, y2 + 0.5 );
cairo_line_to( cr, x3 + 0.5, y3 + 0.5 );
cairo_move_to( cr, x , y );
cairo_line_to( cr, x1 , y1 );
cairo_line_to( cr, x2 , y2 );
cairo_line_to( cr, x3 , y3 );
cairo_close_path( cr ); cairo_close_path( cr );
cairo_stroke( cr ); cairo_stroke( cr );
} }
@@ -496,67 +617,119 @@ void Fl_Cairo_Graphics_Driver::loop ( int x, int y, int x1, int y1, int x2, int
void Fl_Cairo_Graphics_Driver::xyline ( int x, int y, int x1 ) void Fl_Cairo_Graphics_Driver::xyline ( int x, int y, int x1 )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();
cairo_move_to( cr, x + 0.5, y + 0.5);
cairo_line_to( cr, x1 + 0.5, y + 0.5 );

cairo_set_line_width( cr, lw );


if ( lw <= 1 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
}

cairo_move_to( cr, HXO( x ), HYO( y ) );
cairo_line_to( cr, HWO( x1 ), HYO( y ) );
cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );
} }


void Fl_Cairo_Graphics_Driver::xyline ( int x, int y, int x1, int y2 ) void Fl_Cairo_Graphics_Driver::xyline ( int x, int y, int x1, int y2 )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();

cairo_set_line_width( cr, lw );
cairo_move_to( cr, x + 0.5, y + 0.5 );
cairo_line_to( cr, x1 + 0.5, y + 0.5 );
cairo_line_to( cr, x1 + 0.5, y2 + 0.5 );
if ( lw <= 1 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
}

/* horizontal line */
cairo_move_to( cr, HXO( x ) , HYO( y ) );
cairo_line_to( cr, HWO( x1 ), HYO( y ) );
/* then vertical line */
cairo_line_to( cr, HWO( x1 ) , VYO( y2 ) );


cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );

} }


void Fl_Cairo_Graphics_Driver::xyline ( int x, int y, int x1, int y2, int x3 ) void Fl_Cairo_Graphics_Driver::xyline ( int x, int y, int x1, int y2, int x3 )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();

if ( lw <= 1 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
}
cairo_move_to( cr, x + 0.5, y + 0.5 );
cairo_line_to( cr, x1 + 0.5, y + 0.5 );
cairo_line_to( cr, x1 + 0.5, y2 + 0.5 );
cairo_line_to( cr, x3 + 0.5, y2 + 0.5 );
cairo_move_to( cr, x , y );
cairo_line_to( cr, x1 , y );
cairo_line_to( cr, x1 , y2 );
cairo_line_to( cr, x3 , y2 );


cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );
} }


void Fl_Cairo_Graphics_Driver::yxline ( int x, int y, int y1 ) void Fl_Cairo_Graphics_Driver::yxline ( int x, int y, int y1 )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();
cairo_move_to( cr, x + 0.5, y + 0.5 );
cairo_line_to( cr, x + 0.5, y1 + 0.5 );

cairo_set_line_width( cr, lw );

if ( lw <= 1 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
}

cairo_move_to( cr, VXO( x ), VHO( y ) );
cairo_line_to( cr, VXO( x ), VYO( y1 ) );
cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );
} }


void Fl_Cairo_Graphics_Driver::yxline ( int x, int y, int y1, int x2 ) void Fl_Cairo_Graphics_Driver::yxline ( int x, int y, int y1, int x2 )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();

if ( lw <= 1 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
}
cairo_move_to( cr, x + 0.5, y + 0.5 );
cairo_line_to( cr, x + 0.5, y1 + 0.5 );
cairo_line_to( cr, x2 + 0.5, y1 + 0.5 );
cairo_move_to( cr, x , y );
cairo_line_to( cr, x, y1 );
cairo_line_to( cr, x2, y1 );


cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );
} }


void Fl_Cairo_Graphics_Driver::yxline ( int x, int y, int y1, int x2, int y3 ) void Fl_Cairo_Graphics_Driver::yxline ( int x, int y, int y1, int x2, int y3 )
{ {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();

if ( lw <= 1 )
{
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE );
}
cairo_move_to( cr, x + 0.5, y + 0.5 );
cairo_line_to( cr, x + 0.5, y1 + 0.5 );
cairo_line_to( cr, x2 + 0.5, y1 + 0.5 );
cairo_line_to( cr, x2 + 0.5, y3 + 0.5 );
cairo_move_to( cr, x , y );
cairo_line_to( cr, x , y1 );
cairo_line_to( cr, x2 , y1 );
cairo_line_to( cr, x2 , y3 );


cairo_stroke( cr ); cairo_stroke( cr );

cairo_set_antialias( cr, aa );
} }


#else #else


+ 28
- 8
src/Fl_Device.cxx View File

@@ -47,6 +47,26 @@ const char *Fl_Cairo_Graphics_Driver::class_id = "Fl_Cairo_Graphics_Driver";
#endif #endif




Fl_Font Fl_Graphics_Driver::font_; // current font
Fl_Fontsize Fl_Graphics_Driver::size_; // current font size
Fl_Color Fl_Graphics_Driver::color_; // current color
int Fl_Graphics_Driver::sptr = 0;
//const int Fl_Graphics_Driver::matrix_stack_size = FL_MATRIX_STACK_SIZE;
Fl_Graphics_Driver::matrix Fl_Graphics_Driver::stack[FL_MATRIX_STACK_SIZE];
Fl_Graphics_Driver::matrix Fl_Graphics_Driver::m = m0;
Fl_Graphics_Driver::matrix *Fl_Graphics_Driver::fl_matrix = &m; /**< Points to the current coordinate transformation matrix */

int Fl_Graphics_Driver::n = 0;
int Fl_Graphics_Driver::p_size = 0;
int Fl_Graphics_Driver::gap_ = 0;
XPOINT *Fl_Graphics_Driver::p = 0;
int Fl_Graphics_Driver::what = 0;
int Fl_Graphics_Driver::fl_clip_state_number = 0;
int Fl_Graphics_Driver::rstackptr = 0;
//const int Fl_Graphics_Driver::region_stack_max = FL_REGION_STACK_SIZE - 1;
Fl_Region Fl_Graphics_Driver::rstack[FL_REGION_STACK_SIZE];


/** \brief Use this drawing surface for future graphics requests. */ /** \brief Use this drawing surface for future graphics requests. */
void Fl_Surface_Device::set_current(void) void Fl_Surface_Device::set_current(void)
{ {
@@ -57,13 +77,13 @@ void Fl_Surface_Device::set_current(void)
const Fl_Graphics_Driver::matrix Fl_Graphics_Driver::m0 = {1, 0, 0, 1, 0, 0}; const Fl_Graphics_Driver::matrix Fl_Graphics_Driver::m0 = {1, 0, 0, 1, 0, 0};


Fl_Graphics_Driver::Fl_Graphics_Driver() { Fl_Graphics_Driver::Fl_Graphics_Driver() {
font_ = 0;
size_ = 0;
sptr=0; rstackptr=0;
fl_clip_state_number=0;
m = m0;
fl_matrix = &m;
p = (XPOINT *)0;
/* font_ = 0; */
/* size_ = 0; */
/* sptr=0; rstackptr=0; */
/* fl_clip_state_number=0; */
/* m = m0; */
/* fl_matrix = &m; */
/* p = (XPOINT *)0; */
font_descriptor_ = NULL; font_descriptor_ = NULL;
}; };


@@ -75,7 +95,7 @@ void Fl_Graphics_Driver::text_extents(const char*t, int n, int& dx, int& dy, int
dy = descent(); dy = descent();
} }


Fl_Display_Device::Fl_Display_Device(Fl_Graphics_Driver *graphics_driver) : Fl_Surface_Device( graphics_driver) {
Fl_Display_Device::Fl_Display_Device(Fl_Graphics_Driver *graphics_driver) : Fl_Surface_Device( graphics_driver ) {
#ifdef __APPLE__ #ifdef __APPLE__
SInt32 versionMajor = 0; SInt32 versionMajor = 0;
SInt32 versionMinor = 0; SInt32 versionMinor = 0;


+ 12
- 0
src/Fl_arg.cxx View File

@@ -179,6 +179,15 @@ int Fl::arg(int argc, char **argv, int &i) {
i++; i++;
return 1; return 1;
} }

#if FLTK_USE_CAIRO
else if (fl_match(s, "cairo", 1)) {
fl_push_use_cairo( true );
i++;
return 1;
}
#endif

#ifdef __APPLE__ #ifdef __APPLE__
// The Finder application in MacOS X passes the "-psn_N_NNNNN" option // The Finder application in MacOS X passes the "-psn_N_NNNNN" option
// to all apps... // to all apps...
@@ -391,6 +400,9 @@ static const char * const helpmsg =
" -not[ooltips]\n" " -not[ooltips]\n"
" -s[cheme] scheme\n" " -s[cheme] scheme\n"
" -ti[tle] windowtitle\n" " -ti[tle] windowtitle\n"
#if FLTK_USE_CAIRO
" -c[airo]\n"
#endif
" -to[oltips]"; " -to[oltips]";


const char * const Fl::help = helpmsg+13; const char * const Fl::help = helpmsg+13;


+ 27
- 2
src/Fl_x.cxx View File

@@ -55,10 +55,12 @@


#if FLTK_USE_CAIRO #if FLTK_USE_CAIRO
static Fl_Cairo_Graphics_Driver fl_cairo_driver; static Fl_Cairo_Graphics_Driver fl_cairo_driver;
static Fl_Display_Device fl_cairo_display(&fl_cairo_driver);
#endif #endif
static Fl_Xlib_Graphics_Driver fl_xlib_driver;


static Fl_Xlib_Graphics_Driver fl_xlib_driver;
static Fl_Display_Device fl_xlib_display(&fl_xlib_driver); static Fl_Display_Device fl_xlib_display(&fl_xlib_driver);

FL_EXPORT Fl_Graphics_Driver *fl_graphics_driver = (Fl_Graphics_Driver*)&fl_xlib_driver; // the current target device of graphics operations FL_EXPORT Fl_Graphics_Driver *fl_graphics_driver = (Fl_Graphics_Driver*)&fl_xlib_driver; // the current target device of graphics operations
Fl_Surface_Device* Fl_Surface_Device::_surface = (Fl_Surface_Device*)&fl_xlib_display; // the current target surface of graphics operations Fl_Surface_Device* Fl_Surface_Device::_surface = (Fl_Surface_Device*)&fl_xlib_display; // the current target surface of graphics operations
Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display
@@ -73,9 +75,20 @@ FL_EXPORT void fl_push_use_cairo ( bool v )
{ {
#if FLTK_USE_CAIRO #if FLTK_USE_CAIRO
if ( v ) if ( v )
{
/* FIXME: why are there *SO MANY VERSIONS OF THE SAME THING*? */
fl_graphics_driver = &fl_cairo_driver; fl_graphics_driver = &fl_cairo_driver;
Fl_Surface_Device::_surface = (Fl_Surface_Device*)&fl_cairo_display;
Fl_Display_Device::_display = &fl_cairo_display;
}
else else
{
fl_graphics_driver = &fl_xlib_driver; fl_graphics_driver = &fl_xlib_driver;
Fl_Surface_Device::_surface = (Fl_Surface_Device*)&fl_xlib_display;
Fl_Display_Device::_display = &fl_xlib_display;
}

fl_restore_clip();


if ( use_cairo_ptr < (int) (sizeof( use_cairo_stack ) / sizeof( bool ) )) if ( use_cairo_ptr < (int) (sizeof( use_cairo_stack ) / sizeof( bool ) ))
use_cairo_stack[++use_cairo_ptr] = v; use_cairo_stack[++use_cairo_ptr] = v;
@@ -92,11 +105,23 @@ FL_EXPORT void fl_pop_use_cairo ( void )


if ( use_cairo_ptr > 0 ) if ( use_cairo_ptr > 0 )
v = use_cairo_stack[--use_cairo_ptr]; v = use_cairo_stack[--use_cairo_ptr];
if ( v ) if ( v )
{
/* FIXME: why are there *SO MANY VERSIONS OF THE SAME THING*? */
fl_graphics_driver = &fl_cairo_driver; fl_graphics_driver = &fl_cairo_driver;
Fl_Surface_Device::_surface = (Fl_Surface_Device*)&fl_cairo_display;
Fl_Display_Device::_display = &fl_cairo_display;
}
else else
{
fl_graphics_driver = &fl_xlib_driver; fl_graphics_driver = &fl_xlib_driver;
Fl_Surface_Device::_surface = (Fl_Surface_Device*)&fl_xlib_display;
Fl_Display_Device::_display = &fl_xlib_display;
}

fl_restore_clip();

#else #else
/* noop */ /* noop */
; ;


+ 0
- 3
test/cairo_test.cxx View File

@@ -144,9 +144,6 @@ static void my_cairo_draw_cb(Fl_Cairo_Window* window, cairo_t* cr) {
} }


int main(int argc, char** argv) { int main(int argc, char** argv) {
#ifdef AUTOLINK
Fl::cairo_autolink_context(true);
#endif
Fl_Cairo_Window window(300,300); Fl_Cairo_Window window(300,300);
window.resizable(&window); window.resizable(&window);


Loading…
Cancel
Save