Author: manolo
Date: 2010-03-02 15:07:43 -0800 (Tue, 02 Mar 2010)
New Revision: 7196
Log:
Added image support to PostScript graphics output.

Added:
   branches/branch-1.3-Fl_Printer/src/postscript/image.cxx
Modified:
   branches/branch-1.3-Fl_Printer/FL/Fl_Device.H
   branches/branch-1.3-Fl_Printer/FL/Fl_Printer.H
   branches/branch-1.3-Fl_Printer/FL/fl_draw.H
   branches/branch-1.3-Fl_Printer/src/Fl_Bitmap.cxx
   branches/branch-1.3-Fl_Printer/src/Fl_Device.cxx
   branches/branch-1.3-Fl_Printer/src/Fl_GDI_Printer.cxx
   branches/branch-1.3-Fl_Printer/src/Fl_Image.cxx
   branches/branch-1.3-Fl_Printer/src/Fl_PS_Printer.cxx
   branches/branch-1.3-Fl_Printer/src/Fl_Pixmap.cxx
   branches/branch-1.3-Fl_Printer/src/Fl_Quartz_Printer.mm
   branches/branch-1.3-Fl_Printer/src/fl_draw_image.cxx
   branches/branch-1.3-Fl_Printer/src/fl_draw_image_mac.cxx
   branches/branch-1.3-Fl_Printer/src/fl_draw_image_win32.cxx
   branches/branch-1.3-Fl_Printer/test/device.cxx

Modified: branches/branch-1.3-Fl_Printer/FL/Fl_Device.H
===================================================================
--- branches/branch-1.3-Fl_Printer/FL/Fl_Device.H       2010-03-02 22:59:55 UTC 
(rev 7195)
+++ branches/branch-1.3-Fl_Printer/FL/Fl_Device.H       2010-03-02 23:07:43 UTC 
(rev 7196)
@@ -14,11 +14,19 @@
 #include <stdio.h>
 #endif
 
+class Fl_Image;
+class Fl_RGB_Image;
+class Fl_Pixmap;
+class Fl_Bitmap;
+typedef void (*Fl_Draw_Image_Cb)(void* ,int,int,int,uchar*);
+
 /**
  @brief A pure virtual class subclassed to send graphics output to display, 
local files, or printers.
  */
 class Fl_Device {
 protected:
+  int type_;
+  uchar bg_r_, bg_g_, bg_b_; // color for background and/or mixing if 
particular device does not support masking and/or alpha
   friend void fl_rect(int x, int y, int w, int h);
   friend void fl_rectf(int x, int y, int w, int h);
   friend void fl_line_style(int style, int width, char* dashes);
@@ -65,6 +73,11 @@
   friend void fl_begin_complex_polygon();
   friend void fl_gap();
   friend void fl_end_complex_polygon();
+  friend void fl_draw_image(const uchar*, int,int,int,int, int delta, int 
ldelta);
+  friend void fl_draw_image_mono(const uchar*, int,int,int,int, int delta, int 
ld);
+  friend void fl_draw_image(Fl_Draw_Image_Cb, void*, int,int,int,int, int 
delta);
+  friend void fl_draw_image_mono(Fl_Draw_Image_Cb, void*, int,int,int,int, int 
delta);
+  
   virtual void rect(int x, int y, int w, int h);
   virtual void rectf(int x, int y, int w, int h);
   virtual void line_style(int style, int width=0, char* dashes=0);
@@ -109,8 +122,25 @@
   virtual int not_clipped(int x, int y, int w, int h);
   virtual void push_no_clip();
   virtual void pop_clip();
+  // Images
+  virtual   void draw_image(const uchar*, int,int,int,int, int delta=3, int 
ldelta=0);
+  virtual   void draw_image_mono(const uchar*, int,int,int,int, int delta=1, 
int ld=0);
+  virtual   void draw_image(Fl_Draw_Image_Cb, void*, int,int,int,int, int 
delta=3);
+  virtual   void draw_image_mono(Fl_Draw_Image_Cb, void*, int,int,int,int, int 
delta=1);
+  // Image classes
+  virtual   void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, 
int cy);
+  virtual   void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int 
cx, int cy);
+  virtual   void draw(Fl_Bitmap * bmp,int XP, int YP, int WP, int HP, int cx, 
int cy);
   
 public:
+  enum device_types { 
+    xlib_display = 0, quartz_display, gdi_display, 
+    gdi_printer = 256, quartz_printer, postscript_device 
+  };
+  /** 
+   @brief An RTTI emulation of device classes. It returns values < 256 if it 
is a screen device 
+   */
+  int type() {return type_;};
   /**
    @brief Sets this device (display, local file, printer) as the target of 
future graphics calls.
    *
@@ -140,7 +170,7 @@
  */
 class Fl_Quartz_Display : public Fl_Display {
 public:
-  Fl_Quartz_Display() {};
+  Fl_Quartz_Display() { type_ = quartz_display; };
 };
 #endif
 #if defined(WIN32) || defined(FL_DOXYGEN)
