cross-platform的绘制–FLTK3.0 demo

void fltk3::GraphicsDriver::rectf(int x, int y, int w, int h) 
{
if (w<=0 || h<=0) return;
#if defined(USE_X11)   //X11 defined
if (!clip_to_short(x, y, w, h))
XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h);
#elif defined(WIN32)    // win 32
RECT rect;
rect.left = x; rect.top = y; 
rect.right = x + w; rect.bottom = y + h;
FillRect(fl_gc, &rect, fl_brush());
#elif defined(__APPLE_QUARTZ__)   //apple quarts
CGRect rect = CGRectMake(x, y, w0.9, h0.9);
CGContextFillRect(fl_gc, rect);
#else
# error unsupported platform
#endif
}
 
let’s us analyze the GraphicsDriver
 
GDI :
class FLTK3_EXPORT GDIGraphicsDriver : public fltk3::GraphicsDriver {
 
Apple:
class FLTK3_EXPORT QuartzGraphicsDriver : public fltk3::GraphicsDriver {
MAC OS de  CGContext 也有 window,bitmap == 类似 windows 上的 memory DC,
还有  offscreen 的 Context,print, PDF等
 
 
XLib:
class XlibGraphicsDriver : public fltk3::GraphicsDriver {
 
 
 
又从 irr enginee 中可以看出一般人的写法都是:
 
对 device 分别写不同的cpp,只是抽象出一个头文件
 
来看看 FLTK的 rect。
FLTK 在 头文件里声明一个 全局的 GraphicsDriver。如下;
namespace fltk3 {
class GraphicsDriver;
/** \brief Points to the driver that currently receives all graphics requests */

FLTK3_EXPORT extern GraphicsDriver *graphics_driver;

 
这个 声明放在一个 device.h 的头文件里。
然后再不同的平台上,做不同的赋值,如下是 X11 系统的:
static fltk3::XlibGraphicsDriver fl_xlib_driver;
static fltk3::DisplayDevice fl_xlib_display(&fl_xlib_driver);
FLTK3_EXPORT fltk3::GraphicsDriver *fltk3::graphics_driver = (fltk3::GraphicsDriver*)&fl_xlib_driver; // the current target device of graphics operations
下面是win32 的

static fltk3::GDIGraphicsDriver fl_gdi_driver;
static fltk3::DisplayDevice fl_gdi_display(&fl_gdi_driver);
FLTK3_EXPORT fltk3::GraphicsDriver *fltk3::graphics_driver = (fltk3::GraphicsDriver*)&fl_gdi_driver; // the current target driver of graphics operations
fltk3::SurfaceDevice* fltk3::SurfaceDevice::_surface = (fltk3::SurfaceDevice*)&fl_gdi_display; // the current target surface of graphics operations
fltk3::DisplayDevice *fltk3::DisplayDevice::_display = &fl_gdi_display; // the platform display
 
上面的是 对 render 的封装。
真正绘制,是需要取得窗口的DC 的,在windows 上这样的。

// Here we ensure only one GetDC is ever in place.
HDC fl_GetDC(HWND w) {
if (fl_gc) {
if (w == fl_window && fl_window != NULL) return fl_gc;
if (fl_window) fl_release_dc(fl_window, fl_gc); // ReleaseDC
}
fl_gc = GetDC(w);
fl_save_dc(w, fl_gc);
fl_window = w;
// calling GetDC seems to always reset these: (?)
SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT);
SetBkMode(fl_gc, TRANSPARENT);
return fl_gc;

}

 
看 上面的 fl_gc 是个 全局变量。
 
然后来看 driver 怎么用这个 fl_gc;
void fltk3::GraphicsDriver::rect(int x, int y, int w, int h) {
if (w<=0 || h<=0) return;
#if defined(USE_X11)
if (!clip_to_short(x, y, w, h))
XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1);
#elif defined(WIN32)
MoveToEx(fl_gc, x, y, 0L);
LineTo(fl_gc, x+w-1, y);
LineTo(fl_gc, x+w-1, y+h-1);
LineTo(fl_gc, x, y+h-1);
LineTo(fl_gc, x, y);
#elif defined(__APPLE_QUARTZ__)
if ( (!USINGQUARTZPRINTER) && fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
CGRect rect = CGRectMake(x, y, w-1, h-1);
CGContextStrokeRect(fl_gc, rect);
if ( (!USINGQUARTZPRINTER) && fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
#else
# error unsupported platform
#endif

}

 
然后来看:
class FLTK3_EXPORT GDIGraphicsDriver : public fltk3::GraphicsDriver
class XlibGraphicsDriver : public fltk3::GraphicsDriver
class FLTK3_EXPORT QuartzGraphicsDriver : public fltk3::GraphicsDriver
 
通过这样的机制来完成不同平台的绘制封装。
感觉这个方式有点绕。
再看看 fl_gc 的定义:
win32平台
e:\Research\OpenSource\GUI-Framework\fltk30\include\fltk3\win32.h

extern FLTK3_EXPORT HINSTANCE fl_display;
extern FLTK3_EXPORT ::Window fl_window;
extern FLTK3_EXPORT HDC fl_gc;
extern FLTK3_EXPORT MSG fl_msg;
extern FLTK3_EXPORT HDC fl_GetDC(::Window);
extern FLTK3_EXPORT HDC fl_makeDC(HBITMAP);
 
e:\Research\OpenSource\GUI-Framework\fltk30\src\fltk3\win32.cxx
HDC fl_gc = 0;
x11平台
e:\Research\OpenSource\GUI-Framework\fltk30\include\fltk3\x.h
extern FLTK3_EXPORT GC fl_gc;
e:\Research\OpenSource\GUI-Framework\fltk30\src\fltk3\x11.cxx
GC fl_gc;
Apple平台
extern CGContextRef fl_gc;
 
 
0

Comments are closed.