diff options
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H | 140 | ||||
| -rw-r--r-- | src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx | 656 | ||||
| -rw-r--r-- | src/drivers/PostScript/Fl_PostScript.cxx | 446 | ||||
| -rw-r--r-- | src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H | 64 | ||||
| -rw-r--r-- | src/drivers/PostScript/Fl_PostScript_image.cxx | 139 |
5 files changed, 843 insertions, 602 deletions
diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H new file mode 100644 index 000000000..bbcb4144a --- /dev/null +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H @@ -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(); +}; diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx new file mode 100644 index 000000000..ff64bfed0 --- /dev/null +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx @@ -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 diff --git a/src/drivers/PostScript/Fl_PostScript.cxx b/src/drivers/PostScript/Fl_PostScript.cxx index 53811d6cf..c041923d2 100644 --- a/src/drivers/PostScript/Fl_PostScript.cxx +++ b/src/drivers/PostScript/Fl_PostScript.cxx @@ -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 diff --git a/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H b/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H index 80019fda0..5c15e0e26 100644 --- a/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H +++ b/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H @@ -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 diff --git a/src/drivers/PostScript/Fl_PostScript_image.cxx b/src/drivers/PostScript/Fl_PostScript_image.cxx index 102c1d4e2..ae53aaadc 100644 --- a/src/drivers/PostScript/Fl_PostScript_image.cxx +++ b/src/drivers/PostScript/Fl_PostScript_image.cxx @@ -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) |