@@ -149,7 +179,7 @@
  */
 class Fl_GDI_Display : public Fl_Display {
 public:
-  Fl_GDI_Display() {};
+  Fl_GDI_Display() { type_ = gdi_display; };
 };
 #endif
 #if !( defined(__APPLE__) || defined(WIN32)) || defined(FL_DOXYGEN)
@@ -158,7 +188,7 @@
  */
 class Fl_Xlib_Display : public Fl_Display {
 public:
-  Fl_Xlib_Display() {};
+  Fl_Xlib_Display() { type_ = xlib_display; };
 };
 #endif
 

Modified: branches/branch-1.3-Fl_Printer/FL/Fl_Printer.H
===================================================================
--- branches/branch-1.3-Fl_Printer/FL/Fl_Printer.H      2010-03-02 22:59:55 UTC 
(rev 7195)
+++ branches/branch-1.3-Fl_Printer/FL/Fl_Printer.H      2010-03-02 23:07:43 UTC 
(rev 7196)
@@ -2,6 +2,10 @@
 #define Fl_Printer_H
 
 #include <FL/Fl_Device.H>
+#include <FL/Fl_draw.H>
+#include <FL/Fl_Pixmap.H>
+#include <FL/Fl_RGB_Image.H>
+#include <FL/Fl_Bitmap.H>
 #include <stdio.h>
 
 /**
@@ -26,6 +30,9 @@
   Fl_Printer
 #endif
    : public Fl_Device {
+     friend class Fl_Pixmap;
+     friend class Fl_RGB_Image;
+     friend class Fl_Bitmap;
 private:
   struct chain_elt {
     Fl_Image *image;
@@ -217,7 +224,7 @@
   void translate(int x, int y);
   void untranslate(void);
 public:
-  Fl_Quartz_Printer(void) : Fl_Virtual_Printer() {};
+  Fl_Quartz_Printer(void);
   int start_job(int pagecount, int *frompage = NULL, int *topage = NULL);
   int start_page (void);
   int printable_rect(int *w, int *h);
@@ -396,12 +403,12 @@
   void draw(int angle, const char *str, int n, int x, int y);
   void transformed_draw(const char* s, int n, double x, double y); //precise 
text placing
   void transformed_draw(const char* s, double x, double y);
-  /*  
-   void draw_scalled_image(const uchar *data, double x, double y, double w, 
double h, int iw, int ih, int D=3, int LD=0);
-   void draw_scalled_image_mono(const uchar *data, double x, double y, double 
w, double h, int iw, int ih, int D=3, int LD=0);
-   void draw_scalled_image(Fl_Draw_Image_Cb call, void *data, double x, double 
y, double w, double h, int iw, int ih, int D);
-   void draw_scalled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, 
double y, double w, double h, int iw, int ih, int D);
-   */
+  int alpha_mask(const uchar * data, int w, int h, int D, int LD=0);
+  void draw_scaled_image(const uchar *data, double x, double y, double w, 
double h, int iw, int ih, int D=3, int LD=0);
+  void draw_scaled_image_mono(const uchar *data, double x, double y, double w, 
double h, int iw, int ih, int D=3, int LD=0);
+  void draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double 
y, double w, double h, int iw, int ih, int D);
+  void draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, 
double y, double w, double h, int iw, int ih, int D);
+
 public:
   void page_policy(int p);
   int page_policy(){return page_policy_;};
@@ -486,7 +493,6 @@
   void end_complex_polygon(){end_polygon();};
   void transformed_vertex(double x, double y);
   
-  
   void font(int face, int size);
   int font(){return font_;};
   int size(){return size_;};
@@ -494,6 +500,16 @@
   double width(const char* s, int n);
   int descent();
   int height();
+    
+  void draw_image(const uchar* d, int x,int y,int w,int h, int delta=3, int 
ldelta=0){draw_scaled_image(d,x,y,w,h,w,h,delta,ldelta);};
+  void draw_image_mono(const uchar* d, int x,int y,int w,int h, int delta=1, 
int ld=0){draw_scaled_image_mono(d,x,y,w,h,w,h,delta,ld);};
+  void draw_image(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int 
h, int delta=3){draw_scaled_image(call,data, x, y, w, h, w, h, delta);};
+  void draw_image_mono(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, 
int h, int delta=1){draw_scaled_image_mono(call, data, x, y, w, h, w, h, 
delta);};
+    
+  void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy);
+  void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy);
+  void draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy);
+    
 #endif // FL_DOXYGEN
 };
 

Modified: branches/branch-1.3-Fl_Printer/FL/fl_draw.H
===================================================================
--- branches/branch-1.3-Fl_Printer/FL/fl_draw.H 2010-03-02 22:59:55 UTC (rev 
7195)
+++ branches/branch-1.3-Fl_Printer/FL/fl_draw.H 2010-03-02 23:07:43 UTC (rev 
7196)
@@ -407,13 +407,17 @@
   any visual of 8 bits or less, and all common TrueColor visuals up
   to 32 bits.
   */
