summaryrefslogtreecommitdiff
path: root/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx')
-rw-r--r--src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx354
1 files changed, 6 insertions, 348 deletions
diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
index a277010e3..d373c1768 100644
--- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
+++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
@@ -14,61 +14,6 @@
// https://www.fltk.org/bugs.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 "Fl_Quartz_Graphics_Driver.H"
#include "Fl_Font.H"
#include <math.h>
@@ -87,13 +32,6 @@ 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;
@@ -115,28 +53,7 @@ static Fl_Fontdesc built_in_table_PS[] = { // PostScript font names preferred wh
{"AndaleMono"}, // there is no bold Monaco font on standard Mac
{"ZapfDingbatsITC"}
};
-#endif
-#if HAS_ATSU
-static Fl_Fontdesc built_in_table_full[] = { // full font names used before 10.5
- {"Arial"},
- {"Arial Bold"},
- {"Arial Italic"},
- {"Arial Bold Italic"},
- {"Courier"},
- {"Courier Bold"},
- {"Courier New Italic"},
- {"Courier New Bold Italic"},
- {"Times New Roman"},
- {"Times New Roman Bold"},
- {"Times New Roman Italic"},
- {"Times New Roman Bold Italic"},
- {"Symbol"},
- {"Monaco"},
- {"Andale Mono"}, // there is no bold Monaco font on standard Mac
- {"Webdings"}
-};
-#endif
// Bug: older versions calculated the value for *ap as a side effect of
// making the name, and then forgot about it. To avoid having to change
@@ -178,22 +95,9 @@ int Fl_Quartz_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
}
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
-#if HAS_ATSU
- layout = NULL;
-#endif
Fl_Quartz_Graphics_Driver *driver = (Fl_Quartz_Graphics_Driver*)&Fl_Graphics_Driver::default_driver();
-#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;
- }
- driver->descriptor_init_CoreText(name, size, this);
-#else
driver->descriptor_init(name, size, this);
-#endif
}
@@ -207,20 +111,12 @@ Fl_Quartz_Font_Descriptor::~Fl_Quartz_Font_Descriptor() {
#endif
*/
if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL);
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (fontref) {
CFRelease(fontref);
for (unsigned i = 0; i < sizeof(width)/sizeof(float*); i++) {
if (width[i]) free(width[i]);
}
}
-#endif
-#if HAS_ATSU
- if (layout) {
- ATSUDisposeTextLayout(layout);
- ATSUDisposeStyle(style);
- }
-#endif
}
@@ -332,9 +228,7 @@ double Fl_Quartz_Graphics_Driver::width(unsigned int wc) {
return width(utf16, l);
}
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-static void set_fontname_CoreText(Fl_Fontdesc *f) {
+void Fl_Quartz_Graphics_Driver::set_fontname_in_fontdesc(Fl_Fontdesc *f) {
CFStringRef cfname = CFStringCreateWithCString(NULL, f->name, kCFStringEncodingUTF8);
CTFontRef ctfont = cfname ? CTFontCreateWithName(cfname, 0, NULL) : NULL;
if (cfname) { CFRelease(cfname); cfname = NULL; }
@@ -348,20 +242,6 @@ static void set_fontname_CoreText(Fl_Fontdesc *f) {
}
if (!cfname) strlcpy(f->fontname, f->name, ENDOFBUFFER);
}
-#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
-}
const char *Fl_Quartz_Graphics_Driver::font_name(int num) {
if (!fl_fonts) fl_fonts = calc_fl_fonts();
@@ -385,49 +265,11 @@ 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 && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if (CoreText_or_ATSU == use_ATSU) return built_in_table_full;
- 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 (CoreText_or_ATSU == use_ATSU) return set_fonts_ATSU(xstarname);
- return set_fonts_CoreText(xstarname);
-}
-
-void Fl_Quartz_Graphics_Driver::text_extents(const char* txt, int n, int& dx, int& dy, int& w, int& h)
-{
- if (CoreText_or_ATSU == use_ATSU) {
- text_extents_ATSU(txt, n, dx, dy, w, h);
- return;
- }
- text_extents_CoreText(txt, n, dx, dy, w, h);
-}
-
-#endif
-
-
-/// CoreText-based code
-#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,
+void Fl_Quartz_Graphics_Driver::descriptor_init(const char* name,
Fl_Fontsize size, Fl_Quartz_Font_Descriptor *d)
{
CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
@@ -510,7 +352,7 @@ static CGFloat variation_selector_width(CFStringRef str16, Fl_Quartz_Font_Descri
return retval;
}
-double Fl_Quartz_Graphics_Driver::ADD_SUFFIX(width, _CoreText)(const UniChar* txt, int n)
+double Fl_Quartz_Graphics_Driver::width(const UniChar* txt, int n)
{
double retval = 0;
UniChar uni;
@@ -581,7 +423,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,
+void Fl_Quartz_Graphics_Driver::text_extents(const char *str8, int n,
int &dx, int &dy, int &w, int &h) {
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
UniChar *txt = mac_Utf8_to_Utf16(str8, n, &n);
@@ -615,7 +457,7 @@ static CGColorRef flcolortocgcolor(Fl_Color i)
return CGColorCreate(cspace, components);
}
-void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(draw, _CoreText)(const char *str, int n, float x, float y)
+void Fl_Quartz_Graphics_Driver::draw(const char *str, int n, float x, float y)
{
Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
// convert to UTF-16 first
@@ -680,7 +522,7 @@ static int name_compare(const void *a, const void *b)
}
}
-Fl_Font Fl_Quartz_Graphics_Driver::ADD_SUFFIX(set_fonts, _CoreText)(const char* xstarname)
+Fl_Font Fl_Quartz_Graphics_Driver::set_fonts(const char* xstarname)
{
#pragma unused ( xstarname )
if (fl_free_font > FL_FREE_FONT) return (Fl_Font)fl_free_font; // if already called
@@ -717,187 +559,3 @@ Fl_Font Fl_Quartz_Graphics_Driver::ADD_SUFFIX(set_fonts, _CoreText)(const char*
delete[] tabfontnames;
return (Fl_Font)fl_free_font;
}
-
-
-#endif // >= 10.5
-
-
-
-/// ATSU-based code to support Mac OS < 10.5
-#if HAS_ATSU
-
-void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(descriptor_init, _ATSU)(const char* name,
- Fl_Fontsize size, Fl_Quartz_Font_Descriptor *d)
-{
- OSStatus err;
- // fill our structure with a few default values
- d->ascent = size*3/4.;
- d->descent = size-d->ascent;
- d->q_width = size*2/3.;
- // now we allocate everything needed to render text in this font later
- // get us the default layout and style
- err = ATSUCreateTextLayout(&d->layout);
- UniChar mTxt[2] = { 65, 0 };
- err = ATSUSetTextPointerLocation(d->layout, mTxt, kATSUFromTextBeginning, 1, 1);
- err = ATSUCreateStyle(&d->style);
- err = ATSUSetRunStyle(d->layout, d->style, kATSUFromTextBeginning, kATSUToTextEnd);
- // now set the actual font, size and attributes. We also set the font matrix to
- // render our font up-side-down, so when rendered through our inverted CGContext,
- // text will appear normal again.
- Fixed fsize = IntToFixed(size);
- ATSUFontID fontID;
- ATSUFindFontFromName(name, strlen(name), kFontFullName, kFontMacintoshPlatform, kFontNoScriptCode, kFontEnglishLanguage, &fontID);
-
- // draw the font upside-down... Compensate for fltk/OSX origin differences
- ATSUAttributeTag sTag[] = { kATSUFontTag, kATSUSizeTag, kATSUFontMatrixTag };
- ByteCount sBytes[] = { sizeof(ATSUFontID), sizeof(Fixed), sizeof(CGAffineTransform) };
- ATSUAttributeValuePtr sAttr[] = { &fontID, &fsize, &font_mx };
- if (fontID != kATSUInvalidFontID) err = ATSUSetAttributes(d->style, 1, sTag, sBytes, sAttr); // set the font attribute
- err = ATSUSetAttributes(d->style, 2, sTag + 1, sBytes + 1, sAttr + 1); // then the size and matrix attributes
- // next, make sure that Quartz will only render at integer coordinates
- ATSLineLayoutOptions llo = kATSLineUseDeviceMetrics | kATSLineDisableAllLayoutOperations;
- ATSUAttributeTag aTag[] = { kATSULineLayoutOptionsTag };
- ByteCount aBytes[] = { sizeof(ATSLineLayoutOptions) };
- ATSUAttributeValuePtr aAttr[] = { &llo };
- err = ATSUSetLineControls (d->layout, kATSUFromTextBeginning, 1, aTag, aBytes, aAttr);
- // now we are finally ready to measure some letter to get the bounding box
- Fixed bBefore, bAfter, bAscent, bDescent;
- err = ATSUGetUnjustifiedBounds(d->layout, kATSUFromTextBeginning, 1, &bBefore, &bAfter, &bAscent, &bDescent);
- // Requesting a certain height font on Mac does not guarantee that ascent+descent
- // equal the requested height. fl_height will reflect the actual height that we got.
- // The font "Apple Chancery" is a pretty extreme example of overlapping letters.
- float fa = -FixedToFloat(bAscent), fd = -FixedToFloat(bDescent);
- if (fa>0.0f && fd>0.0f) {
- //float f = Size/(fa+fd);
- d->ascent = int(fa); //int(fa*f+0.5f);
- d->descent = int(fd); //Size - ascent;
- }
- int w = FixedToInt(bAfter);
- if (w)
- d->q_width = FixedToInt(bAfter);
-
- // Now, by way of experiment, try enabling Transient Font Matching, this will
- // cause ATSU to find a suitable font to render any chars the current font can't do...
- ATSUSetTransientFontMatching (d->layout, true);
-}
-
-void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(draw, _ATSU)(const char *str, int n, float x, float y)
-{
- 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();
- OSStatus err;
- // now collect our ATSU resources
- ATSUTextLayout layout = fl_fontsize->layout;
-
- ByteCount iSize = sizeof(CGContextRef);
- ATSUAttributeTag iTag = kATSUCGContextTag;
- ATSUAttributeValuePtr iValuePtr=&gc;
- ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr);
-
- err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n);
- CGContextSetShouldAntialias(gc, true);
- err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y));
- CGContextSetShouldAntialias(gc, false);
-}
-
-double Fl_Quartz_Graphics_Driver::ADD_SUFFIX(width, _ATSU)(const UniChar* txt, int n) {
- OSStatus err;
- Fixed bBefore, bAfter, bAscent, bDescent;
- ATSUTextLayout layout;
- ByteCount iSize;
- ATSUAttributeTag iTag;
- ATSUAttributeValuePtr iValuePtr;
-
- 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;
- // activate the current GC
- iSize = sizeof(CGContextRef);
- iTag = kATSUCGContextTag;
- CGContextRef value = (CGContextRef)fl_graphics_driver->gc();
- iValuePtr = &value;
- ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr);
- // now measure the bounding box
- err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n);
- err = ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, n, &bBefore, &bAfter, &bAscent, &bDescent);
- // If err is OK then return length, else return 0. Or something...
- int len = FixedToInt(bAfter);
- return len;
-}
-
-void Fl_Quartz_Graphics_Driver::ADD_SUFFIX(text_extents, _ATSU)(const char *str8, int n,
- int &dx, int &dy, int &w, int &h)
-{
- Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
- UniChar *txt = mac_Utf8_to_Utf16(str8, n, &n);
- OSStatus err;
- ATSUTextLayout layout;
- ByteCount iSize;
- ATSUAttributeTag iTag;
- ATSUAttributeValuePtr iValuePtr;
-
- // 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;
- // activate the current GC
- iSize = sizeof(CGContextRef);
- iTag = kATSUCGContextTag;
- CGContextRef value = (CGContextRef)gc();
- iValuePtr = &value;
- ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr);
- // now measure the bounding box
- err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n);
- Rect bbox;
- err = ATSUMeasureTextImage(layout, kATSUFromTextBeginning, n, 0, 0, &bbox);
- w = bbox.right - bbox.left;
- h = bbox.bottom - bbox.top;
- dx = bbox.left;
- dy = -bbox.bottom;
- //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::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
-
- ItemCount oFontCount, oCountAgain;
- ATSUFontID *oFontIDs;
- // How many fonts?
- ATSUFontCount (&oFontCount);
- // now allocate space for them...
- oFontIDs = (ATSUFontID *)malloc((oFontCount+1) * sizeof(ATSUFontID));
- ATSUGetFontIDs (oFontIDs, oFontCount, &oCountAgain);
- // Now oFontIDs should contain a list of all the available Unicode fonts
- // Iterate through the list to get each font name
- for (ItemCount idx = 0; idx < oFontCount; idx++)
- {
- // ByteCount actualLength = 0;
- // Ptr oName;
- // How to get the name - Apples docs say call this twice, once to get the length, then again
- // to get the actual name...
- // ATSUFindFontName (oFontIDs[idx], kFontFullName, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage,
- // 0, NULL, &actualLength, NULL);
- // Now actualLength tells us the length of buffer we need
- // oName = (Ptr)malloc(actualLength + 8);
- // But who's got time for that nonsense? Let's just hard code a fixed buffer (urgh!)
- ByteCount actualLength = 511;
- char oName[512];
- ATSUFindFontName (oFontIDs[idx], kFontFullName, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage,
- actualLength, oName, &actualLength, &oCountAgain);
- // bounds check and terminate the returned name
- if(actualLength > 511)
- oName[511] = 0;
- else
- oName[actualLength] = 0;
- Fl::set_font((Fl_Font)(fl_free_font++), fl_strdup(oName));
- // free(oName);
- }
- free(oFontIDs);
- return (Fl_Font)fl_free_font;
-}
-
-#endif // HAS_ATSU