# HG changeset patch # User Jonathan Kew # Date 1518606125 -39600 # Node ID dc462be5c9a67b6f3b14cab88951c6563b327896 # Parent cecc23e078c60fcfe8a9967a7067da877d1f2a23 Bug 1435984 - patch 6 - Apply variation settings from the font entry when instantiation fonts for DirectWrite. r=lsalzman diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -695,16 +695,25 @@ gfxDWriteFontEntry::CreateFontInstance(c return new gfxDWriteFont(unscaledFont, this, aFontStyle, aNeedsBold); } nsresult gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, const nsTArray* aVariations, DWRITE_FONT_SIMULATIONS aSimulations) { + // Convert an OpenType font tag from our uint32_t representation + // (as constructed by TRUETYPE_TAG(...)) to the order DWrite wants. + auto makeDWriteAxisTag = [](uint32_t aTag) { + return DWRITE_MAKE_FONT_AXIS_TAG((aTag >> 24) & 0xff, + (aTag >> 16) & 0xff, + (aTag >> 8) & 0xff, + aTag & 0xff); + }; + // initialize mFontFace if this hasn't been done before if (!mFontFace) { HRESULT hr; if (mFont) { hr = mFont->CreateFontFace(getter_AddRefs(mFontFace)); } else if (mFontFile) { IDWriteFontFile *fontFile = mFontFile.get(); hr = Factory::GetDWriteFactory()-> @@ -721,16 +730,36 @@ gfxDWriteFontEntry::CreateFontFace(IDWri if (FAILED(hr)) { return NS_ERROR_FAILURE; } // Also get the IDWriteFontFace5 interface if we're running on a // sufficiently new DWrite version where it is available. if (mFontFace) { mFontFace->QueryInterface(__uuidof(IDWriteFontFace5), (void**)getter_AddRefs(mFontFace5)); + if (!mVariationSettings.IsEmpty()) { + // If the font entry has variations specified, mFontFace5 will + // be a distinct face that has the variations applied. + RefPtr resource; + HRESULT hr = + mFontFace5->GetFontResource(getter_AddRefs(resource)); + MOZ_ASSERT(SUCCEEDED(hr)); + AutoTArray fontAxisValues; + for (const auto& v : mVariationSettings) { + DWRITE_FONT_AXIS_VALUE axisValue = { + makeDWriteAxisTag(v.mTag), + v.mValue + }; + fontAxisValues.AppendElement(axisValue); + } + resource->CreateFontFace(mFontFace->GetSimulations(), + fontAxisValues.Elements(), + fontAxisValues.Length(), + getter_AddRefs(mFontFace5)); + } } } // Do we need to modify DWrite simulations from what mFontFace has? bool needSimulations = (aSimulations & DWRITE_FONT_SIMULATIONS_BOLD) && !(mFontFace->GetSimulations() & DWRITE_FONT_SIMULATIONS_BOLD); @@ -738,23 +767,34 @@ gfxDWriteFontEntry::CreateFontFace(IDWri // IDWriteFontResource to create a new modified face. if (mFontFace5 && (aVariations && !aVariations->IsEmpty() || needSimulations)) { RefPtr resource; HRESULT hr = mFontFace5->GetFontResource(getter_AddRefs(resource)); MOZ_ASSERT(SUCCEEDED(hr)); AutoTArray fontAxisValues; if (aVariations) { - for (const auto& v : *aVariations) { + // Merge mVariationSettings and *aVariations if both present + const nsTArray* vars; + AutoTArray mergedSettings; + if (!aVariations) { + vars = &mVariationSettings; + } else { + if (mVariationSettings.IsEmpty()) { + vars = aVariations; + } else { + gfxFontUtils::MergeVariations(mVariationSettings, + *aVariations, + &mergedSettings); + vars = &mergedSettings; + } + } + for (const auto& v : *vars) { DWRITE_FONT_AXIS_VALUE axisValue = { - // let dwrite put the tag bytes in the order it wants - DWRITE_MAKE_FONT_AXIS_TAG((v.mTag >> 24) & 0xff, - (v.mTag >> 16) & 0xff, - (v.mTag >> 8) & 0xff, - v.mTag & 0xff), + makeDWriteAxisTag(v.mTag), v.mValue }; fontAxisValues.AppendElement(axisValue); } } IDWriteFontFace5* ff5; resource->CreateFontFace(aSimulations, fontAxisValues.Elements(), @@ -788,18 +828,23 @@ gfxDWriteFontEntry::CreateFontFace(IDWri aSimulations, aFontFace); for (UINT32 i = 0; i < numberOfFiles; ++i) { files[i]->Release(); } return FAILED(hr) ? NS_ERROR_FAILURE : NS_OK; } - // no simulation: we can just add a reference to mFontFace and return that - *aFontFace = mFontFace; + // no simulation: we can just add a reference to mFontFace5 (if present) + // or mFontFace (otherwise) and return that + if (mFontFace5) { + *aFontFace = mFontFace5; + } else { + *aFontFace = mFontFace; + } (*aFontFace)->AddRef(); return NS_OK; } bool gfxDWriteFontEntry::InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont) { HRESULT hr;