-FL_EXPORT void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int 
D=3, int L=0);
+//FL_EXPORT void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int 
D=3, int L=0);
+inline void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, 
int L=0)
+  { fl_device->draw_image(buf, X, Y, W, H, D, L); };
 
 /**
   Draw a gray-scale (1 channel) image.
   \see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L)
   */
-FL_EXPORT void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, 
int D=1, int L=0);
+//FL_EXPORT void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, 
int D=1, int L=0);
+inline void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int 
D=1, int L=0)
+  { fl_device->draw_image_mono(buf, X, Y, W, H, D, L); };
 
 /**
   Draw image using callback function to generate image data.
@@ -447,7 +451,9 @@
 
   If \p D is 4 or more, you must fill in the unused bytes with zero.
   */
-FL_EXPORT void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int 
W,int H, int D=3);
+//FL_EXPORT void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int 
Y,int W,int H, int D=3);
+inline void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int 
W,int H, int D=3)
+  { fl_device->draw_image(cb, data, X, Y, W, H, D); };
 
 /**
   Draw gray-scale image using callback function to generate image data.

Modified: branches/branch-1.3-Fl_Printer/src/Fl_Bitmap.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/Fl_Bitmap.cxx    2010-03-02 22:59:55 UTC 
(rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/Fl_Bitmap.cxx    2010-03-02 23:07:43 UTC 
(rev 7196)
@@ -37,6 +37,7 @@
 #include <FL/Fl_Widget.H>
 #include <FL/Fl_Menu_Item.H>
 #include <FL/Fl_Bitmap.H>
+#include <FL/Fl_Printer.H>
 #include "flstring.h"
 
 #if defined(__APPLE_QUARTZ__)
@@ -264,6 +265,10 @@
 }
 
 void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
+  if(fl_device->type() == Fl_Device::postscript_device) {
+    ((Fl_Virtual_Printer*)fl_device)->draw(this, XP, YP, WP, HP, cx, cy);
+    return;
+  }
   if (!array) {
     draw_empty(XP, YP);
     return;

Modified: branches/branch-1.3-Fl_Printer/src/Fl_Device.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/Fl_Device.cxx    2010-03-02 22:59:55 UTC 
(rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/Fl_Device.cxx    2010-03-02 23:07:43 UTC 
(rev 7196)
@@ -11,6 +11,21 @@
 
 extern Fl_Device *fl_device;
 
+void Fl_Device::draw(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, 
int cy)
+{
+  // presently, never gets called
+}
+
+void Fl_Device::draw(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, int cx, int 
cy)
+{
+  // presently, never gets called
+}
+
+void Fl_Device::draw(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, 
int cy)
+{
+  // presently, never gets called
+}
+
 void Fl_Virtual_Printer::print_widget(Fl_Widget* widget, int delta_x, int 
delta_y) 
 { 
   int old_x, old_y, new_x, new_y, is_window;

Modified: branches/branch-1.3-Fl_Printer/src/Fl_GDI_Printer.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/Fl_GDI_Printer.cxx       2010-03-02 
22:59:55 UTC (rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/Fl_GDI_Printer.cxx       2010-03-02 
23:07:43 UTC (rev 7196)
@@ -13,6 +13,7 @@
 
 Fl_GDI_Printer::Fl_GDI_Printer(void) : Fl_Virtual_Printer() {
   hPr = NULL;
+  type_ = gdi_printer;
 }
 
 static void WIN_SetupPrinterDeviceContext(HDC prHDC)
@@ -80,12 +81,14 @@
     }
     x_offset = 0;
     y_offset = 0;
+    this->set_current();
   }
   return err;
 }
 
 void Fl_GDI_Printer::end_job (void)
 {
+  current_display()->set_current();
   if (hPr != NULL) {
     if (! abortPrint) {
       prerr = EndDoc (hPr);

Modified: branches/branch-1.3-Fl_Printer/src/Fl_Image.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/Fl_Image.cxx     2010-03-02 22:59:55 UTC 
(rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/Fl_Image.cxx     2010-03-02 23:07:43 UTC 
(rev 7196)
@@ -31,6 +31,7 @@
 #include <FL/Fl_Widget.H>
 #include <FL/Fl_Menu_Item.H>
 #include <FL/Fl_Image.H>
+#include <FL/Fl_Printer.H>
 #include "flstring.h"
 
 #ifdef WIN32
@@ -434,6 +435,10 @@
 #endif // !WIN32 && !USE_QUARTZ
 
 void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
+  if(fl_device->type() == Fl_Device::postscript_device) {
+    ((Fl_Virtual_Printer*)fl_device)->draw(this, XP, YP, WP, HP, cx, cy);
+    return;
+  }
   // Don't draw an empty image...
   if (!d() || !array) {
     draw_empty(XP, YP);

Modified: branches/branch-1.3-Fl_Printer/src/Fl_PS_Printer.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/Fl_PS_Printer.cxx        2010-03-02 
22:59:55 UTC (rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/Fl_PS_Printer.cxx        2010-03-02 
23:07:43 UTC (rev 7196)
@@ -310,9 +310,10 @@
 Fl_PSfile_Device::Fl_PSfile_Device(void)
 {
   close_cmd_ = 0;
-  lang_level_ = 1;
+  lang_level_ = 3;
   mask = 0;
   ps_filename_ = NULL;
+  type_ = postscript_device;
 }
 
 int Fl_PSfile_Device::start_postscript (int pagecount, enum Page_Format format)
@@ -471,6 +472,7 @@
 
 void Fl_PSfile_Device::rectf(int x, int y, int w, int h) {
   fprintf(output, "%g %g %i %i FR\n", x-0.5, y-0.5, w, h);
+  Fl::get_color(color_, bg_r_, bg_g_, bg_b_);
 }
 
 void Fl_PSfile_Device::line(int x1, int y1, int x2, int y2) {

Modified: branches/branch-1.3-Fl_Printer/src/Fl_Pixmap.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/Fl_Pixmap.cxx    2010-03-02 22:59:55 UTC 
(rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/Fl_Pixmap.cxx    2010-03-02 23:07:43 UTC 
(rev 7196)
@@ -47,6 +47,7 @@
 #include <FL/Fl_Widget.H>
 #include <FL/Fl_Menu_Item.H>
 #include <FL/Fl_Pixmap.H>
+#include <FL/Fl_Printer.H>
 
 #include <stdio.h>
 #include "flstring.h"
@@ -74,6 +75,10 @@
 }
 
 void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
+  if(fl_device->type() == Fl_Device::postscript_device) {
+    ((Fl_Virtual_Printer*)fl_device)->draw(this, XP, YP, WP, HP, cx, cy);
+    return;
+    }
   // ignore empty or bad pixmap data:
   if (!data()) {
     draw_empty(XP, YP);

Modified: branches/branch-1.3-Fl_Printer/src/Fl_Quartz_Printer.mm
===================================================================
--- branches/branch-1.3-Fl_Printer/src/Fl_Quartz_Printer.mm     2010-03-02 
22:59:55 UTC (rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/Fl_Quartz_Printer.mm     2010-03-02 
23:07:43 UTC (rev 7196)
@@ -14,11 +14,12 @@
 
 extern void fl_quartz_restore_line_style_();
 
-/*Fl_Quartz_Printer::Fl_Quartz_Printer(void)
+Fl_Quartz_Printer::Fl_Quartz_Printer(void)
 {
   x_offset = 0;
   y_offset = 0;
-}*/
+  type_ = quartz_printer;
+}
 
 int Fl_Quartz_Printer::start_job (int pagecount, int *frompage, int *topage)
 //printing using a Quartz graphics context
