Browse Source

Font: Make Font and TypefaceCache threadsafe

Previously, it wasn't safe to access Font instances from multiple
threads because there was a chance that they might reference the same
shared internal state. In this case, calling getTypeface() or getAscent from
two threads simultaneously would cause a race on the typeface and ascent
data members, even though the Font instances appeared to be disjoint.

With this change in place, it is now safe to use Font instances from
multiple threads simultaneously.

It is still an error to modify the same Font instance from multiple
threads without synchronization!

    // Fine:
    Font a;
    Font b = a;

    auto futureA = std::async (std::launch::async, [&a] { /* do something with a */ });
    auto futureB = std::async (std::launch::async, [&b] { /* do something with b */ });

    // Bad idea:
    Font f;

    auto futureA = std::async (std::launch::async, [&f] { /* do something with f */ });
    auto futureB = std::async (std::launch::async, [&f] { /* do something with f */ });
v6.1.6
reuk 4 years ago
parent
commit
3768349a05
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
14 changed files with 226 additions and 108 deletions
  1. +1
    -1
      extras/NetworkGraphicsDemo/Source/SharedCanvas.h
  2. +1
    -1
      modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp
  3. +180
    -81
      modules/juce_graphics/fonts/juce_Font.cpp
  4. +11
    -6
      modules/juce_graphics/fonts/juce_Font.h
  5. +2
    -2
      modules/juce_graphics/fonts/juce_GlyphArrangement.cpp
  6. +2
    -4
      modules/juce_graphics/fonts/juce_Typeface.cpp
  7. +2
    -2
      modules/juce_graphics/native/juce_RenderingHelpers.h
  8. +4
    -2
      modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm
  9. +7
    -3
      modules/juce_graphics/native/juce_mac_Fonts.mm
  10. +2
    -1
      modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp
  11. +5
    -3
      modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp
  12. +1
    -1
      modules/juce_graphics/native/juce_win32_Fonts.cpp
  13. +1
    -1
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp
  14. +7
    -0
      modules/juce_opengl/opengl/juce_OpenGLRenderer.h

+ 1
- 1
extras/NetworkGraphicsDemo/Source/SharedCanvas.h View File

@@ -399,7 +399,7 @@ public:
{
Path p;
Font& font = getState().font;
font.getTypeface()->getOutlineForGlyph (glyphNumber, p);
font.getTypefacePtr()->getOutlineForGlyph (glyphNumber, p);
fillPath (p, AffineTransform::scale (font.getHeight() * font.getHorizontalScale(), font.getHeight()).followedBy (transform));
}


+ 1
- 1
modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp View File

@@ -532,7 +532,7 @@ void LowLevelGraphicsPostScriptRenderer::drawGlyph (int glyphNumber, const Affin
{
Path p;
Font& font = stateStack.getLast()->font;
font.getTypeface()->getOutlineForGlyph (glyphNumber, p);
font.getTypefacePtr()->getOutlineForGlyph (glyphNumber, p);
fillPath (p, AffineTransform::scale (font.getHeight() * font.getHorizontalScale(), font.getHeight()).followedBy (transform));
}


+ 180
- 81
modules/juce_graphics/fonts/juce_Font.cpp View File

@@ -135,7 +135,11 @@ public:
return face.typeface;
}
Typeface::Ptr defaultFace;
Typeface::Ptr getDefaultFace() const noexcept
{
const ScopedReadLock slr (lock);
return defaultFace;
}
private:
struct CachedFace
@@ -151,6 +155,7 @@ private:
Typeface::Ptr typeface;
};
Typeface::Ptr defaultFace;
ReadWriteLock lock;
Array<CachedFace> faces;
size_t counter = 0;
@@ -182,7 +187,7 @@ class Font::SharedFontInternal : public ReferenceCountedObject
{
public:
SharedFontInternal() noexcept
: typeface (TypefaceCache::getInstance()->defaultFace),
: typeface (TypefaceCache::getInstance()->getDefaultFace()),
typefaceName (Font::getDefaultSansSerifFontName()),
typefaceStyle (Font::getDefaultStyle()),
height (FontValues::defaultFontHeight)
@@ -196,7 +201,7 @@ public:
underline ((styleFlags & underlined) != 0)
{
if (styleFlags == plain)
typeface = TypefaceCache::getInstance()->defaultFace;
typeface = TypefaceCache::getInstance()->getDefaultFace();
}
SharedFontInternal (const String& name, int styleFlags, float fontHeight) noexcept
@@ -206,7 +211,7 @@ public:
underline ((styleFlags & underlined) != 0)
{
if (styleFlags == plain && typefaceName.isEmpty())
typeface = TypefaceCache::getInstance()->defaultFace;
typeface = TypefaceCache::getInstance()->getDefaultFace();
}
SharedFontInternal (const String& name, const String& style, float fontHeight) noexcept
@@ -248,10 +253,119 @@ public:
&& typefaceStyle == other.typefaceStyle;
}
/* The typeface and ascent data members may be read/set from multiple threads
simultaneously, e.g. in the case that two Font instances reference the same
SharedFontInternal and call getTypefacePtr() simultaneously.
We lock in functions that modify the typeface or ascent in order to
ensure thread safety.
*/
Typeface::Ptr getTypefacePtr (const Font& f)
{
const ScopedLock lock (mutex);
if (typeface == nullptr)
{
typeface = TypefaceCache::getInstance()->findTypefaceFor (f);
jassert (typeface != nullptr);
}
return typeface;
}
void checkTypefaceSuitability (const Font& f)
{
const ScopedLock lock (mutex);
if (typeface != nullptr && ! typeface->isSuitableForFont (f))
typeface = nullptr;
}
float getAscent (const Font& f)
{
const ScopedLock lock (mutex);
if (ascent == 0.0f)
ascent = getTypefacePtr (f)->getAscent();
return height * ascent;
}
/* We do not need to lock in these functions, as it's guaranteed
that these data members can only change if there is a single Font
instance referencing the shared state.
*/
String getTypefaceName() const { return typefaceName; }
String getTypefaceStyle() const { return typefaceStyle; }
float getHeight() const { return height; }
float getHorizontalScale() const { return horizontalScale; }
float getKerning() const { return kerning; }
bool getUnderline() const { return underline; }
/* This shared state may be shared between two or more Font instances that are being
read/modified from multiple threads.
Before modifying a shared instance you *must* call dupeInternalIfShared to
ensure that only one Font instance is pointing to the SharedFontInternal instance
during the modification.
*/
void setTypeface (Typeface::Ptr x)
{
jassert (getReferenceCount() == 1);
typeface = std::move (x);
}
void setTypefaceName (String x)
{
jassert (getReferenceCount() == 1);
typefaceName = std::move (x);
}
void setTypefaceStyle (String x)
{
jassert (getReferenceCount() == 1);
typefaceStyle = std::move (x);
}
void setHeight (float x)
{
jassert (getReferenceCount() == 1);
height = x;
}
void setHorizontalScale (float x)
{
jassert (getReferenceCount() == 1);
horizontalScale = x;
}
void setKerning (float x)
{
jassert (getReferenceCount() == 1);
kerning = x;
}
void setAscent (float x)
{
jassert (getReferenceCount() == 1);
ascent = x;
}
void setUnderline (bool x)
{
jassert (getReferenceCount() == 1);
underline = x;
}
private:
Typeface::Ptr typeface;
String typefaceName, typefaceStyle;
float height, horizontalScale = 1.0f, kerning = 0, ascent = 0;
float height = 0.0f, horizontalScale = 1.0f, kerning = 0.0f, ascent = 0.0f;
bool underline = false;
CriticalSection mutex;
};
//==============================================================================
@@ -291,9 +405,7 @@ Font& Font::operator= (Font&& other) noexcept
return *this;
}
Font::~Font() noexcept
{
}
Font::~Font() noexcept = default;
bool Font::operator== (const Font& other) const noexcept
{
@@ -314,8 +426,7 @@ void Font::dupeInternalIfShared()
void Font::checkTypefaceSuitability()
{
if (font->typeface != nullptr && ! font->typeface->isSuitableForFont (*this))
font->typeface = nullptr;
font->checkTypefaceSuitability (*this);
}
//==============================================================================
@@ -346,30 +457,30 @@ const String& Font::getDefaultSerifFontName() { return getFontPlacehol
const String& Font::getDefaultMonospacedFontName() { return getFontPlaceholderNames().mono; }
const String& Font::getDefaultStyle() { return getFontPlaceholderNames().regular; }
const String& Font::getTypefaceName() const noexcept { return font->typefaceName; }
const String& Font::getTypefaceStyle() const noexcept { return font->typefaceStyle; }
String Font::getTypefaceName() const noexcept { return font->getTypefaceName(); }
String Font::getTypefaceStyle() const noexcept { return font->getTypefaceStyle(); }
void Font::setTypefaceName (const String& faceName)
{
if (faceName != font->typefaceName)
if (faceName != font->getTypefaceName())
{
jassert (faceName.isNotEmpty());
dupeInternalIfShared();
font->typefaceName = faceName;
font->typeface = nullptr;
font->ascent = 0;
font->setTypefaceName (faceName);
font->setTypeface (nullptr);
font->setAscent (0);
}
}
void Font::setTypefaceStyle (const String& typefaceStyle)
{
if (typefaceStyle != font->typefaceStyle)
if (typefaceStyle != font->getTypefaceStyle())
{
dupeInternalIfShared();
font->typefaceStyle = typefaceStyle;
font->typeface = nullptr;
font->ascent = 0;
font->setTypefaceStyle (typefaceStyle);
font->setTypeface (nullptr);
font->setAscent (0);
}
}
@@ -382,18 +493,17 @@ Font Font::withTypefaceStyle (const String& newStyle) const
StringArray Font::getAvailableStyles() const
{
return findAllTypefaceStyles (getTypeface()->getName());
return findAllTypefaceStyles (getTypefacePtr()->getName());
}
Typeface* Font::getTypeface() const
Typeface::Ptr Font::getTypefacePtr() const
{
if (font->typeface == nullptr)
{
font->typeface = TypefaceCache::getInstance()->findTypefaceFor (*this);
jassert (font->typeface != nullptr);
}
return font->getTypefacePtr (*this);
}
return font->typeface.get();
Typeface* Font::getTypeface() const
{
return getTypefacePtr().get();
}
//==============================================================================
@@ -435,7 +545,7 @@ Font Font::withHeight (const float newHeight) const
float Font::getHeightToPointsFactor() const
{
return getTypeface()->getHeightToPointsFactor();
return getTypefacePtr()->getHeightToPointsFactor();
}
Font Font::withPointHeight (float heightInPoints) const
@@ -449,10 +559,10 @@ void Font::setHeight (float newHeight)
{
newHeight = FontValues::limitFontHeight (newHeight);
if (font->height != newHeight)
if (font->getHeight() != newHeight)
{
dupeInternalIfShared();
font->height = newHeight;
font->setHeight (newHeight);
checkTypefaceSuitability();
}
}
@@ -461,18 +571,18 @@ void Font::setHeightWithoutChangingWidth (float newHeight)
{
newHeight = FontValues::limitFontHeight (newHeight);
if (font->height != newHeight)
if (font->getHeight() != newHeight)
{
dupeInternalIfShared();
font->horizontalScale *= (font->height / newHeight);
font->height = newHeight;
font->setHorizontalScale (font->getHorizontalScale() * (font->getHeight() / newHeight));
font->setHeight (newHeight);
checkTypefaceSuitability();
}
}
int Font::getStyleFlags() const noexcept
{
int styleFlags = font->underline ? underlined : plain;
int styleFlags = font->getUnderline() ? underlined : plain;
if (isBold()) styleFlags |= bold;
if (isItalic()) styleFlags |= italic;
@@ -492,10 +602,10 @@ void Font::setStyleFlags (const int newFlags)
if (getStyleFlags() != newFlags)
{
dupeInternalIfShared();
font->typeface = nullptr;
font->typefaceStyle = FontStyleHelpers::getStyleName (newFlags);
font->underline = (newFlags & underlined) != 0;
font->ascent = 0;
font->setTypeface (nullptr);
font->setTypefaceStyle (FontStyleHelpers::getStyleName (newFlags));
font->setUnderline ((newFlags & underlined) != 0);
font->setAscent (0);
}
}
@@ -506,14 +616,14 @@ void Font::setSizeAndStyle (float newHeight,
{
newHeight = FontValues::limitFontHeight (newHeight);
if (font->height != newHeight
|| font->horizontalScale != newHorizontalScale
|| font->kerning != newKerningAmount)
if (font->getHeight() != newHeight
|| font->getHorizontalScale() != newHorizontalScale
|| font->getKerning() != newKerningAmount)
{
dupeInternalIfShared();
font->height = newHeight;
font->horizontalScale = newHorizontalScale;
font->kerning = newKerningAmount;
font->setHeight (newHeight);
font->setHorizontalScale (newHorizontalScale);
font->setKerning (newKerningAmount);
checkTypefaceSuitability();
}
@@ -527,14 +637,14 @@ void Font::setSizeAndStyle (float newHeight,
{
newHeight = FontValues::limitFontHeight (newHeight);
if (font->height != newHeight
|| font->horizontalScale != newHorizontalScale
|| font->kerning != newKerningAmount)
if (font->getHeight() != newHeight
|| font->getHorizontalScale() != newHorizontalScale
|| font->getKerning() != newKerningAmount)
{
dupeInternalIfShared();
font->height = newHeight;
font->horizontalScale = newHorizontalScale;
font->kerning = newKerningAmount;
font->setHeight (newHeight);
font->setHorizontalScale (newHorizontalScale);
font->setKerning (newKerningAmount);
checkTypefaceSuitability();
}
@@ -551,18 +661,18 @@ Font Font::withHorizontalScale (const float newHorizontalScale) const
void Font::setHorizontalScale (const float scaleFactor)
{
dupeInternalIfShared();
font->horizontalScale = scaleFactor;
font->setHorizontalScale (scaleFactor);
checkTypefaceSuitability();
}
float Font::getHorizontalScale() const noexcept
{
return font->horizontalScale;
return font->getHorizontalScale();
}
float Font::getExtraKerningFactor() const noexcept
{
return font->kerning;
return font->getKerning();
}
Font Font::withExtraKerningFactor (const float extraKerning) const
@@ -575,16 +685,16 @@ Font Font::withExtraKerningFactor (const float extraKerning) const
void Font::setExtraKerningFactor (const float extraKerning)
{
dupeInternalIfShared();
font->kerning = extraKerning;
font->setKerning (extraKerning);
checkTypefaceSuitability();
}
Font Font::boldened() const { return withStyle (getStyleFlags() | bold); }
Font Font::italicised() const { return withStyle (getStyleFlags() | italic); }
bool Font::isBold() const noexcept { return FontStyleHelpers::isBold (font->typefaceStyle); }
bool Font::isItalic() const noexcept { return FontStyleHelpers::isItalic (font->typefaceStyle); }
bool Font::isUnderlined() const noexcept { return font->underline; }
bool Font::isBold() const noexcept { return FontStyleHelpers::isBold (font->getTypefaceStyle()); }
bool Font::isItalic() const noexcept { return FontStyleHelpers::isItalic (font->getTypefaceStyle()); }
bool Font::isUnderlined() const noexcept { return font->getUnderline(); }
void Font::setBold (const bool shouldBeBold)
{
@@ -603,20 +713,17 @@ void Font::setItalic (const bool shouldBeItalic)
void Font::setUnderline (const bool shouldBeUnderlined)
{
dupeInternalIfShared();
font->underline = shouldBeUnderlined;
font->setUnderline (shouldBeUnderlined);
checkTypefaceSuitability();
}
float Font::getAscent() const
{
if (font->ascent == 0.0f)
font->ascent = getTypeface()->getAscent();
return font->height * font->ascent;
return font->getAscent (*this);
}
float Font::getHeight() const noexcept { return font->height; }
float Font::getDescent() const { return font->height - getAscent(); }
float Font::getHeight() const noexcept { return font->getHeight(); }
float Font::getDescent() const { return font->getHeight() - getAscent(); }
float Font::getHeightInPoints() const { return getHeight() * getHeightToPointsFactor(); }
float Font::getAscentInPoints() const { return getAscent() * getHeightToPointsFactor(); }
@@ -629,35 +736,27 @@ int Font::getStringWidth (const String& text) const
float Font::getStringWidthFloat (const String& text) const
{
// This call isn't thread-safe when there's a message thread running
jassert (MessageManager::getInstanceWithoutCreating() == nullptr
|| MessageManager::getInstanceWithoutCreating()->currentThreadHasLockedMessageManager());
auto w = getTypeface()->getStringWidth (text);
auto w = getTypefacePtr()->getStringWidth (text);
if (font->kerning != 0.0f)
w += font->kerning * (float) text.length();
if (font->getKerning() != 0.0f)
w += font->getKerning() * (float) text.length();
return w * font->height * font->horizontalScale;
return w * font->getHeight() * font->getHorizontalScale();
}
void Font::getGlyphPositions (const String& text, Array<int>& glyphs, Array<float>& xOffsets) const
{
// This call isn't thread-safe when there's a message thread running
jassert (MessageManager::getInstanceWithoutCreating() == nullptr
|| MessageManager::getInstanceWithoutCreating()->currentThreadHasLockedMessageManager());
getTypeface()->getGlyphPositions (text, glyphs, xOffsets);
getTypefacePtr()->getGlyphPositions (text, glyphs, xOffsets);
if (auto num = xOffsets.size())
{
auto scale = font->height * font->horizontalScale;
auto scale = font->getHeight() * font->getHorizontalScale();
auto* x = xOffsets.getRawDataPointer();
if (font->kerning != 0.0f)
if (font->getKerning() != 0.0f)
{
for (int i = 0; i < num; ++i)
x[i] = (x[i] + (float) i * font->kerning) * scale;
x[i] = (x[i] + (float) i * font->getKerning()) * scale;
}
else
{


+ 11
- 6
modules/juce_graphics/fonts/juce_Font.h View File

@@ -121,7 +121,7 @@ public:
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()->getName(), which will give you the platform-specific font family.
Font::getTypefacePtr()->getName(), 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.
*/
@@ -136,15 +136,15 @@ public:
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()->getName(), which will give you the platform-specific font family.
Font::getTypefacePtr()->getName(), which will give you the platform-specific font family.
*/
const String& getTypefaceName() const noexcept;
String getTypefaceName() const noexcept;
//==============================================================================
/** Returns the font style of the typeface that this font uses.
@see withTypefaceStyle, getAvailableStyles()
*/
const String& getTypefaceStyle() const noexcept;
String getTypefaceStyle() const noexcept;
/** Changes the font style of the typeface.
@see getAvailableStyles()
@@ -395,12 +395,17 @@ public:
void getGlyphPositions (const String& text, Array<int>& glyphs, Array<float>& xOffsets) const;
//==============================================================================
/** Returns the typeface used by this font.
/** This is unsafe, use getTypefacePtr() instead.
Returns the typeface used by this font.
Note that the object returned may go out of scope if this font is deleted
or has its style changed.
*/
Typeface* getTypeface() const;
JUCE_DEPRECATED (Typeface* getTypeface() const);
/** Returns the typeface used by this font. */
Typeface::Ptr getTypefacePtr() const;
/** Creates an array of Font objects to represent all the fonts on the system.


+ 2
- 2
modules/juce_graphics/fonts/juce_GlyphArrangement.cpp View File

@@ -63,7 +63,7 @@ void PositionedGlyph::createPath (Path& path) const
{
if (! isWhitespace())
{
if (auto* t = font.getTypeface())
if (auto t = font.getTypefacePtr())
{
Path p;
t->getOutlineForGlyph (glyph, p);
@@ -78,7 +78,7 @@ bool PositionedGlyph::hitTest (float px, float py) const
{
if (getBounds().contains (px, py) && ! isWhitespace())
{
if (auto* t = font.getTypeface())
if (auto t = font.getTypefacePtr())
{
Path p;
t->getOutlineForGlyph (glyph, p);


+ 2
- 4
modules/juce_graphics/fonts/juce_Typeface.cpp View File

@@ -110,14 +110,12 @@ Typeface::Typeface (const String& faceName, const String& styleName) noexcept
{
}
Typeface::~Typeface()
{
}
Typeface::~Typeface() = default;
Typeface::Ptr Typeface::getFallbackTypeface()
{
const Font fallbackFont (Font::getFallbackFontName(), Font::getFallbackFontStyle(), 10.0f);
return Typeface::Ptr (fallbackFont.getTypeface());
return fallbackFont.getTypefacePtr();
}
EdgeTable* Typeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform, float fontHeight)


+ 2
- 2
modules/juce_graphics/native/juce_RenderingHelpers.h View File

@@ -289,7 +289,7 @@ public:
void generate (const Font& newFont, int glyphNumber)
{
font = newFont;
auto* typeface = newFont.getTypeface();
auto typeface = newFont.getTypefacePtr();
snapToIntegerCoordinate = typeface->isHinted();
glyph = glyphNumber;
@@ -2567,7 +2567,7 @@ public:
auto t = transform.getTransformWith (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
.followedBy (trans));
std::unique_ptr<EdgeTable> et (font.getTypeface()->getEdgeTableForGlyph (glyphNumber, t, fontHeight));
std::unique_ptr<EdgeTable> et (font.getTypefacePtr()->getEdgeTableForGlyph (glyphNumber, t, fontHeight));
if (et != nullptr)
fillShape (*new EdgeTableRegionType (*et), false);


+ 4
- 2
modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm View File

@@ -610,7 +610,9 @@ void CoreGraphicsContext::setFont (const Font& newFont)
state->fontRef = nullptr;
state->font = newFont;
if (auto osxTypeface = dynamic_cast<OSXTypeface*> (state->font.getTypeface()))
auto typeface = state->font.getTypefacePtr();
if (auto osxTypeface = dynamic_cast<OSXTypeface*> (typeface.get()))
{
state->fontRef = osxTypeface->fontRef;
CGContextSetFont (context.get(), state->fontRef);
@@ -667,7 +669,7 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra
{
Path p;
auto& f = state->font;
f.getTypeface()->getOutlineForGlyph (glyphNumber, p);
f.getTypefacePtr()->getOutlineForGlyph (glyphNumber, p);
fillPath (p, AffineTransform::scale (f.getHeight() * f.getHorizontalScale(), f.getHeight())
.followedBy (transform));


+ 7
- 3
modules/juce_graphics/native/juce_mac_Fonts.mm View File

@@ -748,7 +748,9 @@ private:
CTFontRef getCTFontFromTypeface (const Font& f)
{
if (auto* tf = dynamic_cast<OSXTypeface*> (f.getTypeface()))
const auto typeface = f.getTypefacePtr();
if (auto* tf = dynamic_cast<OSXTypeface*> (typeface.get()))
return tf->ctFontRef.get();
return {};
@@ -848,7 +850,7 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
static DefaultFontNames defaultNames;
auto newFont = font;
auto& faceName = font.getTypefaceName();
auto faceName = font.getTypefaceName();
if (faceName == getDefaultSansSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSans);
else if (faceName == getDefaultSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSerif);
@@ -866,7 +868,9 @@ static bool canAllTypefacesBeUsedInLayout (const AttributedString& text)
for (int i = 0; i < numCharacterAttributes; ++i)
{
if (auto tf = dynamic_cast<OSXTypeface*> (text.getAttribute (i).font.getTypeface()))
auto typeface = text.getAttribute (i).font.getTypefacePtr();
if (auto tf = dynamic_cast<OSXTypeface*> (typeface.get()))
if (tf->canBeUsedForLayout)
continue;


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

@@ -370,7 +370,8 @@ public:
{
if (currentFontFace == nullptr)
{
auto* typeface = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface());
auto typefacePtr = font.getTypefacePtr();
auto* typeface = dynamic_cast<WindowsDirectWriteTypeface*> (typefacePtr.get());
currentFontFace = typeface->getIDWriteFontFace();
fontHeightToEmSizeFactor = typeface->getUnitsToHeightScaleFactor();
}


+ 5
- 3
modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp View File

@@ -192,8 +192,9 @@ namespace DirectWriteTypeLayout
for (int i = 0; i < attributedString.getNumAttributes(); ++i)
{
auto& font = attributedString.getAttribute(i).font;
auto typeface = font.getTypefacePtr();
if (auto* wt = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface()))
if (auto* wt = dynamic_cast<WindowsDirectWriteTypeface*> (typeface.get()))
if (wt->getIDWriteFontFace() == glyphRun.fontFace)
return font.withHeight (fontHeight);
}
@@ -334,7 +335,7 @@ namespace DirectWriteTypeLayout
Font defaultFont;
BOOL fontFound = false;
uint32 fontIndex;
fontCollection.FindFamilyName (defaultFont.getTypeface()->getName().toWideCharPointer(), &fontIndex, &fontFound);
fontCollection.FindFamilyName (defaultFont.getTypefacePtr()->getName().toWideCharPointer(), &fontIndex, &fontFound);
if (! fontFound)
fontIndex = 0;
@@ -443,8 +444,9 @@ static bool canAllTypefacesAndFontsBeUsedInLayout (const AttributedString& text)
for (int i = 0; i < numCharacterAttributes; ++i)
{
const auto& font = text.getAttribute (i).font;
auto typeface = font.getTypefacePtr();
if (font.getHorizontalScale() != 1.0f || dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface()) == nullptr)
if (font.getHorizontalScale() != 1.0f || dynamic_cast<WindowsDirectWriteTypeface*> (typeface.get()) == nullptr)
return false;
}


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

@@ -300,7 +300,7 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
static DefaultFontNames defaultNames;
Font newFont (font);
auto& faceName = font.getTypefaceName();
auto faceName = font.getTypefaceName();
if (faceName == getDefaultSansSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSans);
else if (faceName == getDefaultSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSerif);


+ 1
- 1
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp View File

@@ -1664,7 +1664,7 @@ struct SavedState : public RenderingHelpers::SavedStateBase<SavedState>
auto t = transform.getTransformWith (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
.followedBy (trans));
const std::unique_ptr<EdgeTable> et (font.getTypeface()->getEdgeTableForGlyph (glyphNumber, t, fontHeight));
const std::unique_ptr<EdgeTable> et (font.getTypefacePtr()->getEdgeTableForGlyph (glyphNumber, t, fontHeight));
if (et != nullptr)
fillShape (*new EdgeTableRegionType (*et), false);


+ 7
- 0
modules/juce_opengl/opengl/juce_OpenGLRenderer.h View File

@@ -62,6 +62,13 @@ public:
For information about how to trigger a render callback, see
OpenGLContext::triggerRepaint() and OpenGLContext::setContinuousRepainting().
IMPORTANT: Never take a MessageManagerLock inside this function! On
macOS, the OpenGL context will be locked for the duration of this call.
The main thread may also attempt to interact with the OpenGL context at
any time, which will also require locking the OpenGL context. As a
result, taking a MessageManagerLock inside renderOpenGL() may cause a
hierarchical deadlock.
*/
virtual void renderOpenGL() = 0;


Loading…
Cancel
Save