summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2024-11-20 08:01:40 +0100
committerManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2024-11-20 08:01:40 +0100
commit1f05a0df443fd5e883d84f1322da6fcd7ad80f6d (patch)
tree049f103e187094940857910ef739ea0a9d8a3cad /src
parent6df2219aa0e56d9632824c94a3b217ec015aa22f (diff)
Fix fl_draw_image sometimes crashes when window is scaled - cont'd (#1134)
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Graphics_Driver.cxx54
-rw-r--r--src/fl_draw.cxx45
2 files changed, 54 insertions, 45 deletions
diff --git a/src/Fl_Graphics_Driver.cxx b/src/Fl_Graphics_Driver.cxx
index 95716530a..78678de55 100644
--- a/src/Fl_Graphics_Driver.cxx
+++ b/src/Fl_Graphics_Driver.cxx
@@ -445,6 +445,60 @@ void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y
/** see fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D) */
void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D) {}
+
+typedef struct {
+ const uchar *buf;
+ int D_in;
+ int D_out;
+ int L;
+} image_data;
+
+
+static void scan_cb(image_data *data, int x, int y, int w, uchar *buffer) {
+ const uchar *from = data->buf + y * data->L + data->D_in * x;
+ while (w-- > 0) {
+ memcpy(buffer, from, data->D_out);
+ buffer += data->D_out;
+ from += data->D_in;
+ }
+}
+
+/* used only by inline fl_draw_image() */
+void Fl_Graphics_Driver::draw_image_general_(const uchar *buf, int X, int Y, int W, int H, int D, int L) {
+ const bool alpha = !!(abs(D) & FL_IMAGE_WITH_ALPHA);
+ int d_corrected, d_out;
+ if (alpha) {
+ d_corrected = D ^ FL_IMAGE_WITH_ALPHA;
+ d_out = 4;
+ } else {
+ d_corrected = D;
+ d_out = 3;
+ }
+ if (abs(d_corrected) > d_out) {
+ image_data data;
+ data.buf = buf;
+ data.D_in = d_corrected;
+ data.D_out = d_out;
+ data.L = (L ? L : W * d_corrected);
+ if (alpha) d_out |= FL_IMAGE_WITH_ALPHA;
+ fl_graphics_driver->draw_image((Fl_Draw_Image_Cb)scan_cb, &data, X, Y, W, H, d_out);
+ } else
+ fl_graphics_driver->draw_image(buf, X, Y, W, H, D, L);
+}
+
+/* used only by inline fl_draw_image_mono() */
+void Fl_Graphics_Driver::draw_image_mono_general_(const uchar *buf, int X, int Y, int W, int H, int D, int L) {
+ if (abs(D) > 1) {
+ image_data data;
+ data.buf = buf;
+ data.D_in = D;
+ data.D_out = 1;
+ data.L = (L ? L : W * D);
+ fl_graphics_driver->draw_image_mono((Fl_Draw_Image_Cb)scan_cb, &data, X, Y, W, H, 1);
+ } else
+ fl_graphics_driver->draw_image_mono(buf, X, Y, W, H, D, L);
+}
+
/** Support function for image drawing */
void Fl_Graphics_Driver::delete_bitmask(fl_uintptr_t /*bm*/) {}
diff --git a/src/fl_draw.cxx b/src/fl_draw.cxx
index 2f579fc57..72823b078 100644
--- a/src/fl_draw.cxx
+++ b/src/fl_draw.cxx
@@ -779,48 +779,3 @@ void fl_draw_radio(int x, int y, int d, Fl_Color color) {
}
fl_color(current);
}
-
-
-typedef struct {
- const uchar *buf;
- int D_in;
- int D_out;
- int L;
-} image_data;
-
-
-static void scan_cb(image_data *data, int x, int y, int w, uchar *buffer) {
- const uchar *from = data->buf + y * data->L + data->D_in * x;
- while (w-- > 0) {
- memcpy(buffer, from, data->D_out);
- buffer += data->D_out;
- from += data->D_in;
- }
-}
-
-
-void fl_draw_image(const uchar *buf, int X, int Y, int W, int H, int D, int L) {
- if (abs(D) > 3) {
- image_data data;
- data.buf = buf;
- data.D_in = D;
- data.D_out = 3;
- data.L = (L ? L : W * D);
- fl_graphics_driver->draw_image((Fl_Draw_Image_Cb)scan_cb, &data, X, Y, W, H, 3);
- } else
- fl_graphics_driver->draw_image(buf, X, Y, W, H, D, L);
-}
-
-
-void fl_draw_image_mono(const uchar *buf, int X, int Y, int W, int H, int D, int L) {
- if (abs(D) > 1) {
- image_data data;
- data.buf = buf;
- data.D_in = D;
- data.D_out = 1;
- data.L = (L ? L : W * D);
- fl_graphics_driver->draw_image_mono((Fl_Draw_Image_Cb)scan_cb, &data, X, Y, W, H, 1);
- } else
- fl_graphics_driver->draw_image_mono(buf, X, Y, W, H, D, L);
-}
-