Browse Source

New method Font::withPointHeight, for specifying font sizes in points.

tags/2021-05-28
jules 12 years ago
parent
commit
2ae82c4db4
13 changed files with 104 additions and 90 deletions
  1. +1
    -2
      extras/JuceDemo/Source/demos/FontsAndTextDemo.cpp
  2. +3
    -9
      modules/juce_graphics/fonts/juce_CustomTypeface.cpp
  3. +1
    -0
      modules/juce_graphics/fonts/juce_CustomTypeface.h
  4. +7
    -0
      modules/juce_graphics/fonts/juce_Font.cpp
  5. +3
    -0
      modules/juce_graphics/fonts/juce_Font.h
  6. +5
    -5
      modules/juce_graphics/fonts/juce_Typeface.h
  7. +19
    -14
      modules/juce_graphics/native/juce_android_Fonts.cpp
  8. +1
    -1
      modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm
  9. +51
    -48
      modules/juce_graphics/native/juce_mac_Fonts.mm
  10. +1
    -1
      modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp
  11. +1
    -1
      modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp
  12. +3
    -3
      modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp
  13. +8
    -6
      modules/juce_graphics/native/juce_win32_Fonts.cpp

+ 1
- 2
extras/JuceDemo/Source/demos/FontsAndTextDemo.cpp View File

@@ -130,8 +130,7 @@ public:
if (rowIsSelected)
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.setColour (Colours::black);


+ 3
- 9
modules/juce_graphics/fonts/juce_CustomTypeface.cpp View File

