Fix mac-specific STR#2999. Use PostScript font name to ask the system for a font, and full font name

to display a font name.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10011 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2013-10-29 12:46:51 +00:00
parent f947042535
commit 1ad6b09de7
5 changed files with 71 additions and 31 deletions

View File

@ -57,6 +57,7 @@ typedef struct flCocoaRegion {
} *Fl_Region; // a region is the union of a series of rectangles
# include "Fl_Window.H"
# include "../src/Fl_Font.H"
// Some random X equivalents
struct XPoint { int x, y; };
@ -132,6 +133,8 @@ public:
static void screen_work_area(int &X, int &Y, int &W, int &H, int n); // compute work area of a given screen
static int next_marked_length; // next length of marked text after current marked text will have been replaced
static int insertion_point_location(int *px, int *py, int *pheight); // computes window coordinates & height of insertion point
static const int CoreText_threshold; // Mac OS version from which the Core Text API is used to display text
static Fl_Fontdesc* calc_fl_fonts(void); // computes the fl_fonts global variable
private:
static void relink(Fl_Window*, Fl_Window*);
bool subwindow;

View File

@ -60,7 +60,6 @@ public:
# endif
ATSUStyle style;
short ascent, descent, q_width;
char *q_name;
# elif USE_XFT
XftFont* font;
//const char* encoding;

View File

@ -104,6 +104,7 @@ Window fl_window;
Fl_Window *Fl_Window::current_;
int fl_mac_os_version = calc_mac_os_version(); // the version number of the running Mac OS X (e.g., 100604 for 10.6.4)
static SEL inputContextSEL = (fl_mac_os_version >= 100600 ? @selector(inputContext) : @selector(FLinputContext));
Fl_Fontdesc* fl_fonts = Fl_X::calc_fl_fonts();
// forward declarations of variables in this file
static int got_events = 0;

View File

