Create class Fl_Cairo_Graphics_Driver.
That class is extracted from inside Fl_PostScript_Graphics_Driver and might become handy in the future.
This commit is contained in:
parent
a3cb4af739
commit
1fbcae13bd
@ -217,6 +217,9 @@ if (USE_X11)
|
||||
set (DRIVER_FILES ${DRIVER_FILES}
|
||||
drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
|
||||
)
|
||||
if (USE_PANGO)
|
||||
set (DRIVER_FILES ${DRIVER_FILES} drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx)
|
||||
endif (USE_PANGO)
|
||||
else ()
|
||||
set (DRIVER_FILES ${DRIVER_FILES}
|
||||
drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx
|
||||
|
||||
@ -283,7 +283,8 @@ XLIBFONTFILES = \
|
||||
|
||||
# These C++ files are used under condition: BUILD_X11 AND BUILD_XFT
|
||||
XLIBXFTFILES = \
|
||||
drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
|
||||
drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx \
|
||||
drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx
|
||||
|
||||
# These C++ files are used under condition: BUILD_GDI
|
||||
GDICPPFILES = \
|
||||
@ -601,6 +602,7 @@ rebuild:
|
||||
|
||||
clean:
|
||||
-$(RM) *.o xutf8/*.o *.dll.a core.* *~ *.bak *.bck
|
||||
-$(RM) drivers/Cairo/*.o
|
||||
-$(RM) drivers/Cocoa/*.o
|
||||
-$(RM) drivers/Darwin/*.o
|
||||
-$(RM) drivers/GDI/*.o
|
||||
|
||||
140
src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H
Normal file
140
src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H
Normal file
@ -0,0 +1,140 @@
|
||||
//
|
||||
// Support for Cairo graphics for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// https://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please see the following page on how to report bugs and issues:
|
||||
//
|
||||
// https://www.fltk.org/bugs.php
|
||||
//
|
||||
|
||||
/* \file
|
||||
Declaration of class Fl_Cairo_Graphics_Driver.
|
||||
*/
|
||||
|
||||
#include <FL/Fl_Graphics_Driver.H>
|
||||
|
||||
typedef struct _cairo cairo_t;
|
||||
typedef struct _PangoLayout PangoLayout;
|
||||
typedef struct _PangoFontDescription PangoFontDescription;
|
||||
|
||||
class FL_EXPORT Fl_Cairo_Graphics_Driver : public Fl_Graphics_Driver {
|
||||
protected:
|
||||
cairo_t *cairo_;
|
||||
PangoLayout *pango_layout_;
|
||||
void draw_rgb_bitmap_(Fl_Image *img,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
public:
|
||||
Fl_Cairo_Graphics_Driver();
|
||||
virtual ~Fl_Cairo_Graphics_Driver();
|
||||
enum SHAPE {NONE=0, LINE, LOOP, POLYGON, POINTS};
|
||||
|
||||
class Clip {
|
||||
public:
|
||||
int x, y, w, h;
|
||||
Clip *prev;
|
||||
};
|
||||
Clip * clip_;
|
||||
|
||||
int lang_level_;
|
||||
int gap_;
|
||||
int pages_;
|
||||
cairo_t *cr() { return cairo_; }
|
||||
PangoLayout *pango_layout() {return pango_layout_;};
|
||||
virtual PangoFontDescription* pango_font_description(Fl_Font fnum) { return NULL; }
|
||||
|
||||
void check_status(void);
|
||||
|
||||
enum SHAPE shape_;
|
||||
int linewidth_;// need for clipping, lang level 1-2
|
||||
int linestyle_;//
|
||||
unsigned char cr_,cg_,cb_;
|
||||
char linedash_[256];//should be enough
|
||||
void concat(); // transform ror scalable dradings...
|
||||
void reconcat(); //invert
|
||||
void recover(); //recovers the state after grestore (such as line styles...)
|
||||
void reset();
|
||||
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
float angle;
|
||||
int left_margin;
|
||||
int top_margin;
|
||||
|
||||
double pw_, ph_;
|
||||
|
||||
uchar bg_r, bg_g, bg_b;
|
||||
void transformed_draw(const char* s, int n, double x, double y); //precise text placing
|
||||
|
||||
// implementation of drawing methods
|
||||
void color(Fl_Color c);
|
||||
void color(uchar r, uchar g, uchar b);
|
||||
Fl_Color color();
|
||||
|
||||
void push_clip(int x, int y, int w, int h);
|
||||
void push_no_clip();
|
||||
void pop_clip();
|
||||
|
||||
void line_style(int style, int width=0, char* dashes=0);
|
||||
|
||||
void rect(int x, int y, int w, int h);
|
||||
void rectf(int x, int y, int w, int h);
|
||||
|
||||
void xyline(int x, int y, int x1);
|
||||
void xyline(int x, int y, int x1, int y2);
|
||||
void xyline(int x, int y, int x1, int y2, int x3);
|
||||
|
||||
void yxline(int x, int y, int y1);
|
||||
void yxline(int x, int y, int y1, int x2);
|
||||
void yxline(int x, int y, int y1, int x2, int y3);
|
||||
|
||||
void line(int x1, int y1, int x2, int y2);
|
||||
void line(int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
|
||||
void loop(int x0, int y0, int x1, int y1, int x2, int y2);
|
||||
void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
void polygon(int x0, int y0, int x1, int y1, int x2, int y2);
|
||||
void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
|
||||
void begin_points();
|
||||
void begin_line();
|
||||
void begin_loop();
|
||||
void begin_polygon();
|
||||
void vertex(double x, double y);
|
||||
void curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
void circle(double x, double y, double r);
|
||||
void arc(double x, double y, double r, double start, double a);
|
||||
void arc(int x, int y, int w, int h, double a1, double a2);
|
||||
void pie(int x, int y, int w, int h, double a1, double a2);
|
||||
void end_points();
|
||||
void end_line();
|
||||
void end_loop();
|
||||
void end_polygon();
|
||||
void begin_complex_polygon(){begin_polygon();};
|
||||
void gap(){gap_=1;};
|
||||
void end_complex_polygon(){end_polygon();};
|
||||
void transformed_vertex(double x, double y);
|
||||
|
||||
void draw_image_mono(const uchar* d, int x,int y,int w,int h, int delta=1, int ld=0);
|
||||
void draw_image(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int h, int delta=3);
|
||||
void draw_image_mono(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int h, int delta=1);
|
||||
|
||||
void draw(const char* s, int nBytes, int x, int y) {transformed_draw(s,nBytes,x,y); };
|
||||
void draw(const char* s, int nBytes, float x, float y) {transformed_draw(s,nBytes,x,y); };
|
||||
void draw(int angle, const char *str, int n, int x, int y);
|
||||
void rtl_draw(const char* s, int n, int x, int y);
|
||||
void draw_pixmap(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_bitmap(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_rgb(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
// ---
|
||||
Fl_Bitmask create_bitmask(int w, int h, const uchar *array) { return 0L; }
|
||||
|
||||
void ps_origin(int x, int y);
|
||||
void ps_translate(int, int);
|
||||
void ps_untranslate();
|
||||
};
|
||||
656
src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx
Normal file
656
src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx
Normal file
@ -0,0 +1,656 @@
|
||||
//
|
||||
// Support for Cairo graphics for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// https://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please see the following page on how to report bugs and issues:
|
||||
//
|
||||
// https://www.fltk.org/bugs.php
|
||||
//
|
||||
|
||||
/* \file
|
||||
Implementation of class Fl_Cairo_Graphics_Driver .
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#if USE_PANGO
|
||||
|
||||
#include "Fl_Cairo_Graphics_Driver.H"
|
||||
#include <FL/fl_draw.H>
|
||||
#include <cairo/cairo.h>
|
||||
#include <pango/pangocairo.h>
|
||||
|
||||
// duplicated from Fl_PostScript.cxx
|
||||
struct callback_data {
|
||||
const uchar *data;
|
||||
int D, LD;
|
||||
};
|
||||
static const int dashes_flat[5][7]={
|
||||
{-1,0,0,0,0,0,0},
|
||||
{3,1,-1,0,0,0,0},
|
||||
{1,1,-1,0,0,0,0},
|
||||
{3,1,1,1,-1,0,0},
|
||||
{3,1,1,1,1,1,-1}
|
||||
};
|
||||
static const double dashes_cap[5][7]={
|
||||
{-1,0,0,0,0,0,0},
|
||||
{2,2,-1,0,0,0,0},
|
||||
{0.01,1.99,-1,0,0,0,0},
|
||||
{2,2,0.01,1.99,-1,0,0},
|
||||
{2,2,0.01,1.99,0.01,1.99,-1}
|
||||
};
|
||||
static void draw_image_cb(void *data, int x, int y, int w, uchar *buf) {
|
||||
struct callback_data *cb_data;
|
||||
const uchar *curdata;
|
||||
|
||||
cb_data = (struct callback_data*)data;
|
||||
int last = x+w;
|
||||
curdata = cb_data->data + x*cb_data->D + y*cb_data->LD;
|
||||
for (; x<last; x++) {
|
||||
memcpy(buf, curdata, abs(cb_data->D));
|
||||
buf += abs(cb_data->D);
|
||||
curdata += cb_data->D;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Fl_Cairo_Graphics_Driver::Fl_Cairo_Graphics_Driver() : Fl_Graphics_Driver() {}
|
||||
|
||||
Fl_Cairo_Graphics_Driver::~Fl_Cairo_Graphics_Driver() {}
|
||||
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::rectf(int x, int y, int w, int h) {
|
||||
cairo_rectangle(cairo_, x, y, w, h);
|
||||
cairo_fill(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::rect(int x, int y, int w, int h) {
|
||||
cairo_rectangle(cairo_, x, y, w, h);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::line(int x1, int y1, int x2, int y2) {
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_stroke(cairo_);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::line(int x0, int y0, int x1, int y1, int x2, int y2) {
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_stroke(cairo_);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::xyline(int x, int y, int x1) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x1, y);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x1, y);
|
||||
cairo_line_to(cairo_, x1, y2);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x1, y);
|
||||
cairo_line_to(cairo_, x1, y2);
|
||||
cairo_line_to(cairo_, x3, y2);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::yxline(int x, int y, int y1) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x, y1);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x, y1);
|
||||
cairo_line_to(cairo_, x2, y1);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x, y1);
|
||||
cairo_line_to(cairo_, x2, y1);
|
||||
cairo_line_to(cairo_, x2, y3);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) {
|
||||
cairo_save(cairo_);
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_close_path(cairo_);
|
||||
cairo_stroke(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
cairo_save(cairo_);
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_line_to(cairo_, x3, y3);
|
||||
cairo_close_path(cairo_);
|
||||
cairo_stroke(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
|
||||
cairo_save(cairo_);
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_close_path(cairo_);
|
||||
cairo_fill(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
cairo_save(cairo_);
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_line_to(cairo_, x3, y3);
|
||||
cairo_close_path(cairo_);
|
||||
cairo_fill(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::line_style(int style, int width, char* dashes) {
|
||||
linewidth_=width;
|
||||
linestyle_=style;
|
||||
if(dashes){
|
||||
if(dashes != linedash_)
|
||||
strcpy(linedash_,dashes);
|
||||
|
||||
} else
|
||||
linedash_[0]=0;
|
||||
char width0 = 0;
|
||||
if (!width){
|
||||
width=1; //for screen drawing compatibility
|
||||
width0=1;
|
||||
}
|
||||
cairo_set_line_width(cairo_, width);
|
||||
|
||||
if(!style && (!dashes || !(*dashes)) && width0) //system lines
|
||||
style = FL_CAP_SQUARE;
|
||||
|
||||
int cap = (style &0xf00);
|
||||
cairo_line_cap_t c_cap;
|
||||
if (cap == FL_CAP_SQUARE) c_cap = CAIRO_LINE_CAP_SQUARE;
|
||||
else if (cap == FL_CAP_FLAT) c_cap = CAIRO_LINE_CAP_BUTT;
|
||||
else if (cap == FL_CAP_ROUND) c_cap = CAIRO_LINE_CAP_ROUND;
|
||||
else c_cap = CAIRO_LINE_CAP_BUTT;
|
||||
cairo_set_line_cap(cairo_, c_cap);
|
||||
|
||||
int join = (style & 0xf000);
|
||||
cairo_line_join_t c_join;
|
||||
if (join == FL_JOIN_MITER) c_join = CAIRO_LINE_JOIN_MITER;
|
||||
else if (join == FL_JOIN_ROUND)c_join = CAIRO_LINE_JOIN_ROUND;
|
||||
else if (join == FL_JOIN_BEVEL) c_join = CAIRO_LINE_JOIN_BEVEL;
|
||||
else c_join = CAIRO_LINE_JOIN_MITER;
|
||||
cairo_set_line_join(cairo_, c_join);
|
||||
|
||||
double *ddashes = NULL;
|
||||
int l = 0;
|
||||
if (dashes && *dashes){
|
||||
ddashes = new double[strlen(dashes)];
|
||||
while (dashes[l]) {ddashes[l] = dashes[l]; l++; }
|
||||
} else if (style & 0xff) {
|
||||
ddashes = new double[6];
|
||||
if (style & 0x200){ // round and square caps, dash length need to be adjusted
|
||||
const double *dt = dashes_cap[style & 0xff];
|
||||
while (*dt >= 0){
|
||||
ddashes[l++] = width * (*dt);
|
||||
dt++;
|
||||
}
|
||||
} else {
|
||||
const int *ds = dashes_flat[style & 0xff];
|
||||
while (*ds >= 0){
|
||||
ddashes[l++] = width * (*ds);
|
||||
ds++;
|
||||
}
|
||||
}
|
||||
}
|
||||
cairo_set_dash(cairo_, ddashes, l, 0);
|
||||
delete[] ddashes;
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::color(unsigned char r, unsigned char g, unsigned char b) {
|
||||
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
|
||||
cr_ = r; cg_ = g; cb_ = b;
|
||||
double fr, fg, fb;
|
||||
fr = r/255.0;
|
||||
fg = g/255.0;
|
||||
fb = b/255.0;
|
||||
cairo_set_source_rgb(cairo_, fr, fg, fb);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::color(Fl_Color c) {
|
||||
Fl::get_color(c, cr_, cg_, cb_);
|
||||
Fl_Cairo_Graphics_Driver::color(cr_, cg_, cb_);
|
||||
}
|
||||
|
||||
Fl_Color Fl_Cairo_Graphics_Driver::color() { return Fl_Graphics_Driver::color(); }
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::draw(int rotation, const char *str, int n, int x, int y)
|
||||
{
|
||||
cairo_save(cairo_);
|
||||
cairo_translate(cairo_, x, y);
|
||||
cairo_rotate(cairo_, -rotation * M_PI / 180);
|
||||
this->transformed_draw(str, n, 0, 0);
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::transformed_draw(const char* str, int n, double x, double y) {
|
||||
if (!n) return;
|
||||
pango_layout_set_font_description(pango_layout_, pango_font_description(Fl_Graphics_Driver::font()));
|
||||
int pwidth, pheight;
|
||||
cairo_save(cairo_);
|
||||
pango_layout_set_text(pango_layout_, str, n);
|
||||
pango_layout_get_size(pango_layout_, &pwidth, &pheight);
|
||||
if (pwidth > 0) {
|
||||
double s = width(str, n);
|
||||
cairo_translate(cairo_, x, y - height() + descent());
|
||||
s = (s/pwidth) * PANGO_SCALE;
|
||||
cairo_scale(cairo_, s, s);
|
||||
pango_cairo_show_layout(cairo_, pango_layout_);
|
||||
}
|
||||
cairo_restore(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::rtl_draw(const char* str, int n, int x, int y) {
|
||||
int w = (int)width(str, n);
|
||||
transformed_draw(str, n, x - w, y);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::concat(){
|
||||
cairo_matrix_t mat = {fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y};
|
||||
cairo_transform(cairo_, &mat);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::reconcat(){
|
||||
cairo_matrix_t mat = {fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y};
|
||||
cairo_status_t stat = cairo_matrix_invert(&mat);
|
||||
if (stat != CAIRO_STATUS_SUCCESS) {
|
||||
fputs("error in cairo_matrix_invert\n", stderr);
|
||||
}
|
||||
cairo_transform(cairo_, &mat);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::begin_points() {
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_new_path(cairo_);
|
||||
gap_=1;
|
||||
shape_=POINTS;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::begin_line() {
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_new_path(cairo_);
|
||||
gap_=1;
|
||||
shape_=LINE;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::begin_loop() {
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_new_path(cairo_);
|
||||
gap_=1;
|
||||
shape_=LOOP;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::begin_polygon() {
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_new_path(cairo_);
|
||||
gap_=1;
|
||||
shape_=POLYGON;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::vertex(double x, double y) {
|
||||
if(shape_==POINTS){
|
||||
cairo_move_to(cairo_, x, y);
|
||||
gap_=1;
|
||||
return;
|
||||
}
|
||||
if(gap_){
|
||||
cairo_move_to(cairo_, x, y);
|
||||
gap_=0;
|
||||
}else
|
||||
cairo_line_to(cairo_, x, y);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3)
|
||||
{
|
||||
if(shape_==NONE) return;
|
||||
if(gap_)
|
||||
cairo_move_to(cairo_, x, y);
|
||||
else
|
||||
cairo_line_to(cairo_, x, y);
|
||||
gap_=0;
|
||||
cairo_curve_to(cairo_, x1 , y1 , x2 , y2 , x3 , y3);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::circle(double x, double y, double r){
|
||||
if (shape_==NONE){
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_arc(cairo_, x, y, r, 0, 2*M_PI);
|
||||
reconcat();
|
||||
cairo_restore(cairo_);
|
||||
} else
|
||||
cairo_arc(cairo_, x, y, r, 0, 2*M_PI);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::arc(double x, double y, double r, double start, double a){
|
||||
if (shape_==NONE) return;
|
||||
gap_ = 0;
|
||||
if(start > a)
|
||||
cairo_arc(cairo_, x, y, r, -start*M_PI/180, -a*M_PI/180);
|
||||
else
|
||||
cairo_arc_negative(cairo_, x, y, r, -start*M_PI/180, -a*M_PI/180);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::arc(int x, int y, int w, int h, double a1, double a2) {
|
||||
if (w <= 1 || h <= 1) return;
|
||||
cairo_save(cairo_);
|
||||
begin_line();
|
||||
cairo_translate(cairo_, x + w/2.0 -0.5 , y + h/2.0 - 0.5);
|
||||
cairo_scale(cairo_, (w-1)/2.0 , (h-1)/2.0);
|
||||
arc(0,0,1,a2,a1);
|
||||
cairo_scale(cairo_, 2.0/(w-1) , 2.0/(h-1));
|
||||
cairo_translate(cairo_, -x - w/2.0 +0.5 , -y - h/2.0 +0.5);
|
||||
end_line();
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::pie(int x, int y, int w, int h, double a1, double a2) {
|
||||
cairo_save(cairo_);
|
||||
begin_polygon();
|
||||
cairo_translate(cairo_, x + w/2.0 -0.5 , y + h/2.0 - 0.5);
|
||||
cairo_scale(cairo_, (w-1)/2.0 , (h-1)/2.0);
|
||||
vertex(0,0);
|
||||
arc(0.0,0.0, 1, a2, a1);
|
||||
end_polygon();
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::end_points() {
|
||||
end_line();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::end_line() {
|
||||
gap_=1;
|
||||
reconcat();
|
||||
cairo_stroke(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
shape_=NONE;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::end_loop(){
|
||||
gap_=1;
|
||||
reconcat();
|
||||
cairo_close_path(cairo_);
|
||||
cairo_stroke(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
shape_=NONE;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::end_polygon() {
|
||||
gap_=1;
|
||||
reconcat();
|
||||
cairo_close_path(cairo_);
|
||||
cairo_fill(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
shape_=NONE;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::transformed_vertex(double x, double y) {
|
||||
reconcat();
|
||||
if(gap_){
|
||||
cairo_move_to(cairo_, x, y);
|
||||
gap_=0;
|
||||
}else
|
||||
cairo_line_to(cairo_, x, y);
|
||||
concat();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::push_clip(int x, int y, int w, int h) {
|
||||
Clip * c=new Clip();
|
||||
clip_box(x,y,w,h,c->x,c->y,c->w,c->h);
|
||||
c->prev=clip_;
|
||||
clip_=c;
|
||||
cairo_save(cairo_);
|
||||
cairo_rectangle(cairo_, clip_->x-0.5 , clip_->y-0.5 , clip_->w , clip_->h);
|
||||
cairo_clip(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::push_no_clip() {
|
||||
Clip * c = new Clip();
|
||||
c->prev=clip_;
|
||||
clip_=c;
|
||||
clip_->x = clip_->y = clip_->w = clip_->h = -1;
|
||||
cairo_save(cairo_);
|
||||
cairo_reset_clip(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::pop_clip() {
|
||||
if(!clip_)return;
|
||||
Clip * c=clip_;
|
||||
clip_=clip_->prev;
|
||||
delete c;
|
||||
cairo_restore(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::ps_origin(int x, int y) {
|
||||
cairo_restore(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
cairo_save(cairo_);
|
||||
cairo_scale(cairo_, scale_x, scale_y);
|
||||
cairo_translate(cairo_, x, y);
|
||||
cairo_rotate(cairo_, angle * M_PI / 180);
|
||||
cairo_save(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::ps_translate(int x, int y)
|
||||
{
|
||||
cairo_save(cairo_);
|
||||
cairo_translate(cairo_, x, y);
|
||||
cairo_save(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::ps_untranslate(void)
|
||||
{
|
||||
cairo_restore(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::check_status(void) {
|
||||
#ifdef DEBUG
|
||||
if (cairo_status(cairo_) != CAIRO_STATUS_SUCCESS) {
|
||||
fprintf(stderr,"we have a problem");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data, int ix, int iy, int iw, int ih, int D)
|
||||
{
|
||||
uchar *array = new uchar[iw * D * ih];
|
||||
for (int l = 0; l < ih; l++) {
|
||||
call(data, 0, l, iw, array + l*D*iw);
|
||||
if (D%2 == 0) for (int i = 0; i < iw; i++) {
|
||||
*(array + l*D*iw + i*D + D-1) = 0xff;
|
||||
}
|
||||
}
|
||||
Fl_RGB_Image *rgb = new Fl_RGB_Image(array, iw, ih, D);
|
||||
rgb->alloc_array = 1;
|
||||
draw_rgb(rgb, ix, iy, iw, ih, 0, 0);
|
||||
delete rgb;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::draw_image_mono(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD)
|
||||
{
|
||||
struct callback_data cb_data;
|
||||
if (!LD) LD = iw*abs(D);
|
||||
if (D<0) data += iw*abs(D);
|
||||
cb_data.data = data;
|
||||
cb_data.D = D;
|
||||
cb_data.LD = LD;
|
||||
draw_image(draw_image_cb, &cb_data, ix, iy, iw, ih, abs(D));
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb call, void *data, int ix, int iy, int iw, int ih, int D)
|
||||
{
|
||||
draw_image(call, data, ix, iy, iw, ih, D);
|
||||
}
|
||||
|
||||
static void destroy_BGRA(void *data) {
|
||||
delete[] (uchar*)data;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
Fl_RGB_Image *rgb = new Fl_RGB_Image(pxm);
|
||||
draw_rgb_bitmap_(rgb, XP, YP, WP, HP, cx, cy);
|
||||
delete rgb;
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
draw_rgb_bitmap_(rgb, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::draw_bitmap(Fl_Bitmap *bitmap,int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
draw_rgb_bitmap_(bitmap, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
|
||||
void Fl_Cairo_Graphics_Driver::draw_rgb_bitmap_(Fl_Image *img,int XP, int YP, int WP, int HP, int cx, int cy)
|
||||
{
|
||||
cairo_surface_t *surf;
|
||||
cairo_format_t format = (img->d() >= 1 ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_A1);
|
||||
int stride = cairo_format_stride_for_width(format, img->data_w());
|
||||
uchar *BGRA = new uchar[stride * img->data_h()];
|
||||
memset(BGRA, 0, stride * img->data_h());
|
||||
if (img->d() >= 1) { // process Fl_RGB_Image of all depths
|
||||
Fl_RGB_Image *rgb = (Fl_RGB_Image*)img;
|
||||
int lrgb = rgb->ld() ? rgb->ld() : rgb->data_w() * rgb->d();
|
||||
uchar A = 0xff, R,G,B, *q;
|
||||
const uchar *r;
|
||||
float f = 1;
|
||||
if (rgb->d() >= 3) { // color images
|
||||
for (int j = 0; j < rgb->data_h(); j++) {
|
||||
r = rgb->array + j * lrgb;
|
||||
q = BGRA + j * stride;
|
||||
for (int i = 0; i < rgb->data_w(); i++) {
|
||||
R = *r;
|
||||
G = *(r+1);
|
||||
B = *(r+2);
|
||||
if (rgb->d() == 4) {
|
||||
A = *(r+3);
|
||||
f = float(A)/0xff;
|
||||
}
|
||||
*q = B * f;
|
||||
*(q+1) = G * f;
|
||||
*(q+2) = R * f;
|
||||
*(q+3) = A;
|
||||
r += rgb->d(); q += 4;
|
||||
}
|
||||
}
|
||||
} else if (rgb->d() == 1 || rgb->d() == 2) { // B&W
|
||||
for (int j = 0; j < rgb->data_h(); j++) {
|
||||
r = rgb->array + j * lrgb;
|
||||
q = BGRA + j * stride;
|
||||
for (int i = 0; i < rgb->data_w(); i++) {
|
||||
G = *r;
|
||||
if (rgb->d() == 2) {
|
||||
A = *(r+1);
|
||||
f = float(A)/0xff;
|
||||
}
|
||||
*(q) = G * f;
|
||||
*(q+1) = G * f;
|
||||
*(q+2) = G * f;
|
||||
*(q+3) = A;
|
||||
r += rgb->d(); q += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Fl_Bitmap *bm = (Fl_Bitmap*)img;
|
||||
uchar *r, p;
|
||||
unsigned *q;
|
||||
for (int j = 0; j < bm->data_h(); j++) {
|
||||
r = (uchar*)bm->array + j * ((bm->data_w() + 7)/8);
|
||||
q = (unsigned*)(BGRA + j * stride);
|
||||
unsigned k = 0, mask32 = 1;
|
||||
p = *r;
|
||||
for (int i = 0; i < bm->data_w(); i++) {
|
||||
if (p&1) (*q) |= mask32;
|
||||
k++;
|
||||
if (k % 8 != 0) p >>= 1; else p = *(++r);
|
||||
if (k % 32 != 0) mask32 <<= 1; else {q++; mask32 = 1;}
|
||||
}
|
||||
}
|
||||
}
|
||||
surf = cairo_image_surface_create_for_data(BGRA, format, img->data_w(), img->data_h(), stride);
|
||||
if (cairo_surface_status(surf) == CAIRO_STATUS_SUCCESS) {
|
||||
static cairo_user_data_key_t key = {};
|
||||
(void)cairo_surface_set_user_data(surf, &key, BGRA, destroy_BGRA);
|
||||
cairo_pattern_t *pat = cairo_pattern_create_for_surface(surf);
|
||||
cairo_save(cairo_);
|
||||
cairo_rectangle(cairo_, XP-0.5, YP-0.5, WP+1, HP+1);
|
||||
cairo_clip(cairo_);
|
||||
if (img->d() >= 1) cairo_set_source(cairo_, pat);
|
||||
cairo_matrix_t matrix;
|
||||
cairo_matrix_init_scale(&matrix, double(img->data_w())/(img->w()+1), double(img->data_h())/(img->h()+1));
|
||||
cairo_matrix_translate(&matrix, -XP+0.5+cx, -YP+0.5+cy);
|
||||
cairo_pattern_set_matrix(pat, &matrix);
|
||||
cairo_mask(cairo_, pat);
|
||||
cairo_pattern_destroy(pat);
|
||||
cairo_surface_destroy(surf);
|
||||
cairo_restore(cairo_);
|
||||
check_status();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USE_PANGO
|
||||
@ -100,6 +100,7 @@ Fl_PostScript_File_Device::~Fl_PostScript_File_Device() {
|
||||
\{
|
||||
*/
|
||||
|
||||
#if ! USE_PANGO
|
||||
static const int dashes_flat[5][7]={
|
||||
{-1,0,0,0,0,0,0},
|
||||
{3,1,-1,0,0,0,0},
|
||||
@ -116,6 +117,7 @@ static const double dashes_cap[5][7]={
|
||||
{2,2,0.01,1.99,-1,0,0},
|
||||
{2,2,0.01,1.99,0.01,1.99,-1}
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief The constructor.
|
||||
@ -1500,448 +1502,8 @@ int Fl_PostScript_Graphics_Driver::start_eps(int width, int height) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::rectf(int x, int y, int w, int h) {
|
||||
cairo_rectangle(cairo_, x, y, w, h);
|
||||
cairo_fill(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::rect(int x, int y, int w, int h) {
|
||||
cairo_rectangle(cairo_, x, y, w, h);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::line(int x1, int y1, int x2, int y2) {
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_stroke(cairo_);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::line(int x0, int y0, int x1, int y1, int x2, int y2) {
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_stroke(cairo_);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x1, y);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x1, y);
|
||||
cairo_line_to(cairo_, x1, y2);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x1, y);
|
||||
cairo_line_to(cairo_, x1, y2);
|
||||
cairo_line_to(cairo_, x3, y2);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x, y1);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x, y1);
|
||||
cairo_line_to(cairo_, x2, y1);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
|
||||
cairo_move_to(cairo_, x, y);
|
||||
cairo_line_to(cairo_, x, y1);
|
||||
cairo_line_to(cairo_, x2, y1);
|
||||
cairo_line_to(cairo_, x2, y3);
|
||||
cairo_stroke(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) {
|
||||
cairo_save(cairo_);
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_close_path(cairo_);
|
||||
cairo_stroke(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
cairo_save(cairo_);
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_line_to(cairo_, x3, y3);
|
||||
cairo_close_path(cairo_);
|
||||
cairo_stroke(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
|
||||
cairo_save(cairo_);
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_close_path(cairo_);
|
||||
cairo_fill(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
cairo_save(cairo_);
|
||||
cairo_new_path(cairo_);
|
||||
cairo_move_to(cairo_, x0, y0);
|
||||
cairo_line_to(cairo_, x1, y1);
|
||||
cairo_line_to(cairo_, x2, y2);
|
||||
cairo_line_to(cairo_, x3, y3);
|
||||
cairo_close_path(cairo_);
|
||||
cairo_fill(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::line_style(int style, int width, char* dashes) {
|
||||
linewidth_=width;
|
||||
linestyle_=style;
|
||||
if(dashes){
|
||||
if(dashes != linedash_)
|
||||
strcpy(linedash_,dashes);
|
||||
|
||||
} else
|
||||
linedash_[0]=0;
|
||||
char width0 = 0;
|
||||
if (!width){
|
||||
width=1; //for screen drawing compatibility
|
||||
width0=1;
|
||||
}
|
||||
cairo_set_line_width(cairo_, width);
|
||||
|
||||
if(!style && (!dashes || !(*dashes)) && width0) //system lines
|
||||
style = FL_CAP_SQUARE;
|
||||
|
||||
int cap = (style &0xf00);
|
||||
cairo_line_cap_t c_cap;
|
||||
if (cap == FL_CAP_SQUARE) c_cap = CAIRO_LINE_CAP_SQUARE;
|
||||
else if (cap == FL_CAP_FLAT) c_cap = CAIRO_LINE_CAP_BUTT;
|
||||
else if (cap == FL_CAP_ROUND) c_cap = CAIRO_LINE_CAP_ROUND;
|
||||
else c_cap = CAIRO_LINE_CAP_BUTT;
|
||||
cairo_set_line_cap(cairo_, c_cap);
|
||||
|
||||
int join = (style & 0xf000);
|
||||
cairo_line_join_t c_join;
|
||||
if (join == FL_JOIN_MITER) c_join = CAIRO_LINE_JOIN_MITER;
|
||||
else if (join == FL_JOIN_ROUND)c_join = CAIRO_LINE_JOIN_ROUND;
|
||||
else if (join == FL_JOIN_BEVEL) c_join = CAIRO_LINE_JOIN_BEVEL;
|
||||
else c_join = CAIRO_LINE_JOIN_MITER;
|
||||
cairo_set_line_join(cairo_, c_join);
|
||||
|
||||
double *ddashes = NULL;
|
||||
int l = 0;
|
||||
if (dashes && *dashes){
|
||||
ddashes = new double[strlen(dashes)];
|
||||
while (dashes[l]) {ddashes[l] = dashes[l]; l++; }
|
||||
} else if (style & 0xff) {
|
||||
ddashes = new double[6];
|
||||
if (style & 0x200){ // round and square caps, dash length need to be adjusted
|
||||
const double *dt = dashes_cap[style & 0xff];
|
||||
while (*dt >= 0){
|
||||
ddashes[l++] = width * (*dt);
|
||||
dt++;
|
||||
}
|
||||
} else {
|
||||
const int *ds = dashes_flat[style & 0xff];
|
||||
while (*ds >= 0){
|
||||
ddashes[l++] = width * (*ds);
|
||||
ds++;
|
||||
}
|
||||
}
|
||||
}
|
||||
cairo_set_dash(cairo_, ddashes, l, 0);
|
||||
delete[] ddashes;
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::color(unsigned char r, unsigned char g, unsigned char b) {
|
||||
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
|
||||
cr_ = r; cg_ = g; cb_ = b;
|
||||
double fr, fg, fb;
|
||||
fr = r/255.0;
|
||||
fg = g/255.0;
|
||||
fb = b/255.0;
|
||||
cairo_set_source_rgb(cairo_, fr, fg, fb);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::draw(int rotation, const char *str, int n, int x, int y)
|
||||
{
|
||||
cairo_save(cairo_);
|
||||
cairo_translate(cairo_, x, y);
|
||||
cairo_rotate(cairo_, -rotation * M_PI / 180);
|
||||
this->transformed_draw(str, n, 0, 0);
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, double x, double y) {
|
||||
if (!n) return;
|
||||
pango_layout_set_font_description(pango_layout_, Fl_Xlib_Graphics_Driver::pango_font_description(Fl_Graphics_Driver::font()));
|
||||
int pwidth, pheight;
|
||||
cairo_save(cairo_);
|
||||
pango_layout_set_text(pango_layout_, str, n);
|
||||
pango_layout_get_size(pango_layout_, &pwidth, &pheight);
|
||||
if (pwidth > 0) {
|
||||
double s = width(str, n);
|
||||
cairo_translate(cairo_, x, y - height() + descent());
|
||||
s = (s/pwidth) * PANGO_SCALE;
|
||||
cairo_scale(cairo_, s, s);
|
||||
pango_cairo_show_layout(cairo_, pango_layout_);
|
||||
}
|
||||
cairo_restore(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::rtl_draw(const char* str, int n, int x, int y) {
|
||||
int w = (int)width(str, n);
|
||||
transformed_draw(str, n, x - w, y);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::concat(){
|
||||
cairo_matrix_t mat = {fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y};
|
||||
cairo_transform(cairo_, &mat);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::reconcat(){
|
||||
cairo_matrix_t mat = {fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y};
|
||||
cairo_status_t stat = cairo_matrix_invert(&mat);
|
||||
if (stat != CAIRO_STATUS_SUCCESS) {
|
||||
fputs("error in cairo_matrix_invert\n", stderr);
|
||||
}
|
||||
cairo_transform(cairo_, &mat);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::begin_points() {
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_new_path(cairo_);
|
||||
gap_=1;
|
||||
shape_=POINTS;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::begin_line() {
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_new_path(cairo_);
|
||||
gap_=1;
|
||||
shape_=LINE;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::begin_loop() {
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_new_path(cairo_);
|
||||
gap_=1;
|
||||
shape_=LOOP;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::begin_polygon() {
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_new_path(cairo_);
|
||||
gap_=1;
|
||||
shape_=POLYGON;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::vertex(double x, double y) {
|
||||
if(shape_==POINTS){
|
||||
cairo_move_to(cairo_, x, y);
|
||||
gap_=1;
|
||||
return;
|
||||
}
|
||||
if(gap_){
|
||||
cairo_move_to(cairo_, x, y);
|
||||
gap_=0;
|
||||
}else
|
||||
cairo_line_to(cairo_, x, y);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3)
|
||||
{
|
||||
if(shape_==NONE) return;
|
||||
if(gap_)
|
||||
cairo_move_to(cairo_, x, y);
|
||||
else
|
||||
cairo_line_to(cairo_, x, y);
|
||||
gap_=0;
|
||||
cairo_curve_to(cairo_, x1 , y1 , x2 , y2 , x3 , y3);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::circle(double x, double y, double r){
|
||||
if (shape_==NONE){
|
||||
cairo_save(cairo_);
|
||||
concat();
|
||||
cairo_arc(cairo_, x, y, r, 0, 2*M_PI);
|
||||
reconcat();
|
||||
cairo_restore(cairo_);
|
||||
} else
|
||||
cairo_arc(cairo_, x, y, r, 0, 2*M_PI);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::arc(double x, double y, double r, double start, double a){
|
||||
if (shape_==NONE) return;
|
||||
gap_ = 0;
|
||||
if(start > a)
|
||||
cairo_arc(cairo_, x, y, r, -start*M_PI/180, -a*M_PI/180);
|
||||
else
|
||||
cairo_arc_negative(cairo_, x, y, r, -start*M_PI/180, -a*M_PI/180);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::arc(int x, int y, int w, int h, double a1, double a2) {
|
||||
if (w <= 1 || h <= 1) return;
|
||||
cairo_save(cairo_);
|
||||
begin_line();
|
||||
cairo_translate(cairo_, x + w/2.0 -0.5 , y + h/2.0 - 0.5);
|
||||
cairo_scale(cairo_, (w-1)/2.0 , (h-1)/2.0);
|
||||
arc(0,0,1,a2,a1);
|
||||
cairo_scale(cairo_, 2.0/(w-1) , 2.0/(h-1));
|
||||
cairo_translate(cairo_, -x - w/2.0 +0.5 , -y - h/2.0 +0.5);
|
||||
end_line();
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::pie(int x, int y, int w, int h, double a1, double a2) {
|
||||
cairo_save(cairo_);
|
||||
begin_polygon();
|
||||
cairo_translate(cairo_, x + w/2.0 -0.5 , y + h/2.0 - 0.5);
|
||||
cairo_scale(cairo_, (w-1)/2.0 , (h-1)/2.0);
|
||||
vertex(0,0);
|
||||
arc(0.0,0.0, 1, a2, a1);
|
||||
end_polygon();
|
||||
cairo_restore(cairo_);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::end_points() {
|
||||
end_line();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::end_line() {
|
||||
gap_=1;
|
||||
reconcat();
|
||||
cairo_stroke(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
shape_=NONE;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::end_loop(){
|
||||
gap_=1;
|
||||
reconcat();
|
||||
cairo_close_path(cairo_);
|
||||
cairo_stroke(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
shape_=NONE;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::end_polygon() {
|
||||
gap_=1;
|
||||
reconcat();
|
||||
cairo_close_path(cairo_);
|
||||
cairo_fill(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
shape_=NONE;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::transformed_vertex(double x, double y) {
|
||||
reconcat();
|
||||
if(gap_){
|
||||
cairo_move_to(cairo_, x, y);
|
||||
gap_=0;
|
||||
}else
|
||||
cairo_line_to(cairo_, x, y);
|
||||
concat();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::push_clip(int x, int y, int w, int h) {
|
||||
Clip * c=new Clip();
|
||||
clip_box(x,y,w,h,c->x,c->y,c->w,c->h);
|
||||
c->prev=clip_;
|
||||
clip_=c;
|
||||
cairo_save(cairo_);
|
||||
cairo_rectangle(cairo_, clip_->x-0.5 , clip_->y-0.5 , clip_->w , clip_->h);
|
||||
cairo_clip(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::push_no_clip() {
|
||||
Clip * c = new Clip();
|
||||
c->prev=clip_;
|
||||
clip_=c;
|
||||
clip_->x = clip_->y = clip_->w = clip_->h = -1;
|
||||
cairo_save(cairo_);
|
||||
cairo_reset_clip(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::pop_clip() {
|
||||
if(!clip_)return;
|
||||
Clip * c=clip_;
|
||||
clip_=clip_->prev;
|
||||
delete c;
|
||||
cairo_restore(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::ps_origin(int x, int y) {
|
||||
cairo_restore(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
cairo_save(cairo_);
|
||||
cairo_scale(cairo_, scale_x, scale_y);
|
||||
cairo_translate(cairo_, x, y);
|
||||
cairo_rotate(cairo_, angle * M_PI / 180);
|
||||
cairo_save(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::ps_translate(int x, int y)
|
||||
{
|
||||
cairo_save(cairo_);
|
||||
cairo_translate(cairo_, x, y);
|
||||
cairo_save(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::ps_untranslate(void)
|
||||
{
|
||||
cairo_restore(cairo_);
|
||||
cairo_restore(cairo_);
|
||||
check_status();
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::check_status(void) {
|
||||
#ifdef DEBUG
|
||||
if (cairo_status(cairo_) != CAIRO_STATUS_SUCCESS) {
|
||||
fprintf(stderr,"we have a problem");
|
||||
}
|
||||
#endif
|
||||
PangoFontDescription* Fl_PostScript_Graphics_Driver::pango_font_description(Fl_Font fnum) {
|
||||
return Fl_Xlib_Graphics_Driver::pango_font_description(fnum);
|
||||
}
|
||||
|
||||
#endif // USE_PANGO
|
||||
|
||||
@ -28,11 +28,6 @@
|
||||
#define USE_PANGO 0
|
||||
#endif
|
||||
|
||||
#if USE_PANGO
|
||||
typedef struct _cairo cairo_t;
|
||||
typedef struct _PangoLayout PangoLayout;
|
||||
#endif
|
||||
|
||||
/**
|
||||
\cond DriverDev
|
||||
\addtogroup DriverDeveloper
|
||||
@ -42,14 +37,51 @@ typedef struct _PangoLayout PangoLayout;
|
||||
/**
|
||||
PostScript graphical backend.
|
||||
*/
|
||||
#if USE_PANGO
|
||||
|
||||
#include "../Cairo/Fl_Cairo_Graphics_Driver.H"
|
||||
|
||||
class FL_EXPORT Fl_PostScript_Graphics_Driver : public Fl_Cairo_Graphics_Driver {
|
||||
public:
|
||||
FILE *output;
|
||||
Fl_PostScript_Close_Command close_cmd_;
|
||||
enum Fl_Paged_Device::Page_Format page_format_;
|
||||
char *ps_filename_;
|
||||
int nPages;
|
||||
|
||||
Fl_PostScript_Graphics_Driver();
|
||||
~Fl_PostScript_Graphics_Driver();
|
||||
void close_command(Fl_PostScript_Close_Command cmd){close_cmd_=cmd;};
|
||||
FILE * file() {return output;};
|
||||
void page(double pw, double ph, int media = 0);
|
||||
void page(int format);
|
||||
int start_postscript (int pagecount, enum Fl_Paged_Device::Page_Format format, enum Fl_Paged_Device::Page_Layout layout);
|
||||
int start_eps(int width, int height);
|
||||
void draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD);
|
||||
void draw_image(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int h, int delta=3) {
|
||||
Fl_Cairo_Graphics_Driver::draw_image(call, data, x,y,w,h,delta);
|
||||
}
|
||||
void font(int f, int s);
|
||||
Fl_Font font();
|
||||
double width(const char *s, int n);
|
||||
double width(unsigned u);
|
||||
int height();
|
||||
int descent();
|
||||
void text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h);
|
||||
void color(Fl_Color c);
|
||||
void color(uchar r, uchar g, uchar b) {Fl_Cairo_Graphics_Driver::color(r,g,b);}
|
||||
Fl_Color color();
|
||||
void point(int x, int y);
|
||||
int not_clipped(int x, int y, int w, int h);
|
||||
int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H);
|
||||
virtual PangoFontDescription* pango_font_description(Fl_Font fnum);
|
||||
virtual int has_feature(driver_feature feature_mask) { return feature_mask & PRINTER; }
|
||||
};
|
||||
|
||||
#else // USE_PANGO
|
||||
|
||||
class FL_EXPORT Fl_PostScript_Graphics_Driver : public Fl_Graphics_Driver {
|
||||
private:
|
||||
#if USE_PANGO
|
||||
cairo_t *cairo_;
|
||||
PangoLayout *pango_layout_;
|
||||
void draw_rgb_bitmap_(Fl_Image *img,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
#else
|
||||
void transformed_draw_extra(const char* str, int n, double x, double y, int w, bool rtl);
|
||||
void *prepare_rle85();
|
||||
void write_rle85(uchar b, void *data);
|
||||
@ -58,14 +90,10 @@ private:
|
||||
void write85(void *data, const uchar *p, int len);
|
||||
void close85(void *data);
|
||||
int scale_for_image_(Fl_Image *img, int XP, int YP, int WP, int HP,int cx, int cy);
|
||||
#endif
|
||||
protected:
|
||||
#if ! USE_PANGO
|
||||
uchar **mask_bitmap() {return &mask;}
|
||||
#endif
|
||||
public:
|
||||
Fl_PostScript_Graphics_Driver();
|
||||
#ifndef FL_DOXYGEN
|
||||
enum SHAPE {NONE=0, LINE, LOOP, POLYGON, POINTS};
|
||||
|
||||
class Clip {
|
||||
@ -78,11 +106,6 @@ public:
|
||||
int lang_level_;
|
||||
int gap_;
|
||||
int pages_;
|
||||
#if USE_PANGO
|
||||
cairo_t *cr() { return cairo_; }
|
||||
PangoLayout *pango_layout() {return pango_layout_;};
|
||||
void check_status(void);
|
||||
#else
|
||||
int interpolate_; //interpolation of images
|
||||
uchar * mask;
|
||||
int mx; // width of mask;
|
||||
@ -98,7 +121,6 @@ public:
|
||||
\return value returned by vfprintf() call
|
||||
*/
|
||||
int clocale_printf(const char *format, ...);
|
||||
#endif // USE_PANGO
|
||||
|
||||
enum SHAPE shape_;
|
||||
int linewidth_;// need for clipping, lang level 1-2
|
||||
@ -141,7 +163,6 @@ public:
|
||||
|
||||
void page(double pw, double ph, int media = 0);
|
||||
void page(int format);
|
||||
#endif // FL_DOXYGEN
|
||||
|
||||
// implementation of drawing methods
|
||||
void color(Fl_Color c);
|
||||
@ -224,6 +245,7 @@ public:
|
||||
void ps_untranslate();
|
||||
};
|
||||
|
||||
#endif // USE_PANGO
|
||||
/**
|
||||
\}
|
||||
\endcond
|
||||
|
||||
@ -635,145 +635,6 @@ int Fl_PostScript_Graphics_Driver::scale_for_image_(Fl_Image *img, int XP, int Y
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // USE_PANGO
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data, int ix, int iy, int iw, int ih, int D)
|
||||
{
|
||||
uchar *array = new uchar[iw * D * ih];
|
||||
for (int l = 0; l < ih; l++) {
|
||||
call(data, 0, l, iw, array + l*D*iw);
|
||||
if (D%2 == 0) for (int i = 0; i < iw; i++) {
|
||||
*(array + l*D*iw + i*D + D-1) = 0xff;
|
||||
}
|
||||
}
|
||||
Fl_RGB_Image *rgb = new Fl_RGB_Image(array, iw, ih, D);
|
||||
rgb->alloc_array = 1;
|
||||
draw_rgb(rgb, ix, iy, iw, ih, 0, 0);
|
||||
delete rgb;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::draw_image_mono(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD)
|
||||
{
|
||||
struct callback_data cb_data;
|
||||
if (!LD) LD = iw*abs(D);
|
||||
if (D<0) data += iw*abs(D);
|
||||
cb_data.data = data;
|
||||
cb_data.D = D;
|
||||
cb_data.LD = LD;
|
||||
draw_image(draw_image_cb, &cb_data, ix, iy, iw, ih, abs(D));
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb call, void *data, int ix, int iy, int iw, int ih, int D)
|
||||
{
|
||||
draw_image(call, data, ix, iy, iw, ih, D);
|
||||
}
|
||||
|
||||
static void destroy_BGRA(void *data) {
|
||||
delete[] (uchar*)data;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
Fl_RGB_Image *rgb = new Fl_RGB_Image(pxm);
|
||||
draw_rgb_bitmap_(rgb, XP, YP, WP, HP, cx, cy);
|
||||
delete rgb;
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
draw_rgb_bitmap_(rgb, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::draw_bitmap(Fl_Bitmap *bitmap,int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
draw_rgb_bitmap_(bitmap, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::draw_rgb_bitmap_(Fl_Image *img,int XP, int YP, int WP, int HP, int cx, int cy)
|
||||
{
|
||||
cairo_surface_t *surf;
|
||||
cairo_format_t format = (img->d() >= 1 ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_A1);
|
||||
int stride = cairo_format_stride_for_width(format, img->data_w());
|
||||
uchar *BGRA = new uchar[stride * img->data_h()];
|
||||
memset(BGRA, 0, stride * img->data_h());
|
||||
if (img->d() >= 1) { // process Fl_RGB_Image of all depths
|
||||
Fl_RGB_Image *rgb = (Fl_RGB_Image*)img;
|
||||
int lrgb = rgb->ld() ? rgb->ld() : rgb->data_w() * rgb->d();
|
||||
uchar A = 0xff, R,G,B, *q;
|
||||
const uchar *r;
|
||||
float f = 1;
|
||||
if (rgb->d() >= 3) { // color images
|
||||
for (int j = 0; j < rgb->data_h(); j++) {
|
||||
r = rgb->array + j * lrgb;
|
||||
q = BGRA + j * stride;
|
||||
for (int i = 0; i < rgb->data_w(); i++) {
|
||||
R = *r;
|
||||
G = *(r+1);
|
||||
B = *(r+2);
|
||||
if (rgb->d() == 4) {
|
||||
A = *(r+3);
|
||||
f = float(A)/0xff;
|
||||
}
|
||||
*q = B * f;
|
||||
*(q+1) = G * f;
|
||||
*(q+2) = R * f;
|
||||
*(q+3) = A;
|
||||
r += rgb->d(); q += 4;
|
||||
}
|
||||
}
|
||||
} else if (rgb->d() == 1 || rgb->d() == 2) { // B&W
|
||||
for (int j = 0; j < rgb->data_h(); j++) {
|
||||
r = rgb->array + j * lrgb;
|
||||
q = BGRA + j * stride;
|
||||
for (int i = 0; i < rgb->data_w(); i++) {
|
||||
G = *r;
|
||||
if (rgb->d() == 2) {
|
||||
A = *(r+1);
|
||||
f = float(A)/0xff;
|
||||
}
|
||||
*(q) = G * f;
|
||||
*(q+1) = G * f;
|
||||
*(q+2) = G * f;
|
||||
*(q+3) = A;
|
||||
r += rgb->d(); q += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Fl_Bitmap *bm = (Fl_Bitmap*)img;
|
||||
uchar *r, p;
|
||||
unsigned *q;
|
||||
for (int j = 0; j < bm->data_h(); j++) {
|
||||
r = (uchar*)bm->array + j * ((bm->data_w() + 7)/8);
|
||||
q = (unsigned*)(BGRA + j * stride);
|
||||
unsigned k = 0, mask32 = 1;
|
||||
p = *r;
|
||||
for (int i = 0; i < bm->data_w(); i++) {
|
||||
if (p&1) (*q) |= mask32;
|
||||
k++;
|
||||
if (k % 8 != 0) p >>= 1; else p = *(++r);
|
||||
if (k % 32 != 0) mask32 <<= 1; else {q++; mask32 = 1;}
|
||||
}
|
||||
}
|
||||
}
|
||||
surf = cairo_image_surface_create_for_data(BGRA, format, img->data_w(), img->data_h(), stride);
|
||||
if (cairo_surface_status(surf) == CAIRO_STATUS_SUCCESS) {
|
||||
static cairo_user_data_key_t key = {};
|
||||
(void)cairo_surface_set_user_data(surf, &key, BGRA, destroy_BGRA);
|
||||
cairo_pattern_t *pat = cairo_pattern_create_for_surface(surf);
|
||||
cairo_save(cairo_);
|
||||
cairo_rectangle(cairo_, XP-0.5, YP-0.5, WP+1, HP+1);
|
||||
cairo_clip(cairo_);
|
||||
if (img->d() >= 1) cairo_set_source(cairo_, pat);
|
||||
cairo_matrix_t matrix;
|
||||
cairo_matrix_init_scale(&matrix, double(img->data_w())/(img->w()+1), double(img->data_h())/(img->h()+1));
|
||||
cairo_matrix_translate(&matrix, -XP+0.5+cx, -YP+0.5+cy);
|
||||
cairo_pattern_set_matrix(pat, &matrix);
|
||||
cairo_mask(cairo_, pat);
|
||||
cairo_pattern_destroy(pat);
|
||||
cairo_surface_destroy(surf);
|
||||
cairo_restore(cairo_);
|
||||
check_status();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USE_PANGO
|
||||
|
||||
#endif // !defined(FL_DOXYGEN) && !defined(FL_NO_PRINT_SUPPORT)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user