summaryrefslogtreecommitdiffstats
path: root/gfx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-08 15:12:12 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-08 15:12:12 +0000
commita7c14e2f29831f4bc5eb18e23e55eb6f7a4e3431 (patch)
tree54617b4f5f04ee87a2c9e3b97cc88b8626859124 /gfx
parentReleasing progress-linux version 115.7.0esr-1~deb12u1progress7u1. (diff)
downloadfirefox-esr-a7c14e2f29831f4bc5eb18e23e55eb6f7a4e3431.tar.xz
firefox-esr-a7c14e2f29831f4bc5eb18e23e55eb6f7a4e3431.zip
Merging upstream version 115.8.0esr.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx')
-rw-r--r--gfx/2d/DrawTarget.cpp5
-rw-r--r--gfx/2d/ScaledFontBase.cpp16
-rw-r--r--gfx/gl/GLContext.cpp6
-rw-r--r--gfx/gl/GLContext.h2
-rw-r--r--gfx/gl/GLContextProviderCGL.mm2
-rw-r--r--gfx/gl/GLContextProviderEAGL.mm2
-rw-r--r--gfx/gl/GLContextProviderWGL.cpp10
-rw-r--r--gfx/gl/GLLibraryEGL.h8
-rw-r--r--gfx/gl/GLXLibrary.h3
-rw-r--r--gfx/ipc/InProcessCompositorSession.cpp5
-rw-r--r--gfx/ipc/RemoteCompositorSession.cpp5
-rw-r--r--gfx/thebes/SharedFontList-impl.h6
-rw-r--r--gfx/thebes/SharedFontList.cpp83
-rw-r--r--gfx/thebes/SharedFontList.h7
-rw-r--r--gfx/thebes/gfxDWriteFontList.cpp12
-rw-r--r--gfx/thebes/gfxDWriteFonts.cpp12
-rw-r--r--gfx/thebes/gfxFT2FontList.cpp2
-rw-r--r--gfx/thebes/gfxFcPlatformFontList.cpp2
-rw-r--r--gfx/thebes/gfxFontEntry.cpp3
-rw-r--r--gfx/thebes/gfxFontEntry.h1
-rw-r--r--gfx/thebes/gfxMacPlatformFontList.h30
-rw-r--r--gfx/thebes/gfxMacPlatformFontList.mm23
-rw-r--r--gfx/thebes/gfxPlatformFontList.cpp76
-rw-r--r--gfx/thebes/gfxPlatformFontList.h8
24 files changed, 206 insertions, 123 deletions
diff --git a/gfx/2d/DrawTarget.cpp b/gfx/2d/DrawTarget.cpp
index eb7b23f3be..7f95dc6661 100644
--- a/gfx/2d/DrawTarget.cpp
+++ b/gfx/2d/DrawTarget.cpp
@@ -183,8 +183,9 @@ void DrawTarget::StrokeGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions) {
- RefPtr<Path> path = aFont->GetPathForGlyphs(aBuffer, this);
- Stroke(path, aPattern, aStrokeOptions, aOptions);
+ if (RefPtr<Path> path = aFont->GetPathForGlyphs(aBuffer, this)) {
+ Stroke(path, aPattern, aStrokeOptions, aOptions);
+ }
}
already_AddRefed<SourceSurface> DrawTarget::IntoLuminanceSource(
diff --git a/gfx/2d/ScaledFontBase.cpp b/gfx/2d/ScaledFontBase.cpp
index d62dcb0127..cd52df3ccd 100644
--- a/gfx/2d/ScaledFontBase.cpp
+++ b/gfx/2d/ScaledFontBase.cpp
@@ -127,7 +127,11 @@ already_AddRefed<Path> ScaledFontBase::GetPathForGlyphs(
}
#ifdef USE_CAIRO
if (aTarget->GetBackendType() == BackendType::CAIRO) {
- MOZ_ASSERT(mScaledFont);
+ auto* cairoScaledFont = GetCairoScaledFont();
+ if (!cairoScaledFont) {
+ MOZ_ASSERT_UNREACHABLE("Invalid scaled font");
+ return nullptr;
+ }
DrawTarget* dt = const_cast<DrawTarget*>(aTarget);
cairo_t* ctx = static_cast<cairo_t*>(
@@ -141,7 +145,7 @@ already_AddRefed<Path> ScaledFontBase::GetPathForGlyphs(
cairo_set_matrix(ctx, &mat);
}
- cairo_set_scaled_font(ctx, mScaledFont);
+ cairo_set_scaled_font(ctx, cairoScaledFont);
// Convert our GlyphBuffer into an array of Cairo glyphs.
std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
@@ -181,7 +185,11 @@ void ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer& aBuffer,
}
#ifdef USE_CAIRO
if (backendType == BackendType::CAIRO) {
- MOZ_ASSERT(mScaledFont);
+ auto* cairoScaledFont = GetCairoScaledFont();
+ if (!cairoScaledFont) {
+ MOZ_ASSERT_UNREACHABLE("Invalid scaled font");
+ return;
+ }
PathBuilderCairo* builder = static_cast<PathBuilderCairo*>(aBuilder);
cairo_t* ctx = cairo_create(DrawTargetCairo::GetDummySurface());
@@ -200,7 +208,7 @@ void ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer& aBuffer,
glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
}
- cairo_set_scaled_font(ctx, mScaledFont);
+ cairo_set_scaled_font(ctx, cairoScaledFont);
cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs);
RefPtr<PathCairo> cairoPath = new PathCairo(ctx);
diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp
index f67aedd0b2..d11c131c45 100644
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -2432,6 +2432,12 @@ uint32_t GetBytesPerTexel(GLenum format, GLenum type) {
return 0;
}
+void GLContext::ResetTLSCurrentContext() {
+ if (sCurrentContext.init()) {
+ sCurrentContext.set(nullptr);
+ }
+}
+
bool GLContext::MakeCurrent(bool aForce) const {
if (MOZ_UNLIKELY(IsContextLost())) return false;
diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h
index d88b96019f..41dbe92bee 100644
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -185,6 +185,8 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
bool mImplicitMakeCurrent = false;
bool mUseTLSIsCurrent;
+ static void ResetTLSCurrentContext();
+
class TlsScope final {
const WeakPtr<GLContext> mGL;
const bool mWasTlsOk;
diff --git a/gfx/gl/GLContextProviderCGL.mm b/gfx/gl/GLContextProviderCGL.mm
index 1b4049de3e..a01701f571 100644
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -84,6 +84,8 @@ CGLContextObj GLContextCGL::GetCGLContext() const {
bool GLContextCGL::MakeCurrentImpl() const {
if (mContext) {
+ GLContext::ResetTLSCurrentContext();
+
[mContext makeCurrentContext];
MOZ_ASSERT(IsCurrentImpl());
// Use non-blocking swap in "ASAP mode".
diff --git a/gfx/gl/GLContextProviderEAGL.mm b/gfx/gl/GLContextProviderEAGL.mm
index 4aabe89df1..b90adaacf3 100644
--- a/gfx/gl/GLContextProviderEAGL.mm
+++ b/gfx/gl/GLContextProviderEAGL.mm
@@ -90,6 +90,8 @@ bool GLContextEAGL::RecreateRB() {
bool GLContextEAGL::MakeCurrentImpl() const {
if (mContext) {
+ GLContext::ResetTLSCurrentContext();
+
if (![EAGLContext setCurrentContext:mContext]) {
return false;
}
diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp
index 2720cab14e..5d90ee5169 100644
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -158,12 +158,16 @@ bool WGLLibrary::EnsureInitialized() {
const auto curCtx = mSymbols.fGetCurrentContext();
const auto curDC = mSymbols.fGetCurrentDC();
+ GLContext::ResetTLSCurrentContext();
+
if (!mSymbols.fMakeCurrent(mRootDc, mDummyGlrc)) {
NS_WARNING("wglMakeCurrent failed");
return false;
}
- const auto resetContext =
- MakeScopeExit([&]() { mSymbols.fMakeCurrent(curDC, curCtx); });
+ const auto resetContext = MakeScopeExit([&]() {
+ GLContext::ResetTLSCurrentContext();
+ mSymbols.fMakeCurrent(curDC, curCtx);
+ });
const auto loader = GetSymbolLoader();
@@ -297,6 +301,8 @@ GLContextWGL::~GLContextWGL() {
}
bool GLContextWGL::MakeCurrentImpl() const {
+ GLContext::ResetTLSCurrentContext();
+
const bool succeeded = sWGLLib.mSymbols.fMakeCurrent(mDC, mContext);
NS_ASSERTION(succeeded, "Failed to make GL context current!");
return succeeded;
diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h
index 28f84b27f4..0a853e67c9 100644
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -11,7 +11,7 @@
#include "base/platform_thread.h" // for PlatformThreadId
#include "gfxEnv.h"
-#include "GLTypes.h"
+#include "GLContext.h"
#include "mozilla/EnumTypeTraits.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/Maybe.h"
@@ -264,7 +264,6 @@ class GLLibraryEGL final {
const bool CHECK_CONTEXT_OWNERSHIP = true;
if (CHECK_CONTEXT_OWNERSHIP) {
const MutexAutoLock lock(mMutex);
-
const auto tid = PlatformThread::CurrentId();
const auto prevCtx = fGetCurrentContext();
@@ -287,6 +286,11 @@ class GLLibraryEGL final {
}
}
+ // Always reset the TLS current context.
+ // If we're called by TLS-caching MakeCurrent, after we return true,
+ // the caller will set the TLS correctly anyway.
+ GLContext::ResetTLSCurrentContext();
+
WRAP(fMakeCurrent(dpy, draw, read, ctx));
}
diff --git a/gfx/gl/GLXLibrary.h b/gfx/gl/GLXLibrary.h
index 7a004762ff..d2577c935c 100644
--- a/gfx/gl/GLXLibrary.h
+++ b/gfx/gl/GLXLibrary.h
@@ -6,7 +6,7 @@
#ifndef GFX_GLXLIBRARY_H
#define GFX_GLXLIBRARY_H
-#include "GLContextTypes.h"
+#include "GLContext.h"
#include "mozilla/Assertions.h"
#include "mozilla/DataMutex.h"
#include "mozilla/gfx/XlibDisplay.h"
@@ -65,6 +65,7 @@ class GLXLibrary final {
Bool fMakeCurrent(Display* display, GLXDrawable drawable,
GLXContext context) const {
DECL_WRAPPER_SCOPE(display)
+ GLContext::ResetTLSCurrentContext();
return mSymbols.fMakeCurrent(display, drawable, context);
}
diff --git a/gfx/ipc/InProcessCompositorSession.cpp b/gfx/ipc/InProcessCompositorSession.cpp
index f5f94461cb..9efb83b57a 100644
--- a/gfx/ipc/InProcessCompositorSession.cpp
+++ b/gfx/ipc/InProcessCompositorSession.cpp
@@ -61,7 +61,10 @@ RefPtr<InProcessCompositorSession> InProcessCompositorSession::Create(
}
void InProcessCompositorSession::NotifySessionLost() {
- mWidget->NotifyCompositorSessionLost(this);
+ // Hold a reference to mWidget since NotifyCompositorSessionLost may
+ // release the last reference mid-execution.
+ RefPtr<nsBaseWidget> widget(mWidget);
+ widget->NotifyCompositorSessionLost(this);
}
CompositorBridgeParent* InProcessCompositorSession::GetInProcessBridge() const {
diff --git a/gfx/ipc/RemoteCompositorSession.cpp b/gfx/ipc/RemoteCompositorSession.cpp
index bbd8ddd13f..34b7cd4856 100644
--- a/gfx/ipc/RemoteCompositorSession.cpp
+++ b/gfx/ipc/RemoteCompositorSession.cpp
@@ -46,10 +46,13 @@ RemoteCompositorSession::~RemoteCompositorSession() {
}
void RemoteCompositorSession::NotifySessionLost() {
+ // Hold a reference to mWidget since NotifyCompositorSessionLost may
+ // release the last reference mid-execution.
+ RefPtr<nsBaseWidget> widget(mWidget);
// Re-entrancy should be impossible: when we are being notified of a lost
// session, we have by definition not shut down yet. We will shutdown, but
// then will be removed from the notification list.
- mWidget->NotifyCompositorSessionLost(this);
+ widget->NotifyCompositorSessionLost(this);
}
CompositorBridgeParent* RemoteCompositorSession::GetInProcessBridge() const {
diff --git a/gfx/thebes/SharedFontList-impl.h b/gfx/thebes/SharedFontList-impl.h
index e39e4dd47d..928e9eb2d6 100644
--- a/gfx/thebes/SharedFontList-impl.h
+++ b/gfx/thebes/SharedFontList-impl.h
@@ -200,12 +200,6 @@ class FontList {
*/
Pointer Alloc(uint32_t aSize);
- /**
- * Convert a native pointer to a shared-memory Pointer record that can be
- * passed between processes.
- */
- Pointer ToSharedPointer(const void* aPtr);
-
uint32_t GetGeneration() { return GetHeader().mGeneration; }
/**
diff --git a/gfx/thebes/SharedFontList.cpp b/gfx/thebes/SharedFontList.cpp
index e9f64089be..f97e7e2832 100644
--- a/gfx/thebes/SharedFontList.cpp
+++ b/gfx/thebes/SharedFontList.cpp
@@ -138,11 +138,13 @@ Family::Family(FontList* aList, const InitData& aData)
class SetCharMapRunnable : public mozilla::Runnable {
public:
- SetCharMapRunnable(uint32_t aListGeneration, Pointer aFacePtr,
- gfxCharacterMap* aCharMap)
+ SetCharMapRunnable(uint32_t aListGeneration,
+ std::pair<uint32_t, bool> aFamilyIndex,
+ uint32_t aFaceIndex, gfxCharacterMap* aCharMap)
: Runnable("SetCharMapRunnable"),
mListGeneration(aListGeneration),
- mFacePtr(aFacePtr),
+ mFamilyIndex(aFamilyIndex),
+ mFaceIndex(aFaceIndex),
mCharMap(aCharMap) {}
NS_IMETHOD Run() override {
@@ -150,26 +152,39 @@ class SetCharMapRunnable : public mozilla::Runnable {
if (!list || list->GetGeneration() != mListGeneration) {
return NS_OK;
}
- dom::ContentChild::GetSingleton()->SendSetCharacterMap(mListGeneration,
- mFacePtr, *mCharMap);
+ dom::ContentChild::GetSingleton()->SendSetCharacterMap(
+ mListGeneration, mFamilyIndex.first, mFamilyIndex.second, mFaceIndex,
+ *mCharMap);
return NS_OK;
}
private:
uint32_t mListGeneration;
- Pointer mFacePtr;
+ std::pair<uint32_t, bool> mFamilyIndex;
+ uint32_t mFaceIndex;
RefPtr<gfxCharacterMap> mCharMap;
};
-void Face::SetCharacterMap(FontList* aList, gfxCharacterMap* aCharMap) {
+void Face::SetCharacterMap(FontList* aList, gfxCharacterMap* aCharMap,
+ const Family* aFamily) {
if (!XRE_IsParentProcess()) {
- Pointer ptr = aList->ToSharedPointer(this);
+ std::pair<uint32_t, bool> familyIndex = aFamily->FindIndex(aList);
+ const auto* faces = aFamily->Faces(aList);
+ uint32_t faceIndex = 0;
+ while (faceIndex < aFamily->NumFaces()) {
+ if (faces[faceIndex].ToPtr<Face>(aList) == this) {
+ break;
+ }
+ ++faceIndex;
+ }
+ MOZ_RELEASE_ASSERT(faceIndex < aFamily->NumFaces(), "Face ptr not found!");
if (NS_IsMainThread()) {
dom::ContentChild::GetSingleton()->SendSetCharacterMap(
- aList->GetGeneration(), ptr, *aCharMap);
+ aList->GetGeneration(), familyIndex.first, familyIndex.second,
+ faceIndex, *aCharMap);
} else {
- NS_DispatchToMainThread(
- new SetCharMapRunnable(aList->GetGeneration(), ptr, aCharMap));
+ NS_DispatchToMainThread(new SetCharMapRunnable(
+ aList->GetGeneration(), familyIndex, faceIndex, aCharMap));
}
return;
}
@@ -240,7 +255,7 @@ void Family::AddFaces(FontList* aList, const nsTArray<Face::InitData>& aFaces) {
(void)new (face) Face(aList, *initData);
facePtrs[i] = fp;
if (initData->mCharMap) {
- face->SetCharacterMap(aList, initData->mCharMap);
+ face->SetCharacterMap(aList, initData->mCharMap, this);
}
}
}
@@ -613,16 +628,19 @@ void Family::SetupFamilyCharMap(FontList* aList) {
}
if (!XRE_IsParentProcess()) {
// |this| could be a Family record in either the Families() or Aliases()
- // arrays
+ // arrays; FindIndex will map it back to its index and which array.
+ std::pair<uint32_t, bool> index = FindIndex(aList);
if (NS_IsMainThread()) {
dom::ContentChild::GetSingleton()->SendSetupFamilyCharMap(
- aList->GetGeneration(), aList->ToSharedPointer(this));
+ aList->GetGeneration(), index.first, index.second);
return;
}
NS_DispatchToMainThread(NS_NewRunnableFunction(
"SetupFamilyCharMap callback",
- [gen = aList->GetGeneration(), ptr = aList->ToSharedPointer(this)] {
- dom::ContentChild::GetSingleton()->SendSetupFamilyCharMap(gen, ptr);
+ [gen = aList->GetGeneration(), idx = index.first,
+ alias = index.second] {
+ dom::ContentChild::GetSingleton()->SendSetupFamilyCharMap(gen, idx,
+ alias);
}));
return;
}
@@ -667,6 +685,26 @@ void Family::SetupFamilyCharMap(FontList* aList) {
}
}
+std::pair<uint32_t, bool> Family::FindIndex(FontList* aList) const {
+ const auto* start = aList->Families();
+ const auto* end = start + aList->NumFamilies();
+ if (this >= start && this < end) {
+ uint32_t index = this - start;
+ MOZ_RELEASE_ASSERT(start + index == this, "misaligned Family ptr!");
+ return std::pair(index, false);
+ }
+
+ start = aList->AliasFamilies();
+ end = start + aList->NumAliases();
+ if (this >= start && this < end) {
+ uint32_t index = this - start;
+ MOZ_RELEASE_ASSERT(start + index == this, "misaligned AliasFamily ptr!");
+ return std::pair(index, true);
+ }
+
+ MOZ_CRASH("invalid font-list Family ptr!");
+}
+
FontList::FontList(uint32_t aGeneration) {
if (XRE_IsParentProcess()) {
// Create the initial shared block, and initialize Header
@@ -1322,19 +1360,6 @@ void FontList::SearchForLocalFace(const nsACString& aName, Family** aFamily,
}
}
-Pointer FontList::ToSharedPointer(const void* aPtr) {
- const char* p = (const char*)aPtr;
- const uint32_t blockCount = mBlocks.Length();
- for (uint32_t i = 0; i < blockCount; ++i) {
- const char* blockAddr = (const char*)mBlocks[i]->Memory();
- if (p >= blockAddr && p < blockAddr + SHM_BLOCK_SIZE) {
- return Pointer(i, p - blockAddr);
- }
- }
- MOZ_DIAGNOSTIC_ASSERT(false, "invalid shared-memory pointer");
- return Pointer::Null();
-}
-
size_t FontList::SizeOfIncludingThis(
mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
diff --git a/gfx/thebes/SharedFontList.h b/gfx/thebes/SharedFontList.h
index f2eaf28223..279bbd1a57 100644
--- a/gfx/thebes/SharedFontList.h
+++ b/gfx/thebes/SharedFontList.h
@@ -198,7 +198,8 @@ struct Face {
return !mDescriptor.IsNull() && mIndex != uint16_t(-1);
}
- void SetCharacterMap(FontList* aList, gfxCharacterMap* aCharMap);
+ void SetCharacterMap(FontList* aList, gfxCharacterMap* aCharMap,
+ const Family* aFamily);
String mDescriptor;
uint16_t mIndex;
@@ -330,6 +331,10 @@ struct Family {
void SetupFamilyCharMap(FontList* aList);
+ // Return the index of this family in the font-list's Families() or
+ // AliasFamilies() list, and which of those it belongs to.
+ std::pair<uint32_t, bool> FindIndex(FontList* aList) const;
+
private:
// Returns true if there are specifically-sized bitmap faces in the list,
// so size selection still needs to be done. (Currently only on Linux.)
diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp
index d31ba05deb..cb88fd86d9 100644
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -554,7 +554,7 @@ nsresult gfxDWriteFontEntry::ReadCMAP(FontInfoData* aFontInfoData) {
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
fontlist::FontList* sharedFontList = pfl->SharedFontList();
if (!IsUserFont() && mShmemFace) {
- mShmemFace->SetCharacterMap(sharedFontList, charmap); // async
+ mShmemFace->SetCharacterMap(sharedFontList, charmap, mShmemFamily);
if (TrySetShmemCharacterMap()) {
setCharMap = false;
}
@@ -674,11 +674,13 @@ gfxFont* gfxDWriteFontEntry::CreateFontInstance(
switch (StaticPrefs::gfx_font_rendering_directwrite_bold_simulation()) {
case 0: // never use the DWrite simulation
break;
- case 1: // use DWrite simulation for installed fonts but not webfonts
- useBoldSim = !mIsDataUserFont;
+ case 1: // use DWrite simulation for installed fonts except COLR fonts,
+ // but not webfonts
+ useBoldSim =
+ !mIsDataUserFont && !HasFontTable(TRUETYPE_TAG('C', 'O', 'L', 'R'));
break;
- default: // always use DWrite bold simulation
- useBoldSim = true;
+ default: // always use DWrite bold simulation, except for COLR fonts
+ useBoldSim = !HasFontTable(TRUETYPE_TAG('C', 'O', 'L', 'R'));
break;
}
}
diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp
index fa6bc48cf9..a77dfee6be 100644
--- a/gfx/thebes/gfxDWriteFonts.cpp
+++ b/gfx/thebes/gfxDWriteFonts.cpp
@@ -96,11 +96,15 @@ gfxDWriteFont::gfxDWriteFont(const RefPtr<UnscaledFontDWrite>& aUnscaledFont,
case 0: // never use the DWrite simulation
mApplySyntheticBold = true;
break;
- case 1: // use DWrite simulation for installed fonts but not webfonts
- mApplySyntheticBold = aFontEntry->mIsDataUserFont;
+ case 1: // use DWrite simulation for installed fonts except COLR fonts,
+ // but not webfonts
+ mApplySyntheticBold =
+ aFontEntry->mIsDataUserFont ||
+ aFontEntry->HasFontTable(TRUETYPE_TAG('C', 'O', 'L', 'R'));
break;
- default: // always use DWrite bold simulation
- // the flag is initialized to false in gfxFont
+ default: // always use DWrite bold simulation, except for COLR fonts
+ mApplySyntheticBold =
+ aFontEntry->HasFontTable(TRUETYPE_TAG('C', 'O', 'L', 'R'));
break;
}
}
diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp
index 372abce92d..b68fcac3e0 100644
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -427,7 +427,7 @@ nsresult FT2FontEntry::ReadCMAP(FontInfoData* aFontInfoData) {
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
fontlist::FontList* sharedFontList = pfl->SharedFontList();
if (!IsUserFont() && mShmemFace) {
- mShmemFace->SetCharacterMap(sharedFontList, charmap); // async
+ mShmemFace->SetCharacterMap(sharedFontList, charmap, mShmemFamily);
if (TrySetShmemCharacterMap()) {
setCharMap = false;
}
diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp
index 4ecbe0d657..ff5c8d4acf 100644
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -448,7 +448,7 @@ nsresult gfxFontconfigFontEntry::ReadCMAP(FontInfoData* aFontInfoData) {
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
fontlist::FontList* sharedFontList = pfl->SharedFontList();
if (!IsUserFont() && mShmemFace) {
- mShmemFace->SetCharacterMap(sharedFontList, charmap); // async
+ mShmemFace->SetCharacterMap(sharedFontList, charmap, mShmemFamily);
if (TrySetShmemCharacterMap()) {
setCharMap = false;
}
diff --git a/gfx/thebes/gfxFontEntry.cpp b/gfx/thebes/gfxFontEntry.cpp
index 6d32cc2cfc..9918fc1c4d 100644
--- a/gfx/thebes/gfxFontEntry.cpp
+++ b/gfx/thebes/gfxFontEntry.cpp
@@ -132,12 +132,13 @@ gfxFontEntry::~gfxFontEntry() {
// the entry, so locking not required.
void gfxFontEntry::InitializeFrom(fontlist::Face* aFace,
const fontlist::Family* aFamily) {
+ mShmemFace = aFace;
+ mShmemFamily = aFamily;
mStyleRange = aFace->mStyle;
mWeightRange = aFace->mWeight;
mStretchRange = aFace->mStretch;
mFixedPitch = aFace->mFixedPitch;
mIsBadUnderlineFont = aFamily->IsBadUnderlineFamily();
- mShmemFace = aFace;
auto* list = gfxPlatformFontList::PlatformFontList()->SharedFontList();
mFamilyName = aFamily->DisplayName().AsString(list);
mHasCmapTable = TrySetShmemCharacterMap();
diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h
index 86d2445d0b..a721f7f6b6 100644
--- a/gfx/thebes/gfxFontEntry.h
+++ b/gfx/thebes/gfxFontEntry.h
@@ -555,6 +555,7 @@ class gfxFontEntry {
gfxCharacterMap* GetCharacterMap() const { return mCharacterMap; }
mozilla::fontlist::Face* mShmemFace = nullptr;
+ const mozilla::fontlist::Family* mShmemFamily = nullptr;
mozilla::Atomic<const SharedBitSet*> mShmemCharacterMap;
const SharedBitSet* GetShmemCharacterMap() const {
diff --git a/gfx/thebes/gfxMacPlatformFontList.h b/gfx/thebes/gfxMacPlatformFontList.h
index 518c58d3af..dd24eebe69 100644
--- a/gfx/thebes/gfxMacPlatformFontList.h
+++ b/gfx/thebes/gfxMacPlatformFontList.h
@@ -54,7 +54,7 @@ class MacOSFontEntry final : public gfxFontEntry {
// returns it; if not, the instance returned will be owned solely by the
// caller.)
// Note that in the case of a broken font, this could return null.
- CGFontRef CreateOrCopyFontRef();
+ CGFontRef CreateOrCopyFontRef() MOZ_REQUIRES_SHARED(mLock);
// override gfxFontEntry table access function to bypass table cache,
// use CGFontRef API to get direct access to system font data
@@ -84,19 +84,19 @@ class MacOSFontEntry final : public gfxFontEntry {
static void DestroyBlobFunc(void* aUserData);
- CGFontRef
- mFontRef; // owning reference to the CGFont, released on destruction
+ CGFontRef mFontRef MOZ_GUARDED_BY(mLock); // owning reference
- double mSizeHint;
+ const double mSizeHint;
- bool mFontRefInitialized;
- bool mRequiresAAT;
- bool mIsCFF;
- bool mIsCFFInitialized;
- bool mHasVariations;
- bool mHasVariationsInitialized;
- bool mHasAATSmallCaps;
- bool mHasAATSmallCapsInitialized;
+ bool mFontRefInitialized MOZ_GUARDED_BY(mLock);
+
+ mozilla::Atomic<bool> mRequiresAAT;
+ mozilla::Atomic<bool> mIsCFF;
+ mozilla::Atomic<bool> mIsCFFInitialized;
+ mozilla::Atomic<bool> mHasVariations;
+ mozilla::Atomic<bool> mHasVariationsInitialized;
+ mozilla::Atomic<bool> mHasAATSmallCaps;
+ mozilla::Atomic<bool> mHasAATSmallCapsInitialized;
// To work around Core Text's mishandling of the default value for 'opsz',
// we need to record whether the font has an a optical size axis, what its
@@ -105,10 +105,10 @@ class MacOSFontEntry final : public gfxFontEntry {
// These fields are used by gfxMacFont, but stored in the font entry so
// that only a single font instance needs to inspect the available
// variations.
- gfxFontVariationAxis mOpszAxis;
- float mAdjustedDefaultOpsz;
+ gfxFontVariationAxis mOpszAxis MOZ_GUARDED_BY(mLock);
+ float mAdjustedDefaultOpsz MOZ_GUARDED_BY(mLock);
- nsTHashtable<nsUint32HashKey> mAvailableTables;
+ nsTHashtable<nsUint32HashKey> mAvailableTables MOZ_GUARDED_BY(mLock);
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont;
};
diff --git a/gfx/thebes/gfxMacPlatformFontList.mm b/gfx/thebes/gfxMacPlatformFontList.mm
index b95c6fa1d1..8942a4247a 100644
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -414,8 +414,8 @@ nsresult MacOSFontEntry::ReadCMAP(FontInfoData* aFontInfoData) {
if (NS_SUCCEEDED(rv)) {
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
fontlist::FontList* sharedFontList = pfl->SharedFontList();
- if (!IsUserFont() && mShmemFace) {
- mShmemFace->SetCharacterMap(sharedFontList, charmap); // async
+ if (!IsUserFont() && mShmemFace && mShmemFamily) {
+ mShmemFace->SetCharacterMap(sharedFontList, charmap, mShmemFamily);
if (TrySetShmemCharacterMap()) {
setCharMap = false;
}
@@ -552,6 +552,13 @@ gfxFontEntry* MacOSFontEntry::Clone() const {
}
CGFontRef MacOSFontEntry::GetFontRef() {
+ {
+ AutoReadLock lock(mLock);
+ if (mFontRefInitialized) {
+ return mFontRef;
+ }
+ }
+ AutoWriteLock lock(mLock);
if (!mFontRefInitialized) {
// Cache the CGFontRef, to be released by our destructor.
mFontRef = CreateOrCopyFontRef();
@@ -616,7 +623,9 @@ class FontTableRec {
}
hb_blob_t* MacOSFontEntry::GetFontTable(uint32_t aTag) {
+ mLock.ReadLock();
AutoCFRelease<CGFontRef> fontRef = CreateOrCopyFontRef();
+ mLock.ReadUnlock();
if (!fontRef) {
return nullptr;
}
@@ -637,6 +646,16 @@ hb_blob_t* MacOSFontEntry::GetFontTable(uint32_t aTag) {
}
bool MacOSFontEntry::HasFontTable(uint32_t aTableTag) {
+ {
+ // If we've already initialized mAvailableTables, we can return without
+ // needing to take an exclusive lock.
+ AutoReadLock lock(mLock);
+ if (mAvailableTables.Count()) {
+ return mAvailableTables.GetEntry(aTableTag);
+ }
+ }
+
+ AutoWriteLock lock(mLock);
if (mAvailableTables.Count() == 0) {
nsAutoreleasePool localPool;
diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp
index 1131ecb513..282fb36195 100644
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -3014,7 +3014,8 @@ void gfxPlatformFontList::InitializeFamily(uint32_t aGeneration,
}
void gfxPlatformFontList::SetCharacterMap(uint32_t aGeneration,
- const fontlist::Pointer& aFacePtr,
+ uint32_t aFamilyIndex, bool aAlias,
+ uint32_t aFaceIndex,
const gfxSparseBitSet& aMap) {
MOZ_ASSERT(XRE_IsParentProcess());
auto list = SharedFontList();
@@ -3028,14 +3029,35 @@ void gfxPlatformFontList::SetCharacterMap(uint32_t aGeneration,
if (AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
return;
}
- auto* face = aFacePtr.ToPtr<fontlist::Face>(list);
- if (face) {
+
+ const fontlist::Family* family;
+ if (aAlias) {
+ if (aFamilyIndex >= list->NumAliases()) {
+ MOZ_ASSERT(false, "AliasFamily index out of range");
+ return;
+ }
+ family = list->AliasFamilies() + aFamilyIndex;
+ } else {
+ if (aFamilyIndex >= list->NumFamilies()) {
+ MOZ_ASSERT(false, "Family index out of range");
+ return;
+ }
+ family = list->Families() + aFamilyIndex;
+ }
+
+ if (aFaceIndex >= family->NumFaces()) {
+ MOZ_ASSERT(false, "Face index out of range");
+ return;
+ }
+
+ if (auto* face =
+ family->Faces(list)[aFaceIndex].ToPtr<fontlist::Face>(list)) {
face->mCharacterMap = GetShmemCharMap(&aMap);
}
}
-void gfxPlatformFontList::SetupFamilyCharMap(
- uint32_t aGeneration, const fontlist::Pointer& aFamilyPtr) {
+void gfxPlatformFontList::SetupFamilyCharMap(uint32_t aGeneration,
+ uint32_t aIndex, bool aAlias) {
MOZ_ASSERT(XRE_IsParentProcess());
auto list = SharedFontList();
MOZ_ASSERT(list);
@@ -3049,46 +3071,20 @@ void gfxPlatformFontList::SetupFamilyCharMap(
return;
}
- // aFamilyPtr was passed from a content process which may not be trusted,
- // so we cannot assume it is valid or safe to use. If the Pointer value is
- // bad, we must not crash or do anything bad, just bail out.
- // (In general, if the child process was trying to use an invalid pointer it
- // should have hit the MOZ_DIAGNOSTIC_ASSERT in FontList::ToSharedPointer
- // rather than passing a null or bad pointer to the parent.)
-
- auto* family = aFamilyPtr.ToPtr<fontlist::Family>(list);
- if (!family) {
- // Unable to resolve to a native pointer (or it was null).
- NS_WARNING("unexpected null Family pointer");
- return;
- }
-
- // Validate the pointer before trying to use it: check that it points to a
- // correctly-aligned offset within the Families() or AliasFamilies() array.
- // We just assert (in debug builds only) on failure, and return safely.
- // A misaligned pointer here would indicate a buggy (or compromised) child
- // process, but crashing the parent would be unnecessary and does not yield
- // any useful insight.
- if (family >= list->Families() &&
- family < list->Families() + list->NumFamilies()) {
- size_t offset = (char*)family - (char*)list->Families();
- if (offset % sizeof(fontlist::Family) != 0) {
- MOZ_ASSERT(false, "misaligned Family pointer");
+ if (aAlias) {
+ if (aIndex >= list->NumAliases()) {
+ MOZ_ASSERT(false, "AliasFamily index out of range");
return;
}
- } else if (family >= list->AliasFamilies() &&
- family < list->AliasFamilies() + list->NumAliases()) {
- size_t offset = (char*)family - (char*)list->AliasFamilies();
- if (offset % sizeof(fontlist::Family) != 0) {
- MOZ_ASSERT(false, "misaligned Family pointer");
- return;
- }
- } else {
- MOZ_ASSERT(false, "not a valid Family or AliasFamily pointer");
+ list->AliasFamilies()[aIndex].SetupFamilyCharMap(list);
return;
}
- family->SetupFamilyCharMap(list);
+ if (aIndex >= list->NumFamilies()) {
+ MOZ_ASSERT(false, "Family index out of range");
+ return;
+ }
+ list->Families()[aIndex].SetupFamilyCharMap(list);
}
bool gfxPlatformFontList::InitOtherFamilyNames(uint32_t aGeneration,
diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h
index 930026d8cc..cd17a3b4cd 100644
--- a/gfx/thebes/gfxPlatformFontList.h
+++ b/gfx/thebes/gfxPlatformFontList.h
@@ -357,12 +357,10 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
base::SharedMemoryHandle ShareShmBlockToProcess(uint32_t aIndex,
base::ProcessId aPid);
- void SetCharacterMap(uint32_t aGeneration,
- const mozilla::fontlist::Pointer& aFacePtr,
- const gfxSparseBitSet& aMap);
+ void SetCharacterMap(uint32_t aGeneration, uint32_t aFamilyIndex, bool aAlias,
+ uint32_t aFaceIndex, const gfxSparseBitSet& aMap);
- void SetupFamilyCharMap(uint32_t aGeneration,
- const mozilla::fontlist::Pointer& aFamilyPtr);
+ void SetupFamilyCharMap(uint32_t aGeneration, uint32_t aIndex, bool aAlias);
// Start the async cmap loading process, if not already under way, from the
// given family index. (For use in any process that needs font lookups.)