@@ -100,6 +101,7 @@
 #endif
   if (status != noErr) return 1;
   y_offset = x_offset = 0;
+  this->set_current();
   return 0;
 }
 
@@ -262,6 +264,7 @@
     fl_alert ("PM Session error %d", (int)status);
   }
   PMSessionEndDocumentNoDialog(printSession);
+  current_display()->set_current();
   fl_gc = 0;
   Fl::first_window()->show();
 }

Modified: branches/branch-1.3-Fl_Printer/src/fl_draw_image.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/fl_draw_image.cxx        2010-03-02 
22:59:55 UTC (rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/fl_draw_image.cxx        2010-03-02 
23:07:43 UTC (rev 7196)
@@ -543,17 +543,17 @@
   }
 }
 
-void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_Device::draw_image(const uchar* buf, int x, int y, int w, int h, int 
d, int l){
   innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
 }
-void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Device::draw_image(Fl_Draw_Image_Cb cb, void* data,
                   int x, int y, int w, int h,int d) {
   innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
 }
-void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, 
int l){
+void Fl_Device::draw_image_mono(const uchar* buf, int x, int y, int w, int h, 
int d, int l){
   innards(buf,x,y,w,h,d,l,1,0,0);
 }
-void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Device::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
                   int x, int y, int w, int h,int d) {
   innards(0,x,y,w,h,d,0,1,cb,data);
 }

Modified: branches/branch-1.3-Fl_Printer/src/fl_draw_image_mac.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/fl_draw_image_mac.cxx    2010-03-02 
22:59:55 UTC (rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/fl_draw_image_mac.cxx    2010-03-02 
23:07:43 UTC (rev 7196)
@@ -145,17 +145,17 @@
 #endif
 }
 
-void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_Device::draw_image(const uchar* buf, int x, int y, int w, int h, int 
d, int l){
   innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
 }
-void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Device::draw_image(Fl_Draw_Image_Cb cb, void* data,
                   int x, int y, int w, int h,int d) {
   innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
 }
-void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, 
int l){
+void Fl_Device::draw_image_mono(const uchar* buf, int x, int y, int w, int h, 
int d, int l){
   innards(buf,x,y,w,h,d,l,1,0,0);
 }
-void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Device::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
                   int x, int y, int w, int h,int d) {
   innards(0,x,y,w,h,d,0,1,cb,data);
 }

