summaryrefslogtreecommitdiff
path: root/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-10-14 09:17:15 +0000
committerManolo Gouy <Manolo>2016-10-14 09:17:15 +0000
commit7a81273a0cfe5128ce7b6454dbd325d6461fd5cd (patch)
tree587160d37000fad63db08a498532cd82d7cec0de /src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
parent2b5fbbacfcfe6465feb8ca3be65931e42c22f2dd (diff)
MacOS: finer control of the compilation conditions under which Core text and ATSU are used or not.
The compilation conditions depend on the targeted architecture, what version of the SDK is used, and what MacOS deployment version is used. Under most conditions, a single API is possible, and no pointer-to-member function is used. But the code supports building apps that can run both APIs depending on the version of the running MacOS. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@12025 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx')
-rw-r--r--src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx163
1 files changed, 121 insertions, 42 deletions
diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
index 981c570fd..d1a30091b 100644
--- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
+++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
@@ -16,6 +16,62 @@
// http://www.fltk.org/str.php
//
+/* Implementation of support for two text drawing APIs: Core Text (current) and ATSU (legacy)
+
+ The HAS_ATSU macro (defined in Fl_Quartz_Graphics_Driver.H) is true
+ if and only if ATSU is available at compile time.
+ The condition
+ #if HAS_ATSU && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ is true if and only if both APIs are available at compile time.
+ Depending on what MacOS SDK and what deployment target are used, the code can be
+ compiled in 2 ways:
+ 1) both APIs are available at compile time and which one is used
+ is determined at runtime,
+ or
+ 2) only one API is available.
+
+ When both APIs are compiled in, the choice of which one is used at runtime is done
+ the first time the Fl_Quartz_Graphics_Driver constructor runs, and remains unchanged.
+ Core Text is selected if the running Mac OS version is ≥ 10.5.
+ The static function init_CoreText_or_ATSU() does this by setting the value
+ of the class variable CoreText_or_ATSU to either use_CoreText or use_ATSU.
+
+ If both APIs are available, several member functions come in groups of 3.
+ For example, functions draw(), draw_CoreText() and draw_ATSU() are defined. The only
+ task of draw() is to call either draw_CoreText() or draw_ATSU() depending on
+ what API has been selected at program start.
+
+ If the compilation condition authorizes a single API, one member function
+ is defined instead of 3 in the other case. For example, a single draw() function
+ is compiled, and contains the same code as what is called either draw_CoreText()
+ or draw_ATSU() in the other case.
+
+ The ADD_SUFFIX(name, suffix) macro is used so that each function has the
+ short (e.g., draw) or long (e.g., draw_CoreText) name adequate for
+ each compilation condition.
+
+ The 2 most often used text functions are draw() and width(). Two pointers to member
+ function are defined. Function init_CoreText_or_ATSU() assigns one with either
+ draw_CoreText() or draw_ATSU(), and the other with either width_CoreText() or width_ATSU().
+ The draw() and width() functions only have to dereference one pointer to member
+ function to call the adequate code.
+
+ If the compilation condition authorizes a single text API, only the code related
+ to this API (say, CoreText) is compiled whereas all code related to the other API
+ (thus, ATSU) is excluded from compilation. Furthermore, none of the code to
+ choose API at runtime and to select which member function is called is compiled.
+ Consequently, no pointer to member function is used.
+
+ The condition for both APIs to be compiled-in is
+ - target i386 or ppc architectures
+ and
+ - use SDK ≥ 10.5 and < 10.11
+ and
+ - set MacOS deployment target < 10.5 (through the -mmacosx-version-min= compilation option)
+
+ */
+
+
#include "../../config_lib.h"
#ifdef FL_CFG_GFX_QUARTZ
@@ -33,6 +89,12 @@ static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 };
static int fl_free_font = FL_FREE_FONT;
+#if HAS_ATSU && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+# define ADD_SUFFIX(name, suffix) name##suffix
+#else
+# define ADD_SUFFIX(name, suffix) name
+#endif
+
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
static CFMutableDictionaryRef attributes = NULL;
@@ -131,14 +193,14 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
layout = NULL;
#endif
Fl_Quartz_Graphics_Driver *driver = (Fl_Quartz_Graphics_Driver*)&Fl_Graphics_Driver::default_driver();
-#if HAS_ATSU
+#if HAS_ATSU && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (Fl_Quartz_Graphics_Driver::CoreText_or_ATSU == Fl_Quartz_Graphics_Driver::use_ATSU) {
driver->descriptor_init_ATSU(name, size, this);
return;
}
-#endif
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
driver->descriptor_init_CoreText(name, size, this);
+#else
+ driver->descriptor_init(name, size, this);
#endif
}
@@ -233,14 +295,6 @@ int Fl_Quartz_Graphics_Driver::descent() {
return fl_fontsize->descent + 1;
}
-void Fl_Quartz_Graphics_Driver::draw(const char *str, int n, float x, float y) {
- (this->*CoreText_or_ATSU_draw)(str, n, x, y);
-}
-
-double Fl_Quartz_Graphics_Driver::width(const UniChar* txt, int n) {
- return (this->*CoreText_or_ATSU_width)(txt, n);
-}
-
void Fl_Quartz_Graphics_Driver::draw(const char* str, int n, int x, int y) {
draw(str, n, (float)x, y+0.5f);
}
@@ -278,14 +332,8 @@ double Fl_Quartz_Graphics_Driver::width(unsigned int wc) {
}
-void Fl_Quartz_Graphics_Driver::set_fontname_in_fontdesc(Fl_Fontdesc *f) {
-#if HAS_ATSU
- if (CoreText_or_ATSU == use_ATSU) {
- strlcpy(f->fontname, f->name, ENDOFBUFFER);
- return;
- }
-#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+static void set_fontname_CoreText(Fl_Fontdesc *f) {
CFStringRef cfname = CFStringCreateWithCString(NULL, f->name, kCFStringEncodingUTF8);
CTFontRef ctfont = CTFontCreateWithName(cfname, 0, NULL);
CFRelease(cfname);
@@ -293,6 +341,19 @@ void Fl_Quartz_Graphics_Driver::set_fontname_in_fontdesc(Fl_Fontdesc *f) {
CFRelease(ctfont);
CFStringGetCString(cfname, f->fontname, ENDOFBUFFER, kCFStringEncodingUTF8);
CFRelease(cfname);
+}
+#endif
+
+void Fl_Quartz_Graphics_Driver::set_fontname_in_fontdesc(Fl_Fontdesc *f) {
+#if HAS_ATSU && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if (CoreText_or_ATSU == use_ATSU)
+ strlcpy(f->fontname, f->name, ENDOFBUFFER);
+ else
+ set_fontname_CoreText(f);
+#elif HAS_ATSU
+ strlcpy(f->fontname, f->name, ENDOFBUFFER);
+#else
+ set_fontname_CoreText(f);
#endif
}
@@ -323,44 +384,51 @@ void Fl_Quartz_Graphics_Driver::font_name(int num, const char *name) {
Fl_Fontdesc* Fl_Quartz_Graphics_Driver::calc_fl_fonts(void)
{
-#if HAS_ATSU
+#if HAS_ATSU && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (CoreText_or_ATSU == use_ATSU) return built_in_table_full;
-#endif
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ return built_in_table_PS;
+#elif HAS_ATSU
+ return built_in_table_full;
+#else
return built_in_table_PS;
#endif
}
+#if HAS_ATSU && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+
+void Fl_Quartz_Graphics_Driver::draw(const char *str, int n, float x, float y) {
+ (this->*CoreText_or_ATSU_draw)(str, n, x, y);
+}
+
+double Fl_Quartz_Graphics_Driver::width(const UniChar* txt, int n) {
+ return (this->*CoreText_or_ATSU_width)(txt, n);
+}
+
Fl_Font Fl_Quartz_Graphics_Driver::set_fonts(const char* xstarname)
{
-#if HAS_ATSU
if (CoreText_or_ATSU == use_ATSU) return set_fonts_ATSU(xstarname);
-#endif
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
return set_fonts_CoreText(xstarname);
-#endif
}
-
void Fl_Quartz_Graphics_Driver::text_extents(const char* txt, int n, int& dx, int& dy, int& w, int& h)
{
-#if HAS_ATSU
if (CoreText_or_ATSU == use_ATSU) {
text_extents_ATSU(txt, n, dx, dy, w, h);
return;
}
-#endif
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
text_extents_CoreText(txt, n, dx, dy, w, h);
-#endif
}
+#endif
+
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
/// CoreText-based code
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-void Fl_Quartz_Graphics_Driver::descriptor_init_CoreText(const char* name, Fl_Fontsize size, Fl_Font_Descriptor *d) {
+void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(descriptor_init, _CoreText)(const char* name,
+ Fl_Fontsize size, Fl_Font_Descriptor *d)
+{
CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
d->fontref = CTFontCreateWithName(str, size, NULL);
CGGlyph glyph[2];
@@ -441,7 +509,8 @@ static CGFloat variation_selector_width(CFStringRef str16, Fl_Font_Descriptor *f
return retval;
}
-double Fl_Quartz_Graphics_Driver::width_CoreText(const UniChar* txt, int n) {
+double Fl_Quartz_Graphics_Driver::ADD_SUFFIX(width, _CoreText)(const UniChar* txt, int n)
+{
double retval = 0;
UniChar uni;
int i;
@@ -511,7 +580,8 @@ double Fl_Quartz_Graphics_Driver::width_CoreText(const UniChar* txt, int n) {
// text extent calculation
-void Fl_Quartz_Graphics_Driver::text_extents_CoreText(const char *str8, int n, int &dx, int &dy, int &w, int &h) {
+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();
UniChar *txt = mac_Utf8_to_Utf16(str8, n, &n);
CFStringRef str16 = CFStringCreateWithCharactersNoCopy(NULL, txt, n, kCFAllocatorNull);
@@ -544,7 +614,8 @@ static CGColorRef flcolortocgcolor(Fl_Color i)
return CGColorCreate(cspace, components);
}
-void Fl_Quartz_Graphics_Driver::draw_CoreText(const char *str, int n, float x, float y) {
+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();
// convert to UTF-16 first
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
@@ -601,7 +672,8 @@ static int name_compare(const void *a, const void *b)
}
}
-Fl_Font Fl_Quartz_Graphics_Driver::set_fonts_CoreText(const char* xstarname) {
+Fl_Font Fl_Quartz_Graphics_Driver::ADD_SUFFIX(set_fonts, _CoreText)(const char* xstarname)
+{
#pragma unused ( xstarname )
if (fl_free_font > FL_FREE_FONT) return (Fl_Font)fl_free_font; // if already called
@@ -639,10 +711,13 @@ Fl_Font Fl_Quartz_Graphics_Driver::set_fonts_CoreText(const char* xstarname) {
#endif // >= 10.5
-#if HAS_ATSU
+
/// ATSU-based code to support Mac OS < 10.5
+#if HAS_ATSU
-void Fl_Quartz_Graphics_Driver::descriptor_init_ATSU(const char* name, Fl_Fontsize size, Fl_Font_Descriptor *d) {
+void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(descriptor_init, _ATSU)(const char* name,
+ Fl_Fontsize size, Fl_Font_Descriptor *d)
+{
OSStatus err;
// fill our structure with a few default values
d->ascent = size*3/4.;
@@ -695,7 +770,8 @@ void Fl_Quartz_Graphics_Driver::descriptor_init_ATSU(const char* name, Fl_Fontsi
ATSUSetTransientFontMatching (d->layout, true);
}
-void Fl_Quartz_Graphics_Driver::draw_ATSU(const char *str, int n, float x, float y) {
+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();
// convert to UTF-16 first
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
@@ -715,7 +791,7 @@ void Fl_Quartz_Graphics_Driver::draw_ATSU(const char *str, int n, float x, float
CGContextSetShouldAntialias(gc, false);
}
-double Fl_Quartz_Graphics_Driver::width_ATSU(const UniChar* txt, int n) {
+double Fl_Quartz_Graphics_Driver::ADD_SUFFIX(width, _ATSU)(const UniChar* txt, int n) {
OSStatus err;
Fixed bBefore, bAfter, bAscent, bDescent;
ATSUTextLayout layout;
@@ -741,7 +817,9 @@ double Fl_Quartz_Graphics_Driver::width_ATSU(const UniChar* txt, int n) {
return len;
}
-void Fl_Quartz_Graphics_Driver::text_extents_ATSU(const char *str8, int n, int &dx, int &dy, int &w, int &h) {
+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();
UniChar *txt = mac_Utf8_to_Utf16(str8, n, &n);
OSStatus err;
@@ -770,7 +848,8 @@ void Fl_Quartz_Graphics_Driver::text_extents_ATSU(const char *str8, int n, int &
//printf("r: %d l: %d t: %d b: %d w: %d h: %d\n", bbox.right, bbox.left, bbox.top, bbox.bottom, w, h);
}
-Fl_Font Fl_Quartz_Graphics_Driver::set_fonts_ATSU(const char* xstarname) {
+Fl_Font Fl_Quartz_Graphics_Driver::ADD_SUFFIX(set_fonts, _ATSU)(const char* xstarname)
+{
#pragma unused ( xstarname )
if (fl_free_font > FL_FREE_FONT) return (Fl_Font)fl_free_font; // if already called