@@ -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)
{


+ 1
- 0
modules/juce_graphics/fonts/juce_CustomTypeface.h View File

@@ -120,6 +120,7 @@ public:
// The following methods implement the basic Typeface behaviour.
float getAscent() const;
float getDescent() const;
float getHeightToPointsFactor() const;
float getStringWidth (const String& text);
void getGlyphPositions (const String& text, Array <int>& glyphs, Array<float>& xOffsets);
bool getOutlineForGlyph (int glyphNumber, Path& path);


+ 7
- 0
modules/juce_graphics/fonts/juce_Font.cpp View File

@@ -446,6 +446,13 @@ Font Font::withHeight (const float newHeight) const
return f;
}
Font Font::withPointHeight (float heightInPoints) const
{
Font f (*this);
f.setHeight (heightInPoints / getTypeface()->getHeightToPointsFactor());
return f;
}
void Font::setHeight (float newHeight)
{
newHeight = FontValues::limitFontHeight (newHeight);


+ 3
- 0
modules/juce_graphics/fonts/juce_Font.h View File

@@ -215,6 +215,9 @@ public:
/** Returns a copy of this font with a new height. */
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.
@see getHeight, withHeight, setHeightWithoutChangingWidth
*/


+ 5
- 5
modules/juce_graphics/fonts/juce_Typeface.h View File

@@ -94,24 +94,24 @@ public:
*/
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.
You should never need to call this directly! Use Font::getStringWidth() instead!
*/
virtual float getStringWidth (const String& text) = 0;
/** 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.
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;
/** Returns the outline for a glyph.
The path returned will be normalised to a font height of 1.0.
*/
virtual bool getOutlineForGlyph (int glyphNumber, Path& path) = 0;


+ 19
- 14
modules/juce_graphics/native/juce_android_Fonts.cpp View File

@@ -89,14 +89,16 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
return Typeface::createSystemTypefaceFor (f);
}
const float referenceFontSize = 256.0f;
const float referenceFontToUnits = 1.0f / referenceFontSize;
//==============================================================================
class AndroidTypeface : public Typeface
{
public:
AndroidTypeface (const Font& font)
: Typeface (font.getTypefaceName(), font.getTypefaceStyle()),
ascent (0),
descent (0)
ascent (0), descent (0), heightToPointsFactor (1.0f)
{
JNIEnv* const env = getEnv();
@@ -121,17 +123,20 @@ public:
paint = GlobalRef (GraphicsHelpers::createPaint (Graphics::highResamplingQuality));
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)
{
@@ -149,7 +154,7 @@ public:
for (int i = 0; i < numDone; ++i)
x += localWidths[i];
return x * unitsToHeightScaleFactor;
return x * referenceFontToUnits;
}
void getGlyphPositions (const String& text, Array<int>& glyphs, Array<float>& xOffsets)
@@ -173,7 +178,7 @@ public:
{
glyphs.add ((int) s.getAndAdvance());
x += localWidths[i];
xOffsets.add (x * unitsToHeightScaleFactor);
xOffsets.add (x * referenceFontToUnits);
}
}
@@ -186,7 +191,7 @@ public:
{
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());
env->DeleteLocalRef (matrix);
@@ -227,7 +232,7 @@ public:
}
GlobalRef typeface, paint, rect;
float ascent, descent, unitsToHeightScaleFactor;
float ascent, descent, heightToPointsFactor;
private:
static File findFontFile (const String& family,


+ 1
- 1
modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm View File

@@ -561,7 +561,7 @@ void CoreGraphicsContext::setFont (const Font& newFont)
{
state->fontRef = osxTypeface->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.a *= state->font.getHorizontalScale();


+ 51
- 48
modules/juce_graphics/native/juce_mac_Fonts.mm View File

@@ -28,6 +28,8 @@
#define JUCE_CORETEXT_AVAILABLE 1
#endif
const float referenceFontSize = 1024.0f;
#if JUCE_CORETEXT_AVAILABLE
#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,
const float fontSize, const Font& font)
const float fontSizePoints, const Font& font)
{
CFStringRef cfActualFontFamily = (CFStringRef) CTFontCopyAttribute (ctFontRef, kCTFontFamilyNameAttribute);
if (CFStringCompare (cfFontFamily, cfActualFontFamily, 0) != kCFCompareEqualTo)
{
CFRelease (ctFontRef);
ctFontRef = CTFontCreateWithName (cfFontFamily, fontSize, nullptr);
ctFontRef = CTFontCreateWithName (cfFontFamily, fontSizePoints, nullptr);
if (font.isItalic()) ctFontRef = getFontWithTrait (ctFontRef, kCTFontItalicTrait);
if (font.isBold()) ctFontRef = getFontWithTrait (ctFontRef, kCTFontBoldTrait);
@@ -88,8 +90,24 @@ namespace CoreTextTypeLayout
}
#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 cfFontStyle = findBestAvailableStyle (font, transformRequired).toCFString();
@@ -106,27 +124,15 @@ namespace CoreTextTypeLayout
CTFontDescriptorRef ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes);
CFRelease (fontDescAttributes);
CTFontRef ctFontRef = CTFontCreateWithFontDescriptor (ctFontDescRef, fontSize, nullptr);
CTFontRef ctFontRef = CTFontCreateWithFontDescriptor (ctFontDescRef, fontSizePoints, nullptr);
CFRelease (ctFontDescRef);
#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
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;
}
@@ -209,7 +215,8 @@ namespace CoreTextTypeLayout
if (const Font* const f = attr->getFont())
{
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()),
kCTFontAttributeName, ctFontRef);
@@ -362,21 +369,18 @@ namespace CoreTextTypeLayout
if (CFDictionaryGetValueIfPresent (runAttributes, kCTFontAttributeName, (const void **) &ctRunFont))
{
CFStringRef cfsFontName = CTFontCopyPostScriptName (ctRunFont);
CTFontRef ctFontRef = CTFontCreateWithName (cfsFontName, 1024, nullptr);
CTFontRef ctFontRef = CTFontCreateWithName (cfsFontName, referenceFontSize, nullptr);
CFRelease (cfsFontName);
CGFontRef cgFontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr);
const float fontHeightToPointsFactor = getHeightToPointsFactor (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 cfsFontStyle = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontStyleNameAttribute);
glyphRun->font = Font (String::fromCFString (cfsFontFamily),
String::fromCFString (cfsFontStyle),
CTFontGetSize (ctRunFont) / fontHeightToCGSizeFactor);
CTFontGetSize (ctRunFont) / fontHeightToPointsFactor);
CFRelease (cfsFontStyle);
CFRelease (cfsFontFamily);
@@ -415,29 +419,27 @@ public:
: Typeface (font.getTypefaceName(),
font.getTypefaceStyle()),
fontRef (nullptr),
fontHeightToCGSizeFactor (1.0f),
fontHeightToPointsFactor (1.0f),
renderingTransform (CGAffineTransformIdentity),
ctFontRef (nullptr),
attributedStringAtts (nullptr),
ascent (0.0f),
unitsToHeightScaleFactor (0.0f)
{
ctFontRef = CoreTextTypeLayout::createCTFont (font, 1024.0f, renderingTransform, false);
ctFontRef = CoreTextTypeLayout::createCTFont (font, referenceFontSize, renderingTransform);
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);
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;
CFNumberRef numberRef = CFNumberCreate (0, kCFNumberShortType, &zero);
@@ -462,8 +464,9 @@ public:
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)
{
@@ -565,7 +568,7 @@ public:
//==============================================================================
CGFontRef fontRef;
float fontHeightToCGSizeFactor;
float fontHeightToPointsFactor;
CGAffineTransform renderingTransform;
private:
@@ -717,7 +720,7 @@ public:
juceStringToNS (style), NSFontFaceAttribute, nil];
NSFontDescriptor* nsFontDesc = [NSFontDescriptor fontDescriptorWithFontAttributes: nsDict];
nsFont = [NSFont fontWithDescriptor: nsFontDesc size: 1024];
nsFont = [NSFont fontWithDescriptor: nsFontDesc size: referenceFontSize];
[nsFont retain];
@@ -737,7 +740,7 @@ public:
const float totalHeight = std::abs ([nsFont ascender]) + std::abs ([nsFont descender]);
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = 1024.0f / totalHeight;
fontHeightToPointsFactor = referenceFontSize / totalHeight;
#else
#if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
@@ -751,16 +754,15 @@ public:
const float totalHeight = std::abs ([nsFont ascender]) + std::abs ([nsFont descender]);
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = 1024.0f / totalHeight;
fontHeightToPointsFactor = referenceFontSize / totalHeight;
}
else
#endif
{
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
}
@@ -775,8 +777,9 @@ public:
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)
{
@@ -928,7 +931,7 @@ public:
//==============================================================================
CGFontRef fontRef;
float fontHeightToCGSizeFactor;
float fontHeightToPointsFactor;
CGAffineTransform renderingTransform;
private:


+ 1
- 1
modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp View File

@@ -547,7 +547,7 @@ public:
{
WindowsDirectWriteTypeface* typeface = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface());
currentFontFace = typeface->getIDWriteFontFace();
fontHeightToEmSizeFactor = typeface->getFontHeightToEmSizeFactor();
fontHeightToEmSizeFactor = typeface->unitsToHeightScaleFactor();
}
}