Modified: branches/branch-1.3-Fl_Printer/src/fl_draw_image_win32.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/fl_draw_image_win32.cxx  2010-03-02 
22:59:55 UTC (rev 7195)
+++ branches/branch-1.3-Fl_Printer/src/fl_draw_image_win32.cxx  2010-03-02 
23:07:43 UTC (rev 7196)
@@ -283,7 +283,7 @@
 
 static int fl_abs(int v) { return v<0 ? -v : v; }
 
-void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_Device::draw_image(const uchar* buf, int x, int y, int w, int h, int 
d, int l){
   if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
     d ^= FL_IMAGE_WITH_ALPHA;
     innards(buf,x,y,w,h,d,l,fl_abs(d),0,0);
@@ -292,7 +292,7 @@
   }
 }
 
-void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Device::draw_image(Fl_Draw_Image_Cb cb, void* data,
                   int x, int y, int w, int h,int d) {
   if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
     d ^= FL_IMAGE_WITH_ALPHA;
@@ -302,7 +302,7 @@
   }
 }
 
-void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, 
int l){
+void Fl_Device::draw_image_mono(const uchar* buf, int x, int y, int w, int h, 
int d, int l){
   if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
     d ^= FL_IMAGE_WITH_ALPHA;
     innards(buf,x,y,w,h,d,l,1,0,0);
@@ -311,7 +311,7 @@
   }
 }
 
