| @@ -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 <char*> (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; | |||
| @@ -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 <Cocoa/Cocoa.h> | |||
| #import <CoreAudio/HostTime.h> | |||
| #import <CoreAudio/AudioHardware.h> | |||
| #import <CoreMIDI/MIDIServices.h> | |||
| #import <QTKit/QTKit.h> | |||
| #import <WebKit/WebKit.h> | |||
| #import <DiscRecording/DiscRecording.h> | |||
| #import <ApplicationServices/ApplicationServices.h> | |||
| #import <IOKit/IOKitLib.h> | |||
| #import <IOKit/IOCFPlugIn.h> | |||
| #import <IOKit/hid/IOHIDLib.h> | |||
| #import <IOKit/hid/IOHIDKeys.h> | |||
| #import <IOKit/network/IOEthernetInterface.h> | |||
| #import <IOKit/network/IONetworkInterface.h> | |||
| #import <IOKit/network/IOEthernetController.h> | |||
| #import <IOKit/pwr_mgt/IOPMLib.h> | |||
| #include <sys/sysctl.h> | |||
| #include <sys/stat.h> | |||
| #include <sys/dir.h> | |||
| #include <sys/param.h> | |||
| #include <sys/mount.h> | |||
| #include <fnmatch.h> | |||
| #include <utime.h> | |||
| #if MACOS_10_4_OR_EARLIER | |||
| #include <GLUT/glut.h> | |||
| #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 <Cocoa/Cocoa.h> | |||
| #import <CoreAudio/HostTime.h> | |||
| #import <CoreAudio/AudioHardware.h> | |||
| #import <CoreMIDI/MIDIServices.h> | |||
| #import <QTKit/QTKit.h> | |||
| #import <WebKit/WebKit.h> | |||
| #import <DiscRecording/DiscRecording.h> | |||
| #import <IOKit/IOKitLib.h> | |||
| #import <IOKit/IOCFPlugIn.h> | |||
| #import <IOKit/hid/IOHIDLib.h> | |||
| #import <IOKit/hid/IOHIDKeys.h> | |||
| #import <IOKit/network/IOEthernetInterface.h> | |||
| #import <IOKit/network/IONetworkInterface.h> | |||
| #import <IOKit/network/IOEthernetController.h> | |||
| #import <IOKit/pwr_mgt/IOPMLib.h> | |||
| #include <sys/sysctl.h> | |||
| #include <sys/stat.h> | |||
| #include <sys/dir.h> | |||
| #include <sys/param.h> | |||
| #include <sys/mount.h> | |||
| #include <fnmatch.h> | |||
| #include <utime.h> | |||
| #if MACOS_10_4_OR_EARLIER | |||
| #include <GLUT/glut.h> | |||
| #endif | |||
| #endif // __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ | |||
| @@ -593,7 +593,6 @@ | |||
| #import <QTKit/QTKit.h> | |||
| #import <WebKit/WebKit.h> | |||
| #import <DiscRecording/DiscRecording.h> | |||
| #import <ApplicationServices/ApplicationServices.h> | |||
| #import <IOKit/IOKitLib.h> | |||
| #import <IOKit/IOCFPlugIn.h> | |||
| #import <IOKit/hid/IOHIDLib.h> | |||
| @@ -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 <char*> (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; | |||