+ 1
- 1
modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp View File

@@ -160,7 +160,7 @@ namespace DirectWriteTypeLayout
};
//==================================================================================================
float getFontHeightToEmSizeFactor (IDWriteFont* const dwFont)
static float getFontHeightToEmSizeFactor (IDWriteFont* const dwFont)
{
ComSmartPtr<IDWriteFontFace> dwFontFace;
dwFont->CreateFontFace (dwFontFace.resetAndGetPointerAddress());


+ 3
- 3
modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp View File

@@ -181,8 +181,9 @@ public:
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)
{
@@ -250,7 +251,6 @@ public:
}
IDWriteFontFace* getIDWriteFontFace() const noexcept { return dwFontFace; }
float getFontHeightToEmSizeFactor() const noexcept { return unitsToHeightScaleFactor; }
private:
ComSmartPtr<IDWriteFontFace> dwFontFace;


+ 8
- 6
modules/juce_graphics/native/juce_win32_Fonts.cpp View File

@@ -210,13 +210,14 @@ public:
fontH (0),
previousFontH (0),
dc (CreateCompatibleDC (0)),
ascent (1.0f),
ascent (1.0f), heightToPointsFactor (1.0f),
defaultGlyph (-1)
{
loadFont();
if (GetTextMetrics (dc, &tm))
{
heightToPointsFactor = 256.0f / tm.tmHeight;
ascent = tm.tmAscent / (float) tm.tmHeight;
defaultGlyph = getGlyphForChar (dc, tm.tmDefaultChar);
createKerningPairs (dc, (float) tm.tmHeight);
@@ -232,8 +233,9 @@ public:
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)
{
@@ -352,7 +354,7 @@ private:
HGDIOBJ previousFontH;
HDC dc;
TEXTMETRIC tm;
float ascent;
float ascent, heightToPointsFactor;
int defaultGlyph;
struct KerningPair
@@ -492,7 +494,7 @@ Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
if (factories.systemFonts != nullptr)
return new WindowsDirectWriteTypeface (font, factories.systemFonts);
else
#endif
return new WindowsTypeface (font);
return new WindowsTypeface (font);
}

Loading…
Cancel
Save