mirror of
https://github.com/fltk/fltk.git
synced 2026-05-28 11:25:22 +08:00
It's possible to transmit an Fl_Shared_Image to Fl_Window::shape(const Fl_Image*) at no cost.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10809 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
+3
-3
@@ -138,9 +138,9 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
shape_data_type *shape_data_; ///< non-null means the window has a non-rectangular shape
|
shape_data_type *shape_data_; ///< non-null means the window has a non-rectangular shape
|
||||||
private:
|
private:
|
||||||
void shape_bitmap_(Fl_Bitmap* b);
|
void shape_bitmap_(Fl_Image* b);
|
||||||
void shape_alpha_(Fl_RGB_Image* img, int offset);
|
void shape_alpha_(Fl_Image* img, int offset);
|
||||||
void shape_pixmap_(Fl_Pixmap* pixmap);
|
void shape_pixmap_(Fl_Image* pixmap);
|
||||||
public:
|
public:
|
||||||
void shape(const Fl_Image* img);
|
void shape(const Fl_Image* img);
|
||||||
/** Set the window's shape with an Fl_Image.
|
/** Set the window's shape with an Fl_Image.
|
||||||
|
|||||||
+21
-19
@@ -54,7 +54,7 @@ static inline uchar swap_byte(const uchar b) {
|
|||||||
|
|
||||||
static inline BYTE bit(int x) { return (BYTE)(1 << (x%8)); }
|
static inline BYTE bit(int x) { return (BYTE)(1 << (x%8)); }
|
||||||
|
|
||||||
static HRGN bitmap2region(Fl_Bitmap* image) {
|
static HRGN bitmap2region(Fl_Image* image) {
|
||||||
HRGN hRgn = 0;
|
HRGN hRgn = 0;
|
||||||
/* Does this need to be dynamically determined, perhaps? */
|
/* Does this need to be dynamically determined, perhaps? */
|
||||||
const int ALLOC_UNIT = 100;
|
const int ALLOC_UNIT = 100;
|
||||||
@@ -67,7 +67,7 @@ static HRGN bitmap2region(Fl_Bitmap* image) {
|
|||||||
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
|
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
|
||||||
|
|
||||||
const int bytesPerLine = (image->w() + 7)/8;
|
const int bytesPerLine = (image->w() + 7)/8;
|
||||||
BYTE* p, *data = (BYTE*)image->array;
|
BYTE* p, *data = (BYTE*)*image->data();
|
||||||
for (int y = 0; y < image->h(); y++) {
|
for (int y = 0; y < image->h(); y++) {
|
||||||
// each row, left to right
|
// each row, left to right
|
||||||
for (int x = 0; x < image->w(); x++) {
|
for (int x = 0; x < image->w(); x++) {
|
||||||
@@ -155,9 +155,9 @@ void Fl_Window::combine_mask()
|
|||||||
if (!XShapeCombineMask_f) return;
|
if (!XShapeCombineMask_f) return;
|
||||||
shape_data_->lw_ = w();
|
shape_data_->lw_ = w();
|
||||||
shape_data_->lh_ = h();
|
shape_data_->lh_ = h();
|
||||||
Fl_Bitmap* temp = (Fl_Bitmap*)shape_data_->shape_->copy(shape_data_->lw_, shape_data_->lh_);
|
Fl_Image* temp = shape_data_->shape_->copy(shape_data_->lw_, shape_data_->lh_);
|
||||||
Pixmap pbitmap = XCreateBitmapFromData(fl_display, fl_xid(this),
|
Pixmap pbitmap = XCreateBitmapFromData(fl_display, fl_xid(this),
|
||||||
(const char*)temp->array,
|
(const char*)*temp->data(),
|
||||||
temp->w(), temp->h());
|
temp->w(), temp->h());
|
||||||
XShapeCombineMask_f(fl_display, fl_xid(this), ShapeBounding, 0, 0, pbitmap, ShapeSet);
|
XShapeCombineMask_f(fl_display, fl_xid(this), ShapeBounding, 0, 0, pbitmap, ShapeSet);
|
||||||
if (pbitmap != None) XFreePixmap(fl_display, pbitmap);
|
if (pbitmap != None) XFreePixmap(fl_display, pbitmap);
|
||||||
@@ -168,7 +168,7 @@ void Fl_Window::combine_mask()
|
|||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
|
||||||
void Fl_Window::shape_bitmap_(Fl_Bitmap* b) {
|
void Fl_Window::shape_bitmap_(Fl_Image* b) {
|
||||||
shape_data_->shape_ = b;
|
shape_data_->shape_ = b;
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
if (b) {
|
if (b) {
|
||||||
@@ -176,7 +176,7 @@ void Fl_Window::shape_bitmap_(Fl_Bitmap* b) {
|
|||||||
int bytes_per_row = (b->w() + 7)/8;
|
int bytes_per_row = (b->w() + 7)/8;
|
||||||
uchar *from = new uchar[bytes_per_row * b->h()];
|
uchar *from = new uchar[bytes_per_row * b->h()];
|
||||||
for (int i = 0; i < b->h(); i++) {
|
for (int i = 0; i < b->h(); i++) {
|
||||||
uchar *p = (uchar*)b->array + bytes_per_row * i;
|
uchar *p = (uchar*)(*b->data()) + bytes_per_row * i;
|
||||||
uchar *last = p + bytes_per_row;
|
uchar *last = p + bytes_per_row;
|
||||||
uchar *q = from + (b->h() - 1 - i) * bytes_per_row;
|
uchar *q = from + (b->h() - 1 - i) * bytes_per_row;
|
||||||
while (p < last) {
|
while (p < last) {
|
||||||
@@ -195,7 +195,7 @@ void Fl_Window::shape_bitmap_(Fl_Bitmap* b) {
|
|||||||
/* the image can be of any depth
|
/* the image can be of any depth
|
||||||
offset gives the byte offset from the pixel start to the byte used to construct the shape
|
offset gives the byte offset from the pixel start to the byte used to construct the shape
|
||||||
*/
|
*/
|
||||||
void Fl_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
|
void Fl_Window::shape_alpha_(Fl_Image* img, int offset) {
|
||||||
int i, d = img->d(), w = img->w(), h = img->h();
|
int i, d = img->d(), w = img->w(), h = img->h();
|
||||||
shape_data_->shape_ = img;
|
shape_data_->shape_ = img;
|
||||||
if (shape_data_->shape_) {
|
if (shape_data_->shape_) {
|
||||||
@@ -203,7 +203,7 @@ void Fl_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
|
|||||||
int bytes_per_row = w * d;
|
int bytes_per_row = w * d;
|
||||||
uchar *from = new uchar[w * h];
|
uchar *from = new uchar[w * h];
|
||||||
for ( i = 0; i < h; i++) {
|
for ( i = 0; i < h; i++) {
|
||||||
uchar *p = (uchar*)img->array + bytes_per_row * i + offset;
|
uchar *p = (uchar*)(*img->data()) + bytes_per_row * i + offset;
|
||||||
uchar *last = p + bytes_per_row;
|
uchar *last = p + bytes_per_row;
|
||||||
uchar *q = from + (h - 1 - i) * w;
|
uchar *q = from + (h - 1 - i) * w;
|
||||||
while (p < last) {
|
while (p < last) {
|
||||||
@@ -230,13 +230,13 @@ void Fl_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
|
|||||||
/* the img image can be of any depth
|
/* the img image can be of any depth
|
||||||
offset gives the byte offset from the pixel start to the byte used to construct the shape
|
offset gives the byte offset from the pixel start to the byte used to construct the shape
|
||||||
*/
|
*/
|
||||||
void Fl_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
|
void Fl_Window::shape_alpha_(Fl_Image* img, int offset) {
|
||||||
int i, j, d = img->d(), w = img->w(), h = img->h(), bytesperrow = (w+7)/8;
|
int i, j, d = img->d(), w = img->w(), h = img->h(), bytesperrow = (w+7)/8;
|
||||||
unsigned u;
|
unsigned u;
|
||||||
uchar byte, onebit;
|
uchar byte, onebit;
|
||||||
// build an Fl_Bitmap covering the non-fully transparent/black part of the image
|
// build an Fl_Bitmap covering the non-fully transparent/black part of the image
|
||||||
const uchar* bits = new uchar[h*bytesperrow]; // to store the bitmap
|
const uchar* bits = new uchar[h*bytesperrow]; // to store the bitmap
|
||||||
const uchar* alpha = img->array + offset; // points to alpha value of rgba pixels
|
const uchar* alpha = (const uchar*)*img->data() + offset; // points to alpha value of rgba pixels
|
||||||
for (i = 0; i < h; i++) {
|
for (i = 0; i < h; i++) {
|
||||||
uchar *p = (uchar*)bits + i * bytesperrow;
|
uchar *p = (uchar*)bits + i * bytesperrow;
|
||||||
byte = 0;
|
byte = 0;
|
||||||
@@ -269,8 +269,8 @@ void Fl_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void Fl_Window::shape_pixmap_(Fl_Pixmap* pixmap) {
|
void Fl_Window::shape_pixmap_(Fl_Image* pixmap) {
|
||||||
Fl_RGB_Image* rgba = new Fl_RGB_Image(pixmap);
|
Fl_RGB_Image* rgba = new Fl_RGB_Image((Fl_Pixmap*)pixmap);
|
||||||
shape_alpha_(rgba, 3);
|
shape_alpha_(rgba, 3);
|
||||||
delete rgba;
|
delete rgba;
|
||||||
}
|
}
|
||||||
@@ -287,12 +287,14 @@ Fl_Window::shape_data_type* Fl_Window::shape_data_ = NULL;
|
|||||||
rectangular bounding box is available
|
rectangular bounding box is available
|
||||||
to them. It is up to you to make sure they adhere to the bounds of their masking shape.
|
to them. It is up to you to make sure they adhere to the bounds of their masking shape.
|
||||||
|
|
||||||
The \p img argument can be an Fl_Bitmap, Fl_Pixmap or Fl_RGB_Image:
|
The \p img argument can be an Fl_Bitmap, Fl_Pixmap, Fl_RGB_Image or Fl_Shared_Image:
|
||||||
\li With Fl_Bitmap or Fl_Pixmap, the shaped window covers the image part where bitmap bits equal one,
|
\li With Fl_Bitmap or Fl_Pixmap, the shaped window covers the image part where bitmap bits equal one,
|
||||||
or where the pixmap is not fully transparent.
|
or where the pixmap is not fully transparent.
|
||||||
\li With an Fl_RGB_Image with an alpha channel (depths 2 or 4), the shaped window covers the image part
|
\li With an Fl_RGB_Image with an alpha channel (depths 2 or 4), the shaped window covers the image part
|
||||||
that is not fully transparent.
|
that is not fully transparent.
|
||||||
\li With an Fl_RGB_Image of depth 1 (gray-scale) or 3 (RGB), the shaped window covers the non-black image part.
|
\li With an Fl_RGB_Image of depth 1 (gray-scale) or 3 (RGB), the shaped window covers the non-black image part.
|
||||||
|
\li With an Fl_Shared_Image, the shape is determined by rules above applied to the underlying image.
|
||||||
|
The shared image should not have been scaled through Fl_Shared_Image::scale().
|
||||||
|
|
||||||
Platform details:
|
Platform details:
|
||||||
\li On the unix/linux platform, the SHAPE extension of the X server is required.
|
\li On the unix/linux platform, the SHAPE extension of the X server is required.
|
||||||
@@ -327,10 +329,10 @@ void Fl_Window::shape(const Fl_Image* img) {
|
|||||||
memset(shape_data_, 0, sizeof(shape_data_type));
|
memset(shape_data_, 0, sizeof(shape_data_type));
|
||||||
border(false);
|
border(false);
|
||||||
int d = img->d();
|
int d = img->d();
|
||||||
if (d && img->count() >= 2) shape_pixmap_((Fl_Pixmap*)img);
|
if (d && img->count() >= 2) shape_pixmap_((Fl_Image*)img);
|
||||||
else if (d == 0) shape_bitmap_((Fl_Bitmap*)img);
|
else if (d == 0) shape_bitmap_((Fl_Image*)img);
|
||||||
else if (d == 2 || d == 4) shape_alpha_((Fl_RGB_Image*)img, d - 1);
|
else if (d == 2 || d == 4) shape_alpha_((Fl_Image*)img, d - 1);
|
||||||
else if ((d == 1 || d == 3) && img->count() == 1) shape_alpha_((Fl_RGB_Image*)img, 0);
|
else if ((d == 1 || d == 3) && img->count() == 1) shape_alpha_((Fl_Image*)img, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +348,7 @@ void Fl_Window::draw() {
|
|||||||
// size of window has changed since last time
|
// size of window has changed since last time
|
||||||
shape_data_->lw_ = w();
|
shape_data_->lw_ = w();
|
||||||
shape_data_->lh_ = h();
|
shape_data_->lh_ = h();
|
||||||
Fl_Bitmap* temp = (Fl_Bitmap*)shape_data_->shape_->copy(shape_data_->lw_, shape_data_->lh_);
|
Fl_Image* temp = shape_data_->shape_->copy(shape_data_->lw_, shape_data_->lh_);
|
||||||
HRGN region = bitmap2region(temp);
|
HRGN region = bitmap2region(temp);
|
||||||
SetWindowRgn(fl_xid(this), region, TRUE); // the system deletes the region when it's no longer needed
|
SetWindowRgn(fl_xid(this), region, TRUE); // the system deletes the region when it's no longer needed
|
||||||
delete temp;
|
delete temp;
|
||||||
|
|||||||
Reference in New Issue
Block a user