Image drawing: simplify the code organisation to better support Fl_Image::scale().
Graphics drivers now use up to 6 virtual member functions to support Fl_Image drawing in the context of GUI and image rescaling : virtual void draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) virtual void draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) virtual void draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) and virtual void draw_fixed(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) virtual void draw_fixed(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) virtual void draw_fixed(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12828 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
efc3ec1b7b
commit
16705ef734
@ -94,6 +94,34 @@ class FL_EXPORT Fl_Graphics_Driver {
|
||||
friend FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array);
|
||||
friend FL_EXPORT void fl_delete_bitmask(Fl_Bitmask);
|
||||
private:
|
||||
/* ============== Implementation note about image drawing =========================
|
||||
A graphics driver uses either its implementation of the draw_rgb(Fl_RGB_Image *,....)
|
||||
or that of the draw_fixed(Fl_RGB_Image *,....) member functions to draw an RGB image.
|
||||
Same thing with draw_bitmap(Fl_Bitmap *,....) or draw_fixed(Fl_Bitmap *,....).
|
||||
Same thing with draw_pixmap(Fl_Pixmap *,....) or draw_fixed(Fl_Pixmap *,....).
|
||||
- The driver uses draw_???() if it can directly map the image data,
|
||||
sized at data_w() x data_h(), to the image drawing area, sized at w()*scale x h()*scale
|
||||
where scale is the current GUI scale factor.
|
||||
- If the driver does not support such scale-and-draw operation, it should use draw_fixed()
|
||||
which is called by the library after the image has been internally resized to the adequate
|
||||
drawing size and cached.
|
||||
- The platform-independent Fl_Graphics_Driver class implements draw_???(image-class *,....)
|
||||
that scales the image and calls the platform-specific implementation of
|
||||
draw_fixed(image-class *,....) with the scaled, cached image.
|
||||
- Some graphics drivers implement only draw_???() or draw_fixed() as in these examples:
|
||||
- Fl_Quartz_Graphics_Driver implements only draw_rgb(Fl_RGB_Image *,....) because it
|
||||
can perform the scale-and-draw operation whatever the RGB image and the required scaling.
|
||||
- Fl_GDI_Graphics_Driver implements only draw_fixed(Fl_Pixmap *,....). The library
|
||||
takes care of scaling and caching the Pixmap to the adequate drawing size.
|
||||
- Some drivers implement both draw_???() and draw_fixed() :
|
||||
- Fl_Xlib_Graphics_Driver implements both draw_rgb(Fl_RGB_Image *,....) and
|
||||
draw_fixed(Fl_RGB_Image *,....) because scale-and-draw is possible only in the
|
||||
presence of Xrender. In the absence of Xrender, the draw_rgb() implementation calls
|
||||
Fl_Graphics_Driver::draw_rgb() which runs Fl_Xlib_Graphics_Driver::draw_fixed(Fl_RGB_Image*,...).
|
||||
*/
|
||||
virtual void draw_fixed(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
virtual void draw_fixed(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
virtual void draw_fixed(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
// some platforms may need to reimplement this
|
||||
virtual void set_current_();
|
||||
protected:
|
||||
@ -145,6 +173,8 @@ protected:
|
||||
/** Support function for Fl_Bitmap drawing */
|
||||
virtual fl_uintptr_t cache(Fl_Bitmap *img) { return 0; }
|
||||
/** Support function for Fl_RGB_Image drawing */
|
||||
virtual fl_uintptr_t cache(Fl_RGB_Image *img) { return 0; }
|
||||
/** Support function for Fl_RGB_Image drawing */
|
||||
virtual void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_) { }
|
||||
// --- implementation is in src/drivers/xxx/Fl_xxx_Graphics_Driver_image.cxx
|
||||
/** see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L) */
|
||||
@ -160,19 +190,19 @@ protected:
|
||||
Specifies a bounding box for the image, with the origin (upper left-hand corner) of
|
||||
the image offset by the cx and cy arguments.
|
||||
*/
|
||||
virtual void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
virtual void draw_rgb(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
/** \brief Draws an Fl_Pixmap object using this graphics driver.
|
||||
*
|
||||
Specifies a bounding box for the image, with the origin (upper left-hand corner) of
|
||||
the image offset by the cx and cy arguments.
|
||||
*/
|
||||
virtual void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
virtual void draw_pixmap(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
/** \brief Draws an Fl_Bitmap object using this graphics driver.
|
||||
*
|
||||
Specifies a bounding box for the image, with the origin (upper left-hand corner) of
|
||||
the image offset by the cx and cy arguments.
|
||||
*/
|
||||
virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
virtual void draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
|
||||
|
||||
/** Support function for image drawing */
|
||||
@ -230,6 +260,7 @@ protected:
|
||||
}
|
||||
|
||||
Fl_Graphics_Driver();
|
||||
void cache_size(Fl_Image *img, int &width, int &height);
|
||||
public:
|
||||
virtual ~Fl_Graphics_Driver() {} ///< Destructor
|
||||
static Fl_Graphics_Driver &default_driver();
|
||||
@ -401,8 +432,6 @@ public:
|
||||
virtual const char *font_name(int num) {return NULL;}
|
||||
/** Support for Fl::set_font() */
|
||||
virtual void font_name(int num, const char *name) {}
|
||||
// Draws an Fl_Image scaled to width W & height H
|
||||
virtual int draw_scaled(Fl_Image *img, int X, int Y, int W, int H);
|
||||
/** Support function for fl_overlay_rect() and scaled GUI.
|
||||
Defaut implementation may be enough */
|
||||
virtual bool overlay_rect_unscaled();
|
||||
@ -459,15 +488,8 @@ public:
|
||||
Fl_Scalable_Graphics_Driver();
|
||||
protected:
|
||||
int line_width_;
|
||||
void cache_size(Fl_Image *img, int &width, int &height);
|
||||
virtual Fl_Region scale_clip(float f) { return 0; }
|
||||
void unscale_clip(Fl_Region r);
|
||||
virtual void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
virtual void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_unscaled(Fl_RGB_Image *img, float s, int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
virtual void point(int x, int y);
|
||||
virtual void point_unscaled(float x, float y) {}
|
||||
virtual void rect(int x, int y, int w, int h);
|
||||
|
@ -67,6 +67,7 @@ private:
|
||||
void *prepare85();
|
||||
void write85(void *data, const uchar *p, int len);
|
||||
void close85(void *data);
|
||||
int scale_and_draw(Fl_Image *img, int XP, int YP, int WP, int HP);
|
||||
protected:
|
||||
uchar **mask_bitmap() {return &mask;}
|
||||
void mask_bitmap(uchar **value) { }
|
||||
@ -212,7 +213,6 @@ class Clip {
|
||||
void draw(Fl_Pixmap * pxm,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);
|
||||
void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
|
||||
/** Shields output PostScript data from modifications of the current locale.
|
||||
It typically avoids PostScript errors caused if the current locale uses comma instead of dot
|
||||
as "decimal point".
|
||||
|
@ -113,7 +113,7 @@ Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *array)
|
||||
}
|
||||
|
||||
void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy);
|
||||
fl_graphics_driver->draw_bitmap(this, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
|
||||
int Fl_Bitmap::prepare(int XP, int YP, int WP, int HP, int &cx, int &cy,
|
||||
|
@ -69,14 +69,6 @@ void Fl_Graphics_Driver::focus_rect(int x, int y, int w, int h)
|
||||
line_style(FL_SOLID);
|
||||
}
|
||||
|
||||
/** Draws an Fl_Image scaled to width \p W & height \p H with top-left corner at \em X,Y
|
||||
\return zero when the graphics driver doesn't implement scaled drawing for the received image,
|
||||
non-zero if it does implement it.
|
||||
*/
|
||||
int Fl_Graphics_Driver::draw_scaled(Fl_Image *img, int X, int Y, int W, int H) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** see fl_copy_offscreen() */
|
||||
void Fl_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy)
|
||||
{
|
||||
@ -308,7 +300,7 @@ void Fl_Scalable_Graphics_Driver::circle(double x, double y, double r) {
|
||||
}
|
||||
|
||||
// compute width & height of cached image so it can be tiled without undrawn gaps when scaling output
|
||||
void Fl_Scalable_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height)
|
||||
void Fl_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height)
|
||||
{
|
||||
if ( int(scale_) == scale_ ) {
|
||||
width = width * scale_;
|
||||
@ -320,7 +312,7 @@ void Fl_Scalable_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &hei
|
||||
}
|
||||
|
||||
|
||||
void Fl_Scalable_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
void Fl_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::start_image(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
@ -344,11 +336,11 @@ void Fl_Scalable_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, i
|
||||
} else *id(pxm) = cache(pxm);
|
||||
}
|
||||
// draw pxm using its scaled id_ & pixmap_
|
||||
draw_unscaled(pxm, scale_, X, Y, W, H, cx, cy);
|
||||
draw_fixed(pxm, X, Y, W, H, cx, cy);
|
||||
}
|
||||
|
||||
|
||||
void Fl_Scalable_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
void Fl_Graphics_Driver::draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::start_image(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
@ -369,11 +361,11 @@ void Fl_Scalable_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, in
|
||||
} else *id(bm) = cache(bm);
|
||||
}
|
||||
// draw bm using its scaled id_
|
||||
draw_unscaled(bm, scale_, X, Y, W, H, cx, cy);
|
||||
draw_fixed(bm, X, Y, W, H, cx, cy);
|
||||
}
|
||||
|
||||
|
||||
void Fl_Scalable_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
void Fl_Graphics_Driver::draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
// Don't draw an empty image...
|
||||
if (!img->d() || !img->array) {
|
||||
Fl_Graphics_Driver::draw_empty(img, XP, YP);
|
||||
@ -382,14 +374,8 @@ void Fl_Scalable_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP
|
||||
if (start_image(img, XP, YP, WP, HP, cx, cy, XP, YP, WP, HP)) {
|
||||
return;
|
||||
}
|
||||
int need_scaled_drawing = fabs(img->w() - img->data_w()/scale_)/img->w() > 0.05 ||
|
||||
fabs(img->h() - img->data_h()/scale_)/img->h() > 0.05;
|
||||
if (need_scaled_drawing && can_do_alpha_blending()) { // try and use the system's scaled image drawing
|
||||
push_clip(XP, YP, WP, HP);
|
||||
int done = draw_scaled(img, XP-cx, YP-cy, img->w(), img->h());
|
||||
pop_clip();
|
||||
if (done) return;
|
||||
}
|
||||
int need_scaled_drawing = ( fabs(img->w() - img->data_w()/scale_)/img->w() > 0.05 ||
|
||||
fabs(img->h() - img->data_h()/scale_)/img->h() > 0.05 );
|
||||
// to allow rescale at runtime
|
||||
int w2, h2, *pw, *ph;
|
||||
if (need_scaled_drawing) {
|
||||
@ -407,15 +393,19 @@ void Fl_Scalable_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP
|
||||
Fl_Image::RGB_scaling(Fl_Image::scaling_algorithm());
|
||||
Fl_RGB_Image *img2 = (Fl_RGB_Image*)img->copy(w2, h2);
|
||||
Fl_Image::RGB_scaling(keep);
|
||||
draw_unscaled(img2, scale_, XP, YP, WP, HP, cx, cy);
|
||||
cache(img2);
|
||||
draw_fixed(img2, XP, YP, WP, HP, cx, cy);
|
||||
*id(img) = *id(img2);
|
||||
*mask(img) = *mask(img2);
|
||||
*id(img2) = 0;
|
||||
*mask(img2) = 0;
|
||||
*pw = w2;
|
||||
*ph = h2;
|
||||
delete img2;
|
||||
}
|
||||
else { // draw img using its scaled id_
|
||||
draw_unscaled(img, scale_, XP, YP, WP, HP, cx, cy);
|
||||
if (!*id(img)) cache(img);
|
||||
draw_fixed(img, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,7 +643,7 @@ void Fl_RGB_Image::desaturate() {
|
||||
}
|
||||
|
||||
void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy);
|
||||
fl_graphics_driver->draw_rgb(this, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
|
||||
void Fl_RGB_Image::label(Fl_Widget* widget) {
|
||||
|
@ -47,7 +47,7 @@ void Fl_Pixmap::measure() {
|
||||
}
|
||||
|
||||
void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy);
|
||||
fl_graphics_driver->draw_pixmap(this, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,6 +54,9 @@ protected:
|
||||
// - methods marked with // super: use the implemnetation of the super class
|
||||
// - virtual ... override functions are implemented for Android
|
||||
private:
|
||||
virtual void draw_fixed(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) override;
|
||||
virtual void draw_fixed(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) override;
|
||||
virtual void draw_fixed(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) override;
|
||||
// some platforms may need to reimplement this
|
||||
// This is called from the surface device, see: end_current_()
|
||||
// super: virtual void set_current_();
|
||||
@ -67,6 +70,7 @@ protected:
|
||||
virtual fl_uintptr_t cache(Fl_Pixmap *img) override;
|
||||
/** Support function for Fl_Bitmap drawing */
|
||||
virtual fl_uintptr_t cache(Fl_Bitmap *img) override;
|
||||
virtual fl_uintptr_t cache(Fl_RGB_Image *img) override;
|
||||
/** Support function for Fl_RGB_Image drawing */
|
||||
virtual void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_) override;
|
||||
// --- implementation is in src/drivers/xxx/Fl_xxx_Graphics_Driver_image.cxx
|
||||
@ -78,20 +82,6 @@ protected:
|
||||
virtual void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3) override;
|
||||
/** see fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D) */
|
||||
virtual void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1) override;
|
||||
/** \brief Draws an Fl_RGB_Image object using this graphics driver. */
|
||||
virtual void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) override;
|
||||
/** \brief Draws an Fl_Pixmap object using this graphics driver.
|
||||
*
|
||||
Specifies a bounding box for the image, with the origin (upper left-hand corner) of
|
||||
the image offset by the cx and cy arguments.
|
||||
*/
|
||||
virtual void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) override;
|
||||
/** \brief Draws an Fl_Bitmap object using this graphics driver.
|
||||
*
|
||||
Specifies a bounding box for the image, with the origin (upper left-hand corner) of
|
||||
the image offset by the cx and cy arguments.
|
||||
*/
|
||||
virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) override;
|
||||
#if 0
|
||||
virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
|
||||
|
||||
@ -282,9 +272,6 @@ public:
|
||||
virtual const char *font_name(int num) override;
|
||||
/** Support for Fl::set_font() */
|
||||
virtual void font_name(int num, const char *name) override;
|
||||
// Draws an Fl_Image scaled to width W & height H
|
||||
// TODO: we don't seem to need this until we introduce a scaling graphis driver
|
||||
// super: virtual int draw_scaled(Fl_Image *img, int X, int Y, int W, int H);
|
||||
/** Support function for fl_overlay_rect() and scaled GUI.
|
||||
Defaut implementation may be enough */
|
||||
// super: virtual bool overlay_rect_unscaled();
|
||||
@ -358,7 +345,6 @@ public:
|
||||
virtual int has_feature(driver_feature mask) { return mask & (NATIVE | PRINTER); }
|
||||
void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -962,31 +962,23 @@ void Fl_Android_Graphics_Driver::circle(double x, double y, double r)
|
||||
}
|
||||
|
||||
|
||||
void Fl_Android_Graphics_Driver::draw(Fl_Pixmap * pxm, int XP, int YP, int WP, int HP, int cx, int cy)
|
||||
void Fl_Android_Graphics_Driver::draw_fixed(Fl_Pixmap * pxm, int X, int Y, int W, int H, int cx, int cy)
|
||||
{
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::prepare(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
}
|
||||
if (*Fl_Graphics_Driver::id(pxm)) {
|
||||
Fl_Android_565A_Map *cache = (Fl_Android_565A_Map*)*Fl_Graphics_Driver::id(pxm);
|
||||
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(X, Y, W, H))) {
|
||||
draw(XP, YP, cache, it->clipped_rect());
|
||||
draw(X-cx, Y-cy, cache, it->clipped_rect());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Fl_Android_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy)
|
||||
void Fl_Android_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy)
|
||||
{
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
}
|
||||
if (*Fl_Graphics_Driver::id(bm)) {
|
||||
Fl_Android_Bytemap *cache = (Fl_Android_Bytemap*)*Fl_Graphics_Driver::id(bm);
|
||||
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(X, Y, W, H))) {
|
||||
draw(XP, YP, cache, it->clipped_rect());
|
||||
draw(X-cx, Y-cy, cache, it->clipped_rect());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1050,68 +1042,65 @@ void Fl_Android_Graphics_Driver::uncache_pixmap(fl_uintptr_t p)
|
||||
delete img;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Android_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy)
|
||||
fl_uintptr_t Fl_Android_Graphics_Driver::cache(Fl_RGB_Image *img)
|
||||
{
|
||||
int X, Y, W, H;
|
||||
// Don't draw an empty image...
|
||||
if (!img->d() || !img->array) {
|
||||
Fl_Graphics_Driver::draw_empty(img, XP, YP);
|
||||
return;
|
||||
}
|
||||
if (start_image(img, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
}
|
||||
Fl_Android_565A_Map *cgimg = (Fl_Android_565A_Map*)*Fl_Graphics_Driver::id(img);
|
||||
if (!cgimg) {
|
||||
int w = img->w(), h = img->h(), d = img->d(), stride = w*d + img->ld();
|
||||
cgimg = new Fl_Android_565A_Map(w, h);
|
||||
*Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cgimg;
|
||||
if (d==1) { // grayscale
|
||||
for (int iy=0; iy<h; iy++) {
|
||||
const uchar *src = img->array + iy*stride;
|
||||
uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
|
||||
for (int ix=0; ix<w; ix++) {
|
||||
uchar l = *src++;
|
||||
uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, 255);
|
||||
*dst++ = rgba;
|
||||
}
|
||||
int w = img->data_w(), h = img->data_h(), d = img->d(), stride = w*d + img->ld();
|
||||
Fl_Android_565A_Map *cgimg = new Fl_Android_565A_Map(w, h);
|
||||
*Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cgimg;
|
||||
int *pw, *ph;
|
||||
cache_w_h(img, pw, ph);
|
||||
*pw = img->data_w();
|
||||
*ph = img->data_h();
|
||||
if (d==1) { // grayscale
|
||||
for (int iy=0; iy<h; iy++) {
|
||||
const uchar *src = img->array + iy*stride;
|
||||
uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
|
||||
for (int ix=0; ix<w; ix++) {
|
||||
uchar l = *src++;
|
||||
uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, 255);
|
||||
*dst++ = rgba;
|
||||
}
|
||||
} else if (d==2) { // gray + alpha
|
||||
for (int iy=0; iy<h; iy++) {
|
||||
const uchar *src = img->array + iy*stride;
|
||||
uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
|
||||
for (int ix=0; ix<w; ix++) {
|
||||
uchar l = *src++, a = *src++;
|
||||
uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, a);
|
||||
*dst++ = rgba;
|
||||
}
|
||||
}
|
||||
} else if (d==2) { // gray + alpha
|
||||
for (int iy=0; iy<h; iy++) {
|
||||
const uchar *src = img->array + iy*stride;
|
||||
uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
|
||||
for (int ix=0; ix<w; ix++) {
|
||||
uchar l = *src++, a = *src++;
|
||||
uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, a);
|
||||
*dst++ = rgba;
|
||||
}
|
||||
} else if (d==3) { // rgb
|
||||
for (int iy=0; iy<h; iy++) {
|
||||
const uchar *src = img->array + iy*stride;
|
||||
uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
|
||||
for (int ix=0; ix<w; ix++) {
|
||||
uchar r = *src++, g = *src++, b = *src++;
|
||||
uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, 255);
|
||||
*dst++ = rgba;
|
||||
}
|
||||
}
|
||||
} else if (d==3) { // rgb
|
||||
for (int iy=0; iy<h; iy++) {
|
||||
const uchar *src = img->array + iy*stride;
|
||||
uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
|
||||
for (int ix=0; ix<w; ix++) {
|
||||
uchar r = *src++, g = *src++, b = *src++;
|
||||
uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, 255);
|
||||
*dst++ = rgba;
|
||||
}
|
||||
} else if (d==4) { // rgb + alpha
|
||||
for (int iy=0; iy<h; iy++) {
|
||||
const uchar *src = img->array + iy*stride;
|
||||
uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
|
||||
for (int ix=0; ix<w; ix++) {
|
||||
uchar r = *src++, g = *src++, b = *src++, a = *src++;
|
||||
uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, a);
|
||||
*dst++ = rgba;
|
||||
}
|
||||
}
|
||||
} else if (d==4) { // rgb + alpha
|
||||
for (int iy=0; iy<h; iy++) {
|
||||
const uchar *src = img->array + iy*stride;
|
||||
uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
|
||||
for (int ix=0; ix<w; ix++) {
|
||||
uchar r = *src++, g = *src++, b = *src++, a = *src++;
|
||||
uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, a);
|
||||
*dst++ = rgba;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (fl_uintptr_t)cgimg;
|
||||
}
|
||||
|
||||
void Fl_Android_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy)
|
||||
{
|
||||
Fl_Android_565A_Map *cgimg = (Fl_Android_565A_Map*)*Fl_Graphics_Driver::id(img);
|
||||
if (cgimg) {
|
||||
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(X, Y, W, H))) {
|
||||
draw(XP, YP, cgimg, it->clipped_rect());
|
||||
draw(X-cx, Y-cy, cgimg, it->clipped_rect());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1232,6 +1221,7 @@ void Fl_Android_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_ui
|
||||
{
|
||||
Fl_Android_565A_Map *cgimg = (Fl_Android_565A_Map*)id_;
|
||||
delete cgimg;
|
||||
id_ = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,7 +40,11 @@ private:
|
||||
int depth; // to support translation
|
||||
POINT *origins; // to support translation
|
||||
void set_current_();
|
||||
void draw_fixed(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_fixed(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
protected:
|
||||
void draw_fixed(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
fl_uintptr_t cache(Fl_RGB_Image *rgb);
|
||||
HDC gc_;
|
||||
int numcount;
|
||||
int counts[20];
|
||||
@ -64,10 +68,7 @@ public:
|
||||
virtual void draw_unscaled(int angle, const char *str, int n, int x, int y);
|
||||
virtual void rtl_draw_unscaled(const char* str, int n, int x, int y);
|
||||
virtual void font_unscaled(Fl_Font face, Fl_Fontsize size);
|
||||
void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_unscaled(Fl_Bitmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_unscaled(Fl_RGB_Image *img, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
|
||||
virtual void draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_image_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
|
||||
virtual void draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
|
||||
virtual void draw_image_mono_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
|
||||
@ -163,9 +164,9 @@ private:
|
||||
transparent_f_type TransparentBlt();
|
||||
public:
|
||||
virtual int has_feature(driver_feature mask) { return mask & (NATIVE | PRINTER); }
|
||||
void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
|
||||
void draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_bitmap(Fl_Bitmap *bm, 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);
|
||||
};
|
||||
|
||||
|
||||
|
@ -125,7 +125,7 @@ void Fl_GDI_Graphics_Driver::copy_offscreen_with_alpha(int x,int y,int w,int h,H
|
||||
SelectObject(new_gc, bitmap);
|
||||
BOOL alpha_ok = 0;
|
||||
// first try to alpha blend
|
||||
if ( can_do_alpha_blending() ) {
|
||||
if ( fl_can_do_alpha_blending() ) {
|
||||
alpha_ok = alpha_blend_(x, y, w, h, new_gc, srcx, srcy, w, h);
|
||||
}
|
||||
// if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1
|
||||
|
@ -400,15 +400,11 @@ void Fl_GDI_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) {
|
||||
DeleteObject((HGDIOBJ)bm);
|
||||
}
|
||||
|
||||
void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
}
|
||||
X = X*s;
|
||||
Y = Y*s;
|
||||
void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = X*scale_;
|
||||
Y = Y*scale_;
|
||||
cache_size(bm, W, H);
|
||||
cx *= s; cy *= s;
|
||||
cx *= scale_; cy *= scale_;
|
||||
|
||||
HDC tempdc = CreateCompatibleDC(gc_);
|
||||
int save = SaveDC(tempdc);
|
||||
@ -428,17 +424,26 @@ Fl_GDI_Printer_Graphics_Driver::transparent_f_type Fl_GDI_Printer_Graphics_Drive
|
||||
return fpter;
|
||||
}
|
||||
|
||||
void Fl_GDI_Printer_Graphics_Driver::draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
void Fl_GDI_Printer_Graphics_Driver::draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::start_image(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
}
|
||||
transparent_f_type fl_TransparentBlt = TransparentBlt();
|
||||
if (!fl_TransparentBlt) {
|
||||
Fl_GDI_Graphics_Driver::draw(bm, XP, YP, WP, HP, cx, cy);
|
||||
Fl_Graphics_Driver::draw_bitmap(bm, X, Y, W, H, cx, cy);
|
||||
return;
|
||||
}
|
||||
if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
bool recache = false;
|
||||
if (*id(bm)) {
|
||||
int *pw, *ph;
|
||||
cache_w_h(bm, pw, ph);
|
||||
recache = (*pw != bm->data_w() || *ph != bm->data_h());
|
||||
}
|
||||
if (recache || !*id(bm)) {
|
||||
bm->uncache();
|
||||
*Fl_Graphics_Driver::id(bm) = cache(bm);
|
||||
}
|
||||
|
||||
HDC tempdc;
|
||||
int save;
|
||||
// algorithm for bitmap output to Fl_GDI_Printer
|
||||
@ -449,28 +454,31 @@ void Fl_GDI_Printer_Graphics_Driver::draw_unscaled(Fl_Bitmap *bm, float s, int X
|
||||
g = 255-g;
|
||||
b = 255-b;
|
||||
Fl_Color background = fl_rgb_color(r, g, b); // a color very different from the bitmap's
|
||||
Fl_Offscreen tmp_id = fl_create_offscreen(W, H);
|
||||
fl_begin_offscreen(tmp_id);
|
||||
Fl_Image_Surface *img_surf = new Fl_Image_Surface(bm->data_w(), bm->data_h());
|
||||
Fl_Surface_Device::push_current(img_surf);
|
||||
fl_color(background);
|
||||
fl_rectf(0,0,W,H); // use this color as offscreen background
|
||||
fl_rectf(0,0, bm->data_w(), bm->data_h()); // use this color as offscreen background
|
||||
fl_color(save_c); // back to bitmap's color
|
||||
HDC off_gc = (HDC)fl_graphics_driver->gc();
|
||||
tempdc = CreateCompatibleDC(off_gc);
|
||||
save = SaveDC(tempdc);
|
||||
SelectObject(tempdc, (HGDIOBJ)*Fl_Graphics_Driver::id(bm));
|
||||
SelectObject(off_gc, fl_brush()); // use bitmap's desired color
|
||||
BitBlt(off_gc, 0, 0, W, H, tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen
|
||||
fl_end_offscreen(); // offscreen data is in tmp_id
|
||||
SelectObject(tempdc, (HGDIOBJ)tmp_id); // use offscreen data
|
||||
BitBlt(off_gc, 0, 0, bm->data_w(), bm->data_h(), tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen
|
||||
Fl_Surface_Device::pop_current();
|
||||
SelectObject(tempdc, (HGDIOBJ)img_surf->offscreen()); // use offscreen data
|
||||
// draw it to printer context with background color as transparent
|
||||
fl_TransparentBlt(gc_, X,Y,W,H, tempdc, cx, cy, bm->data_w(), bm->data_h(), RGB(r, g, b) );
|
||||
fl_delete_offscreen(tmp_id);
|
||||
float scaleW = bm->data_w()/float(bm->w());
|
||||
float scaleH = bm->data_h()/float(bm->h());
|
||||
fl_TransparentBlt(gc_, X, Y, W, H, tempdc, cx * scaleW, cy * scaleH, W * scaleW, H * scaleH, RGB(r, g, b) );
|
||||
delete img_surf;
|
||||
RestoreDC(tempdc, save);
|
||||
DeleteDC(tempdc);
|
||||
}
|
||||
if (recache) bm->uncache();
|
||||
}
|
||||
|
||||
|
||||
static Fl_Offscreen build_id(Fl_RGB_Image *img, void **pmask)
|
||||
fl_uintptr_t Fl_GDI_Graphics_Driver::cache(Fl_RGB_Image *img)
|
||||
{
|
||||
Fl_Image_Surface *surface = new Fl_Image_Surface(img->data_w(), img->data_h());
|
||||
Fl_Surface_Device::push_current(surface);
|
||||
@ -479,31 +487,35 @@ static Fl_Offscreen build_id(Fl_RGB_Image *img, void **pmask)
|
||||
} else {
|
||||
fl_draw_image(img->array, 0, 0, img->data_w(), img->data_h(), img->d(), img->ld());
|
||||
if (img->d() == 2 || img->d() == 4) {
|
||||
*pmask = fl_create_alphamask(img->data_w(), img->data_h(), img->d(), img->ld(), img->array);
|
||||
*Fl_Graphics_Driver::mask(img) = (fl_uintptr_t)fl_create_alphamask(img->data_w(), img->data_h(), img->d(), img->ld(), img->array);
|
||||
}
|
||||
}
|
||||
Fl_Surface_Device::pop_current();
|
||||
Fl_Offscreen offs = surface->get_offscreen_before_delete();
|
||||
delete surface;
|
||||
return offs;
|
||||
int *pw, *ph;
|
||||
cache_w_h(img, pw, ph);
|
||||
*pw = img->data_w();
|
||||
*ph = img->data_h();
|
||||
*Fl_Graphics_Driver::id(img) = (fl_uintptr_t)offs;
|
||||
return (fl_uintptr_t)offs;
|
||||
}
|
||||
|
||||
|
||||
void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_RGB_Image *img, float s, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = X*s;
|
||||
Y = Y*s;
|
||||
void Fl_GDI_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = X*scale_;
|
||||
Y = Y*scale_;
|
||||
cache_size(img, W, H);
|
||||
cx *= s; cy *= s;
|
||||
cx *= scale_; cy *= scale_;
|
||||
if (W + cx > img->data_w()) W = img->data_w() - cx;
|
||||
if (H + cy > img->data_h()) H = img->data_h() - cy;
|
||||
if (!*Fl_Graphics_Driver::id(img)) {
|
||||
*Fl_Graphics_Driver::id(img) = (fl_uintptr_t)build_id(img, (void**)(Fl_Graphics_Driver::mask(img)));
|
||||
*Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cache(img);
|
||||
int *pw, *ph;
|
||||
cache_w_h(img, pw, ph);
|
||||
*pw = img->data_w();
|
||||
*ph = img->data_h();
|
||||
}
|
||||
Fl_Region r2 = scale_clip(s);
|
||||
if (*Fl_Graphics_Driver::mask(img)) {
|
||||
HDC new_gc = CreateCompatibleDC(gc_);
|
||||
int save = SaveDC(new_gc);
|
||||
@ -518,52 +530,65 @@ void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_RGB_Image *img, float s, int X, in
|
||||
} else {
|
||||
copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(img), cx, cy);
|
||||
}
|
||||
unscale_clip(r2);
|
||||
}
|
||||
|
||||
int Fl_GDI_Printer_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP) {
|
||||
XFORM old_tr, tr;
|
||||
GetWorldTransform(gc_, &old_tr); // storing old transform
|
||||
tr.eM11 = float(WP)/float(img->data_w());
|
||||
tr.eM22 = float(HP)/float(img->data_h());
|
||||
tr.eM12 = tr.eM21 = 0;
|
||||
tr.eDx = float(XP);
|
||||
tr.eDy = float(YP);
|
||||
ModifyWorldTransform(gc_, &tr, MWT_LEFTMULTIPLY);
|
||||
img->draw(0, 0, img->data_w(), img->data_h(), 0, 0);
|
||||
SetWorldTransform(gc_, &old_tr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int Fl_GDI_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP) {
|
||||
Fl_RGB_Image *rgb = img->as_rgb_image();
|
||||
if (!rgb || !rgb->array) return 0; // for bitmaps and pixmaps
|
||||
if ((rgb->d() % 2) == 0 && !can_do_alpha_blending()) return 0;
|
||||
|
||||
void Fl_GDI_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, XP, YP, WP, HP)) {
|
||||
return;
|
||||
}
|
||||
if ((rgb->d() % 2) == 0 && !fl_can_do_alpha_blending()) {
|
||||
Fl_Graphics_Driver::draw_rgb(rgb, XP, YP, WP, HP, cx, cy);
|
||||
return;
|
||||
}
|
||||
if (!*Fl_Graphics_Driver::id(rgb)) {
|
||||
*Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)build_id(rgb,
|
||||
(void**)(Fl_Graphics_Driver::mask(rgb)));
|
||||
*Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)cache(rgb);
|
||||
int *pw, *ph;
|
||||
cache_w_h(rgb, pw, ph);
|
||||
*pw = rgb->data_w();
|
||||
*ph = rgb->data_h();
|
||||
}
|
||||
cache_size(img, WP, HP);
|
||||
float scaleW = float(rgb->data_w())/rgb->w();
|
||||
float scaleH = float(rgb->data_h())/rgb->h();
|
||||
int W = WP, H = HP;
|
||||
cache_size(rgb, W, H);
|
||||
HDC new_gc = CreateCompatibleDC(gc_);
|
||||
int save = SaveDC(new_gc);
|
||||
SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(rgb));
|
||||
if ( (rgb->d() % 2) == 0 ) {
|
||||
alpha_blend_(XP*scale_, YP*scale_, WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h());
|
||||
alpha_blend_(XP*scale_, YP*scale_, W, H, new_gc, cx*scaleW, cy*scaleH, WP*scaleW, HP*scaleH);
|
||||
} else {
|
||||
SetStretchBltMode(gc_, HALFTONE);
|
||||
StretchBlt(gc_, XP*scale_, YP*scale_, WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h(), SRCCOPY);
|
||||
StretchBlt(gc_, XP*scale_, YP*scale_, W, H, new_gc, cx*scaleW, cy*scaleH, WP*scaleW, HP*scaleH, SRCCOPY);
|
||||
}
|
||||
RestoreDC(new_gc, save);
|
||||
DeleteDC(new_gc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void Fl_GDI_Printer_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, XP, YP, WP, HP)) {
|
||||
return;
|
||||
}
|
||||
XFORM old_tr, tr;
|
||||
GetWorldTransform(gc_, &old_tr); // storing old transform
|
||||
tr.eM11 = float(rgb->w())/float(rgb->data_w());
|
||||
tr.eM22 = float(rgb->h())/float(rgb->data_h());
|
||||
tr.eM12 = tr.eM21 = 0;
|
||||
tr.eDx = float(XP);
|
||||
tr.eDy = float(YP);
|
||||
ModifyWorldTransform(gc_, &tr, MWT_LEFTMULTIPLY);
|
||||
if (*id(rgb)) {
|
||||
int *pw, *ph;
|
||||
cache_w_h(rgb, pw, ph);
|
||||
if ( *pw != rgb->data_w() || *ph != rgb->data_h()) rgb->uncache();
|
||||
}
|
||||
if (!*id(rgb)) cache(rgb);
|
||||
draw_fixed(rgb, 0, 0, WP/tr.eM11, HP/tr.eM22, cx/tr.eM11, cy/tr.eM22);
|
||||
SetWorldTransform(gc_, &old_tr);
|
||||
}
|
||||
|
||||
|
||||
void Fl_GDI_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_)
|
||||
{
|
||||
if (id_) {
|
||||
@ -613,12 +638,12 @@ fl_uintptr_t Fl_GDI_Graphics_Driver::cache(Fl_Bitmap *bm) {
|
||||
return (fl_uintptr_t)fl_create_bitmap(bm->data_w(), bm->data_h(), bm->array);
|
||||
}
|
||||
|
||||
void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = X*s;
|
||||
Y = Y*s;
|
||||
void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = X*scale_;
|
||||
Y = Y*scale_;
|
||||
cache_size(pxm, W, H);
|
||||
cx *= s; cy *= s;
|
||||
Fl_Region r2 = scale_clip(s);
|
||||
cx *= scale_; cy *= scale_;
|
||||
Fl_Region r2 = scale_clip(scale_);
|
||||
if (*Fl_Graphics_Driver::mask(pxm)) {
|
||||
HDC new_gc = CreateCompatibleDC(gc_);
|
||||
int save = SaveDC(new_gc);
|
||||
@ -635,18 +660,32 @@ void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int X, int Y
|
||||
}
|
||||
|
||||
|
||||
void Fl_GDI_Printer_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
void Fl_GDI_Printer_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::prepare(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) return;
|
||||
if (start_image(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) return;
|
||||
transparent_f_type fl_TransparentBlt = TransparentBlt();
|
||||
if (fl_TransparentBlt) {
|
||||
bool recache = false;
|
||||
if (*id(pxm)) {
|
||||
int *pw, *ph;
|
||||
cache_w_h(pxm, pw, ph);
|
||||
recache = (*pw != pxm->data_w() || *ph != pxm->data_h());
|
||||
}
|
||||
if (recache || !*id(pxm)) {
|
||||
pxm->uncache();
|
||||
*Fl_Graphics_Driver::id(pxm) = cache(pxm);
|
||||
}
|
||||
HDC new_gc = CreateCompatibleDC(gc_);
|
||||
int save = SaveDC(new_gc);
|
||||
SelectObject(new_gc, (void*)*Fl_Graphics_Driver::id(pxm));
|
||||
// print all of offscreen but its parts in background color
|
||||
fl_TransparentBlt(gc_, X, Y, W, H, new_gc, cx, cy, W, H, *Fl_Graphics_Driver::pixmap_bg_color(pxm) );
|
||||
float scaleW = pxm->data_w()/float(pxm->w());
|
||||
float scaleH = pxm->data_h()/float(pxm->h());
|
||||
fl_TransparentBlt(gc_, X, Y, W, H, new_gc, cx * scaleW, cy * scaleH, W * scaleW, H * scaleH,
|
||||
*Fl_Graphics_Driver::pixmap_bg_color(pxm) );
|
||||
RestoreDC(new_gc,save);
|
||||
DeleteDC(new_gc);
|
||||
if (recache) pxm->uncache();
|
||||
}
|
||||
else {
|
||||
copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(pxm), cx, cy);
|
||||
|
@ -195,7 +195,6 @@ class Fl_Pico_Graphics_Driver : public Fl_Graphics_Driver {
|
||||
// the image offset by the cx and cy arguments.
|
||||
// */
|
||||
// virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {}
|
||||
// virtual int draw_scaled(Fl_Image *img, int X, int Y, int W, int H);
|
||||
// virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
|
||||
//
|
||||
// /** Sets the value of the driver-specific graphics context. */
|
||||
|
@ -49,7 +49,6 @@ public:
|
||||
// void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
// void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
// void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
// int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
|
||||
// void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
|
||||
// void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
|
||||
// void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
|
||||
|
@ -48,7 +48,6 @@ public:
|
||||
// void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
// void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
// void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
// int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
|
||||
// void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
|
||||
// void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
|
||||
// void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
|
||||
|
@ -575,7 +575,7 @@ void Fl_PostScript_Graphics_Driver::draw(Fl_Pixmap * pxm,int XP, int YP, int WP,
|
||||
int need_clip = cx || cy || WP != pxm->w() || HP != pxm->h();
|
||||
if (need_clip) push_clip(XP, YP, WP, HP);
|
||||
if (pxm->w() != pxm->data_w() || pxm->h() != pxm->data_h()) {
|
||||
draw_scaled(pxm, XP-cx, YP-cy, pxm->w(), pxm->h());
|
||||
scale_and_draw(pxm, XP-cx, YP-cy, pxm->w(), pxm->h());
|
||||
} else {
|
||||
const char * const * di =pxm->data();
|
||||
int w,h;
|
||||
@ -597,7 +597,7 @@ void Fl_PostScript_Graphics_Driver::draw(Fl_RGB_Image * rgb,int XP, int YP, int
|
||||
int need_clip = cx || cy || WP != rgb->w() || HP != rgb->h();
|
||||
if (need_clip) push_clip(XP, YP, WP, HP);
|
||||
if (rgb->w() != rgb->data_w() || rgb->h() != rgb->data_h()) {
|
||||
draw_scaled(rgb, XP-cx, YP-cy, rgb->w(), rgb->h());
|
||||
scale_and_draw(rgb, XP-cx, YP-cy, rgb->w(), rgb->h());
|
||||
} else {
|
||||
const uchar * di = rgb->array;
|
||||
int w = rgb->w();
|
||||
@ -612,7 +612,7 @@ void Fl_PostScript_Graphics_Driver::draw(Fl_RGB_Image * rgb,int XP, int YP, int
|
||||
if (need_clip) pop_clip();
|
||||
}
|
||||
|
||||
int Fl_PostScript_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP){
|
||||
int Fl_PostScript_Graphics_Driver::scale_and_draw(Fl_Image *img, int XP, int YP, int WP, int HP){
|
||||
int X, Y, W, H;
|
||||
clip_box(XP,YP,WP,HP,X,Y,W,H); // X,Y,W,H will give the unclipped area of XP,YP,WP,HP
|
||||
if (W == 0 || H == 0) return 1;
|
||||
@ -632,7 +632,7 @@ void Fl_PostScript_Graphics_Driver::draw(Fl_Bitmap * bitmap,int XP, int YP, int
|
||||
int need_clip = cx || cy || WP != bitmap->w() || HP != bitmap->h();
|
||||
if (need_clip) push_clip(XP, YP, WP, HP);
|
||||
if (bitmap->w() != bitmap->data_w() || bitmap->h() != bitmap->data_h()) {
|
||||
draw_scaled(bitmap, XP-cx, YP-cy, bitmap->w(), bitmap->h());
|
||||
scale_and_draw(bitmap, XP-cx, YP-cy, bitmap->w(), bitmap->h());
|
||||
} else {
|
||||
const uchar * di = bitmap->array;
|
||||
int w,h;
|
||||
|
@ -67,15 +67,16 @@ public:
|
||||
// --- bitmap stuff
|
||||
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
|
||||
void delete_bitmask(Fl_Bitmask bm);
|
||||
void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_bitmap(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
|
||||
void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
|
||||
void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
|
||||
void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1);
|
||||
fl_uintptr_t cache(Fl_Pixmap *img);
|
||||
fl_uintptr_t cache(Fl_Bitmap *img);
|
||||
fl_uintptr_t cache(Fl_RGB_Image *img);
|
||||
void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_);
|
||||
void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
|
||||
void draw_CGImage(CGImageRef cgimg, int x, int y, int w, int h, int srcx, int srcy, int sw, int sh);
|
||||
|
@ -132,7 +132,7 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
|
||||
fl_rectf(x,y,w,h);
|
||||
}
|
||||
|
||||
void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
void Fl_Quartz_Graphics_Driver::draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
@ -142,8 +142,38 @@ void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int
|
||||
}
|
||||
}
|
||||
|
||||
fl_uintptr_t Fl_Quartz_Graphics_Driver::cache(Fl_RGB_Image *rgb) {
|
||||
CGColorSpaceRef lut = rgb->d()<=2 ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
|
||||
int ld = rgb->ld();
|
||||
if (!ld) ld = rgb->data_w() * rgb->d();
|
||||
CGDataProviderRef src;
|
||||
if ( has_feature(PRINTER) ) {
|
||||
// When printing, the data at rgb->array are used when the printed page is completed,
|
||||
// that is, after return from this function.
|
||||
// At that stage, the rgb object has possibly been deleted. It is therefore necessary
|
||||
// to use a copy of rgb->array for printing. The mask_ member of rgb
|
||||
// is used to avoid repeating the copy operation if rgb is printed again.
|
||||
// The CGImage data provider deletes the copy at the latest of these two events:
|
||||
// deletion of rgb, and completion of the page where rgb was printed.
|
||||
size_t total = ld * rgb->data_h();
|
||||
uchar *copy = new uchar[total];
|
||||
memcpy(copy, rgb->array, total);
|
||||
src = CGDataProviderCreateWithData(NULL, copy, total, dataReleaseCB);
|
||||
*Fl_Graphics_Driver::mask(rgb) = 1;
|
||||
} else {
|
||||
// the CGImage data provider must not release the image data.
|
||||
src = CGDataProviderCreateWithData(NULL, rgb->array, ld * rgb->data_h(), NULL);
|
||||
}
|
||||
CGImageRef cgimg = CGImageCreate(rgb->data_w(), rgb->data_h(), 8, rgb->d()*8, ld,
|
||||
lut, (rgb->d()&1)?kCGImageAlphaNone:kCGImageAlphaLast,
|
||||
src, 0L, false, kCGRenderingIntentDefault);
|
||||
*Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)cgimg;
|
||||
CGColorSpaceRelease(lut);
|
||||
CGDataProviderRelease(src);
|
||||
return (fl_uintptr_t)cgimg;
|
||||
}
|
||||
|
||||
void Fl_Quartz_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
void Fl_Quartz_Graphics_Driver::draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
// Don't draw an empty image...
|
||||
if (!img->d() || !img->array) {
|
||||
@ -160,40 +190,14 @@ void Fl_Quartz_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP,
|
||||
cgimg = NULL;
|
||||
}
|
||||
if (!cgimg) {
|
||||
CGColorSpaceRef lut = img->d()<=2 ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
|
||||
int ld = img->ld();
|
||||
if (!ld) ld = img->data_w() * img->d();
|
||||
CGDataProviderRef src;
|
||||
if ( has_feature(PRINTER) ) {
|
||||
// When printing, the data at img->array are used when the printed page is completed,
|
||||
// that is, after return from this function.
|
||||
// At that stage, the img object has possibly been deleted. It is therefore necessary
|
||||
// to use a copy of img->array for printing. The mask_ member of img
|
||||
// is used to avoid repeating the copy operation if img is printed again.
|
||||
// The CGImage data provider deletes the copy at the latest of these two events:
|
||||
// deletion of img, and completion of the page where img was printed.
|
||||
size_t total = ld * img->data_h();
|
||||
uchar *copy = new uchar[total];
|
||||
memcpy(copy, img->array, total);
|
||||
src = CGDataProviderCreateWithData(NULL, copy, total, dataReleaseCB);
|
||||
*Fl_Graphics_Driver::mask(img) = 1;
|
||||
} else {
|
||||
// the CGImage data provider must not release the image data.
|
||||
src = CGDataProviderCreateWithData(NULL, img->array, ld * img->data_h(), NULL);
|
||||
}
|
||||
cgimg = CGImageCreate(img->data_w(), img->data_h(), 8, img->d()*8, ld,
|
||||
lut, (img->d()&1)?kCGImageAlphaNone:kCGImageAlphaLast,
|
||||
src, 0L, false, kCGRenderingIntentDefault);
|
||||
*Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cgimg;
|
||||
CGColorSpaceRelease(lut);
|
||||
CGDataProviderRelease(src);
|
||||
cgimg = (CGImageRef)cache(img);
|
||||
}
|
||||
if (cgimg && gc_) {
|
||||
draw_CGImage(cgimg, X,Y,W,H, cx,cy, img->w(), img->h());
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_Quartz_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
void Fl_Quartz_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::prepare(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) return;
|
||||
CGImageRef cgimg = (CGImageRef)*Fl_Graphics_Driver::id(pxm);
|
||||
|
@ -62,16 +62,16 @@ private:
|
||||
int line_delta_;
|
||||
virtual void set_current_();
|
||||
int clip_max_; // +/- x/y coordinate limit (16-bit coordinate space)
|
||||
virtual void draw_fixed(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_fixed(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_fixed(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
protected:
|
||||
virtual void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_unscaled(Fl_Bitmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_unscaled(Fl_RGB_Image *img, float s, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
virtual void draw_image_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
|
||||
virtual void draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
|
||||
virtual void draw_image_mono_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
|
||||
virtual void draw_image_mono_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1);
|
||||
#if HAVE_XRENDER
|
||||
virtual int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
|
||||
int scale_and_render_pixmap(Fl_Offscreen pixmap, int depth, double scale_x, double scale_y, int srcx, int srcy, int XP, int YP, int WP, int HP);
|
||||
#endif
|
||||
virtual int height_unscaled();
|
||||
@ -101,7 +101,7 @@ protected:
|
||||
static Window draw_window;
|
||||
static struct _XftDraw* draw_;
|
||||
#endif
|
||||
Fl_Offscreen cache_rgb(Fl_RGB_Image *img);
|
||||
fl_uintptr_t cache(Fl_RGB_Image *img);
|
||||
public:
|
||||
Fl_Xlib_Graphics_Driver(void);
|
||||
virtual ~Fl_Xlib_Graphics_Driver();
|
||||
|
@ -624,14 +624,14 @@ void Fl_Xlib_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) {
|
||||
XFreePixmap(fl_display, bm);
|
||||
}
|
||||
|
||||
void Fl_Xlib_Graphics_Driver::draw_unscaled(Fl_Bitmap *bm, float s, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = (X+offset_x_)*s;
|
||||
Y = (Y+offset_y_)*s;
|
||||
void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = (X+offset_x_)*scale_;
|
||||
Y = (Y+offset_y_)*scale_;
|
||||
cache_size(bm, W, H);
|
||||
cx *= s; cy *= s;
|
||||
cx *= scale_; cy *= scale_;
|
||||
XSetStipple(fl_display, gc_, *Fl_Graphics_Driver::id(bm));
|
||||
int ox = X-cx; if (ox < 0) ox += bm->w()*s;
|
||||
int oy = Y-cy; if (oy < 0) oy += bm->h()*s;
|
||||
int ox = X-cx; if (ox < 0) ox += bm->w()*scale_;
|
||||
int oy = Y-cy; if (oy < 0) oy += bm->h()*scale_;
|
||||
XSetTSOrigin(fl_display, gc_, ox, oy);
|
||||
XSetFillStyle(fl_display, gc_, FillStippled);
|
||||
XFillRectangle(fl_display, fl_window, gc_, X, Y, W, H);
|
||||
@ -696,7 +696,7 @@ static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, i
|
||||
delete[] dst;
|
||||
}
|
||||
|
||||
Fl_Offscreen Fl_Xlib_Graphics_Driver::cache_rgb(Fl_RGB_Image *img) {
|
||||
fl_uintptr_t Fl_Xlib_Graphics_Driver::cache(Fl_RGB_Image *img) {
|
||||
Fl_Image_Surface *surface;
|
||||
int depth = img->d();
|
||||
if (depth == 1 || depth == 3) {
|
||||
@ -717,48 +717,53 @@ Fl_Offscreen Fl_Xlib_Graphics_Driver::cache_rgb(Fl_RGB_Image *img) {
|
||||
cache_w_h(img, pw, ph);
|
||||
*pw = img->data_w();
|
||||
*ph = img->data_h();
|
||||
return off;
|
||||
*Fl_Graphics_Driver::id(img) = (fl_uintptr_t)off;
|
||||
return (fl_uintptr_t)off;
|
||||
}
|
||||
|
||||
// X,Y,W,H,cx,cy are in FLTK units
|
||||
// if s != 1 and id(img) != 0, the offscreen has been previously scaled by s
|
||||
// if s != 1 and id(img) == 0, img has been previously scaled by s
|
||||
void Fl_Xlib_Graphics_Driver::draw_unscaled(Fl_RGB_Image *img, float s, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = (X+offset_x_)*s;
|
||||
Y = (Y+offset_y_)*s;
|
||||
|
||||
void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = (X+offset_x_)*scale_;
|
||||
Y = (Y+offset_y_)*scale_;
|
||||
cache_size(img, W, H);
|
||||
cx *= s; cy *= s;
|
||||
if (W + cx > img->data_w()) W = img->data_w() - cx;
|
||||
if (H + cy > img->data_h()) H = img->data_h() - cy;
|
||||
if (!*Fl_Graphics_Driver::id(img)) {
|
||||
*Fl_Graphics_Driver::id(img) = cache_rgb(img);
|
||||
cx *= scale_; cy *= scale_;
|
||||
if (img->d() == 1 || img->d() == 3) {
|
||||
XCopyArea(fl_display, *Fl_Graphics_Driver::id(img), fl_window, gc_, cx, cy, W, H, X, Y);
|
||||
return;
|
||||
}
|
||||
Fl_Region r2 = scale_clip(s);
|
||||
if (*Fl_Graphics_Driver::id(img)) {
|
||||
if (img->d() == 4 || img->d() == 2) {
|
||||
#if HAVE_XRENDER
|
||||
scale_ = 1;
|
||||
scale_and_render_pixmap(*Fl_Graphics_Driver::id(img), img->d(), 1, 1, cx, cy, X, Y, W, H);
|
||||
scale_ = s;
|
||||
#endif
|
||||
} else {
|
||||
XCopyArea(fl_display, *Fl_Graphics_Driver::id(img), fl_window, gc_, cx, cy, W, H, X, Y);
|
||||
}
|
||||
} else {
|
||||
// Composite image with alpha manually each time...
|
||||
scale_ = 1;
|
||||
int ox = offset_x_, oy = offset_y_;
|
||||
offset_x_ = offset_y_ = 0;
|
||||
Fl_X11_Screen_Driver *d = (Fl_X11_Screen_Driver*)Fl::screen_driver();
|
||||
int nscreen = Fl_Window::current()->driver()->screen_num();
|
||||
float keep = d->scale(nscreen);
|
||||
d->scale(nscreen, 1);
|
||||
alpha_blend(img, X, Y, W, H, cx, cy);
|
||||
d->scale(nscreen, keep);
|
||||
scale_ = s;
|
||||
offset_x_ = ox; offset_y_ = oy;
|
||||
// Composite image with alpha manually each time...
|
||||
float s = scale_;
|
||||
scale_ = 1;
|
||||
int ox = offset_x_, oy = offset_y_;
|
||||
offset_x_ = offset_y_ = 0;
|
||||
Fl_X11_Screen_Driver *d = (Fl_X11_Screen_Driver*)Fl::screen_driver();
|
||||
int nscreen = Fl_Window::current()->driver()->screen_num();
|
||||
float keep = d->scale(nscreen);
|
||||
d->scale(nscreen, 1);
|
||||
push_no_clip();
|
||||
alpha_blend(img, X, Y, W, H, cx, cy);
|
||||
pop_clip();
|
||||
d->scale(nscreen, keep);
|
||||
scale_ = s;
|
||||
offset_x_ = ox; offset_y_ = oy;
|
||||
}
|
||||
|
||||
void Fl_Xlib_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
if (!fl_can_do_alpha_blending()) {
|
||||
Fl_Graphics_Driver::draw_rgb(rgb, XP, YP, WP, HP, cx, cy);
|
||||
return;
|
||||
}
|
||||
unscale_clip(r2);
|
||||
int X, Y, W, H;
|
||||
if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
}
|
||||
if (!*Fl_Graphics_Driver::id(rgb)) {
|
||||
*Fl_Graphics_Driver::id(rgb) = cache(rgb);
|
||||
}
|
||||
cache_size(rgb, W, H);
|
||||
scale_and_render_pixmap( *Fl_Graphics_Driver::id(rgb), rgb->d(),
|
||||
rgb->data_w() / double(rgb->w()*scale_), rgb->data_h() / double(rgb->h()*scale_),
|
||||
cx*scale_, cy*scale_, (X + offset_x_)*scale_, (Y + offset_y_)*scale_, W, H);
|
||||
}
|
||||
|
||||
void Fl_Xlib_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_)
|
||||
@ -777,12 +782,12 @@ fl_uintptr_t Fl_Xlib_Graphics_Driver::cache(Fl_Bitmap *bm) {
|
||||
return (fl_uintptr_t)create_bitmask(bm->data_w(), bm->data_h(), bm->array);
|
||||
}
|
||||
|
||||
void Fl_Xlib_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = (X+offset_x_)*s;
|
||||
Y = (Y+offset_y_)*s;
|
||||
void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) {
|
||||
X = (X+offset_x_)*scale_;
|
||||
Y = (Y+offset_y_)*scale_;
|
||||
cache_size(pxm, W, H);
|
||||
cx *= s; cy *= s;
|
||||
Fl_Region r2 = scale_clip(s);
|
||||
cx *= scale_; cy *= scale_;
|
||||
Fl_Region r2 = scale_clip(scale_);
|
||||
if (*Fl_Graphics_Driver::mask(pxm)) {
|
||||
// make X use the bitmap as a mask:
|
||||
XSetClipMask(fl_display, gc_, *Fl_Graphics_Driver::mask(pxm));
|
||||
@ -813,7 +818,7 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int X, int
|
||||
}
|
||||
// put the old clip region back
|
||||
XSetClipOrigin(fl_display, gc_, 0, 0);
|
||||
s = scale_; scale_ = 1;
|
||||
float s = scale_; scale_ = 1;
|
||||
restore_clip();
|
||||
scale_ = s;
|
||||
}
|
||||
@ -884,17 +889,6 @@ int Fl_Xlib_Graphics_Driver::scale_and_render_pixmap(Fl_Offscreen pixmap, int de
|
||||
return 1;
|
||||
}
|
||||
|
||||
// XP,YP,WP,HP are in FLTK units
|
||||
int Fl_Xlib_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP) {
|
||||
Fl_RGB_Image *rgb = img->as_rgb_image();
|
||||
if (!rgb || !can_do_alpha_blending()) return 0;
|
||||
if (!*Fl_Graphics_Driver::id(rgb)) {
|
||||
*Fl_Graphics_Driver::id(rgb) = cache_rgb(rgb);
|
||||
}
|
||||
cache_size(img, WP, HP);
|
||||
return scale_and_render_pixmap( *Fl_Graphics_Driver::id(rgb), rgb->d(),
|
||||
rgb->data_w() / double(WP), rgb->data_h() / double(HP), 0, 0, (XP + offset_x_)*scale_, (YP + offset_y_)*scale_, WP, HP);
|
||||
}
|
||||
#endif // HAVE_XRENDER
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user