@ -26,6 +26,8 @@ static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 };
static CFMutableDictionaryRef attributes = NULL;
#endif
const int Fl_X::CoreText_threshold = 100500; // this represents Mac OS 10.5
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
next = 0;
# if HAVE_GL
@ -34,10 +36,9 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
// knowWidths = 0;
// OpenGL needs those for its font handling
q_name = strdup(name);
size = Size;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (fl_mac_os_version >= 100500) {//unfortunately, CTFontCreateWithName != NULL on 10.4 also!
if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
fontref = CTFontCreateWithName(str, size, NULL);
CGGlyph glyph[2];
@ -115,9 +116,12 @@ else {
// render our font up-side-down, so when rendered through our inverted CGContext,
// text will appear normal again.
Fixed fsize = IntToFixed(Size);
// ATSUFontID fontID = FMGetFontFromATSFontRef(font);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
ATSUFontID fontID;
ATSUFindFontFromName(name, strlen(name), kFontFullName, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage, &fontID);
#else
ATSUFontID fontID = FMGetFontFromATSFontRef(font);
#endif
// draw the font upside-down... Compensate for fltk/OSX origin differences
ATSUAttributeTag sTag[] = { kATSUFontTag, kATSUSizeTag, kATSUFontMatrixTag };
@ -176,7 +180,7 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() {
*/
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 (fl_mac_os_version >= 100500) {
if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
CFRelease(fontref);
for (unsigned i = 0; i < sizeof(width)/sizeof(float*); i++) {
if (width[i]) free(width[i]);
@ -187,23 +191,42 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() {
////////////////////////////////////////////////////////////////
static Fl_Fontdesc built_in_table[] = {
{"Arial"},
{"Arial Bold"},
{"Arial Italic"},
{"Arial Bold Italic"},
{"Courier New"},
{"Courier New Bold"},
{"Courier New Italic"},
{"Courier New Bold Italic"},
{"Times New Roman"},
{"Times New Roman Bold"},
{"Times New Roman Italic"},
{"Times New Roman Bold Italic"},
static Fl_Fontdesc built_in_table_PS[] = { // PostScript font names preferred when Mac OS ≥ 10.5
{"ArialMT"},
{"Arial-BoldMT"},
{"Arial-ItalicMT"},
{"Arial-BoldItalicMT"},
{"CourierNewPSMT"},
{"CourierNewPS-BoldMT"},
{"CourierNewPS-ItalicMT"},
{"CourierNewPS-BoldItalicMT"},
{"TimesNewRomanPSMT"},
{"TimesNewRomanPS-BoldMT"},
{"TimesNewRomanPS-ItalicMT"},
{"TimesNewRomanPS-BoldItalicMT"},
{"Symbol"},
{"Monaco"},
{"Andale Mono"}, // there is no bold Monaco font on standard Mac
{"Webdings"},
{"AndaleMono"}, // there is no bold Monaco font on standard Mac
{"ZapfDingbatsITC"}
};
static Fl_Fontdesc built_in_table_full[] = { // full font names used before 10.5
{"Arial"},
{"Arial Bold"},
{"Arial Italic"},
{"Arial Bold Italic"},
{"Courier New"},
{"Courier New 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"}
};
static UniChar *utfWbuf = 0;
@ -223,7 +246,10 @@ static UniChar *mac_Utf8_to_Utf16(const char *txt, int len, int *new_len)
return utfWbuf;
} // mac_Utf8_to_Utf16
Fl_Fontdesc* fl_fonts = built_in_table;
Fl_Fontdesc* Fl_X::calc_fl_fonts(void)
{
return (fl_mac_os_version >= Fl_X::CoreText_threshold ? built_in_table_PS : built_in_table_full);
}
static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) {
Fl_Fontdesc* s = fl_fonts+fnum;
@ -287,7 +313,7 @@ static CGFloat surrogate_width(const UniChar *txt, Fl_Font_Descriptor *fl_fontsi
static double fl_mac_width(const UniChar* txt, int n, Fl_Font_Descriptor *fl_fontsize) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (fl_mac_os_version >= 100500) {
if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
double retval = 0;
UniChar uni;
int i;
@ -302,7 +328,7 @@ if (fl_mac_os_version >= 100500) {
// 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_fontsize->q_name);
//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;
@ -406,7 +432,7 @@ void Fl_Quartz_Graphics_Driver::text_extents(const char *str8, int n, int &dx, i
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
UniChar *txt = mac_Utf8_to_Utf16(str8, n, &n);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (fl_mac_os_version >= 100500) {
if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
CFStringRef str16 = CFStringCreateWithCharactersNoCopy(NULL, txt, n, kCFAllocatorNull);
CFDictionarySetValue (attributes, kCTFontAttributeName, fl_fontsize->fontref);
CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes);
@ -474,7 +500,7 @@ static void fl_mac_draw(const char *str, int n, float x, float y, Fl_Graphics_Dr
// convert to UTF-16 first
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (fl_mac_os_version >= 100500) {
if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
CFStringRef str16 = CFStringCreateWithCharactersNoCopy(NULL, uniStr, n, kCFAllocatorNull);
if (str16 == NULL) return; // shd not happen
CGColorRef color = flcolortocgcolor(driver->color());

View File

@ -29,15 +29,27 @@
// 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 127 // sizeof(Fl_Font.fontname)-1
#define ENDOFBUFFER sizeof(fl_fonts->fontname)-1
// turn a stored font name into a pretty name:
const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
Fl_Fontdesc *f = fl_fonts + fnum;
if (!f->fontname[0]) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
CFStringRef cfname = CFStringCreateWithCString(NULL, f->name, kCFStringEncodingUTF8);
CTFontRef ctfont = CTFontCreateWithName(cfname, 0, NULL);
CFRelease(cfname);
cfname = CTFontCopyFullName(ctfont);
CFRelease(ctfont);
CFStringGetCString(cfname, f->fontname, ENDOFBUFFER, kCFStringEncodingUTF8);
CFRelease(cfname);
}
else
#endif
strlcpy(f->fontname, f->name, ENDOFBUFFER);
const char* p = f->name;
if (!p || !*p) {if (ap) *ap = 0; return "";}
strlcpy(f->fontname, p, ENDOFBUFFER);
int type = 0;
if (strstr(f->name, "Bold")) type |= FL_BOLD;
if (strstr(f->name, "Italic")) type |= FL_ITALIC;
@ -61,8 +73,7 @@ Fl_Font Fl::set_fonts(const char* xstarname) {
if (fl_free_font > FL_FREE_FONT) return (Fl_Font)fl_free_font; // if already called
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if(fl_mac_os_version >= 100500) {
//if(CTFontCreateWithFontDescriptor != NULL) {// CTFontCreateWithFontDescriptor != NULL on 10.4 also!
if(fl_mac_os_version >= Fl_X::CoreText_threshold) {
int value[1] = {1};
CFDictionaryRef dict = CFDictionaryCreate(NULL,
(const void **)kCTFontCollectionRemoveDuplicatesOption,
@ -77,9 +88,9 @@ if(fl_mac_os_version >= 100500) {
for (i = 0; i < count; i++) {
CTFontDescriptorRef fdesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arrayref, i);
CTFontRef font = CTFontCreateWithFontDescriptor(fdesc, 0., NULL);
CFStringRef cfname = CTFontCopyFullName(font);
CFStringRef cfname = CTFontCopyPostScriptName(font);
CFRelease(font);
static char fname[100];
static char fname[200];
CFStringGetCString(cfname, fname, sizeof(fname), kCFStringEncodingUTF8);
tabfontnames[i] = strdup(fname); // never free'ed
CFRelease(cfname);