diff --git a/extras/NetworkGraphicsDemo/Source/SharedCanvas.h b/extras/NetworkGraphicsDemo/Source/SharedCanvas.h index cdeb634340..450755ebc8 100644 --- a/extras/NetworkGraphicsDemo/Source/SharedCanvas.h +++ b/extras/NetworkGraphicsDemo/Source/SharedCanvas.h @@ -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)); } diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp b/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp index f66dde13e5..e7fbe8477a 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp @@ -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)); } diff --git a/modules/juce_graphics/fonts/juce_Font.cpp b/modules/juce_graphics/fonts/juce_Font.cpp index 4a08265e55..02d999c70b 100644 --- a/modules/juce_graphics/fonts/juce_Font.cpp +++ b/modules/juce_graphics/fonts/juce_Font.cpp @@ -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 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::Ptr Font::getTypefacePtr() const +{ + return font->getTypefacePtr (*this); } Typeface* Font::getTypeface() const { - if (font->typeface == nullptr) - { - font->typeface = TypefaceCache::getInstance()->findTypefaceFor (*this); - jassert (font->typeface != nullptr); - } - - return font->typeface.get(); + 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 = getTypefacePtr()->getStringWidth (text); - auto w = getTypeface()->getStringWidth (text); + if (font->getKerning() != 0.0f) + w += font->getKerning() * (float) text.length(); - if (font->kerning != 0.0f) - w += font->kerning * (float) text.length(); - - return w * font->height * font->horizontalScale; + return w * font->getHeight() * font->getHorizontalScale(); } void Font::getGlyphPositions (const String& text, Array& glyphs, Array& 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 { diff --git a/modules/juce_graphics/fonts/juce_Font.h b/modules/juce_graphics/fonts/juce_Font.h index 0d72f57b33..cb82613ce4 100644 --- a/modules/juce_graphics/fonts/juce_Font.h +++ b/modules/juce_graphics/fonts/juce_Font.h @@ -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& glyphs, Array& 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. diff --git a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp index 50984ac178..1d621f8517 100644 --- a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp +++ b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp @@ -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); diff --git a/modules/juce_graphics/fonts/juce_Typeface.cpp b/modules/juce_graphics/fonts/juce_Typeface.cpp index 71e2baba99..ed8961238e 100644 --- a/modules/juce_graphics/fonts/juce_Typeface.cpp +++ b/modules/juce_graphics/fonts/juce_Typeface.cpp @@ -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) diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h index a44c3d18db..dbde048f14 100644 --- a/modules/juce_graphics/native/juce_RenderingHelpers.h +++ b/modules/juce_graphics/native/juce_RenderingHelpers.h @@ -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 et (font.getTypeface()->getEdgeTableForGlyph (glyphNumber, t, fontHeight)); + std::unique_ptr et (font.getTypefacePtr()->getEdgeTableForGlyph (glyphNumber, t, fontHeight)); if (et != nullptr) fillShape (*new EdgeTableRegionType (*et), false); diff --git a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm index 77350dcc09..591fc7daf0 100644 --- a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm +++ b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm @@ -610,7 +610,9 @@ void CoreGraphicsContext::setFont (const Font& newFont) state->fontRef = nullptr; state->font = newFont; - if (auto osxTypeface = dynamic_cast (state->font.getTypeface())) + auto typeface = state->font.getTypefacePtr(); + + if (auto osxTypeface = dynamic_cast (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)); diff --git a/modules/juce_graphics/native/juce_mac_Fonts.mm b/modules/juce_graphics/native/juce_mac_Fonts.mm index 7dc38f5580..d58d3a9ba3 100644 --- a/modules/juce_graphics/native/juce_mac_Fonts.mm +++ b/modules/juce_graphics/native/juce_mac_Fonts.mm @@ -748,7 +748,9 @@ private: CTFontRef getCTFontFromTypeface (const Font& f) { - if (auto* tf = dynamic_cast (f.getTypeface())) + const auto typeface = f.getTypefacePtr(); + + if (auto* tf = dynamic_cast (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 (text.getAttribute (i).font.getTypeface())) + auto typeface = text.getAttribute (i).font.getTypefacePtr(); + + if (auto tf = dynamic_cast (typeface.get())) if (tf->canBeUsedForLayout) continue; diff --git a/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp b/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp index 8ca777b538..1f17a41c36 100644 --- a/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp +++ b/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp @@ -370,7 +370,8 @@ public: { if (currentFontFace == nullptr) { - auto* typeface = dynamic_cast (font.getTypeface()); + auto typefacePtr = font.getTypefacePtr(); + auto* typeface = dynamic_cast (typefacePtr.get()); currentFontFace = typeface->getIDWriteFontFace(); fontHeightToEmSizeFactor = typeface->getUnitsToHeightScaleFactor(); } diff --git a/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp b/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp index 189138d0c6..1b194506dd 100644 --- a/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp +++ b/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp @@ -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 (font.getTypeface())) + if (auto* wt = dynamic_cast (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 (font.getTypeface()) == nullptr) + if (font.getHorizontalScale() != 1.0f || dynamic_cast (typeface.get()) == nullptr) return false; } diff --git a/modules/juce_graphics/native/juce_win32_Fonts.cpp b/modules/juce_graphics/native/juce_win32_Fonts.cpp index f6b5faa5af..f7245d73b7 100644 --- a/modules/juce_graphics/native/juce_win32_Fonts.cpp +++ b/modules/juce_graphics/native/juce_win32_Fonts.cpp @@ -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); diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 5ca0201a43..bd7ea9da9f 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -1664,7 +1664,7 @@ struct SavedState : public RenderingHelpers::SavedStateBase auto t = transform.getTransformWith (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight) .followedBy (trans)); - const std::unique_ptr et (font.getTypeface()->getEdgeTableForGlyph (glyphNumber, t, fontHeight)); + const std::unique_ptr et (font.getTypefacePtr()->getEdgeTableForGlyph (glyphNumber, t, fontHeight)); if (et != nullptr) fillShape (*new EdgeTableRegionType (*et), false); diff --git a/modules/juce_opengl/opengl/juce_OpenGLRenderer.h b/modules/juce_opengl/opengl/juce_OpenGLRenderer.h index 88ce648439..82fe33d078 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLRenderer.h +++ b/modules/juce_opengl/opengl/juce_OpenGLRenderer.h @@ -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;