-void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Device::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
                   int x, int y, int w, int h,int d) {
   if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
     d ^= FL_IMAGE_WITH_ALPHA;

Added: branches/branch-1.3-Fl_Printer/src/postscript/image.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/postscript/image.cxx                     
        (rev 0)
+++ branches/branch-1.3-Fl_Printer/src/postscript/image.cxx     2010-03-02 
23:07:43 UTC (rev 7196)
@@ -0,0 +1,525 @@
+//
+// "$Id: image.cxx 4324 2005-05-09 21:47:22Z rokan $"
+//
+// Postscript image drawing implementation for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "[email protected]".
+//
+
+
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include <FL/Fl_Printer.H>
+#include <FL/Fl.H>
+#include <FL/Fl_Pixmap.H>
+#include <FL/Fl_Bitmap.H>
+ 
+
+
+int Fl_PSfile_Device::alpha_mask(const uchar * data, int w, int h, int D, int 
LD){
+
+  mask = 0;
+  if((D/2)*2 != D){ //no mask info
+    return 0;
+  }
+  int xx;
+  int i,j, k, l;
+  LD += w*D;
+  int V255=0;
+  int V0 =0;
+  int V_=0;
+//  uchar d;
+  for(j=0;j<h;j++){
+    for(i=0;i<w;i++)
+      switch(data[j*LD+D*i+D-1]){
+        case 255: V255 = 1; break;
+        case 0: V0 = 1; break;
+        default: V_= 1;
+      }
+    if(V_) break;
+  };
+  if(!V_){
+    if(V0)
+      if(V255){// not true alpha, only masking
+        xx = (w+7)/8;
+        mask = new uchar[h * xx];
+        for(i=0;i<h * xx;i++) mask[i]=0;
+        for(j=0;j<h;j++)
+          for(i=0;i<w;i++)
+            if(data[j*LD+D*i+D-1])
+              mask[j*xx+i/8] |= 1 << (i % 8);
+        mx = w;
+        my = h; //mask imensions
+        return 0;
+      }else{
+        mask=0;
+        return 1; //everything masked
+      }
+    else
+      return 0;
+  }
+
+
+
+  /////   Alpha dither, generating (4*w) * 4 mask area       /////
+  /////         with Floyd-Steinberg error diffusion         /////
+
+  mask = new uchar[((w+1)/2) * h * 4];
+
+  for(i=0;i<((w+1)/2) * h * 4; i++) mask[i] = 0; //cleaning
+
+
+
+  mx= w*4;
+  my=h*4; // mask dimensions
+
+  xx = (w+1)/2;                //  mask line width in bytes
+
+  short * errors1 = new short [w*4+2]; //  two rows of dither errors
+  short * errors2 = new short [w*4+2]; //  two rows of dither errors
+
+  for(i=0;i<w*4+2;i++) errors2[i] = 0; // cleaning,after first swap will 
become current
+  for(i=0;i<w*4+2;i++) errors1[i] = 0; // cleaning,after first swap will 
become current
+
+  short * current = errors1;
+  short * next = errors2;
+  short * swap;
+
+  for(j=0;j<h;j++){
+    for(l=0;l<4;){           // generating 4 rows of mask lines for 1 RGB line
+      int jj = j*4+l;
+
+      /// mask row index
+      swap = next;
+      next = current;
+      current = swap;
+      *(next+1) = 0;          // must clean the first cell, next are overriden 
by *1
+      for(i=0;i<w;i++){
+        for(k=0;k<4;k++){   // generating 4 x-pixels for 1 RGB
+          short error, o1, o2, o3;
+          int ii = i*4+k;   // mask cell index
+          short val = data[j*LD+D*i+D-1] + current[1+ii];
+          if (val>127){
+            mask[jj*xx+ii/8]  |= 1 << (ii % 8); //set mask bit
+            error =  val-255;
+          }else
+            error = val;
+
+          ////// error spreading /////
+          if(error >0){
+            next[ii] +=  o1 = (error * 3 + 8)/16;
+            current[ii+2] += o2 = (error * 7 + 8)/16;
+            next[ii+2] = o3 =(error + 8)/16;  // *1 - ok replacing (cleaning)
+          }else{
+            next[ii] += o1 = (error * 3 - 8)/16;
+            current[ii+2] += o2 = (error * 7 - 8)/16;
+            next[ii+2] = o3 = (error - 8)/16;
+          }
+          next[1+ii] += error - o1 - o2 - o3;
+        }
+      }
+      l++;
+
+      ////// backward
+
+      jj = j*4+l;
+      swap = next;
+      next = current;
+      current = swap;
+      *(next+1) = 0;          // must clean the first cell, next are overriden 
by *1
+
+      for(i=w-1;i>=0;i--){
+
+        for(k=3;k>=0;k--){   // generating 4 x-pixels for 1 RGB
+          short error, o1, o2, o3;
+
+          int ii = i*4+k;   // mask cell index
+          short val = data[j*LD+D*i+D-1] + current[1+ii];
+          if (val>127){
+
+            mask[jj*xx+ii/8]  |= 1 << (ii % 8); //set mask bit
+            error =  val-255;
+          }else
+            error = val;
+
+          ////// error spreading /////
+          if(error >0){
+            next[ii+2] +=  o1 = (error * 3 + 8)/16;
+            current[ii] += o2 = (error * 7 + 8)/16;
+            next[ii] = o3 =(error + 8)/16;  // *1 - ok replacing (cleaning)
+          }else{
+            next[ii+2] += o1 = (error * 3 - 8)/16;
+
+            current[ii] += o2 = (error * 7 - 8)/16;
+            next[ii] = o3 = (error - 8)/16;
+          }
+          next[1+ii] += error - o1 - o2 - o3;
+        }
+      }
+      l++;
+    }
+  }
+  delete[] errors1;
+  delete[] errors2;
+  return 0;
+}
+
+
+
+// TODO: anybody has more efficient algoritm?
+static inline uchar swap_byte(const uchar i){
+  uchar b =0;
+  if(i & 1) b |= 128;
+  if(i & 2) b |= 64;
+  if(i & 4) b |= 32;
+  if(i & 8) b |= 16;
+  if(i & 16) b |= 8;
+  if(i & 32) b |= 4;
+  if(i & 64) b |= 2;
+  if(i & 128) b |= 1;
+  return b;
+}
+
+
+extern uchar **fl_mask_bitmap;
+
+
+void Fl_PSfile_Device::draw_scaled_image(const uchar *data, double x, double 
y, double w, double h, int iw, int ih, int D, int LD) {
+
+
+  if(D<3){ //mono
+    draw_scaled_image_mono(data, x, y, w, h, iw, ih, D, LD);
+    return;
+  }
+
+
+  int i,j, k;
+
+  fprintf(output,"save\n");
+
+  char * interpol;
+  if(lang_level_>1){
+    if(interpolate_)
+      interpol="true";
+    else
+      interpol="false";
+    if(mask && lang_level_>2)
+      fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , 
iw , ih, mx, my, interpol);
+    else
+      fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , 
ih, interpol);
+  }else
+    fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih);
+
+
+  if(!LD) LD = iw*D;
+  uchar *curmask=mask;
+
+  for (j=0; j<ih;j++){
+    if(mask){
+
+      for(k=0;k<my/ih;k++){
+        for (i=0; i<((mx+7)/8);i++){
+          if (!(i%80)) fprintf(output, "\n");
+          fprintf(output, "%.2x",swap_byte(*curmask));
+          curmask++;
+        }
+        fprintf(output,"\n");
+      }
+    }
+    const uchar *curdata=data+j*LD;
+    for(i=0 ; i<iw ; i++) {
+      uchar r = curdata[0];
+      uchar g =  curdata[1];
+      uchar b =  curdata[2];
+      if(lang_level_<3 && D>3) { //can do  mixing using bg_* colors)
+        unsigned int a2 = curdata[3]; //must be int
+        unsigned int a = 255-a2;
+        r = (a2 * r + bg_r * a)/255;
+        g = (a2 * g + bg_g * a)/255;
+        b = (a2 * b + bg_b * a)/255;
+      }
+      if (!(i%40)) fprintf(output, "\n");
+      fprintf(output, "%.2x%.2x%.2x", r, g, b);
+      curdata +=D;
+    }
+    fprintf(output,"\n");
+
+  }
+
+  fprintf(output," >\nrestore\n" );
+
+
+};
+
+void Fl_PSfile_Device::draw_scaled_image(Fl_Draw_Image_Cb call, void *data, 
double x, double y, double w, double h, int iw, int ih, int D) {
+
+
+  fprintf(output,"save\n");
+  int i,j,k;
+  char * interpol;
+  if(lang_level_>1){
+    if(interpolate_) interpol="true";
+    else interpol="false";
+    if(mask && lang_level_>2)
+      fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , 
iw , ih, mx, my, interpol);
+    else
+      fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , 
ih, interpol);
+  }else
+    fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih);
+
+  int LD=iw*D;
+  uchar *rgbdata=new uchar[LD];
+  uchar *curmask=mask;
+
+  for (j=0; j<ih;j++){
+    if(mask && lang_level_>2){  // InterleaveType 2 mask data
+      for(k=0; k<my/ih;k++){ //for alpha pseudo-masking
+        for (i=0; i<((mx+7)/8);i++){
+          if (!(i%40)) fprintf(output, "\n");
+          fprintf(output, "%.2x",swap_byte(*curmask));
+          curmask++;
+        }
+        fprintf(output,"\n");
+      }
+    }
+    call(data,0,j,iw,rgbdata);
+    uchar *curdata=rgbdata;
+    for(i=0 ; i<iw ; i++) {
+      uchar r = curdata[0];
+      uchar g =  curdata[1];
+      uchar b =  curdata[2];
+
+
+      if (!(i%40)) fprintf(output, "\n");
+      fprintf(output, "%.2x%.2x%.2x", r, g, b);
+
+      curdata +=D;
+    }
+    fprintf(output,"\n");
+
+  }
+  fprintf(output,">\n");
+
+  fprintf(output,"restore\n");
+  delete[] rgbdata;
+}
+
+void Fl_PSfile_Device::draw_scaled_image_mono(const uchar *data, double x, 
double y, double w, double h, int iw, int ih, int D, int LD) {
+
+  fprintf(output,"save\n");
+
+  int i,j, k;
+
+  char * interpol;
+  if(lang_level_>1){
+    if(interpolate_)
+      interpol="true";
+    else
+      interpol="false";
+    if(mask && lang_level_>2)
+      fprintf(output, "%g %g %g %g %i %i %i %i %s GIM\n", x , y+h , w , -h , 
iw , ih, mx, my, interpol);
+    else
+      fprintf(output, "%g %g %g %g %i %i %s GII\n", x , y+h , w , -h , iw , 
ih, interpol);
+  }else
+    fprintf(output , "%g %g %g %g %i %i GI", x , y+h , w , -h , iw , ih);
+
+
+  if(!LD) LD = iw*D;
+
+
+  int bg = (bg_r + bg_g + bg_b)/3;
+
+  uchar *curmask=mask;
+  for (j=0; j<ih;j++){
+    if(mask){
+      for(k=0;k<my/ih;k++){
+        for (i=0; i<((mx+7)/8);i++){
+          if (!(i%80)) fprintf(output, "\n");
+          fprintf(output, "%.2x",swap_byte(*curmask));
+          curmask++;
+        }
+        fprintf(output,"\n");
+      }
+    }
+    const uchar *curdata=data+j*LD;
+    for(i=0 ; i<iw ; i++) {
+      if (!(i%80)) fprintf(output, "\n");
+      uchar r = curdata[0];
+      if(lang_level_<3 && D>1) { //can do  mixing
+
+        unsigned int a2 = curdata[1]; //must be int
+        unsigned int a = 255-a2;
+        r = (a2 * r + bg * a)/255;
+      }
+      if (!(i%120)) fprintf(output, "\n");
+      fprintf(output, "%.2x", r);
+      curdata +=D;
+    }
+    fprintf(output,"\n");
+
+  }
+
+  fprintf(output," >\nrestore\n" );
+
+};
+
+
+
+void Fl_PSfile_Device::draw_scaled_image_mono(Fl_Draw_Image_Cb call, void 
*data, double x, double y, double w, double h, int iw, int ih, int D) {
+
+  fprintf(output,"save\n");
+  int i,j,k;
+  char * interpol;
+  if(lang_level_>1){
+    if(interpolate_) interpol="true";
+    else interpol="false";
+    if(mask && lang_level_>2)
+      fprintf(output, "%g %g %g %g %i %i %i %i %s GIM\n", x , y+h , w , -h , 
iw , ih, mx, my, interpol);
+    else
+      fprintf(output, "%g %g %g %g %i %i %s GII\n", x , y+h , w , -h , iw , 
ih, interpol);
+  }else
+    fprintf(output , "%g %g %g %g %i %i GI", x , y+h , w , -h , iw , ih);
+
+  int LD=iw*D;
+  uchar *rgbdata=new uchar[LD];
+  uchar *curmask=mask;
+  for (j=0; j<ih;j++){
+
+    if(mask && lang_level_>2){  // InterleaveType 2 mask data
+      for(k=0; k<my/ih;k++){ //for alpha pseudo-masking
+        for (i=0; i<((mx+7)/8);i++){
+          if (!(i%40)) fprintf(output, "\n");
+          fprintf(output, "%.2x",swap_byte(*curmask));
+          curmask++;
+        }
+        fprintf(output,"\n");
+      }
+    }
+    call(data,0,j,iw,rgbdata);
+    uchar *curdata=rgbdata;
+    for(i=0 ; i<iw ; i++) {
+      uchar r = curdata[0];
+      if (!(i%120)) fprintf(output, "\n");
+      fprintf(output, "%.2x", r);
+      curdata +=D;
+    }
+    fprintf(output,"\n");
+  }
+  fprintf(output,">\n");
+  fprintf(output,"restore\n");
+  delete[] rgbdata;
+}
+
+
+////////////////////////////// Image classes //////////////////////
+
+
+void Fl_PSfile_Device::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, 
int cx, int cy){
+  const char * const * di =pxm->data();
+  int w,h;
+  if (!fl_measure_pixmap(di, w, h)) return;
+  mask=0;
+  fl_mask_bitmap=&mask;
+  mx = WP;
+  my = HP;
+  push_clip(XP, YP, WP, HP);
+  fl_draw_pixmap(di,XP -cx, YP -cy, fl_rgb_color(bg_r_, bg_g_, bg_b_) ); 
//yes, it is dirty, but fl is dispatched, so it works!
+  pop_clip();
+  delete[] mask;
+  mask=0;
+  fl_mask_bitmap=0;
+};
+
+void Fl_PSfile_Device::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, 
int cx, int cy){
+  const uchar  * di = rgb->array;
+  int w = rgb->w();
+  int h = rgb->h();
+  mask=0;
+  if(lang_level_>2) //when not true, not making alphamask, mixing colors 
instead...
+  if (alpha_mask(di, w, h, rgb->d(),rgb->ld())) return; //everthing masked, no 
need for painting!
+  push_clip(XP, YP, WP, HP);
+  draw_scaled_image(di, XP + cx, YP + cy, w, h,  w,  h, rgb->d(), rgb->ld());
+  pop_clip();
+  delete[]mask;
+  mask=0;
+};
+
+void Fl_PSfile_Device::draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, 
int cx, int cy){
+  const uchar  * di = bitmap->array;
+  int w,h;
+  int LD=(bitmap->w()+7)/8;
+  int xx;
+
+  if (WP> bitmap->w() - cx){// to assure that it does not go out of bounds;
+     w = bitmap->w() - cx;
+     xx = (bitmap->w()+7)/8 - cx/8; //length of mask in bytes
+  }else{
+    w =WP;
+    xx = (w+7)/8 - cx/8;
+  }
+  if( HP > bitmap->h()-cy)
+    h = bitmap->h() - cy;
+  else
+    h = HP;
+
+  di += cy*LD + cx/8;
+  int si = cx % 8; // small shift to be clipped, it is simpler than shifting 
whole mask
+
+  int i,j;
+  push_clip(XP, YP, WP, HP);
+  fprintf(output , "%i %i %i %i %i %i MI", XP - si, YP + HP , WP , -HP , w , 
h);
+
+  for (j=0; j<HP; j++){
+    for (i=0; i<xx; i++){
+      if (!(i%80)) fprintf(output, "\n"); // not have lines longer than 255 
chars
+      fprintf(output, "%.2x",swap_byte(~(*di)));
+      di++;
+    }
+    fprintf(output,"\n");
+  }
+  fprintf(output,">\n");
+  pop_clip();
+};
+
+
+//
+// End of "$Id: image.cxx 4324 2005-05-09 21:47:22Z rokan $"
+//
+
+
+
+
+
+
+
+
+
+
+  
+
+
+
+
+
+
+

