@@ -33,129 +33,46 @@ | |||||
// compiled on its own). | // compiled on its own). | ||||
#ifdef JUCE_INCLUDED_FILE | #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: | public: | ||||
String name; | String name; | ||||
bool isBold, isItalic; | bool isBold, isItalic; | ||||
float fontSize; | |||||
float fontSize, totalSize, ascent; | |||||
int refCount; | 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_), | name (name_), | ||||
isBold (bold_), | isBold (bold_), | ||||
isItalic (italic_), | isItalic (italic_), | ||||
fontSize (size_), | fontSize (size_), | ||||
refCount (1) | 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, | bool getPathAndKerning (const juce_wchar char1, | ||||
@@ -165,128 +82,65 @@ public: | |||||
float* ascent, | float* ascent, | ||||
float* descent) | 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() | juce_wchar getDefaultChar() | ||||
@@ -296,35 +150,35 @@ public: | |||||
}; | }; | ||||
//============================================================================== | //============================================================================== | ||||
class ATSFontHelperCache : public Timer, | |||||
public DeletedAtShutdown | |||||
class FontHelperCache : public Timer, | |||||
public DeletedAtShutdown | |||||
{ | { | ||||
VoidArray cache; | VoidArray cache; | ||||
public: | public: | ||||
ATSFontHelperCache() | |||||
FontHelperCache() | |||||
{ | { | ||||
} | } | ||||
~ATSFontHelperCache() | |||||
~FontHelperCache() | |||||
{ | { | ||||
for (int i = cache.size(); --i >= 0;) | for (int i = cache.size(); --i >= 0;) | ||||
{ | { | ||||
ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i); | |||||
FontHelper* const f = (FontHelper*) cache.getUnchecked(i); | |||||
delete f; | delete f; | ||||
} | } | ||||
clearSingletonInstance(); | 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;) | 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 | if (f->name == name | ||||
&& f->isBold == bold | && 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); | cache.add (f); | ||||
return f; | return f; | ||||
} | } | ||||
void releaseFont (ATSFontHelper* f) | |||||
void releaseFont (FontHelper* f) | |||||
{ | { | ||||
for (int i = cache.size(); --i >= 0;) | for (int i = cache.size(); --i >= 0;) | ||||
{ | { | ||||
ATSFontHelper* const f2 = (ATSFontHelper*) cache.getUnchecked(i); | |||||
FontHelper* const f2 = (FontHelper*) cache.getUnchecked(i); | |||||
if (f == f2) | if (f == f2) | ||||
{ | { | ||||
@@ -365,7 +219,7 @@ public: | |||||
for (int i = cache.size(); --i >= 0;) | 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) | if (f->refCount == 0) | ||||
{ | { | ||||
@@ -378,10 +232,10 @@ public: | |||||
delete this; | 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, | 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.. | // This method is only safe to be called from the normal UI thread.. | ||||
jassert (MessageManager::getInstance()->isThisTheMessageThread()); | jassert (MessageManager::getInstance()->isThisTheMessageThread()); | ||||
ATSFontHelper* const helper = ATSFontHelperCache::getInstance() | |||||
->getFont (fontName, bold, italic); | |||||
FontHelper* const helper = FontHelperCache::getInstance() | |||||
->getFont (fontName, bold, italic); | |||||
clear(); | clear(); | ||||
setAscent (helper->getAscent() / helper->getTotalHeight()); | |||||
setAscent (helper->ascent / helper->totalSize); | |||||
setName (fontName); | setName (fontName); | ||||
setDefaultCharacter (helper->getDefaultChar()); | setDefaultCharacter (helper->getDefaultChar()); | ||||
setBold (bold); | setBold (bold); | ||||
@@ -408,7 +262,7 @@ void Typeface::initialiseTypefaceCharacteristics (const String& fontName, | |||||
jassertfalse | jassertfalse | ||||
} | } | ||||
ATSFontHelperCache::getInstance()->releaseFont (helper); | |||||
FontHelperCache::getInstance()->releaseFont (helper); | |||||
} | } | ||||
bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() | 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.. | // This method is only safe to be called from the normal UI thread.. | ||||
jassert (MessageManager::getInstance()->isThisTheMessageThread()); | jassert (MessageManager::getInstance()->isThisTheMessageThread()); | ||||
ATSFontHelper* const helper = ATSFontHelperCache::getInstance() | |||||
->getFont (getName(), isBold(), isItalic()); | |||||
FontHelper* const helper = FontHelperCache::getInstance() | |||||
->getFont (getName(), isBold(), isItalic()); | |||||
Path path; | Path path; | ||||
float width; | float width; | ||||
@@ -425,10 +279,10 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() | |||||
if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0)) | 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) | for (int i = 0; i < glyphs.size(); ++i) | ||||
{ | { | ||||
@@ -437,7 +291,7 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() | |||||
float kerning; | float kerning; | ||||
if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0)) | if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0)) | ||||
{ | { | ||||
kerning = (kerning - width) / helper->getTotalHeight(); | |||||
kerning = (kerning - width) / helper->totalSize; | |||||
if (kerning != 0) | if (kerning != 0) | ||||
addKerningPair (character, g->getCharacter(), kerning); | 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)) | 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) | if (kerning != 0) | ||||
addKerningPair (g->getCharacter(), character, kerning); | addKerningPair (g->getCharacter(), character, kerning); | ||||
@@ -455,68 +309,20 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() | |||||
foundOne = true; | foundOne = true; | ||||
} | } | ||||
ATSFontHelperCache::getInstance()->releaseFont (helper); | |||||
FontHelperCache::getInstance()->releaseFont (helper); | |||||
return foundOne; | return foundOne; | ||||
} | } | ||||
//============================================================================== | |||||
const StringArray Font::findAllTypefaceNames() throw() | const StringArray Font::findAllTypefaceNames() throw() | ||||
{ | { | ||||
StringArray names; | 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); | names.sort (true); | ||||
return names; | 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 <QTKit/QTKit.h> | ||||
#import <WebKit/WebKit.h> | #import <WebKit/WebKit.h> | ||||
#import <DiscRecording/DiscRecording.h> | #import <DiscRecording/DiscRecording.h> | ||||
#import <ApplicationServices/ApplicationServices.h> | |||||
#import <IOKit/IOKitLib.h> | #import <IOKit/IOKitLib.h> | ||||
#import <IOKit/IOCFPlugIn.h> | #import <IOKit/IOCFPlugIn.h> | ||||
#import <IOKit/hid/IOHIDLib.h> | #import <IOKit/hid/IOHIDLib.h> | ||||
@@ -257180,7 +257179,7 @@ public: | |||||
} | } | ||||
if (! outputDevice->setParameters ((unsigned int) sampleRate, | if (! outputDevice->setParameters ((unsigned int) sampleRate, | ||||
jmax (minChansOut, currentOutputChans.getHighestBit() + 1), | |||||
jlimit (minChansOut, maxChansOut, currentOutputChans.getHighestBit() + 1), | |||||
bufferSize)) | bufferSize)) | ||||
{ | { | ||||
error = outputDevice->error; | error = outputDevice->error; | ||||
@@ -257201,7 +257200,7 @@ public: | |||||
} | } | ||||
if (! inputDevice->setParameters ((unsigned int) sampleRate, | if (! inputDevice->setParameters ((unsigned int) sampleRate, | ||||
jmax (minChansIn, currentInputChans.getHighestBit() + 1), | |||||
jlimit (minChansIn, maxChansIn, currentInputChans.getHighestBit() + 1), | |||||
bufferSize)) | bufferSize)) | ||||
{ | { | ||||
error = inputDevice->error; | error = inputDevice->error; | ||||
@@ -269299,127 +269298,44 @@ const String AudioCDBurner::burn (JUCE_NAMESPACE::AudioCDBurner::BurnProgressLis | |||||
// compiled on its own). | // compiled on its own). | ||||
#ifdef JUCE_INCLUDED_FILE | #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: | public: | ||||
String name; | String name; | ||||
bool isBold, isItalic; | bool isBold, isItalic; | ||||
float fontSize; | |||||
float fontSize, totalSize, ascent; | |||||
int refCount; | 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_), | name (name_), | ||||
isBold (bold_), | isBold (bold_), | ||||
isItalic (italic_), | isItalic (italic_), | ||||
fontSize (size_), | fontSize (size_), | ||||
refCount (1) | 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, | bool getPathAndKerning (const juce_wchar char1, | ||||
@@ -269429,128 +269345,65 @@ public: | |||||
float* ascent, | float* ascent, | ||||
float* descent) | 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() | juce_wchar getDefaultChar() | ||||
@@ -269559,35 +269412,35 @@ public: | |||||
} | } | ||||
}; | }; | ||||
class ATSFontHelperCache : public Timer, | |||||
public DeletedAtShutdown | |||||
class FontHelperCache : public Timer, | |||||
public DeletedAtShutdown | |||||
{ | { | ||||
VoidArray cache; | VoidArray cache; | ||||
public: | public: | ||||
ATSFontHelperCache() | |||||
FontHelperCache() | |||||
{ | { | ||||
} | } | ||||
~ATSFontHelperCache() | |||||
~FontHelperCache() | |||||
{ | { | ||||
for (int i = cache.size(); --i >= 0;) | for (int i = cache.size(); --i >= 0;) | ||||
{ | { | ||||
ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i); | |||||
FontHelper* const f = (FontHelper*) cache.getUnchecked(i); | |||||
delete f; | delete f; | ||||
} | } | ||||
clearSingletonInstance(); | 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;) | 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 | if (f->name == name | ||||
&& f->isBold == bold | && 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); | cache.add (f); | ||||
return f; | return f; | ||||
} | } | ||||
void releaseFont (ATSFontHelper* f) | |||||
void releaseFont (FontHelper* f) | |||||
{ | { | ||||
for (int i = cache.size(); --i >= 0;) | for (int i = cache.size(); --i >= 0;) | ||||
{ | { | ||||
ATSFontHelper* const f2 = (ATSFontHelper*) cache.getUnchecked(i); | |||||
FontHelper* const f2 = (FontHelper*) cache.getUnchecked(i); | |||||
if (f == f2) | if (f == f2) | ||||
{ | { | ||||
@@ -269628,7 +269481,7 @@ public: | |||||
for (int i = cache.size(); --i >= 0;) | 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) | if (f->refCount == 0) | ||||
{ | { | ||||
@@ -269641,10 +269494,10 @@ public: | |||||
delete this; | 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, | void Typeface::initialiseTypefaceCharacteristics (const String& fontName, | ||||
bool bold, | 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.. | // This method is only safe to be called from the normal UI thread.. | ||||
jassert (MessageManager::getInstance()->isThisTheMessageThread()); | jassert (MessageManager::getInstance()->isThisTheMessageThread()); | ||||
ATSFontHelper* const helper = ATSFontHelperCache::getInstance() | |||||
->getFont (fontName, bold, italic); | |||||
FontHelper* const helper = FontHelperCache::getInstance() | |||||
->getFont (fontName, bold, italic); | |||||
clear(); | clear(); | ||||
setAscent (helper->getAscent() / helper->getTotalHeight()); | |||||
setAscent (helper->ascent / helper->totalSize); | |||||
setName (fontName); | setName (fontName); | ||||
setDefaultCharacter (helper->getDefaultChar()); | setDefaultCharacter (helper->getDefaultChar()); | ||||
setBold (bold); | setBold (bold); | ||||
@@ -269670,7 +269523,7 @@ void Typeface::initialiseTypefaceCharacteristics (const String& fontName, | |||||
jassertfalse | jassertfalse | ||||
} | } | ||||
ATSFontHelperCache::getInstance()->releaseFont (helper); | |||||
FontHelperCache::getInstance()->releaseFont (helper); | |||||
} | } | ||||
bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() | 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.. | // This method is only safe to be called from the normal UI thread.. | ||||
jassert (MessageManager::getInstance()->isThisTheMessageThread()); | jassert (MessageManager::getInstance()->isThisTheMessageThread()); | ||||
ATSFontHelper* const helper = ATSFontHelperCache::getInstance() | |||||
->getFont (getName(), isBold(), isItalic()); | |||||
FontHelper* const helper = FontHelperCache::getInstance() | |||||
->getFont (getName(), isBold(), isItalic()); | |||||
Path path; | Path path; | ||||
float width; | float width; | ||||
@@ -269687,10 +269540,10 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() | |||||
if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0)) | 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) | for (int i = 0; i < glyphs.size(); ++i) | ||||
{ | { | ||||
@@ -269699,7 +269552,7 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() | |||||
float kerning; | float kerning; | ||||
if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0)) | if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0)) | ||||
{ | { | ||||
kerning = (kerning - width) / helper->getTotalHeight(); | |||||
kerning = (kerning - width) / helper->totalSize; | |||||
if (kerning != 0) | if (kerning != 0) | ||||
addKerningPair (character, g->getCharacter(), kerning); | 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)) | 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) | if (kerning != 0) | ||||
addKerningPair (g->getCharacter(), character, kerning); | addKerningPair (g->getCharacter(), character, kerning); | ||||
@@ -269717,68 +269570,19 @@ bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() | |||||
foundOne = true; | foundOne = true; | ||||
} | } | ||||
ATSFontHelperCache::getInstance()->releaseFont (helper); | |||||
FontHelperCache::getInstance()->releaseFont (helper); | |||||
return foundOne; | return foundOne; | ||||
} | } | ||||
const StringArray Font::findAllTypefaceNames() throw() | const StringArray Font::findAllTypefaceNames() throw() | ||||
{ | { | ||||
StringArray names; | 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); | names.sort (true); | ||||
return names; | return names; | ||||