mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Initial commit of font style access, providing access to the styles available for each font family.
This commit is contained in:
parent
9c21813960
commit
941907a3d1
14 changed files with 824 additions and 348 deletions
|
|
@ -38,7 +38,7 @@ SourceCodeEditor::SourceCodeEditor (OpenDocumentManager::Document* document_,
|
|||
|
||||
#if JUCE_MAC
|
||||
Font font (10.6f);
|
||||
font.setTypefaceName ("Menlo Regular");
|
||||
font.setTypefaceName ("Menlo");
|
||||
#else
|
||||
Font font (10.0f);
|
||||
font.setTypefaceName (Font::getDefaultMonospacedFontName());
|
||||
|
|
|
|||
|
|
@ -102,13 +102,13 @@ namespace CustomTypefaceHelpers
|
|||
|
||||
//==============================================================================
|
||||
CustomTypeface::CustomTypeface()
|
||||
: Typeface (String::empty)
|
||||
: Typeface (String::empty, String::empty)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
CustomTypeface::CustomTypeface (InputStream& serialisedTypefaceStream)
|
||||
: Typeface (String::empty)
|
||||
: Typeface (String::empty, String::empty)
|
||||
{
|
||||
clear();
|
||||
|
||||
|
|
@ -116,8 +116,11 @@ CustomTypeface::CustomTypeface (InputStream& serialisedTypefaceStream)
|
|||
BufferedInputStream in (gzin, 32768);
|
||||
|
||||
name = in.readString();
|
||||
isBold = in.readBool();
|
||||
isItalic = in.readBool();
|
||||
|
||||
const bool isBold = in.readBool();
|
||||
const bool isItalic = in.readBool();
|
||||
style = FontStyleHelpers::getStyleName (isBold, isItalic);
|
||||
|
||||
ascent = in.readFloat();
|
||||
defaultCharacter = CustomTypefaceHelpers::readChar (in);
|
||||
|
||||
|
|
@ -153,19 +156,27 @@ void CustomTypeface::clear()
|
|||
{
|
||||
defaultCharacter = 0;
|
||||
ascent = 1.0f;
|
||||
isBold = isItalic = false;
|
||||
style = "Regular";
|
||||
zeromem (lookupTable, sizeof (lookupTable));
|
||||
glyphs.clear();
|
||||
}
|
||||
|
||||
void CustomTypeface::setCharacteristics (const String& name_, const float ascent_, const bool isBold_,
|
||||
const bool isItalic_, const juce_wchar defaultCharacter_) noexcept
|
||||
void CustomTypeface::setCharacteristics (const String& name_, const float ascent_, const bool isBold,
|
||||
const bool isItalic, const juce_wchar defaultCharacter_) noexcept
|
||||
{
|
||||
name = name_;
|
||||
defaultCharacter = defaultCharacter_;
|
||||
ascent = ascent_;
|
||||
isBold = isBold_;
|
||||
isItalic = isItalic_;
|
||||
style = FontStyleHelpers::getStyleName (isBold, isItalic);
|
||||
}
|
||||
|
||||
void CustomTypeface::setCharacteristics (const String& name_, const String& style_, const float ascent_,
|
||||
const juce_wchar defaultCharacter_) noexcept
|
||||
{
|
||||
name = name_;
|
||||
style = style_;
|
||||
defaultCharacter = defaultCharacter_;
|
||||
ascent = ascent_;
|
||||
}
|
||||
|
||||
void CustomTypeface::addGlyph (const juce_wchar character, const Path& path, const float width) noexcept
|
||||
|
|
@ -216,7 +227,7 @@ bool CustomTypeface::loadGlyphIfPossible (const juce_wchar /*characterNeeded*/)
|
|||
|
||||
void CustomTypeface::addGlyphsFromOtherTypeface (Typeface& typefaceToCopy, juce_wchar characterStartIndex, int numCharacters) noexcept
|
||||
{
|
||||
setCharacteristics (name, typefaceToCopy.getAscent(), isBold, isItalic, defaultCharacter);
|
||||
setCharacteristics (name, style, typefaceToCopy.getAscent(), defaultCharacter);
|
||||
|
||||
for (int i = 0; i < numCharacters; ++i)
|
||||
{
|
||||
|
|
@ -256,8 +267,8 @@ bool CustomTypeface::writeToStream (OutputStream& outputStream)
|
|||
GZIPCompressorOutputStream out (&outputStream);
|
||||
|
||||
out.writeString (name);
|
||||
out.writeBool (isBold);
|
||||
out.writeBool (isItalic);
|
||||
out.writeBool (FontStyleHelpers::isBold (style));
|
||||
out.writeBool (FontStyleHelpers::isItalic (style));
|
||||
out.writeFloat (ascent);
|
||||
CustomTypefaceHelpers::writeChar (out, defaultCharacter);
|
||||
out.writeInt (glyphs.size());
|
||||
|
|
|
|||
|
|
@ -64,19 +64,31 @@ public:
|
|||
void clear();
|
||||
|
||||
/** Sets the vital statistics for the typeface.
|
||||
@param name the typeface's name
|
||||
@param ascent the ascent - this is normalised to a height of 1.0 and this is
|
||||
the value that will be returned by Typeface::getAscent(). The
|
||||
descent is assumed to be (1.0 - ascent)
|
||||
@param isBold should be true if the typeface is bold
|
||||
@param isItalic should be true if the typeface is italic
|
||||
@param defaultCharacter the character to be used as a replacement if there's
|
||||
no glyph available for the character that's being drawn
|
||||
@param fontFamily the typeface's font family
|
||||
@param ascent the ascent - this is normalised to a height of 1.0 and this is
|
||||
the value that will be returned by Typeface::getAscent(). The
|
||||
descent is assumed to be (1.0 - ascent)
|
||||
@param isBold should be true if the typeface is bold
|
||||
@param isItalic should be true if the typeface is italic
|
||||
@param defaultCharacter the character to be used as a replacement if there's
|
||||
no glyph available for the character that's being drawn
|
||||
*/
|
||||
void setCharacteristics (const String& name, float ascent,
|
||||
void setCharacteristics (const String& fontFamily, float ascent,
|
||||
bool isBold, bool isItalic,
|
||||
juce_wchar defaultCharacter) noexcept;
|
||||
|
||||
/** Sets the vital statistics for the typeface.
|
||||
@param fontFamily the typeface's font family
|
||||
@param fontStyle the typeface's font style
|
||||
@param ascent the ascent - this is normalised to a height of 1.0 and this is
|
||||
the value that will be returned by Typeface::getAscent(). The
|
||||
descent is assumed to be (1.0 - ascent)
|
||||
@param defaultCharacter the character to be used as a replacement if there's
|
||||
no glyph available for the character that's being drawn
|
||||
*/
|
||||
void setCharacteristics (const String& fontFamily, const String& fontStyle,
|
||||
float ascent, juce_wchar defaultCharacter) noexcept;
|
||||
|
||||
/** Adds a glyph to the typeface.
|
||||
|
||||
The path that is passed in is normalised so that the font height is 1.0, and its
|
||||
|
|
@ -117,7 +129,6 @@ protected:
|
|||
//==============================================================================
|
||||
juce_wchar defaultCharacter;
|
||||
float ascent;
|
||||
bool isBold, isItalic;
|
||||
|
||||
//==============================================================================
|
||||
/** If a subclass overrides this, it can load glyphs into the font on-demand.
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace FontValues
|
|||
|
||||
const float defaultFontHeight = 14.0f;
|
||||
String fallbackFont;
|
||||
String fallbackFontStyle;
|
||||
}
|
||||
|
||||
typedef Typeface::Ptr (*GetTypefaceForFont) (const Font&);
|
||||
|
|
@ -62,16 +63,18 @@ public:
|
|||
|
||||
Typeface::Ptr findTypefaceFor (const Font& font)
|
||||
{
|
||||
const int flags = font.getStyleFlags() & (Font::bold | Font::italic);
|
||||
const String faceName (font.getTypefaceName());
|
||||
const String faceStyle (font.getTypefaceStyle());
|
||||
|
||||
int i;
|
||||
for (i = faces.size(); --i >= 0;)
|
||||
jassert (faceName.isNotEmpty());
|
||||
|
||||
for (int i = faces.size(); --i >= 0;)
|
||||
{
|
||||
CachedFace& face = faces.getReference(i);
|
||||
|
||||
if (face.flags == flags
|
||||
&& face.typefaceName == faceName
|
||||
if (face.typefaceName == faceName
|
||||
&& face.typefaceStyle == faceStyle
|
||||
&& face.typeface != nullptr
|
||||
&& face.typeface->isSuitableForFont (font))
|
||||
{
|
||||
face.lastUsageCount = ++counter;
|
||||
|
|
@ -82,7 +85,7 @@ public:
|
|||
int replaceIndex = 0;
|
||||
size_t bestLastUsageCount = std::numeric_limits<int>::max();
|
||||
|
||||
for (i = faces.size(); --i >= 0;)
|
||||
for (int i = faces.size(); --i >= 0;)
|
||||
{
|
||||
const size_t lu = faces.getReference(i).lastUsageCount;
|
||||
|
||||
|
|
@ -95,7 +98,7 @@ public:
|
|||
|
||||
CachedFace& face = faces.getReference (replaceIndex);
|
||||
face.typefaceName = faceName;
|
||||
face.flags = flags;
|
||||
face.typefaceStyle = faceStyle;
|
||||
face.lastUsageCount = ++counter;
|
||||
|
||||
if (juce_getTypefaceForFont == nullptr)
|
||||
|
|
@ -120,7 +123,7 @@ private:
|
|||
struct CachedFace
|
||||
{
|
||||
CachedFace() noexcept
|
||||
: lastUsageCount (0), flags (-1)
|
||||
: lastUsageCount (0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -129,8 +132,8 @@ private:
|
|||
// Since the typeface itself doesn't know that it may have this alias, the name under
|
||||
// which it was fetched needs to be stored separately.
|
||||
String typefaceName;
|
||||
String typefaceStyle;
|
||||
size_t lastUsageCount;
|
||||
int flags;
|
||||
Typeface::Ptr typeface;
|
||||
};
|
||||
|
||||
|
|
@ -152,47 +155,54 @@ void Typeface::setTypefaceCacheSize (int numFontsToCache)
|
|||
class Font::SharedFontInternal : public SingleThreadedReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
SharedFontInternal (const float height_, const int styleFlags_) noexcept
|
||||
SharedFontInternal (const String& typefaceStyle_, const float height_) noexcept
|
||||
: typefaceName (Font::getDefaultSansSerifFontName()),
|
||||
typefaceStyle (typefaceStyle_),
|
||||
height (height_),
|
||||
horizontalScale (1.0f),
|
||||
kerning (0),
|
||||
ascent (0),
|
||||
styleFlags (styleFlags_),
|
||||
typeface ((styleFlags_ & (Font::bold | Font::italic)) == 0
|
||||
underline (false),
|
||||
typeface (typefaceStyle_ == Font::getDefaultStyle()
|
||||
? TypefaceCache::getInstance()->getDefaultTypeface() : nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SharedFontInternal (const String& typefaceName_, const float height_, const int styleFlags_) noexcept
|
||||
SharedFontInternal (const String& typefaceName_, const String& typefaceStyle_, const float height_) noexcept
|
||||
: typefaceName (typefaceName_),
|
||||
typefaceStyle (typefaceStyle_),
|
||||
height (height_),
|
||||
horizontalScale (1.0f),
|
||||
kerning (0),
|
||||
ascent (0),
|
||||
styleFlags (styleFlags_),
|
||||
underline (false),
|
||||
typeface (nullptr)
|
||||
{
|
||||
if (typefaceName.isEmpty())
|
||||
typefaceName = Font::getDefaultSansSerifFontName();
|
||||
}
|
||||
|
||||
SharedFontInternal (const Typeface::Ptr& typeface_) noexcept
|
||||
: typefaceName (typeface_->getName()),
|
||||
typefaceStyle (typeface_->getStyle()),
|
||||
height (FontValues::defaultFontHeight),
|
||||
horizontalScale (1.0f),
|
||||
kerning (0),
|
||||
ascent (0),
|
||||
styleFlags (Font::plain),
|
||||
underline (false),
|
||||
typeface (typeface_)
|
||||
{
|
||||
jassert (typefaceName.isNotEmpty());
|
||||
}
|
||||
|
||||
SharedFontInternal (const SharedFontInternal& other) noexcept
|
||||
: typefaceName (other.typefaceName),
|
||||
typefaceStyle (other.typefaceStyle),
|
||||
height (other.height),
|
||||
horizontalScale (other.horizontalScale),
|
||||
kerning (other.kerning),
|
||||
ascent (other.ascent),
|
||||
styleFlags (other.styleFlags),
|
||||
underline (other.underline),
|
||||
typeface (other.typeface)
|
||||
{
|
||||
}
|
||||
|
|
@ -200,31 +210,44 @@ public:
|
|||
bool operator== (const SharedFontInternal& other) const noexcept
|
||||
{
|
||||
return height == other.height
|
||||
&& styleFlags == other.styleFlags
|
||||
&& underline == other.underline
|
||||
&& horizontalScale == other.horizontalScale
|
||||
&& kerning == other.kerning
|
||||
&& typefaceName == other.typefaceName;
|
||||
&& typefaceName == other.typefaceName
|
||||
&& typefaceStyle == other.typefaceStyle;
|
||||
}
|
||||
|
||||
String typefaceName;
|
||||
String typefaceName, typefaceStyle;
|
||||
float height, horizontalScale, kerning, ascent;
|
||||
int styleFlags;
|
||||
bool underline;
|
||||
Typeface::Ptr typeface;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
Font::Font()
|
||||
: font (new SharedFontInternal (FontValues::defaultFontHeight, Font::plain))
|
||||
: font (new SharedFontInternal (Font::getDefaultStyle(), FontValues::defaultFontHeight))
|
||||
{
|
||||
}
|
||||
|
||||
Font::Font (const float fontHeight, const int styleFlags)
|
||||
: font (new SharedFontInternal (FontValues::limitFontHeight (fontHeight), styleFlags))
|
||||
: font (new SharedFontInternal (Font::getDefaultStyle(), FontValues::limitFontHeight (fontHeight)))
|
||||
{
|
||||
setStyleFlags(styleFlags);
|
||||
}
|
||||
|
||||
Font::Font (const String& typefaceName, const float fontHeight, const int styleFlags)
|
||||
: font (new SharedFontInternal (typefaceName, FontValues::limitFontHeight (fontHeight), styleFlags))
|
||||
: font (new SharedFontInternal (typefaceName, Font::getDefaultStyle(), FontValues::limitFontHeight (fontHeight)))
|
||||
{
|
||||
setStyleFlags (styleFlags);
|
||||
}
|
||||
|
||||
Font::Font (const String& typefaceStyle, float fontHeight)
|
||||
: font (new SharedFontInternal (typefaceStyle, FontValues::limitFontHeight (fontHeight)))
|
||||
{
|
||||
}
|
||||
|
||||
Font::Font (const String& typefaceName, const String& typefaceStyle, float fontHeight)
|
||||
: font (new SharedFontInternal (typefaceName, typefaceStyle, FontValues::limitFontHeight (fontHeight)))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -297,6 +320,12 @@ const String& Font::getDefaultMonospacedFontName()
|
|||
return name;
|
||||
}
|
||||
|
||||
const String& Font::getDefaultStyle()
|
||||
{
|
||||
static const String style ("<Regular>");
|
||||
return style;
|
||||
}
|
||||
|
||||
const String& Font::getTypefaceName() const noexcept
|
||||
{
|
||||
return font->typefaceName;
|
||||
|
|
@ -306,6 +335,8 @@ void Font::setTypefaceName (const String& faceName)
|
|||
{
|
||||
if (faceName != font->typefaceName)
|
||||
{
|
||||
jassert (faceName.isNotEmpty());
|
||||
|
||||
dupeInternalIfShared();
|
||||
font->typefaceName = faceName;
|
||||
font->typeface = nullptr;
|
||||
|
|
@ -313,6 +344,22 @@ void Font::setTypefaceName (const String& faceName)
|
|||
}
|
||||
}
|
||||
|
||||
const String& Font::getTypefaceStyle() const noexcept
|
||||
{
|
||||
return font->typefaceStyle;
|
||||
}
|
||||
|
||||
void Font::setTypefaceStyle (const String& typefaceStyle)
|
||||
{
|
||||
if (typefaceStyle != font->typefaceStyle)
|
||||
{
|
||||
dupeInternalIfShared();
|
||||
font->typefaceStyle = typefaceStyle;
|
||||
font->typeface = nullptr;
|
||||
font->ascent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Typeface* Font::getTypeface() const
|
||||
{
|
||||
if (font->typeface == nullptr)
|
||||
|
|
@ -336,6 +383,20 @@ void Font::setFallbackFontName (const String& name)
|
|||
#endif
|
||||
}
|
||||
|
||||
const String& Font::getFallbackFontStyle()
|
||||
{
|
||||
return FontValues::fallbackFontStyle;
|
||||
}
|
||||
|
||||
void Font::setFallbackFontStyle (const String& style)
|
||||
{
|
||||
FontValues::fallbackFontStyle = style;
|
||||
|
||||
#if JUCE_MAC || JUCE_IOS
|
||||
jassertfalse; // Note that use of a fallback font isn't currently implemented in OSX..
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
float Font::getHeight() const noexcept
|
||||
{
|
||||
|
|
@ -374,7 +435,12 @@ void Font::setHeightWithoutChangingWidth (float newHeight)
|
|||
|
||||
int Font::getStyleFlags() const noexcept
|
||||
{
|
||||
return font->styleFlags;
|
||||
int styleFlags = font->underline ? underlined : plain;
|
||||
|
||||
if (isBold()) styleFlags |= bold;
|
||||
if (isItalic()) styleFlags |= italic;
|
||||
|
||||
return styleFlags;
|
||||
}
|
||||
|
||||
Font Font::withStyle (const int newFlags) const
|
||||
|
|
@ -386,10 +452,12 @@ Font Font::withStyle (const int newFlags) const
|
|||
|
||||
void Font::setStyleFlags (const int newFlags)
|
||||
{
|
||||
if (font->styleFlags != newFlags)
|
||||
if (getStyleFlags() != newFlags)
|
||||
{
|
||||
dupeInternalIfShared();
|
||||
font->styleFlags = newFlags;
|
||||
font->typefaceStyle = FontStyleHelpers::getStyleName ((newFlags & bold) != 0,
|
||||
(newFlags & italic) != 0);
|
||||
font->underline = (newFlags & underlined) != 0;
|
||||
font->typeface = nullptr;
|
||||
font->ascent = 0;
|
||||
}
|
||||
|
|
@ -415,6 +483,26 @@ void Font::setSizeAndStyle (float newHeight,
|
|||
setStyleFlags (newStyleFlags);
|
||||
}
|
||||
|
||||
void Font::setSizeAndStyle (float newHeight,
|
||||
const String& newStyle,
|
||||
const float newHorizontalScale,
|
||||
const float newKerningAmount)
|
||||
{
|
||||
newHeight = FontValues::limitFontHeight (newHeight);
|
||||
|
||||
if (font->height != newHeight
|
||||
|| font->horizontalScale != newHorizontalScale
|
||||
|| font->kerning != newKerningAmount)
|
||||
{
|
||||
dupeInternalIfShared();
|
||||
font->height = newHeight;
|
||||
font->horizontalScale = newHorizontalScale;
|
||||
font->kerning = newKerningAmount;
|
||||
}
|
||||
|
||||
setTypefaceStyle (newStyle);
|
||||
}
|
||||
|
||||
float Font::getHorizontalScale() const noexcept
|
||||
{
|
||||
return font->horizontalScale;
|
||||
|
|
@ -451,33 +539,41 @@ void Font::setExtraKerningFactor (const float extraKerning)
|
|||
font->kerning = extraKerning;
|
||||
}
|
||||
|
||||
Font Font::boldened() const { return withStyle (font->styleFlags | bold); }
|
||||
Font Font::italicised() const { return withStyle (font->styleFlags | italic); }
|
||||
Font Font::boldened() const { return withStyle (getStyleFlags() | bold); }
|
||||
Font Font::italicised() const { return withStyle (getStyleFlags() | italic); }
|
||||
|
||||
bool Font::isBold() const noexcept { return (font->styleFlags & bold) != 0; }
|
||||
bool Font::isItalic() const noexcept { return (font->styleFlags & italic) != 0; }
|
||||
bool Font::isBold() const noexcept
|
||||
{
|
||||
return FontStyleHelpers::isBold (font->typefaceStyle);
|
||||
}
|
||||
|
||||
bool Font::isItalic() const noexcept
|
||||
{
|
||||
return FontStyleHelpers::isItalic (font->typefaceStyle);
|
||||
}
|
||||
|
||||
void Font::setBold (const bool shouldBeBold)
|
||||
{
|
||||
setStyleFlags (shouldBeBold ? (font->styleFlags | bold)
|
||||
: (font->styleFlags & ~bold));
|
||||
const int flags = getStyleFlags();
|
||||
setStyleFlags (shouldBeBold ? (flags | bold)
|
||||
: (flags & ~bold));
|
||||
}
|
||||
|
||||
void Font::setItalic (const bool shouldBeItalic)
|
||||
{
|
||||
setStyleFlags (shouldBeItalic ? (font->styleFlags | italic)
|
||||
: (font->styleFlags & ~italic));
|
||||
const int flags = getStyleFlags();
|
||||
setStyleFlags (shouldBeItalic ? (flags | italic)
|
||||
: (flags & ~italic));
|
||||
}
|
||||
|
||||
void Font::setUnderline (const bool shouldBeUnderlined)
|
||||
{
|
||||
setStyleFlags (shouldBeUnderlined ? (font->styleFlags | underlined)
|
||||
: (font->styleFlags & ~underlined));
|
||||
font->underline = shouldBeUnderlined;
|
||||
}
|
||||
|
||||
bool Font::isUnderlined() const noexcept
|
||||
{
|
||||
return (font->styleFlags & underlined) != 0;
|
||||
return font->underline;
|
||||
}
|
||||
|
||||
float Font::getAscent() const
|
||||
|
|
@ -537,23 +633,30 @@ void Font::findFonts (Array<Font>& destArray)
|
|||
const StringArray names (findAllTypefaceNames());
|
||||
|
||||
for (int i = 0; i < names.size(); ++i)
|
||||
destArray.add (Font (names[i], FontValues::defaultFontHeight, Font::plain));
|
||||
{
|
||||
const StringArray styles (findAllTypefaceStyles (names[i]));
|
||||
|
||||
String style ("Regular");
|
||||
|
||||
if (! styles.contains (style, true))
|
||||
style = styles[0];
|
||||
|
||||
destArray.add (Font (names[i], style, FontValues::defaultFontHeight));
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
String Font::toString() const
|
||||
{
|
||||
String s (getTypefaceName());
|
||||
String s;
|
||||
|
||||
if (s == getDefaultSansSerifFontName())
|
||||
s = String::empty;
|
||||
else
|
||||
s += "; ";
|
||||
if (getTypefaceName() != getDefaultSansSerifFontName())
|
||||
s << getTypefaceName() << "; ";
|
||||
|
||||
s += String (getHeight(), 1);
|
||||
s << String (getHeight(), 1);
|
||||
|
||||
if (isBold()) s += " bold";
|
||||
if (isItalic()) s += " italic";
|
||||
if (getTypefaceStyle() != getDefaultStyle())
|
||||
s << ' ' << getTypefaceStyle();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
@ -575,9 +678,7 @@ Font Font::fromString (const String& fontDescription)
|
|||
if (height <= 0)
|
||||
height = 10.0f;
|
||||
|
||||
int flags = Font::plain;
|
||||
if (sizeAndStyle.containsIgnoreCase ("bold")) flags |= Font::bold;
|
||||
if (sizeAndStyle.containsIgnoreCase ("italic")) flags |= Font::italic;
|
||||
const String style (sizeAndStyle.fromFirstOccurrenceOf (" ", false, false));
|
||||
|
||||
return Font (name, height, flags);
|
||||
return Font (name, style, height);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public:
|
|||
|
||||
/** Creates a font with a given typeface and parameters.
|
||||
|
||||
@param typefaceName the name of the typeface to use
|
||||
@param typefaceName the font family of the typeface to use
|
||||
@param fontHeight the height in pixels (can be fractional)
|
||||
@param styleFlags the style to use - this can be a combination of the
|
||||
Font::bold, Font::italic and Font::underlined, or
|
||||
|
|
@ -77,6 +77,21 @@ public:
|
|||
*/
|
||||
Font (const String& typefaceName, float fontHeight, int styleFlags);
|
||||
|
||||
/** Creates a sans-serif font in a given style and size.
|
||||
|
||||
@param typefaceStyle the font style of the typeface to use
|
||||
@param fontHeight the height in pixels (can be fractional)
|
||||
*/
|
||||
Font (const String& typefaceStyle, float fontHeight);
|
||||
|
||||
/** Creates a font with a given typeface and parameters.
|
||||
|
||||
@param typefaceName the font family of the typeface to use
|
||||
@param typefaceStyle the font style of the typeface to use
|
||||
@param fontHeight the height in pixels (can be fractional)
|
||||
*/
|
||||
Font (const String& typefaceName, const String& typefaceStyle, float fontHeight);
|
||||
|
||||
/** Creates a copy of another Font object. */
|
||||
Font (const Font& other) noexcept;
|
||||
|
||||
|
|
@ -106,64 +121,88 @@ public:
|
|||
~Font() noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the name of the typeface family.
|
||||
/** Changes the font family of the typeface.
|
||||
|
||||
e.g. "Arial", "Courier", etc.
|
||||
|
||||
This may also be set to Font::getDefaultSansSerifFontName(), Font::getDefaultSerifFontName(),
|
||||
or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font names,
|
||||
but are generic names that are used to represent the various default fonts.
|
||||
If you need to know the exact typeface name being used, you can call
|
||||
Font::getTypeface()->getTypefaceName(), which will give you the platform-specific name.
|
||||
or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font family names,
|
||||
but are generic font family names that are used to represent the various default fonts.
|
||||
If you need to know the exact typeface font family being used, you can call
|
||||
Font::getTypeface()->getFamily(), which will give you the platform-specific font family.
|
||||
|
||||
If a suitable font isn't found on the machine, it'll just use a default instead.
|
||||
*/
|
||||
void setTypefaceName (const String& faceName);
|
||||
|
||||
/** Returns the name of the typeface family that this font uses.
|
||||
/** Returns the font family of the typeface that this font uses.
|
||||
|
||||
e.g. "Arial", "Courier", etc.
|
||||
|
||||
This may also be set to Font::getDefaultSansSerifFontName(), Font::getDefaultSerifFontName(),
|
||||
or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font names,
|
||||
but are generic names that are used to represent the various default fonts.
|
||||
or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font family names,
|
||||
but are generic font familiy names that are used to represent the various default fonts.
|
||||
|
||||
If you need to know the exact typeface name being used, you can call
|
||||
Font::getTypeface()->getTypefaceName(), which will give you the platform-specific name.
|
||||
If you need to know the exact typeface font family being used, you can call
|
||||
Font::getTypeface()->getFamily(), which will give you the platform-specific font family.
|
||||
*/
|
||||
const String& getTypefaceName() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a typeface name that represents the default sans-serif font.
|
||||
/** Changes the font style of the typeface
|
||||
|
||||
e.g. "Regular", "Italic", etc.
|
||||
|
||||
*/
|
||||
void setTypefaceStyle (const String& typefaceStyle);
|
||||
|
||||
/** Returns the font style of the typeface that this font uses.
|
||||
|
||||
e.g. "Regular", "Italic", etc.
|
||||
|
||||
*/
|
||||
const String& getTypefaceStyle() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a typeface font family that represents the default sans-serif font.
|
||||
|
||||
This is also the typeface that will be used when a font is created without
|
||||
specifying any typeface details.
|
||||
|
||||
Note that this method just returns a generic placeholder string that means "the default
|
||||
sans-serif font" - it's not the actual name of this font.
|
||||
sans-serif font" - it's not the actual font family of this font.
|
||||
|
||||
@see setTypefaceName, getDefaultSerifFontName, getDefaultMonospacedFontName
|
||||
*/
|
||||
static const String& getDefaultSansSerifFontName();
|
||||
|
||||
/** Returns a typeface name that represents the default sans-serif font.
|
||||
/** Returns a typeface font family that represents the default sans-serif font.
|
||||
|
||||
Note that this method just returns a generic placeholder string that means "the default
|
||||
serif font" - it's not the actual name of this font.
|
||||
serif font" - it's not the actual font family of this font.
|
||||
|
||||
@see setTypefaceName, getDefaultSansSerifFontName, getDefaultMonospacedFontName
|
||||
*/
|
||||
static const String& getDefaultSerifFontName();
|
||||
|
||||
/** Returns a typeface name that represents the default sans-serif font.
|
||||
/** Returns a typeface font family that represents the default sans-serif font.
|
||||
|
||||
Note that this method just returns a generic placeholder string that means "the default
|
||||
monospaced font" - it's not the actual name of this font.
|
||||
monospaced font" - it's not the actual font family of this font.
|
||||
|
||||
@see setTypefaceName, getDefaultSansSerifFontName, getDefaultSerifFontName
|
||||
*/
|
||||
static const String& getDefaultMonospacedFontName();
|
||||
|
||||
/** Returns a typeface font style that represents the default sans-serif font.
|
||||
|
||||
Note that this method just returns a generic placeholder string that means "the default
|
||||
font style" - it's not the actual font style of this font.
|
||||
|
||||
@see setTypefaceStyle
|
||||
*/
|
||||
static const String& getDefaultStyle();
|
||||
|
||||
/** Returns the default system typeface for the given font. */
|
||||
static Typeface::Ptr getDefaultTypefaceForFont (const Font& font);
|
||||
|
||||
|
|
@ -299,6 +338,12 @@ public:
|
|||
float newHorizontalScale,
|
||||
float newKerningAmount);
|
||||
|
||||
/** Changes all the font's characteristics with one call. */
|
||||
void setSizeAndStyle (float newHeight,
|
||||
const String& newStyle,
|
||||
float newHorizontalScale,
|
||||
float newKerningAmount);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the total width of a string as it would be drawn using this font.
|
||||
|
||||
|
|
@ -329,33 +374,52 @@ public:
|
|||
|
||||
/** Creates an array of Font objects to represent all the fonts on the system.
|
||||
|
||||
If you just need the names of the typefaces, you can also use
|
||||
If you just need the font family names of the typefaces, you can also use
|
||||
findAllTypefaceNames() instead.
|
||||
|
||||
@param results the array to which new Font objects will be added.
|
||||
*/
|
||||
static void findFonts (Array<Font>& results);
|
||||
|
||||
/** Returns a list of all the available typeface names.
|
||||
/** Returns a list of all the available typeface font families.
|
||||
|
||||
The names returned can be passed into setTypefaceName().
|
||||
|
||||
You can use this instead of findFonts() if you only need their names, and not
|
||||
font objects.
|
||||
You can use this instead of findFonts() if you only need their font family names,
|
||||
and not font objects.
|
||||
*/
|
||||
static StringArray findAllTypefaceNames();
|
||||
|
||||
/** Returns a list of all the available typeface font styles.
|
||||
|
||||
The names returned can be passed into setTypefaceStyle().
|
||||
|
||||
You can use this instead of findFonts() if you only need their styles, and not
|
||||
font objects.
|
||||
*/
|
||||
static StringArray findAllTypefaceStyles (const String& family);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the name of the typeface to be used for rendering glyphs that aren't found
|
||||
in the requested typeface.
|
||||
/** Returns the font family of the typeface to be used for rendering glyphs that aren't
|
||||
found in the requested typeface.
|
||||
*/
|
||||
static const String& getFallbackFontName();
|
||||
|
||||
/** Sets the (platform-specific) name of the typeface to use to find glyphs that aren't
|
||||
available in whatever font you're trying to use.
|
||||
/** Sets the (platform-specific) font family of the typeface to use to find glyphs that
|
||||
aren't available in whatever font you're trying to use.
|
||||
*/
|
||||
static void setFallbackFontName (const String& name);
|
||||
|
||||
/** Returns the font style of the typeface to be used for rendering glyphs that aren't
|
||||
found in the requested typeface.
|
||||
*/
|
||||
static const String& getFallbackFontStyle();
|
||||
|
||||
/** Sets the (platform-specific) font style of the typeface to use to find glyphs that
|
||||
aren't available in whatever font you're trying to use.
|
||||
*/
|
||||
static void setFallbackFontStyle (const String& style);
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a string to describe this font.
|
||||
The string will contain information to describe the font's typeface, size, and
|
||||
|
|
|
|||
|
|
@ -23,8 +23,45 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
Typeface::Typeface (const String& name_) noexcept
|
||||
: name (name_)
|
||||
namespace FontStyleHelpers
|
||||
{
|
||||
static const char* getStyleName (const bool bold,
|
||||
const bool italic) noexcept
|
||||
{
|
||||
if (bold && ! italic) return "Bold";
|
||||
if (italic && ! bold) return "Italic";
|
||||
if (bold && italic) return "Bold Italic";
|
||||
return "Regular";
|
||||
}
|
||||
|
||||
static bool isBold (const String& style) noexcept
|
||||
{
|
||||
return style.containsWholeWordIgnoreCase ("Bold");
|
||||
}
|
||||
|
||||
static bool isItalic (const String& style) noexcept
|
||||
{
|
||||
return style.containsWholeWordIgnoreCase ("Italic")
|
||||
|| style.containsWholeWordIgnoreCase ("Oblique");
|
||||
}
|
||||
|
||||
static bool isPlaceholderFamilyName (const String& family)
|
||||
{
|
||||
return family == Font::getDefaultSansSerifFontName()
|
||||
|| family == Font::getDefaultSerifFontName()
|
||||
|| family == Font::getDefaultMonospacedFontName();
|
||||
}
|
||||
|
||||
static String getConcreteFamilyNameFromPlaceholder (const String& family)
|
||||
{
|
||||
const Font f (family, Font::getDefaultStyle(), 15.0f);
|
||||
return Font::getDefaultTypefaceForFont (f)->getName();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
Typeface::Typeface (const String& name_, const String& style_) noexcept
|
||||
: name (name_), style (style_)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +71,7 @@ Typeface::~Typeface()
|
|||
|
||||
Typeface::Ptr Typeface::getFallbackTypeface()
|
||||
{
|
||||
const Font fallbackFont (Font::getFallbackFontName(), 10, 0);
|
||||
const Font fallbackFont (Font::getFallbackFontName(), Font::getFallbackFontStyle(), 10.0f);
|
||||
return fallbackFont.getTypeface();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,11 +55,17 @@ public:
|
|||
typedef ReferenceCountedObjectPtr <Typeface> Ptr;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the name of the typeface.
|
||||
/** Returns the font family of the typeface.
|
||||
@see Font::getTypefaceName
|
||||
*/
|
||||
const String& getName() const noexcept { return name; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the font style of the typeface.
|
||||
@see Font::getTypefaceStyle
|
||||
*/
|
||||
const String& getStyle() const noexcept { return style; }
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a new system typeface. */
|
||||
static Ptr createSystemTypefaceFor (const Font& font);
|
||||
|
|
@ -122,9 +128,9 @@ public:
|
|||
|
||||
protected:
|
||||
//==============================================================================
|
||||
String name;
|
||||
String name, style;
|
||||
|
||||
explicit Typeface (const String& name) noexcept;
|
||||
Typeface (const String& name, const String& style) noexcept;
|
||||
|
||||
static Ptr getFallbackTypeface();
|
||||
|
||||
|
|
|
|||
|
|
@ -67,8 +67,6 @@
|
|||
namespace juce
|
||||
{
|
||||
|
||||
// START_AUTOINCLUDE colour/*.cpp, geometry/*.cpp, placement/*.cpp, contexts/*.cpp, images/*.cpp,
|
||||
// image_formats/*.cpp, fonts/*.cpp, effects/*.cpp
|
||||
#include "colour/juce_Colour.cpp"
|
||||
#include "colour/juce_ColourGradient.cpp"
|
||||
#include "colour/juce_Colours.cpp"
|
||||
|
|
@ -92,14 +90,13 @@ namespace juce
|
|||
#include "image_formats/juce_JPEGLoader.cpp"
|
||||
#include "image_formats/juce_PNGLoader.cpp"
|
||||
#include "fonts/juce_AttributedString.cpp"
|
||||
#include "fonts/juce_Typeface.cpp"
|
||||
#include "fonts/juce_CustomTypeface.cpp"
|
||||
#include "fonts/juce_Font.cpp"
|
||||
#include "fonts/juce_GlyphArrangement.cpp"
|
||||
#include "fonts/juce_TextLayout.cpp"
|
||||
#include "fonts/juce_Typeface.cpp"
|
||||
#include "effects/juce_DropShadowEffect.cpp"
|
||||
#include "effects/juce_GlowEffect.cpp"
|
||||
// END_AUTOINCLUDE
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_MAC || JUCE_IOS
|
||||
|
|
|
|||
|
|
@ -41,7 +41,22 @@ StringArray Font::findAllTypefaceNames()
|
|||
File ("/system/fonts").findChildFiles (fonts, File::findFiles, false, "*.ttf");
|
||||
|
||||
for (int i = 0; i < fonts.size(); ++i)
|
||||
results.add (fonts.getReference(i).getFileNameWithoutExtension());
|
||||
results.addIfNotAlreadyThere (fonts.getReference(i).getFileNameWithoutExtension()
|
||||
.upToLastOccurrenceOf ("-", false, false));
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
StringArray Font::findAllTypefaceStyles (const String& family)
|
||||
{
|
||||
StringArray results ("Regular");
|
||||
|
||||
Array<File> fonts;
|
||||
File ("/system/fonts").findChildFiles (fonts, File::findFiles, false, family + "-*.ttf");
|
||||
|
||||
for (int i = 0; i < fonts.size(); ++i)
|
||||
results.addIfNotAlreadyThere (fonts.getReference(i).getFileNameWithoutExtension()
|
||||
.fromLastOccurrenceOf ("-", false, false));
|
||||
|
||||
return results;
|
||||
}
|
||||
|
|
@ -79,24 +94,27 @@ class AndroidTypeface : public Typeface
|
|||
{
|
||||
public:
|
||||
AndroidTypeface (const Font& font)
|
||||
: Typeface (font.getTypefaceName()),
|
||||
: Typeface (font.getTypefaceName(), font.getTypefaceStyle()),
|
||||
ascent (0),
|
||||
descent (0)
|
||||
{
|
||||
jint flags = 0;
|
||||
if (font.isBold()) flags = 1;
|
||||
if (font.isItalic()) flags += 2;
|
||||
JNIEnv* const env = getEnv();
|
||||
|
||||
JNIEnv* env = getEnv();
|
||||
const bool isBold = style.contains ("Bold");
|
||||
const bool isItalic = style.contains ("Italic");
|
||||
|
||||
File fontFile (File ("/system/fonts").getChildFile (name).withFileExtension (".ttf"));
|
||||
File fontFile (getFontFile (name, style));
|
||||
|
||||
if (! fontFile.exists())
|
||||
fontFile = findFontFile (name, isBold, isItalic);
|
||||
|
||||
if (fontFile.exists())
|
||||
typeface = GlobalRef (env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.createFromFile,
|
||||
javaString (fontFile.getFullPathName()).get()));
|
||||
else
|
||||
typeface = GlobalRef (env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.create,
|
||||
javaString (getName()).get(), flags));
|
||||
javaString (getName()).get(),
|
||||
(isBold ? 1 : 0) + (isItalic ? 2 : 0)));
|
||||
|
||||
rect = GlobalRef (env->NewObject (RectClass, RectClass.constructor, 0, 0, 0, 0));
|
||||
|
||||
|
|
@ -212,6 +230,41 @@ public:
|
|||
float ascent, descent, unitsToHeightScaleFactor;
|
||||
|
||||
private:
|
||||
static File findFontFile (const String& family,
|
||||
const bool bold, const bool italic)
|
||||
{
|
||||
File file;
|
||||
|
||||
if (bold || italic)
|
||||
{
|
||||
String suffix;
|
||||
if (bold) suffix = "Bold";
|
||||
if (italic) suffix << "Italic";
|
||||
|
||||
file = getFontFile (family, suffix);
|
||||
|
||||
if (file.exists())
|
||||
return file;
|
||||
}
|
||||
|
||||
file = getFontFile (family, "Regular");
|
||||
|
||||
if (! file.exists())
|
||||
file = getFontFile (family, String::empty);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static File getFontFile (const String& family, const String& style)
|
||||
{
|
||||
String path ("/system/fonts/" + family);
|
||||
|
||||
if (style.isNotEmpty())
|
||||
path << '-' << style;
|
||||
|
||||
return File (path + ".ttf");
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidTypeface);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -222,10 +222,29 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void getFamilyNames (StringArray& familyNames) const
|
||||
StringArray findAllFamilyNames() const
|
||||
{
|
||||
StringArray s;
|
||||
|
||||
for (int i = 0; i < faces.size(); i++)
|
||||
familyNames.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
|
||||
s.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
StringArray findAllTypefaceStyles (const String& family) const
|
||||
{
|
||||
StringArray s;
|
||||
|
||||
for (int i = 0; i < faces.size(); i++)
|
||||
{
|
||||
const KnownTypeface* const face = faces.getUnchecked(i);
|
||||
|
||||
if (face->family == family)
|
||||
s.addIfNotAlreadyThere (FontStyleHelpers::getStyleName (face->isBold, face->isItalic));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void getMonospacedNames (StringArray& monoSpaced) const
|
||||
|
|
@ -298,14 +317,13 @@ public:
|
|||
if (faceWrapper != nullptr)
|
||||
{
|
||||
setCharacteristics (font.getTypefaceName(),
|
||||
font.getTypefaceStyle(),
|
||||
faceWrapper->face->ascender / (float) (faceWrapper->face->ascender - faceWrapper->face->descender),
|
||||
font.isBold(), font.isItalic(),
|
||||
L' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG ("Failed to create typeface: " << font.getTypefaceName() << " "
|
||||
<< (font.isBold() ? 'B' : ' ') << (font.isItalic() ? 'I' : ' '));
|
||||
DBG ("Failed to create typeface: " << font.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,10 +475,12 @@ Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
|
|||
|
||||
StringArray Font::findAllTypefaceNames()
|
||||
{
|
||||
StringArray s;
|
||||
FTTypefaceList::getInstance()->getFamilyNames (s);
|
||||
s.sort (true);
|
||||
return s;
|
||||
return FTTypefaceList::getInstance()->findAllFamilyNames();
|
||||
}
|
||||
|
||||
StringArray Font::findAllTypefaceStyles (const String& family)
|
||||
{
|
||||
return FTTypefaceList::getInstance()->findAllTypefaceStyles (family);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -480,17 +500,16 @@ private:
|
|||
{
|
||||
const StringArray choices (choicesArray);
|
||||
|
||||
int j;
|
||||
for (j = 0; j < choices.size(); ++j)
|
||||
for (int j = 0; j < choices.size(); ++j)
|
||||
if (names.contains (choices[j], true))
|
||||
return choices[j];
|
||||
|
||||
for (j = 0; j < choices.size(); ++j)
|
||||
for (int j = 0; j < choices.size(); ++j)
|
||||
for (int i = 0; i < names.size(); ++i)
|
||||
if (names[i].startsWithIgnoreCase (choices[j]))
|
||||
return names[i];
|
||||
|
||||
for (j = 0; j < choices.size(); ++j)
|
||||
for (int j = 0; j < choices.size(); ++j)
|
||||
for (int i = 0; i < names.size(); ++i)
|
||||
if (names[i].containsIgnoreCase (choices[j]))
|
||||
return names[i];
|
||||
|
|
|
|||
|
|
@ -34,52 +34,37 @@
|
|||
namespace CoreTextTypeLayout
|
||||
{
|
||||
static CTFontRef createCTFont (const Font& font, const float fontSize,
|
||||
const bool applyScaleFactor, bool& needsItalicTransform)
|
||||
const bool applyScaleFactor)
|
||||
{
|
||||
CFStringRef cfName = font.getTypefaceName().toCFString();
|
||||
CTFontRef ctFontRef = CTFontCreateWithName (cfName, fontSize, nullptr);
|
||||
CFRelease (cfName);
|
||||
CFStringRef cfFontFamily = font.getTypefaceName().toCFString();
|
||||
CFStringRef cfFontStyle = font.getTypefaceStyle().toCFString();
|
||||
CFStringRef keys[] = { kCTFontFamilyNameAttribute, kCTFontStyleNameAttribute };
|
||||
CFTypeRef values[] = { cfFontFamily, cfFontStyle };
|
||||
|
||||
if (ctFontRef != nullptr)
|
||||
CFDictionaryRef fontDescAttributes = CFDictionaryCreate (nullptr, (const void**) &keys,
|
||||
(const void**) &values,
|
||||
numElementsInArray (keys),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
CFRelease (cfFontStyle);
|
||||
CFRelease (cfFontFamily);
|
||||
|
||||
CTFontDescriptorRef ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes);
|
||||
CFRelease (fontDescAttributes);
|
||||
|
||||
CTFontRef ctFontRef = CTFontCreateWithFontDescriptor (ctFontDescRef, fontSize, nullptr);
|
||||
CFRelease (ctFontDescRef);
|
||||
|
||||
if (applyScaleFactor)
|
||||
{
|
||||
if (font.isItalic())
|
||||
{
|
||||
CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits (ctFontRef, 0.0f, nullptr,
|
||||
kCTFontItalicTrait, kCTFontItalicTrait);
|
||||
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);
|
||||
|
||||
if (newFont != nullptr)
|
||||
{
|
||||
CFRelease (ctFontRef);
|
||||
ctFontRef = newFont;
|
||||
}
|
||||
else
|
||||
{
|
||||
needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform..
|
||||
}
|
||||
}
|
||||
|
||||
if (font.isBold())
|
||||
{
|
||||
CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits (ctFontRef, 0.0f, nullptr,
|
||||
kCTFontBoldTrait, kCTFontBoldTrait);
|
||||
if (newFont != nullptr)
|
||||
{
|
||||
CFRelease (ctFontRef);
|
||||
ctFontRef = newFont;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
CTFontRef newFont = CTFontCreateCopyWithAttributes (ctFontRef, fontSize * factor, nullptr, nullptr);
|
||||
CFRelease (ctFontRef);
|
||||
ctFontRef = newFont;
|
||||
}
|
||||
|
||||
return ctFontRef;
|
||||
|
|
@ -164,8 +149,7 @@ namespace CoreTextTypeLayout
|
|||
if (attr->getFont() != nullptr)
|
||||
{
|
||||
const Font& f = *attr->getFont();
|
||||
bool needsItalicTransform = false;
|
||||
CTFontRef ctFontRef = createCTFont (f, f.getHeight(), true, needsItalicTransform);
|
||||
CTFontRef ctFontRef = createCTFont (f, f.getHeight(), true);
|
||||
|
||||
CFAttributedStringSetAttribute (attribString, CFRangeMake (range.getStart(), range.getLength()),
|
||||
kCTFontAttributeName, ctFontRef);
|
||||
|
|
@ -317,17 +301,24 @@ namespace CoreTextTypeLayout
|
|||
CTFontRef ctRunFont;
|
||||
if (CFDictionaryGetValueIfPresent (runAttributes, kCTFontAttributeName, (const void **) &ctRunFont))
|
||||
{
|
||||
CFStringRef cfsFontName = CTFontCopyPostScriptName (ctRunFont);
|
||||
CTFontRef ctFontRef = CTFontCreateWithName (cfsFontName, 1024, nullptr);
|
||||
CTFontDescriptorRef ctFontDescRef = CTFontCopyFontDescriptor (ctRunFont);
|
||||
CFDictionaryRef fontDescAttributes = CTFontDescriptorCopyAttributes (ctFontDescRef);
|
||||
CTFontRef ctFontRef = CTFontCreateWithFontDescriptor (ctFontDescRef, 1024, nullptr);
|
||||
CFRelease (ctFontDescRef);
|
||||
|
||||
CGFontRef cgFontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr);
|
||||
CFRelease (ctFontRef);
|
||||
const int totalHeight = std::abs (CGFontGetAscent (cgFontRef)) + std::abs (CGFontGetDescent (cgFontRef));
|
||||
const float fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (cgFontRef) / (float) totalHeight;
|
||||
CGFontRelease (cgFontRef);
|
||||
|
||||
glyphRun->font = Font (String::fromCFString (cfsFontName),
|
||||
CTFontGetSize (ctRunFont) / fontHeightToCGSizeFactor, 0); // XXX bold/italic flags?
|
||||
CFRelease (cfsFontName);
|
||||
CFStringRef cfsFontFamily = (CFStringRef) CFDictionaryGetValue (fontDescAttributes, kCTFontFamilyNameAttribute);
|
||||
CFStringRef cfsFontStyle = (CFStringRef) CFDictionaryGetValue (fontDescAttributes, kCTFontStyleNameAttribute);
|
||||
|
||||
glyphRun->font = Font (String::fromCFString (cfsFontFamily),
|
||||
String::fromCFString (cfsFontStyle),
|
||||
CTFontGetSize (ctRunFont) / fontHeightToCGSizeFactor);
|
||||
CFRelease (fontDescAttributes);
|
||||
}
|
||||
|
||||
CGColorRef cgRunColor;
|
||||
|
|
@ -360,7 +351,8 @@ class OSXTypeface : public Typeface
|
|||
{
|
||||
public:
|
||||
OSXTypeface (const Font& font)
|
||||
: Typeface (font.getTypefaceName()),
|
||||
: Typeface (font.getTypefaceName(),
|
||||
font.getTypefaceStyle()),
|
||||
fontRef (nullptr),
|
||||
fontHeightToCGSizeFactor (1.0f),
|
||||
renderingTransform (CGAffineTransformIdentity),
|
||||
|
|
@ -369,8 +361,7 @@ public:
|
|||
ascent (0.0f),
|
||||
unitsToHeightScaleFactor (0.0f)
|
||||
{
|
||||
bool needsItalicTransform = false;
|
||||
ctFontRef = CoreTextTypeLayout::createCTFont (font, 1024.0f, false, needsItalicTransform);
|
||||
ctFontRef = CoreTextTypeLayout::createCTFont (font, 1024.0f, false);
|
||||
|
||||
if (ctFontRef != nullptr)
|
||||
{
|
||||
|
|
@ -380,12 +371,6 @@ public:
|
|||
|
||||
pathTransform = AffineTransform::identity.scale (1.0f / totalSize, 1.0f / totalSize);
|
||||
|
||||
if (needsItalicTransform)
|
||||
{
|
||||
pathTransform = pathTransform.sheared (-0.15f, 0.0f);
|
||||
renderingTransform.c = 0.15f;
|
||||
}
|
||||
|
||||
fontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr);
|
||||
|
||||
const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
|
||||
|
|
@ -550,6 +535,87 @@ private:
|
|||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSXTypeface);
|
||||
};
|
||||
|
||||
StringArray Font::findAllTypefaceNames()
|
||||
{
|
||||
StringArray names;
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 && ! JUCE_IOS
|
||||
// CTFontManager only exists on OS X 10.6 and later, it does not exist on iOS
|
||||
CFArrayRef fontFamilyArray = CTFontManagerCopyAvailableFontFamilyNames();
|
||||
|
||||
for (CFIndex i = 0; i < CFArrayGetCount (fontFamilyArray); ++i)
|
||||
{
|
||||
const String family (String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (fontFamilyArray, i)));
|
||||
|
||||
if (! family.startsWithChar ('.')) // ignore fonts that start with a '.'
|
||||
names.addIfNotAlreadyThere (family);
|
||||
}
|
||||
|
||||
CFRelease (fontFamilyArray);
|
||||
#else
|
||||
CTFontCollectionRef fontCollectionRef = CTFontCollectionCreateFromAvailableFonts (nullptr);
|
||||
CFArrayRef fontDescriptorArray = CTFontCollectionCreateMatchingFontDescriptors (fontCollectionRef);
|
||||
CFRelease (fontCollectionRef);
|
||||
|
||||
for (CFIndex i = 0; i < CFArrayGetCount (fontDescriptorArray); ++i)
|
||||
{
|
||||
CTFontDescriptorRef ctFontDescriptorRef = (CTFontDescriptorRef) CFArrayGetValueAtIndex (fontDescriptorArray, i);
|
||||
CFStringRef cfsFontFamily = (CFStringRef) CTFontDescriptorCopyAttribute (ctFontDescriptorRef, kCTFontFamilyNameAttribute);
|
||||
|
||||
names.addIfNotAlreadyThere (String::fromCFString (cfsFontFamily));
|
||||
|
||||
CFRelease (cfsFontFamily);
|
||||
}
|
||||
|
||||
CFRelease (fontDescriptorArray);
|
||||
#endif
|
||||
|
||||
names.sort (true);
|
||||
return names;
|
||||
}
|
||||
|
||||
StringArray Font::findAllTypefaceStyles (const String& family)
|
||||
{
|
||||
if (FontStyleHelpers::isPlaceholderFamilyName (family))
|
||||
return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family));
|
||||
|
||||
StringArray results;
|
||||
|
||||
CFStringRef cfsFontFamily = family.toCFString();
|
||||
CFStringRef keys[] = { kCTFontFamilyNameAttribute };
|
||||
CFTypeRef values[] = { cfsFontFamily };
|
||||
|
||||
CFDictionaryRef fontDescAttributes = CFDictionaryCreate (nullptr, (const void**) &keys, (const void**) &values, numElementsInArray (keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
CFRelease (cfsFontFamily);
|
||||
|
||||
CTFontDescriptorRef ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes);
|
||||
CFRelease (fontDescAttributes);
|
||||
|
||||
CFArrayRef fontFamilyArray = CFArrayCreate(kCFAllocatorDefault, (const void**) &ctFontDescRef, 1, &kCFTypeArrayCallBacks);
|
||||
CFRelease (ctFontDescRef);
|
||||
|
||||
CTFontCollectionRef fontCollectionRef = CTFontCollectionCreateWithFontDescriptors (fontFamilyArray, nullptr);
|
||||
CFRelease (fontFamilyArray);
|
||||
|
||||
CFArrayRef fontDescriptorArray = CTFontCollectionCreateMatchingFontDescriptors (fontCollectionRef);
|
||||
CFRelease (fontCollectionRef);
|
||||
|
||||
if (fontDescriptorArray != nullptr)
|
||||
{
|
||||
for (CFIndex i = 0; i < CFArrayGetCount (fontDescriptorArray); ++i)
|
||||
{
|
||||
CTFontDescriptorRef ctFontDescriptorRef = (CTFontDescriptorRef) CFArrayGetValueAtIndex (fontDescriptorArray, i);
|
||||
CFStringRef cfsFontStyle = (CFStringRef) CTFontDescriptorCopyAttribute (ctFontDescriptorRef, kCTFontStyleNameAttribute);
|
||||
results.add (String::fromCFString (cfsFontStyle));
|
||||
CFRelease (cfsFontStyle);
|
||||
}
|
||||
|
||||
CFRelease (fontDescriptorArray);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -580,49 +646,13 @@ class OSXTypeface : public Typeface
|
|||
{
|
||||
public:
|
||||
OSXTypeface (const Font& font)
|
||||
: Typeface (font.getTypefaceName())
|
||||
: Typeface (font.getTypefaceName(), font.getTypefaceStyle())
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
renderingTransform = CGAffineTransformIdentity;
|
||||
|
||||
bool needsItalicTransform = false;
|
||||
|
||||
#if JUCE_IOS
|
||||
NSString* fontName = juceStringToNS (font.getTypefaceName());
|
||||
|
||||
if (font.isItalic() || font.isBold())
|
||||
{
|
||||
NSArray* familyFonts = [UIFont fontNamesForFamilyName: juceStringToNS (font.getTypefaceName())];
|
||||
|
||||
for (NSString* i in familyFonts)
|
||||
{
|
||||
const String fn (nsStringToJuce (i));
|
||||
const String afterDash (fn.fromFirstOccurrenceOf ("-", false, false));
|
||||
|
||||
const bool probablyBold = afterDash.containsIgnoreCase ("bold") || fn.endsWithIgnoreCase ("bold");
|
||||
const bool probablyItalic = afterDash.containsIgnoreCase ("oblique")
|
||||
|| afterDash.containsIgnoreCase ("italic")
|
||||
|| fn.endsWithIgnoreCase ("oblique")
|
||||
|| fn.endsWithIgnoreCase ("italic");
|
||||
|
||||
if (probablyBold == font.isBold()
|
||||
&& probablyItalic == font.isItalic())
|
||||
{
|
||||
fontName = i;
|
||||
needsItalicTransform = false;
|
||||
break;
|
||||
}
|
||||
else if (probablyBold && (! probablyItalic) && probablyBold == font.isBold())
|
||||
{
|
||||
fontName = i;
|
||||
needsItalicTransform = true; // not ideal, so carry on in case we find a better one
|
||||
}
|
||||
}
|
||||
|
||||
if (needsItalicTransform)
|
||||
renderingTransform.c = 0.15f;
|
||||
}
|
||||
|
||||
NSString* fontName = juceStringToNS (style);
|
||||
fontRef = CGFontCreateWithFontName ((CFStringRef) fontName);
|
||||
|
||||
if (fontRef == 0)
|
||||
|
|
@ -638,21 +668,12 @@ public:
|
|||
unitsToHeightScaleFactor = 1.0f / totalHeight;
|
||||
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / totalHeight;
|
||||
#else
|
||||
nsFont = [NSFont fontWithName: juceStringToNS (font.getTypefaceName()) size: 1024];
|
||||
NSDictionary* nsDict = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
juceStringToNS (name), NSFontFamilyAttribute,
|
||||
juceStringToNS (style), NSFontFaceAttribute, nil];
|
||||
|
||||
if (font.isItalic())
|
||||
{
|
||||
NSFont* newFont = [[NSFontManager sharedFontManager] convertFont: nsFont
|
||||
toHaveTrait: NSItalicFontMask];
|
||||
|
||||
if (newFont == nsFont)
|
||||
needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform..
|
||||
|
||||
nsFont = newFont;
|
||||
}
|
||||
|
||||
if (font.isBold())
|
||||
nsFont = [[NSFontManager sharedFontManager] convertFont: nsFont toHaveTrait: NSBoldFontMask];
|
||||
NSFontDescriptor* nsFontDesc = [NSFontDescriptor fontDescriptorWithFontAttributes: nsDict];
|
||||
nsFont = [NSFont fontWithDescriptor: nsFontDesc size: 1024];
|
||||
|
||||
[nsFont retain];
|
||||
|
||||
|
|
@ -662,12 +683,6 @@ public:
|
|||
|
||||
pathTransform = AffineTransform::identity.scale (1.0f / totalSize, 1.0f / totalSize);
|
||||
|
||||
if (needsItalicTransform)
|
||||
{
|
||||
pathTransform = pathTransform.sheared (-0.15f, 0.0f);
|
||||
renderingTransform.c = 0.15f;
|
||||
}
|
||||
|
||||
#if SUPPORT_ONLY_10_4_FONTS
|
||||
ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
|
||||
|
||||
|
|
@ -910,7 +925,7 @@ private:
|
|||
#endif
|
||||
}
|
||||
|
||||
#if ! SUPPORT_ONLY_10_4_FONTS
|
||||
#if ! SUPPORT_ONLY_10_4_FONTS
|
||||
// Reads a CGFontRef's character map table to convert unicode into glyph numbers
|
||||
class CharToGlyphMapper
|
||||
{
|
||||
|
|
@ -1009,23 +1024,14 @@ private:
|
|||
};
|
||||
|
||||
ScopedPointer <CharToGlyphMapper> charToGlyphMapper;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSXTypeface);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
|
||||
{
|
||||
return new OSXTypeface (font);
|
||||
}
|
||||
|
||||
StringArray Font::findAllTypefaceNames()
|
||||
{
|
||||
StringArray names;
|
||||
|
||||
JUCE_AUTORELEASEPOOL
|
||||
|
||||
#if JUCE_IOS
|
||||
|
|
@ -1041,6 +1047,43 @@ StringArray Font::findAllTypefaceNames()
|
|||
return names;
|
||||
}
|
||||
|
||||
StringArray Font::findAllTypefaceStyles (const String& family)
|
||||
{
|
||||
if (FontStyleHelpers::isPlaceholderFamilyName (family))
|
||||
return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family));
|
||||
|
||||
StringArray results;
|
||||
JUCE_AUTORELEASEPOOL
|
||||
|
||||
#if JUCE_IOS
|
||||
NSArray* styles = [UIFont fontNamesForFamilyName: juceStringToNS (family)];
|
||||
#else
|
||||
NSArray* styles = [[NSFontManager sharedFontManager] availableMembersOfFontFamily: juceStringToNS (family)];
|
||||
#endif
|
||||
|
||||
for (unsigned int i = 0; i < [styles count]; ++i)
|
||||
{
|
||||
#if JUCE_IOS
|
||||
// Fonts are returned in the form of "Arial-BoldMT"
|
||||
results.add (nsStringToJuce ((NSString*) [styles objectAtIndex: i]));
|
||||
#else
|
||||
NSArray* style = [styles objectAtIndex: i];
|
||||
results.add (nsStringToJuce ((NSString*) [style objectAtIndex: 1]));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
|
||||
{
|
||||
return new OSXTypeface (font);
|
||||
}
|
||||
|
||||
struct DefaultFontNames
|
||||
{
|
||||
DefaultFontNames()
|
||||
|
|
@ -1064,15 +1107,24 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
|
|||
{
|
||||
static DefaultFontNames defaultNames;
|
||||
|
||||
String faceName (font.getTypefaceName());
|
||||
Font newFont (font);
|
||||
const String& faceName = font.getTypefaceName();
|
||||
|
||||
if (faceName == Font::getDefaultSansSerifFontName()) faceName = defaultNames.defaultSans;
|
||||
else if (faceName == Font::getDefaultSerifFontName()) faceName = defaultNames.defaultSerif;
|
||||
else if (faceName == Font::getDefaultMonospacedFontName()) faceName = defaultNames.defaultFixed;
|
||||
if (faceName == getDefaultSansSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSans);
|
||||
else if (faceName == getDefaultSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSerif);
|
||||
else if (faceName == getDefaultMonospacedFontName()) newFont.setTypefaceName (defaultNames.defaultFixed);
|
||||
|
||||
Font f (font);
|
||||
f.setTypefaceName (faceName);
|
||||
return Typeface::createSystemTypefaceFor (f);
|
||||
if (font.getTypefaceStyle() == getDefaultStyle())
|
||||
newFont.setTypefaceStyle ("Regular");
|
||||
|
||||
#if JUCE_IOS && ! JUCE_CORETEXT_AVAILABLE
|
||||
// Fonts style names on Cocoa Touch are unusual like "Arial-BoldMT"
|
||||
// No font will be found for the style of "Regular" so we must modify the style
|
||||
if (newFont.getTypefaceStyle() == "Regular")
|
||||
newFont.setTypefaceStyle (faceName);
|
||||
#endif
|
||||
|
||||
return Typeface::createSystemTypefaceFor (newFont);
|
||||
}
|
||||
|
||||
bool TextLayout::createNativeLayout (const AttributedString& text)
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ namespace DirectWriteTypeLayout
|
|||
glyphLine.ascent = jmax (glyphLine.ascent, scaledFontSize (dwFontMetrics.ascent, dwFontMetrics, glyphRun));
|
||||
glyphLine.descent = jmax (glyphLine.descent, scaledFontSize (dwFontMetrics.descent, dwFontMetrics, glyphRun));
|
||||
|
||||
int styleFlags = 0;
|
||||
const String fontName (getFontName (glyphRun, styleFlags));
|
||||
String fontFamily, fontStyle;
|
||||
getFontFamilyAndStyle (glyphRun, fontFamily, fontStyle);
|
||||
|
||||
TextLayout::Run* const glyphRunLayout = new TextLayout::Run (Range<int> (runDescription->textPosition,
|
||||
runDescription->textPosition + runDescription->stringLength),
|
||||
|
|
@ -102,7 +102,7 @@ namespace DirectWriteTypeLayout
|
|||
const float totalHeight = std::abs ((float) dwFontMetrics.ascent) + std::abs ((float) dwFontMetrics.descent);
|
||||
const float fontHeightToEmSizeFactor = (float) dwFontMetrics.designUnitsPerEm / totalHeight;
|
||||
|
||||
glyphRunLayout->font = Font (fontName, glyphRun->fontEmSize / fontHeightToEmSizeFactor, styleFlags);
|
||||
glyphRunLayout->font = Font (fontFamily, fontStyle, glyphRun->fontEmSize / fontHeightToEmSizeFactor);
|
||||
glyphRunLayout->colour = getColourOf (static_cast<ID2D1SolidColorBrush*> (clientDrawingEffect));
|
||||
|
||||
const Point<float> lineOrigin (layout->getLine (currentLine).lineOrigin);
|
||||
|
|
@ -145,62 +145,29 @@ namespace DirectWriteTypeLayout
|
|||
return Colour::fromFloatRGBA (colour.r, colour.g, colour.b, colour.a);
|
||||
}
|
||||
|
||||
String getFontName (DWRITE_GLYPH_RUN const* glyphRun, int& styleFlags) const
|
||||
void getFontFamilyAndStyle (DWRITE_GLYPH_RUN const* glyphRun, String& family, String& style) const
|
||||
{
|
||||
ComSmartPtr<IDWriteFont> dwFont;
|
||||
|
||||
HRESULT hr = fontCollection->GetFontFromFontFace (glyphRun->fontFace, dwFont.resetAndGetPointerAddress());
|
||||
jassert (dwFont != nullptr);
|
||||
|
||||
if (dwFont->GetWeight() == DWRITE_FONT_WEIGHT_BOLD) styleFlags |= Font::bold;
|
||||
if (dwFont->GetStyle() == DWRITE_FONT_STYLE_ITALIC) styleFlags |= Font::italic;
|
||||
{
|
||||
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
|
||||
hr = dwFont->GetFontFamily (dwFontFamily.resetAndGetPointerAddress());
|
||||
family = getFontFamilyName (dwFontFamily);
|
||||
}
|
||||
|
||||
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
|
||||
hr = dwFont->GetFontFamily (dwFontFamily.resetAndGetPointerAddress());
|
||||
jassert (dwFontFamily != nullptr);
|
||||
|
||||
// Get the Font Family Names
|
||||
ComSmartPtr<IDWriteLocalizedStrings> dwFamilyNames;
|
||||
hr = dwFontFamily->GetFamilyNames (dwFamilyNames.resetAndGetPointerAddress());
|
||||
jassert (dwFamilyNames != nullptr);
|
||||
|
||||
UINT32 index = 0;
|
||||
BOOL exists = false;
|
||||
hr = dwFamilyNames->FindLocaleName (L"en-us", &index, &exists);
|
||||
if (! exists)
|
||||
index = 0;
|
||||
|
||||
UINT32 length = 0;
|
||||
hr = dwFamilyNames->GetStringLength (index, &length);
|
||||
|
||||
HeapBlock <wchar_t> name (length + 1);
|
||||
hr = dwFamilyNames->GetString (index, name, length + 1);
|
||||
|
||||
return String (name);
|
||||
style = getFontFaceName (dwFont);
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomDirectWriteTextRenderer);
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
float getFontHeightToEmSizeFactor (const Font& font, IDWriteFontCollection& dwFontCollection)
|
||||
float getFontHeightToEmSizeFactor (IDWriteFont* const dwFont)
|
||||
{
|
||||
BOOL fontFound = false;
|
||||
uint32 fontIndex;
|
||||
dwFontCollection.FindFamilyName (font.getTypefaceName().toWideCharPointer(), &fontIndex, &fontFound);
|
||||
|
||||
if (! fontFound)
|
||||
fontIndex = 0;
|
||||
|
||||
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
|
||||
HRESULT hr = dwFontCollection.GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress());
|
||||
|
||||
ComSmartPtr<IDWriteFont> dwFont;
|
||||
hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL,
|
||||
dwFont.resetAndGetPointerAddress());
|
||||
|
||||
ComSmartPtr<IDWriteFontFace> dwFontFace;
|
||||
hr = dwFont->CreateFontFace (dwFontFace.resetAndGetPointerAddress());
|
||||
dwFont->CreateFontFace (dwFontFace.resetAndGetPointerAddress());
|
||||
|
||||
DWRITE_FONT_METRICS dwFontMetrics;
|
||||
dwFontFace->GetMetrics (&dwFontMetrics);
|
||||
|
|
@ -251,13 +218,35 @@ namespace DirectWriteTypeLayout
|
|||
|
||||
if (font != nullptr)
|
||||
{
|
||||
textLayout->SetFontFamilyName (font->getTypefaceName().toWideCharPointer(), range);
|
||||
BOOL fontFound = false;
|
||||
uint32 fontIndex;
|
||||
fontCollection->FindFamilyName (font->getTypefaceName().toWideCharPointer(), &fontIndex, &fontFound);
|
||||
|
||||
const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*font, *fontCollection);
|
||||
if (! fontFound)
|
||||
fontIndex = 0;
|
||||
|
||||
ComSmartPtr<IDWriteFontFamily> fontFamily;
|
||||
HRESULT hr = fontCollection->GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress());
|
||||
|
||||
ComSmartPtr<IDWriteFont> dwFont;
|
||||
uint32 fontFacesCount = 0;
|
||||
fontFacesCount = fontFamily->GetFontCount();
|
||||
|
||||
for (uint32 i = 0; i < fontFacesCount; ++i)
|
||||
{
|
||||
hr = fontFamily->GetFont (i, dwFont.resetAndGetPointerAddress());
|
||||
|
||||
if (attr.getFont()->getTypefaceStyle() == getFontFaceName (dwFont))
|
||||
break;
|
||||
}
|
||||
|
||||
textLayout->SetFontFamilyName (attr.getFont()->getTypefaceName().toWideCharPointer(), range);
|
||||
textLayout->SetFontWeight (dwFont->GetWeight(), range);
|
||||
textLayout->SetFontStretch (dwFont->GetStretch(), range);
|
||||
textLayout->SetFontStyle (dwFont->GetStyle(), range);
|
||||
|
||||
const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (dwFont);
|
||||
textLayout->SetFontSize (font->getHeight() * fontHeightToEmSizeFactor, range);
|
||||
|
||||
if (font->isBold()) textLayout->SetFontWeight (DWRITE_FONT_WEIGHT_BOLD, range);
|
||||
if (font->isItalic()) textLayout->SetFontStyle (DWRITE_FONT_STYLE_ITALIC, range);
|
||||
}
|
||||
|
||||
if (attr.getColour() != nullptr)
|
||||
|
|
@ -290,7 +279,21 @@ namespace DirectWriteTypeLayout
|
|||
HRESULT hr = direct2dFactory->CreateDCRenderTarget (&d2dRTProp, renderTarget.resetAndGetPointerAddress());
|
||||
|
||||
Font defaultFont;
|
||||
const float defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (defaultFont, *fontCollection);
|
||||
BOOL fontFound = false;
|
||||
uint32 fontIndex;
|
||||
fontCollection->FindFamilyName (defaultFont.getTypefaceName().toWideCharPointer(), &fontIndex, &fontFound);
|
||||
|
||||
if (! fontFound)
|
||||
fontIndex = 0;
|
||||
|
||||
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
|
||||
hr = fontCollection->GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress());
|
||||
|
||||
ComSmartPtr<IDWriteFont> dwFont;
|
||||
hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL,
|
||||
dwFont.resetAndGetPointerAddress());
|
||||
|
||||
const float defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (dwFont);
|
||||
|
||||
jassert (directWriteFactory != nullptr);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,47 @@
|
|||
*/
|
||||
|
||||
#if JUCE_USE_DIRECTWRITE
|
||||
namespace
|
||||
{
|
||||
static String getLocalisedName (IDWriteLocalizedStrings* names)
|
||||
{
|
||||
jassert (names != nullptr);
|
||||
|
||||
uint32 index = 0;
|
||||
BOOL exists = false;
|
||||
HRESULT hr = names->FindLocaleName (L"en-us", &index, &exists);
|
||||
if (! exists)
|
||||
index = 0;
|
||||
|
||||
uint32 length = 0;
|
||||
hr = names->GetStringLength (index, &length);
|
||||
|
||||
HeapBlock<wchar_t> name (length + 1);
|
||||
hr = names->GetString (index, name, length + 1);
|
||||
|
||||
return static_cast <const wchar_t*> (name);
|
||||
}
|
||||
|
||||
static String getFontFamilyName (IDWriteFontFamily* family)
|
||||
{
|
||||
jassert (family != nullptr);
|
||||
ComSmartPtr<IDWriteLocalizedStrings> familyNames;
|
||||
HRESULT hr = family->GetFamilyNames (familyNames.resetAndGetPointerAddress());
|
||||
jassert (SUCCEEDED (hr)); (void) hr;
|
||||
return getLocalisedName (familyNames);
|
||||
}
|
||||
|
||||
static String getFontFaceName (IDWriteFont* font)
|
||||
{
|
||||
jassert (font != nullptr);
|
||||
ComSmartPtr<IDWriteLocalizedStrings> faceNames;
|
||||
HRESULT hr = font->GetFaceNames (faceNames.resetAndGetPointerAddress());
|
||||
jassert (SUCCEEDED (hr)); (void) hr;
|
||||
|
||||
return getLocalisedName (faceNames);
|
||||
}
|
||||
}
|
||||
|
||||
class Direct2DFactories
|
||||
{
|
||||
public:
|
||||
|
|
@ -86,7 +127,7 @@ class WindowsDirectWriteTypeface : public Typeface
|
|||
{
|
||||
public:
|
||||
WindowsDirectWriteTypeface (const Font& font, IDWriteFontCollection* fontCollection)
|
||||
: Typeface (font.getTypefaceName()),
|
||||
: Typeface (font.getTypefaceName(), font.getTypefaceStyle()),
|
||||
ascent (0.0f)
|
||||
{
|
||||
jassert (fontCollection != nullptr);
|
||||
|
|
@ -102,12 +143,22 @@ public:
|
|||
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
|
||||
hr = fontCollection->GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress());
|
||||
|
||||
// Get a specific font in the font family using certain weight and style flags
|
||||
// Get a specific font in the font family using typeface style
|
||||
ComSmartPtr<IDWriteFont> dwFont;
|
||||
DWRITE_FONT_WEIGHT dwWeight = font.isBold() ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL;
|
||||
DWRITE_FONT_STYLE dwStyle = font.isItalic() ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
|
||||
uint32 fontFacesCount = 0;
|
||||
fontFacesCount = dwFontFamily->GetFontCount();
|
||||
|
||||
for (uint32 i = 0; i < fontFacesCount; ++i)
|
||||
{
|
||||
hr = dwFontFamily->GetFont (i, dwFont.resetAndGetPointerAddress());
|
||||
|
||||
ComSmartPtr<IDWriteLocalizedStrings> faceNames;
|
||||
hr = dwFont->GetFaceNames (faceNames.resetAndGetPointerAddress());
|
||||
|
||||
if (font.getTypefaceStyle() == getLocalisedName (faceNames))
|
||||
break;
|
||||
}
|
||||
|
||||
hr = dwFontFamily->GetFirstMatchingFont (dwWeight, DWRITE_FONT_STRETCH_NORMAL, dwStyle, dwFont.resetAndGetPointerAddress());
|
||||
hr = dwFont->CreateFontFace (dwFontFace.resetAndGetPointerAddress());
|
||||
|
||||
DWRITE_FONT_METRICS dwFontMetrics;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
namespace FontEnumerators
|
||||
{
|
||||
int CALLBACK fontEnum2 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam)
|
||||
static int CALLBACK fontEnum2 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam)
|
||||
{
|
||||
if (lpelfe != nullptr && (type & RASTER_FONTTYPE) == 0)
|
||||
{
|
||||
|
|
@ -36,7 +36,7 @@ namespace FontEnumerators
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CALLBACK fontEnum1 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam)
|
||||
static int CALLBACK fontEnum1 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam)
|
||||
{
|
||||
if (lpelfe != nullptr && (type & RASTER_FONTTYPE) == 0)
|
||||
{
|
||||
|
|
@ -65,28 +65,99 @@ namespace FontEnumerators
|
|||
StringArray Font::findAllTypefaceNames()
|
||||
{
|
||||
StringArray results;
|
||||
HDC dc = CreateCompatibleDC (0);
|
||||
|
||||
#if JUCE_USE_DIRECTWRITE
|
||||
const Direct2DFactories& factories = Direct2DFactories::getInstance();
|
||||
|
||||
if (factories.systemFonts != nullptr)
|
||||
{
|
||||
LOGFONTW lf = { 0 };
|
||||
lf.lfWeight = FW_DONTCARE;
|
||||
lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
|
||||
lf.lfQuality = DEFAULT_QUALITY;
|
||||
lf.lfCharSet = DEFAULT_CHARSET;
|
||||
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lf.lfPitchAndFamily = FF_DONTCARE;
|
||||
ComSmartPtr<IDWriteFontFamily> fontFamily;
|
||||
uint32 fontFamilyCount = 0;
|
||||
fontFamilyCount = factories.systemFonts->GetFontFamilyCount();
|
||||
|
||||
EnumFontFamiliesEx (dc, &lf,
|
||||
(FONTENUMPROCW) &FontEnumerators::fontEnum1,
|
||||
(LPARAM) &results, 0);
|
||||
for (uint32 i = 0; i < fontFamilyCount; ++i)
|
||||
{
|
||||
HRESULT hr = factories.systemFonts->GetFontFamily (i, fontFamily.resetAndGetPointerAddress());
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
results.addIfNotAlreadyThere (getFontFamilyName (fontFamily));
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
HDC dc = CreateCompatibleDC (0);
|
||||
|
||||
{
|
||||
LOGFONTW lf = { 0 };
|
||||
lf.lfWeight = FW_DONTCARE;
|
||||
lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
|
||||
lf.lfQuality = DEFAULT_QUALITY;
|
||||
lf.lfCharSet = DEFAULT_CHARSET;
|
||||
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lf.lfPitchAndFamily = FF_DONTCARE;
|
||||
|
||||
EnumFontFamiliesEx (dc, &lf,
|
||||
(FONTENUMPROCW) &FontEnumerators::fontEnum1,
|
||||
(LPARAM) &results, 0);
|
||||
}
|
||||
|
||||
DeleteDC (dc);
|
||||
}
|
||||
|
||||
DeleteDC (dc);
|
||||
|
||||
results.sort (true);
|
||||
return results;
|
||||
}
|
||||
|
||||
StringArray Font::findAllTypefaceStyles (const String& family)
|
||||
{
|
||||
if (FontStyleHelpers::isPlaceholderFamilyName (family))
|
||||
return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family));
|
||||
|
||||
StringArray results;
|
||||
|
||||
#if JUCE_USE_DIRECTWRITE
|
||||
const Direct2DFactories& factories = Direct2DFactories::getInstance();
|
||||
|
||||
if (factories.systemFonts != nullptr)
|
||||
{
|
||||
BOOL fontFound = false;
|
||||
uint32 fontIndex = 0;
|
||||
HRESULT hr = factories.systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound);
|
||||
if (! fontFound)
|
||||
fontIndex = 0;
|
||||
|
||||
// Get the font family using the search results
|
||||
// Fonts like: Times New Roman, Times New Roman Bold, Times New Roman Italic are all in the same font family
|
||||
ComSmartPtr<IDWriteFontFamily> fontFamily;
|
||||
hr = factories.systemFonts->GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress());
|
||||
|
||||
// Get the font faces
|
||||
ComSmartPtr<IDWriteFont> dwFont;
|
||||
uint32 fontFacesCount = 0;
|
||||
fontFacesCount = fontFamily->GetFontCount();
|
||||
|
||||
for (uint32 i = 0; i < fontFacesCount; ++i)
|
||||
{
|
||||
hr = fontFamily->GetFont (i, dwFont.resetAndGetPointerAddress());
|
||||
|
||||
// Ignore any algorithmically generated bold and oblique styles..
|
||||
if (dwFont->GetSimulations() == DWRITE_FONT_SIMULATIONS_NONE)
|
||||
results.addIfNotAlreadyThere (getFontFaceName (dwFont));
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
results.add ("Regular");
|
||||
results.add ("Italic");
|
||||
results.add ("Bold");
|
||||
results.add ("Bold Italic");
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
extern bool juce_IsRunningInWine();
|
||||
|
||||
struct DefaultFontNames
|
||||
|
|
@ -116,15 +187,17 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
|
|||
{
|
||||
static DefaultFontNames defaultNames;
|
||||
|
||||
String faceName (font.getTypefaceName());
|
||||
Font newFont (font);
|
||||
const String& faceName = font.getTypefaceName();
|
||||
|
||||
if (faceName == Font::getDefaultSansSerifFontName()) faceName = defaultNames.defaultSans;
|
||||
else if (faceName == Font::getDefaultSerifFontName()) faceName = defaultNames.defaultSerif;
|
||||
else if (faceName == Font::getDefaultMonospacedFontName()) faceName = defaultNames.defaultFixed;
|
||||
if (faceName == getDefaultSansSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSans);
|
||||
else if (faceName == getDefaultSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSerif);
|
||||
else if (faceName == getDefaultMonospacedFontName()) newFont.setTypefaceName (defaultNames.defaultFixed);
|
||||
|
||||
Font f (font);
|
||||
f.setTypefaceName (faceName);
|
||||
return Typeface::createSystemTypefaceFor (f);
|
||||
if (font.getTypefaceStyle() == getDefaultStyle())
|
||||
newFont.setTypefaceStyle ("Regular");
|
||||
|
||||
return Typeface::createSystemTypefaceFor (newFont);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -132,14 +205,13 @@ class WindowsTypeface : public Typeface
|
|||
{
|
||||
public:
|
||||
WindowsTypeface (const Font& font)
|
||||
: Typeface (font.getTypefaceName()),
|
||||
: Typeface (font.getTypefaceName(),
|
||||
font.getTypefaceStyle()),
|
||||
fontH (0),
|
||||
previousFontH (0),
|
||||
dc (CreateCompatibleDC (0)),
|
||||
ascent (1.0f),
|
||||
defaultGlyph (-1),
|
||||
bold (font.isBold()),
|
||||
italic (font.isItalic())
|
||||
defaultGlyph (-1)
|
||||
{
|
||||
loadFont();
|
||||
|
||||
|
|
@ -282,7 +354,6 @@ private:
|
|||
TEXTMETRIC tm;
|
||||
float ascent;
|
||||
int defaultGlyph;
|
||||
bool bold, italic;
|
||||
|
||||
struct KerningPair
|
||||
{
|
||||
|
|
@ -314,8 +385,8 @@ private:
|
|||
lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
|
||||
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
||||
lf.lfQuality = PROOF_QUALITY;
|
||||
lf.lfItalic = (BYTE) (italic ? TRUE : FALSE);
|
||||
lf.lfWeight = bold ? FW_BOLD : FW_NORMAL;
|
||||
lf.lfItalic = (BYTE) (style == "Italic" ? TRUE : FALSE);
|
||||
lf.lfWeight = style == "Bold" ? FW_BOLD : FW_NORMAL;
|
||||
lf.lfHeight = -256;
|
||||
name.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue