Bug 1331683 - Don't attempt to use any Core Text and Core Graphics variation-font APIs on pre-Sierra systems. r=jrmuizel,lsalzman

This commit is contained in:
Jonathan Kew 2017-02-09 21:37:24 +00:00
Родитель a06eb5c98d
Коммит 36f52391d9
8 изменённых файлов: 105 добавлений и 24 удалений

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

@ -13,6 +13,8 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
#include "nsCocoaFeatures.h"
// Simple helper class to automatically release a CFObject when it goes out
// of scope.
template<class T>
@ -54,6 +56,12 @@ static CFDictionaryRef
CreateVariationDictionaryOrNull(CGFontRef aCGFont, uint32_t aVariationCount,
const mozilla::gfx::ScaledFont::VariationSetting* aVariations)
{
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
// versions (see bug 1331683)
if (!nsCocoaFeatures::OnSierraOrLater()) {
return nullptr;
}
AutoRelease<CTFontRef>
ctFont(CTFontCreateWithGraphicsFont(aCGFont, 0, nullptr, nullptr));
AutoRelease<CFArrayRef> axes(CTFontCopyVariationAxes(ctFont));

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

@ -15,6 +15,7 @@
#ifdef MOZ_WIDGET_UIKIT
#include <CoreFoundation/CoreFoundation.h>
#endif
#include "nsCocoaFeatures.h"
#ifdef MOZ_WIDGET_COCOA
// prototype for private API
@ -38,6 +39,12 @@ bool ScaledFontMac::sSymbolLookupDone = false;
static CTFontRef
CreateCTFontFromCGFontWithVariations(CGFontRef aCGFont, CGFloat aSize)
{
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
// versions (see bug 1331683)
if (!nsCocoaFeatures::OnSierraOrLater()) {
return CTFontCreateWithGraphicsFont(aCGFont, aSize, nullptr, nullptr);
}
CFDictionaryRef vars = CGFontCopyVariations(aCGFont);
CTFontRef ctFont;
if (vars) {
@ -275,17 +282,21 @@ ScaledFontMac::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
// Collect any variation settings that were incorporated into the CTFont.
uint32_t variationCount = 0;
VariationSetting* variations = nullptr;
if (mCTFont) {
CFDictionaryRef dict = CTFontCopyVariation(mCTFont);
if (dict) {
CFIndex count = CFDictionaryGetCount(dict);
if (count > 0) {
variations = new VariationSetting[count];
VariationSetting* vPtr = variations;
CFDictionaryApplyFunction(dict, CollectVariationSetting, &vPtr);
variationCount = vPtr - variations;
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
// versions (see bug 1331683)
if (nsCocoaFeatures::OnSierraOrLater()) {
if (mCTFont) {
CFDictionaryRef dict = CTFontCopyVariation(mCTFont);
if (dict) {
CFIndex count = CFDictionaryGetCount(dict);
if (count > 0) {
variations = new VariationSetting[count];
VariationSetting* vPtr = variations;
CFDictionaryApplyFunction(dict, CollectVariationSetting, &vPtr);
variationCount = vPtr - variations;
}
CFRelease(dict);
}
CFRelease(dict);
}
}

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

@ -340,6 +340,13 @@ const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
static CTFontRef
CreateCTFontFromCGFontWithVariations(CGFontRef aCGFont, CGFloat aSize)
{
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
// versions (see bug 1331683)
// Declare helper provided by widget/cocoa/nsCocoaFeatures.mm
extern bool Gecko_OnSierraOrLater();
if (!Gecko_OnSierraOrLater()) {
return CTFontCreateWithGraphicsFont(aCGFont, aSize, NULL, NULL);
}
CFDictionaryRef vars = CGFontCopyVariations(aCGFont);
CTFontRef ctFont;
if (vars) {

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

@ -801,22 +801,26 @@ static CTFontRef ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize,
// as other uses of CTFontCreateWithGraphicsFont which is that such CTFonts should not escape
// the scaler context, since they aren't 'normal'.
// Not AutoCFRelease<> because CGFontCopyVariations can return null!
CFDictionaryRef variations = CGFontCopyVariations(baseCGFont);
if (variations) {
AutoCFRelease<CFDictionaryRef>
varAttr(CFDictionaryCreate(nullptr,
(const void**)&kCTFontVariationAttribute,
(const void**)&variations,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
CFRelease(variations);
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
// versions (see bug 1331683)
if (darwinVersion() >= 16) {
// Not AutoCFRelease<> because CGFontCopyVariations can return null!
CFDictionaryRef variations = CGFontCopyVariations(baseCGFont);
if (variations) {
AutoCFRelease<CFDictionaryRef>
varAttr(CFDictionaryCreate(nullptr,
(const void**)&kCTFontVariationAttribute,
(const void**)&variations,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
CFRelease(variations);
AutoCFRelease<CTFontDescriptorRef>
varDesc(CTFontDescriptorCreateWithAttributes(varAttr));
AutoCFRelease<CTFontDescriptorRef>
varDesc(CTFontDescriptorCreateWithAttributes(varAttr));
return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, varDesc);
return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, varDesc);
}
}
return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, nullptr);

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

@ -16,6 +16,7 @@
#include "gfxMacPlatformFontList.h"
#include "gfxFontConstants.h"
#include "gfxTextRun.h"
#include "nsCocoaFeatures.h"
#include "cairo-quartz.h"
@ -60,6 +61,12 @@ static CFDictionaryRef
CreateVariationDictionaryOrNull(CGFontRef aCGFont,
const nsTArray<gfxFontVariation>& aVariations)
{
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
// versions (see bug 1331683)
if (!nsCocoaFeatures::OnSierraOrLater()) {
return nullptr;
}
AutoRelease<CTFontRef>
ctFont(CTFontCreateWithGraphicsFont(aCGFont, 0, nullptr, nullptr));
AutoRelease<CFArrayRef> axes(CTFontCopyVariationAxes(ctFont));
@ -531,6 +538,12 @@ gfxMacFont::CreateCTFontFromCGFontWithVariations(CGFontRef aCGFont,
CGFloat aSize,
CTFontDescriptorRef aFontDesc)
{
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
// versions (see bug 1331683)
if (!nsCocoaFeatures::OnSierraOrLater()) {
return CTFontCreateWithGraphicsFont(aCGFont, aSize, nullptr, aFontDesc);
}
CFDictionaryRef variations = ::CGFontCopyVariations(aCGFont);
CTFontRef ctFont;
if (variations) {

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

@ -1784,6 +1784,23 @@ GetSpacingFlags(nsIFrame* aFrame, const nsStyleText* aStyleText = nullptr)
return nonStandardSpacing ? gfxTextRunFactory::TEXT_ENABLE_SPACING : 0;
}
static bool
IsBaselineAligned(const nsStyleCoord& aCoord)
{
switch (aCoord.GetUnit()) {
case eStyleUnit_Enumerated:
return aCoord.GetIntValue() == NS_STYLE_VERTICAL_ALIGN_BASELINE;
case eStyleUnit_Coord:
return aCoord.GetCoordValue() == 0;
case eStyleUnit_Percent:
return aCoord.GetPercentValue() == 0;
case eStyleUnit_Calc:
return aCoord.GetCalcValue()->IsDefinitelyZero();
default:
return false;
}
}
bool
BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1, nsTextFrame* aFrame2)
{
@ -1813,6 +1830,10 @@ BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1, nsTextFr
if (textStyle1->NewlineIsSignificant(aFrame1) && HasTerminalNewline(aFrame1))
return false;
if (!IsBaselineAligned(sc1->StyleDisplay()->mVerticalAlign)) {
return false;
}
if (aFrame1->GetContent() == aFrame2->GetContent() &&
aFrame1->GetNextInFlow() != aFrame2) {
// aFrame2 must be a non-fluid continuation of aFrame1. This can happen
@ -1829,6 +1850,10 @@ BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1, nsTextFr
if (sc1 == sc2)
return true;
if (!IsBaselineAligned(sc1->StyleDisplay()->mVerticalAlign)) {
return false;
}
const nsStyleFont* fontStyle1 = sc1->StyleFont();
const nsStyleFont* fontStyle2 = sc2->StyleFont();
nscoord letterSpacing1 = LetterSpacing(aFrame1);

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

@ -39,4 +39,10 @@ private:
static int32_t mOSXVersion;
};
// C-callable helper for cairo-quartz-font.c
extern "C" {
bool Gecko_OnSierraOrLater();
}
#endif // nsCocoaFeatures_h_

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

@ -167,6 +167,13 @@ nsCocoaFeatures::OnSierraOrLater()
return (OSXVersion() >= MAC_OS_X_VERSION_10_12_HEX);
}
/* Version of OnSierraOrLater as a global function callable from C (cairo) */
bool
Gecko_OnSierraOrLater()
{
return nsCocoaFeatures::OnSierraOrLater();
}
/* static */ bool
nsCocoaFeatures::IsAtLeastVersion(int32_t aMajor, int32_t aMinor, int32_t aBugFix)
{