@@ -130,8 +130,7 @@ public: | |||||
if (rowIsSelected) | if (rowIsSelected) | ||||
g.fillAll (Colours::lightblue); | g.fillAll (Colours::lightblue); | ||||
Font font (fonts [rowNumber]); | |||||
font.setHeight (height * 0.7f); | |||||
Font font = fonts[rowNumber].withPointHeight (height * 0.6f); | |||||
g.setFont (font); | g.setFont (font); | ||||
g.setColour (Colours::black); | g.setColour (Colours::black); | ||||
@@ -304,15 +304,9 @@ bool CustomTypeface::writeToStream (OutputStream& outputStream) | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
float CustomTypeface::getAscent() const | |||||
{ | |||||
return ascent; | |||||
} | |||||
float CustomTypeface::getDescent() const | |||||
{ | |||||
return 1.0f - ascent; | |||||
} | |||||
float CustomTypeface::getAscent() const { return ascent; } | |||||
float CustomTypeface::getDescent() const { return 1.0f - ascent; } | |||||
float CustomTypeface::getHeightToPointsFactor() const { return ascent; } | |||||
float CustomTypeface::getStringWidth (const String& text) | float CustomTypeface::getStringWidth (const String& text) | ||||
{ | { | ||||
@@ -120,6 +120,7 @@ public: | |||||
// The following methods implement the basic Typeface behaviour. | // The following methods implement the basic Typeface behaviour. | ||||
float getAscent() const; | float getAscent() const; | ||||
float getDescent() const; | float getDescent() const; | ||||
float getHeightToPointsFactor() const; | |||||
float getStringWidth (const String& text); | float getStringWidth (const String& text); | ||||
void getGlyphPositions (const String& text, Array <int>& glyphs, Array<float>& xOffsets); | void getGlyphPositions (const String& text, Array <int>& glyphs, Array<float>& xOffsets); | ||||
bool getOutlineForGlyph (int glyphNumber, Path& path); | bool getOutlineForGlyph (int glyphNumber, Path& path); | ||||
@@ -446,6 +446,13 @@ Font Font::withHeight (const float newHeight) const | |||||
return f; | return f; | ||||
} | } | ||||
Font Font::withPointHeight (float heightInPoints) const | |||||
{ | |||||
Font f (*this); | |||||
f.setHeight (heightInPoints / getTypeface()->getHeightToPointsFactor()); | |||||
return f; | |||||
} | |||||
void Font::setHeight (float newHeight) | void Font::setHeight (float newHeight) | ||||
{ | { | ||||
newHeight = FontValues::limitFontHeight (newHeight); | newHeight = FontValues::limitFontHeight (newHeight); | ||||
@@ -215,6 +215,9 @@ public: | |||||
/** Returns a copy of this font with a new height. */ | /** Returns a copy of this font with a new height. */ | ||||
Font withHeight (float height) const; | Font withHeight (float height) const; | ||||
/** Returns a copy of this font with a new height, specified in points. */ | |||||
Font withPointHeight (float heightInPoints) const; | |||||
/** Changes the font's height. | /** Changes the font's height. | ||||
@see getHeight, withHeight, setHeightWithoutChangingWidth | @see getHeight, withHeight, setHeightWithoutChangingWidth | ||||
*/ | */ | ||||
@@ -94,24 +94,24 @@ public: | |||||
*/ | */ | ||||
virtual float getDescent() const = 0; | virtual float getDescent() const = 0; | ||||
/** Measures the width of a line of text. | |||||
/** Returns the value by which you should multiply a juce font-height value to | |||||
convert it to the equivalent point-size. | |||||
*/ | |||||
virtual float getHeightToPointsFactor() const = 0; | |||||
/** Measures the width of a line of text. | |||||
The distance returned is based on the font having an normalised height of 1.0. | The distance returned is based on the font having an normalised height of 1.0. | ||||
You should never need to call this directly! Use Font::getStringWidth() instead! | You should never need to call this directly! Use Font::getStringWidth() instead! | ||||
*/ | */ | ||||
virtual float getStringWidth (const String& text) = 0; | virtual float getStringWidth (const String& text) = 0; | ||||
/** Converts a line of text into its glyph numbers and their positions. | /** Converts a line of text into its glyph numbers and their positions. | ||||
The distances returned are based on the font having an normalised height of 1.0. | The distances returned are based on the font having an normalised height of 1.0. | ||||
You should never need to call this directly! Use Font::getGlyphPositions() instead! | You should never need to call this directly! Use Font::getGlyphPositions() instead! | ||||
*/ | */ | ||||
virtual void getGlyphPositions (const String& text, Array <int>& glyphs, Array<float>& xOffsets) = 0; | virtual void getGlyphPositions (const String& text, Array <int>& glyphs, Array<float>& xOffsets) = 0; | ||||
/** Returns the outline for a glyph. | /** Returns the outline for a glyph. | ||||
The path returned will be normalised to a font height of 1.0. | The path returned will be normalised to a font height of 1.0. | ||||
*/ | */ | ||||
virtual bool getOutlineForGlyph (int glyphNumber, Path& path) = 0; | virtual bool getOutlineForGlyph (int glyphNumber, Path& path) = 0; | ||||
@@ -89,14 +89,16 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font) | |||||
return Typeface::createSystemTypefaceFor (f); | return Typeface::createSystemTypefaceFor (f); | ||||
} | } | ||||
const float referenceFontSize = 256.0f; | |||||
const float referenceFontToUnits = 1.0f / referenceFontSize; | |||||
//============================================================================== | //============================================================================== | ||||
class AndroidTypeface : public Typeface | class AndroidTypeface : public Typeface | ||||
{ | { | ||||
public: | public: | ||||
AndroidTypeface (const Font& font) | AndroidTypeface (const Font& font) | ||||
: Typeface (font.getTypefaceName(), font.getTypefaceStyle()), | : Typeface (font.getTypefaceName(), font.getTypefaceStyle()), | ||||
ascent (0), | |||||
descent (0) | |||||
ascent (0), descent (0), heightToPointsFactor (1.0f) | |||||
{ | { | ||||
JNIEnv* const env = getEnv(); | JNIEnv* const env = getEnv(); | ||||
@@ -121,17 +123,20 @@ public: | |||||
paint = GlobalRef (GraphicsHelpers::createPaint (Graphics::highResamplingQuality)); | paint = GlobalRef (GraphicsHelpers::createPaint (Graphics::highResamplingQuality)); | ||||
const LocalRef<jobject> ignored (paint.callObjectMethod (Paint.setTypeface, typeface.get())); | const LocalRef<jobject> ignored (paint.callObjectMethod (Paint.setTypeface, typeface.get())); | ||||
const float standardSize = 256.0f; | |||||
paint.callVoidMethod (Paint.setTextSize, standardSize); | |||||
ascent = std::abs (paint.callFloatMethod (Paint.ascent)) / standardSize; | |||||
descent = paint.callFloatMethod (Paint.descent) / standardSize; | |||||
paint.callVoidMethod (Paint.setTextSize, referenceFontSize); | |||||
const float fullAscent = std::abs (paint.callFloatMethod (Paint.ascent)); | |||||
const float fullDescent = paint.callFloatMethod (Paint.descent); | |||||
const float totalHeight = fullAscent + fullDescent; | |||||
const float height = ascent + descent; | |||||
unitsToHeightScaleFactor = 1.0f / 256.0f; | |||||
ascent = fullAscent / totalHeight; | |||||
descent = fullDescent / totalHeight; | |||||
heightToPointsFactor = referenceFontSize / totalHeight; | |||||
} | } | ||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return descent; } | |||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return descent; } | |||||
float getHeightToPointsFactor() const { return heightToPointsFactor; } | |||||
float getStringWidth (const String& text) | float getStringWidth (const String& text) | ||||
{ | { | ||||
@@ -149,7 +154,7 @@ public: | |||||
for (int i = 0; i < numDone; ++i) | for (int i = 0; i < numDone; ++i) | ||||
x += localWidths[i]; | x += localWidths[i]; | ||||
return x * unitsToHeightScaleFactor; | |||||
return x * referenceFontToUnits; | |||||
} | } | ||||
void getGlyphPositions (const String& text, Array<int>& glyphs, Array<float>& xOffsets) | void getGlyphPositions (const String& text, Array<int>& glyphs, Array<float>& xOffsets) | ||||
@@ -173,7 +178,7 @@ public: | |||||
{ | { | ||||
glyphs.add ((int) s.getAndAdvance()); | glyphs.add ((int) s.getAndAdvance()); | ||||
x += localWidths[i]; | x += localWidths[i]; | ||||
xOffsets.add (x * unitsToHeightScaleFactor); | |||||
xOffsets.add (x * referenceFontToUnits); | |||||
} | } | ||||
} | } | ||||
@@ -186,7 +191,7 @@ public: | |||||
{ | { | ||||
JNIEnv* env = getEnv(); | JNIEnv* env = getEnv(); | ||||
jobject matrix = GraphicsHelpers::createMatrix (env, AffineTransform::scale (unitsToHeightScaleFactor).followedBy (t)); | |||||
jobject matrix = GraphicsHelpers::createMatrix (env, AffineTransform::scale (referenceFontToUnits).followedBy (t)); | |||||
jintArray maskData = (jintArray) android.activity.callObjectMethod (JuceAppActivity.renderGlyph, (jchar) glyphNumber, paint.get(), matrix, rect.get()); | jintArray maskData = (jintArray) android.activity.callObjectMethod (JuceAppActivity.renderGlyph, (jchar) glyphNumber, paint.get(), matrix, rect.get()); | ||||
env->DeleteLocalRef (matrix); | env->DeleteLocalRef (matrix); | ||||
@@ -227,7 +232,7 @@ public: | |||||
} | } | ||||
GlobalRef typeface, paint, rect; | GlobalRef typeface, paint, rect; | ||||
float ascent, descent, unitsToHeightScaleFactor; | |||||
float ascent, descent, heightToPointsFactor; | |||||
private: | private: | ||||
static File findFontFile (const String& family, | static File findFontFile (const String& family, | ||||
@@ -561,7 +561,7 @@ void CoreGraphicsContext::setFont (const Font& newFont) | |||||
{ | { | ||||
state->fontRef = osxTypeface->fontRef; | state->fontRef = osxTypeface->fontRef; | ||||
CGContextSetFont (context, state->fontRef); | CGContextSetFont (context, state->fontRef); | ||||
CGContextSetFontSize (context, state->font.getHeight() * osxTypeface->fontHeightToCGSizeFactor); | |||||
CGContextSetFontSize (context, state->font.getHeight() * osxTypeface->fontHeightToPointsFactor); | |||||
state->fontTransform = osxTypeface->renderingTransform; | state->fontTransform = osxTypeface->renderingTransform; | ||||
state->fontTransform.a *= state->font.getHorizontalScale(); | state->fontTransform.a *= state->font.getHorizontalScale(); | ||||
@@ -28,6 +28,8 @@ | |||||
#define JUCE_CORETEXT_AVAILABLE 1 | #define JUCE_CORETEXT_AVAILABLE 1 | ||||
#endif | #endif | ||||
const float referenceFontSize = 1024.0f; | |||||
#if JUCE_CORETEXT_AVAILABLE | #if JUCE_CORETEXT_AVAILABLE | ||||
#if JUCE_MAC && MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5 | #if JUCE_MAC && MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5 | ||||
@@ -70,14 +72,14 @@ namespace CoreTextTypeLayout | |||||
} | } | ||||
static CTFontRef useStyleFallbackIfNecessary (CTFontRef ctFontRef, CFStringRef cfFontFamily, | static CTFontRef useStyleFallbackIfNecessary (CTFontRef ctFontRef, CFStringRef cfFontFamily, | ||||
const float fontSize, const Font& font) | |||||
const float fontSizePoints, const Font& font) | |||||
{ | { | ||||
CFStringRef cfActualFontFamily = (CFStringRef) CTFontCopyAttribute (ctFontRef, kCTFontFamilyNameAttribute); | CFStringRef cfActualFontFamily = (CFStringRef) CTFontCopyAttribute (ctFontRef, kCTFontFamilyNameAttribute); | ||||
if (CFStringCompare (cfFontFamily, cfActualFontFamily, 0) != kCFCompareEqualTo) | if (CFStringCompare (cfFontFamily, cfActualFontFamily, 0) != kCFCompareEqualTo) | ||||
{ | { | ||||
CFRelease (ctFontRef); | CFRelease (ctFontRef); | ||||
ctFontRef = CTFontCreateWithName (cfFontFamily, fontSize, nullptr); | |||||
ctFontRef = CTFontCreateWithName (cfFontFamily, fontSizePoints, nullptr); | |||||
if (font.isItalic()) ctFontRef = getFontWithTrait (ctFontRef, kCTFontItalicTrait); | if (font.isItalic()) ctFontRef = getFontWithTrait (ctFontRef, kCTFontItalicTrait); | ||||
if (font.isBold()) ctFontRef = getFontWithTrait (ctFontRef, kCTFontBoldTrait); | if (font.isBold()) ctFontRef = getFontWithTrait (ctFontRef, kCTFontBoldTrait); | ||||
@@ -88,8 +90,24 @@ namespace CoreTextTypeLayout | |||||
} | } | ||||
#endif | #endif | ||||
static CTFontRef createCTFont (const Font& font, const float fontSize, | |||||
CGAffineTransform& transformRequired, const bool applyScaleFactor) | |||||
static float getFontTotalHeight (CTFontRef font) | |||||
{ | |||||
return std::abs ((float) CTFontGetAscent (font)) + std::abs ((float) CTFontGetDescent (font)); | |||||
} | |||||
static float getHeightToPointsFactor (CTFontRef font) | |||||
{ | |||||
return referenceFontSize / getFontTotalHeight (font); | |||||
} | |||||
static CTFontRef getFontWithPointSize (CTFontRef font, float size) | |||||
{ | |||||
CTFontRef newFont = CTFontCreateCopyWithAttributes (font, size, nullptr, nullptr); | |||||
CFRelease (font); | |||||
return newFont; | |||||
} | |||||
static CTFontRef createCTFont (const Font& font, const float fontSizePoints, CGAffineTransform& transformRequired) | |||||
{ | { | ||||
CFStringRef cfFontFamily = FontStyleHelpers::getConcreteFamilyName (font).toCFString(); | CFStringRef cfFontFamily = FontStyleHelpers::getConcreteFamilyName (font).toCFString(); | ||||
CFStringRef cfFontStyle = findBestAvailableStyle (font, transformRequired).toCFString(); | CFStringRef cfFontStyle = findBestAvailableStyle (font, transformRequired).toCFString(); | ||||
@@ -106,27 +124,15 @@ namespace CoreTextTypeLayout | |||||
CTFontDescriptorRef ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes); | CTFontDescriptorRef ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes); | ||||
CFRelease (fontDescAttributes); | CFRelease (fontDescAttributes); | ||||
CTFontRef ctFontRef = CTFontCreateWithFontDescriptor (ctFontDescRef, fontSize, nullptr); | |||||
CTFontRef ctFontRef = CTFontCreateWithFontDescriptor (ctFontDescRef, fontSizePoints, nullptr); | |||||
CFRelease (ctFontDescRef); | CFRelease (ctFontDescRef); | ||||
#if JUCE_MAC && ((! defined (MAC_OS_X_VERSION_10_7)) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7) | #if JUCE_MAC && ((! defined (MAC_OS_X_VERSION_10_7)) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7) | ||||
ctFontRef = useStyleFallbackIfNecessary (ctFontRef, cfFontFamily, fontSize, font); | |||||
ctFontRef = useStyleFallbackIfNecessary (ctFontRef, cfFontFamily, fontSizePoints, font); | |||||
#endif | #endif | ||||
CFRelease (cfFontFamily); | CFRelease (cfFontFamily); | ||||
if (applyScaleFactor) | |||||
{ | |||||
CGFontRef cgFontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr); | |||||
const int totalHeight = std::abs (CGFontGetAscent (cgFontRef)) + std::abs (CGFontGetDescent (cgFontRef)); | |||||
const float factor = CGFontGetUnitsPerEm (cgFontRef) / (float) totalHeight; | |||||
CGFontRelease (cgFontRef); | |||||
CTFontRef newFont = CTFontCreateCopyWithAttributes (ctFontRef, fontSize * factor, nullptr, nullptr); | |||||
CFRelease (ctFontRef); | |||||
ctFontRef = newFont; | |||||
} | |||||
return ctFontRef; | return ctFontRef; | ||||
} | } | ||||
@@ -209,7 +215,8 @@ namespace CoreTextTypeLayout | |||||
if (const Font* const f = attr->getFont()) | if (const Font* const f = attr->getFont()) | ||||
{ | { | ||||
CGAffineTransform transform; | CGAffineTransform transform; | ||||
CTFontRef ctFontRef = createCTFont (*f, f->getHeight(), transform, true); | |||||
CTFontRef ctFontRef = createCTFont (*f, referenceFontSize, transform); | |||||
ctFontRef = getFontWithPointSize (ctFontRef, f->getHeight() * getHeightToPointsFactor (ctFontRef)); | |||||
CFAttributedStringSetAttribute (attribString, CFRangeMake (range.getStart(), range.getLength()), | CFAttributedStringSetAttribute (attribString, CFRangeMake (range.getStart(), range.getLength()), | ||||
kCTFontAttributeName, ctFontRef); | kCTFontAttributeName, ctFontRef); | ||||
@@ -362,21 +369,18 @@ namespace CoreTextTypeLayout | |||||
if (CFDictionaryGetValueIfPresent (runAttributes, kCTFontAttributeName, (const void **) &ctRunFont)) | if (CFDictionaryGetValueIfPresent (runAttributes, kCTFontAttributeName, (const void **) &ctRunFont)) | ||||
{ | { | ||||
CFStringRef cfsFontName = CTFontCopyPostScriptName (ctRunFont); | CFStringRef cfsFontName = CTFontCopyPostScriptName (ctRunFont); | ||||
CTFontRef ctFontRef = CTFontCreateWithName (cfsFontName, 1024, nullptr); | |||||
CTFontRef ctFontRef = CTFontCreateWithName (cfsFontName, referenceFontSize, nullptr); | |||||
CFRelease (cfsFontName); | CFRelease (cfsFontName); | ||||
CGFontRef cgFontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr); | |||||
const float fontHeightToPointsFactor = getHeightToPointsFactor (ctFontRef); | |||||
CFRelease (ctFontRef); | CFRelease (ctFontRef); | ||||
const int totalHeight = std::abs (CGFontGetAscent (cgFontRef)) + std::abs (CGFontGetDescent (cgFontRef)); | |||||
const float fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (cgFontRef) / (float) totalHeight; | |||||
CGFontRelease (cgFontRef); | |||||
CFStringRef cfsFontFamily = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontFamilyNameAttribute); | CFStringRef cfsFontFamily = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontFamilyNameAttribute); | ||||
CFStringRef cfsFontStyle = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontStyleNameAttribute); | CFStringRef cfsFontStyle = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontStyleNameAttribute); | ||||
glyphRun->font = Font (String::fromCFString (cfsFontFamily), | glyphRun->font = Font (String::fromCFString (cfsFontFamily), | ||||
String::fromCFString (cfsFontStyle), | String::fromCFString (cfsFontStyle), | ||||
CTFontGetSize (ctRunFont) / fontHeightToCGSizeFactor); | |||||
CTFontGetSize (ctRunFont) / fontHeightToPointsFactor); | |||||
CFRelease (cfsFontStyle); | CFRelease (cfsFontStyle); | ||||
CFRelease (cfsFontFamily); | CFRelease (cfsFontFamily); | ||||
@@ -415,29 +419,27 @@ public: | |||||
: Typeface (font.getTypefaceName(), | : Typeface (font.getTypefaceName(), | ||||
font.getTypefaceStyle()), | font.getTypefaceStyle()), | ||||
fontRef (nullptr), | fontRef (nullptr), | ||||
fontHeightToCGSizeFactor (1.0f), | |||||
fontHeightToPointsFactor (1.0f), | |||||
renderingTransform (CGAffineTransformIdentity), | renderingTransform (CGAffineTransformIdentity), | ||||
ctFontRef (nullptr), | ctFontRef (nullptr), | ||||
attributedStringAtts (nullptr), | attributedStringAtts (nullptr), | ||||
ascent (0.0f), | ascent (0.0f), | ||||
unitsToHeightScaleFactor (0.0f) | unitsToHeightScaleFactor (0.0f) | ||||
{ | { | ||||
ctFontRef = CoreTextTypeLayout::createCTFont (font, 1024.0f, renderingTransform, false); | |||||
ctFontRef = CoreTextTypeLayout::createCTFont (font, referenceFontSize, renderingTransform); | |||||
if (ctFontRef != nullptr) | if (ctFontRef != nullptr) | ||||
{ | { | ||||
ascent = std::abs ((float) CTFontGetAscent (ctFontRef)); | |||||
const float totalSize = ascent + std::abs ((float) CTFontGetDescent (ctFontRef)); | |||||
ascent /= totalSize; | |||||
const float ctAscent = std::abs ((float) CTFontGetAscent (ctFontRef)); | |||||
const float ctDescent = std::abs ((float) CTFontGetDescent (ctFontRef)); | |||||
const float ctTotalHeight = ctAscent + ctDescent; | |||||
pathTransform = AffineTransform::identity.scale (1.0f / totalSize); | |||||
ascent = ctAscent / ctTotalHeight; | |||||
unitsToHeightScaleFactor = 1.0f / ctTotalHeight; | |||||
pathTransform = AffineTransform::identity.scale (unitsToHeightScaleFactor); | |||||
fontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr); | fontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr); | ||||
const int totalHeight = std::abs (CGFontGetAscent (fontRef)) + std::abs (CGFontGetDescent (fontRef)); | |||||
const float ctTotalHeight = std::abs (CTFontGetAscent (ctFontRef)) + std::abs (CTFontGetDescent (ctFontRef)); | |||||
unitsToHeightScaleFactor = 1.0f / ctTotalHeight; | |||||
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight; | |||||
fontHeightToPointsFactor = referenceFontSize / ctTotalHeight; | |||||
const short zero = 0; | const short zero = 0; | ||||
CFNumberRef numberRef = CFNumberCreate (0, kCFNumberShortType, &zero); | CFNumberRef numberRef = CFNumberCreate (0, kCFNumberShortType, &zero); | ||||
@@ -462,8 +464,9 @@ public: | |||||
CFRelease (ctFontRef); | CFRelease (ctFontRef); | ||||
} | } | ||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return 1.0f - ascent; } | |||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return 1.0f - ascent; } | |||||
float getHeightToPointsFactor() const { return fontHeightToPointsFactor; } | |||||
float getStringWidth (const String& text) | float getStringWidth (const String& text) | ||||
{ | { | ||||
@@ -565,7 +568,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
CGFontRef fontRef; | CGFontRef fontRef; | ||||
float fontHeightToCGSizeFactor; | |||||
float fontHeightToPointsFactor; | |||||
CGAffineTransform renderingTransform; | CGAffineTransform renderingTransform; | ||||
private: | private: | ||||
@@ -717,7 +720,7 @@ public: | |||||
juceStringToNS (style), NSFontFaceAttribute, nil]; | juceStringToNS (style), NSFontFaceAttribute, nil]; | ||||
NSFontDescriptor* nsFontDesc = [NSFontDescriptor fontDescriptorWithFontAttributes: nsDict]; | NSFontDescriptor* nsFontDesc = [NSFontDescriptor fontDescriptorWithFontAttributes: nsDict]; | ||||
nsFont = [NSFont fontWithDescriptor: nsFontDesc size: 1024]; | |||||
nsFont = [NSFont fontWithDescriptor: nsFontDesc size: referenceFontSize]; | |||||
[nsFont retain]; | [nsFont retain]; | ||||
@@ -737,7 +740,7 @@ public: | |||||
const float totalHeight = std::abs ([nsFont ascender]) + std::abs ([nsFont descender]); | const float totalHeight = std::abs ([nsFont ascender]) + std::abs ([nsFont descender]); | ||||
unitsToHeightScaleFactor = 1.0f / totalHeight; | unitsToHeightScaleFactor = 1.0f / totalHeight; | ||||
fontHeightToCGSizeFactor = 1024.0f / totalHeight; | |||||
fontHeightToPointsFactor = referenceFontSize / totalHeight; | |||||
#else | #else | ||||
#if SUPPORT_10_4_FONTS | #if SUPPORT_10_4_FONTS | ||||
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) | if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) | ||||
@@ -751,16 +754,15 @@ public: | |||||
const float totalHeight = std::abs ([nsFont ascender]) + std::abs ([nsFont descender]); | const float totalHeight = std::abs ([nsFont ascender]) + std::abs ([nsFont descender]); | ||||
unitsToHeightScaleFactor = 1.0f / totalHeight; | unitsToHeightScaleFactor = 1.0f / totalHeight; | ||||
fontHeightToCGSizeFactor = 1024.0f / totalHeight; | |||||
fontHeightToPointsFactor = referenceFontSize / totalHeight; | |||||
} | } | ||||
else | else | ||||
#endif | #endif | ||||
{ | { | ||||
fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]); | fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]); | ||||
const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef)); | |||||
unitsToHeightScaleFactor = 1.0f / totalHeight; | |||||
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight; | |||||
unitsToHeightScaleFactor = 1.0f / getFontTotalHeight (fontRef); | |||||
fontHeightToPointsFactor = getHeightToPointsFactor (fontRef); | |||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
@@ -775,8 +777,9 @@ public: | |||||
CGFontRelease (fontRef); | CGFontRelease (fontRef); | ||||
} | } | ||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return 1.0f - ascent; } | |||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return 1.0f - ascent; } | |||||
float getHeightToPointsFactor() const { return fontHeightToPointsFactor; } | |||||
float getStringWidth (const String& text) | float getStringWidth (const String& text) | ||||
{ | { | ||||
@@ -928,7 +931,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
CGFontRef fontRef; | CGFontRef fontRef; | ||||
float fontHeightToCGSizeFactor; | |||||
float fontHeightToPointsFactor; | |||||
CGAffineTransform renderingTransform; | CGAffineTransform renderingTransform; | ||||
private: | private: | ||||
@@ -547,7 +547,7 @@ public: | |||||
{ | { | ||||
WindowsDirectWriteTypeface* typeface = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface()); | WindowsDirectWriteTypeface* typeface = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface()); | ||||
currentFontFace = typeface->getIDWriteFontFace(); | currentFontFace = typeface->getIDWriteFontFace(); | ||||
fontHeightToEmSizeFactor = typeface->getFontHeightToEmSizeFactor(); | |||||
fontHeightToEmSizeFactor = typeface->unitsToHeightScaleFactor(); | |||||
} | } | ||||
} | } | ||||
@@ -160,7 +160,7 @@ namespace DirectWriteTypeLayout | |||||
}; | }; | ||||
//================================================================================================== | //================================================================================================== | ||||
float getFontHeightToEmSizeFactor (IDWriteFont* const dwFont) | |||||
static float getFontHeightToEmSizeFactor (IDWriteFont* const dwFont) | |||||
{ | { | ||||
ComSmartPtr<IDWriteFontFace> dwFontFace; | ComSmartPtr<IDWriteFontFace> dwFontFace; | ||||
dwFont->CreateFontFace (dwFontFace.resetAndGetPointerAddress()); | dwFont->CreateFontFace (dwFontFace.resetAndGetPointerAddress()); | ||||
@@ -181,8 +181,9 @@ public: | |||||
pathTransform = AffineTransform::scale (pathScale); | pathTransform = AffineTransform::scale (pathScale); | ||||
} | } | ||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return 1.0f - ascent; } | |||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return 1.0f - ascent; } | |||||
float getHeightToPointsFactor() const { return unitsToHeightScaleFactor; } | |||||
float getStringWidth (const String& text) | float getStringWidth (const String& text) | ||||
{ | { | ||||
@@ -250,7 +251,6 @@ public: | |||||
} | } | ||||
IDWriteFontFace* getIDWriteFontFace() const noexcept { return dwFontFace; } | IDWriteFontFace* getIDWriteFontFace() const noexcept { return dwFontFace; } | ||||
float getFontHeightToEmSizeFactor() const noexcept { return unitsToHeightScaleFactor; } | |||||
private: | private: | ||||
ComSmartPtr<IDWriteFontFace> dwFontFace; | ComSmartPtr<IDWriteFontFace> dwFontFace; | ||||
@@ -210,13 +210,14 @@ public: | |||||
fontH (0), | fontH (0), | ||||
previousFontH (0), | previousFontH (0), | ||||
dc (CreateCompatibleDC (0)), | dc (CreateCompatibleDC (0)), | ||||
ascent (1.0f), | |||||
ascent (1.0f), heightToPointsFactor (1.0f), | |||||
defaultGlyph (-1) | defaultGlyph (-1) | ||||
{ | { | ||||
loadFont(); | loadFont(); | ||||
if (GetTextMetrics (dc, &tm)) | if (GetTextMetrics (dc, &tm)) | ||||
{ | { | ||||
heightToPointsFactor = 256.0f / tm.tmHeight; | |||||
ascent = tm.tmAscent / (float) tm.tmHeight; | ascent = tm.tmAscent / (float) tm.tmHeight; | ||||
defaultGlyph = getGlyphForChar (dc, tm.tmDefaultChar); | defaultGlyph = getGlyphForChar (dc, tm.tmDefaultChar); | ||||
createKerningPairs (dc, (float) tm.tmHeight); | createKerningPairs (dc, (float) tm.tmHeight); | ||||
@@ -232,8 +233,9 @@ public: | |||||
DeleteObject (fontH); | DeleteObject (fontH); | ||||
} | } | ||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return 1.0f - ascent; } | |||||
float getAscent() const { return ascent; } | |||||
float getDescent() const { return 1.0f - ascent; } | |||||
float getHeightToPointsFactor() const { return heightToPointsFactor; } | |||||
float getStringWidth (const String& text) | float getStringWidth (const String& text) | ||||
{ | { | ||||
@@ -352,7 +354,7 @@ private: | |||||
HGDIOBJ previousFontH; | HGDIOBJ previousFontH; | ||||
HDC dc; | HDC dc; | ||||
TEXTMETRIC tm; | TEXTMETRIC tm; | ||||
float ascent; | |||||
float ascent, heightToPointsFactor; | |||||
int defaultGlyph; | int defaultGlyph; | ||||
struct KerningPair | struct KerningPair | ||||
@@ -492,7 +494,7 @@ Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) | |||||
if (factories.systemFonts != nullptr) | if (factories.systemFonts != nullptr) | ||||
return new WindowsDirectWriteTypeface (font, factories.systemFonts); | return new WindowsDirectWriteTypeface (font, factories.systemFonts); | ||||
else | |||||
#endif | #endif | ||||
return new WindowsTypeface (font); | |||||
return new WindowsTypeface (font); | |||||
} | } |