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.cxx561
1 files changed, 0 insertions, 561 deletions
diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
deleted file mode 100644
index d373c1768..000000000
--- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
+++ /dev/null
@@ -1,561 +0,0 @@
-//
-// MacOS font selection routines for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2026 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
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#include "Fl_Quartz_Graphics_Driver.H"
-#include "Fl_Font.H"
-#include <math.h>
-#include <FL/Fl.H>
-#include <FL/platform.H>
-#include <FL/fl_utf8.h> // for fl_utf8toUtf16()
-#include <FL/fl_string_functions.h> // fl_strdup()
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
-const NSUInteger kCTFontOrientationHorizontal = kCTFontHorizontalOrientation;
-#endif
-
-Fl_Fontdesc* fl_fonts = NULL;
-
-static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 };
-
-static int fl_free_font = FL_FREE_FONT;
-
-
-static CFMutableDictionaryRef attributes = NULL;
-
-static Fl_Fontdesc built_in_table_PS[] = { // PostScript font names preferred when Mac OS ≥ 10.5
- {"ArialMT"},
- {"Arial-BoldMT"},
- {"Arial-ItalicMT"},
- {"Arial-BoldItalicMT"},
- {"Courier"},
- {"Courier-Bold"},
- {"Courier-Oblique"},
- {"Courier-BoldOblique"},
- {"TimesNewRomanPSMT"},
- {"TimesNewRomanPS-BoldMT"},
- {"TimesNewRomanPS-ItalicMT"},
- {"TimesNewRomanPS-BoldItalicMT"},
- {"Symbol"},
- {"Monaco"},
- {"AndaleMono"}, // there is no bold Monaco font on standard Mac
- {"ZapfDingbatsITC"}
-};
-
-
-// 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
-// the header files I decided to store this value in the last character
-// of the font name array.
-#define ENDOFBUFFER sizeof(fl_fonts->fontname)-1
-
-// turn a stored font name into a pretty name:
-const char* Fl_Quartz_Graphics_Driver::get_font_name(Fl_Font fnum, int* ap) {
- if (!fl_fonts) fl_fonts = calc_fl_fonts();
- Fl_Fontdesc *f = fl_fonts + fnum;
- if (!f->fontname[0]) {
- this->set_fontname_in_fontdesc(f);
- const char* thisFont = f->name;
- if (!thisFont || !*thisFont) {if (ap) *ap = 0; return "";}
- int type = 0;
- if (strstr(f->name, "Bold")) type |= FL_BOLD;
- if (strstr(f->name, "Italic") || strstr(f->name, "Oblique")) type |= FL_ITALIC;
- f->fontname[ENDOFBUFFER] = (char)type;
- }
- if (ap) *ap = f->fontname[ENDOFBUFFER];
- return f->fontname;
-}
-
-
-int Fl_Quartz_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
- static int array[128];
- if (!fl_fonts) fl_fonts = calc_fl_fonts();
- Fl_Fontdesc *s = fl_fonts+fnum;
- if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
- int cnt = 0;
-
- // ATS supports all font size
- array[0] = 0;
- sizep = array;
- cnt = 1;
-
- return cnt;
-}
-
-Fl_Quartz_Font_Descriptor::Fl_Quartz_Font_Descriptor(const char* name, Fl_Fontsize Size) : Fl_Font_Descriptor(name, Size) {
- fontref = NULL;
- Fl_Quartz_Graphics_Driver *driver = (Fl_Quartz_Graphics_Driver*)&Fl_Graphics_Driver::default_driver();
- driver->descriptor_init(name, size, this);
-}
-
-
-Fl_Quartz_Font_Descriptor::~Fl_Quartz_Font_Descriptor() {
-/*
-#if HAVE_GL
- // ++ todo: remove OpenGL font allocations
-// 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
-// of "free" routine pointer, or a subclass?
-#endif
- */
- if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL);
- if (fontref) {
- CFRelease(fontref);
- for (unsigned i = 0; i < sizeof(width)/sizeof(float*); i++) {
- if (width[i]) free(width[i]);
- }
- }
-}
-
-
-static UniChar *utfWbuf = 0;
-static unsigned utfWlen = 0;
-
-static UniChar *mac_Utf8_to_Utf16(const char *txt, int len, int *new_len)
-{
- unsigned wlen = fl_utf8toUtf16(txt, len, (unsigned short*)utfWbuf, utfWlen);
- if (wlen >= utfWlen)
- {
- utfWlen = wlen + 100;
- if (utfWbuf) free(utfWbuf);
- utfWbuf = (UniChar*)malloc((utfWlen)*sizeof(UniChar));
- wlen = fl_utf8toUtf16(txt, len, (unsigned short*)utfWbuf, utfWlen);
- }
- *new_len = wlen;
- return utfWbuf;
-}
-
-
-static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) {
- if (!fl_fonts) fl_fonts = Fl_Graphics_Driver::default_driver().calc_fl_fonts();
- 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)
- if (f->size == size) return f;
- f = new Fl_Quartz_Font_Descriptor(s->name, size);
- f->next = s->first;
- s->first = f;
- return f;
-}
-
-
-void Fl_Quartz_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
- if (fnum == -1) {
- Fl_Graphics_Driver::font(0, 0);
- return;
- }
- Fl_Graphics_Driver::font(fnum, size);
- font_descriptor( find(fnum, size) );
-}
-
-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 (Fl_Quartz_Font_Descriptor*)font_descriptor();
-}
-
-int Fl_Quartz_Graphics_Driver::height() {
- Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
- return fl_fontsize->ascent + fl_fontsize->descent;
-}
-
-int Fl_Quartz_Graphics_Driver::descent() {
- Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor();
- return fl_fontsize->descent + 1;
-}
-
-void Fl_Quartz_Graphics_Driver::draw(const char* str, int n, int x, int y) {
- draw(str, n, (float)x, y+0.5f);
-}
-
-void Fl_Quartz_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
- CGContextSaveGState(gc_);
- CGContextTranslateCTM(gc_, x, y);
- CGContextRotateCTM(gc_, - angle*(M_PI/180) );
- draw(str, n, 0, 0);
- CGContextRestoreGState(gc_);
-}
-
-void Fl_Quartz_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
- int dx, dy, w, h;
- text_extents(c, n, dx, dy, w, h);
- draw(c, n, x - w - dx, y);
-}
-
-double Fl_Quartz_Graphics_Driver::width(const char* txt, int n) {
- if (n == 0) return 0;
- int len1 = fl_utf8len1(*txt);
- if (len1 > 0 && n > len1) { // a text with several codepoints: compute its typographical width
- CFStringRef str = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n, kCFStringEncodingUTF8, false);
- if (str) {
- CFDictionarySetValue(attributes, kCTFontAttributeName, valid_font_descriptor()->fontref);
- CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str, attributes);
- CFRelease(str);
- CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
- CFRelease(mastr);
- double d = CTLineGetTypographicBounds(ctline, NULL, NULL, NULL);
- CFRelease(ctline);
- return d;
- }
- }
- int wc_len = n;
- UniChar *uniStr = mac_Utf8_to_Utf16(txt, n, &wc_len);
- return width(uniStr, wc_len);
-}
-
-double Fl_Quartz_Graphics_Driver::width(unsigned int wc) {
- UniChar utf16[3];
- int l = 1;
- if (wc <= 0xFFFF) {
- *utf16 = wc;
- }
- else {
- l = (int)fl_ucs_to_Utf16(wc, utf16, 3);
- }
- return width(utf16, l);
-}
-
-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; }
- if (ctfont) {
- cfname = CTFontCopyFullName(ctfont);
- CFRelease(ctfont);
- if (cfname) {
- CFStringGetCString(cfname, f->fontname, ENDOFBUFFER, kCFStringEncodingUTF8);
- CFRelease(cfname);
- }
- }
- if (!cfname) strlcpy(f->fontname, f->name, ENDOFBUFFER);
-}
-
-const char *Fl_Quartz_Graphics_Driver::font_name(int num) {
- if (!fl_fonts) fl_fonts = calc_fl_fonts();
- return fl_fonts[num].name;
-}
-
-void Fl_Quartz_Graphics_Driver::font_name(int num, const char *name) {
- Fl_Fontdesc *s = fl_fonts + num;
- if (s->name) {
- if (!strcmp(s->name, name)) {s->name = name; return;}
- for (Fl_Font_Descriptor* f = s->first; f;) {
- Fl_Font_Descriptor* n = f->next; delete f; f = n;
- }
- s->first = 0;
- }
- s->name = name;
- s->fontname[0] = 0;
- s->first = 0;
-}
-
-
-Fl_Fontdesc* Fl_Quartz_Graphics_Driver::calc_fl_fonts(void)
-{
- return built_in_table_PS;
-}
-
-
-void Fl_Quartz_Graphics_Driver::descriptor_init(const char* name,
- Fl_Fontsize size, Fl_Quartz_Font_Descriptor *d)
-{
- CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
- d->fontref = CTFontCreateWithName(str, size, NULL);
- CGGlyph glyph[2];
- const UniChar A[2]={'W','.'};
- CTFontGetGlyphsForCharacters(d->fontref, A, glyph, 2);
- CGSize advances[2];
- double w;
- CTFontGetAdvancesForGlyphs(d->fontref, kCTFontOrientationHorizontal, glyph, advances, 2);
- w = advances[0].width;
- if ( fabs(advances[0].width - advances[1].width) < 1E-2 ) {//this is a fixed-width font
- // slightly rescale fixed-width fonts so the character width has an integral value
- CFRelease(d->fontref);
- CGFloat fsize = size / ( w/floor(w + 0.5) );
- d->fontref = CTFontCreateWithName(str, fsize, NULL);
- w = CTFontGetAdvancesForGlyphs(d->fontref, kCTFontOrientationHorizontal, glyph, NULL, 1);
- }
- CFRelease(str);
- d->ascent = (short)(CTFontGetAscent(d->fontref) + 0.5);
- d->descent = (short)(CTFontGetDescent(d->fontref) + 0.5);
- d->q_width = w + 0.5;
- for (unsigned i = 0; i < sizeof(d->width)/sizeof(float*); i++) d->width[i] = NULL;
- if (!attributes) {
- static CFNumberRef zero_ref;
- float zero = 0.;
- zero_ref = CFNumberCreate(NULL, kCFNumberFloat32Type, &zero);
- // deactivate kerning for all fonts, so that string width = sum of character widths
- // which allows fast fl_width() implementation.
- attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
- 3,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue (attributes, kCTKernAttributeName, zero_ref);
- }
- if (d->ascent == 0) { // this may happen with some third party fonts
- CFDictionarySetValue (attributes, kCTFontAttributeName, d->fontref);
- CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, CFSTR("Wj"), attributes);
- CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
- CFRelease(mastr);
- CGFloat fascent, fdescent;
- CTLineGetTypographicBounds(ctline, &fascent, &fdescent, NULL);
- CFRelease(ctline);
- d->ascent = (short)(fascent + 0.5);
- d->descent = (short)(fdescent + 0.5);
- }
-}
-
-// returns width of a pair of UniChar's in the surrogate range
-static CGFloat surrogate_width(const UniChar *txt, Fl_Quartz_Font_Descriptor *fl_fontsize)
-{
- CTFontRef font2 = fl_fontsize->fontref;
- bool must_release = false;
- CGGlyph glyphs[2];
- bool b = CTFontGetGlyphsForCharacters(font2, txt, glyphs, 2);
- CGSize a;
- if(!b) { // the current font doesn't contain this char
- CFStringRef str = CFStringCreateWithCharactersNoCopy(NULL, txt, 2, kCFAllocatorNull);
- // find a font that contains it
- font2 = CTFontCreateForString(font2, str, CFRangeMake(0,2));
- must_release = true;
- CFRelease(str);
- b = CTFontGetGlyphsForCharacters(font2, txt, glyphs, 2);
- }
- if (b) CTFontGetAdvancesForGlyphs(font2, kCTFontOrientationHorizontal, glyphs, &a, 1);
- else a.width = fl_fontsize->q_width;
- if(must_release) CFRelease(font2);
- return a.width;
-}
-
-static CGFloat variation_selector_width(CFStringRef str16, Fl_Quartz_Font_Descriptor *fl_fontsize)
-{
- CGFloat retval;
- CFDictionarySetValue(attributes, kCTFontAttributeName, fl_fontsize->fontref);
- CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes);
- CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
- CFRelease(mastr);
- retval = CTLineGetOffsetForStringIndex(ctline, 2, NULL);
- CFRelease(ctline);
- return retval;
-}
-
-double Fl_Quartz_Graphics_Driver::width(const UniChar* txt, int n)
-{
- double retval = 0;
- UniChar uni;
- int i;
- 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
- retval += surrogate_width(&txt[i], fl_fontsize);
- i++; // because a pair of UniChar's represent a single character
- continue;
- }
- if (i+1 < n && txt[i+1] >= 0xFE00 && txt[i+1] <= 0xFE0F) { // handles variation selectors
- CFStringRef substr = CFStringCreateWithCharacters(NULL, txt + i, 2);
- retval += variation_selector_width(substr, fl_fontsize);
- CFRelease(substr);
- i++;
- continue;
- }
- const int block = 0x10000 / (sizeof(fl_fontsize->width)/sizeof(float*)); // block size
- // r: index of the character block containing uni
- unsigned int r = uni >> 7; // change 7 if sizeof(width) is changed
- if (!fl_fontsize->width[r]) { // this character block has not been hit yet
- //fprintf(stderr,"r=%d size=%d name=%s\n",r,fl_fontsize->size,fl_fonts[fl_font()].name);
- // allocate memory to hold width of each character in the block
- fl_fontsize->width[r] = (float*) malloc(sizeof(float) * block);
- UniChar ii = r * block;
- CGSize advance_size;
- CGGlyph glyph;
- for (int j = 0; j < block; j++) { // loop over the block
- // ii spans all characters of this block
- bool b = CTFontGetGlyphsForCharacters(fl_fontsize->fontref, &ii, &glyph, 1);
- if (b)
- CTFontGetAdvancesForGlyphs(fl_fontsize->fontref, kCTFontOrientationHorizontal, &glyph, &advance_size, 1);
- else
- advance_size.width = -1e9; // calculate this later
- // the width of one character of this block of characters
- fl_fontsize->width[r][j] = advance_size.width;
- ii++;
- }
- }
- // sum the widths of all characters of txt
- double wdt = fl_fontsize->width[r][uni & (block-1)];
- if (wdt == -1e9) {
- CGSize advance_size;
- CGGlyph glyph;
- CTFontRef font2 = fl_fontsize->fontref;
- bool must_release = false;
- bool b = CTFontGetGlyphsForCharacters(font2, &uni, &glyph, 1);
- if (!b) { // the current font doesn't contain this char
- CFStringRef str = CFStringCreateWithCharactersNoCopy(NULL, &uni, 1, kCFAllocatorNull);
- // find a font that contains it
- font2 = CTFontCreateForString(font2, str, CFRangeMake(0,1));
- must_release = true;
- CFRelease(str);
- b = CTFontGetGlyphsForCharacters(font2, &uni, &glyph, 1);
- }
- if (b) CTFontGetAdvancesForGlyphs(font2, kCTFontOrientationHorizontal, &glyph, &advance_size, 1);
- else advance_size.width = 0.;
- // the width of the 'uni' character
- wdt = fl_fontsize->width[r][uni & (block-1)] = advance_size.width;
- if (must_release) CFRelease(font2);
- }
- retval += wdt;
- }
- return retval;
-}
-
-
-// text extent calculation
-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);
- CFStringRef str16 = CFStringCreateWithCharactersNoCopy(NULL, txt, n, kCFAllocatorNull);
- CFDictionarySetValue (attributes, kCTFontAttributeName, fl_fontsize->fontref);
- CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes);
- CFRelease(str16);
- CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
- CFRelease(mastr);
- CGContextSetTextPosition(gc_, 0, 0);
- CGContextSetShouldAntialias(gc_, true);
- CGRect rect = CTLineGetImageBounds(ctline, gc_);
- CGContextSetShouldAntialias(gc_, false);
- CFRelease(ctline);
- dx = floor(rect.origin.x + 0.5);
- dy = floor(- rect.origin.y - rect.size.height + 0.5);
- w = rect.size.width + 0.5;
- h = rect.size.height + 0.5;
-}
-
-
-static CGColorRef flcolortocgcolor(Fl_Color i)
-{
- uchar r, g, b;
- Fl::get_color(i, r, g, b);
- CGFloat components[4] = {r/255.0f, g/255.0f, b/255.0f, 1.};
- static CGColorSpaceRef cspace = NULL;
- if (cspace == NULL) {
- cspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
- }
- return CGColorCreate(cspace, components);
-}
-
-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
- UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
- CGContextRef gc = (CGContextRef)this->gc();
- CFMutableStringRef str16 = CFStringCreateMutableWithExternalCharactersNoCopy(NULL, uniStr, n, n, kCFAllocatorNull);
- if (str16 == NULL) return; // shd not happen
- CGColorRef color = flcolortocgcolor(this->color());
- CFDictionarySetValue (attributes, kCTFontAttributeName, fl_fontsize->fontref);
- CFDictionarySetValue (attributes, kCTForegroundColorAttributeName, color);
- CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes);
- CFRelease(str16);
- CFRelease(color);
- CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
- CFRelease(mastr);
- CGContextSetTextMatrix(gc, font_mx);
- CGContextSetTextPosition(gc, x, y);
- CGContextSetShouldAntialias(gc, true);
- CTLineDraw(ctline, gc);
- CGContextSetShouldAntialias(gc, false);
- CFRelease(ctline);
-}
-
-// Skip over bold/italic/oblique qualifiers part of PostScript font names
-// Example:
-// input: '-Regular_Light-Condensed'
-// return: '_Light-Condensed'
-//
-static char *skip(char *p, int& derived)
-{
- // 0 5 10
- // | | |
- if (strncmp(p, "-BoldItalic", 11) == 0) { p += 11; derived = 3; }
- else if (strncmp(p, "-BoldOblique", 12) == 0) { p += 12; derived = 3; }
- else if (strncmp(p, "-Bold", 5) == 0) { p += 5; derived = 1; }
- else if (strncmp(p, "-Italic", 7) == 0) { p += 7; derived = 2; }
- else if (strncmp(p, "-Oblique", 8) == 0) { p += 8; derived = 2; }
- else if (strncmp(p, "-Regular", 8) == 0) { p += 8; }
- else if (strncmp(p, "-Roman", 6) == 0) { p += 6; }
- return p;
-}
-
-static int name_compare(const void *a, const void *b)
-{
- /* Compare PostScript font names.
- First compare font family names ignoring bold, italic and oblique qualifiers.
- When families are identical, order them according to regular, bold, italic, bolditalic.
- */
- char *n1 = *(char**)a;
- char *n2 = *(char**)b;
- int derived1 = 0;
- int derived2 = 0;
- while (true) {
- if (*n1 == '-') n1 = skip(n1, derived1);
- if (*n2 == '-') n2 = skip(n2, derived2);
- if (*n1 < *n2) return -1;
- if (*n1 > *n2) return +1;
- if (*n1 == 0) {
- return derived1 - derived2;
- }
- n1++; n2++;
- }
-}
-
-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
-
- int value[1] = {1};
- CFDictionaryRef dict = CFDictionaryCreate(NULL,
- (const void **)kCTFontCollectionRemoveDuplicatesOption,
- (const void **)&value, 1, NULL, NULL);
- CTFontCollectionRef fcref = CTFontCollectionCreateFromAvailableFonts(dict);
- CFRelease(dict);
- CFArrayRef arrayref = CTFontCollectionCreateMatchingFontDescriptors(fcref);
- CFRelease(fcref);
- CFIndex count = CFArrayGetCount(arrayref);
- CFIndex i;
- char **tabfontnames = new char*[count];
- for (i = 0; i < count; i++) {
- CTFontDescriptorRef fdesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arrayref, i);
- CTFontRef font = CTFontCreateWithFontDescriptor(fdesc, 0., NULL);
- CFStringRef cfname = CTFontCopyPostScriptName(font);
- CFRelease(font);
- CFDataRef cfdata = CFStringCreateExternalRepresentation(NULL, cfname, kCFStringEncodingUTF8, '?');
- CFIndex l = CFDataGetLength(cfdata);
- tabfontnames[i] = (char*)malloc(l+1); // never free'ed
- memcpy(tabfontnames[i], CFDataGetBytePtr(cfdata), l);
- tabfontnames[i][l] = 0;
- CFRelease(cfdata);
- CFRelease(cfname);
- }
- CFRelease(arrayref);
- qsort(tabfontnames, count, sizeof(char*), name_compare);
- for (i = 0; i < count; i++) {
- Fl::set_font((Fl_Font)(fl_free_font++), tabfontnames[i]);
- }
- delete[] tabfontnames;
- return (Fl_Font)fl_free_font;
-}