tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 97881a44751d12ebf8e6fbfdf5dbeb9c70428069
parent 27591d4a8b7f4fba0361733a9458b68f96e5dbcc
Author: Frédéric Wang <fwang@igalia.com>
Date:   Tue,  6 Jan 2026 05:35:35 +0000

Bug 2008530 - Part 1 Statically initialize the MathML unicode table for stretchy operators. r=layout-reviewers,dshin

Differential Revision: https://phabricator.services.mozilla.com/D277859

Diffstat:
Mlayout/mathml/nsMathMLChar.cpp | 157+++++++++++++++----------------------------------------------------------------
1 file changed, 30 insertions(+), 127 deletions(-)

diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp @@ -23,7 +23,6 @@ #include "mozilla/dom/Document.h" #include "mozilla/gfx/2D.h" #include "mozilla/intl/UnicodeScriptCodes.h" -#include "nsCOMPtr.h" #include "nsCSSRendering.h" #include "nsContentUtils.h" #include "nsDeviceContext.h" @@ -97,16 +96,10 @@ class nsGlyphTable { gfxFontGroup* aFontGroup, const nsGlyphCode& aGlyph) = 0; protected: - nsGlyphTable() : mCharCache(0), mFlags(gfx::ShapedTextFlags()) {} - explicit nsGlyphTable(gfx::ShapedTextFlags aFlags) - : mCharCache(0), mFlags(aFlags) {} - // For speedy re-use, we always cache the last data used in the table. // mCharCache is the Unicode point of the last char that was queried in this // table. - char16_t mCharCache; - - gfx::ShapedTextFlags mFlags; + char16_t mCharCache = 0; }; // A Unicode construction is a set of all the stretchy MathML characters that @@ -174,9 +167,7 @@ static const UnicodeConstruction gUnicodeTableConstructions[] = { class nsUnicodeTable final : public nsGlyphTable { public: - nsUnicodeTable() { MOZ_COUNT_CTOR(nsUnicodeTable); } - - MOZ_COUNTED_DTOR(nsUnicodeTable) + constexpr nsUnicodeTable() = default; const nsCString& FontNameFor(const nsGlyphCode& aGlyphCode) const override { MOZ_ASSERT_UNREACHABLE(); @@ -218,6 +209,10 @@ class nsUnicodeTable final : public nsGlyphTable { gfxFontGroup* aFontGroup, const nsGlyphCode& aGlyph) override; private: + // Not available for the heap! + void* operator new(size_t) = delete; + void* operator new[](size_t) = delete; + struct UnicodeConstructionComparator { int operator()(const UnicodeConstruction& aValue) const { if (mTarget < aValue[0]) { @@ -232,9 +227,11 @@ class nsUnicodeTable final : public nsGlyphTable { : mTarget(aTarget) {} const char16_t mTarget; }; - size_t mCachedIndex; + size_t mCachedIndex = 0; }; +static constinit nsUnicodeTable gUnicodeTable; + /* virtual */ nsGlyphCode nsUnicodeTable::ElementAt(DrawTarget* /* aDrawTarget */, int32_t /* aAppUnitsPerDevPixel */, @@ -272,7 +269,7 @@ already_AddRefed<gfxTextRun> nsUnicodeTable::MakeTextRun( NS_ASSERTION(!aGlyph.isGlyphID, "nsUnicodeTable can only access glyphs by code point"); return aFontGroup->MakeTextRun(&aGlyph.code, 1, aDrawTarget, - aAppUnitsPerDevPixel, mFlags, + aAppUnitsPerDevPixel, gfx::ShapedTextFlags(), nsTextFrameUtils::Flags(), nullptr); } @@ -321,12 +318,13 @@ class nsOpenTypeTable final : public nsGlyphTable { RefPtr<gfxFont> mFont; nsCString mFontFamilyName; uint32_t mGlyphID; + gfx::ShapedTextFlags mFlags; nsOpenTypeTable(gfxFont* aFont, gfx::ShapedTextFlags aFlags) - : nsGlyphTable(aFlags), - mFont(aFont), + : mFont(aFont), mFontFamilyName(aFont->GetFontEntry()->FamilyName()), - mGlyphID(0) { + mGlyphID(0), + mFlags(aFlags) { MOZ_COUNT_CTOR(nsOpenTypeTable); } @@ -439,96 +437,6 @@ already_AddRefed<gfxTextRun> nsOpenTypeTable::MakeTextRun( } // ----------------------------------------------------------------------------- -// This is the list of all the applicable glyph tables. -// We will maintain a single global instance that will only reveal those -// glyph tables that are associated to fonts currently installed on the -// user' system. The class is an XPCOM shutdown observer to allow us to -// free its allocated data at shutdown - -class nsGlyphTableList final : public nsIObserver { - public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - - nsUnicodeTable mUnicodeTable; - - nsGlyphTableList() {} - - nsresult Initialize(); - nsresult Finalize(); - - private: - ~nsGlyphTableList() = default; -}; - -NS_IMPL_ISUPPORTS(nsGlyphTableList, nsIObserver) - -// ----------------------------------------------------------------------------- -// Here is the global list of applicable glyph tables that we will be using -static nsGlyphTableList* gGlyphTableList = nullptr; - -static bool gGlyphTableInitialized = false; - -// XPCOM shutdown observer -NS_IMETHODIMP -nsGlyphTableList::Observe(nsISupports* aSubject, const char* aTopic, - const char16_t* someData) { - Finalize(); - return NS_OK; -} - -// Add an observer to XPCOM shutdown so that we can free our data at shutdown -nsresult nsGlyphTableList::Initialize() { - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); - if (!obs) { - return NS_ERROR_FAILURE; - } - - nsresult rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -// Remove our observer and free the memory that were allocated for us -nsresult nsGlyphTableList::Finalize() { - // Remove our observer from the observer service - nsresult rv = NS_OK; - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); - if (obs) { - rv = obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); - } else { - rv = NS_ERROR_FAILURE; - } - - gGlyphTableInitialized = false; - // our oneself will be destroyed when our |Release| is called by the observer - NS_IF_RELEASE(gGlyphTableList); - return rv; -} - -// ----------------------------------------------------------------------------- - -static nsresult InitCharGlobals() { - NS_ASSERTION(!gGlyphTableInitialized, "Error -- already initialized"); - gGlyphTableInitialized = true; - - // Allocate the placeholders for the preferred parts and variants - nsresult rv = NS_ERROR_OUT_OF_MEMORY; - auto glyphTableList = MakeRefPtr<nsGlyphTableList>(); - if (glyphTableList) { - rv = glyphTableList->Initialize(); - } - if (NS_FAILED(rv)) { - return rv; - } - // The gGlyphTableList has been successfully registered as a shutdown - // observer and will be deleted at shutdown. - glyphTableList.forget(&gGlyphTableList); - return rv; -} - -// ----------------------------------------------------------------------------- // And now the implementation of nsMathMLChar nsMathMLChar::~nsMathMLChar() { MOZ_COUNT_DTOR(nsMathMLChar); } @@ -544,16 +452,13 @@ void nsMathMLChar::SetComputedStyle(ComputedStyle* aComputedStyle) { } void nsMathMLChar::SetData(nsString& aData) { - if (!gGlyphTableInitialized) { - InitCharGlobals(); - } mData = aData; // some assumptions until proven otherwise // note that mGlyph is not initialized mDirection = NS_STRETCH_DIRECTION_UNSUPPORTED; mBoundingMetrics = nsBoundingMetrics(); // check if stretching is applicable ... - if (gGlyphTableList && (1 == mData.Length())) { + if (1 == mData.Length()) { mDirection = nsMathMLOperators::GetStretchyDirection(mData); // default tentative table (not the one that is necessarily going // to be used) @@ -758,7 +663,7 @@ bool nsMathMLChar::SetFontFamily(nsPresContext* aPresContext, // Set the font if it is an unicode table or if the same family name has // been found. const bool shouldSetFont = [&] { - if (aGlyphTable == &gGlyphTableList->mUnicodeTable) { + if (aGlyphTable == &gUnicodeTable) { return true; } @@ -1034,7 +939,7 @@ bool nsMathMLChar::StretchEnumContext::TryParts( // For the Unicode table, we check that all the glyphs are actually found and // come from the same font. - if (aGlyphTable == &gGlyphTableList->mUnicodeTable) { + if (aGlyphTable == &gUnicodeTable) { gfxFont* unicodeFont = nullptr; for (int32_t i = 0; i < 4; i++) { if (!textRun[i]) { @@ -1189,20 +1094,19 @@ bool nsMathMLChar::StretchEnumContext::EnumCallback( // Determine the glyph table to use for this font. UniquePtr<nsOpenTypeTable> openTypeTable; - nsGlyphTable* glyphTable; - if (aFamily.IsGeneric()) { - // This is a generic font, use the Unicode table. - glyphTable = &gGlyphTableList->mUnicodeTable; - } else { - // If the font contains an Open Type MATH table, use it. - RefPtr<gfxFont> font = fontGroup->GetFirstValidFont(); - openTypeTable = nsOpenTypeTable::Create(font, aFlags); - if (openTypeTable) { - glyphTable = openTypeTable.get(); - } else { - glyphTable = &gGlyphTableList->mUnicodeTable; + auto glyphTable = [&aFamily, &fontGroup, &openTypeTable, + &aFlags]() -> nsGlyphTable* { + if (!aFamily.IsGeneric()) { + // If the font contains an Open Type MATH table, use it. + RefPtr<gfxFont> font = fontGroup->GetFirstValidFont(); + openTypeTable = nsOpenTypeTable::Create(font, aFlags); + if (openTypeTable) { + return openTypeTable.get(); + } } - } + // Fallback to the Unicode table. + return &gUnicodeTable; + }(); if (!openTypeTable) { // Make sure we only try the UnicodeTable once. @@ -1216,8 +1120,7 @@ bool nsMathMLChar::StretchEnumContext::EnumCallback( // special table is being used then the font in this family should have the // specified glyphs. const StyleFontFamilyList& familyList = - glyphTable == &gGlyphTableList->mUnicodeTable ? context->mFamilyList - : family; + glyphTable == &gUnicodeTable ? context->mFamilyList : family; return (context->mTryVariants && context->TryVariants(glyphTable, &fontGroup, familyList, aRtl)) ||