@@ -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; | |||