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:
Jonathan Kew 2020-11-13 13:15:39 +00:00
Родитель 8e1dfa2a73
Коммит 16eb1dba68
34 изменённых файлов: 252 добавлений и 214 удалений

Просмотреть файл

@ -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,
&params, 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