зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1674340 - Separate out language from gfxFontStyle and pass it separately to shaping processes that need it. r=lsalzman
This allows us to avoid instantiating separate gfxFont objects when content is tagged with different 'lang' attributes, yet ends up using the same fonts (e.g. Wikipedia may use a default font such as Arial for language names/links that are tagged with several dozen different languages). Differential Revision: https://phabricator.services.mozilla.com/D96978
This commit is contained in:
Родитель
8e1dfa2a73
Коммит
16eb1dba68
|
@ -3997,6 +3997,9 @@ gfxFontGroup* CanvasRenderingContext2D::GetCurrentFontStyle() {
|
|||
bool fontUpdated = SetFontInternal(kDefaultFontStyle, err);
|
||||
if (err.Failed() || !fontUpdated) {
|
||||
err.SuppressException();
|
||||
// XXX Should we get a default lang from the prescontext or something?
|
||||
nsAtom* language = nsGkAtoms::x_western;
|
||||
bool explicitLanguage = false;
|
||||
gfxFontStyle style;
|
||||
style.size = kDefaultFontSize;
|
||||
gfxTextPerfMetrics* tp = nullptr;
|
||||
|
@ -4009,8 +4012,8 @@ gfxFontGroup* CanvasRenderingContext2D::GetCurrentFontStyle() {
|
|||
GetAppUnitsValues(&perDevPixel, &perCSSPixel);
|
||||
gfxFloat devToCssSize = gfxFloat(perDevPixel) / gfxFloat(perCSSPixel);
|
||||
CurrentState().fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(
|
||||
FontFamilyList(StyleGenericFontFamily::SansSerif), &style, tp,
|
||||
fontStats, nullptr, devToCssSize);
|
||||
FontFamilyList(StyleGenericFontFamily::SansSerif), &style, language,
|
||||
explicitLanguage, tp, fontStats, nullptr, devToCssSize);
|
||||
if (CurrentState().fontGroup) {
|
||||
CurrentState().font = kDefaultFontStyle;
|
||||
} else {
|
||||
|
|
|
@ -149,7 +149,8 @@ already_AddRefed<nsFontMetrics> nsFontCache::GetMetricsFor(
|
|||
if (fm->Font().Equals(aFont) &&
|
||||
fm->GetUserFontSet() == aParams.userFontSet &&
|
||||
fm->Language() == language &&
|
||||
fm->Orientation() == aParams.orientation) {
|
||||
fm->Orientation() == aParams.orientation &&
|
||||
fm->ExplicitLanguage() == aParams.explicitLanguage) {
|
||||
if (i != n) {
|
||||
// promote it to the end of the cache
|
||||
mFontMetrics.RemoveElementAt(i);
|
||||
|
|
|
@ -114,12 +114,12 @@ nsFontMetrics::nsFontMetrics(const nsFont& aFont, const Params& aParams,
|
|||
mDeviceContext(aContext),
|
||||
mP2A(aContext->AppUnitsPerDevPixel()),
|
||||
mOrientation(aParams.orientation),
|
||||
mExplicitLanguage(aParams.explicitLanguage),
|
||||
mTextRunRTL(false),
|
||||
mVertical(false),
|
||||
mTextOrientation(mozilla::StyleTextOrientation::Mixed) {
|
||||
gfxFontStyle style(aFont.style, aFont.weight, aFont.stretch,
|
||||
gfxFloat(aFont.size.ToAppUnits()) / mP2A, aParams.language,
|
||||
aParams.explicitLanguage, aFont.sizeAdjust,
|
||||
gfxFloat(aFont.size.ToAppUnits()) / mP2A, aFont.sizeAdjust,
|
||||
aFont.systemFont, mDeviceContext->IsPrinterContext(),
|
||||
aFont.synthesis & NS_FONT_SYNTHESIS_WEIGHT,
|
||||
aFont.synthesis & NS_FONT_SYNTHESIS_STYLE,
|
||||
|
@ -132,8 +132,8 @@ nsFontMetrics::nsFontMetrics(const nsFont& aFont, const Params& aParams,
|
|||
|
||||
gfxFloat devToCssSize = gfxFloat(mP2A) / gfxFloat(AppUnitsPerCSSPixel());
|
||||
mFontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(
|
||||
aFont.fontlist, &style, aParams.textPerf, aParams.fontStats,
|
||||
aParams.userFontSet, devToCssSize);
|
||||
aFont.fontlist, &style, mLanguage, mExplicitLanguage, aParams.textPerf,
|
||||
aParams.fontStats, aParams.userFontSet, devToCssSize);
|
||||
}
|
||||
|
||||
nsFontMetrics::~nsFontMetrics() {
|
||||
|
|
|
@ -235,6 +235,8 @@ class nsFontMetrics final {
|
|||
return mTextOrientation;
|
||||
}
|
||||
|
||||
bool ExplicitLanguage() const { return mExplicitLanguage; }
|
||||
|
||||
gfxFontGroup* GetThebesFontGroup() const { return mFontGroup; }
|
||||
gfxUserFontSet* GetUserFontSet() const;
|
||||
|
||||
|
@ -257,6 +259,11 @@ class nsFontMetrics final {
|
|||
// descent) they will return.
|
||||
FontOrientation mOrientation;
|
||||
|
||||
// Whether mLanguage comes from explicit markup (in which case it should be
|
||||
// used to tailor effects like case-conversion) or is an inferred/default
|
||||
// value.
|
||||
bool mExplicitLanguage;
|
||||
|
||||
// These fields may be set by clients to control the behavior of methods
|
||||
// like GetWidth and DrawString according to the writing mode, direction
|
||||
// and text-orientation desired.
|
||||
|
|
|
@ -78,7 +78,8 @@ static bool IsBuggyIndicScript(unicode::Script aScript) {
|
|||
bool gfxCoreTextShaper::ShapeText(DrawTarget* aDrawTarget,
|
||||
const char16_t* aText, uint32_t aOffset,
|
||||
uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
// Create a CFAttributedString with text and style info, so we can use
|
||||
// CoreText to lay it out.
|
||||
|
|
|
@ -19,7 +19,7 @@ class gfxCoreTextShaper : public gfxFontShaper {
|
|||
virtual ~gfxCoreTextShaper();
|
||||
|
||||
bool ShapeText(DrawTarget* aDrawTarget, const char16_t* aText, uint32_t aOffset, uint32_t aLength,
|
||||
Script aScript, bool aVertical, RoundingFlags aRounding,
|
||||
Script aScript, nsAtom* aLanguage, bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) override;
|
||||
|
||||
// clean up static objects that may have been cached
|
||||
|
|
|
@ -873,7 +873,7 @@ gfxDWriteFontList::gfxDWriteFontList() : mForceGDIClassicMaxFontSize(0.0) {
|
|||
// Arial to avoid this.
|
||||
|
||||
FontFamily gfxDWriteFontList::GetDefaultFontForPlatform(
|
||||
const gfxFontStyle* aStyle) {
|
||||
const gfxFontStyle* aStyle, nsAtom* aLanguage) {
|
||||
// try Arial first
|
||||
FontFamily ff;
|
||||
ff = FindFamily("Arial"_ns);
|
||||
|
@ -1870,12 +1870,10 @@ void gfxDWriteFontList::GetDirectWriteSubstitutes() {
|
|||
}
|
||||
}
|
||||
|
||||
bool gfxDWriteFontList::FindAndAddFamilies(StyleGenericFontFamily aGeneric,
|
||||
const nsACString& aFamily,
|
||||
nsTArray<FamilyAndGeneric>* aOutput,
|
||||
FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle,
|
||||
gfxFloat aDevToCssSize) {
|
||||
bool gfxDWriteFontList::FindAndAddFamilies(
|
||||
StyleGenericFontFamily aGeneric, const nsACString& aFamily,
|
||||
nsTArray<FamilyAndGeneric>* aOutput, FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle, nsAtom* aLanguage, gfxFloat aDevToCssSize) {
|
||||
nsAutoCString keyName(aFamily);
|
||||
BuildKeyNameFromFontName(keyName);
|
||||
|
||||
|
@ -1896,8 +1894,8 @@ bool gfxDWriteFontList::FindAndAddFamilies(StyleGenericFontFamily aGeneric,
|
|||
return false;
|
||||
}
|
||||
|
||||
return gfxPlatformFontList::FindAndAddFamilies(aGeneric, keyName, aOutput,
|
||||
aFlags, aStyle, aDevToCssSize);
|
||||
return gfxPlatformFontList::FindAndAddFamilies(
|
||||
aGeneric, keyName, aOutput, aFlags, aStyle, aLanguage, aDevToCssSize);
|
||||
}
|
||||
|
||||
void gfxDWriteFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
|
||||
|
|
|
@ -413,6 +413,7 @@ class gfxDWriteFontList final : public gfxPlatformFontList {
|
|||
nsTArray<FamilyAndGeneric>* aOutput,
|
||||
FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
nsAtom* aLanguage = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) override;
|
||||
|
||||
gfxFloat GetForceGDIClassicMaxFontSize() {
|
||||
|
@ -425,7 +426,8 @@ class gfxDWriteFontList final : public gfxPlatformFontList {
|
|||
FontListSizes* aSizes) const;
|
||||
|
||||
protected:
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle,
|
||||
nsAtom* aLanguage = nullptr) override;
|
||||
|
||||
// attempt to use platform-specific fallback for the given character,
|
||||
// return null if no usable result found
|
||||
|
|
|
@ -1737,8 +1737,8 @@ searchDone:
|
|||
return fe;
|
||||
}
|
||||
|
||||
FontFamily gfxFT2FontList::GetDefaultFontForPlatform(
|
||||
const gfxFontStyle* aStyle) {
|
||||
FontFamily gfxFT2FontList::GetDefaultFontForPlatform(const gfxFontStyle* aStyle,
|
||||
nsAtom* aLanguage) {
|
||||
FontFamily ff;
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
ff = FindFamily("Roboto"_ns);
|
||||
|
|
|
@ -214,7 +214,8 @@ class gfxFT2FontList final : public gfxPlatformFontList {
|
|||
|
||||
void FindFontsInDir(const nsCString& aDir, FontNameCache* aFNC);
|
||||
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle,
|
||||
nsAtom* aLanguage = nullptr) override;
|
||||
|
||||
nsTHashtable<nsCStringHashKey> mSkipSpaceLookupCheckFamilies;
|
||||
|
||||
|
|
|
@ -42,10 +42,11 @@ using namespace mozilla::gfx;
|
|||
|
||||
bool gfxFT2Font::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
if (!gfxFont::ShapeText(aDrawTarget, aText, aOffset, aLength, aScript,
|
||||
aVertical, aRounding, aShapedText)) {
|
||||
aLanguage, aVertical, aRounding, aShapedText)) {
|
||||
// harfbuzz must have failed(?!), just render raw glyphs
|
||||
AddRange(aText, aOffset, aLength, aShapedText);
|
||||
PostShapingFixup(aDrawTarget, aText, aOffset, aLength, aVertical,
|
||||
|
|
|
@ -63,7 +63,7 @@ class gfxFT2Font : public gfxFT2FontBase {
|
|||
|
||||
bool ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) override;
|
||||
|
||||
void FillGlyphDataForChar(FT_Face face, uint32_t ch, CachedGlyphData* gd);
|
||||
|
|
|
@ -1856,11 +1856,11 @@ void gfxFcPlatformFontList::GetFontList(nsAtom* aLangGroup,
|
|||
}
|
||||
|
||||
FontFamily gfxFcPlatformFontList::GetDefaultFontForPlatform(
|
||||
const gfxFontStyle* aStyle) {
|
||||
const gfxFontStyle* aStyle, nsAtom* aLanguage) {
|
||||
// Get the default font by using a fake name to retrieve the first
|
||||
// scalable font that fontconfig suggests for the given language.
|
||||
PrefFontList* prefFonts =
|
||||
FindGenericFamilies("-moz-default"_ns, aStyle->language);
|
||||
PrefFontList* prefFonts = FindGenericFamilies(
|
||||
"-moz-default"_ns, aLanguage ? aLanguage : nsGkAtoms::x_western);
|
||||
NS_ASSERTION(prefFonts, "null list of generic fonts");
|
||||
if (prefFonts && !prefFonts->IsEmpty()) {
|
||||
return (*prefFonts)[0];
|
||||
|
@ -1906,10 +1906,9 @@ gfxFontEntry* gfxFcPlatformFontList::MakePlatformFont(
|
|||
bool gfxFcPlatformFontList::FindAndAddFamilies(
|
||||
StyleGenericFontFamily aGeneric, const nsACString& aFamily,
|
||||
nsTArray<FamilyAndGeneric>* aOutput, FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle, gfxFloat aDevToCssSize) {
|
||||
gfxFontStyle* aStyle, nsAtom* aLanguage, gfxFloat aDevToCssSize) {
|
||||
nsAutoCString familyName(aFamily);
|
||||
ToLowerCase(familyName);
|
||||
nsAtom* language = (aStyle ? aStyle->language.get() : nullptr);
|
||||
|
||||
if (!(aFlags & FindFamiliesFlags::eQuotedFamilyName)) {
|
||||
// deprecated generic names are explicitly converted to standard generics
|
||||
|
@ -1926,7 +1925,7 @@ bool gfxFcPlatformFontList::FindAndAddFamilies(
|
|||
// fontconfig generics? use fontconfig to determine the family for lang
|
||||
if (isDeprecatedGeneric ||
|
||||
mozilla::FontFamilyName::Convert(familyName).IsGeneric()) {
|
||||
PrefFontList* prefFonts = FindGenericFamilies(familyName, language);
|
||||
PrefFontList* prefFonts = FindGenericFamilies(familyName, aLanguage);
|
||||
if (prefFonts && !prefFonts->IsEmpty()) {
|
||||
aOutput->AppendElements(*prefFonts);
|
||||
return true;
|
||||
|
@ -1986,7 +1985,7 @@ bool gfxFcPlatformFontList::FindAndAddFamilies(
|
|||
}
|
||||
gfxPlatformFontList::FindAndAddFamilies(
|
||||
aGeneric, nsDependentCString(ToCharPtr(substName)), &cachedFamilies,
|
||||
aFlags);
|
||||
aFlags, aStyle, aLanguage);
|
||||
}
|
||||
|
||||
// Cache the resulting list, so we don't have to do this again.
|
||||
|
|
|
@ -266,6 +266,7 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList {
|
|||
nsTArray<FamilyAndGeneric>* aOutput,
|
||||
FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
nsAtom* aLanguage = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) override;
|
||||
|
||||
bool GetStandardFamilyName(const nsCString& aFontName,
|
||||
|
@ -320,7 +321,8 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList {
|
|||
|
||||
static void CheckFontUpdates(nsITimer* aTimer, void* aThis);
|
||||
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle,
|
||||
nsAtom* aLanguage = nullptr) override;
|
||||
|
||||
enum class DistroID : int8_t {
|
||||
Unknown = 0,
|
||||
|
|
|
@ -2732,9 +2732,9 @@ static char16_t IsBoundarySpace(char16_t aChar, char16_t aNextChar) {
|
|||
template <typename T>
|
||||
gfxShapedWord* gfxFont::GetShapedWord(
|
||||
DrawTarget* aDrawTarget, const T* aText, uint32_t aLength, uint32_t aHash,
|
||||
Script aRunScript, bool aVertical, int32_t aAppUnitsPerDevUnit,
|
||||
gfx::ShapedTextFlags aFlags, RoundingFlags aRounding,
|
||||
gfxTextPerfMetrics* aTextPerf GFX_MAYBE_UNUSED) {
|
||||
Script aRunScript, nsAtom* aLanguage, bool aVertical,
|
||||
int32_t aAppUnitsPerDevUnit, gfx::ShapedTextFlags aFlags,
|
||||
RoundingFlags aRounding, gfxTextPerfMetrics* aTextPerf GFX_MAYBE_UNUSED) {
|
||||
// if the cache is getting too big, flush it and start over
|
||||
uint32_t wordCacheMaxEntries =
|
||||
gfxPlatform::GetPlatform()->WordCacheMaxEntries();
|
||||
|
@ -2744,8 +2744,8 @@ gfxShapedWord* gfxFont::GetShapedWord(
|
|||
}
|
||||
|
||||
// if there's a cached entry for this word, just return it
|
||||
CacheHashKey key(aText, aLength, aHash, aRunScript, aAppUnitsPerDevUnit,
|
||||
aFlags, aRounding);
|
||||
CacheHashKey key(aText, aLength, aHash, aRunScript, aLanguage,
|
||||
aAppUnitsPerDevUnit, aFlags, aRounding);
|
||||
|
||||
CacheHashEntry* entry = mWordCache->PutEntry(key, fallible);
|
||||
if (!entry) {
|
||||
|
@ -2770,8 +2770,8 @@ gfxShapedWord* gfxFont::GetShapedWord(
|
|||
}
|
||||
#endif
|
||||
|
||||
sw = gfxShapedWord::Create(aText, aLength, aRunScript, aAppUnitsPerDevUnit,
|
||||
aFlags, aRounding);
|
||||
sw = gfxShapedWord::Create(aText, aLength, aRunScript, aLanguage,
|
||||
aAppUnitsPerDevUnit, aFlags, aRounding);
|
||||
entry->mShapedWord.reset(sw);
|
||||
if (!sw) {
|
||||
NS_WARNING("failed to create gfxShapedWord - expect missing text");
|
||||
|
@ -2779,7 +2779,7 @@ gfxShapedWord* gfxFont::GetShapedWord(
|
|||
}
|
||||
|
||||
DebugOnly<bool> ok = ShapeText(aDrawTarget, aText, 0, aLength, aRunScript,
|
||||
aVertical, aRounding, sw);
|
||||
aLanguage, aVertical, aRounding, sw);
|
||||
|
||||
NS_WARNING_ASSERTION(ok, "failed to shape word - expect garbled text");
|
||||
|
||||
|
@ -2788,7 +2788,7 @@ gfxShapedWord* gfxFont::GetShapedWord(
|
|||
|
||||
template gfxShapedWord* gfxFont::GetShapedWord(
|
||||
DrawTarget* aDrawTarget, const uint8_t* aText, uint32_t aLength,
|
||||
uint32_t aHash, Script aRunScript, bool aVertical,
|
||||
uint32_t aHash, Script aRunScript, nsAtom* aLanguage, bool aVertical,
|
||||
int32_t aAppUnitsPerDevUnit, gfx::ShapedTextFlags aFlags,
|
||||
RoundingFlags aRounding, gfxTextPerfMetrics* aTextPerf);
|
||||
|
||||
|
@ -2800,7 +2800,8 @@ bool gfxFont::CacheHashEntry::KeyEquals(const KeyTypePointer aKey) const {
|
|||
if (sw->GetLength() != aKey->mLength || sw->GetFlags() != aKey->mFlags ||
|
||||
sw->GetRounding() != aKey->mRounding ||
|
||||
sw->GetAppUnitsPerDevUnit() != aKey->mAppUnitsPerDevUnit ||
|
||||
sw->GetScript() != aKey->mScript) {
|
||||
sw->GetScript() != aKey->mScript ||
|
||||
sw->GetLanguage() != aKey->mLanguage) {
|
||||
return false;
|
||||
}
|
||||
if (sw->TextIs8Bit()) {
|
||||
|
@ -2830,8 +2831,8 @@ bool gfxFont::CacheHashEntry::KeyEquals(const KeyTypePointer aKey) const {
|
|||
|
||||
bool gfxFont::ShapeText(DrawTarget* aDrawTarget, const uint8_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding, gfxShapedText* aShapedText) {
|
||||
nsDependentCSubstring ascii((const char*)aText, aLength);
|
||||
nsAutoString utf16;
|
||||
AppendASCIItoUTF16(ascii, utf16);
|
||||
|
@ -2839,13 +2840,13 @@ bool gfxFont::ShapeText(DrawTarget* aDrawTarget, const uint8_t* aText,
|
|||
return false;
|
||||
}
|
||||
return ShapeText(aDrawTarget, utf16.BeginReading(), aOffset, aLength, aScript,
|
||||
aVertical, aRounding, aShapedText);
|
||||
aLanguage, aVertical, aRounding, aShapedText);
|
||||
}
|
||||
|
||||
bool gfxFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding, gfxShapedText* aShapedText) {
|
||||
// XXX Currently, we do all vertical shaping through harfbuzz.
|
||||
// Vertical graphite support may be wanted as a future enhancement.
|
||||
if (FontCanSupportGraphite() && !aVertical) {
|
||||
|
@ -2855,7 +2856,7 @@ bool gfxFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
|||
Telemetry::ScalarAdd(Telemetry::ScalarID::BROWSER_USAGE_GRAPHITE, 1);
|
||||
}
|
||||
if (mGraphiteShaper->ShapeText(aDrawTarget, aText, aOffset, aLength,
|
||||
aScript, aVertical, aRounding,
|
||||
aScript, aLanguage, aVertical, aRounding,
|
||||
aShapedText)) {
|
||||
PostShapingFixup(aDrawTarget, aText, aOffset, aLength, aVertical,
|
||||
aShapedText);
|
||||
|
@ -2868,7 +2869,8 @@ bool gfxFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
|||
mHarfBuzzShaper = MakeUnique<gfxHarfBuzzShaper>(this);
|
||||
}
|
||||
if (mHarfBuzzShaper->ShapeText(aDrawTarget, aText, aOffset, aLength, aScript,
|
||||
aVertical, aRounding, aShapedText)) {
|
||||
aLanguage, aVertical, aRounding,
|
||||
aShapedText)) {
|
||||
PostShapingFixup(aDrawTarget, aText, aOffset, aLength, aVertical,
|
||||
aShapedText);
|
||||
if (GetFontEntry()->HasTrackingTable()) {
|
||||
|
@ -2917,7 +2919,7 @@ template <typename T>
|
|||
bool gfxFont::ShapeFragmentWithoutWordCache(DrawTarget* aDrawTarget,
|
||||
const T* aText, uint32_t aOffset,
|
||||
uint32_t aLength, Script aScript,
|
||||
bool aVertical,
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
gfxTextRun* aTextRun) {
|
||||
aTextRun->SetupClusterBoundaries(aOffset, aText, aLength);
|
||||
|
@ -2952,8 +2954,8 @@ bool gfxFont::ShapeFragmentWithoutWordCache(DrawTarget* aDrawTarget,
|
|||
}
|
||||
}
|
||||
|
||||
ok = ShapeText(aDrawTarget, aText, aOffset, fragLen, aScript, aVertical,
|
||||
aRounding, aTextRun);
|
||||
ok = ShapeText(aDrawTarget, aText, aOffset, fragLen, aScript, aLanguage,
|
||||
aVertical, aRounding, aTextRun);
|
||||
|
||||
aText += fragLen;
|
||||
aOffset += fragLen;
|
||||
|
@ -2975,8 +2977,8 @@ static bool IsInvalidControlChar(uint32_t aCh) {
|
|||
template <typename T>
|
||||
bool gfxFont::ShapeTextWithoutWordCache(DrawTarget* aDrawTarget, const T* aText,
|
||||
uint32_t aOffset, uint32_t aLength,
|
||||
Script aScript, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
Script aScript, nsAtom* aLanguage,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxTextRun* aTextRun) {
|
||||
uint32_t fragStart = 0;
|
||||
bool ok = true;
|
||||
|
@ -2992,9 +2994,9 @@ bool gfxFont::ShapeTextWithoutWordCache(DrawTarget* aDrawTarget, const T* aText,
|
|||
}
|
||||
|
||||
if (length > 0) {
|
||||
ok = ShapeFragmentWithoutWordCache(aDrawTarget, aText + fragStart,
|
||||
aOffset + fragStart, length, aScript,
|
||||
aVertical, aRounding, aTextRun);
|
||||
ok = ShapeFragmentWithoutWordCache(
|
||||
aDrawTarget, aText + fragStart, aOffset + fragStart, length, aScript,
|
||||
aLanguage, aVertical, aRounding, aTextRun);
|
||||
}
|
||||
|
||||
if (i == aLength) {
|
||||
|
@ -3015,7 +3017,8 @@ bool gfxFont::ShapeTextWithoutWordCache(DrawTarget* aDrawTarget, const T* aText,
|
|||
gfx::ShapedTextFlags::TEXT_HIDE_CONTROL_CHARACTERS)) {
|
||||
if (GetFontEntry()->IsUserFont() && HasCharacter(ch)) {
|
||||
ShapeFragmentWithoutWordCache(aDrawTarget, aText + i, aOffset + i, 1,
|
||||
aScript, aVertical, aRounding, aTextRun);
|
||||
aScript, aLanguage, aVertical, aRounding,
|
||||
aTextRun);
|
||||
} else {
|
||||
aTextRun->SetMissingGlyph(aOffset + i, ch, this);
|
||||
}
|
||||
|
@ -3054,7 +3057,8 @@ bool gfxFont::SplitAndInitTextRun(
|
|||
DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
|
||||
const T* aString, // text for this font run
|
||||
uint32_t aRunStart, // position in the textrun
|
||||
uint32_t aRunLength, Script aRunScript, ShapedTextFlags aOrientation) {
|
||||
uint32_t aRunLength, Script aRunScript, nsAtom* aLanguage,
|
||||
ShapedTextFlags aOrientation) {
|
||||
if (aRunLength == 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -3099,8 +3103,8 @@ bool gfxFont::SplitAndInitTextRun(
|
|||
if (aRunLength > wordCacheCharLimit || HasSpaces(aString, aRunLength)) {
|
||||
TEXT_PERF_INCR(tp, wordCacheSpaceRules);
|
||||
return ShapeTextWithoutWordCache(aDrawTarget, aString, aRunStart,
|
||||
aRunLength, aRunScript, vertical,
|
||||
rounding, aTextRun);
|
||||
aRunLength, aRunScript, aLanguage,
|
||||
vertical, rounding, aTextRun);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3149,7 +3153,7 @@ bool gfxFont::SplitAndInitTextRun(
|
|||
TEXT_PERF_INCR(tp, wordCacheLong);
|
||||
bool ok = ShapeFragmentWithoutWordCache(
|
||||
aDrawTarget, aString + wordStart, aRunStart + wordStart, length,
|
||||
aRunScript, vertical, rounding, aTextRun);
|
||||
aRunScript, aLanguage, vertical, rounding, aTextRun);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3164,8 +3168,8 @@ bool gfxFont::SplitAndInitTextRun(
|
|||
}
|
||||
}
|
||||
gfxShapedWord* sw = GetShapedWord(
|
||||
aDrawTarget, aString + wordStart, length, hash, aRunScript, vertical,
|
||||
appUnitsPerDevUnit, wordFlags, rounding, tp);
|
||||
aDrawTarget, aString + wordStart, length, hash, aRunScript, aLanguage,
|
||||
vertical, appUnitsPerDevUnit, wordFlags, rounding, tp);
|
||||
if (sw) {
|
||||
aTextRun->CopyGlyphDataFrom(sw, aRunStart + wordStart);
|
||||
} else {
|
||||
|
@ -3188,7 +3192,7 @@ bool gfxFont::SplitAndInitTextRun(
|
|||
NS_ASSERTION(boundary16 < 256, "unexpected boundary!");
|
||||
gfxShapedWord* sw = GetShapedWord(
|
||||
aDrawTarget, &boundary, 1, gfxShapedWord::HashMix(0, boundary),
|
||||
aRunScript, vertical, appUnitsPerDevUnit,
|
||||
aRunScript, aLanguage, vertical, appUnitsPerDevUnit,
|
||||
flags | gfx::ShapedTextFlags::TEXT_IS_8BIT, rounding, tp);
|
||||
if (sw) {
|
||||
aTextRun->CopyGlyphDataFrom(sw, aRunStart + i);
|
||||
|
@ -3225,8 +3229,8 @@ bool gfxFont::SplitAndInitTextRun(
|
|||
gfx::ShapedTextFlags::TEXT_HIDE_CONTROL_CHARACTERS)) {
|
||||
if (GetFontEntry()->IsUserFont() && HasCharacter(ch)) {
|
||||
ShapeFragmentWithoutWordCache(aDrawTarget, aString + i, aRunStart + i,
|
||||
1, aRunScript, vertical, rounding,
|
||||
aTextRun);
|
||||
1, aRunScript, aLanguage, vertical,
|
||||
rounding, aTextRun);
|
||||
} else {
|
||||
aTextRun->SetMissingGlyph(aRunStart + i, ch, this);
|
||||
}
|
||||
|
@ -3244,11 +3248,11 @@ bool gfxFont::SplitAndInitTextRun(
|
|||
template bool gfxFont::SplitAndInitTextRun(
|
||||
DrawTarget* aDrawTarget, gfxTextRun* aTextRun, const uint8_t* aString,
|
||||
uint32_t aRunStart, uint32_t aRunLength, Script aRunScript,
|
||||
ShapedTextFlags aOrientation);
|
||||
nsAtom* aLanguage, ShapedTextFlags aOrientation);
|
||||
template bool gfxFont::SplitAndInitTextRun(
|
||||
DrawTarget* aDrawTarget, gfxTextRun* aTextRun, const char16_t* aString,
|
||||
uint32_t aRunStart, uint32_t aRunLength, Script aRunScript,
|
||||
ShapedTextFlags aOrientation);
|
||||
nsAtom* aLanguage, ShapedTextFlags aOrientation);
|
||||
|
||||
template <>
|
||||
bool gfxFont::InitFakeSmallCapsRun(DrawTarget* aDrawTarget,
|
||||
|
@ -3256,8 +3260,8 @@ bool gfxFont::InitFakeSmallCapsRun(DrawTarget* aDrawTarget,
|
|||
uint32_t aOffset, uint32_t aLength,
|
||||
FontMatchType aMatchType,
|
||||
gfx::ShapedTextFlags aOrientation,
|
||||
Script aScript, bool aSyntheticLower,
|
||||
bool aSyntheticUpper) {
|
||||
Script aScript, nsAtom* aLanguage,
|
||||
bool aSyntheticLower, bool aSyntheticUpper) {
|
||||
bool ok = true;
|
||||
|
||||
RefPtr<gfxFont> smallCapsFont = GetSmallCapsFont();
|
||||
|
@ -3297,7 +3301,7 @@ bool gfxFont::InitFakeSmallCapsRun(DrawTarget* aDrawTarget,
|
|||
} else if (ch != ToLowerCase(ch)) {
|
||||
// ch is upper case
|
||||
chAction = (aSyntheticUpper ? kUppercaseReduce : kNoChange);
|
||||
if (mStyle.explicitLanguage && mStyle.language == nsGkAtoms::el) {
|
||||
if (aLanguage == nsGkAtoms::el) {
|
||||
// In Greek, check for characters that will be modified by
|
||||
// the GreekUpperCase mapping - this catches accented
|
||||
// capitals where the accent is to be removed (bug 307039).
|
||||
|
@ -3330,7 +3334,7 @@ bool gfxFont::InitFakeSmallCapsRun(DrawTarget* aDrawTarget,
|
|||
aOrientation, isCJK);
|
||||
if (!f->SplitAndInitTextRun(aDrawTarget, aTextRun, aText + runStart,
|
||||
aOffset + runStart, runLength, aScript,
|
||||
aOrientation)) {
|
||||
aLanguage, aOrientation)) {
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
|
@ -3349,9 +3353,8 @@ bool gfxFont::InitFakeSmallCapsRun(DrawTarget* aDrawTarget,
|
|||
|
||||
bool mergeNeeded = nsCaseTransformTextRunFactory::TransformString(
|
||||
origString, convertedString, /* aAllUppercase = */ true,
|
||||
/* aCaseTransformsOnly = */ false,
|
||||
mStyle.explicitLanguage ? mStyle.language.get() : nullptr,
|
||||
charsToMergeArray, deletedCharsArray);
|
||||
/* aCaseTransformsOnly = */ false, aLanguage, charsToMergeArray,
|
||||
deletedCharsArray);
|
||||
|
||||
if (mergeNeeded) {
|
||||
// This is the hard case: the transformation caused chars
|
||||
|
@ -3365,9 +3368,10 @@ bool gfxFont::InitFakeSmallCapsRun(DrawTarget* aDrawTarget,
|
|||
¶ms, convertedString.Length(), aTextRun->GetFontGroup(),
|
||||
gfx::ShapedTextFlags(), nsTextFrameUtils::Flags()));
|
||||
tempRun->AddGlyphRun(f, aMatchType, 0, true, aOrientation, isCJK);
|
||||
if (!f->SplitAndInitTextRun(
|
||||
aDrawTarget, tempRun.get(), convertedString.BeginReading(),
|
||||
0, convertedString.Length(), aScript, aOrientation)) {
|
||||
if (!f->SplitAndInitTextRun(aDrawTarget, tempRun.get(),
|
||||
convertedString.BeginReading(), 0,
|
||||
convertedString.Length(), aScript,
|
||||
aLanguage, aOrientation)) {
|
||||
ok = false;
|
||||
} else {
|
||||
RefPtr<gfxTextRun> mergedRun(gfxTextRun::Create(
|
||||
|
@ -3383,9 +3387,10 @@ bool gfxFont::InitFakeSmallCapsRun(DrawTarget* aDrawTarget,
|
|||
} else {
|
||||
aTextRun->AddGlyphRun(f, aMatchType, aOffset + runStart, true,
|
||||
aOrientation, isCJK);
|
||||
if (!f->SplitAndInitTextRun(
|
||||
aDrawTarget, aTextRun, convertedString.BeginReading(),
|
||||
aOffset + runStart, runLength, aScript, aOrientation)) {
|
||||
if (!f->SplitAndInitTextRun(aDrawTarget, aTextRun,
|
||||
convertedString.BeginReading(),
|
||||
aOffset + runStart, runLength, aScript,
|
||||
aLanguage, aOrientation)) {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
@ -3410,14 +3415,14 @@ bool gfxFont::InitFakeSmallCapsRun(DrawTarget* aDrawTarget,
|
|||
uint32_t aOffset, uint32_t aLength,
|
||||
FontMatchType aMatchType,
|
||||
gfx::ShapedTextFlags aOrientation,
|
||||
Script aScript, bool aSyntheticLower,
|
||||
bool aSyntheticUpper) {
|
||||
Script aScript, nsAtom* aLanguage,
|
||||
bool aSyntheticLower, bool aSyntheticUpper) {
|
||||
NS_ConvertASCIItoUTF16 unicodeString(reinterpret_cast<const char*>(aText),
|
||||
aLength);
|
||||
return InitFakeSmallCapsRun(aDrawTarget, aTextRun,
|
||||
static_cast<const char16_t*>(unicodeString.get()),
|
||||
aOffset, aLength, aMatchType, aOrientation,
|
||||
aScript, aSyntheticLower, aSyntheticUpper);
|
||||
return InitFakeSmallCapsRun(
|
||||
aDrawTarget, aTextRun, static_cast<const char16_t*>(unicodeString.get()),
|
||||
aOffset, aLength, aMatchType, aOrientation, aScript, aLanguage,
|
||||
aSyntheticLower, aSyntheticUpper);
|
||||
}
|
||||
|
||||
gfxFont* gfxFont::GetSmallCapsFont() {
|
||||
|
@ -3968,8 +3973,7 @@ void gfxFont::RemoveGlyphChangeObserver(GlyphChangeObserver* aObserver) {
|
|||
#define DEFAULT_PIXEL_FONT_SIZE 16.0f
|
||||
|
||||
gfxFontStyle::gfxFontStyle()
|
||||
: language(nsGkAtoms::x_western),
|
||||
size(DEFAULT_PIXEL_FONT_SIZE),
|
||||
: size(DEFAULT_PIXEL_FONT_SIZE),
|
||||
sizeAdjust(-1.0f),
|
||||
baselineOffset(0.0f),
|
||||
languageOverride(NO_FONT_LANGUAGE_OVERRIDE),
|
||||
|
@ -3984,18 +3988,15 @@ gfxFontStyle::gfxFontStyle()
|
|||
useGrayscaleAntialiasing(false),
|
||||
allowSyntheticWeight(true),
|
||||
allowSyntheticStyle(true),
|
||||
noFallbackVariantFeatures(true),
|
||||
explicitLanguage(false) {}
|
||||
noFallbackVariantFeatures(true) {}
|
||||
|
||||
gfxFontStyle::gfxFontStyle(FontSlantStyle aStyle, FontWeight aWeight,
|
||||
FontStretch aStretch, gfxFloat aSize,
|
||||
nsAtom* aLanguage, bool aExplicitLanguage,
|
||||
float aSizeAdjust, bool aSystemFont,
|
||||
bool aPrinterFont, bool aAllowWeightSynthesis,
|
||||
bool aAllowStyleSynthesis,
|
||||
uint32_t aLanguageOverride)
|
||||
: language(aLanguage),
|
||||
size(aSize),
|
||||
: size(aSize),
|
||||
sizeAdjust(aSizeAdjust),
|
||||
baselineOffset(0.0f),
|
||||
languageOverride(aLanguageOverride),
|
||||
|
@ -4010,8 +4011,7 @@ gfxFontStyle::gfxFontStyle(FontSlantStyle aStyle, FontWeight aWeight,
|
|||
useGrayscaleAntialiasing(false),
|
||||
allowSyntheticWeight(aAllowWeightSynthesis),
|
||||
allowSyntheticStyle(aAllowStyleSynthesis),
|
||||
noFallbackVariantFeatures(true),
|
||||
explicitLanguage(aExplicitLanguage) {
|
||||
noFallbackVariantFeatures(true) {
|
||||
MOZ_ASSERT(!mozilla::IsNaN(size));
|
||||
MOZ_ASSERT(!mozilla::IsNaN(sizeAdjust));
|
||||
|
||||
|
@ -4029,11 +4029,6 @@ gfxFontStyle::gfxFontStyle(FontSlantStyle aStyle, FontWeight aWeight,
|
|||
NS_WARNING("negative font size");
|
||||
size = 0.0;
|
||||
}
|
||||
|
||||
if (!language) {
|
||||
NS_WARNING("null language");
|
||||
language = nsGkAtoms::x_western;
|
||||
}
|
||||
}
|
||||
|
||||
PLDHashNumber gfxFontStyle::Hash() const {
|
||||
|
@ -4044,8 +4039,7 @@ PLDHashNumber gfxFontStyle::Hash() const {
|
|||
sizeof(gfxFontVariation));
|
||||
return mozilla::AddToHash(hash, systemFont, style.ForHash(),
|
||||
stretch.ForHash(), weight.ForHash(), size,
|
||||
int32_t(sizeAdjust * 1000.0f),
|
||||
nsRefPtrHashKey<nsAtom>::HashKey(language));
|
||||
int32_t(sizeAdjust * 1000.0f));
|
||||
}
|
||||
|
||||
void gfxFontStyle::AdjustForSubSuperscript(int32_t aAppUnitsPerDevPixel) {
|
||||
|
|
|
@ -79,16 +79,9 @@ struct gfxFontStyle {
|
|||
|
||||
gfxFontStyle();
|
||||
gfxFontStyle(FontSlantStyle aStyle, FontWeight aWeight, FontStretch aStretch,
|
||||
gfxFloat aSize, nsAtom* aLanguage, bool aExplicitLanguage,
|
||||
float aSizeAdjust, bool aSystemFont, bool aPrinterFont,
|
||||
bool aWeightSynthesis, bool aStyleSynthesis,
|
||||
gfxFloat aSize, float aSizeAdjust, bool aSystemFont,
|
||||
bool aPrinterFont, bool aWeightSynthesis, bool aStyleSynthesis,
|
||||
uint32_t aLanguageOverride);
|
||||
|
||||
// the language (may be an internal langGroup code rather than an actual
|
||||
// language code) specified in the document or element's lang property,
|
||||
// or inferred from the charset
|
||||
RefPtr<nsAtom> language;
|
||||
|
||||
// Features are composed of (1) features from style rules (2) features
|
||||
// from feature settings rules and (3) family-specific features. (1) and
|
||||
// (3) are guaranteed to be mutually exclusive
|
||||
|
@ -182,10 +175,6 @@ struct gfxFontStyle {
|
|||
// code, so set up a bool to indicate when shaping with fallback is needed
|
||||
bool noFallbackVariantFeatures : 1;
|
||||
|
||||
// whether the |language| field comes from explicit lang tagging in the
|
||||
// document, or was inferred from charset/system locale
|
||||
bool explicitLanguage : 1;
|
||||
|
||||
// Return the final adjusted font size for the given aspect ratio.
|
||||
// Not meant to be called when sizeAdjust = -1.0.
|
||||
gfxFloat GetAdjustedSize(gfxFloat aspect) const {
|
||||
|
@ -219,8 +208,6 @@ struct gfxFontStyle {
|
|||
(systemFont == other.systemFont) &&
|
||||
(printerFont == other.printerFont) &&
|
||||
(useGrayscaleAntialiasing == other.useGrayscaleAntialiasing) &&
|
||||
(explicitLanguage == other.explicitLanguage) &&
|
||||
(language == other.language) &&
|
||||
(baselineOffset == other.baselineOffset) &&
|
||||
(*reinterpret_cast<const uint32_t*>(&sizeAdjust) ==
|
||||
*reinterpret_cast<const uint32_t*>(&other.sizeAdjust)) &&
|
||||
|
@ -641,6 +628,9 @@ class gfxFontShaper {
|
|||
// aShapedText to be updated; aLength is also the length of aText.
|
||||
virtual bool ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
nsAtom* aLanguage, // may be null, indicating no
|
||||
// lang-specific shaping to be
|
||||
// applied
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) = 0;
|
||||
|
||||
|
@ -1224,7 +1214,8 @@ class gfxShapedWord final : public gfxShapedText {
|
|||
// glyph data; the caller must call gfxFont::ShapeText() with appropriate
|
||||
// parameters to set up the glyphs.
|
||||
static gfxShapedWord* Create(const uint8_t* aText, uint32_t aLength,
|
||||
Script aRunScript, uint16_t aAppUnitsPerDevUnit,
|
||||
Script aRunScript, nsAtom* aLanguage,
|
||||
uint16_t aAppUnitsPerDevUnit,
|
||||
mozilla::gfx::ShapedTextFlags aFlags,
|
||||
gfxFontShaper::RoundingFlags aRounding) {
|
||||
NS_ASSERTION(aLength <= gfxPlatform::GetPlatform()->WordCacheCharLimit(),
|
||||
|
@ -1240,12 +1231,13 @@ class gfxShapedWord final : public gfxShapedText {
|
|||
}
|
||||
|
||||
// Construct in the pre-allocated storage, using placement new
|
||||
return new (storage) gfxShapedWord(aText, aLength, aRunScript,
|
||||
return new (storage) gfxShapedWord(aText, aLength, aRunScript, aLanguage,
|
||||
aAppUnitsPerDevUnit, aFlags, aRounding);
|
||||
}
|
||||
|
||||
static gfxShapedWord* Create(const char16_t* aText, uint32_t aLength,
|
||||
Script aRunScript, uint16_t aAppUnitsPerDevUnit,
|
||||
Script aRunScript, nsAtom* aLanguage,
|
||||
uint16_t aAppUnitsPerDevUnit,
|
||||
mozilla::gfx::ShapedTextFlags aFlags,
|
||||
gfxFontShaper::RoundingFlags aRounding) {
|
||||
NS_ASSERTION(aLength <= gfxPlatform::GetPlatform()->WordCacheCharLimit(),
|
||||
|
@ -1258,7 +1250,8 @@ class gfxShapedWord final : public gfxShapedText {
|
|||
nsAutoCString narrowText;
|
||||
LossyAppendUTF16toASCII(nsDependentSubstring(aText, aLength), narrowText);
|
||||
return Create((const uint8_t*)(narrowText.BeginReading()), aLength,
|
||||
aRunScript, aAppUnitsPerDevUnit, aFlags, aRounding);
|
||||
aRunScript, aLanguage, aAppUnitsPerDevUnit, aFlags,
|
||||
aRounding);
|
||||
}
|
||||
|
||||
uint32_t size = offsetof(gfxShapedWord, mCharGlyphsStorage) +
|
||||
|
@ -1268,7 +1261,7 @@ class gfxShapedWord final : public gfxShapedText {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return new (storage) gfxShapedWord(aText, aLength, aRunScript,
|
||||
return new (storage) gfxShapedWord(aText, aLength, aRunScript, aLanguage,
|
||||
aAppUnitsPerDevUnit, aFlags, aRounding);
|
||||
}
|
||||
|
||||
|
@ -1300,6 +1293,7 @@ class gfxShapedWord final : public gfxShapedText {
|
|||
}
|
||||
|
||||
Script GetScript() const { return mScript; }
|
||||
nsAtom* GetLanguage() const { return mLanguage.get(); }
|
||||
|
||||
gfxFontShaper::RoundingFlags GetRounding() const { return mRounding; }
|
||||
|
||||
|
@ -1317,12 +1311,13 @@ class gfxShapedWord final : public gfxShapedText {
|
|||
|
||||
// Construct storage for a ShapedWord, ready to receive glyph data
|
||||
gfxShapedWord(const uint8_t* aText, uint32_t aLength, Script aRunScript,
|
||||
uint16_t aAppUnitsPerDevUnit,
|
||||
nsAtom* aLanguage, uint16_t aAppUnitsPerDevUnit,
|
||||
mozilla::gfx::ShapedTextFlags aFlags,
|
||||
gfxFontShaper::RoundingFlags aRounding)
|
||||
: gfxShapedText(aLength,
|
||||
aFlags | mozilla::gfx::ShapedTextFlags::TEXT_IS_8BIT,
|
||||
aAppUnitsPerDevUnit),
|
||||
mLanguage(aLanguage),
|
||||
mScript(aRunScript),
|
||||
mRounding(aRounding),
|
||||
mAgeCounter(0) {
|
||||
|
@ -1332,10 +1327,11 @@ class gfxShapedWord final : public gfxShapedText {
|
|||
}
|
||||
|
||||
gfxShapedWord(const char16_t* aText, uint32_t aLength, Script aRunScript,
|
||||
uint16_t aAppUnitsPerDevUnit,
|
||||
nsAtom* aLanguage, uint16_t aAppUnitsPerDevUnit,
|
||||
mozilla::gfx::ShapedTextFlags aFlags,
|
||||
gfxFontShaper::RoundingFlags aRounding)
|
||||
: gfxShapedText(aLength, aFlags, aAppUnitsPerDevUnit),
|
||||
mLanguage(aLanguage),
|
||||
mScript(aRunScript),
|
||||
mRounding(aRounding),
|
||||
mAgeCounter(0) {
|
||||
|
@ -1345,6 +1341,7 @@ class gfxShapedWord final : public gfxShapedText {
|
|||
SetupClusterBoundaries(0, aText, aLength);
|
||||
}
|
||||
|
||||
RefPtr<nsAtom> mLanguage;
|
||||
Script mScript;
|
||||
|
||||
gfxFontShaper::RoundingFlags mRounding;
|
||||
|
@ -1755,8 +1752,8 @@ class gfxFont {
|
|||
const T* aText, uint32_t aOffset, uint32_t aLength,
|
||||
FontMatchType aMatchType,
|
||||
mozilla::gfx::ShapedTextFlags aOrientation,
|
||||
Script aScript, bool aSyntheticLower,
|
||||
bool aSyntheticUpper);
|
||||
Script aScript, nsAtom* aLanguage,
|
||||
bool aSyntheticLower, bool aSyntheticUpper);
|
||||
|
||||
// call the (virtual) InitTextRun method to do glyph generation/shaping,
|
||||
// limiting the length of text passed by processing the run in multiple
|
||||
|
@ -1765,6 +1762,7 @@ class gfxFont {
|
|||
bool SplitAndInitTextRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
|
||||
const T* aString, uint32_t aRunStart,
|
||||
uint32_t aRunLength, Script aRunScript,
|
||||
nsAtom* aLanguage,
|
||||
mozilla::gfx::ShapedTextFlags aOrientation);
|
||||
|
||||
// Get a ShapedWord representing the given text (either 8- or 16-bit)
|
||||
|
@ -1772,8 +1770,8 @@ class gfxFont {
|
|||
template <typename T>
|
||||
gfxShapedWord* GetShapedWord(DrawTarget* aDrawTarget, const T* aText,
|
||||
uint32_t aLength, uint32_t aHash,
|
||||
Script aRunScript, bool aVertical,
|
||||
int32_t aAppUnitsPerDevUnit,
|
||||
Script aRunScript, nsAtom* aLanguage,
|
||||
bool aVertical, int32_t aAppUnitsPerDevUnit,
|
||||
mozilla::gfx::ShapedTextFlags aFlags,
|
||||
RoundingFlags aRounding,
|
||||
gfxTextPerfMetrics* aTextPerf);
|
||||
|
@ -1961,16 +1959,16 @@ class gfxFont {
|
|||
// For 8-bit text, expand to 16-bit and then call the following method.
|
||||
bool ShapeText(DrawTarget* aContext, const uint8_t* aText,
|
||||
uint32_t aOffset, // dest offset in gfxShapedText
|
||||
uint32_t aLength, Script aScript, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
uint32_t aLength, Script aScript, nsAtom* aLanguage,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText); // where to store the result
|
||||
|
||||
// Call the appropriate shaper to generate glyphs for aText and store
|
||||
// them into aShapedText.
|
||||
virtual bool ShapeText(DrawTarget* aContext, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText);
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding, gfxShapedText* aShapedText);
|
||||
|
||||
// Helper to adjust for synthetic bold and set character-type flags
|
||||
// in the shaped text; implementations of ShapeText should call this
|
||||
|
@ -1990,8 +1988,9 @@ class gfxFont {
|
|||
template <typename T>
|
||||
bool ShapeTextWithoutWordCache(DrawTarget* aDrawTarget, const T* aText,
|
||||
uint32_t aOffset, uint32_t aLength,
|
||||
Script aScript, bool aVertical,
|
||||
RoundingFlags aRounding, gfxTextRun* aTextRun);
|
||||
Script aScript, nsAtom* aLanguage,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxTextRun* aTextRun);
|
||||
|
||||
// Shape a fragment of text (a run that is known to contain only
|
||||
// "valid" characters, no newlines/tabs/other control chars).
|
||||
|
@ -2001,8 +2000,8 @@ class gfxFont {
|
|||
template <typename T>
|
||||
bool ShapeFragmentWithoutWordCache(DrawTarget* aDrawTarget, const T* aText,
|
||||
uint32_t aOffset, uint32_t aLength,
|
||||
Script aScript, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
Script aScript, nsAtom* aLanguage,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxTextRun* aTextRun);
|
||||
|
||||
void CheckForFeaturesInvolvingSpace();
|
||||
|
@ -2025,21 +2024,24 @@ class gfxFont {
|
|||
uint32_t mLength;
|
||||
mozilla::gfx::ShapedTextFlags mFlags;
|
||||
Script mScript;
|
||||
RefPtr<nsAtom> mLanguage;
|
||||
int32_t mAppUnitsPerDevUnit;
|
||||
PLDHashNumber mHashKey;
|
||||
bool mTextIs8Bit;
|
||||
RoundingFlags mRounding;
|
||||
|
||||
CacheHashKey(const uint8_t* aText, uint32_t aLength, uint32_t aStringHash,
|
||||
Script aScriptCode, int32_t aAppUnitsPerDevUnit,
|
||||
Script aScriptCode, nsAtom* aLanguage,
|
||||
int32_t aAppUnitsPerDevUnit,
|
||||
mozilla::gfx::ShapedTextFlags aFlags, RoundingFlags aRounding)
|
||||
: mLength(aLength),
|
||||
mFlags(aFlags),
|
||||
mScript(aScriptCode),
|
||||
mLanguage(aLanguage),
|
||||
mAppUnitsPerDevUnit(aAppUnitsPerDevUnit),
|
||||
mHashKey(aStringHash + static_cast<int32_t>(aScriptCode) +
|
||||
aAppUnitsPerDevUnit * 0x100 + uint16_t(aFlags) * 0x10000 +
|
||||
int(aRounding)),
|
||||
int(aRounding) + (aLanguage ? aLanguage->hash() : 0)),
|
||||
mTextIs8Bit(true),
|
||||
mRounding(aRounding) {
|
||||
NS_ASSERTION(aFlags & mozilla::gfx::ShapedTextFlags::TEXT_IS_8BIT,
|
||||
|
@ -2048,11 +2050,13 @@ class gfxFont {
|
|||
}
|
||||
|
||||
CacheHashKey(const char16_t* aText, uint32_t aLength, uint32_t aStringHash,
|
||||
Script aScriptCode, int32_t aAppUnitsPerDevUnit,
|
||||
Script aScriptCode, nsAtom* aLanguage,
|
||||
int32_t aAppUnitsPerDevUnit,
|
||||
mozilla::gfx::ShapedTextFlags aFlags, RoundingFlags aRounding)
|
||||
: mLength(aLength),
|
||||
mFlags(aFlags),
|
||||
mScript(aScriptCode),
|
||||
mLanguage(aLanguage),
|
||||
mAppUnitsPerDevUnit(aAppUnitsPerDevUnit),
|
||||
mHashKey(aStringHash + static_cast<int32_t>(aScriptCode) +
|
||||
aAppUnitsPerDevUnit * 0x100 + uint16_t(aFlags) * 0x10000 +
|
||||
|
|
|
@ -59,7 +59,8 @@ UniquePtr<gfxFont> gfxGDIFont::CopyWithAntialiasOption(
|
|||
|
||||
bool gfxGDIFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
if (!mIsValid) {
|
||||
NS_WARNING("invalid font! expect incorrect text rendering");
|
||||
|
@ -67,7 +68,7 @@ bool gfxGDIFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
|||
}
|
||||
|
||||
return gfxFont::ShapeText(aDrawTarget, aText, aOffset, aLength, aScript,
|
||||
aVertical, aRounding, aShapedText);
|
||||
aLanguage, aVertical, aRounding, aShapedText);
|
||||
}
|
||||
|
||||
const gfxFont::Metrics& gfxGDIFont::GetHorizontalMetrics() { return *mMetrics; }
|
||||
|
|
|
@ -61,10 +61,9 @@ class gfxGDIFont : public gfxFont {
|
|||
protected:
|
||||
const Metrics& GetHorizontalMetrics() override;
|
||||
|
||||
/* override to ensure the cairo font is set up properly */
|
||||
bool ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) override;
|
||||
|
||||
void Initialize(); // creates metrics and Cairo fonts
|
||||
|
|
|
@ -826,7 +826,7 @@ bool gfxGDIFontList::FindAndAddFamilies(StyleGenericFontFamily aGeneric,
|
|||
const nsACString& aFamily,
|
||||
nsTArray<FamilyAndGeneric>* aOutput,
|
||||
FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle,
|
||||
gfxFontStyle* aStyle, nsAtom* aLanguage,
|
||||
gfxFloat aDevToCssSize) {
|
||||
NS_ConvertUTF8toUTF16 key16(aFamily);
|
||||
BuildKeyNameFromFontName(key16);
|
||||
|
@ -842,12 +842,12 @@ bool gfxGDIFontList::FindAndAddFamilies(StyleGenericFontFamily aGeneric,
|
|||
return false;
|
||||
}
|
||||
|
||||
return gfxPlatformFontList::FindAndAddFamilies(aGeneric, aFamily, aOutput,
|
||||
aFlags, aStyle, aDevToCssSize);
|
||||
return gfxPlatformFontList::FindAndAddFamilies(
|
||||
aGeneric, aFamily, aOutput, aFlags, aStyle, aLanguage, aDevToCssSize);
|
||||
}
|
||||
|
||||
FontFamily gfxGDIFontList::GetDefaultFontForPlatform(
|
||||
const gfxFontStyle* aStyle) {
|
||||
FontFamily gfxGDIFontList::GetDefaultFontForPlatform(const gfxFontStyle* aStyle,
|
||||
nsAtom* aLanguage) {
|
||||
FontFamily ff;
|
||||
|
||||
// this really shouldn't fail to find a font....
|
||||
|
|
|
@ -308,6 +308,7 @@ class gfxGDIFontList final : public gfxPlatformFontList {
|
|||
nsTArray<FamilyAndGeneric>* aOutput,
|
||||
FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
nsAtom* aLanguage = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) override;
|
||||
|
||||
virtual gfxFontEntry* LookupLocalFont(const nsACString& aFontName,
|
||||
|
@ -328,7 +329,8 @@ class gfxGDIFontList final : public gfxPlatformFontList {
|
|||
FontListSizes* aSizes) const;
|
||||
|
||||
protected:
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle,
|
||||
nsAtom* aLanguage = nullptr) override;
|
||||
|
||||
private:
|
||||
friend class gfxWindowsPlatform;
|
||||
|
|
|
@ -131,7 +131,8 @@ static inline size_t CountUnicodes(const char16_t* aText, uint32_t aLength) {
|
|||
bool gfxGraphiteShaper::ShapeText(DrawTarget* aDrawTarget,
|
||||
const char16_t* aText, uint32_t aOffset,
|
||||
uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
const gfxFontStyle* style = mFont->GetStyle();
|
||||
auto t_mGrFace = rlbox::from_opaque(mGrFace);
|
||||
|
@ -191,9 +192,9 @@ bool gfxGraphiteShaper::ShapeText(DrawTarget* aDrawTarget,
|
|||
grLang = MakeGraphiteLangTag(style->languageOverride);
|
||||
} else if (entry->mLanguageOverride) {
|
||||
grLang = MakeGraphiteLangTag(entry->mLanguageOverride);
|
||||
} else if (style->explicitLanguage) {
|
||||
} else if (aLanguage) {
|
||||
nsAutoCString langString;
|
||||
style->language->ToUTF8String(langString);
|
||||
aLanguage->ToUTF8String(langString);
|
||||
grLang = GetGraphiteTagForLang(langString);
|
||||
}
|
||||
tainted_gr<gr_feature_val*> grFeatures =
|
||||
|
|
|
@ -23,7 +23,7 @@ class gfxGraphiteShaper : public gfxFontShaper {
|
|||
|
||||
bool ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) override;
|
||||
|
||||
static void Shutdown();
|
||||
|
|
|
@ -1355,7 +1355,8 @@ void gfxHarfBuzzShaper::InitializeVertical() {
|
|||
bool gfxHarfBuzzShaper::ShapeText(DrawTarget* aDrawTarget,
|
||||
const char16_t* aText, uint32_t aOffset,
|
||||
uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
mUseVerticalPresentationForms = false;
|
||||
|
||||
|
@ -1415,9 +1416,9 @@ bool gfxHarfBuzzShaper::ShapeText(DrawTarget* aDrawTarget,
|
|||
language = hb_ot_tag_to_language(style->languageOverride);
|
||||
} else if (entry->mLanguageOverride) {
|
||||
language = hb_ot_tag_to_language(entry->mLanguageOverride);
|
||||
} else if (style->explicitLanguage) {
|
||||
} else if (aLanguage) {
|
||||
nsCString langString;
|
||||
style->language->ToUTF8String(langString);
|
||||
aLanguage->ToUTF8String(langString);
|
||||
language = hb_language_from_string(langString.get(), langString.Length());
|
||||
} else {
|
||||
language = hb_ot_tag_to_language(HB_OT_TAG_DEFAULT_LANGUAGE);
|
||||
|
|
|
@ -29,7 +29,7 @@ class gfxHarfBuzzShaper : public gfxFontShaper {
|
|||
|
||||
bool ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) override;
|
||||
|
||||
// get a given font table in harfbuzz blob form
|
||||
|
|
|
@ -142,7 +142,8 @@ gfxMacFont::~gfxMacFont() {
|
|||
|
||||
bool gfxMacFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
||||
uint32_t aOffset, uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
nsAtom* aLanguage, bool aVertical,
|
||||
RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
if (!mIsValid) {
|
||||
NS_WARNING("invalid font! expect incorrect text rendering");
|
||||
|
@ -158,7 +159,7 @@ bool gfxMacFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
|||
mCoreTextShaper = MakeUnique<gfxCoreTextShaper>(this);
|
||||
}
|
||||
if (mCoreTextShaper->ShapeText(aDrawTarget, aText, aOffset, aLength,
|
||||
aScript, aVertical, aRounding,
|
||||
aScript, aLanguage, aVertical, aRounding,
|
||||
aShapedText)) {
|
||||
PostShapingFixup(aDrawTarget, aText, aOffset, aLength, aVertical,
|
||||
aShapedText);
|
||||
|
@ -181,7 +182,7 @@ bool gfxMacFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
|||
}
|
||||
|
||||
return gfxFont::ShapeText(aDrawTarget, aText, aOffset, aLength, aScript,
|
||||
aVertical, aRounding, aShapedText);
|
||||
aLanguage, aVertical, aRounding, aShapedText);
|
||||
}
|
||||
|
||||
gfxFont::RunMetrics gfxMacFont::Measure(const gfxTextRun* aTextRun,
|
||||
|
|
|
@ -63,7 +63,7 @@ class gfxMacFont : public gfxFont {
|
|||
|
||||
// override to prefer CoreText shaping with fonts that depend on AAT
|
||||
bool ShapeText(DrawTarget* aDrawTarget, const char16_t* aText, uint32_t aOffset, uint32_t aLength,
|
||||
Script aScript, bool aVertical, RoundingFlags aRounding,
|
||||
Script aScript, nsAtom* aLanguage, bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) override;
|
||||
|
||||
void InitMetrics();
|
||||
|
|
|
@ -146,6 +146,7 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
|
|||
nsTArray<FamilyAndGeneric>* aOutput,
|
||||
FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
nsAtom* aLanguage = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) override;
|
||||
|
||||
// lookup the system font for a particular system font type and set
|
||||
|
@ -163,7 +164,8 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
|
|||
void ReadSystemFontList(nsTArray<FontFamilyListEntry>* aList);
|
||||
|
||||
protected:
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
|
||||
FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle,
|
||||
nsAtom* aLanguage = nullptr) override;
|
||||
|
||||
private:
|
||||
friend class gfxPlatformMac;
|
||||
|
|
|
@ -1215,7 +1215,7 @@ void gfxMacPlatformFontList::InitSystemFontNames() {
|
|||
if (mUseSizeSensitiveSystemFont) {
|
||||
NSFont* displaySys = [NSFont systemFontOfSize:128.0];
|
||||
NSString* displayFamilyName = GetRealFamilyName(displaySys);
|
||||
if ([displayFamilyName isEqualToString: textFamilyName]) {
|
||||
if ([displayFamilyName isEqualToString:textFamilyName]) {
|
||||
mUseSizeSensitiveSystemFont = false;
|
||||
} else {
|
||||
nsCocoaUtils::GetStringForNSString(displayFamilyName, familyName);
|
||||
|
@ -1374,7 +1374,8 @@ gfxFontEntry* gfxMacPlatformFontList::PlatformGlobalFontFallback(const uint32_t
|
|||
return fontEntry;
|
||||
}
|
||||
|
||||
FontFamily gfxMacPlatformFontList::GetDefaultFontForPlatform(const gfxFontStyle* aStyle) {
|
||||
FontFamily gfxMacPlatformFontList::GetDefaultFontForPlatform(const gfxFontStyle* aStyle,
|
||||
nsAtom* aLanguage) {
|
||||
nsAutoreleasePool localPool;
|
||||
|
||||
NSString* defaultFamily = [[NSFont userFontOfSize:aStyle->size] familyName];
|
||||
|
@ -1459,7 +1460,7 @@ bool gfxMacPlatformFontList::FindAndAddFamilies(mozilla::StyleGenericFontFamily
|
|||
const nsACString& aFamily,
|
||||
nsTArray<FamilyAndGeneric>* aOutput,
|
||||
FindFamiliesFlags aFlags, gfxFontStyle* aStyle,
|
||||
gfxFloat aDevToCssSize) {
|
||||
nsAtom* aLanguage, gfxFloat aDevToCssSize) {
|
||||
if (aFamily.EqualsLiteral(kSystemFont_system)) {
|
||||
// Search for special system font name, -apple-system. This is not done via
|
||||
// the shared fontlist on Catalina or later, because the hidden system font
|
||||
|
@ -1467,12 +1468,13 @@ bool gfxMacPlatformFontList::FindAndAddFamilies(mozilla::StyleGenericFontFamily
|
|||
// this family.
|
||||
const nsCString& systemFontFamilyName =
|
||||
mUseSizeSensitiveSystemFont && aStyle &&
|
||||
(aStyle->size * aDevToCssSize) >= kTextDisplayCrossover
|
||||
? mSystemDisplayFontFamilyName : mSystemTextFontFamilyName;
|
||||
(aStyle->size * aDevToCssSize) >= kTextDisplayCrossover
|
||||
? mSystemDisplayFontFamilyName
|
||||
: mSystemTextFontFamilyName;
|
||||
if (SharedFontList() && !nsCocoaFeatures::OnCatalinaOrLater()) {
|
||||
FindFamiliesFlags flags = aFlags | FindFamiliesFlags::eSearchHiddenFamilies;
|
||||
return gfxPlatformFontList::FindAndAddFamilies(aGeneric, systemFontFamilyName, aOutput,
|
||||
flags, aStyle, aDevToCssSize);
|
||||
return gfxPlatformFontList::FindAndAddFamilies(aGeneric, systemFontFamilyName, aOutput, flags,
|
||||
aStyle, aLanguage, aDevToCssSize);
|
||||
} else {
|
||||
if (auto* fam = FindSystemFontFamily(systemFontFamilyName)) {
|
||||
aOutput->AppendElement(fam);
|
||||
|
@ -1483,7 +1485,7 @@ bool gfxMacPlatformFontList::FindAndAddFamilies(mozilla::StyleGenericFontFamily
|
|||
}
|
||||
|
||||
return gfxPlatformFontList::FindAndAddFamilies(aGeneric, aFamily, aOutput, aFlags, aStyle,
|
||||
aDevToCssSize);
|
||||
aLanguage, aDevToCssSize);
|
||||
}
|
||||
|
||||
void gfxMacPlatformFontList::LookupSystemFont(LookAndFeel::FontID aSystemFontID,
|
||||
|
|
|
@ -1909,10 +1909,12 @@ bool gfxPlatform::IsFontFormatSupported(uint32_t aFormatFlags) {
|
|||
|
||||
gfxFontGroup* gfxPlatform::CreateFontGroup(
|
||||
const FontFamilyList& aFontFamilyList, const gfxFontStyle* aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf, FontMatchingStats* aFontMatchingStats,
|
||||
gfxUserFontSet* aUserFontSet, gfxFloat aDevToCssSize) const {
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
|
||||
aFontMatchingStats, aUserFontSet, aDevToCssSize);
|
||||
nsAtom* aLanguage, bool aExplicitLanguage, gfxTextPerfMetrics* aTextPerf,
|
||||
FontMatchingStats* aFontMatchingStats, gfxUserFontSet* aUserFontSet,
|
||||
gfxFloat aDevToCssSize) const {
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aLanguage, aExplicitLanguage,
|
||||
aTextPerf, aFontMatchingStats, aUserFontSet,
|
||||
aDevToCssSize);
|
||||
}
|
||||
|
||||
gfxFontEntry* gfxPlatform::LookupLocalFont(const nsACString& aFontName,
|
||||
|
|
|
@ -393,7 +393,8 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
|
|||
* Create a gfxFontGroup based on the given family list and style.
|
||||
*/
|
||||
gfxFontGroup* CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle* aStyle,
|
||||
const gfxFontStyle* aStyle, nsAtom* aLanguage,
|
||||
bool aExplicitLanguage,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
FontMatchingStats* aFontMatchingStats,
|
||||
gfxUserFontSet* aUserFontSet,
|
||||
|
|
|
@ -1138,7 +1138,7 @@ gfxFontFamily* gfxPlatformFontList::CheckFamily(gfxFontFamily* aFamily) {
|
|||
bool gfxPlatformFontList::FindAndAddFamilies(
|
||||
StyleGenericFontFamily aGeneric, const nsACString& aFamily,
|
||||
nsTArray<FamilyAndGeneric>* aOutput, FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle, gfxFloat aDevToCssSize) {
|
||||
gfxFontStyle* aStyle, nsAtom* aLanguage, gfxFloat aDevToCssSize) {
|
||||
nsAutoCString key;
|
||||
GenerateFontListKey(aFamily, key);
|
||||
|
||||
|
@ -1283,13 +1283,13 @@ bool gfxPlatformFontList::FindAndAddFamilies(
|
|||
|
||||
fontlist::Family* gfxPlatformFontList::FindSharedFamily(
|
||||
const nsACString& aFamily, FindFamiliesFlags aFlags, gfxFontStyle* aStyle,
|
||||
gfxFloat aDevToCss) {
|
||||
nsAtom* aLanguage, gfxFloat aDevToCss) {
|
||||
if (!SharedFontList()) {
|
||||
return nullptr;
|
||||
}
|
||||
AutoTArray<FamilyAndGeneric, 1> families;
|
||||
if (!FindAndAddFamilies(StyleGenericFontFamily::None, aFamily, &families,
|
||||
aFlags, aStyle, aDevToCss) ||
|
||||
aFlags, aStyle, aLanguage, aDevToCss) ||
|
||||
!families[0].mFamily.mIsShared) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1595,12 +1595,9 @@ void gfxPlatformFontList::GetFontFamiliesFromGenericFamilies(
|
|||
PrefFontList* aGenericFamilies) {
|
||||
// lookup and add platform fonts uniquely
|
||||
for (const nsCString& genericFamily : aGenericNameFamilies) {
|
||||
gfxFontStyle style;
|
||||
style.language = aLangGroup;
|
||||
style.systemFont = false;
|
||||
AutoTArray<FamilyAndGeneric, 10> families;
|
||||
FindAndAddFamilies(aGenericType, genericFamily, &families,
|
||||
FindFamiliesFlags(0), &style);
|
||||
FindFamiliesFlags(0), nullptr, aLangGroup);
|
||||
for (const FamilyAndGeneric& f : families) {
|
||||
if (!aGenericFamilies->Contains(f.mFamily)) {
|
||||
aGenericFamilies->AppendElement(f.mFamily);
|
||||
|
|
|
@ -253,6 +253,7 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
|
|||
nsTArray<FamilyAndGeneric>* aOutput,
|
||||
FindFamiliesFlags aFlags,
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
nsAtom* aLanguage = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0);
|
||||
|
||||
gfxFontEntry* FindFontForFamily(const nsACString& aFamily,
|
||||
|
@ -585,18 +586,21 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
|
|||
mozilla::fontlist::Family* FindSharedFamily(
|
||||
const nsACString& aFamily,
|
||||
FindFamiliesFlags aFlags = FindFamiliesFlags(0),
|
||||
gfxFontStyle* aStyle = nullptr, gfxFloat aDevToCssSize = 1.0);
|
||||
gfxFontStyle* aStyle = nullptr, nsAtom* aLanguage = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0);
|
||||
|
||||
gfxFontFamily* FindUnsharedFamily(
|
||||
const nsACString& aFamily,
|
||||
FindFamiliesFlags aFlags = FindFamiliesFlags(0),
|
||||
gfxFontStyle* aStyle = nullptr, gfxFloat aDevToCssSize = 1.0) {
|
||||
gfxFontStyle* aStyle = nullptr, nsAtom* aLanguage = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) {
|
||||
if (SharedFontList()) {
|
||||
return nullptr;
|
||||
}
|
||||
AutoTArray<FamilyAndGeneric, 1> families;
|
||||
if (FindAndAddFamilies(mozilla::StyleGenericFontFamily::None, aFamily,
|
||||
&families, aFlags, aStyle, aDevToCssSize)) {
|
||||
&families, aFlags, aStyle, aLanguage,
|
||||
aDevToCssSize)) {
|
||||
return families[0].mFamily.mUnshared;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -605,13 +609,14 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
|
|||
FontFamily FindFamily(const nsACString& aFamily,
|
||||
FindFamiliesFlags aFlags = FindFamiliesFlags(0),
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
nsAtom* aLanguage = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) {
|
||||
if (SharedFontList()) {
|
||||
return FontFamily(
|
||||
FindSharedFamily(aFamily, aFlags, aStyle, aDevToCssSize));
|
||||
FindSharedFamily(aFamily, aFlags, aStyle, aLanguage, aDevToCssSize));
|
||||
}
|
||||
return FontFamily(
|
||||
FindUnsharedFamily(aFamily, aFlags, aStyle, aDevToCssSize));
|
||||
FindUnsharedFamily(aFamily, aFlags, aStyle, aLanguage, aDevToCssSize));
|
||||
}
|
||||
|
||||
// Lookup family name in global family list without substitutions or
|
||||
|
@ -766,7 +771,8 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
|
|||
const FontEntryTable& aTable, mozilla::MallocSizeOf aMallocSizeOf);
|
||||
|
||||
// Platform-specific helper for GetDefaultFont(...).
|
||||
virtual FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle) = 0;
|
||||
virtual FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle,
|
||||
nsAtom* aLanguage = nullptr) = 0;
|
||||
|
||||
// Protects mFontFamilies.
|
||||
mozilla::Mutex mFontFamiliesMutex;
|
||||
|
|
|
@ -1546,7 +1546,8 @@ void gfxTextRun::SetSpaceGlyph(gfxFont* aFont, DrawTarget* aDrawTarget,
|
|||
aFont->GetRoundOffsetsToPixels(aDrawTarget);
|
||||
gfxShapedWord* sw = aFont->GetShapedWord(
|
||||
aDrawTarget, &space, 1, gfxShapedWord::HashMix(0, ' '), Script::LATIN,
|
||||
vertical, mAppUnitsPerDevUnit, flags, roundingFlags, nullptr);
|
||||
/* aLanguage = */ nullptr, vertical, mAppUnitsPerDevUnit, flags,
|
||||
roundingFlags, nullptr);
|
||||
if (sw) {
|
||||
const GlyphRun* prevRun = TrailingGlyphRun();
|
||||
bool isCJK = prevRun && prevRun->mFont == aFont &&
|
||||
|
@ -1733,8 +1734,10 @@ void gfxTextRun::Dump(FILE* out) {
|
|||
# undef APPEND_FLAGS
|
||||
# undef APPEND_FLAG
|
||||
|
||||
fprintf(out, "gfxTextRun@%p (length %u) [%s] [%s]\n", this, mLength,
|
||||
flagsString.get(), flags2String.get());
|
||||
nsAutoCString lang;
|
||||
mFontGroup->Language()->ToUTF8String(lang);
|
||||
fprintf(out, "gfxTextRun@%p (length %u) [%s] [%s] [%s]\n", this, mLength,
|
||||
flagsString.get(), flags2String.get(), lang.get());
|
||||
|
||||
uint32_t numGlyphRuns;
|
||||
const GlyphRun* glyphRuns = GetGlyphRuns(&numGlyphRuns);
|
||||
|
@ -1744,12 +1747,9 @@ void gfxTextRun::Dump(FILE* out) {
|
|||
const gfxFontStyle* style = font->GetStyle();
|
||||
nsAutoString styleString;
|
||||
nsStyleUtil::AppendFontSlantStyle(style->style, styleString);
|
||||
nsAutoCString lang;
|
||||
style->language->ToUTF8String(lang);
|
||||
fprintf(out, " [%d] offset=%d %s %f/%g/%s/%s\n", i,
|
||||
fprintf(out, " [%d] offset=%d %s %f/%g/%s\n", i,
|
||||
glyphRuns[i].mCharacterOffset, font->GetName().get(), style->size,
|
||||
style->weight.ToFloat(), NS_ConvertUTF16toUTF8(styleString).get(),
|
||||
lang.get());
|
||||
style->weight.ToFloat(), NS_ConvertUTF16toUTF8(styleString).get());
|
||||
}
|
||||
|
||||
fprintf(out, " Glyphs:\n");
|
||||
|
@ -1828,12 +1828,14 @@ void gfxTextRun::Dump(FILE* out) {
|
|||
#endif
|
||||
|
||||
gfxFontGroup::gfxFontGroup(const FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle* aStyle,
|
||||
const gfxFontStyle* aStyle, nsAtom* aLanguage,
|
||||
bool aExplicitLanguage,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
FontMatchingStats* aFontMatchingStats,
|
||||
gfxUserFontSet* aUserFontSet, gfxFloat aDevToCssSize)
|
||||
: mFamilyList(aFontFamilyList),
|
||||
mStyle(*aStyle),
|
||||
mLanguage(aLanguage),
|
||||
mUnderlineOffset(UNDERLINE_OFFSET_NOT_SET),
|
||||
mHyphenWidth(-1),
|
||||
mDevToCssSize(aDevToCssSize),
|
||||
|
@ -1841,9 +1843,10 @@ gfxFontGroup::gfxFontGroup(const FontFamilyList& aFontFamilyList,
|
|||
mTextPerf(aTextPerf),
|
||||
mFontMatchingStats(aFontMatchingStats),
|
||||
mLastPrefLang(eFontPrefLang_Western),
|
||||
mPageLang(gfxPlatformFontList::GetFontPrefLangFor(aStyle->language)),
|
||||
mPageLang(gfxPlatformFontList::GetFontPrefLangFor(aLanguage)),
|
||||
mLastPrefFirstFont(false),
|
||||
mSkipDrawing(false) {
|
||||
mSkipDrawing(false),
|
||||
mExplicitLanguage(aExplicitLanguage) {
|
||||
// We don't use SetUserFontSet() here, as we want to unconditionally call
|
||||
// BuildFontList() rather than only do UpdateUserFonts() if it changed.
|
||||
mCurrGeneration = GetGeneration();
|
||||
|
@ -1869,7 +1872,7 @@ void gfxFontGroup::BuildFontList() {
|
|||
MOZ_ASSERT_UNREACHABLE("broken FontFamilyName, no atom!");
|
||||
}
|
||||
} else {
|
||||
pfl->AddGenericFonts(name.mGeneric, mStyle.language, fonts);
|
||||
pfl->AddGenericFonts(name.mGeneric, mLanguage, fonts);
|
||||
if (mTextPerf) {
|
||||
mTextPerf->current.genericLookups++;
|
||||
}
|
||||
|
@ -1913,8 +1916,7 @@ void gfxFontGroup::BuildFontList() {
|
|||
// if necessary, append default generic onto the end
|
||||
if (mFamilyList.GetDefaultFontType() != StyleGenericFontFamily::None &&
|
||||
!mFamilyList.HasDefaultGeneric()) {
|
||||
pfl->AddGenericFonts(mFamilyList.GetDefaultFontType(), mStyle.language,
|
||||
fonts);
|
||||
pfl->AddGenericFonts(mFamilyList.GetDefaultFontType(), mLanguage, fonts);
|
||||
if (mTextPerf) {
|
||||
mTextPerf->current.genericLookups++;
|
||||
}
|
||||
|
@ -1953,7 +1955,7 @@ void gfxFontGroup::AddPlatformFont(const nsACString& aName, bool aQuotedName,
|
|||
StyleGenericFontFamily::None, aName, &aFamilyList,
|
||||
aQuotedName ? gfxPlatformFontList::FindFamiliesFlags::eQuotedFamilyName
|
||||
: gfxPlatformFontList::FindFamiliesFlags(0),
|
||||
&mStyle, mDevToCssSize);
|
||||
&mStyle, mLanguage.get(), mDevToCssSize);
|
||||
}
|
||||
|
||||
void gfxFontGroup::AddFamilyToFontList(gfxFontFamily* aFamily,
|
||||
|
@ -2541,7 +2543,7 @@ void gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
|
|||
if (sizeof(T) == sizeof(uint8_t) && !transformedString) {
|
||||
if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Warning))) {
|
||||
nsAutoCString lang;
|
||||
mStyle.language->ToUTF8String(lang);
|
||||
mLanguage->ToUTF8String(lang);
|
||||
nsAutoCString families;
|
||||
mFamilyList.ToString(families);
|
||||
nsAutoCString str((const char*)aString, aLength);
|
||||
|
@ -2588,7 +2590,7 @@ void gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
|
|||
while (scriptRuns.Next(runStart, runLimit, runScript)) {
|
||||
if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Warning))) {
|
||||
nsAutoCString lang;
|
||||
mStyle.language->ToUTF8String(lang);
|
||||
mLanguage->ToUTF8String(lang);
|
||||
nsAutoCString families;
|
||||
mFamilyList.ToString(families);
|
||||
nsAutoString styleString;
|
||||
|
@ -2708,7 +2710,7 @@ void gfxFontGroup::InitScriptRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
|
|||
(matchedLength > 0), range.orientation, isCJK);
|
||||
if (!matchedFont->SplitAndInitTextRun(
|
||||
aDrawTarget, aTextRun, aString + runStart, aOffset + runStart,
|
||||
matchedLength, aRunScript, range.orientation)) {
|
||||
matchedLength, aRunScript, mLanguage, range.orientation)) {
|
||||
// glyph layout failed! treat as missing glyphs
|
||||
matchedFont = nullptr;
|
||||
}
|
||||
|
@ -2743,7 +2745,7 @@ void gfxFontGroup::InitScriptRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
|
|||
(matchedLength > 0), range.orientation, isCJK);
|
||||
if (!subSuperFont->SplitAndInitTextRun(
|
||||
aDrawTarget, aTextRun, aString + runStart, aOffset + runStart,
|
||||
matchedLength, aRunScript, range.orientation)) {
|
||||
matchedLength, aRunScript, mLanguage, range.orientation)) {
|
||||
// glyph layout failed! treat as missing glyphs
|
||||
matchedFont = nullptr;
|
||||
}
|
||||
|
@ -2755,7 +2757,8 @@ void gfxFontGroup::InitScriptRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
|
|||
if (!matchedFont->InitFakeSmallCapsRun(
|
||||
aDrawTarget, aTextRun, aString + runStart, aOffset + runStart,
|
||||
matchedLength, range.matchType, range.orientation, aRunScript,
|
||||
syntheticLower, syntheticUpper)) {
|
||||
mExplicitLanguage ? mLanguage.get() : nullptr, syntheticLower,
|
||||
syntheticUpper)) {
|
||||
matchedFont = nullptr;
|
||||
}
|
||||
} else {
|
||||
|
@ -2777,7 +2780,7 @@ void gfxFontGroup::InitScriptRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
|
|||
(matchedLength > 0), range.orientation, isCJK);
|
||||
if (!matchedFont->SplitAndInitTextRun(
|
||||
aDrawTarget, aTextRun, aString + runStart, aOffset + runStart,
|
||||
matchedLength, aRunScript, range.orientation)) {
|
||||
matchedLength, aRunScript, mLanguage, range.orientation)) {
|
||||
// glyph layout failed! treat as missing glyphs
|
||||
matchedFont = nullptr;
|
||||
}
|
||||
|
@ -3522,7 +3525,7 @@ void gfxFontGroup::ComputeRanges(nsTArray<TextRange>& aRanges, const T* aString,
|
|||
|
||||
if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Debug))) {
|
||||
nsAutoCString lang;
|
||||
mStyle.language->ToUTF8String(lang);
|
||||
mLanguage->ToUTF8String(lang);
|
||||
nsAutoCString families;
|
||||
mFamilyList.ToString(families);
|
||||
|
||||
|
|
|
@ -932,7 +932,8 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
|||
Shutdown(); // platform must call this to release the languageAtomService
|
||||
|
||||
gfxFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle* aStyle, gfxTextPerfMetrics* aTextPerf,
|
||||
const gfxFontStyle* aStyle, nsAtom* aLanguage,
|
||||
bool aExplicitLanguage, gfxTextPerfMetrics* aTextPerf,
|
||||
FontMatchingStats* aFontMatchingStats,
|
||||
gfxUserFontSet* aUserFontSet, gfxFloat aDevToCssSize);
|
||||
|
||||
|
@ -1092,6 +1093,8 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
|||
}
|
||||
}
|
||||
|
||||
nsAtom* Language() const { return mLanguage.get(); }
|
||||
|
||||
protected:
|
||||
friend class mozilla::PostTraversalTask;
|
||||
|
||||
|
@ -1377,6 +1380,8 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
|||
RefPtr<gfxFont> mDefaultFont;
|
||||
gfxFontStyle mStyle;
|
||||
|
||||
RefPtr<nsAtom> mLanguage;
|
||||
|
||||
gfxFloat mUnderlineOffset;
|
||||
gfxFloat mHyphenWidth;
|
||||
gfxFloat mDevToCssSize;
|
||||
|
@ -1405,6 +1410,8 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
|||
// download to complete (or fallback
|
||||
// timer to fire)
|
||||
|
||||
bool mExplicitLanguage; // Does mLanguage come from an explicit attribute?
|
||||
|
||||
uint32_t mFontListGeneration = 0; // platform font list generation for this
|
||||
// fontgroup
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче