diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2024-11-20 08:01:40 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2024-11-20 08:01:40 +0100 |
| commit | 1f05a0df443fd5e883d84f1322da6fcd7ad80f6d (patch) | |
| tree | 049f103e187094940857910ef739ea0a9d8a3cad /src | |
| parent | 6df2219aa0e56d9632824c94a3b217ec015aa22f (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.cxx | 54 | ||||
| -rw-r--r-- | src/fl_draw.cxx | 45 |
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); -} - |
