STR#3450: Draw text with OpenGL using textures on all platforms.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12650 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
90630409cb
commit
dcc82d8926
4
CHANGES
4
CHANGES
@ -18,6 +18,10 @@ Changes in FLTK 1.4.0 Released: ??? ?? 2017
|
||||
New Features and Extensions
|
||||
|
||||
- (add new items here)
|
||||
- OpenGL draws text using textures on all platforms, when the necessary
|
||||
hardware support is present (a backup mechanism is available in absence
|
||||
of this support). Thus, all text drawable in Fl_Window's can be drawn
|
||||
in Fl_GL_Window's (STR#3450).
|
||||
- New member functions FL::run_also_windowless(),
|
||||
and FL::wait_also_windowless(double secnds) to run the event
|
||||
loop even without any mapped window if the platform supports it.
|
||||
|
22
FL/Fl.H
22
FL/Fl.H
@ -134,6 +134,7 @@ class FL_EXPORT Fl {
|
||||
private:
|
||||
|
||||
static int use_high_res_GL_;
|
||||
static int draw_GL_text_with_textures_;
|
||||
|
||||
public:
|
||||
|
||||
@ -1279,6 +1280,27 @@ int main() {
|
||||
\version 1.3.4
|
||||
*/
|
||||
static int use_high_res_GL() { return use_high_res_GL_; }
|
||||
|
||||
/** sets whether OpenGL uses textures to draw all text.
|
||||
By default, FLTK draws OpenGL text using textures, if the necessary
|
||||
hardware support is available. Call \p Fl::draw_GL_text_with_textures(0)
|
||||
once in your program before the first call to gl_font() to have FLTK
|
||||
draw instead OpenGL text using a legacy, platform-dependent procedure.
|
||||
It's recommended not to deactivate textures under the MacOS platform
|
||||
because the MacOS legacy procedure is extremely rudimentary.
|
||||
\param val use 0 to prevent FLTK from drawing GL text with textures
|
||||
\see gl_texture_pile_height(int max)
|
||||
\version 1.4.0
|
||||
*/
|
||||
static void draw_GL_text_with_textures(int val) { draw_GL_text_with_textures_ = val; }
|
||||
|
||||
/** returns whether whether OpenGL uses textures to draw all text.
|
||||
Default is yes.
|
||||
\see draw_GL_text_with_textures(int val)
|
||||
\version 1.4.0
|
||||
*/
|
||||
static int draw_GL_text_with_textures() { return draw_GL_text_with_textures_; }
|
||||
|
||||
|
||||
#ifdef FLTK_HAVE_CAIRO
|
||||
/** \defgroup group_cairo Cairo Support Functions and Classes
|
||||
|
@ -4,7 +4,7 @@
|
||||
// Definition of class Fl_Gl_Window_Driver, and of its platform-specific derived classes
|
||||
// for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2016-2017 by Bill Spitzak and others.
|
||||
// Copyright 2016-2018 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@ -44,7 +44,7 @@ public:
|
||||
void alist(const int *l) { pWindow->alist = l;}
|
||||
void* overlay() {return pWindow->overlay;}
|
||||
void draw_overlay() {pWindow->draw_overlay();}
|
||||
|
||||
|
||||
Fl_Gl_Window_Driver(Fl_Gl_Window *win) : pWindow(win) {}
|
||||
virtual ~Fl_Gl_Window_Driver() {}
|
||||
static Fl_Gl_Window_Driver *newGlWindowDriver(Fl_Gl_Window *w);
|
||||
@ -79,10 +79,17 @@ public:
|
||||
virtual void gl_visual(Fl_Gl_Choice*); // support for Fl::gl_visual() function
|
||||
virtual void gl_start() {} // support for gl_start() function
|
||||
virtual void* GetProcAddress(const char *procName); // support for glutGetProcAddress()
|
||||
virtual void draw_string(const char* str, int n); // support for gl_draw()
|
||||
virtual void draw_string_legacy(const char* str, int n); // support for gl_draw()
|
||||
void draw_string_legacy_get_list(const char* str, int n); // support for gl_draw()
|
||||
static void draw_string_legacy_glut(const char* str, int n); // support for gl_draw()
|
||||
virtual void get_list(Fl_Font_Descriptor* fd, int r) {} // support for gl_draw() without textures
|
||||
virtual void gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) {} // support for gl_font() without textures
|
||||
virtual int overlay_color(Fl_Color i) {return 0;} // support for gl_color() with HAVE_GL_OVERLAY
|
||||
static void draw_string_with_texture(const char* str, int n); // cross-platform
|
||||
// support for gl_draw(). The cross-platform version may be enough.
|
||||
virtual char *alpha_mask_for_string(const char *str, int n, int w, int h);
|
||||
virtual int genlistsize() { return 0; } // support for gl_draw()
|
||||
virtual Fl_Font_Descriptor** fontnum_to_fontdescriptor(int fnum);
|
||||
};
|
||||
|
||||
#ifdef FL_CFG_GFX_QUARTZ
|
||||
@ -111,13 +118,13 @@ class Fl_Cocoa_Gl_Window_Driver : public Fl_Gl_Window_Driver {
|
||||
virtual void make_overlay_current();
|
||||
virtual void redraw_overlay();
|
||||
virtual void gl_start();
|
||||
virtual void draw_string(const char* str, int n);
|
||||
static NSOpenGLContext* create_GLcontext_for_window(NSOpenGLPixelFormat *pixelformat, NSOpenGLContext *shared_ctx, Fl_Window *window);
|
||||
static NSOpenGLPixelFormat *mode_to_NSOpenGLPixelFormat(int mode, const int*); // uses Objective-c
|
||||
static void GLcontext_update(NSOpenGLContext*); // uses Objective-c
|
||||
static void GLcontext_release(NSOpenGLContext*); // uses Objective-c
|
||||
static void GLcontext_makecurrent(NSOpenGLContext*); // uses Objective-c
|
||||
static void GL_cleardrawable(void); // uses Objective-c
|
||||
virtual char *alpha_mask_for_string(const char *str, int n, int w, int h);
|
||||
};
|
||||
#endif // FL_CFG_GFX_QUARTZ
|
||||
|
||||
@ -141,8 +148,10 @@ class Fl_WinAPI_Gl_Window_Driver : public Fl_Gl_Window_Driver {
|
||||
virtual void make_overlay_current();
|
||||
virtual void redraw_overlay();
|
||||
virtual void* GetProcAddress(const char *procName);
|
||||
virtual void draw_string_legacy(const char* str, int n);
|
||||
virtual void gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize);
|
||||
virtual void get_list(Fl_Font_Descriptor *fd, int r);
|
||||
virtual int genlistsize();
|
||||
#if HAVE_GL_OVERLAY
|
||||
virtual int can_do_overlay();
|
||||
virtual int overlay_color(Fl_Color i);
|
||||
@ -153,7 +162,7 @@ class Fl_WinAPI_Gl_Window_Driver : public Fl_Gl_Window_Driver {
|
||||
|
||||
|
||||
#ifdef FL_CFG_GFX_XLIB
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xutil.h> // for XVisualInfo
|
||||
class Fl_X11_Gl_Window_Driver : public Fl_Gl_Window_Driver {
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
Fl_X11_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
|
||||
@ -178,9 +187,14 @@ class Fl_X11_Gl_Window_Driver : public Fl_Gl_Window_Driver {
|
||||
virtual void waitGL();
|
||||
virtual void gl_visual(Fl_Gl_Choice*); // support for Fl::gl_visual()
|
||||
virtual void gl_start();
|
||||
virtual void draw_string_legacy(const char* str, int n);
|
||||
virtual void gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize);
|
||||
virtual void get_list(Fl_Font_Descriptor *fd, int r);
|
||||
public:
|
||||
virtual int genlistsize();
|
||||
#if !USE_XFT
|
||||
virtual Fl_Font_Descriptor** fontnum_to_fontdescriptor(int fnum);
|
||||
#endif
|
||||
public:
|
||||
static GLContext create_gl_context(XVisualInfo* vis);
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// Definition of classes Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device
|
||||
// for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2010-2017 by Bill Spitzak and others.
|
||||
// Copyright 2010-2018 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@ -90,6 +90,7 @@ class FL_EXPORT Fl_Graphics_Driver {
|
||||
friend void fl_copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
|
||||
friend FL_EXPORT int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg);
|
||||
friend FL_EXPORT void gl_start();
|
||||
friend FL_EXPORT void gl_finish();
|
||||
friend FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array);
|
||||
friend FL_EXPORT void fl_delete_bitmask(Fl_Bitmask);
|
||||
private:
|
||||
@ -387,7 +388,7 @@ public:
|
||||
/** Some platforms may need to implement this to support fonts */
|
||||
virtual Fl_Fontdesc* calc_fl_fonts(void) {return NULL;}
|
||||
/** Support for Fl::set_font() */
|
||||
virtual unsigned font_desc_size() {return 0;}
|
||||
virtual unsigned font_desc_size();
|
||||
/** Support for Fl::get_font() */
|
||||
virtual const char *font_name(int num) {return NULL;}
|
||||
/** Support for Fl::set_font() */
|
||||
@ -397,6 +398,33 @@ public:
|
||||
};
|
||||
|
||||
#ifndef FL_DOXYGEN
|
||||
|
||||
/* This class is not part of FLTK's public API.
|
||||
Platforms usually define a derived class called Fl_XXX_Font_Descriptor
|
||||
containing extra platform-specific data/functions.
|
||||
This is a class for an actual system font, with junk to
|
||||
help choose it and info on character sizes. Each Fl_Fontdesc has a
|
||||
linked list of these. These are created the first time each system
|
||||
font/size combination is used.
|
||||
*/
|
||||
class Fl_Font_Descriptor {
|
||||
public:
|
||||
/** linked list for this Fl_Fontdesc */
|
||||
Fl_Font_Descriptor *next;
|
||||
Fl_Fontsize size; /**< font size */
|
||||
Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size);
|
||||
FL_EXPORT ~Fl_Font_Descriptor() {}
|
||||
short ascent, descent, q_width;
|
||||
unsigned int listbase;// base of display list, 0 = none
|
||||
};
|
||||
|
||||
// This struct is not part of FLTK's public API.
|
||||
struct Fl_Fontdesc {
|
||||
const char *name;
|
||||
char fontname[128]; // "Pretty" font name
|
||||
Fl_Font_Descriptor *first; // linked list of sizes of this style
|
||||
};
|
||||
|
||||
/* Abstract class Fl_Scalable_Graphics_Driver is platform-independent.
|
||||
It supports the scaling of all graphics coordinates by a
|
||||
float factor helpful to support HiDPI displays.
|
||||
|
21
FL/gl.h
21
FL/gl.h
@ -3,7 +3,7 @@
|
||||
//
|
||||
// OpenGL header file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2011 by Bill Spitzak and others.
|
||||
// Copyright 1998-2018 by Bill Spitzak and others.
|
||||
//
|
||||
// You must include this instead of GL/gl.h to get the Microsoft
|
||||
// APIENTRY stuff included (from <windows.h>) prior to the OpenGL
|
||||
@ -28,10 +28,11 @@
|
||||
*
|
||||
* To use OpenGL from within an FLTK application you MUST use gl_visual()
|
||||
* to select the default visual before doing show() on any windows. Mesa
|
||||
* will crash if yoy try to use a visual not returned by glxChooseVidual.
|
||||
* will crash if you try to use a visual not returned by glxChooseVisual.
|
||||
*
|
||||
* This does not work with Fl_Double_Window's! It will try to draw
|
||||
* into the front buffer. Depending on the system this will either
|
||||
* Historically, this did not always work well with Fl_Double_Window's!
|
||||
* It can try to draw into the front buffer.
|
||||
* Depending on the system this might either
|
||||
* crash or do nothing (when pixmaps are being used as back buffer
|
||||
* and GL is being done by hardware), work correctly (when GL is done
|
||||
* with software, such as Mesa), or draw into the front buffer and
|
||||
@ -89,16 +90,8 @@ FL_EXPORT void gl_draw(const char*, int n, int x, int y);
|
||||
FL_EXPORT void gl_draw(const char*, int n, float x, float y);
|
||||
FL_EXPORT void gl_draw(const char*, int x, int y, int w, int h, Fl_Align);
|
||||
FL_EXPORT void gl_measure(const char*, int& x, int& y);
|
||||
#ifdef __APPLE__ // PORTME: OpenGL platform texture
|
||||
extern FL_EXPORT void gl_texture_pile_height(int max);
|
||||
extern FL_EXPORT int gl_texture_pile_height();
|
||||
#elif defined(WIN32)
|
||||
// not needed
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: define functions to control OpenGL texture pile height if supported"
|
||||
#else // X11
|
||||
// not needed
|
||||
#endif
|
||||
FL_EXPORT void gl_texture_pile_height(int max);
|
||||
FL_EXPORT int gl_texture_pile_height();
|
||||
|
||||
FL_EXPORT void gl_draw_image(const uchar *, int x,int y,int w,int h, int d=3, int ld=0);
|
||||
|
||||
|
@ -1914,6 +1914,8 @@ Fl_Widget_Tracker::~Fl_Widget_Tracker()
|
||||
|
||||
int Fl::use_high_res_GL_ = 0;
|
||||
|
||||
int Fl::draw_GL_text_with_textures_ = 1;
|
||||
|
||||
int Fl::dnd()
|
||||
{
|
||||
return Fl::screen_driver()->dnd();
|
||||
|
@ -495,6 +495,10 @@ void* Fl_Gl_Window_Driver::GetProcAddress(const char *procName) {
|
||||
#endif // HAVE_DLSYM
|
||||
}
|
||||
|
||||
Fl_Font_Descriptor** Fl_Gl_Window_Driver::fontnum_to_fontdescriptor(int fnum) {
|
||||
extern FL_EXPORT Fl_Fontdesc *fl_fonts;
|
||||
return &(fl_fonts[fnum].first);
|
||||
}
|
||||
|
||||
#ifdef FL_CFG_GFX_QUARTZ
|
||||
#include <FL/platform.H>
|
||||
|
@ -217,8 +217,20 @@ void Fl_Graphics_Driver::draw(Fl_Shared_Image *shared, int X, int Y) {
|
||||
shared->scaled_image_->draw(X, Y, shared->scaled_image_->w(), shared->scaled_image_->h(), 0, 0);
|
||||
}
|
||||
|
||||
unsigned Fl_Graphics_Driver::font_desc_size() {
|
||||
return (unsigned)sizeof(Fl_Fontdesc);
|
||||
}
|
||||
|
||||
#ifndef FL_DOXYGEN
|
||||
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
|
||||
next = 0;
|
||||
# if HAVE_GL
|
||||
listbase = 0;
|
||||
# endif
|
||||
// OpenGL needs those for its font handling
|
||||
size = Size;
|
||||
}
|
||||
|
||||
Fl_Scalable_Graphics_Driver::Fl_Scalable_Graphics_Driver() : Fl_Graphics_Driver() {
|
||||
scale_ = 1;
|
||||
line_width_ = 0;
|
||||
|
@ -3,7 +3,7 @@
|
||||
//
|
||||
// Font definitions for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2011 by Bill Spitzak and others.
|
||||
// Copyright 1998-2018 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@ -26,39 +26,17 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/**
|
||||
This a structure for an actual system font, with junk to
|
||||
help choose it and info on character sizes. Each Fl_Fontdesc has a
|
||||
linked list of these. These are created the first time each system
|
||||
font/size combination is used.
|
||||
*/
|
||||
class Fl_Font_Descriptor {
|
||||
class Fl_GDI_Font_Descriptor : public Fl_Font_Descriptor {
|
||||
public:
|
||||
/** linked list for this Fl_Fontdesc */
|
||||
Fl_Font_Descriptor *next;
|
||||
Fl_Fontsize size; /**< font size */
|
||||
#ifndef FL_DOXYGEN // don't bother with platorm dependant details in the doc.
|
||||
HFONT fid;
|
||||
int *width[64];
|
||||
TEXTMETRIC metr;
|
||||
int angle;
|
||||
FL_EXPORT Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size);
|
||||
FL_EXPORT Fl_GDI_Font_Descriptor(const char* fontname, Fl_Fontsize size);
|
||||
# if HAVE_GL
|
||||
unsigned int listbase;// base of display list, 0 = none
|
||||
char glok[64];
|
||||
# endif // HAVE_GL
|
||||
|
||||
FL_EXPORT ~Fl_Font_Descriptor();
|
||||
|
||||
#endif // FL_DOXYGEN
|
||||
};
|
||||
|
||||
//extern FL_EXPORT Fl_Font_Descriptor *fl_fontsize; // the currently selected one
|
||||
|
||||
struct Fl_Fontdesc {
|
||||
const char *name;
|
||||
char fontname[128]; // "Pretty" font name
|
||||
Fl_Font_Descriptor *first; // linked list of sizes of this style
|
||||
FL_EXPORT ~Fl_GDI_Font_Descriptor();
|
||||
};
|
||||
|
||||
extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table
|
||||
|
@ -4,7 +4,7 @@
|
||||
// Definition of classes Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device
|
||||
// for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2010-2017 by Bill Spitzak and others.
|
||||
// Copyright 2010-2018 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@ -146,7 +146,6 @@ protected:
|
||||
virtual const char* get_font_name(Fl_Font fnum, int* ap);
|
||||
virtual const char *font_name(int num);
|
||||
virtual void font_name(int num, const char *name);
|
||||
virtual unsigned font_desc_size();
|
||||
void global_gc();
|
||||
};
|
||||
|
||||
|
@ -189,10 +189,6 @@ int Fl_GDI_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
|
||||
return nbSize;
|
||||
}
|
||||
|
||||
unsigned Fl_GDI_Graphics_Driver::font_desc_size() {
|
||||
return (unsigned)sizeof(Fl_Fontdesc);
|
||||
}
|
||||
|
||||
const char *Fl_GDI_Graphics_Driver::font_name(int num) {
|
||||
return fl_fonts[num].name;
|
||||
}
|
||||
@ -215,7 +211,7 @@ void Fl_GDI_Graphics_Driver::font_name(int num, const char *name) {
|
||||
static int fl_angle_ = 0;
|
||||
|
||||
#ifndef FL_DOXYGEN
|
||||
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize fsize) {
|
||||
Fl_GDI_Font_Descriptor::Fl_GDI_Font_Descriptor(const char* name, Fl_Fontsize fsize) : Fl_Font_Descriptor(name,fsize) {
|
||||
int weight = FW_NORMAL;
|
||||
int italic = 0;
|
||||
switch (*name++) {
|
||||
@ -252,13 +248,12 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize fsize) {
|
||||
int i;
|
||||
memset(width, 0, 64 * sizeof(int*));
|
||||
#if HAVE_GL
|
||||
listbase = 0;
|
||||
for (i = 0; i < 64; i++) glok[i] = 0;
|
||||
#endif
|
||||
size = fsize;
|
||||
}
|
||||
|
||||
Fl_Font_Descriptor::~Fl_Font_Descriptor() {
|
||||
Fl_GDI_Font_Descriptor::~Fl_GDI_Font_Descriptor() {
|
||||
#if HAVE_GL
|
||||
// Delete list created by gl_draw(). This is not done by this code
|
||||
// as it will link in GL unnecessarily. There should be some kind
|
||||
@ -296,13 +291,13 @@ static Fl_Fontdesc built_in_table[] = {
|
||||
|
||||
Fl_Fontdesc* fl_fonts = built_in_table;
|
||||
|
||||
static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size, int angle) {
|
||||
static Fl_GDI_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size, int angle) {
|
||||
Fl_Fontdesc* s = fl_fonts+fnum;
|
||||
if (!s->name) s = fl_fonts; // use 0 if fnum undefined
|
||||
Fl_Font_Descriptor* f;
|
||||
for (f = s->first; f; f = f->next)
|
||||
Fl_GDI_Font_Descriptor* f;
|
||||
for (f = (Fl_GDI_Font_Descriptor*)s->first; f; f = (Fl_GDI_Font_Descriptor*)f->next)
|
||||
if (f->size == size && f->angle == angle) return f;
|
||||
f = new Fl_Font_Descriptor(s->name, size);
|
||||
f = new Fl_GDI_Font_Descriptor(s->name, size);
|
||||
f->next = s->first;
|
||||
s->first = f;
|
||||
return f;
|
||||
@ -328,13 +323,13 @@ void Fl_GDI_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
|
||||
}
|
||||
|
||||
int Fl_GDI_Graphics_Driver::height_unscaled() {
|
||||
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
|
||||
Fl_GDI_Font_Descriptor *fl_fontsize = (Fl_GDI_Font_Descriptor*)font_descriptor();
|
||||
if (fl_fontsize) return (fl_fontsize->metr.tmAscent + fl_fontsize->metr.tmDescent);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
int Fl_GDI_Graphics_Driver::descent_unscaled() {
|
||||
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
|
||||
Fl_GDI_Font_Descriptor *fl_fontsize = (Fl_GDI_Font_Descriptor*)font_descriptor();
|
||||
if (fl_fontsize) return fl_fontsize->metr.tmDescent;
|
||||
else return -1;
|
||||
}
|
||||
@ -369,7 +364,7 @@ double Fl_GDI_Graphics_Driver::width_unscaled(const char* c, int n) {
|
||||
}
|
||||
|
||||
double Fl_GDI_Graphics_Driver::width_unscaled(unsigned int c) {
|
||||
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
|
||||
Fl_GDI_Font_Descriptor *fl_fontsize = (Fl_GDI_Font_Descriptor*)font_descriptor();
|
||||
unsigned int r;
|
||||
SIZE s;
|
||||
// Special Case Handling of Unicode points over U+FFFF.
|
||||
@ -468,7 +463,7 @@ static void on_printer_extents_update(int &dx, int &dy, int &w, int &h, HDC gc)
|
||||
// Function to determine the extent of the "inked" area of the glyphs in a string
|
||||
void Fl_GDI_Graphics_Driver::text_extents_unscaled(const char *c, int n, int &dx, int &dy, int &w, int &h) {
|
||||
|
||||
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
|
||||
Fl_GDI_Font_Descriptor *fl_fontsize = (Fl_GDI_Font_Descriptor*)font_descriptor();
|
||||
if (!fl_fontsize) { // no valid font, nothing to measure
|
||||
w = 0; h = 0;
|
||||
dx = dy = 0;
|
||||
@ -582,7 +577,7 @@ void Fl_GDI_Graphics_Driver::draw_unscaled(const char* str, int n, int x, int y)
|
||||
COLORREF oldColor = SetTextColor(gc_, fl_RGB());
|
||||
// avoid crash if no font has been set yet
|
||||
if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE);
|
||||
SelectObject(gc_, font_descriptor()->fid);
|
||||
SelectObject(gc_, ((Fl_GDI_Font_Descriptor*)font_descriptor())->fid);
|
||||
int wn = fl_utf8toUtf16(str, n, wstr, wstr_len);
|
||||
if(wn >= wstr_len) {
|
||||
wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1));
|
||||
@ -597,7 +592,7 @@ void Fl_GDI_Graphics_Driver::draw_unscaled(int angle, const char* str, int n, in
|
||||
fl_font(this, Fl_Graphics_Driver::font(), size_unscaled(), angle);
|
||||
int wn = 0; // count of UTF16 cells to render full string
|
||||
COLORREF oldColor = SetTextColor(gc_, fl_RGB());
|
||||
SelectObject(gc_, font_descriptor()->fid);
|
||||
SelectObject(gc_, ((Fl_GDI_Font_Descriptor*)font_descriptor())->fid);
|
||||
wn = fl_utf8toUtf16(str, n, wstr, wstr_len);
|
||||
if(wn >= wstr_len) { // Array too small
|
||||
wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1));
|
||||
@ -619,7 +614,7 @@ void Fl_GDI_Graphics_Driver::rtl_draw_unscaled(const char* c, int n, int x, int
|
||||
}
|
||||
|
||||
COLORREF oldColor = SetTextColor(gc_, fl_RGB());
|
||||
SelectObject(gc_, font_descriptor()->fid);
|
||||
SelectObject(gc_, ((Fl_GDI_Font_Descriptor*)font_descriptor())->fid);
|
||||
#ifdef RTL_CHAR_BY_CHAR
|
||||
int i = 0;
|
||||
int lx = 0;
|
||||
|
@ -3,7 +3,7 @@
|
||||
//
|
||||
// Font definitions for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2011 by Bill Spitzak and others.
|
||||
// Copyright 1998-2018 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@ -28,21 +28,10 @@
|
||||
#include "Fl_Quartz_Graphics_Driver.H"
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
/**
|
||||
This a structure for an actual system font, with junk to
|
||||
help choose it and info on character sizes. Each Fl_Fontdesc has a
|
||||
linked list of these. These are created the first time each system
|
||||
font/size combination is used.
|
||||
*/
|
||||
class Fl_Font_Descriptor {
|
||||
class Fl_Quartz_Font_Descriptor : public Fl_Font_Descriptor {
|
||||
public:
|
||||
/** linked list for this Fl_Fontdesc */
|
||||
Fl_Font_Descriptor *next;
|
||||
Fl_Fontsize size; /**< font size */
|
||||
#ifndef FL_DOXYGEN // don't bother with platorm dependant details in the doc.
|
||||
Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size);
|
||||
FL_EXPORT ~Fl_Font_Descriptor();
|
||||
short ascent, descent, q_width;
|
||||
Fl_Quartz_Font_Descriptor(const char* fontname, Fl_Fontsize size);
|
||||
FL_EXPORT ~Fl_Quartz_Font_Descriptor();
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
CTFontRef fontref;
|
||||
// the unicode span is divided in 512 blocks of 128 characters
|
||||
@ -52,19 +41,6 @@ public:
|
||||
ATSUTextLayout layout;
|
||||
ATSUStyle style;
|
||||
# endif
|
||||
# if HAVE_GL
|
||||
unsigned int listbase;// base of display list, 0 = none
|
||||
# endif // HAVE_GL
|
||||
|
||||
#endif // FL_DOXYGEN
|
||||
};
|
||||
|
||||
//extern FL_EXPORT Fl_Font_Descriptor *fl_fontsize; // the currently selected one
|
||||
|
||||
struct Fl_Fontdesc {
|
||||
const char *name;
|
||||
char fontname[128]; // "Pretty" font name
|
||||
Fl_Font_Descriptor *first; // linked list of sizes of this style
|
||||
};
|
||||
|
||||
extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table
|
||||
|
@ -34,6 +34,7 @@
|
||||
MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
|
||||
|
||||
struct Fl_Fontdesc;
|
||||
class Fl_Quartz_Font_Descriptor;
|
||||
|
||||
/**
|
||||
\brief The Mac OS X-specific graphics class.
|
||||
@ -43,6 +44,7 @@ struct Fl_Fontdesc;
|
||||
class Fl_Quartz_Graphics_Driver : public Fl_Graphics_Driver {
|
||||
friend class Fl_Font_Descriptor;
|
||||
friend class Fl_Cocoa_Printer_Driver;
|
||||
friend class Fl_Quartz_Font_Descriptor;
|
||||
protected:
|
||||
CGContextRef gc_;
|
||||
int p_size;
|
||||
@ -146,10 +148,9 @@ protected:
|
||||
virtual bool high_resolution() { return high_resolution_; }
|
||||
virtual void global_gc();
|
||||
void quartz_restore_line_style();
|
||||
inline Fl_Font_Descriptor *valid_font_descriptor();
|
||||
inline Fl_Quartz_Font_Descriptor *valid_font_descriptor();
|
||||
virtual const char* get_font_name(Fl_Font fnum, int* ap);
|
||||
virtual int get_font_sizes(Fl_Font fnum, int*& sizep);
|
||||
virtual unsigned font_desc_size();
|
||||
virtual const char *font_name(int num);
|
||||
virtual void font_name(int num, const char *name);
|
||||
Fl_Fontdesc* calc_fl_fonts(void);
|
||||
@ -165,13 +166,13 @@ protected:
|
||||
static void init_CoreText_or_ATSU();
|
||||
void draw_CoreText(const char *str, int n, float x, float y);
|
||||
double width_CoreText(const UniChar* txt, int n);
|
||||
void descriptor_init_CoreText(const char* name, Fl_Fontsize Size, Fl_Font_Descriptor *d);
|
||||
void descriptor_init_CoreText(const char* name, Fl_Fontsize Size, Fl_Quartz_Font_Descriptor *d);
|
||||
void text_extents_CoreText(const char*, int n, int& dx, int& dy, int& w, int& h);
|
||||
Fl_Font set_fonts_CoreText(const char* xstarname);
|
||||
|
||||
void draw_ATSU(const char *str, int n, float x, float y);
|
||||
double width_ATSU(const UniChar* txt, int n);
|
||||
void descriptor_init_ATSU(const char* name, Fl_Fontsize Size, Fl_Font_Descriptor *d);
|
||||
void descriptor_init_ATSU(const char* name, Fl_Fontsize Size, Fl_Quartz_Font_Descriptor *d);
|
||||
void text_extents_ATSU(const char*, int n, int& dx, int& dy, int& w, int& h);
|
||||
Fl_Font set_fonts_ATSU(const char* xstarname);
|
||||
|
||||
@ -181,7 +182,7 @@ protected:
|
||||
static pter_to_draw_member CoreText_or_ATSU_draw;
|
||||
static pter_to_width_member CoreText_or_ATSU_width;
|
||||
#else
|
||||
void descriptor_init(const char* name, Fl_Fontsize Size, Fl_Font_Descriptor *d);
|
||||
void descriptor_init(const char* name, Fl_Fontsize Size, Fl_Quartz_Font_Descriptor *d);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -179,13 +179,7 @@ int Fl_Quartz_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
|
||||
return cnt;
|
||||
}
|
||||
|
||||
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
|
||||
next = 0;
|
||||
# if HAVE_GL
|
||||
listbase = 0;
|
||||
# endif
|
||||
// OpenGL needs those for its font handling
|
||||
size = Size;
|
||||
Fl_Quartz_Font_Descriptor::Fl_Quartz_Font_Descriptor(const char* name, Fl_Fontsize Size) : Fl_Font_Descriptor(name, Size) {
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
fontref = NULL;
|
||||
#endif
|
||||
@ -205,7 +199,7 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
|
||||
}
|
||||
|
||||
|
||||
Fl_Font_Descriptor::~Fl_Font_Descriptor() {
|
||||
Fl_Quartz_Font_Descriptor::~Fl_Quartz_Font_Descriptor() {
|
||||
/*
|
||||
#if HAVE_GL
|
||||
// ++ todo: remove OpenGL font allocations
|
||||
@ -257,7 +251,7 @@ static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) {
|
||||
Fl_Font_Descriptor* f;
|
||||
for (f = s->first; f; f = f->next)
|
||||
if (f->size == size) return f;
|
||||
f = new Fl_Font_Descriptor(s->name, size);
|
||||
f = new Fl_Quartz_Font_Descriptor(s->name, size);
|
||||
f->next = s->first;
|
||||
s->first = f;
|
||||
return f;
|
||||
@ -273,19 +267,19 @@ void Fl_Quartz_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
|
||||
font_descriptor( find(fnum, size) );
|
||||
}
|
||||
|
||||
Fl_Font_Descriptor *Fl_Quartz_Graphics_Driver::valid_font_descriptor() {
|
||||
Fl_Quartz_Font_Descriptor *Fl_Quartz_Graphics_Driver::valid_font_descriptor() {
|
||||
// avoid a crash if no font has been selected by user yet
|
||||
if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE);
|
||||
return font_descriptor();
|
||||
return (Fl_Quartz_Font_Descriptor*)font_descriptor();
|
||||
}
|
||||
|
||||
int Fl_Quartz_Graphics_Driver::height() {
|
||||
Fl_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
return fl_fontsize->ascent + fl_fontsize->descent;
|
||||
}
|
||||
|
||||
int Fl_Quartz_Graphics_Driver::descent() {
|
||||
Fl_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
return fl_fontsize->descent + 1;
|
||||
}
|
||||
|
||||
@ -351,11 +345,6 @@ void Fl_Quartz_Graphics_Driver::set_fontname_in_fontdesc(Fl_Fontdesc *f) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
unsigned Fl_Quartz_Graphics_Driver::font_desc_size() {
|
||||
return (unsigned)sizeof(Fl_Fontdesc);
|
||||
}
|
||||
|
||||
const char *Fl_Quartz_Graphics_Driver::font_name(int num) {
|
||||
if (!fl_fonts) fl_fonts = calc_fl_fonts();
|
||||
return fl_fonts[num].name;
|
||||
@ -421,7 +410,7 @@ void Fl_Quartz_Graphics_Driver::text_extents(const char* txt, int n, int& dx, in
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
|
||||
void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(descriptor_init, _CoreText)(const char* name,
|
||||
Fl_Fontsize size, Fl_Font_Descriptor *d)
|
||||
Fl_Fontsize size, Fl_Quartz_Font_Descriptor *d)
|
||||
{
|
||||
CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
|
||||
d->fontref = CTFontCreateWithName(str, size, NULL);
|
||||
@ -470,7 +459,7 @@ void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(descriptor_init, _CoreText)(const cha
|
||||
}
|
||||
|
||||
// returns width of a pair of UniChar's in the surrogate range
|
||||
static CGFloat surrogate_width(const UniChar *txt, Fl_Font_Descriptor *fl_fontsize)
|
||||
static CGFloat surrogate_width(const UniChar *txt, Fl_Quartz_Font_Descriptor *fl_fontsize)
|
||||
{
|
||||
CTFontRef font2 = fl_fontsize->fontref;
|
||||
bool must_release = false;
|
||||
@ -491,7 +480,7 @@ static CGFloat surrogate_width(const UniChar *txt, Fl_Font_Descriptor *fl_fontsi
|
||||
return a.width;
|
||||
}
|
||||
|
||||
static CGFloat variation_selector_width(CFStringRef str16, Fl_Font_Descriptor *fl_fontsize)
|
||||
static CGFloat variation_selector_width(CFStringRef str16, Fl_Quartz_Font_Descriptor *fl_fontsize)
|
||||
{
|
||||
CGFloat retval;
|
||||
CFDictionarySetValue(attributes, kCTFontAttributeName, fl_fontsize->fontref);
|
||||
@ -508,7 +497,7 @@ double Fl_Quartz_Graphics_Driver::ADD_SUFFIX(width, _CoreText)(const UniChar* tx
|
||||
double retval = 0;
|
||||
UniChar uni;
|
||||
int i;
|
||||
Fl_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
for (i = 0; i < n; i++) { // loop over txt
|
||||
uni = txt[i];
|
||||
if (uni >= 0xD800 && uni <= 0xDBFF) { // handles the surrogate range
|
||||
@ -576,7 +565,7 @@ double Fl_Quartz_Graphics_Driver::ADD_SUFFIX(width, _CoreText)(const UniChar* tx
|
||||
// text extent calculation
|
||||
void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(text_extents, _CoreText)(const char *str8, int n,
|
||||
int &dx, int &dy, int &w, int &h) {
|
||||
Fl_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
UniChar *txt = mac_Utf8_to_Utf16(str8, n, &n);
|
||||
CFStringRef str16 = CFStringCreateWithCharactersNoCopy(NULL, txt, n, kCFAllocatorNull);
|
||||
CFDictionarySetValue (attributes, kCTFontAttributeName, fl_fontsize->fontref);
|
||||
@ -610,7 +599,7 @@ static CGColorRef flcolortocgcolor(Fl_Color i)
|
||||
|
||||
void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(draw, _CoreText)(const char *str, int n, float x, float y)
|
||||
{
|
||||
Fl_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
// convert to UTF-16 first
|
||||
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
|
||||
CGContextRef gc = (CGContextRef)this->gc();
|
||||
@ -710,7 +699,7 @@ Fl_Font Fl_Quartz_Graphics_Driver::ADD_SUFFIX(set_fonts, _CoreText)(const char*
|
||||
#if HAS_ATSU
|
||||
|
||||
void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(descriptor_init, _ATSU)(const char* name,
|
||||
Fl_Fontsize size, Fl_Font_Descriptor *d)
|
||||
Fl_Fontsize size, Fl_Quartz_Font_Descriptor *d)
|
||||
{
|
||||
OSStatus err;
|
||||
// fill our structure with a few default values
|
||||
@ -766,7 +755,7 @@ void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(descriptor_init, _ATSU)(const char* n
|
||||
|
||||
void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(draw, _ATSU)(const char *str, int n, float x, float y)
|
||||
{
|
||||
Fl_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
// convert to UTF-16 first
|
||||
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
|
||||
CGContextRef gc = (CGContextRef)this->gc();
|
||||
@ -793,7 +782,7 @@ double Fl_Quartz_Graphics_Driver::ADD_SUFFIX(width, _ATSU)(const UniChar* txt, i
|
||||
ATSUAttributeTag iTag;
|
||||
ATSUAttributeValuePtr iValuePtr;
|
||||
|
||||
Fl_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
// Here's my ATSU text measuring attempt... This seems to do the Right Thing
|
||||
// now collect our ATSU resources and measure our text string
|
||||
layout = fl_fontsize->layout;
|
||||
@ -814,7 +803,7 @@ double Fl_Quartz_Graphics_Driver::ADD_SUFFIX(width, _ATSU)(const UniChar* txt, i
|
||||
void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(text_extents, _ATSU)(const char *str8, int n,
|
||||
int &dx, int &dy, int &w, int &h)
|
||||
{
|
||||
Fl_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
|
||||
UniChar *txt = mac_Utf8_to_Utf16(str8, n, &n);
|
||||
OSStatus err;
|
||||
ATSUTextLayout layout;
|
||||
|
@ -3,7 +3,7 @@
|
||||
//
|
||||
// Font definitions for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2011 by Bill Spitzak and others.
|
||||
// Copyright 1998-2018 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@ -32,18 +32,8 @@ typedef struct _XftFont XftFont;
|
||||
# include "../../Xutf8.h"
|
||||
#endif // USE_XFT
|
||||
|
||||
/**
|
||||
This a structure for an actual system font, with junk to
|
||||
help choose it and info on character sizes. Each Fl_Fontdesc has a
|
||||
linked list of these. These are created the first time each system
|
||||
font/size combination is used.
|
||||
*/
|
||||
class Fl_Font_Descriptor {
|
||||
class Fl_Xlib_Font_Descriptor : public Fl_Font_Descriptor {
|
||||
public:
|
||||
/** linked list for this Fl_Fontdesc */
|
||||
Fl_Font_Descriptor *next;
|
||||
Fl_Fontsize size; /**< font size */
|
||||
#ifndef FL_DOXYGEN // don't bother with platorm dependant details in the doc.
|
||||
# if USE_XFT
|
||||
# if USE_PANGO
|
||||
int descent_;
|
||||
@ -52,30 +42,28 @@ public:
|
||||
XftFont* font;
|
||||
# endif
|
||||
int angle;
|
||||
FL_EXPORT Fl_Font_Descriptor(const char* xfontname, Fl_Fontsize size, int angle);
|
||||
FL_EXPORT Fl_Xlib_Font_Descriptor(const char* xfontname, Fl_Fontsize size, int angle);
|
||||
# else
|
||||
XUtf8FontStruct* font; // X UTF-8 font information
|
||||
FL_EXPORT Fl_Font_Descriptor(const char* xfontname);
|
||||
FL_EXPORT Fl_Xlib_Font_Descriptor(const char* xfontname);
|
||||
# endif
|
||||
# if HAVE_GL
|
||||
unsigned int listbase;// base of display list, 0 = none
|
||||
char glok[64];
|
||||
# endif // HAVE_GL
|
||||
|
||||
FL_EXPORT ~Fl_Font_Descriptor();
|
||||
|
||||
#endif // FL_DOXYGEN
|
||||
FL_EXPORT ~Fl_Xlib_Font_Descriptor();
|
||||
};
|
||||
|
||||
//extern FL_EXPORT Fl_Font_Descriptor *fl_fontsize; // the currently selected one
|
||||
|
||||
struct Fl_Fontdesc {
|
||||
#if !USE_XFT
|
||||
struct Fl_Xlib_Fontdesc { // replaces Fl_Fontdesc
|
||||
const char *name;
|
||||
char fontname[128]; // "Pretty" font name
|
||||
Fl_Font_Descriptor *first; // linked list of sizes of this style
|
||||
char **xlist; // matched X font names
|
||||
int n; // size of xlist, negative = don't free xlist!
|
||||
};
|
||||
#endif
|
||||
|
||||
extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table
|
||||
|
||||
|
@ -180,7 +180,9 @@ protected:
|
||||
virtual void reset_spot();
|
||||
virtual const char* get_font_name(Fl_Font fnum, int* ap);
|
||||
virtual int get_font_sizes(Fl_Font fnum, int*& sizep);
|
||||
#if !USE_XFT
|
||||
virtual unsigned font_desc_size();
|
||||
#endif
|
||||
virtual const char *font_name(int num);
|
||||
virtual void font_name(int num, const char *name);
|
||||
virtual Fl_Font set_fonts(const char* xstarname);
|
||||
|
@ -202,22 +202,34 @@ void Fl_Xlib_Graphics_Driver::set_spot(int font, int size, int X, int Y, int W,
|
||||
XFree(preedit_attr);
|
||||
}
|
||||
|
||||
#if !USE_XFT
|
||||
unsigned Fl_Xlib_Graphics_Driver::font_desc_size() {
|
||||
return (unsigned)sizeof(Fl_Fontdesc);
|
||||
return (unsigned)sizeof(Fl_Xlib_Fontdesc);
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *Fl_Xlib_Graphics_Driver::font_name(int num) {
|
||||
#if USE_XFT
|
||||
return fl_fonts[num].name;
|
||||
#else
|
||||
return ((Fl_Xlib_Fontdesc*)fl_fonts)[num].name;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Fl_Xlib_Graphics_Driver::font_name(int num, const char *name) {
|
||||
#if USE_PANGO
|
||||
#if USE_XFT
|
||||
# if USE_PANGO
|
||||
init_built_in_fonts();
|
||||
#endif
|
||||
# endif
|
||||
Fl_Fontdesc *s = fl_fonts + num;
|
||||
#else
|
||||
Fl_Xlib_Fontdesc *s = ((Fl_Xlib_Fontdesc*)fl_fonts) + num;
|
||||
#endif
|
||||
if (s->name) {
|
||||
if (!strcmp(s->name, name)) {s->name = name; return;}
|
||||
#if !USE_XFT
|
||||
if (s->xlist && s->n >= 0) XFreeFontNames(s->xlist);
|
||||
#endif
|
||||
for (Fl_Font_Descriptor* f = s->first; f;) {
|
||||
Fl_Font_Descriptor* n = f->next; delete f; f = n;
|
||||
}
|
||||
@ -225,7 +237,9 @@ void Fl_Xlib_Graphics_Driver::font_name(int num, const char *name) {
|
||||
}
|
||||
s->name = name;
|
||||
s->fontname[0] = 0;
|
||||
#if !USE_XFT
|
||||
s->xlist = 0;
|
||||
#endif
|
||||
s->first = 0;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ static int use_registry(const char *p) {
|
||||
|
||||
// turn a stored (with *'s) X font name into a pretty name:
|
||||
const char* Fl_Xlib_Graphics_Driver::get_font_name(Fl_Font fnum, int* ap) {
|
||||
Fl_Fontdesc *f = fl_fonts + fnum;
|
||||
Fl_Xlib_Fontdesc *f = ((Fl_Xlib_Fontdesc*)fl_fonts) + fnum;
|
||||
if (!f->fontname[0]) {
|
||||
int type = 0;
|
||||
const char* p = f->name;
|
||||
@ -312,9 +312,10 @@ Fl_Font Fl_Xlib_Graphics_Driver::set_fonts(const char* xstarname) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fl_fonts[j].xlist) {
|
||||
fl_fonts[j].xlist = xlist+first_xlist;
|
||||
fl_fonts[j].n = -(i-first_xlist);
|
||||
Fl_Xlib_Fontdesc *s = ((Fl_Xlib_Fontdesc*)fl_fonts)+j;
|
||||
if (!s->xlist) {
|
||||
s->xlist = xlist+first_xlist;
|
||||
s->n = -(i-first_xlist);
|
||||
used_xlist = 1;
|
||||
}
|
||||
}
|
||||
@ -323,8 +324,8 @@ Fl_Font Fl_Xlib_Graphics_Driver::set_fonts(const char* xstarname) {
|
||||
}
|
||||
|
||||
int Fl_Xlib_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
|
||||
Fl_Fontdesc *s = fl_fonts+fnum;
|
||||
if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
|
||||
Fl_Xlib_Fontdesc *s = ((Fl_Xlib_Fontdesc*)fl_fonts)+fnum;
|
||||
if (!s->name) s = ((Fl_Xlib_Fontdesc*)fl_fonts); // empty slot in table, use entry 0
|
||||
if (!s->xlist) {
|
||||
fl_open_display();
|
||||
s->xlist = XListFonts(fl_display, s->name, 100, &(s->n));
|
||||
@ -358,7 +359,7 @@ int Fl_Xlib_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
|
||||
|
||||
#ifndef FL_DOXYGEN
|
||||
|
||||
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name) {
|
||||
Fl_Xlib_Font_Descriptor::Fl_Xlib_Font_Descriptor(const char* name) : Fl_Font_Descriptor(name, 0) {
|
||||
font = XCreateUtf8FontStruct(fl_display, name);
|
||||
if (!font) {
|
||||
Fl::warning("bad font: %s", name);
|
||||
@ -372,7 +373,7 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name) {
|
||||
|
||||
Fl_XFont_On_Demand fl_xfont;
|
||||
|
||||
Fl_Font_Descriptor::~Fl_Font_Descriptor() {
|
||||
Fl_Xlib_Font_Descriptor::~Fl_Xlib_Font_Descriptor() {
|
||||
# if HAVE_GL
|
||||
// Delete list created by gl_draw(). This is not done by this code
|
||||
// as it will link in GL unnecessarily. There should be some kind
|
||||
@ -389,7 +390,7 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() {
|
||||
|
||||
// WARNING: if you add to this table, you must redefine FL_FREE_FONT
|
||||
// in Enumerations.H & recompile!!
|
||||
static Fl_Fontdesc built_in_table[] = {
|
||||
static Fl_Xlib_Fontdesc built_in_table[] = {
|
||||
{"-*-helvetica-medium-r-normal--*"},
|
||||
{"-*-helvetica-bold-r-normal--*"},
|
||||
{"-*-helvetica-medium-o-normal--*"},
|
||||
@ -408,7 +409,7 @@ static Fl_Fontdesc built_in_table[] = {
|
||||
{"-*-*zapf dingbats-*"}
|
||||
};
|
||||
|
||||
Fl_Fontdesc* fl_fonts = built_in_table;
|
||||
Fl_Fontdesc* fl_fonts = (Fl_Fontdesc*)built_in_table;
|
||||
|
||||
#define MAXSIZE 32767
|
||||
|
||||
@ -554,8 +555,8 @@ static char *put_font_size(const char *n, int size)
|
||||
|
||||
|
||||
char *fl_get_font_xfld(int fnum, int size) {
|
||||
Fl_Fontdesc* s = fl_fonts+fnum;
|
||||
if (!s->name) s = fl_fonts; // use font 0 if still undefined
|
||||
Fl_Xlib_Fontdesc* s = ((Fl_Xlib_Fontdesc*)fl_fonts)+fnum;
|
||||
if (!s->name) s = (Fl_Xlib_Fontdesc*)fl_fonts; // use font 0 if still undefined
|
||||
fl_open_display();
|
||||
return put_font_size(s->name, size);
|
||||
}
|
||||
@ -563,15 +564,15 @@ char *fl_get_font_xfld(int fnum, int size) {
|
||||
// locate or create an Fl_Font_Descriptor for a given Fl_Fontdesc and size:
|
||||
static Fl_Font_Descriptor* find(int fnum, int size) {
|
||||
char *name;
|
||||
Fl_Fontdesc* s = fl_fonts+fnum;
|
||||
if (!s->name) s = fl_fonts; // use font 0 if still undefined
|
||||
Fl_Xlib_Fontdesc* s = ((Fl_Xlib_Fontdesc*)fl_fonts)+fnum;
|
||||
if (!s->name) s = (Fl_Xlib_Fontdesc*)fl_fonts; // use font 0 if still undefined
|
||||
Fl_Font_Descriptor* f;
|
||||
for (f = s->first; f; f = f->next)
|
||||
if (f->size == size) return f;
|
||||
fl_open_display();
|
||||
|
||||
name = put_font_size(s->name, size);
|
||||
f = new Fl_Font_Descriptor(name);
|
||||
f = new Fl_Xlib_Font_Descriptor(name);
|
||||
f->size = size;
|
||||
f->next = s->first;
|
||||
s->first = f;
|
||||
@ -597,7 +598,7 @@ void Fl_Xlib_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
|
||||
}
|
||||
if (fnum == Fl_Graphics_Driver::font() && size == Fl_Graphics_Driver::size()) return;
|
||||
Fl_Graphics_Driver::font(fnum, size);
|
||||
Fl_Font_Descriptor* f = find(fnum, size);
|
||||
Fl_Xlib_Font_Descriptor* f = (Fl_Xlib_Font_Descriptor*)find(fnum, size);
|
||||
if (f != this->font_descriptor()) {
|
||||
this->font_descriptor(f);
|
||||
fl_xfont = f->font->fonts[0];
|
||||
@ -606,12 +607,12 @@ void Fl_Xlib_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
|
||||
}
|
||||
|
||||
int Fl_Xlib_Graphics_Driver::height_unscaled() {
|
||||
if (font_descriptor()) return font_descriptor()->font->ascent + font_descriptor()->font->descent;
|
||||
if (font_descriptor()) return ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font->ascent + ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font->descent;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
int Fl_Xlib_Graphics_Driver::descent_unscaled() {
|
||||
if (font_descriptor()) return font_descriptor()->font->descent;
|
||||
if (font_descriptor()) return ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font->descent;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
@ -621,12 +622,12 @@ Fl_Fontsize Fl_Xlib_Graphics_Driver::size_unscaled() {
|
||||
}
|
||||
|
||||
double Fl_Xlib_Graphics_Driver::width_unscaled(const char* c, int n) {
|
||||
if (font_descriptor()) return (double) XUtf8TextWidth(font_descriptor()->font, c, n);
|
||||
if (font_descriptor()) return (double) XUtf8TextWidth(((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, c, n);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
double Fl_Xlib_Graphics_Driver::width_unscaled(unsigned int c) {
|
||||
if (font_descriptor()) return (double) XUtf8UcsWidth(font_descriptor()->font, c);
|
||||
if (font_descriptor()) return (double) XUtf8UcsWidth(((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, c);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
@ -634,11 +635,11 @@ void Fl_Xlib_Graphics_Driver::text_extents_unscaled(const char *c, int n, int &d
|
||||
if (font_gc != gc_) {
|
||||
if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE);
|
||||
font_gc = gc_;
|
||||
XSetFont(fl_display, gc_, font_descriptor()->font->fid);
|
||||
XSetFont(fl_display, gc_, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font->fid);
|
||||
}
|
||||
int xx, yy, ww, hh;
|
||||
xx = yy = ww = hh = 0;
|
||||
if (gc_) XUtf8_measure_extents(fl_display, fl_window, font_descriptor()->font, gc_, &xx, &yy, &ww, &hh, c, n);
|
||||
if (gc_) XUtf8_measure_extents(fl_display, fl_window, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, gc_, &xx, &yy, &ww, &hh, c, n);
|
||||
|
||||
W = ww; H = hh; dx = xx; dy = yy;
|
||||
// This is the safe but mostly wrong thing we used to do...
|
||||
@ -652,9 +653,9 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(const char* c, int n, int x, int y)
|
||||
if (font_gc != gc_) {
|
||||
if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE);
|
||||
font_gc = gc_;
|
||||
XSetFont(fl_display, gc_, font_descriptor()->font->fid);
|
||||
XSetFont(fl_display, gc_, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font->fid);
|
||||
}
|
||||
if (gc_) XUtf8DrawString(fl_display, fl_window, font_descriptor()->font, gc_, x+offset_x_, y+offset_y_, c, n);
|
||||
if (gc_) XUtf8DrawString(fl_display, fl_window, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, gc_, x+offset_x_, y+offset_y_, c, n);
|
||||
}
|
||||
|
||||
void Fl_Xlib_Graphics_Driver::draw_unscaled(int angle, const char *str, int n, int x, int y) {
|
||||
@ -673,14 +674,14 @@ void Fl_Xlib_Graphics_Driver::rtl_draw_unscaled(const char* c, int n, int x, int
|
||||
if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE);
|
||||
font_gc = gc_;
|
||||
}
|
||||
if (gc_) XUtf8DrawRtlString(fl_display, fl_window, font_descriptor()->font, gc_, x+offset_x_, y+offset_y_, c, n);
|
||||
if (gc_) XUtf8DrawRtlString(fl_display, fl_window, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, gc_, x+offset_x_, y+offset_y_, c, n);
|
||||
}
|
||||
|
||||
float Fl_Xlib_Graphics_Driver::scale_font_for_PostScript(Fl_Font_Descriptor *desc, int s) {
|
||||
float ps_size = (float) s;
|
||||
// Non-Xft fonts can be smaller than required.
|
||||
// Set the PostScript font size to the display font height
|
||||
char *name = desc->font->font_name_list[0];
|
||||
char *name = ((Fl_Xlib_Font_Descriptor*)desc)->font->font_name_list[0];
|
||||
char *p = strstr(name, "--");
|
||||
if (p) {
|
||||
sscanf(p + 2, "%f", &ps_size);
|
||||
|
@ -695,13 +695,9 @@ puts("Font Opened"); fflush(stdout);
|
||||
}
|
||||
} // end of fontopen
|
||||
|
||||
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize fsize, int fangle) {
|
||||
Fl_Xlib_Font_Descriptor::Fl_Xlib_Font_Descriptor(const char* name, Fl_Fontsize fsize, int fangle) : Fl_Font_Descriptor(name, fsize) {
|
||||
// encoding = fl_encoding_;
|
||||
size = fsize;
|
||||
angle = fangle;
|
||||
#if HAVE_GL
|
||||
listbase = 0;
|
||||
#endif // HAVE_GL
|
||||
font = fontopen(name, fsize, false, angle);
|
||||
}
|
||||
|
||||
@ -729,7 +725,7 @@ static const wchar_t *utf8reformat(const char *str, int& n)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void utf8extents(Fl_Font_Descriptor *desc, const char *str, int n, XGlyphInfo *extents)
|
||||
static void utf8extents(Fl_Xlib_Font_Descriptor *desc, const char *str, int n, XGlyphInfo *extents)
|
||||
{
|
||||
memset(extents, 0, sizeof(XGlyphInfo));
|
||||
const wchar_t *buffer = utf8reformat(str, n);
|
||||
@ -741,26 +737,26 @@ static void utf8extents(Fl_Font_Descriptor *desc, const char *str, int n, XGlyph
|
||||
}
|
||||
|
||||
int Fl_Xlib_Graphics_Driver::height_unscaled() {
|
||||
if (font_descriptor()) return font_descriptor()->font->ascent + font_descriptor()->font->descent;
|
||||
if (font_descriptor()) return ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font->ascent + ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font->descent;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
int Fl_Xlib_Graphics_Driver::descent_unscaled() {
|
||||
if (font_descriptor()) return font_descriptor()->font->descent;
|
||||
if (font_descriptor()) return ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font->descent;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
double Fl_Xlib_Graphics_Driver::width_unscaled(const char* str, int n) {
|
||||
if (!font_descriptor()) return -1.0;
|
||||
XGlyphInfo i;
|
||||
utf8extents(font_descriptor(), str, n, &i);
|
||||
utf8extents((Fl_Xlib_Font_Descriptor*)font_descriptor(), str, n, &i);
|
||||
return i.xOff;
|
||||
}
|
||||
|
||||
static double fl_xft_width(Fl_Font_Descriptor *desc, FcChar32 *str, int n) {
|
||||
if (!desc) return -1.0;
|
||||
XGlyphInfo i;
|
||||
XftTextExtents32(fl_display, desc->font, str, n, &i);
|
||||
XftTextExtents32(fl_display, ((Fl_Xlib_Font_Descriptor*)desc)->font, str, n, &i);
|
||||
return i.xOff;
|
||||
}
|
||||
|
||||
@ -776,7 +772,7 @@ void Fl_Xlib_Graphics_Driver::text_extents_unscaled(const char *c, int n, int &d
|
||||
return;
|
||||
}
|
||||
XGlyphInfo gi;
|
||||
utf8extents(font_descriptor(), c, n, &gi);
|
||||
utf8extents((Fl_Xlib_Font_Descriptor*)font_descriptor(), c, n, &gi);
|
||||
|
||||
w = gi.width;
|
||||
h = gi.height;
|
||||
@ -818,9 +814,9 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(const char *str, int n, int x, int y
|
||||
|
||||
const wchar_t *buffer = utf8reformat(str, n);
|
||||
#ifdef __CYGWIN__
|
||||
XftDrawString16(draw_, &color, font_descriptor()->font, x+offset_x_*scale_+line_delta_, y+offset_y_*scale_+line_delta_, (XftChar16 *)buffer, n);
|
||||
XftDrawString16(draw_, &color, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, x+offset_x_*scale_+line_delta_, y+offset_y_*scale_+line_delta_, (XftChar16 *)buffer, n);
|
||||
#else
|
||||
XftDrawString32(draw_, &color, font_descriptor()->font, x+offset_x_*scale_+line_delta_, y+offset_y_*scale_+line_delta_, (XftChar32 *)buffer, n);
|
||||
XftDrawString32(draw_, &color, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, x+offset_x_*scale_+line_delta_, y+offset_y_*scale_+line_delta_, (XftChar32 *)buffer, n);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -862,7 +858,7 @@ void Fl_Xlib_Graphics_Driver::drawUCS4(const void *str, int n, int x, int y) {
|
||||
color.color.blue = ((int)b)*0x101;
|
||||
color.color.alpha = 0xffff;
|
||||
|
||||
XftDrawString32(draw_, &color, font_descriptor()->font, x+offset_x_*scale_+line_delta_, y+offset_y_*scale_+line_delta_, (FcChar32 *)str, n);
|
||||
XftDrawString32(draw_, &color, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, x+offset_x_*scale_+line_delta_, y+offset_y_*scale_+line_delta_, (FcChar32 *)str, n);
|
||||
}
|
||||
|
||||
|
||||
@ -998,7 +994,7 @@ float Fl_Xlib_Graphics_Driver::scale_bitmap_for_PostScript() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
Fl_Font_Descriptor::~Fl_Font_Descriptor() {
|
||||
Fl_Xlib_Font_Descriptor::~Fl_Xlib_Font_Descriptor() {
|
||||
if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL);
|
||||
// XftFontClose(fl_display, font);
|
||||
}
|
||||
@ -1019,18 +1015,18 @@ static void fl_xft_font(Fl_Xlib_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsi
|
||||
driver->Fl_Graphics_Driver::font(0, 0);
|
||||
return;
|
||||
}
|
||||
Fl_Font_Descriptor* f = driver->font_descriptor();
|
||||
Fl_Xlib_Font_Descriptor* f = (Fl_Xlib_Font_Descriptor*)driver->font_descriptor();
|
||||
if (fnum == driver->Fl_Graphics_Driver::font() && size == driver->size_unscaled() && f && f->angle == angle)
|
||||
return;
|
||||
driver->Fl_Graphics_Driver::font(fnum, size);
|
||||
Fl_Fontdesc *font = fl_fonts + fnum;
|
||||
// search the fontsizes we have generated already
|
||||
for (f = font->first; f; f = f->next) {
|
||||
for (f = (Fl_Xlib_Font_Descriptor*)font->first; f; f = (Fl_Xlib_Font_Descriptor*)f->next) {
|
||||
if (f->size == size && f->angle == angle)// && !strcasecmp(f->encoding, fl_encoding_))
|
||||
break;
|
||||
}
|
||||
if (!f) {
|
||||
f = new Fl_Font_Descriptor(font->name, size, angle);
|
||||
f = new Fl_Xlib_Font_Descriptor(font->name, size, angle);
|
||||
f->next = font->first;
|
||||
font->first = f;
|
||||
}
|
||||
@ -1202,6 +1198,7 @@ PangoContext *Fl_Xlib_Graphics_Driver::context() {
|
||||
return pctxt_;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Xlib_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
|
||||
if (!size) return;
|
||||
if (size < 0) {
|
||||
@ -1215,7 +1212,7 @@ void Fl_Xlib_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
|
||||
pfd_ = pango_font_description_from_string(Fl::get_font_name(fnum));
|
||||
pango_font_description_set_absolute_size(pfd_, size*PANGO_SCALE); // 1.8
|
||||
if (!pctxt_) context();
|
||||
Fl_Font_Descriptor *fd = font_descriptor();
|
||||
Fl_Xlib_Font_Descriptor *fd = (Fl_Xlib_Font_Descriptor*)font_descriptor();
|
||||
if (!fd->height_) {
|
||||
PangoFont *pfont = pango_font_map_load_font(pfmap_, pctxt_, pfd_);
|
||||
PangoRectangle logical_rect;
|
||||
@ -1339,7 +1336,7 @@ void Fl_Xlib_Graphics_Driver::text_extents_unscaled(const char *str, int n, int
|
||||
}
|
||||
|
||||
int Fl_Xlib_Graphics_Driver::height_unscaled() {
|
||||
if (font_descriptor()) return font_descriptor()->height_;
|
||||
if (font_descriptor()) return ((Fl_Xlib_Font_Descriptor*)font_descriptor())->height_;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
@ -1350,7 +1347,7 @@ double Fl_Xlib_Graphics_Driver::width_unscaled(unsigned int c) {
|
||||
}
|
||||
|
||||
int Fl_Xlib_Graphics_Driver::descent_unscaled() {
|
||||
if (font_descriptor()) return font_descriptor()->descent_;
|
||||
if (font_descriptor()) return ((Fl_Xlib_Font_Descriptor*)font_descriptor())->descent_;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
@ -1433,13 +1430,9 @@ int Fl_Xlib_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize fsize, int fangle) {
|
||||
Fl_Xlib_Font_Descriptor::Fl_Xlib_Font_Descriptor(const char* name, Fl_Fontsize fsize, int fangle) : Fl_Font_Descriptor(name, fsize) {
|
||||
fl_open_display();
|
||||
size = fsize;
|
||||
angle = fangle;
|
||||
#if HAVE_GL
|
||||
listbase = 0;
|
||||
#endif // HAVE_GL
|
||||
height_ = 0;
|
||||
descent_ = 0;
|
||||
}
|
||||
|
811
src/gl_draw.cxx
811
src/gl_draw.cxx
@ -1,7 +1,7 @@
|
||||
//
|
||||
// "$Id$"
|
||||
//
|
||||
// OpenGL drawing support routines for the Fast Light Tool Kit (FLTK).
|
||||
// OpenGL text drawing support routines for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2018 by Bill Spitzak and others.
|
||||
//
|
||||
@ -19,12 +19,23 @@
|
||||
// Functions from <FL/gl.h>
|
||||
// See also Fl_Gl_Window and gl_start.cxx
|
||||
|
||||
/* Note about implementing GL text support for a new platform
|
||||
|
||||
1) if the GL_EXT_texture_rectangle (a.k.a. GL_ARB_texture_rectangle) GL extension
|
||||
is available, no platform-specific code is needed, besides support for fl_draw() and Fl_Image_Surface for the platform.
|
||||
|
||||
2) if the GL_EXT_texture_rectangle GL extension is not available,
|
||||
a rudimentary support through GLUT is obtained without any platform-specific code.
|
||||
|
||||
3) A more elaborate support can be obtained implementing
|
||||
get_list(), gl_bitmap_font() and draw_string_legacy() for the platform's Fl_XXX_Gl_Window_Driver.
|
||||
*/
|
||||
|
||||
#include "config_lib.h"
|
||||
#if defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: implement OpenGL text rendering here"
|
||||
#endif
|
||||
#endif // defined(FL_PORTING)
|
||||
|
||||
#include "flstring.h"
|
||||
#if HAVE_GL || defined(FL_DOXYGEN)
|
||||
|
||||
#include <FL/Fl.H>
|
||||
@ -32,25 +43,13 @@
|
||||
#include <FL/gl_draw.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/Fl_Gl_Window_Driver.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include <FL/glu.h> // for gluUnProject()
|
||||
#include <FL/glut.H> // for glutStrokeString() and glutStrokeLength()
|
||||
|
||||
#if defined(FL_CFG_GFX_QUARTZ)
|
||||
#include "drivers/Quartz/Fl_Font.H"
|
||||
# define GENLISTSIZE 0
|
||||
|
||||
#elif defined(FL_CFG_GFX_GDI)
|
||||
#include "drivers/GDI/Fl_Font.H"
|
||||
#define GENLISTSIZE 0x10000
|
||||
|
||||
#elif defined(FL_CFG_GFX_XLIB)
|
||||
#include "drivers/Xlib/Fl_Font.H"
|
||||
#if USE_XFT
|
||||
# define GENLISTSIZE 256
|
||||
#else
|
||||
# define GENLISTSIZE 0x10000
|
||||
#endif // USE_XFT
|
||||
|
||||
#ifndef GL_TEXTURE_RECTANGLE_ARB
|
||||
# define GL_TEXTURE_RECTANGLE_ARB 0x84F5
|
||||
#endif
|
||||
#include <FL/fl_utf8.h>
|
||||
|
||||
|
||||
/** Returns the current font's height */
|
||||
@ -65,43 +64,55 @@ double gl_width(const char* s, int n) {return fl_width(s,n);}
|
||||
double gl_width(uchar c) {return fl_width(c);}
|
||||
|
||||
static Fl_Font_Descriptor *gl_fontsize;
|
||||
static int has_texture_rectangle = 0; // true means GL_EXT_texture_rectangle is available
|
||||
|
||||
extern float gl_start_scale; // in gl_start.cxx
|
||||
|
||||
/**
|
||||
Sets the current OpenGL font to the same font as calling fl_font()
|
||||
Sets the current OpenGL font to the same font as calling fl_font().
|
||||
\see Fl::draw_GL_text_with_textures(int val)
|
||||
*/
|
||||
void gl_font(int fontid, int size) {
|
||||
static bool once = true;
|
||||
if (once) {
|
||||
once = false;
|
||||
if (Fl::draw_GL_text_with_textures()) {
|
||||
// For the font texture pile to work, we need a texture rectangle extension, so check for
|
||||
// one here. First we check for GL_EXT_texture_rectangle and if that fails we try
|
||||
// for GL_ARB_texture_rectangle instead. If that also fails, we fall back to the
|
||||
// legacy methods used by fltk-1.3 and earlier.
|
||||
has_texture_rectangle = (strstr((const char*)glGetString(GL_EXTENSIONS), "GL_EXT_texture_rectangle") != NULL);
|
||||
if (!has_texture_rectangle) has_texture_rectangle =
|
||||
(strstr((const char*)glGetString(GL_EXTENSIONS), "GL_ARB_texture_rectangle") != NULL);
|
||||
Fl::draw_GL_text_with_textures(has_texture_rectangle);
|
||||
}
|
||||
}
|
||||
fl_font(fontid, size);
|
||||
Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor();
|
||||
Fl_Gl_Window_Driver::global()->gl_bitmap_font(fl_fontsize);
|
||||
if (!has_texture_rectangle) Fl_Gl_Window_Driver::global()->gl_bitmap_font(fl_fontsize);
|
||||
gl_fontsize = fl_fontsize;
|
||||
}
|
||||
|
||||
#if defined(FL_CFG_GFX_QUARTZ) || defined(FL_CFG_GFX_GDI) || defined(FL_CFG_GFX_XLIB)
|
||||
|
||||
void gl_remove_displaylist_fonts()
|
||||
{
|
||||
# if HAVE_GL
|
||||
// clear variables used mostly in fl_font
|
||||
fl_graphics_driver->font(0, 0);
|
||||
|
||||
for (int j = 0 ; j < FL_FREE_FONT ; ++j)
|
||||
{
|
||||
Fl_Font_Descriptor* past = 0;
|
||||
Fl_Fontdesc* s = fl_fonts + j ;
|
||||
Fl_Font_Descriptor* f = s->first;
|
||||
Fl_Font_Descriptor** s_first = Fl_Gl_Window_Driver::global()->fontnum_to_fontdescriptor(j);
|
||||
Fl_Font_Descriptor* f = *s_first;
|
||||
while (f != 0) {
|
||||
if(f->listbase) {
|
||||
if(f == s->first) {
|
||||
s->first = f->next;
|
||||
if(f == *s_first) {
|
||||
*s_first = f->next;
|
||||
}
|
||||
else {
|
||||
past->next = f->next;
|
||||
}
|
||||
|
||||
// It would be nice if this next line was in a destructor somewhere
|
||||
glDeleteLists(f->listbase, GENLISTSIZE);
|
||||
|
||||
glDeleteLists(f->listbase, Fl_Gl_Window_Driver::global()->genlistsize());
|
||||
Fl_Font_Descriptor* tmp = f;
|
||||
f = f->next;
|
||||
delete tmp;
|
||||
@ -112,44 +123,22 @@ void gl_remove_displaylist_fonts()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // HAVE_GL
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
Draws an array of n characters of the string in the current font
|
||||
at the current position.
|
||||
\see On the Mac OS X platform, see gl_texture_pile_height(int)
|
||||
Draws an array of n characters of the string in the current font at the current position.
|
||||
\see gl_texture_pile_height(int)
|
||||
*/
|
||||
void gl_draw(const char* str, int n) {
|
||||
Fl_Gl_Window_Driver::global()->draw_string(str, n);
|
||||
if (has_texture_rectangle) Fl_Gl_Window_Driver::draw_string_with_texture(str, n);
|
||||
else Fl_Gl_Window_Driver::global()->draw_string_legacy(str, n);
|
||||
}
|
||||
|
||||
void Fl_Gl_Window_Driver::draw_string(const char* str, int n) {
|
||||
static unsigned short *buf = NULL;
|
||||
static int l = 0;
|
||||
int wn = fl_utf8toUtf16(str, n, (unsigned short*)buf, l);
|
||||
if(wn >= l) {
|
||||
buf = (unsigned short*) realloc(buf, sizeof(unsigned short) * (wn + 1));
|
||||
l = wn + 1;
|
||||
wn = fl_utf8toUtf16(str, n, (unsigned short*)buf, l);
|
||||
}
|
||||
n = wn;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
unsigned int r;
|
||||
r = (str[i] & 0xFC00) >> 10;
|
||||
//if (!gl_fontsize->glok[r]) get_list(r);
|
||||
this->get_list(gl_fontsize, r);
|
||||
}
|
||||
glCallLists(n, GL_UNSIGNED_SHORT, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
Draws n characters of the string in the current font at the given position
|
||||
\see On the Mac OS X platform, see gl_texture_pile_height(int)
|
||||
Draws n characters of the string in the current font at the given position
|
||||
\see gl_texture_pile_height(int)
|
||||
*/
|
||||
void gl_draw(const char* str, int n, int x, int y) {
|
||||
glRasterPos2i(x, y);
|
||||
@ -157,8 +146,8 @@ void gl_draw(const char* str, int n, int x, int y) {
|
||||
}
|
||||
|
||||
/**
|
||||
Draws n characters of the string in the current font at the given position
|
||||
\see On the Mac OS X platform, see gl_texture_pile_height(int)
|
||||
Draws n characters of the string in the current font at the given position
|
||||
\see gl_texture_pile_height(int)
|
||||
*/
|
||||
void gl_draw(const char* str, int n, float x, float y) {
|
||||
glRasterPos2f(x, y);
|
||||
@ -167,23 +156,23 @@ void gl_draw(const char* str, int n, float x, float y) {
|
||||
|
||||
/**
|
||||
Draws a nul-terminated string in the current font at the current position
|
||||
\see On the Mac OS X platform, see gl_texture_pile_height(int)
|
||||
\see gl_texture_pile_height(int)
|
||||
*/
|
||||
void gl_draw(const char* str) {
|
||||
gl_draw(str, strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
Draws a nul-terminated string in the current font at the given position
|
||||
\see On the Mac OS X platform, see gl_texture_pile_height(int)
|
||||
Draws a nul-terminated string in the current font at the given position
|
||||
\see gl_texture_pile_height(int)
|
||||
*/
|
||||
void gl_draw(const char* str, int x, int y) {
|
||||
gl_draw(str, strlen(str), x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
Draws a nul-terminated string in the current font at the given position
|
||||
\see On the Mac OS X platform, see gl_texture_pile_height(int)
|
||||
Draws a nul-terminated string in the current font at the given position
|
||||
\see gl_texture_pile_height(int)
|
||||
*/
|
||||
void gl_draw(const char* str, float x, float y) {
|
||||
gl_draw(str, strlen(str), x, y);
|
||||
@ -229,6 +218,13 @@ void gl_rect(int x, int y, int w, int h) {
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) {
|
||||
if (!ld) ld = w*d;
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, ld/d);
|
||||
glRasterPos2i(x,y);
|
||||
glDrawPixels(w,h,d<4?GL_RGB:GL_RGBA,GL_UNSIGNED_BYTE,(const ulong*)b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Sets the curent OpenGL color to an FLTK color.
|
||||
@ -244,155 +240,29 @@ void gl_color(Fl_Color i) {
|
||||
}
|
||||
|
||||
|
||||
#if defined(FL_CFG_GFX_XLIB)
|
||||
#include <FL/platform.H>
|
||||
#include <GL/glx.h>
|
||||
#if ! defined(FL_DOXYGEN) // do not want too much of the gl_texture_fifo internals in the documentation
|
||||
|
||||
/* Implement the gl_texture_fifo mechanism:
|
||||
Strings to be drawn are memorized in a fifo pile (which max size can
|
||||
be increased calling gl_texture_pile_height(int)).
|
||||
Each pile element contains the string, the font, the GUI scale, and
|
||||
an image of the string in the form of a GL texture.
|
||||
Strings are drawn in 2 steps:
|
||||
1) compute the texture for that string if it was not computed before;
|
||||
2) draw the texture using the current GL color.
|
||||
*/
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) {
|
||||
if (!fl_fontsize->listbase) {
|
||||
#if !USE_XFT
|
||||
fl_fontsize->listbase = glGenLists(GENLISTSIZE);
|
||||
#else // Fltk-1.1.8 style GL font selection
|
||||
// FIXME: warning Ideally, for XFT, we really need a glXUseXftFont implementation here...
|
||||
// FIXME: warning GL font selection is basically wrong here
|
||||
/* OksiD had a fairly sophisticated scheme for storing multiple X fonts in a XUtf8FontStruct,
|
||||
* then sorting through them at draw time (for normal X rendering) to find which one can
|
||||
* render the current glyph... But for now, just use the first font in the list for GL...
|
||||
*/
|
||||
XFontStruct *font = fl_xfont.value();
|
||||
int base = font->min_char_or_byte2;
|
||||
int count = font->max_char_or_byte2-base+1;
|
||||
fl_fontsize->listbase = glGenLists(GENLISTSIZE);
|
||||
glXUseXFont(font->fid, base, count, fl_fontsize->listbase+base);
|
||||
#endif // !USE_XFT
|
||||
}
|
||||
glListBase(fl_fontsize->listbase);
|
||||
}
|
||||
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::get_list(Fl_Font_Descriptor *gl_fd, int r) {
|
||||
if (gl_fd->glok[r]) return;
|
||||
gl_fd->glok[r] = 1;
|
||||
# if USE_XFT
|
||||
// FIXME
|
||||
# else
|
||||
unsigned int ii = r * 0x400;
|
||||
for (int i = 0; i < 0x400; i++) {
|
||||
XFontStruct *font = NULL;
|
||||
unsigned short id;
|
||||
fl_XGetUtf8FontAndGlyph(gl_fd->font, ii, &font, &id);
|
||||
if (font) glXUseXFont(font->fid, id, 1, gl_fd->listbase+ii);
|
||||
ii++;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
#if HAVE_GL_OVERLAY
|
||||
extern uchar fl_overlay;
|
||||
int Fl_X11_Gl_Window_Driver::overlay_color(Fl_Color i) {
|
||||
if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return 1;}
|
||||
return 0;
|
||||
}
|
||||
#endif // HAVE_GL_OVERLAY
|
||||
#endif // FL_CFG_GFX_XLIB
|
||||
|
||||
|
||||
#if defined(FL_CFG_GFX_GDI)
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) {
|
||||
if (!fl_fontsize->listbase) {
|
||||
fl_fontsize->listbase = glGenLists(GENLISTSIZE);
|
||||
/* old, unused WIN32 code
|
||||
int base = fl_fontsize->metr.tmFirstChar;
|
||||
int count = fl_fontsize->metr.tmLastChar-base+1;
|
||||
HFONT oldFid = (HFONT)SelectObject((HDC)fl_graphics_driver->gc(), fl_fontsize->fid);
|
||||
fl_fontsize->listbase = glGenLists(256);
|
||||
wglUseFontBitmaps((HDC)fl_graphics_driver->gc(), base, count, fl_fontsize->listbase+base);
|
||||
SelectObject((HDC)fl_graphics_driver->gc(), oldFid);
|
||||
*/
|
||||
}
|
||||
glListBase(fl_fontsize->listbase);
|
||||
}
|
||||
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::get_list(Fl_Font_Descriptor *gl_fd, int r) {
|
||||
if (gl_fd->glok[r]) return;
|
||||
gl_fd->glok[r] = 1;
|
||||
unsigned int ii = r * 0x400;
|
||||
HFONT oldFid = (HFONT)SelectObject((HDC)fl_graphics_driver->gc(), gl_fd->fid);
|
||||
wglUseFontBitmapsW((HDC)fl_graphics_driver->gc(), ii, ii + 0x03ff, gl_fd->listbase+ii);
|
||||
SelectObject((HDC)fl_graphics_driver->gc(), oldFid);
|
||||
}
|
||||
|
||||
#if HAVE_GL_OVERLAY
|
||||
extern uchar fl_overlay;
|
||||
extern int fl_overlay_depth;
|
||||
int Fl_WinAPI_Gl_Window_Driver::overlay_color(Fl_Color i) {
|
||||
if (fl_overlay && fl_overlay_depth) {
|
||||
if (fl_overlay_depth < 8) {
|
||||
// only black & white produce the expected colors. This could
|
||||
// be improved by fixing the colormap set in Fl_Gl_Overlay.cxx
|
||||
int size = 1<<fl_overlay_depth;
|
||||
if (!i) glIndexi(size-2);
|
||||
else if (i >= size-2) glIndexi(size-1);
|
||||
else glIndexi(i);
|
||||
} else {
|
||||
glIndexi(i ? i : FL_GRAY_RAMP);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // HAVE_GL_OVERLAY
|
||||
#endif // FL_CFG_GFX_GDI
|
||||
|
||||
|
||||
void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) {
|
||||
if (!ld) ld = w*d;
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, ld/d);
|
||||
glRasterPos2i(x,y);
|
||||
glDrawPixels(w,h,d<4?GL_RGB:GL_RGBA,GL_UNSIGNED_BYTE,(const ulong*)b);
|
||||
}
|
||||
|
||||
|
||||
#if defined(FL_CFG_GFX_QUARTZ) || defined(FL_DOXYGEN)
|
||||
|
||||
#if ! defined(FL_DOXYGEN)
|
||||
|
||||
#include <FL/platform.H>
|
||||
#if !defined(kCGBitmapByteOrder32Host) // doc says available 10.4 but some 10.4 don't have it
|
||||
# define kCGBitmapByteOrder32Host 0
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
|
||||
# include <OpenGL/glext.h>
|
||||
# define GL_TEXTURE_RECTANGLE_ARB GL_TEXTURE_RECTANGLE_EXT
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED
|
||||
|
||||
/* Text drawing to an OpenGL scene under Mac OS X is implemented using textures, as recommended by Apple.
|
||||
This allows to use any font at any size, and any Unicode character.
|
||||
Some old Apple hardware doesn't implement the required GL_EXT_texture_rectangle extension.
|
||||
For these, glutStrokeString() is used to draw text. In that case, it's possible to vary text size,
|
||||
but not text font, and only ASCII characters can be drawn.
|
||||
*/
|
||||
|
||||
static float gl_scale = 1; // set to 2 for high resolution Fl_Gl_Window
|
||||
static int has_texture_rectangle = 0; // true means GL_EXT_texture_rectangle is available
|
||||
|
||||
#include <FL/glu.h> // for gluUnProject() and gluCheckExtension()
|
||||
#include <FL/glut.H> // for glutStrokeString() and glutStrokeLength()
|
||||
static float gl_scale = 1; // scaling factor between FLTK and GL drawing units: GL = FLTK * gl_scale
|
||||
|
||||
// manages a fifo pile of pre-computed string textures
|
||||
class gl_texture_fifo {
|
||||
friend class Fl_Cocoa_Gl_Window_Driver;
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
private:
|
||||
typedef struct { // information for a pre-computed texture
|
||||
GLuint texName; // its name
|
||||
char *utf8; //its text
|
||||
Fl_Font_Descriptor *fdesc; // its font
|
||||
float ratio; // used without rectangle texture
|
||||
int scale; // 1 or 2 for low/high resolution
|
||||
float scale; // scaling factor of the GUI
|
||||
} data;
|
||||
data *fifo; // array of pile elements
|
||||
int size_; // pile height
|
||||
@ -421,10 +291,34 @@ gl_texture_fifo::~gl_texture_fifo()
|
||||
for (int i = 0; i < size_; i++) {
|
||||
if (fifo[i].utf8) free(fifo[i].utf8);
|
||||
if (textures_generated) glDeleteTextures(1, &fifo[i].texName);
|
||||
}
|
||||
}
|
||||
free(fifo);
|
||||
}
|
||||
|
||||
// returns rank of pre-computed texture for a string if it exists
|
||||
int gl_texture_fifo::already_known(const char *str, int n)
|
||||
{
|
||||
int rank;
|
||||
for ( rank = 0; rank <= last; rank++) {
|
||||
if ( (memcmp(str, fifo[rank].utf8, n) == 0) && (fifo[rank].utf8[n] == 0) &&
|
||||
(fifo[rank].fdesc == gl_fontsize) && (fifo[rank].scale == gl_scale) ) {
|
||||
return rank;
|
||||
}
|
||||
}
|
||||
return -1; // means no texture exists yet for that string
|
||||
}
|
||||
|
||||
static gl_texture_fifo *gl_fifo = NULL; // points to the texture pile class instance
|
||||
|
||||
void gl_texture_reset()
|
||||
{
|
||||
if (gl_fifo) gl_texture_pile_height(gl_texture_pile_height());
|
||||
}
|
||||
|
||||
|
||||
// Cross-platform implementation of the texture mechanism for text rendering
|
||||
// using textures with the alpha channel only.
|
||||
|
||||
// displays a pre-computed texture on the GL scene
|
||||
void gl_texture_fifo::display_texture(int rank)
|
||||
{
|
||||
@ -440,46 +334,39 @@ void gl_texture_fifo::display_texture(int rank)
|
||||
float winw = gl_scale * Fl_Window::current()->w();
|
||||
float winh = gl_scale * Fl_Window::current()->h();
|
||||
// GL_COLOR_BUFFER_BIT for glBlendFunc, GL_ENABLE_BIT for glEnable / glDisable
|
||||
glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glDisable (GL_DEPTH_TEST); // ensure text is not removed by depth buffer test.
|
||||
glEnable (GL_BLEND); // for text fading
|
||||
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // ditto
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_LIGHTING);
|
||||
GLfloat pos[4];
|
||||
glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
|
||||
float R = 2;
|
||||
if (!has_texture_rectangle) {
|
||||
R *= fifo[rank].ratio;
|
||||
if (gl_start_scale != 1) { // using gl_start() / gl_finish()
|
||||
pos[0] /= gl_start_scale;
|
||||
pos[1] /= gl_start_scale;
|
||||
}
|
||||
|
||||
float R = 2;
|
||||
glScalef (R/winw, R/winh, 1.0f);
|
||||
glTranslatef (-winw/R, -winh/R, 0.0f);
|
||||
GLint width;
|
||||
if (has_texture_rectangle) {
|
||||
glEnable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fifo[rank].texName);
|
||||
GLint height;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_RECTANGLE_ARB, 0, GL_TEXTURE_WIDTH, &width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_RECTANGLE_ARB, 0, GL_TEXTURE_HEIGHT, &height);
|
||||
CGRect bounds = CGRectMake (pos[0], pos[1] - gl_scale*fl_descent(), width, height);
|
||||
//write the texture on screen
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (0.0f, 0.0f); // draw lower left in world coordinates
|
||||
glVertex2f (bounds.origin.x, bounds.origin.y);
|
||||
|
||||
glTexCoord2f (0.0f, height); // draw upper left in world coordinates
|
||||
glVertex2f (bounds.origin.x, bounds.origin.y + bounds.size.height);
|
||||
|
||||
glTexCoord2f (width, height); // draw upper right in world coordinates
|
||||
glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height);
|
||||
|
||||
glTexCoord2f (width, 0.0f); // draw lower right in world coordinates
|
||||
glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y);
|
||||
glEnd ();
|
||||
} else {
|
||||
glTranslatef(pos[0]*2/R, pos[1]*2/R, 0.0);
|
||||
glutStrokeString(GLUT_STROKE_ROMAN, (uchar*)fifo[rank].utf8);
|
||||
width = fl_width(fifo[rank].utf8);
|
||||
}
|
||||
glEnable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fifo[rank].texName);
|
||||
GLint width, height;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_RECTANGLE_ARB, 0, GL_TEXTURE_WIDTH, &width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_RECTANGLE_ARB, 0, GL_TEXTURE_HEIGHT, &height);
|
||||
//write the texture on screen
|
||||
glBegin (GL_QUADS);
|
||||
float ox = pos[0];
|
||||
float oy = pos[1] + height - gl_scale * fl_descent();
|
||||
glTexCoord2f (0.0f, 0.0f); // draw lower left in world coordinates
|
||||
glVertex2f (ox, oy);
|
||||
glTexCoord2f (0.0f, height); // draw upper left in world coordinates
|
||||
glVertex2f (ox, oy - height);
|
||||
glTexCoord2f (width, height); // draw upper right in world coordinates
|
||||
glVertex2f (ox + width, oy - height);
|
||||
glTexCoord2f (width, 0.0f); // draw lower right in world coordinates
|
||||
glVertex2f (ox + width, oy);
|
||||
glEnd ();
|
||||
glPopAttrib();
|
||||
|
||||
// reset original matrices
|
||||
@ -498,14 +385,18 @@ void gl_texture_fifo::display_texture(int rank)
|
||||
GLint viewport[4];
|
||||
glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
gluUnProject(pos[0], pos[1], pos[2], modelmat, projmat, viewport, &objX, &objY, &objZ);
|
||||
|
||||
if (gl_start_scale != 1) { // using gl_start() / gl_finish()
|
||||
objX *= gl_start_scale;
|
||||
objY *= gl_start_scale;
|
||||
}
|
||||
glRasterPos2d(objX, objY);
|
||||
}
|
||||
} // display_texture
|
||||
|
||||
|
||||
// pre-computes a string texture
|
||||
int gl_texture_fifo::compute_texture(const char* str, int n)
|
||||
{
|
||||
Fl_Graphics_Driver *prev_driver = fl_graphics_driver;
|
||||
fl_graphics_driver = Fl_Display_Device::display_device()->driver();
|
||||
current = (current + 1) % size_;
|
||||
if (current > last) last = current;
|
||||
if ( fifo[current].utf8 ) free(fifo[current].utf8);
|
||||
@ -515,89 +406,36 @@ int gl_texture_fifo::compute_texture(const char* str, int n)
|
||||
fl_graphics_driver->font_descriptor(gl_fontsize);
|
||||
int w, h;
|
||||
w = fl_width(fifo[current].utf8, n) * gl_scale;
|
||||
// Hack - make w be aligned
|
||||
w = (w + 3) & 0xFFFFFFC;
|
||||
h = fl_height() * gl_scale;
|
||||
|
||||
fifo[current].scale = gl_scale;
|
||||
fifo[current].fdesc = gl_fontsize;
|
||||
if (has_texture_rectangle) {
|
||||
//write str to a bitmap just big enough
|
||||
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
|
||||
void *base = NULL;
|
||||
if (fl_mac_os_version < 100600) base = calloc(4*w, h);
|
||||
void* save_gc = fl_graphics_driver->gc();
|
||||
CGContextRef gc = CGBitmapContextCreate(base, w, h, 8, w*4, lut,
|
||||
(CGBitmapInfo)(kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
|
||||
fl_graphics_driver->gc(gc);
|
||||
CGColorSpaceRelease(lut);
|
||||
GLfloat colors[4];
|
||||
glGetFloatv(GL_CURRENT_COLOR, colors);
|
||||
fl_color((uchar)(colors[0]*255), (uchar)(colors[1]*255), (uchar)(colors[2]*255));
|
||||
CGContextTranslateCTM(gc, 0, h - gl_scale*fl_descent());
|
||||
CGContextScaleCTM(gc, gl_scale, gl_scale);
|
||||
fl_draw(str, n, 0, 0);
|
||||
//put this bitmap in a texture
|
||||
glPushAttrib(GL_TEXTURE_BIT);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fifo[current].texName);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, CGBitmapContextGetData(gc));
|
||||
glPopAttrib();
|
||||
CGContextRelease(gc);
|
||||
fl_graphics_driver->gc(save_gc);
|
||||
if (base) free(base);
|
||||
} else {
|
||||
fifo[current].ratio = float(w)/glutStrokeLength(GLUT_STROKE_ROMAN, (uchar*)fifo[current].utf8);
|
||||
}
|
||||
fl_graphics_driver = prev_driver;
|
||||
char *txt_buf = Fl_Gl_Window_Driver::global()->alpha_mask_for_string(str, n, w, h);
|
||||
|
||||
// put the bitmap in an alpha-component-only texture
|
||||
glPushAttrib(GL_TEXTURE_BIT);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fifo[current].texName);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
|
||||
// GL_ALPHA8 is defined in GL/gl.h of X11 and of MinGW32 and of MinGW64 and of OpenGL.framework for MacOS
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA8, w, h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, txt_buf);
|
||||
/* For the record: texture construction if an alpha-only-texture is not possible
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, rgba_buf);
|
||||
and also, replace GL_SRC_ALPHA by GL_ONE in glBlendFunc() call of display_texture()
|
||||
*/
|
||||
delete[] txt_buf; // free the buffer now we have copied it into the Gl texture
|
||||
glPopAttrib();
|
||||
return current;
|
||||
}
|
||||
|
||||
// returns rank of pre-computed texture for a string if it exists
|
||||
int gl_texture_fifo::already_known(const char *str, int n)
|
||||
{
|
||||
int rank;
|
||||
for ( rank = 0; rank <= last; rank++) {
|
||||
if ( memcmp(str, fifo[rank].utf8, n) == 0 && fifo[rank].utf8[n] == 0 &&
|
||||
fifo[rank].fdesc == gl_fontsize && fifo[rank].scale == gl_scale) return rank;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static gl_texture_fifo *gl_fifo = NULL; // points to the texture pile class instance
|
||||
|
||||
// draws a utf8 string using pre-computed texture if available
|
||||
void Fl_Cocoa_Gl_Window_Driver::draw_string(const char* str, int n)
|
||||
{
|
||||
Fl_Gl_Window *gwin = Fl_Window::current()->as_gl_window();
|
||||
gl_scale = (gwin ? gwin->pixels_per_unit() : 1);
|
||||
|
||||
//fprintf(stderr,"gl_scale=%d\n",gl_scale);
|
||||
if (! gl_fifo) gl_fifo = new gl_texture_fifo();
|
||||
if (!gl_fifo->textures_generated) {
|
||||
has_texture_rectangle = gluCheckExtension((GLubyte*)"GL_EXT_texture_rectangle", glGetString(GL_EXTENSIONS));
|
||||
if (has_texture_rectangle) for (int i = 0; i < gl_fifo->size_; i++) glGenTextures(1, &(gl_fifo->fifo[i].texName));
|
||||
gl_fifo->textures_generated = 1;
|
||||
}
|
||||
int rank = gl_fifo->already_known(str, n);
|
||||
if (rank == -1) {
|
||||
rank = gl_fifo->compute_texture(str, n);
|
||||
}
|
||||
gl_fifo->display_texture(rank);
|
||||
}
|
||||
|
||||
void gl_texture_reset()
|
||||
{
|
||||
if (gl_fifo) gl_texture_pile_height(gl_texture_pile_height());
|
||||
}
|
||||
|
||||
#endif //! defined(FL_DOXYGEN)
|
||||
|
||||
/** \addtogroup group_macosx
|
||||
@{ */
|
||||
#endif // ! defined(FL_DOXYGEN)
|
||||
|
||||
/**
|
||||
\brief Returns the current height of the pile of pre-computed string textures
|
||||
*
|
||||
Returns the current maximum height of the pile of pre-computed string textures.
|
||||
The default value is 100
|
||||
\see Fl::draw_GL_text_with_textures(int)
|
||||
*/
|
||||
int gl_texture_pile_height(void)
|
||||
{
|
||||
@ -606,23 +444,352 @@ int gl_texture_pile_height(void)
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Changes the height of the pile of pre-computed string textures
|
||||
*
|
||||
Changes the maximum height of the pile of pre-computed string textures
|
||||
|
||||
Strings that are often re-displayed can be processed much faster if
|
||||
this pile is set high enough to hold all of them.
|
||||
\param max Height of the texture pile
|
||||
*/
|
||||
\param max Maximum height of the texture pile
|
||||
\see Fl::draw_GL_text_with_textures(int)
|
||||
*/
|
||||
void gl_texture_pile_height(int max)
|
||||
{
|
||||
if (gl_fifo) delete gl_fifo;
|
||||
gl_fifo = new gl_texture_fifo(max);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
void Fl_Gl_Window_Driver::draw_string_legacy(const char* str, int n)
|
||||
{
|
||||
draw_string_legacy_glut(str, n);
|
||||
}
|
||||
|
||||
|
||||
/** draws a utf8 string using an OpenGL texture */
|
||||
void Fl_Gl_Window_Driver::draw_string_with_texture(const char* str, int n)
|
||||
{
|
||||
Fl_Gl_Window *gwin = Fl_Window::current()->as_gl_window();
|
||||
gl_scale = (gwin ? gwin->pixels_per_unit() : 1);
|
||||
if (!gl_fifo) gl_fifo = new gl_texture_fifo();
|
||||
if (!gl_fifo->textures_generated) {
|
||||
if (has_texture_rectangle) for (int i = 0; i < gl_fifo->size_; i++) glGenTextures(1, &(gl_fifo->fifo[i].texName));
|
||||
gl_fifo->textures_generated = 1;
|
||||
}
|
||||
int index = gl_fifo->already_known(str, n);
|
||||
if (index == -1) {
|
||||
index = gl_fifo->compute_texture(str, n);
|
||||
}
|
||||
gl_fifo->display_texture(index);
|
||||
}
|
||||
|
||||
|
||||
char *Fl_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, int w, int h)
|
||||
{
|
||||
// write str to a bitmap that is just big enough
|
||||
// create an Fl_Image_Surface object
|
||||
Fl_Image_Surface *image_surface = new Fl_Image_Surface(w, h);
|
||||
Fl_Font fnt = fl_font(); // get the current font
|
||||
// direct all further graphics requests to the image
|
||||
Fl_Surface_Device::push_current(image_surface);
|
||||
// fill the background with black, which we will interpret as transparent
|
||||
fl_color(0,0,0);
|
||||
fl_rectf(0, 0, w, h);
|
||||
// set up the text colour as white, which we will interpret as opaque
|
||||
fl_color(255,255,255);
|
||||
// Fix the font scaling
|
||||
fl_font (fnt, gl_fontsize->size); // resize "fltk" font to current GL view scaling
|
||||
int desc = fl_descent();
|
||||
// Render the text to the buffer
|
||||
fl_draw(str, n, 0, h - desc);
|
||||
// get the resulting image
|
||||
Fl_RGB_Image* image = image_surface->image();
|
||||
// direct graphics requests back to previous state
|
||||
Fl_Surface_Device::pop_current();
|
||||
delete image_surface;
|
||||
// This gives us an RGB rendering of the text. We build an alpha channel from that.
|
||||
char *txt_buf = new char [w * h];
|
||||
for (int idx = 0; idx < w * h; ++idx)
|
||||
{ // Fake up the alpha component using the green component's value
|
||||
txt_buf[idx] = image->array[idx * 3 + 1];
|
||||
}
|
||||
delete image;
|
||||
return txt_buf;
|
||||
}
|
||||
|
||||
|
||||
// platform-independent, no-texture GL text drawing procedure
|
||||
// when Fl_XXX_Gl_Window_Driver::get_list() and gl_bitmap_font() are implemented
|
||||
void Fl_Gl_Window_Driver::draw_string_legacy_get_list(const char* str, int n) {
|
||||
static unsigned short *buf = NULL;
|
||||
static unsigned l = 0;
|
||||
unsigned wn = fl_utf8toUtf16(str, n, buf, l);
|
||||
if (wn >= l) {
|
||||
buf = (unsigned short*) realloc(buf, sizeof(unsigned short) * (wn + 1));
|
||||
l = wn + 1;
|
||||
wn = fl_utf8toUtf16(str, n, buf, l);
|
||||
}
|
||||
int size = 0;
|
||||
if (gl_start_scale != 1) { // using gl_start() / gl_finish()
|
||||
size = fl_graphics_driver->font_descriptor()->size;
|
||||
gl_font(fl_font(), size * gl_start_scale);
|
||||
}
|
||||
for (unsigned i = 0; i < wn; i++) {
|
||||
unsigned int r;
|
||||
r = (buf[i] & 0xFC00) >> 10;
|
||||
get_list(gl_fontsize, r);
|
||||
}
|
||||
glCallLists(wn, GL_UNSIGNED_SHORT, buf);
|
||||
if (gl_start_scale != 1) { // using gl_start() / gl_finish()
|
||||
gl_font(fl_font(), size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Platform-independent, no-texture, GL text drawing procedure when there's no OS support whatsoever:
|
||||
glutStrokeString() is used to draw text. It's possible to vary text size, but not text font,
|
||||
and only ASCII characters can be drawn.
|
||||
*/
|
||||
void Fl_Gl_Window_Driver::draw_string_legacy_glut(const char* str, int n)
|
||||
{
|
||||
uchar *str_nul = new uchar[n + 1];
|
||||
int m = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if ((uchar)str[i] < 128) str_nul[m++] = str[i];
|
||||
}
|
||||
str_nul[m] = 0;
|
||||
n = m;
|
||||
Fl_Surface_Device::push_current(Fl_Display_Device::display_device());
|
||||
fl_graphics_driver->font_descriptor(gl_fontsize);
|
||||
Fl_Gl_Window *gwin = Fl_Window::current()->as_gl_window();
|
||||
gl_scale = (gwin ? gwin->pixels_per_unit() : 1);
|
||||
float ratio = fl_width((char*)str_nul, n) * gl_scale/glutStrokeLength(GLUT_STROKE_ROMAN, str_nul);
|
||||
Fl_Surface_Device::pop_current();
|
||||
|
||||
//setup matrices
|
||||
GLint matrixMode;
|
||||
glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity ();
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity ();
|
||||
float winw = gl_scale * Fl_Window::current()->w();
|
||||
float winh = gl_scale * Fl_Window::current()->h();
|
||||
|
||||
GLfloat pos[4];
|
||||
glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
|
||||
if (gl_start_scale != 1) { // using gl_start() / gl_finish()
|
||||
pos[0] /= gl_start_scale;
|
||||
pos[1] /= gl_start_scale;
|
||||
}
|
||||
float R = 2 * ratio;
|
||||
glScalef (R/winw, R/winh, 1.0f);
|
||||
glTranslatef (-winw/R, -winh/R, 0.0f);
|
||||
glTranslatef(pos[0]*2/R, pos[1]*2/R, 0.0);
|
||||
glutStrokeString(GLUT_STROKE_ROMAN, str_nul);
|
||||
float width = fl_width((char*)str_nul);
|
||||
delete[] str_nul;
|
||||
glPopAttrib();
|
||||
// reset original matrices
|
||||
glPopMatrix(); // GL_MODELVIEW
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode (matrixMode);
|
||||
//set the raster position to end of string
|
||||
pos[0] += width;
|
||||
GLdouble modelmat[16];
|
||||
glGetDoublev (GL_MODELVIEW_MATRIX, modelmat);
|
||||
GLdouble projmat[16];
|
||||
glGetDoublev (GL_PROJECTION_MATRIX, projmat);
|
||||
GLdouble objX, objY, objZ;
|
||||
GLint viewport[4];
|
||||
glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
gluUnProject(pos[0], pos[1], pos[2], modelmat, projmat, viewport, &objX, &objY, &objZ);
|
||||
if (gl_start_scale != 1) { // using gl_start() / gl_finish()
|
||||
objX *= gl_start_scale;
|
||||
objY *= gl_start_scale;
|
||||
}
|
||||
glRasterPos2d(objX, objY);
|
||||
}
|
||||
|
||||
|
||||
#if defined(FL_CFG_GFX_XLIB)
|
||||
# include "drivers/Xlib/Fl_Font.H"
|
||||
# include <FL/platform.H>
|
||||
# include <GL/glx.h>
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::draw_string_legacy(const char* str, int n) {
|
||||
draw_string_legacy_get_list(str, n);
|
||||
}
|
||||
|
||||
int Fl_X11_Gl_Window_Driver::genlistsize() {
|
||||
#if USE_XFT
|
||||
return 256;
|
||||
#else
|
||||
return 0x10000;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) {
|
||||
/* This method should ONLY be triggered if our GL font texture pile mechanism
|
||||
* is not working on this platform. This code might not reliably render glyphs
|
||||
* from higher codepoints. */
|
||||
if (!fl_fontsize->listbase) {
|
||||
#if USE_XFT
|
||||
/* Ideally, for XFT, we need a glXUseXftFont implementation here... But we
|
||||
* do not have such a thing. Instead, we try to find a legacy Xlib font that
|
||||
* matches the current XFT font and use that.
|
||||
* Ideally, we never come here - we hope the texture pile implementation
|
||||
* will work correctly so that XFT can render the face directly without the
|
||||
* need for this workaround. */
|
||||
XFontStruct *font = fl_xfont.value();
|
||||
int base = font->min_char_or_byte2;
|
||||
int count = font->max_char_or_byte2 - base + 1;
|
||||
fl_fontsize->listbase = glGenLists(genlistsize());
|
||||
glXUseXFont(font->fid, base, count, fl_fontsize->listbase+base);
|
||||
#else
|
||||
/* Not using XFT to render text - the legacy Xlib fonts can usually be rendered
|
||||
* directly by using glXUseXFont mechanisms. */
|
||||
fl_fontsize->listbase = glGenLists(genlistsize());
|
||||
#endif // !USE_XFT
|
||||
}
|
||||
glListBase(fl_fontsize->listbase);
|
||||
}
|
||||
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::get_list(Fl_Font_Descriptor *fd, int r) {
|
||||
Fl_Xlib_Font_Descriptor *gl_fd = (Fl_Xlib_Font_Descriptor*)fd;
|
||||
if (gl_fd->glok[r]) return;
|
||||
gl_fd->glok[r] = 1;
|
||||
# if USE_XFT
|
||||
/* We hope not to come here: We hope that any system using XFT will also
|
||||
* have sufficient GL capability to support our font texture pile mechansim,
|
||||
* allowing XFT to render the face directly. */
|
||||
// Face already set by gl_bitmap_font in this case.
|
||||
# else
|
||||
unsigned int ii = r * 0x400;
|
||||
for (int i = 0; i < 0x400; i++) {
|
||||
XFontStruct *font = NULL;
|
||||
unsigned short id;
|
||||
fl_XGetUtf8FontAndGlyph(gl_fd->font, ii, &font, &id);
|
||||
if (font) glXUseXFont(font->fid, id, 1, gl_fd->listbase+ii);
|
||||
ii++;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
#if !USE_XFT
|
||||
Fl_Font_Descriptor** Fl_X11_Gl_Window_Driver::fontnum_to_fontdescriptor(int fnum) {
|
||||
Fl_Xlib_Fontdesc *s = ((Fl_Xlib_Fontdesc*)fl_fonts) + fnum;
|
||||
return &(s->first);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_GL_OVERLAY
|
||||
extern uchar fl_overlay;
|
||||
int Fl_X11_Gl_Window_Driver::overlay_color(Fl_Color i) {
|
||||
if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return 1;}
|
||||
return 0;
|
||||
}
|
||||
#endif // HAVE_GL_OVERLAY
|
||||
|
||||
#endif // FL_CFG_GFX_XLIB
|
||||
|
||||
|
||||
#if defined(FL_CFG_GFX_GDI)
|
||||
# include "drivers/GDI/Fl_Font.H"
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::draw_string_legacy(const char* str, int n) {
|
||||
draw_string_legacy_get_list(str, n);
|
||||
}
|
||||
|
||||
int Fl_WinAPI_Gl_Window_Driver::genlistsize() {
|
||||
return 0x10000;
|
||||
}
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) {
|
||||
if (!fl_fontsize->listbase) {
|
||||
fl_fontsize->listbase = glGenLists(genlistsize());
|
||||
}
|
||||
glListBase(fl_fontsize->listbase);
|
||||
}
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::get_list(Fl_Font_Descriptor *fd, int r) {
|
||||
Fl_GDI_Font_Descriptor* gl_fd = (Fl_GDI_Font_Descriptor*)fd;
|
||||
if (gl_fd->glok[r]) return;
|
||||
gl_fd->glok[r] = 1;
|
||||
unsigned int ii = r * 0x400;
|
||||
HFONT oldFid = (HFONT)SelectObject((HDC)fl_graphics_driver->gc(), gl_fd->fid);
|
||||
wglUseFontBitmapsW((HDC)fl_graphics_driver->gc(), ii, 0x400, gl_fd->listbase+ii);
|
||||
SelectObject((HDC)fl_graphics_driver->gc(), oldFid);
|
||||
}
|
||||
|
||||
#if HAVE_GL_OVERLAY
|
||||
extern uchar fl_overlay;
|
||||
extern int fl_overlay_depth;
|
||||
int Fl_WinAPI_Gl_Window_Driver::overlay_color(Fl_Color i) {
|
||||
if (fl_overlay && fl_overlay_depth) {
|
||||
if (fl_overlay_depth < 8) {
|
||||
// only black & white produce the expected colors. This could
|
||||
// be improved by fixing the colormap set in Fl_Gl_Overlay.cxx
|
||||
int size = 1<<fl_overlay_depth;
|
||||
if (!i) glIndexi(size-2);
|
||||
else if (i >= size-2) glIndexi(size-1);
|
||||
else glIndexi(i);
|
||||
} else {
|
||||
glIndexi(i ? i : FL_GRAY_RAMP);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // HAVE_GL_OVERLAY
|
||||
#endif // FL_CFG_GFX_GDI
|
||||
|
||||
|
||||
#if defined(FL_CFG_GFX_QUARTZ)
|
||||
# include "drivers/Quartz/Fl_Font.H"
|
||||
|
||||
# if !defined(kCGBitmapByteOrder32Host) // doc says available 10.4 but some 10.4 don't have it
|
||||
# define kCGBitmapByteOrder32Host 0
|
||||
# endif // !defined(kCGBitmapByteOrder32Host)
|
||||
|
||||
/* Some old Apple hardware doesn't implement the GL_EXT_texture_rectangle extension.
|
||||
For it, draw_string_legacy_glut() is used to draw text.
|
||||
*/
|
||||
|
||||
char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, int w, int h)
|
||||
{
|
||||
// write str to a bitmap just big enough
|
||||
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
|
||||
void *base = NULL;
|
||||
if (fl_mac_os_version < 100600) base = calloc(4*w, h);
|
||||
void* save_gc = fl_graphics_driver->gc();
|
||||
CGContextRef gc = CGBitmapContextCreate(base, w, h, 8, w*4, lut,
|
||||
(CGBitmapInfo)(kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
|
||||
CGColorSpaceRelease(lut);
|
||||
fl_graphics_driver->gc(gc);
|
||||
fl_color(FL_WHITE);
|
||||
CGContextScaleCTM(gc, gl_scale, -gl_scale);
|
||||
CGContextTranslateCTM(gc, 0, -fl_descent());
|
||||
fl_draw(str, n, 0, 0);
|
||||
// get the alpha channel only of the bitmap
|
||||
char *txt_buf = new char[w*h], *r = txt_buf, *q;
|
||||
q = (char*)CGBitmapContextGetData(gc);
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
*r++ = *(q+3);
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
CGContextRelease(gc);
|
||||
fl_graphics_driver->gc(save_gc);
|
||||
if (base) free(base);
|
||||
return txt_buf;
|
||||
}
|
||||
|
||||
#endif // FL_CFG_GFX_QUARTZ
|
||||
|
||||
#endif // HAVE_GL
|
||||
#endif // HAVE_GL || defined(FL_DOXYGEN)
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
|
@ -42,23 +42,25 @@ class Fl_Gl_Choice;
|
||||
static GLContext context;
|
||||
static int clip_state_number=-1;
|
||||
static int pw, ph;
|
||||
float gl_start_scale = 1;
|
||||
|
||||
static Fl_Gl_Choice* gl_choice;
|
||||
|
||||
/** Creates an OpenGL context */
|
||||
void gl_start() {
|
||||
gl_start_scale = Fl_Display_Device::display_device()->driver()->scale();
|
||||
if (!context) {
|
||||
if (!gl_choice) Fl::gl_visual(0);
|
||||
context = Fl_Gl_Window_Driver::global()->create_gl_context(Fl_Window::current(), gl_choice);
|
||||
}
|
||||
Fl_Gl_Window_Driver::global()->set_gl_context(Fl_Window::current(), context);
|
||||
Fl_Gl_Window_Driver::global()->gl_start();
|
||||
if (pw != Fl_Window::current()->w() || ph != Fl_Window::current()->h()) {
|
||||
pw = Fl_Window::current()->w();
|
||||
ph = Fl_Window::current()->h();
|
||||
if (pw != int(Fl_Window::current()->w() * gl_start_scale) || ph != int(Fl_Window::current()->h() * gl_start_scale)) {
|
||||
pw = int(Fl_Window::current()->w() * gl_start_scale);
|
||||
ph = int(Fl_Window::current()->h() * gl_start_scale);
|
||||
glLoadIdentity();
|
||||
glViewport(0, 0, pw, ph);
|
||||
glOrtho(0, pw, 0, ph, -1, 1);
|
||||
glOrtho(0, Fl_Window::current()->w(), 0, Fl_Window::current()->h(), -1, 1);
|
||||
glDrawBuffer(GL_FRONT);
|
||||
}
|
||||
if (clip_state_number != fl_graphics_driver->fl_clip_state_number) {
|
||||
@ -67,18 +69,21 @@ void gl_start() {
|
||||
if (fl_clip_box(0, 0, Fl_Window::current()->w(), Fl_Window::current()->h(),
|
||||
x, y, w, h)) {
|
||||
fl_clip_region(Fl_Graphics_Driver::default_driver().XRectangleRegion(x,y,w,h));
|
||||
glScissor(x, Fl_Window::current()->h()-(y+h), w, h);
|
||||
glScissor(x*gl_start_scale, (Fl_Window::current()->h()-(y+h))*gl_start_scale, w*gl_start_scale, h*gl_start_scale);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
} else {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
Fl_Display_Device::display_device()->driver()->scale(1);
|
||||
}
|
||||
|
||||
/** Releases an OpenGL context */
|
||||
void gl_finish() {
|
||||
glFlush();
|
||||
Fl_Gl_Window_Driver::global()->waitGL();
|
||||
Fl_Display_Device::display_device()->driver()->scale(gl_start_scale);
|
||||
gl_start_scale = 1;
|
||||
}
|
||||
|
||||
void Fl_Gl_Window_Driver::gl_visual(Fl_Gl_Choice *c) {
|
||||
|
Loading…
Reference in New Issue
Block a user