Rewrite fl_draw_pixmap.cxx under the driver model.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11587 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy
2016-04-12 13:47:38 +00:00
parent 3d4ce29bd9
commit fce1483eb8
4 changed files with 52 additions and 45 deletions
+3
View File
@@ -159,6 +159,9 @@ public:
virtual void* thread_message() {return NULL;}
// implement to support Fl_File_Icon
virtual int file_type(const char *filename);
// the default implementations of pixmap_extra_transparent_processing() and make_unused_color() and are most probably enough
virtual int pixmap_extra_transparent_processing() {return 0;}
virtual void make_unused_color(unsigned char &r, unsigned char &g, unsigned char &b) {}
};
#endif // FL_SYSTEM_DRIVER_H
@@ -37,6 +37,7 @@
#include <config.h>
#include "Fl_GDI_Graphics_Driver.H"
#include "../WinAPI/Fl_WinAPI_System_Driver.H"
#include <FL/Fl.H>
#include <FL/Fl_Printer.H>
#include <FL/fl_draw.H>
@@ -635,8 +636,7 @@ fl_uintptr_t Fl_GDI_Graphics_Driver::cache(Fl_Pixmap *img, int w, int h, const c
uchar *bitmap = 0;
Fl_Surface_Device::surface()->driver()->mask_bitmap(&bitmap);
fl_draw_pixmap(data, 0, 0, FL_BLACK);
extern UINT win_pixmap_bg_color; // computed by fl_draw_pixmap()
img->pixmap_bg_color = win_pixmap_bg_color;
img->pixmap_bg_color = Fl_WinAPI_System_Driver::win_pixmap_bg_color; // computed by fl_draw_pixmap()
Fl_Surface_Device::surface()->driver()->mask_bitmap(0);
if (bitmap) {
img->mask_ = (fl_uintptr_t)fl_create_bitmask(w, h, bitmap);
@@ -42,6 +42,7 @@
class Fl_WinAPI_System_Driver : public Fl_System_Driver
{
public:
static unsigned win_pixmap_bg_color; // the RGB() of the pixmap background color
virtual void warning(const char *format, va_list args);
virtual void error(const char *format, va_list args);
virtual void fatal(const char *format, va_list args);
@@ -93,6 +94,9 @@ public:
// this one is implemented in Fl_win32.cxx
virtual void* thread_message();
virtual int file_type(const char *filename);
virtual int pixmap_extra_transparent_processing() {return 1;}
// this one is implemented in fl_draw_pixmap.cxx
virtual void make_unused_color(unsigned char &r, unsigned char &g, unsigned char &b);
};
#endif // FL_WINAPI_SYSTEM_DRIVER_H
+43 -43
View File
@@ -32,20 +32,24 @@
// The above comments were checked in as r2, and much has changed since then;
// transparency added, color cube not required, etc. -erco Oct 20 2013
#include "config_lib.h"
#include <FL/Fl.H>
#include <FL/Fl_System_Driver.H>
#if defined(FL_CFG_SYS_WIN32)
#include "drivers/WinAPI/Fl_WinAPI_System_Driver.H"
#endif
#include <FL/x.H>
#include <FL/fl_draw.H>
#include <stdio.h>
#include "flstring.h"
#if defined(WIN32) || defined(__APPLE__) // PORTME: Fl_Graphics_Driver - platform pixmap
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: implement platform specific about pixmap drawing here"
#else
#endif
static int ncolors, chars_per_pixel;
typedef struct { uchar r; uchar g; uchar b; } UsedColor;
static UsedColor *used_colors;
static int color_count; // # of non-transparent colors used in pixmap
/**
Get the dimensions of a pixmap.
An XPM image contains the dimensions in its data. This function
@@ -84,16 +88,14 @@ int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color bg) {
return fl_draw_pixmap((const char*const*)data,x,y,bg);
}
#ifdef WIN32
// to compute an unused color to be used for the pixmap background
FL_EXPORT UINT win_pixmap_bg_color; // the RGB() of the pixmap background color
static int color_count; // # of non-transparent colors used in pixmap
typedef struct { uchar r; uchar g; uchar b; } UsedColor;
static UsedColor *used_colors;
#if defined(FL_CFG_SYS_WIN32)
unsigned Fl_WinAPI_System_Driver::win_pixmap_bg_color = 0; // the RGB() of the pixmap background color
// Makes an RGB triplet different from all the colors used in the pixmap
// and compute win_pixmap_bg_color from this triplet
static void make_unused_color(uchar &r, uchar &g, uchar &b) {
void Fl_WinAPI_System_Driver::make_unused_color(uchar &r, uchar &g, uchar &b) {
int i;
r = 2; g = 3; b = 4;
while (1) {
@@ -120,11 +122,14 @@ static void make_unused_color(uchar &r, uchar &g, uchar &b) {
}
}
}
#endif
#endif // FL_CFG_SYS_WIN32
int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
int w, h;
const uchar*const* data = (const uchar*const*)(cdata+1);
static int use_extra_transparent_processing = Fl::system_driver()->pixmap_extra_transparent_processing();
uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
if (!fl_measure_pixmap(cdata, w, h))
return 0;
@@ -135,11 +140,10 @@ int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
typedef uchar uchar4[4];
uchar4 *colors = new uchar4[1<<(chars_per_pixel*8)];
#ifdef WIN32
uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
color_count = 0;
used_colors = (UsedColor*)malloc(abs(ncolors) * sizeof(UsedColor));
#endif
if (use_extra_transparent_processing) {
color_count = 0;
used_colors = (UsedColor*)malloc(abs(ncolors) * sizeof(UsedColor));
}
if (ncolors < 0) { // FLTK (non standard) compressed colormap
ncolors = -ncolors;
@@ -149,21 +153,19 @@ int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
if (*p == ' ') {
uchar* c = colors[(int)' '];
Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
#ifdef WIN32
transparent_c = c;
#endif
if (use_extra_transparent_processing) transparent_c = c;
p += 4;
ncolors--;
}
// read all the rest of the colors:
for (int i=0; i < ncolors; i++) {
uchar* c = colors[*p++];
#ifdef WIN32
used_colors[color_count].r = *(p+0);
used_colors[color_count].g = *(p+1);
used_colors[color_count].b = *(p+2);
color_count++;
#endif
if (use_extra_transparent_processing) {
used_colors[color_count].r = *(p+0);
used_colors[color_count].g = *(p+1);
used_colors[color_count].b = *(p+2);
color_count++;
}
*c++ = *p++;
*c++ = *p++;
*c++ = *p++;
@@ -193,31 +195,29 @@ int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]);
c[3] = 255;
if (parse) {
#ifdef WIN32
used_colors[color_count].r = c[0];
used_colors[color_count].g = c[1];
used_colors[color_count].b = c[2];
color_count++;
#endif
if (use_extra_transparent_processing) {
used_colors[color_count].r = c[0];
used_colors[color_count].g = c[1];
used_colors[color_count].b = c[2];
color_count++;
}
} else {
// assume "None" or "#transparent" for any errors
// "bg" should be transparent...
Fl::get_color(bg, c[0], c[1], c[2]);
c[3] = 0;
#ifdef WIN32
transparent_c = c;
#endif
if (use_extra_transparent_processing) transparent_c = c;
} // if parse
} // for ncolors
} // if ncolors
#ifdef WIN32
if (transparent_c) {
make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
} else {
uchar r, g, b;
make_unused_color(r, g, b);
if (use_extra_transparent_processing) {
if (transparent_c) {
Fl::system_driver()->make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
} else {
uchar r, g, b;
Fl::system_driver()->make_unused_color(r, g, b);
}
}
#endif
U32 *q = (U32*)out;
for (int Y = 0; Y < h; Y++) {