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