diff --git a/build/macosx/platform_specific_code/juce_mac_Fonts.mm b/build/macosx/platform_specific_code/juce_mac_Fonts.mm index 1858df063c..03193938d2 100644 --- a/build/macosx/platform_specific_code/juce_mac_Fonts.mm +++ b/build/macosx/platform_specific_code/juce_mac_Fonts.mm @@ -33,129 +33,46 @@ // compiled on its own). #ifdef JUCE_INCLUDED_FILE -//============================================================================== -static OSStatus pascal CubicMoveTo (const Float32Point *pt, - void* callBackDataPtr) -{ - Path* const p = (Path*) callBackDataPtr; - p->startNewSubPath (pt->x, pt->y); - - return noErr; -} - -static OSStatus pascal CubicLineTo (const Float32Point *pt, - void* callBackDataPtr) -{ - Path* const p = (Path*) callBackDataPtr; - p->lineTo (pt->x, pt->y); - - return noErr; -} - -static OSStatus pascal CubicCurveTo (const Float32Point *pt1, - const Float32Point *pt2, - const Float32Point *pt3, - void* callBackDataPtr) -{ - Path* const p = (Path*) callBackDataPtr; - p->cubicTo (pt1->x, pt1->y, - pt2->x, pt2->y, - pt3->x, pt3->y); - - return noErr; -} - -static OSStatus pascal CubicClosePath (void* callBackDataPtr) -{ - Path* const p = (Path*) callBackDataPtr; - p->closeSubPath(); - - return noErr; -} //============================================================================== -class ATSFontHelper +class FontHelper { - ATSUFontID fontId; - ATSUStyle style; - - ATSCubicMoveToUPP moveToProc; - ATSCubicLineToUPP lineToProc; - ATSCubicCurveToUPP curveToProc; - ATSCubicClosePathUPP closePathProc; - - float totalSize, ascent; - - TextToUnicodeInfo encodingInfo; + NSFont* font; public: String name; bool isBold, isItalic; - float fontSize; + float fontSize, totalSize, ascent; int refCount; - ATSFontHelper (const String& name_, - const bool bold_, - const bool italic_, - const float size_) - : fontId (0), + FontHelper (const String& name_, + const bool bold_, + const bool italic_, + const float size_) + : font (0), name (name_), isBold (bold_), isItalic (italic_), fontSize (size_), refCount (1) { - const char* const nameUtf8 = name_.toUTF8(); - - ATSUFindFontFromName (const_cast (nameUtf8), - strlen (nameUtf8), - kFontFullName, - kFontNoPlatformCode, - kFontNoScriptCode, - kFontNoLanguageCode, - &fontId); - - ATSUCreateStyle (&style); - - ATSUAttributeTag attTypes[] = { kATSUFontTag, - kATSUQDBoldfaceTag, - kATSUQDItalicTag, - kATSUSizeTag }; - - ByteCount attSizes[] = { sizeof (ATSUFontID), - sizeof (Boolean), - sizeof (Boolean), - sizeof (Fixed) }; - - Boolean bold = bold_, italic = italic_; - Fixed size = X2Fix (size_); - - ATSUAttributeValuePtr attValues[] = { &fontId, - &bold, - &italic, - &size }; - - ATSUSetAttributes (style, 4, attTypes, attSizes, attValues); - - moveToProc = NewATSCubicMoveToUPP (CubicMoveTo); - lineToProc = NewATSCubicLineToUPP (CubicLineTo); - curveToProc = NewATSCubicCurveToUPP (CubicCurveTo); - closePathProc = NewATSCubicClosePathUPP (CubicClosePath); - - ascent = 0.0f; - float kern, descent = 0.0f; - getPathAndKerning (T('N'), T('O'), 0, kern, &ascent, &descent); - totalSize = ascent + descent; + font = [NSFont fontWithName: juceStringToNS (name_) size: size_]; + + if (italic_) + font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask]; + + if (bold_) + font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; + + [font retain]; + + ascent = fabsf ([font ascender]); + totalSize = ascent + fabsf ([font descender]); } - ~ATSFontHelper() + ~FontHelper() { - ATSUDisposeStyle (style); - - DisposeATSCubicMoveToUPP (moveToProc); - DisposeATSCubicLineToUPP (lineToProc); - DisposeATSCubicCurveToUPP (curveToProc); - DisposeATSCubicClosePathUPP (closePathProc); + [font release]; } bool getPathAndKerning (const juce_wchar char1, @@ -165,128 +82,65 @@ public: float* ascent, float* descent) { - bool ok = false; - - UniChar buffer[4]; - buffer[0] = T(' '); - buffer[1] = char1; - buffer[2] = char2; - buffer[3] = 0; - - UniCharCount count = kATSUToTextEnd; - ATSUTextLayout layout; - OSStatus err = ATSUCreateTextLayoutWithTextPtr (buffer, - 0, - 2, - 2, - 1, - &count, - &style, - &layout); - if (err == noErr) + const ScopedAutoReleasePool pool; + + if (font == 0 + || ! [[font coveredCharacterSet] longCharacterIsMember: (UTF32Char) char1]) + return false; + + String chars; + chars << ' ' << char1 << char2; + NSTextStorage* textStorage = [[[NSTextStorage alloc] initWithString: juceStringToNS (chars)] autorelease]; + NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; + NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; + [layoutManager addTextContainer: textContainer]; + [textStorage addLayoutManager: layoutManager]; + [textStorage setFont: font]; + + unsigned int glyphIndex = [layoutManager glyphRangeForCharacterRange: NSMakeRange (1, 1) + actualCharacterRange: 0].location; + NSPoint p1 = [layoutManager locationForGlyphAtIndex: glyphIndex]; + NSPoint p2 = [layoutManager locationForGlyphAtIndex: glyphIndex + 1]; + kerning = p2.x - p1.x; + + if (ascent != 0) + *ascent = this->ascent; + + if (descent != 0) + *descent = fabsf ([font descender]); + + if (path != 0) { - ATSUSetTransientFontMatching (layout, true); - - ATSLayoutRecord* layoutRecords; - ItemCount numRecords; - Fixed* deltaYs; - ItemCount numDeltaYs; - - ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout, - 0, - kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, - (void**) &layoutRecords, - &numRecords); - - ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout, - 0, - kATSUDirectDataBaselineDeltaFixedArray, - (void**) &deltaYs, - &numDeltaYs); - - if (numRecords > 2) - { - kerning = (float) (Fix2X (layoutRecords[2].realPos) - - Fix2X (layoutRecords[1].realPos)); - - if (ascent != 0) - { - ATSUTextMeasurement asc; - ByteCount actualSize; + NSBezierPath* bez = [NSBezierPath bezierPath]; + [bez moveToPoint: NSMakePoint (0, 0)]; + [bez appendBezierPathWithGlyph: [layoutManager glyphAtIndex: glyphIndex] + inFont: font]; - ATSUGetLineControl (layout, - 0, - kATSULineAscentTag, - sizeof (ATSUTextMeasurement), - &asc, - &actualSize); - - *ascent = (float) Fix2X (asc); - } - - if (descent != 0) - { - ATSUTextMeasurement desc; - ByteCount actualSize; - - ATSUGetLineControl (layout, - 0, - kATSULineDescentTag, - sizeof (ATSUTextMeasurement), - &desc, - &actualSize); - - *descent = (float) Fix2X (desc); - } - - if (path != 0) - { - OSStatus callbackResult; - - ok = (ATSUGlyphGetCubicPaths (style, - layoutRecords[1].glyphID, - moveToProc, - lineToProc, - curveToProc, - closePathProc, - (void*) path, - &callbackResult) == noErr); - - if (numDeltaYs > 0 && ok) - { - const float dy = (float) Fix2X (deltaYs[1]); - - path->applyTransform (AffineTransform::translation (0.0f, dy)); - } - } - else + for (int i = 0; i < [bez elementCount]; ++i) + { + NSPoint p[3]; + switch ([bez elementAtIndex: i associatedPoints: p]) { - ok = true; + case NSMoveToBezierPathElement: + path->startNewSubPath (p[0].x, -p[0].y); + break; + case NSLineToBezierPathElement: + path->lineTo (p[0].x, -p[0].y); + break; + case NSCurveToBezierPathElement: + path->cubicTo (p[0].x, -p[0].y, p[1].x, -p[1].y, p[2].x, -p[2].y); + break; + case NSClosePathBezierPathElement: + path->closeSubPath(); + break; + default: + jassertfalse + break; } } - - if (deltaYs != 0) - ATSUDirectReleaseLayoutDataArrayPtr (0, kATSUDirectDataBaselineDeltaFixedArray, - (void**) &deltaYs); - - if (layoutRecords != 0) - ATSUDirectReleaseLayoutDataArrayPtr (0, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, - (void**) &layoutRecords); - - ATSUDisposeTextLayout (layout); } - return kerning; - } - - float getAscent() - { - return ascent; - } - - float getTotalHeight() - { - return totalSize; + return kerning != 0; } juce_wchar getDefaultChar() @@ -296,35 +150,35 @@ public: }; //============================================================================== -class ATSFontHelperCache : public Timer, - public DeletedAtShutdown +class FontHelperCache : public Timer, + public DeletedAtShutdown { VoidArray cache; public: - ATSFontHelperCache() + FontHelperCache() { } - ~ATSFontHelperCache() + ~FontHelperCache() { for (int i = cache.size(); --i >= 0;) { - ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i); + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); delete f; } clearSingletonInstance(); } - ATSFontHelper* getFont (const String& name, - const bool bold, - const bool italic, - const float size = 1024) + FontHelper* getFont (const String& name, + const bool bold, + const bool italic, + const float size = 1024) { for (int i = cache.size(); --i >= 0;) { - ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i); + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); if (f->name == name && f->isBold == bold @@ -336,16 +190,16 @@ public: } } - ATSFontHelper* const f = new ATSFontHelper (name, bold, italic, size); + FontHelper* const f = new FontHelper (name, bold, italic, size); cache.add (f); return f; } - void releaseFont (ATSFontHelper* f) + void releaseFont (FontHelper* f) { for (int i = cache.size(); --i >= 0;) { - ATSFontHelper* const f2 = (ATSFontHelper*) cache.getUnchecked(i); + FontHelper* const f2 = (FontHelper*) cache.getUnchecked(i); if (f == f2) { @@ -365,7 +219,7 @@ public: for (int i = cache.size(); --i >= 0;) { - ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i); + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); if (f->refCount == 0) { @@ -378,10 +232,10 @@ public: delete this; } - juce_DeclareSingleton_SingleThreaded_Minimal (ATSFontHelperCache) + juce_DeclareSingleton_SingleThreaded_Minimal (FontHelperCache) }; -juce_ImplementSingleton_SingleThreaded (ATSFontHelperCache) +juce_ImplementSingleton_SingleThreaded (FontHelperCache) //============================================================================== void Typeface::initialiseTypefaceCharacteristics (const String& fontName, @@ -392,11 +246,11 @@ void Typeface::initialiseTypefaceCharacteristics (const String& fontName, // This method is only safe to be called from the normal UI thread.. jassert (MessageManager::getInstance()->isThisTheMessageThread()); - ATSFontHelper* const helper = ATSFontHelperCache::getInstance() - ->getFont (fontName, bold, italic); + FontHelper* const helper = FontHelperCache::getInstance() + ->getFont (fontName, bold, italic); clear(); - setAscent (helper->getAscent() / helper->getTotalHeight()); + setAscent (helper->ascent / helper->totalSize); setName (fontName); setDefaultCharacter (helper->getDefaultChar()); setBold (bold); @@ -408,7 +262,7 @@ void Typeface::initialiseTypefaceCharacteristics (const String& fontName, jassertfalse } - ATSFontHelperCache::getInstance()->releaseFont (helper); + FontHelperCache::getInstance()->releaseFont (helper); } bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() @@ -416,8 +270,8 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() // This method is only safe to be called from the normal UI thread.. jassert (MessageManager::getInstance()->isThisTheMessageThread()); - ATSFontHelper* const helper = ATSFontHelperCache::getInstance() - ->getFont (getName(), isBold(), isItalic()); + FontHelper* const helper = FontHelperCache::getInstance() + ->getFont (getName(), isBold(), isItalic()); Path path; float width; @@ -425,10 +279,10 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0)) { - path.applyTransform (AffineTransform::scale (1.0f / helper->getTotalHeight(), - 1.0f / helper->getTotalHeight())); + path.applyTransform (AffineTransform::scale (1.0f / helper->totalSize, + 1.0f / helper->totalSize)); - addGlyph (character, path, width / helper->getTotalHeight()); + addGlyph (character, path, width / helper->totalSize); for (int i = 0; i < glyphs.size(); ++i) { @@ -437,7 +291,7 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() float kerning; if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0)) { - kerning = (kerning - width) / helper->getTotalHeight(); + kerning = (kerning - width) / helper->totalSize; if (kerning != 0) addKerningPair (character, g->getCharacter(), kerning); @@ -445,7 +299,7 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() if (helper->getPathAndKerning (g->getCharacter(), character, 0, kerning, 0, 0)) { - kerning = kerning / helper->getTotalHeight() - g->width; + kerning = kerning / helper->totalSize - g->width; if (kerning != 0) addKerningPair (g->getCharacter(), character, kerning); @@ -455,68 +309,20 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() foundOne = true; } - ATSFontHelperCache::getInstance()->releaseFont (helper); + FontHelperCache::getInstance()->releaseFont (helper); return foundOne; } +//============================================================================== const StringArray Font::findAllTypefaceNames() throw() { StringArray names; - ATSFontIterator iter; - - if (ATSFontIteratorCreate (kATSFontContextGlobal, - 0, - 0, - kATSOptionFlagsRestrictedScope, - &iter) == noErr) - { - ATSFontRef font; - - while (ATSFontIteratorNext (iter, &font) == noErr) - { - CFStringRef name; - if (ATSFontGetName (font, - kATSOptionFlagsDefault, - &name) == noErr) - { - const String nm (PlatformUtilities::cfStringToJuceString (name)); - - if (nm.isNotEmpty()) - names.add (nm); - - CFRelease (name); - } - } + const ScopedAutoReleasePool pool; + NSArray* fonts = [[NSFontManager sharedFontManager] availableFontFamilies]; - ATSFontIteratorRelease (&iter); - } - - // Use some totuous logic to eliminate bold/italic versions of fonts that we've already got - // a plain version of. This is only necessary because of Carbon's total lack of support - // for dealing with font families... - for (int j = names.size(); --j >= 0;) - { - const char* const endings[] = { " bold", " italic", " bold italic", " bolditalic", - " oblque", " bold oblique", " boldoblique" }; - - for (int i = 0; i < numElementsInArray (endings); ++i) - { - const String ending (endings[i]); - - if (names[j].endsWithIgnoreCase (ending)) - { - const String root (names[j].dropLastCharacters (ending.length()).trimEnd()); - - if (names.contains (root) - || names.contains (root + T(" plain"), true)) - { - names.remove (j); - break; - } - } - } - } + for (int i = 0; i < [fonts count]; ++i) + names.add (nsStringToJuce ((NSString*) [fonts objectAtIndex: i])); names.sort (true); return names; diff --git a/build/macosx/platform_specific_code/juce_mac_NativeIncludes.h b/build/macosx/platform_specific_code/juce_mac_NativeIncludes.h index 304d122b10..5e61bdbb7a 100644 --- a/build/macosx/platform_specific_code/juce_mac_NativeIncludes.h +++ b/build/macosx/platform_specific_code/juce_mac_NativeIncludes.h @@ -1,73 +1,72 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-7 by Raw Material Software ltd. - - ------------------------------------------------------------------------------ - - JUCE can be redistributed and/or modified under the terms of the - GNU General Public License, as published by the Free Software Foundation; - either version 2 of the License, or (at your option) any later version. - - JUCE is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with JUCE; if not, visit www.gnu.org/licenses or write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - - ------------------------------------------------------------------------------ - - If you'd like to release a closed-source product which uses JUCE, commercial - licenses are also available: visit www.rawmaterialsoftware.com/juce for - more information. - - ============================================================================== -*/ - -#ifndef __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ -#define __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ - -/* - This file wraps together all the mac-specific code, so that - we can include all the native headers just once, and compile all our - platform-specific stuff in one big lump, keeping it out of the way of - the rest of the codebase. -*/ - -#include "../../../src/juce_core/basics/juce_StandardHeader.h" - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#include -#include -#include -#include -#include -#include -#include - -#if MACOS_10_4_OR_EARLIER - #include -#endif - -#endif // __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ +#define __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ + +/* + This file wraps together all the mac-specific code, so that + we can include all the native headers just once, and compile all our + platform-specific stuff in one big lump, keeping it out of the way of + the rest of the codebase. +*/ + +#include "../../../src/juce_core/basics/juce_StandardHeader.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#include +#include +#include +#include +#include +#include +#include + +#if MACOS_10_4_OR_EARLIER + #include +#endif + +#endif // __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index fe1e38c1db..7851ac47af 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -593,7 +593,6 @@ #import #import #import -#import #import #import #import @@ -257180,7 +257179,7 @@ public: } if (! outputDevice->setParameters ((unsigned int) sampleRate, - jmax (minChansOut, currentOutputChans.getHighestBit() + 1), + jlimit (minChansOut, maxChansOut, currentOutputChans.getHighestBit() + 1), bufferSize)) { error = outputDevice->error; @@ -257201,7 +257200,7 @@ public: } if (! inputDevice->setParameters ((unsigned int) sampleRate, - jmax (minChansIn, currentInputChans.getHighestBit() + 1), + jlimit (minChansIn, maxChansIn, currentInputChans.getHighestBit() + 1), bufferSize)) { error = inputDevice->error; @@ -269299,127 +269298,44 @@ const String AudioCDBurner::burn (JUCE_NAMESPACE::AudioCDBurner::BurnProgressLis // compiled on its own). #ifdef JUCE_INCLUDED_FILE -static OSStatus pascal CubicMoveTo (const Float32Point *pt, - void* callBackDataPtr) +class FontHelper { - Path* const p = (Path*) callBackDataPtr; - p->startNewSubPath (pt->x, pt->y); - - return noErr; -} - -static OSStatus pascal CubicLineTo (const Float32Point *pt, - void* callBackDataPtr) -{ - Path* const p = (Path*) callBackDataPtr; - p->lineTo (pt->x, pt->y); - - return noErr; -} - -static OSStatus pascal CubicCurveTo (const Float32Point *pt1, - const Float32Point *pt2, - const Float32Point *pt3, - void* callBackDataPtr) -{ - Path* const p = (Path*) callBackDataPtr; - p->cubicTo (pt1->x, pt1->y, - pt2->x, pt2->y, - pt3->x, pt3->y); - - return noErr; -} - -static OSStatus pascal CubicClosePath (void* callBackDataPtr) -{ - Path* const p = (Path*) callBackDataPtr; - p->closeSubPath(); - - return noErr; -} - -class ATSFontHelper -{ - ATSUFontID fontId; - ATSUStyle style; - - ATSCubicMoveToUPP moveToProc; - ATSCubicLineToUPP lineToProc; - ATSCubicCurveToUPP curveToProc; - ATSCubicClosePathUPP closePathProc; - - float totalSize, ascent; - - TextToUnicodeInfo encodingInfo; + NSFont* font; public: String name; bool isBold, isItalic; - float fontSize; + float fontSize, totalSize, ascent; int refCount; - ATSFontHelper (const String& name_, - const bool bold_, - const bool italic_, - const float size_) - : fontId (0), + FontHelper (const String& name_, + const bool bold_, + const bool italic_, + const float size_) + : font (0), name (name_), isBold (bold_), isItalic (italic_), fontSize (size_), refCount (1) { - const char* const nameUtf8 = name_.toUTF8(); - - ATSUFindFontFromName (const_cast (nameUtf8), - strlen (nameUtf8), - kFontFullName, - kFontNoPlatformCode, - kFontNoScriptCode, - kFontNoLanguageCode, - &fontId); + font = [NSFont fontWithName: juceStringToNS (name_) size: size_]; - ATSUCreateStyle (&style); + if (italic_) + font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask]; - ATSUAttributeTag attTypes[] = { kATSUFontTag, - kATSUQDBoldfaceTag, - kATSUQDItalicTag, - kATSUSizeTag }; + if (bold_) + font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; - ByteCount attSizes[] = { sizeof (ATSUFontID), - sizeof (Boolean), - sizeof (Boolean), - sizeof (Fixed) }; + [font retain]; - Boolean bold = bold_, italic = italic_; - Fixed size = X2Fix (size_); - - ATSUAttributeValuePtr attValues[] = { &fontId, - &bold, - &italic, - &size }; - - ATSUSetAttributes (style, 4, attTypes, attSizes, attValues); - - moveToProc = NewATSCubicMoveToUPP (CubicMoveTo); - lineToProc = NewATSCubicLineToUPP (CubicLineTo); - curveToProc = NewATSCubicCurveToUPP (CubicCurveTo); - closePathProc = NewATSCubicClosePathUPP (CubicClosePath); - - ascent = 0.0f; - float kern, descent = 0.0f; - getPathAndKerning (T('N'), T('O'), 0, kern, &ascent, &descent); - totalSize = ascent + descent; + ascent = fabsf ([font ascender]); + totalSize = ascent + fabsf ([font descender]); } - ~ATSFontHelper() + ~FontHelper() { - ATSUDisposeStyle (style); - - DisposeATSCubicMoveToUPP (moveToProc); - DisposeATSCubicLineToUPP (lineToProc); - DisposeATSCubicCurveToUPP (curveToProc); - DisposeATSCubicClosePathUPP (closePathProc); + [font release]; } bool getPathAndKerning (const juce_wchar char1, @@ -269429,128 +269345,65 @@ public: float* ascent, float* descent) { - bool ok = false; - - UniChar buffer[4]; - buffer[0] = T(' '); - buffer[1] = char1; - buffer[2] = char2; - buffer[3] = 0; - - UniCharCount count = kATSUToTextEnd; - ATSUTextLayout layout; - OSStatus err = ATSUCreateTextLayoutWithTextPtr (buffer, - 0, - 2, - 2, - 1, - &count, - &style, - &layout); - if (err == noErr) - { - ATSUSetTransientFontMatching (layout, true); - - ATSLayoutRecord* layoutRecords; - ItemCount numRecords; - Fixed* deltaYs; - ItemCount numDeltaYs; - - ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout, - 0, - kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, - (void**) &layoutRecords, - &numRecords); - - ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout, - 0, - kATSUDirectDataBaselineDeltaFixedArray, - (void**) &deltaYs, - &numDeltaYs); + const ScopedAutoReleasePool pool; - if (numRecords > 2) - { - kerning = (float) (Fix2X (layoutRecords[2].realPos) - - Fix2X (layoutRecords[1].realPos)); + if (font == 0 + || ! [[font coveredCharacterSet] longCharacterIsMember: (UTF32Char) char1]) + return false; - if (ascent != 0) - { - ATSUTextMeasurement asc; - ByteCount actualSize; + String chars; + chars << ' ' << char1 << char2; + NSTextStorage* textStorage = [[[NSTextStorage alloc] initWithString: juceStringToNS (chars)] autorelease]; + NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; + NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; + [layoutManager addTextContainer: textContainer]; + [textStorage addLayoutManager: layoutManager]; + [textStorage setFont: font]; - ATSUGetLineControl (layout, - 0, - kATSULineAscentTag, - sizeof (ATSUTextMeasurement), - &asc, - &actualSize); + unsigned int glyphIndex = [layoutManager glyphRangeForCharacterRange: NSMakeRange (1, 1) + actualCharacterRange: 0].location; + NSPoint p1 = [layoutManager locationForGlyphAtIndex: glyphIndex]; + NSPoint p2 = [layoutManager locationForGlyphAtIndex: glyphIndex + 1]; + kerning = p2.x - p1.x; - *ascent = (float) Fix2X (asc); - } + if (ascent != 0) + *ascent = this->ascent; - if (descent != 0) - { - ATSUTextMeasurement desc; - ByteCount actualSize; + if (descent != 0) + *descent = fabsf ([font descender]); - ATSUGetLineControl (layout, - 0, - kATSULineDescentTag, - sizeof (ATSUTextMeasurement), - &desc, - &actualSize); - - *descent = (float) Fix2X (desc); - } - - if (path != 0) - { - OSStatus callbackResult; - - ok = (ATSUGlyphGetCubicPaths (style, - layoutRecords[1].glyphID, - moveToProc, - lineToProc, - curveToProc, - closePathProc, - (void*) path, - &callbackResult) == noErr); - - if (numDeltaYs > 0 && ok) - { - const float dy = (float) Fix2X (deltaYs[1]); + if (path != 0) + { + NSBezierPath* bez = [NSBezierPath bezierPath]; + [bez moveToPoint: NSMakePoint (0, 0)]; + [bez appendBezierPathWithGlyph: [layoutManager glyphAtIndex: glyphIndex] + inFont: font]; - path->applyTransform (AffineTransform::translation (0.0f, dy)); - } - } - else + for (int i = 0; i < [bez elementCount]; ++i) + { + NSPoint p[3]; + switch ([bez elementAtIndex: i associatedPoints: p]) { - ok = true; + case NSMoveToBezierPathElement: + path->startNewSubPath (p[0].x, -p[0].y); + break; + case NSLineToBezierPathElement: + path->lineTo (p[0].x, -p[0].y); + break; + case NSCurveToBezierPathElement: + path->cubicTo (p[0].x, -p[0].y, p[1].x, -p[1].y, p[2].x, -p[2].y); + break; + case NSClosePathBezierPathElement: + path->closeSubPath(); + break; + default: + jassertfalse + break; } } - - if (deltaYs != 0) - ATSUDirectReleaseLayoutDataArrayPtr (0, kATSUDirectDataBaselineDeltaFixedArray, - (void**) &deltaYs); - - if (layoutRecords != 0) - ATSUDirectReleaseLayoutDataArrayPtr (0, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, - (void**) &layoutRecords); - - ATSUDisposeTextLayout (layout); } - return kerning; - } - - float getAscent() - { - return ascent; - } - - float getTotalHeight() - { - return totalSize; + return kerning != 0; } juce_wchar getDefaultChar() @@ -269559,35 +269412,35 @@ public: } }; -class ATSFontHelperCache : public Timer, - public DeletedAtShutdown +class FontHelperCache : public Timer, + public DeletedAtShutdown { VoidArray cache; public: - ATSFontHelperCache() + FontHelperCache() { } - ~ATSFontHelperCache() + ~FontHelperCache() { for (int i = cache.size(); --i >= 0;) { - ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i); + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); delete f; } clearSingletonInstance(); } - ATSFontHelper* getFont (const String& name, - const bool bold, - const bool italic, - const float size = 1024) + FontHelper* getFont (const String& name, + const bool bold, + const bool italic, + const float size = 1024) { for (int i = cache.size(); --i >= 0;) { - ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i); + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); if (f->name == name && f->isBold == bold @@ -269599,16 +269452,16 @@ public: } } - ATSFontHelper* const f = new ATSFontHelper (name, bold, italic, size); + FontHelper* const f = new FontHelper (name, bold, italic, size); cache.add (f); return f; } - void releaseFont (ATSFontHelper* f) + void releaseFont (FontHelper* f) { for (int i = cache.size(); --i >= 0;) { - ATSFontHelper* const f2 = (ATSFontHelper*) cache.getUnchecked(i); + FontHelper* const f2 = (FontHelper*) cache.getUnchecked(i); if (f == f2) { @@ -269628,7 +269481,7 @@ public: for (int i = cache.size(); --i >= 0;) { - ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i); + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); if (f->refCount == 0) { @@ -269641,10 +269494,10 @@ public: delete this; } - juce_DeclareSingleton_SingleThreaded_Minimal (ATSFontHelperCache) + juce_DeclareSingleton_SingleThreaded_Minimal (FontHelperCache) }; -juce_ImplementSingleton_SingleThreaded (ATSFontHelperCache) +juce_ImplementSingleton_SingleThreaded (FontHelperCache) void Typeface::initialiseTypefaceCharacteristics (const String& fontName, bool bold, @@ -269654,11 +269507,11 @@ void Typeface::initialiseTypefaceCharacteristics (const String& fontName, // This method is only safe to be called from the normal UI thread.. jassert (MessageManager::getInstance()->isThisTheMessageThread()); - ATSFontHelper* const helper = ATSFontHelperCache::getInstance() - ->getFont (fontName, bold, italic); + FontHelper* const helper = FontHelperCache::getInstance() + ->getFont (fontName, bold, italic); clear(); - setAscent (helper->getAscent() / helper->getTotalHeight()); + setAscent (helper->ascent / helper->totalSize); setName (fontName); setDefaultCharacter (helper->getDefaultChar()); setBold (bold); @@ -269670,7 +269523,7 @@ void Typeface::initialiseTypefaceCharacteristics (const String& fontName, jassertfalse } - ATSFontHelperCache::getInstance()->releaseFont (helper); + FontHelperCache::getInstance()->releaseFont (helper); } bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() @@ -269678,8 +269531,8 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() // This method is only safe to be called from the normal UI thread.. jassert (MessageManager::getInstance()->isThisTheMessageThread()); - ATSFontHelper* const helper = ATSFontHelperCache::getInstance() - ->getFont (getName(), isBold(), isItalic()); + FontHelper* const helper = FontHelperCache::getInstance() + ->getFont (getName(), isBold(), isItalic()); Path path; float width; @@ -269687,10 +269540,10 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0)) { - path.applyTransform (AffineTransform::scale (1.0f / helper->getTotalHeight(), - 1.0f / helper->getTotalHeight())); + path.applyTransform (AffineTransform::scale (1.0f / helper->totalSize, + 1.0f / helper->totalSize)); - addGlyph (character, path, width / helper->getTotalHeight()); + addGlyph (character, path, width / helper->totalSize); for (int i = 0; i < glyphs.size(); ++i) { @@ -269699,7 +269552,7 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() float kerning; if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0)) { - kerning = (kerning - width) / helper->getTotalHeight(); + kerning = (kerning - width) / helper->totalSize; if (kerning != 0) addKerningPair (character, g->getCharacter(), kerning); @@ -269707,7 +269560,7 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() if (helper->getPathAndKerning (g->getCharacter(), character, 0, kerning, 0, 0)) { - kerning = kerning / helper->getTotalHeight() - g->width; + kerning = kerning / helper->totalSize - g->width; if (kerning != 0) addKerningPair (g->getCharacter(), character, kerning); @@ -269717,68 +269570,19 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() foundOne = true; } - ATSFontHelperCache::getInstance()->releaseFont (helper); + FontHelperCache::getInstance()->releaseFont (helper); return foundOne; } const StringArray Font::findAllTypefaceNames() throw() { StringArray names; - ATSFontIterator iter; - - if (ATSFontIteratorCreate (kATSFontContextGlobal, - 0, - 0, - kATSOptionFlagsRestrictedScope, - &iter) == noErr) - { - ATSFontRef font; - - while (ATSFontIteratorNext (iter, &font) == noErr) - { - CFStringRef name; - - if (ATSFontGetName (font, - kATSOptionFlagsDefault, - &name) == noErr) - { - const String nm (PlatformUtilities::cfStringToJuceString (name)); - - if (nm.isNotEmpty()) - names.add (nm); - CFRelease (name); - } - } - - ATSFontIteratorRelease (&iter); - } - - // Use some totuous logic to eliminate bold/italic versions of fonts that we've already got - // a plain version of. This is only necessary because of Carbon's total lack of support - // for dealing with font families... - for (int j = names.size(); --j >= 0;) - { - const char* const endings[] = { " bold", " italic", " bold italic", " bolditalic", - " oblque", " bold oblique", " boldoblique" }; - - for (int i = 0; i < numElementsInArray (endings); ++i) - { - const String ending (endings[i]); - - if (names[j].endsWithIgnoreCase (ending)) - { - const String root (names[j].dropLastCharacters (ending.length()).trimEnd()); + const ScopedAutoReleasePool pool; + NSArray* fonts = [[NSFontManager sharedFontManager] availableFontFamilies]; - if (names.contains (root) - || names.contains (root + T(" plain"), true)) - { - names.remove (j); - break; - } - } - } - } + for (int i = 0; i < [fonts count]; ++i) + names.add (nsStringToJuce ((NSString*) [fonts objectAtIndex: i])); names.sort (true); return names;