Modified: branches/branch-1.3-Fl_Printer/test/device.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/test/device.cxx      2010-03-02 22:59:55 UTC 
(rev 7195)
+++ branches/branch-1.3-Fl_Printer/test/device.cxx      2010-03-02 23:07:43 UTC 
(rev 7196)
@@ -664,20 +664,14 @@
   make_image();
   Fl_RGB_Image *rgb = new Fl_RGB_Image(image, width, height, 4);
   My_Button b_rgb(10,245,100,100,"RGB with alpha");
-#if defined(__APPLE__) || defined(WIN32)
   b_rgb.image(rgb);
-#endif
 
   My_Button b_pixmap(10,345,100,100,"Pixmap");
   Fl_Pixmap *pixmap = new Fl_Pixmap(porsche_xpm);
-#if defined(__APPLE__) || defined(WIN32)
   b_pixmap.image(pixmap);
-#endif
 
   My_Button b_bitmap(10,445,100,100,"Bitmap");
-#if defined(__APPLE__) || defined(WIN32)
   b_bitmap.image(new 
Fl_Bitmap(sorceress_bits,sorceress_width,sorceress_height));
-#endif
 
   new Fl_Clock(360,230,120,120);
   Fl_Return_Button * ret = new Fl_Return_Button (360, 360, 120,30, "Return");

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to