aboutsummaryrefslogtreecommitdiff
path: root/dw/fltkplatform.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dw/fltkplatform.cc')
-rw-r--r--dw/fltkplatform.cc246
1 files changed, 157 insertions, 89 deletions
diff --git a/dw/fltkplatform.cc b/dw/fltkplatform.cc
index 0b0f156a..d4db5d7a 100644
--- a/dw/fltkplatform.cc
+++ b/dw/fltkplatform.cc
@@ -24,18 +24,12 @@
#include "../lout/msg.h"
#include "fltkcore.hh"
-#include <fltk/draw.h>
-#include <fltk/run.h>
-#include <fltk/events.h>
-#include <fltk/Monitor.h>
-#include <fltk/InvisibleBox.h>
-#include <fltk/Tooltip.h>
-#include <fltk/utf.h>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Tooltip.H>
namespace dw {
namespace fltk {
-using namespace ::fltk;
using namespace lout;
/**
@@ -47,37 +41,69 @@ container::typed::HashTable <dw::core::style::FontAttrs,
new container::typed::HashTable <dw::core::style::FontAttrs,
FltkFont> (false, false);
+container::typed::HashTable <lout::object::ConstString,
+ FltkFont::FontFamily> *FltkFont::systemFonts =
+ NULL;
+
+FltkFont::FontFamily FltkFont::standardFontFamily;
+
+FltkFont::FontFamily::FontFamily ()
+{
+ font[0] = FL_HELVETICA;
+ font[1] = FL_HELVETICA_BOLD;
+ font[2] = FL_HELVETICA_ITALIC;
+ font[3] = FL_HELVETICA_BOLD_ITALIC;
+}
+
+void FltkFont::FontFamily::set (Fl_Font f, int attrs)
+{
+ int idx = 0;
+ if (attrs & FL_BOLD)
+ idx += 1;
+ if (attrs & FL_ITALIC)
+ idx += 2;
+ font[idx] = f;
+}
+
+Fl_Font FltkFont::FontFamily::get (int attrs)
+{
+ int idx = 0;
+ if (attrs & FL_BOLD)
+ idx += 1;
+ if (attrs & FL_ITALIC)
+ idx += 2;
+ return font[idx];
+}
+
+
+
FltkFont::FltkFont (core::style::FontAttrs *attrs)
{
+ if (!systemFonts)
+ initSystemFonts ();
+
copyAttrs (attrs);
int fa = 0;
if (weight >= 500)
- fa |= BOLD;
+ fa |= FL_BOLD;
if (style != core::style::FONT_STYLE_NORMAL)
- fa |= ITALIC;
+ fa |= FL_ITALIC;
- font = ::fltk::font(name, fa);
- if (font == NULL) {
- /*
- * If using xft, fltk::HELVETICA just means sans, fltk::COURIER
- * means mono, and fltk::TIMES means serif.
- */
- font = HELVETICA->plus (fa);
- }
+ object::ConstString nameString (name);
+ FontFamily *family = systemFonts->get (&nameString);
+ if (!family)
+ family = &standardFontFamily;
- setfont(font, size);
- spaceWidth = misc::max(0, (int)getwidth(" ") + letterSpacing);
- int xw, xh;
- measure("x", xw, xh);
- xHeight = xh;
- ascent = (int)getascent();
- descent = (int)getdescent();
+ font = family->get (fa);
- /**
- * \bug The code above does not seem to work, so this workaround.
- */
- xHeight = ascent * 3 / 5;
+ fl_font(font, size);
+ spaceWidth = misc::max(0, (int)fl_width(' ') + letterSpacing);
+ int xx, xy, xw, xh;
+ fl_text_extents("x", xx, xy, xw, xh);
+ xHeight = xh;
+ descent = fl_descent();
+ ascent = fl_height() - descent;
}
FltkFont::~FltkFont ()
@@ -85,10 +111,73 @@ FltkFont::~FltkFont ()
fontsTable->remove (this);
}
+static void strstrip(char *big, const char *little)
+{
+ if (strlen(big) >= strlen(little) &&
+ strcasecmp(big + strlen(big) - strlen(little), little) == 0)
+ *(big + strlen(big) - strlen(little)) = '\0';
+}
+
+void FltkFont::initSystemFonts ()
+{
+ systemFonts = new container::typed::HashTable
+ <lout::object::ConstString, FontFamily> (true, true);
+
+ int k = Fl::set_fonts ("-*-iso10646-1");
+ for (int i = 0; i < k; i++) {
+ int t;
+ char *name = strdup (Fl::get_font_name ((Fl_Font) i, &t));
+
+ // normalize font family names (strip off "bold", "italic")
+ if (t & FL_ITALIC)
+ strstrip(name, " italic");
+ if (t & FL_BOLD)
+ strstrip(name, " bold");
+
+ MSG("Found font: %s%s%s\n", name, t & FL_BOLD ? " bold" : "",
+ t & FL_ITALIC ? " italic" : "");
+
+ object::String *familyName = new object::String(name);
+ free (name);
+ FontFamily *family = systemFonts->get (familyName);
+
+ if (family) {
+ family->set ((Fl_Font) i, t);
+ delete familyName;
+ } else {
+ family = new FontFamily ();
+ family->set ((Fl_Font) i, t);
+ systemFonts->put (familyName, family);
+ }
+ }
+}
+
+bool
+FltkFont::fontExists (const char *name)
+{
+ if (!systemFonts)
+ initSystemFonts ();
+ object::ConstString familyName (name);
+ return systemFonts->get (&familyName) != NULL;
+}
+
+Fl_Font
+FltkFont::get (const char *name, int attrs)
+{
+ if (!systemFonts)
+ initSystemFonts ();
+ object::ConstString familyName (name);
+ FontFamily *family = systemFonts->get (&familyName);
+ if (family)
+ return family->get (attrs);
+ else
+ return FL_HELVETICA;
+}
+
bool
FltkPlatform::fontExists (const char *name)
{
- return ::fltk::font(name) != NULL;
+ return FltkFont::fontExists (name);
}
FltkFont*
@@ -114,26 +203,10 @@ FltkColor::FltkColor (int color): Color (color)
{
this->color = color;
- /*
- * fltk/setcolor.cxx:
- * "A Color of zero (fltk::NO_COLOR) will draw black but is
- * ambiguous. It is returned as an error value or to indicate portions
- * of a Style that should be inherited, and it is also used as the
- * default label color for everything so that changing color zero can
- * be used by the -fg switch. You should use fltk::BLACK (56) to get
- * black."
- *
- * i.e., zero only works sometimes.
- */
-
- if (!(colors[SHADING_NORMAL] = shadeColor (color, SHADING_NORMAL) << 8))
- colors[SHADING_NORMAL] = ::fltk::BLACK;
- if (!(colors[SHADING_INVERSE] = shadeColor (color, SHADING_INVERSE) << 8))
- colors[SHADING_INVERSE] = ::fltk::BLACK;
- if (!(colors[SHADING_DARK] = shadeColor (color, SHADING_DARK) << 8))
- colors[SHADING_DARK] = ::fltk::BLACK;
- if (!(colors[SHADING_LIGHT] = shadeColor (color, SHADING_LIGHT) << 8))
- colors[SHADING_LIGHT] = ::fltk::BLACK;
+ colors[SHADING_NORMAL] = shadeColor (color, SHADING_NORMAL) << 8;
+ colors[SHADING_INVERSE] = shadeColor (color, SHADING_INVERSE) << 8;
+ colors[SHADING_DARK] = shadeColor (color, SHADING_DARK) << 8;
+ colors[SHADING_LIGHT] = shadeColor (color, SHADING_LIGHT) << 8;
}
FltkColor::~FltkColor ()
@@ -156,22 +229,15 @@ FltkColor * FltkColor::create (int col)
FltkTooltip::FltkTooltip (const char *text) : Tooltip(text)
{
- shown = false;
-
- if (!text || !strpbrk(text, "&@")) {
+ if (!strchr(text, '@')) {
escaped_str = NULL;
} else {
- /*
- * WORKAROUND: ::fltk::Tooltip::tooltip_timeout() makes instance_
- * if necessary, and immediately uses it. This means that we can't
- * get our hands on it to set RAW_LABEL until after it has been shown
- * once. So let's escape the special characters ourselves.
- */
+ /* FLTK likes to interpret symbols, and so they must be escaped */
const char *src = text;
char *dest = escaped_str = (char *) malloc(strlen(text) * 2 + 1);
while (*src) {
- if (*src == '&' || *src == '@')
+ if (*src == '@')
*dest++ = *src;
*dest++ = *src++;
}
@@ -181,8 +247,6 @@ FltkTooltip::FltkTooltip (const char *text) : Tooltip(text)
FltkTooltip::~FltkTooltip ()
{
- if (shown)
- ::fltk::Tooltip::exit();
if (escaped_str)
free(escaped_str);
}
@@ -194,38 +258,36 @@ FltkTooltip *FltkTooltip::create (const char *text)
void FltkTooltip::onEnter()
{
- fltk::Widget *widget = fltk::belowmouse();
+ Fl_Widget *widget = Fl::belowmouse();
- ::fltk::Tooltip::enter(widget, *((fltk::Rectangle *)widget),
- escaped_str ? escaped_str : str);
- shown = true;
+ Fl_Tooltip::enter_area(widget, widget->x(), widget->y(), widget->w(),
+ widget->h(), escaped_str ? escaped_str : str);
}
void FltkTooltip::onLeave()
{
- ::fltk::Tooltip::exit();
- shown = false;
+ Fl_Tooltip::exit(NULL);
}
void FltkTooltip::onMotion()
{
}
-void FltkView::addFltkWidget (::fltk::Widget *widget,
+void FltkView::addFltkWidget (Fl_Widget *widget,
core::Allocation *allocation)
{
}
-void FltkView::removeFltkWidget (::fltk::Widget *widget)
+void FltkView::removeFltkWidget (Fl_Widget *widget)
{
}
-void FltkView::allocateFltkWidget (::fltk::Widget *widget,
+void FltkView::allocateFltkWidget (Fl_Widget *widget,
core::Allocation *allocation)
{
}
-void FltkView::drawFltkWidget (::fltk::Widget *widget, core::Rectangle *area)
+void FltkView::drawFltkWidget (Fl_Widget *widget, core::Rectangle *area)
{
}
@@ -310,7 +372,7 @@ FltkPlatform::FltkPlatform ()
FltkPlatform::~FltkPlatform ()
{
if (idleFuncRunning)
- remove_idle (generalStaticIdle, (void*)this);
+ Fl::remove_idle (generalStaticIdle, (void*)this);
delete idleQueue;
delete resources;
}
@@ -363,23 +425,23 @@ int FltkPlatform::textWidth (core::style::Font *font, const char *text,
int sc_fontsize = lout::misc::roundInt(ff->size * 0.78);
for (curr = 0; next < len; curr = next) {
next = nextGlyph(text, curr);
- wc = utf8decode(text + curr, text + next, &nb);
+ wc = fl_utf8decode(text + curr, text + next, &nb);
if ((wcu = towupper(wc)) == wc) {
/* already uppercase, just draw the character */
- setfont(ff->font, ff->size);
+ fl_font(ff->font, ff->size);
width += font->letterSpacing;
- width += (int)getwidth(text + curr, next - curr);
+ width += (int)fl_width(text + curr, next - curr);
} else {
/* make utf8 string for converted char */
- nb = utf8encode(wcu, chbuf);
- setfont(ff->font, sc_fontsize);
+ nb = fl_utf8encode(wcu, chbuf);
+ fl_font(ff->font, sc_fontsize);
width += font->letterSpacing;
- width += (int)getwidth(chbuf, nb);
+ width += (int)fl_width(chbuf, nb);
}
}
} else {
- setfont (ff->font, ff->size);
- width = (int) getwidth (text, len);
+ fl_font (ff->font, ff->size);
+ width = (int) fl_width (text, len);
if (font->letterSpacing) {
int curr = 0, next = 0;
@@ -397,22 +459,28 @@ int FltkPlatform::textWidth (core::style::Font *font, const char *text,
int FltkPlatform::nextGlyph (const char *text, int idx)
{
- return utf8fwd (&text[idx + 1], text, &text[strlen (text)]) - text;
+ return fl_utf8fwd (&text[idx + 1], text, &text[strlen (text)]) - text;
}
int FltkPlatform::prevGlyph (const char *text, int idx)
{
- return utf8back (&text[idx - 1], text, &text[strlen (text)]) - text;
+ return fl_utf8back (&text[idx - 1], text, &text[strlen (text)]) - text;
}
float FltkPlatform::dpiX ()
{
- return ::fltk::Monitor::all ().dpi_x ();
+ float horizontal, vertical;
+
+ Fl::screen_dpi(horizontal, vertical);
+ return horizontal;
}
float FltkPlatform::dpiY ()
{
- return ::fltk::Monitor::all ().dpi_y ();
+ float horizontal, vertical;
+
+ Fl::screen_dpi(horizontal, vertical);
+ return vertical;
}
void FltkPlatform::generalStaticIdle (void *data)
@@ -435,7 +503,7 @@ void FltkPlatform::generalIdle ()
if (idleQueue->isEmpty()) {
idleFuncRunning = false;
- remove_idle (generalStaticIdle, (void*)this);
+ Fl::remove_idle (generalStaticIdle, (void*)this);
}
}
@@ -449,7 +517,7 @@ int FltkPlatform::addIdle (void (core::Layout::*func) ())
* idle function, the passed idle function is put into a queue.
*/
if (!idleFuncRunning) {
- add_idle (generalStaticIdle, (void*)this);
+ Fl::add_idle (generalStaticIdle, (void*)this);
idleFuncRunning = true;
}
@@ -478,7 +546,7 @@ void FltkPlatform::removeIdle (int idleId)
}
if (idleFuncRunning && idleQueue->isEmpty())
- remove_idle (generalStaticIdle, (void*)this);
+ Fl::remove_idle (generalStaticIdle, (void*)this);
}
core::style::Font *FltkPlatform::createFont (core::style::FontAttrs
@@ -500,7 +568,7 @@ core::style::Tooltip *FltkPlatform::createTooltip (const char *text)
void FltkPlatform::copySelection(const char *text)
{
- fltk::copy(text, strlen(text), false);
+ Fl::copy(text, strlen(text), 0);
}
core::Imgbuf *FltkPlatform::createImgbuf (core::Imgbuf::Type type,