Ticket #23970: 0001-Issue-23970-Printing-to-a-file-is-broken-with-Linux-.patch

File 0001-Issue-23970-Printing-to-a-file-is-broken-with-Linux-.patch, 33.8 KB (added by pospeselr, 20 months ago)
  • gfx/2d/2D.h

    From 1285151a0ee3539ceb5488c0c0bc61fb47a2ef55 Mon Sep 17 00:00:00 2001
    From: Richard Pospesel <richard@torproject.org>
    Date: Wed, 22 Nov 2017 15:10:24 -0800
    Subject: [PATCH] Issue 23970: Printing to a file is broken with Linux content
     sandboxing enabled
    
    Ported over following firefox patches:
      5c25a123203a
      2797f193a147
      5b9702d8fe4e
      5e7872cb3b5c
    
    Enables functionality for print.print_via_parent option to work,
    allowing print-to-file when sandbox mode is enabled.
    ---
     gfx/2d/2D.h                             |  19 ++
     gfx/2d/Factory.cpp                      |  48 ++++-
     gfx/2d/NativeFontResourceFontconfig.cpp |  65 +++++++
     gfx/2d/NativeFontResourceFontconfig.h   |  41 +++++
     gfx/2d/RecordedEvent.cpp                |  21 +--
     gfx/2d/RecordedEvent.h                  |  10 +-
     gfx/2d/ScaledFontFontconfig.cpp         | 316 ++++++++++++++++++++++++++++++++
     gfx/2d/ScaledFontFontconfig.h           |  59 +++++-
     gfx/2d/ScaledFontWin.cpp                |  17 ++
     gfx/2d/ScaledFontWin.h                  |   4 +
     gfx/2d/moz.build                        |   1 +
     gfx/thebes/gfxAndroidPlatform.h         |   4 +-
     gfx/thebes/gfxFT2FontList.cpp           |  10 +-
     gfx/thebes/gfxFontconfigFonts.h         |   5 +-
     gfx/thebes/gfxPlatform.cpp              |   4 +
     gfx/thebes/gfxPlatform.h                |   5 +
     gfx/thebes/gfxPlatformGtk.cpp           |  10 +
     gfx/thebes/gfxPlatformGtk.h             |   2 +
     modules/libpref/init/all.js             |   2 +-
     19 files changed, 608 insertions(+), 35 deletions(-)
     create mode 100644 gfx/2d/NativeFontResourceFontconfig.cpp
     create mode 100644 gfx/2d/NativeFontResourceFontconfig.h
    
    diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h
    index c1fba3463a8f..0b95f37cb1c3 100644
    a b typedef _cairo_scaled_font cairo_scaled_font_t; 
    4141struct _FcPattern;
    4242typedef _FcPattern FcPattern;
    4343
     44struct FT_LibraryRec_;
     45typedef FT_LibraryRec_* FT_Library;
     46
    4447struct ID3D11Texture2D;
    4548struct ID3D11Device;
    4649struct ID2D1Device;
    public: 
    13841387  static already_AddRefed<NativeFontResource>
    13851388    CreateNativeFontResource(uint8_t *aData, uint32_t aSize, FontType aType);
    13861389
     1390  /**
     1391   * This creates a scaled font of the given type based on font descriptor
     1392   * data retrieved from ScaledFont::GetFontDescriptor.
     1393   */
     1394  static already_AddRefed<ScaledFont>
     1395    CreateScaledFontFromFontDescriptor(FontType aType, const uint8_t* aData, uint32_t aDataLength, Float aSize);
     1396
    13871397  /**
    13881398   * This creates a scaled font with an associated cairo_scaled_font_t, and
    13891399   * must be used when using the Cairo backend. The NativeFont and
    public: 
    14831493    CreateCGGlyphRenderingOptions(const Color &aFontSmoothingBackgroundColor);
    14841494#endif
    14851495
     1496#ifdef MOZ_ENABLE_FREETYPE
     1497  static void SetFTLibrary(FT_Library aFTLibrary);
     1498  static FT_Library GetFTLibrary();
     1499
     1500private:
     1501  static FT_Library mFTLibrary;
     1502public:
     1503#endif
     1504
    14861505#ifdef WIN32
    14871506  static already_AddRefed<DrawTarget> CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat);
    14881507
  • gfx/2d/Factory.cpp

    diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp
    index 5cd5d14eaba1..bfe93d82c0ef 100644
    a b  
    3232
    3333#ifdef MOZ_WIDGET_GTK
    3434#include "ScaledFontFontconfig.h"
     35#include "NativeFontResourceFontconfig.h"
    3536#endif
    3637
    3738#ifdef WIN32
    namespace gfx { 
    156157// In Gecko, this value is managed by gfx.logging.level in gfxPrefs.
    157158int32_t LoggingPrefs::sGfxLogLevel = LOG_DEFAULT;
    158159
     160#ifdef MOZ_ENABLE_FREETYPE
     161FT_Library Factory::mFTLibrary = nullptr;
     162#endif
     163
    159164#ifdef WIN32
    160165ID3D11Device *Factory::mD3D11Device = nullptr;
    161166ID2D1Device *Factory::mD2D1Device = nullptr;
    Factory::ShutDown() 
    192197    delete sConfig;
    193198    sConfig = nullptr;
    194199  }
     200
     201#ifdef MOZ_ENABLE_FREETYPE
     202  if (mFTLibrary) {
     203    mFTLibrary = nullptr;
     204  }
     205#endif
    195206}
    196207
    197208bool
    Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, 
    524535        return NativeFontResourceGDI::Create(aData, aSize,
    525536                                             /* aNeedsCairo = */ true);
    526537      }
    527 #elif XP_DARWIN
     538#elif defined(XP_DARWIN)
    528539      return NativeFontResourceMac::Create(aData, aSize);
     540#elif defined(MOZ_WIDGET_GTK)
     541      return NativeFontResourceFontconfig::Create(aData, aSize);
    529542#else
    530543      gfxWarning() << "Unable to create cairo scaled font from truetype data";
    531544      return nullptr;
    Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, 
    537550  }
    538551}
    539552
     553already_AddRefed<ScaledFont>
     554Factory::CreateScaledFontFromFontDescriptor(FontType aType, const uint8_t* aData, uint32_t aDataLength, Float aSize)
     555{
     556  switch (aType) {
     557#ifdef WIN32
     558  case FontType::GDI:
     559    return ScaledFontWin::CreateFromFontDescriptor(aData, aDataLength, aSize);
     560#endif
     561#ifdef MOZ_WIDGET_GTK
     562  case FontType::FONTCONFIG:
     563    return ScaledFontFontconfig::CreateFromFontDescriptor(aData, aDataLength, aSize);
     564#endif
     565  default:
     566    gfxWarning() << "Invalid type specified for ScaledFont font descriptor";
     567    return nullptr;
     568  }
     569}
     570
    540571already_AddRefed<ScaledFont>
    541572Factory::CreateScaledFontWithCairo(const NativeFont& aNativeFont, Float aSize, cairo_scaled_font_t* aScaledFont)
    542573{
    Factory::CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB) 
    579610}
    580611
    581612
     613#ifdef MOZ_ENABLE_FREETYPE
     614void
     615Factory::SetFTLibrary(FT_Library aFTLibrary)
     616{
     617  mFTLibrary = aFTLibrary;
     618}
     619
     620FT_Library
     621Factory::GetFTLibrary()
     622{
     623  MOZ_ASSERT(mFTLibrary);
     624  return mFTLibrary;
     625}
     626#endif
     627
    582628#ifdef WIN32
    583629already_AddRefed<DrawTarget>
    584630Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat)
  • new file gfx/2d/NativeFontResourceFontconfig.cpp

    diff --git a/gfx/2d/NativeFontResourceFontconfig.cpp b/gfx/2d/NativeFontResourceFontconfig.cpp
    new file mode 100644
    index 000000000000..a205f98fae08
    - +  
     1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2/* vim: set ts=8 sts=2 et sw=2 tw=80: */
     3/* This Source Code Form is subject to the terms of the Mozilla Public
     4 * License, v. 2.0. If a copy of the MPL was not distributed with this
     5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6
     7#include "NativeFontResourceFontconfig.h"
     8#include "ScaledFontFontconfig.h"
     9#include "Logging.h"
     10
     11namespace mozilla {
     12namespace gfx {
     13
     14NativeFontResourceFontconfig::NativeFontResourceFontconfig(UniquePtr<uint8_t[]>&& aFontData, FT_Face aFace)
     15  : mFontData(Move(aFontData)),
     16    mFace(aFace)
     17{
     18}
     19
     20NativeFontResourceFontconfig::~NativeFontResourceFontconfig()
     21{
     22  if (mFace) {
     23    FT_Done_Face(mFace);
     24    mFace = nullptr;
     25  }
     26}
     27
     28already_AddRefed<NativeFontResourceFontconfig>
     29NativeFontResourceFontconfig::Create(uint8_t *aFontData, uint32_t aDataLength)
     30{
     31  if (!aFontData || !aDataLength) {
     32    return nullptr;
     33  }
     34  UniquePtr<uint8_t[]> fontData(new uint8_t[aDataLength]);
     35  memcpy(fontData.get(), aFontData, aDataLength);
     36
     37  FT_Face face;
     38  if (FT_New_Memory_Face(Factory::GetFTLibrary(), fontData.get(), aDataLength, 0, &face) != FT_Err_Ok) {
     39    return nullptr;
     40  }
     41  if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != FT_Err_Ok) {
     42    FT_Done_Face(face);
     43    return nullptr;
     44  }
     45
     46  RefPtr<NativeFontResourceFontconfig> resource =
     47    new NativeFontResourceFontconfig(Move(fontData), face);
     48  return resource.forget();
     49}
     50
     51already_AddRefed<ScaledFont>
     52NativeFontResourceFontconfig::CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
     53                                               const uint8_t* aInstanceData, uint32_t aInstanceDataLength)
     54{
     55  if (aInstanceDataLength < sizeof(ScaledFontFontconfig::InstanceData)) {
     56    gfxWarning() << "Fontconfig scaled font instance data is truncated.";
     57    return nullptr;
     58  }
     59  return ScaledFontFontconfig::CreateFromInstanceData(
     60           *reinterpret_cast<const ScaledFontFontconfig::InstanceData*>(aInstanceData),
     61           mFace, nullptr, 0, aGlyphSize);
     62}
     63
     64} // gfx
     65} // mozilla
  • new file gfx/2d/NativeFontResourceFontconfig.h

    diff --git a/gfx/2d/NativeFontResourceFontconfig.h b/gfx/2d/NativeFontResourceFontconfig.h
    new file mode 100644
    index 000000000000..e2c386198896
    - +  
     1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2/* vim: set ts=8 sts=2 et sw=2 tw=80: */
     3/* This Source Code Form is subject to the terms of the Mozilla Public
     4 * License, v. 2.0. If a copy of the MPL was not distributed with this
     5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6
     7#ifndef mozilla_gfx_NativeFontResourceFontconfig_h
     8#define mozilla_gfx_NativeFontResourceFontconfig_h
     9
     10#include "2D.h"
     11
     12#include <cairo-ft.h>
     13
     14namespace mozilla {
     15namespace gfx {
     16
     17class NativeFontResourceFontconfig final : public NativeFontResource
     18{
     19public:
     20  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResourceFontconfig)
     21
     22  static already_AddRefed<NativeFontResourceFontconfig>
     23    Create(uint8_t *aFontData, uint32_t aDataLength);
     24
     25  already_AddRefed<ScaledFont>
     26    CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
     27                     const uint8_t* aInstanceData, uint32_t aInstanceDataLength) final;
     28
     29  ~NativeFontResourceFontconfig();
     30
     31private:
     32  NativeFontResourceFontconfig(UniquePtr<uint8_t[]>&& aFontData, FT_Face aFace);
     33
     34  UniquePtr<uint8_t[]> mFontData;
     35  FT_Face mFace;
     36};
     37
     38} // gfx
     39} // mozilla
     40
     41#endif // mozilla_gfx_NativeFontResourceFontconfig_h
  • gfx/2d/RecordedEvent.cpp

    diff --git a/gfx/2d/RecordedEvent.cpp b/gfx/2d/RecordedEvent.cpp
    index 3bfc5c8f6333..684ce180db1e 100644
    a b RecordedFontDescriptor::~RecordedFontDescriptor() 
    15951595bool
    15961596RecordedFontDescriptor::PlayEvent(Translator *aTranslator) const
    15971597{
    1598   MOZ_ASSERT(mType == FontType::GDI);
    1599 
    1600   NativeFont nativeFont;
    1601   nativeFont.mType = (NativeFontType)mType;
    1602   nativeFont.mFont = (void*)&mData[0];
    1603 
    16041598  RefPtr<ScaledFont> font =
    1605     Factory::CreateScaledFontForNativeFont(nativeFont, mFontSize);
    1606 
    1607 #ifdef USE_CAIRO_SCALED_FONT
    1608   static_cast<ScaledFontBase*>(font.get())->PopulateCairoScaledFont();
    1609 #endif
     1599    Factory::CreateScaledFontFromFontDescriptor(mType, mData.data(), mData.size(), mFontSize);
     1600  if (!font) {
     1601    gfxDevCrash(LogReason::InvalidFont) <<
     1602      "Failed creating ScaledFont of type " << int(mType) << " from font descriptor";
     1603    return false;
     1604  }
    16101605
    16111606  aTranslator->AddScaledFont(mRefPtr, font);
    16121607  return true;
    RecordedFontDescriptor::RecordToStream(std::ostream &aStream) const 
    16201615  WriteElement(aStream, mFontSize);
    16211616  WriteElement(aStream, mRefPtr);
    16221617  WriteElement(aStream, (size_t)mData.size());
    1623   aStream.write((char*)&mData[0], mData.size());
     1618  aStream.write((char*)mData.data(), mData.size());
    16241619}
    16251620
    16261621void
    RecordedFontDescriptor::RecordedFontDescriptor(istream &aStream) 
    16461641  size_t size;
    16471642  ReadElement(aStream, size);
    16481643  mData.resize(size);
    1649   aStream.read((char*)&mData[0], size);
     1644  aStream.read((char*)mData.data(), size);
    16501645}
    16511646
    16521647bool
  • gfx/2d/RecordedEvent.h

    diff --git a/gfx/2d/RecordedEvent.h b/gfx/2d/RecordedEvent.h
    index bf660ba243c4..dcf4d9e36e02 100644
    a b private: 
    10471047  uint8_t *mData;
    10481048  RecordedFontDetails mFontDetails;
    10491049
    1050   bool mGetFontFileDataSucceeded = false;
     1050  bool mGetFontFileDataSucceeded;
    10511051
    10521052  MOZ_IMPLICIT RecordedFontData(std::istream &aStream);
    10531053};
    private: 
    10551055class RecordedFontDescriptor : public RecordedEvent {
    10561056public:
    10571057
    1058   static void FontDescCb(const uint8_t *aData, uint32_t aSize,
     1058  static void FontDescCb(const uint8_t* aData, uint32_t aSize,
    10591059                         Float aFontSize, void* aBaton)
    10601060  {
    10611061    auto recordedFontDesc = static_cast<RecordedFontDescriptor*>(aBaton);
    public: 
    11081108
    11091109  RecordedScaledFontCreation(ScaledFont* aScaledFont,
    11101110                             RecordedFontDetails aFontDetails)
    1111     : RecordedEvent(SCALEDFONTCREATION), mRefPtr(aScaledFont)
     1111    : RecordedEvent(SCALEDFONTCREATION)
     1112    , mRefPtr(aScaledFont)
    11121113    , mFontDataKey(aFontDetails.fontDataKey)
    1113     , mGlyphSize(aFontDetails.glyphSize) , mIndex(aFontDetails.index)
     1114    , mGlyphSize(aFontDetails.glyphSize)
     1115    , mIndex(aFontDetails.index)
    11141116  {
    11151117    aScaledFont->GetFontInstanceData(FontInstanceDataProc, this);
    11161118  }
  • gfx/2d/ScaledFontFontconfig.cpp

    diff --git a/gfx/2d/ScaledFontFontconfig.cpp b/gfx/2d/ScaledFontFontconfig.cpp
    index d4751f86dac1..68c9a1a42c88 100644
    a b  
    1010#include "skia/include/ports/SkTypeface_cairo.h"
    1111#endif
    1212
     13#include FT_TRUETYPE_TABLES_H
     14
     15#include <fontconfig/fcfreetype.h>
     16
    1317namespace mozilla {
    1418namespace gfx {
    1519
    SkTypeface* ScaledFontFontconfig::GetSkTypeface() 
    4347}
    4448#endif
    4549
     50bool
     51ScaledFontFontconfig::GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton)
     52{
     53  bool success = false;
     54  // Lock the Cairo scaled font to force it to resolve the Fontconfig pattern to an FT_Face.
     55  if (FT_Face face = cairo_ft_scaled_font_lock_face(GetCairoScaledFont())) {
     56    FT_ULong length = 0;
     57    // Request the SFNT file. This may not always succeed for all font types.
     58    if (FT_Load_Sfnt_Table(face, 0, 0, nullptr, &length) == FT_Err_Ok) {
     59      uint8_t* fontData = new uint8_t[length];
     60      if (FT_Load_Sfnt_Table(face, 0, 0, fontData, &length) == FT_Err_Ok) {
     61        aDataCallback(fontData, length, 0, mSize, aBaton);
     62        success = true;
     63      }
     64      delete[] fontData;
     65    }
     66    cairo_ft_scaled_font_unlock_face(GetCairoScaledFont());
     67  }
     68  return success;
     69}
     70
     71ScaledFontFontconfig::InstanceData::InstanceData(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern)
     72  : mFlags(0)
     73  , mHintStyle(FC_HINT_NONE)
     74  , mSubpixelOrder(FC_RGBA_UNKNOWN)
     75  , mLcdFilter(FC_LCD_LEGACY)
     76{
     77  // Record relevant Fontconfig properties into instance data.
     78  FcBool autohint;
     79  if (FcPatternGetBool(aPattern, FC_AUTOHINT, 0, &autohint) == FcResultMatch && autohint) {
     80    mFlags |= AUTOHINT;
     81  }
     82  FcBool bitmap;
     83  if (FcPatternGetBool(aPattern, FC_EMBEDDED_BITMAP, 0, &bitmap) == FcResultMatch && bitmap) {
     84    mFlags |= EMBEDDED_BITMAP;
     85  }
     86  FcBool embolden;
     87  if (FcPatternGetBool(aPattern, FC_EMBOLDEN, 0, &embolden) == FcResultMatch && embolden) {
     88    mFlags |= EMBOLDEN;
     89  }
     90  FcBool vertical;
     91  if (FcPatternGetBool(aPattern, FC_VERTICAL_LAYOUT, 0, &vertical) == FcResultMatch && vertical) {
     92    mFlags |= VERTICAL_LAYOUT;
     93  }
     94
     95  FcBool antialias;
     96  if (FcPatternGetBool(aPattern, FC_ANTIALIAS, 0, &antialias) != FcResultMatch || antialias) {
     97    mFlags |= ANTIALIAS;
     98
     99    // Only record subpixel order and lcd filtering if antialiasing is enabled.
     100    int rgba;
     101    if (FcPatternGetInteger(aPattern, FC_RGBA, 0, &rgba) == FcResultMatch) {
     102      mSubpixelOrder = rgba;
     103    }
     104    int filter;
     105    if (FcPatternGetInteger(aPattern, FC_LCD_FILTER, 0, &filter) == FcResultMatch) {
     106      mLcdFilter = filter;
     107    }
     108  }
     109
     110  cairo_font_options_t* fontOptions = cairo_font_options_create();
     111  cairo_scaled_font_get_font_options(aScaledFont, fontOptions);
     112  // For printer fonts, Cairo hint metrics and hinting will be disabled.
     113  // For other fonts, allow hint metrics and hinting.
     114  if (cairo_font_options_get_hint_metrics(fontOptions) != CAIRO_HINT_METRICS_OFF) {
     115    mFlags |= HINT_METRICS;
     116
     117    FcBool hinting;
     118    if (FcPatternGetBool(aPattern, FC_HINTING, 0, &hinting) != FcResultMatch || hinting) {
     119      int hintstyle;
     120      if (FcPatternGetInteger(aPattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) {
     121        hintstyle = FC_HINT_FULL;
     122      }
     123      mHintStyle = hintstyle;
     124    }
     125  }
     126  cairo_font_options_destroy(fontOptions);
     127
     128  // Some fonts supply an adjusted size or otherwise use the font matrix for italicization.
     129  // Record the scale and the skew to accomodate both of these cases.
     130  cairo_matrix_t fontMatrix;
     131  cairo_scaled_font_get_font_matrix(aScaledFont, &fontMatrix);
     132  mScale = Float(fontMatrix.xx);
     133  mSkew = Float(fontMatrix.xy);
     134}
     135
     136void
     137ScaledFontFontconfig::InstanceData::SetupPattern(FcPattern* aPattern) const
     138{
     139  if (mFlags & AUTOHINT) {
     140    FcPatternAddBool(aPattern, FC_AUTOHINT, FcTrue);
     141  }
     142  if (mFlags & EMBEDDED_BITMAP) {
     143    FcPatternAddBool(aPattern, FC_EMBEDDED_BITMAP, FcTrue);
     144  }
     145  if (mFlags & EMBOLDEN) {
     146    FcPatternAddBool(aPattern, FC_EMBOLDEN, FcTrue);
     147  }
     148  if (mFlags & VERTICAL_LAYOUT) {
     149    FcPatternAddBool(aPattern, FC_VERTICAL_LAYOUT, FcTrue);
     150  }
     151
     152  if (mFlags & ANTIALIAS) {
     153    FcPatternAddBool(aPattern, FC_ANTIALIAS, FcTrue);
     154    if (mSubpixelOrder != FC_RGBA_UNKNOWN) {
     155      FcPatternAddInteger(aPattern, FC_RGBA, mSubpixelOrder);
     156    }
     157    if (mLcdFilter != FC_LCD_LEGACY) {
     158      FcPatternAddInteger(aPattern, FC_LCD_FILTER, mLcdFilter);
     159    }
     160  } else {
     161    FcPatternAddBool(aPattern, FC_ANTIALIAS, FcFalse);
     162  }
     163
     164  if (mHintStyle) {
     165    FcPatternAddBool(aPattern, FC_HINTING, FcTrue);
     166    FcPatternAddInteger(aPattern, FC_HINT_STYLE, mHintStyle);
     167  } else {
     168    FcPatternAddBool(aPattern, FC_HINTING, FcFalse);
     169  }
     170}
     171
     172void
     173ScaledFontFontconfig::InstanceData::SetupFontOptions(cairo_font_options_t* aFontOptions) const
     174{
     175  // Try to build a sane initial set of Cairo font options based on the Fontconfig
     176  // pattern.
     177  if (mFlags & HINT_METRICS) {
     178    // For regular (non-printer) fonts, enable hint metrics as well as hinting
     179    // and (possibly subpixel) antialiasing.
     180    cairo_font_options_set_hint_metrics(aFontOptions, CAIRO_HINT_METRICS_ON);
     181
     182    cairo_hint_style_t hinting;
     183    switch (mHintStyle) {
     184    case FC_HINT_NONE:
     185      hinting = CAIRO_HINT_STYLE_NONE;
     186      break;
     187    case FC_HINT_SLIGHT:
     188      hinting = CAIRO_HINT_STYLE_SLIGHT;
     189      break;
     190    case FC_HINT_MEDIUM:
     191    default:
     192      hinting = CAIRO_HINT_STYLE_MEDIUM;
     193      break;
     194    case FC_HINT_FULL:
     195      hinting = CAIRO_HINT_STYLE_FULL;
     196      break;
     197    }
     198    cairo_font_options_set_hint_style(aFontOptions, hinting);
     199
     200    if (mFlags & ANTIALIAS) {
     201      cairo_subpixel_order_t subpixel = CAIRO_SUBPIXEL_ORDER_DEFAULT;
     202      switch (mSubpixelOrder) {
     203      case FC_RGBA_RGB:
     204        subpixel = CAIRO_SUBPIXEL_ORDER_RGB;
     205        break;
     206      case FC_RGBA_BGR:
     207        subpixel = CAIRO_SUBPIXEL_ORDER_BGR;
     208        break;
     209      case FC_RGBA_VRGB:
     210        subpixel = CAIRO_SUBPIXEL_ORDER_VRGB;
     211        break;
     212      case FC_RGBA_VBGR:
     213        subpixel = CAIRO_SUBPIXEL_ORDER_VBGR;
     214        break;
     215      default:
     216        break;
     217      }
     218      if (subpixel != CAIRO_SUBPIXEL_ORDER_DEFAULT) {
     219        cairo_font_options_set_antialias(aFontOptions, CAIRO_ANTIALIAS_SUBPIXEL);
     220        cairo_font_options_set_subpixel_order(aFontOptions, subpixel);
     221      } else {
     222        cairo_font_options_set_antialias(aFontOptions, CAIRO_ANTIALIAS_GRAY);
     223      }
     224    } else {
     225      cairo_font_options_set_antialias(aFontOptions, CAIRO_ANTIALIAS_NONE);
     226    }
     227  } else {
     228    // For printer fonts, disable hint metrics and hinting. Don't allow subpixel
     229    // antialiasing.
     230    cairo_font_options_set_hint_metrics(aFontOptions, CAIRO_HINT_METRICS_OFF);
     231    cairo_font_options_set_hint_style(aFontOptions, CAIRO_HINT_STYLE_NONE);
     232    cairo_font_options_set_antialias(aFontOptions,
     233      mFlags & ANTIALIAS ? CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE);
     234  }
     235}
     236
     237void
     238ScaledFontFontconfig::InstanceData::SetupFontMatrix(cairo_matrix_t* aFontMatrix) const
     239{
     240  // Build a font matrix that will reproduce a possibly adjusted size
     241  // and any italics/skew. This is just the concatenation of a simple
     242  // scale matrix with a matrix that skews on the X axis.
     243  cairo_matrix_init(aFontMatrix, mScale, 0, mSkew, mScale, 0, 0);
     244}
     245
     246bool
     247ScaledFontFontconfig::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
     248{
     249  InstanceData instance(GetCairoScaledFont(), mPattern);
     250
     251  aCb(reinterpret_cast<uint8_t*>(&instance), sizeof(instance), aBaton);
     252  return true;
     253}
     254
     255bool
     256ScaledFontFontconfig::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton)
     257{
     258  // Check if the Fontconfig pattern uses a font file and index to specify which
     259  // font to load. If so, record these as a font descriptor along with any instance
     260  // data required to rebuild a scaled font from it.
     261  FcChar8* pathname = nullptr;
     262  if (FcPatternGetString(mPattern, FC_FILE, 0, &pathname) != FcResultMatch) {
     263    return false;
     264  }
     265  int index = 0;
     266  FcPatternGetInteger(mPattern, FC_INDEX, 0, &index);
     267  if (index < 0) {
     268    return false;
     269  }
     270
     271  size_t pathLength = strlen(reinterpret_cast<char*>(pathname)) + 1;
     272  size_t dataLength = sizeof(FontDescriptor) + pathLength;
     273  uint8_t* data = new uint8_t[dataLength];
     274  FontDescriptor* desc = reinterpret_cast<FontDescriptor*>(data);
     275  desc->mPathLength = pathLength;
     276  desc->mIndex = index;
     277  desc->mInstanceData = InstanceData(GetCairoScaledFont(), mPattern);
     278  memcpy(data + sizeof(FontDescriptor), pathname, pathLength);
     279
     280  aCb(data, dataLength, mSize, aBaton);
     281  return true;
     282}
     283
     284already_AddRefed<ScaledFont>
     285ScaledFontFontconfig::CreateFromInstanceData(const InstanceData& aInstanceData,
     286                                             FT_Face aFace, const char* aPathname, uint32_t aIndex,
     287                                             Float aSize)
     288
     289{
     290  FcPattern* pattern = FcPatternCreate();
     291  if (!pattern) {
     292    gfxWarning() << "Failing initializing Fontconfig pattern for scaled font";
     293    return nullptr;
     294  }
     295  if (aFace) {
     296    FcPatternAddFTFace(pattern, FC_FT_FACE, aFace);
     297  } else {
     298    FcPatternAddString(pattern, FC_FILE, reinterpret_cast<const FcChar8*>(aPathname));
     299    FcPatternAddInteger(pattern, FC_INDEX, aIndex);
     300  }
     301  FcPatternAddDouble(pattern, FC_PIXEL_SIZE, aSize);
     302  aInstanceData.SetupPattern(pattern);
     303
     304  cairo_font_face_t* font = cairo_ft_font_face_create_for_pattern(pattern);
     305  if (cairo_font_face_status(font) != CAIRO_STATUS_SUCCESS) {
     306    gfxWarning() << "Failed creating Cairo font face for Fontconfig pattern";
     307    FcPatternDestroy(pattern);
     308    return nullptr;
     309  }
     310
     311  cairo_matrix_t sizeMatrix;
     312  aInstanceData.SetupFontMatrix(&sizeMatrix);
     313
     314  cairo_matrix_t identityMatrix;
     315  cairo_matrix_init_identity(&identityMatrix);
     316
     317  cairo_font_options_t *fontOptions = cairo_font_options_create();
     318  aInstanceData.SetupFontOptions(fontOptions);
     319
     320  cairo_scaled_font_t* cairoScaledFont =
     321    cairo_scaled_font_create(font, &sizeMatrix, &identityMatrix, fontOptions);
     322
     323  cairo_font_options_destroy(fontOptions);
     324  cairo_font_face_destroy(font);
     325
     326  if (cairo_scaled_font_status(cairoScaledFont) != CAIRO_STATUS_SUCCESS) {
     327    gfxWarning() << "Failed creating Cairo scaled font for font face";
     328    FcPatternDestroy(pattern);
     329    return nullptr;
     330  }
     331
     332  RefPtr<ScaledFontFontconfig> scaledFont =
     333    new ScaledFontFontconfig(cairoScaledFont, pattern, aSize);
     334
     335  cairo_scaled_font_destroy(cairoScaledFont);
     336  FcPatternDestroy(pattern);
     337
     338  return scaledFont.forget();
     339}
     340
     341already_AddRefed<ScaledFont>
     342ScaledFontFontconfig::CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, Float aSize)
     343{
     344  if (aDataLength < sizeof(FontDescriptor)) {
     345    gfxWarning() << "Fontconfig font descriptor is truncated.";
     346    return nullptr;
     347  }
     348  const FontDescriptor* desc = reinterpret_cast<const FontDescriptor*>(aData);
     349  if (desc->mPathLength < 1 ||
     350      desc->mPathLength > aDataLength - sizeof(FontDescriptor)) {
     351    gfxWarning() << "Pathname in Fontconfig font descriptor has invalid size.";
     352    return nullptr;
     353  }
     354  const char* pathname = reinterpret_cast<const char*>(aData + sizeof(FontDescriptor));
     355  if (pathname[desc->mPathLength - 1] != '\0') {
     356    gfxWarning() << "Pathname in Fontconfig font descriptor is not terminated.";
     357    return nullptr;
     358  }
     359  return CreateFromInstanceData(desc->mInstanceData, nullptr, pathname, desc->mIndex, aSize);
     360}
     361
    46362} // namespace gfx
    47363} // namespace mozilla
  • gfx/2d/ScaledFontFontconfig.h

    diff --git a/gfx/2d/ScaledFontFontconfig.h b/gfx/2d/ScaledFontFontconfig.h
    index 4d4e8217dc1f..b24928d9db05 100644
    a b  
    88
    99#include "ScaledFontBase.h"
    1010
    11 #include <fontconfig/fontconfig.h>
    12 #include <cairo.h>
     11#include <cairo-ft.h>
    1312
    1413namespace mozilla {
    1514namespace gfx {
    1615
     16class NativeFontResourceFontconfig;
     17
    1718class ScaledFontFontconfig : public ScaledFontBase
    1819{
    1920public:
    20   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontFontconfig)
     21  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontFontconfig, override)
    2122  ScaledFontFontconfig(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern, Float aSize);
    2223  ~ScaledFontFontconfig();
    2324
    24   virtual FontType GetType() const { return FontType::FONTCONFIG; }
     25  FontType GetType() const override { return FontType::FONTCONFIG; }
    2526
    2627#ifdef USE_SKIA
    27   virtual SkTypeface* GetSkTypeface();
     28  SkTypeface* GetSkTypeface() override;
    2829#endif
    2930
     31  bool GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton) override;
     32
     33  bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;
     34
     35  bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
     36
     37  static already_AddRefed<ScaledFont>
     38    CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, Float aSize);
     39
    3040private:
     41  friend class NativeFontResourceFontconfig;
     42
     43  struct InstanceData
     44  {
     45    enum {
     46      ANTIALIAS       = 1 << 0,
     47      AUTOHINT        = 1 << 1,
     48      EMBEDDED_BITMAP = 1 << 2,
     49      EMBOLDEN        = 1 << 3,
     50      VERTICAL_LAYOUT = 1 << 4,
     51      HINT_METRICS    = 1 << 5
     52    };
     53
     54    InstanceData(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern);
     55
     56    void SetupPattern(FcPattern* aPattern) const;
     57    void SetupFontOptions(cairo_font_options_t* aFontOptions) const;
     58    void SetupFontMatrix(cairo_matrix_t* aFontMatrix) const;
     59
     60    uint8_t mFlags;
     61    uint8_t mHintStyle;
     62    uint8_t mSubpixelOrder;
     63    uint8_t mLcdFilter;
     64    Float mScale;
     65    Float mSkew;
     66  };
     67
     68  struct FontDescriptor
     69  {
     70    uint32_t mPathLength;
     71    uint32_t mIndex;
     72    InstanceData mInstanceData;
     73  };
     74
     75  static already_AddRefed<ScaledFont>
     76    CreateFromInstanceData(const InstanceData& aInstanceData,
     77                           FT_Face aFace, const char* aPathname, uint32_t aIndex,
     78                           Float aSize);
     79
    3180  FcPattern* mPattern;
    3281};
    3382
  • gfx/2d/ScaledFontWin.cpp

    diff --git a/gfx/2d/ScaledFontWin.cpp b/gfx/2d/ScaledFontWin.cpp
    index 2ebae21e5c04..b80bbea872e2 100644
    a b ScaledFontWin::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) 
    7272  return true;
    7373}
    7474
     75already_AddRefed<ScaledFont>
     76ScaledFontWin::CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, Float aSize)
     77{
     78  NativeFont nativeFont;
     79  nativeFont.mType = NativeFontType::GDI_FONT_FACE;
     80  nativeFont.mFont = (void*)aData;
     81
     82  RefPtr<ScaledFont> font =
     83    Factory::CreateScaledFontForNativeFont(nativeFont, aSize);
     84
     85#ifdef USE_CAIRO_SCALED_FONT
     86  static_cast<ScaledFontBase*>(font.get())->PopulateCairoScaledFont();
     87#endif
     88
     89  return font.forget();
     90}
     91
    7592AntialiasMode
    7693ScaledFontWin::GetDefaultAAMode()
    7794{
  • gfx/2d/ScaledFontWin.h

    diff --git a/gfx/2d/ScaledFontWin.h b/gfx/2d/ScaledFontWin.h
    index c07b263d7285..fe5816707d00 100644
    a b public: 
    2525  bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;
    2626
    2727  virtual bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
     28
     29  static already_AddRefed<ScaledFont>
     30    CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, Float aSize);
     31
    2832  virtual AntialiasMode GetDefaultAAMode() override;
    2933
    3034#ifdef USE_SKIA
  • gfx/2d/moz.build

    diff --git a/gfx/2d/moz.build b/gfx/2d/moz.build
    index ad095503d97e..545ac6823390 100644
    a b if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'windows': 
    9191
    9292if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'):
    9393    SOURCES += [
     94        'NativeFontResourceFontconfig.cpp',
    9495        'ScaledFontFontconfig.cpp',
    9596    ]
    9697
  • gfx/thebes/gfxAndroidPlatform.h

    diff --git a/gfx/thebes/gfxAndroidPlatform.h b/gfx/thebes/gfxAndroidPlatform.h
    index 30e7c89babeb..889928da86a7 100644
    a b namespace mozilla { 
    1919};
    2020using mozilla::dom::FontListEntry;
    2121
    22 typedef struct FT_LibraryRec_ *FT_Library;
    23 
    2422class gfxAndroidPlatform : public gfxPlatform {
    2523public:
    2624    gfxAndroidPlatform();
    public: 
    6058    virtual bool FontHintingEnabled() override;
    6159    virtual bool RequiresLinearZoom() override;
    6260
    63     FT_Library GetFTLibrary();
     61    FT_Library GetFTLibrary() override;
    6462
    6563    virtual bool CanRenderContentToDataSurface() const override {
    6664      return true;
  • gfx/thebes/gfxFT2FontList.cpp

    diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp
    index 8a652df0dd34..2d9e09efe1c0 100644
    a b  
    1313#include "mozilla/UniquePtr.h"
    1414#include "mozilla/UniquePtrExtensions.h"
    1515#include "nsIInputStream.h"
    16 #define gfxToolkitPlatform gfxAndroidPlatform
    1716
    1817#include "nsXULAppAPI.h"
    1918#include <dirent.h>
    public: 
    8584
    8685        NS_ASSERTION(!aFontEntry->mFilename.IsEmpty(),
    8786                     "can't use AutoFTFace for fonts without a filename");
    88         FT_Library ft = gfxToolkitPlatform::GetPlatform()->GetFTLibrary();
     87        FT_Library ft = gfxPlatform::GetPlatform()->GetFTLibrary();
     88        MOZ_ASSERT(ft);
    8989
    9090        // A relative path (no initial "/") means this is a resource in
    9191        // omnijar, not an installed font on the device.
    FT2FontEntry::CreateFontEntry(const nsAString& aFontName, 
    256256    // eventually deleted.
    257257    FT_Face face;
    258258    FT_Error error =
    259         FT_New_Memory_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(),
     259        FT_New_Memory_Face(gfxPlatform::GetPlatform()->GetFTLibrary(),
    260260                           aFontData, aLength, 0, &face);
    261261    if (error != FT_Err_Ok) {
    262262        free((void*)aFontData);
    gfxFT2FontList::AppendFacesFromFontFile(const nsCString& aFileName, 
    974974        return;
    975975    }
    976976
    977     FT_Library ftLibrary = gfxAndroidPlatform::GetPlatform()->GetFTLibrary();
     977    FT_Library ftLibrary = gfxPlatform::GetPlatform()->GetFTLibrary();
    978978    FT_Face dummy;
    979979    if (FT_Err_Ok == FT_New_Face(ftLibrary, aFileName.get(), -1, &dummy)) {
    980980        LOG(("reading font info via FreeType for %s", aFileName.get()));
    gfxFT2FontList::AppendFacesFromOmnijarEntry(nsZipArchive* aArchive, 
    11261126        return;
    11271127    }
    11281128
    1129     FT_Library ftLibrary = gfxAndroidPlatform::GetPlatform()->GetFTLibrary();
     1129    FT_Library ftLibrary = gfxPlatform::GetPlatform()->GetFTLibrary();
    11301130
    11311131    FT_Face dummy;
    11321132    if (FT_Err_Ok != FT_New_Memory_Face(ftLibrary, buf.get(), bufSize, 0, &dummy)) {
  • gfx/thebes/gfxFontconfigFonts.h

    diff --git a/gfx/thebes/gfxFontconfigFonts.h b/gfx/thebes/gfxFontconfigFonts.h
    index cea9d0dbfaf2..cd59cfc68c62 100644
    a b public: 
    5555                                      const uint8_t* aFontData,
    5656                                      uint32_t aLength);
    5757
     58    static FT_Library GetFTLibrary();
     59
    5860private:
    5961
    6062    virtual gfxFont *GetFontAt(int32_t i, uint32_t aCh = 0x20);
    private: 
    116118                               nsIAtom *aLanguage,
    117119                               nsTArray<nsString>& aGenericFamilies);
    118120
    119 
    120     friend class gfxSystemFcFontEntry;
    121     static FT_Library GetFTLibrary();
    122121};
    123122
    124123#endif /* GFX_FONTCONFIG_FONTS_H */
  • gfx/thebes/gfxPlatform.cpp

    diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
    index 2e4ec990f8b3..4843554d655b 100644
    a b gfxPlatform::Init() 
    752752        NS_RUNTIMEABORT("Could not initialize gfxFontCache");
    753753    }
    754754
     755#ifdef MOZ_ENABLE_FREETYPE
     756    Factory::SetFTLibrary(gPlatform->GetFTLibrary());
     757#endif
     758
    755759    /* Create and register our CMS Override observer. */
    756760    gPlatform->mSRGBOverrideObserver = new SRGBOverrideObserver();
    757761    Preferences::AddWeakObserver(gPlatform->mSRGBOverrideObserver, GFX_PREF_CMS_FORCE_SRGB);
  • gfx/thebes/gfxPlatform.h

    diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h
    index 68bb99ea44e9..5ef792b67a40 100644
    a b class nsIAtom; 
    3939class nsIObserver;
    4040class SRGBOverrideObserver;
    4141class gfxTextPerfMetrics;
     42typedef struct FT_LibraryRec_ *FT_Library;
    4243
    4344namespace mozilla {
    4445namespace gl {
    public: 
    681682     */
    682683    virtual void ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData);
    683684
     685    virtual FT_Library GetFTLibrary() {
     686      return nullptr;
     687    }
     688
    684689protected:
    685690    gfxPlatform();
    686691    virtual ~gfxPlatform();
  • gfx/thebes/gfxPlatformGtk.cpp

    diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp
    index 9d7f512f27a7..c8661a433111 100644
    a b gfxPlatformGtk::MakePlatformFont(const nsAString& aFontName, 
    348348                                           aFontData, aLength);
    349349}
    350350
     351FT_Library
     352gfxPlatformGtk::GetFTLibrary()
     353{
     354    if (sUseFcFontList) {
     355        return gfxFcPlatformFontList::GetFTLibrary();
     356    }
     357
     358    return gfxPangoFontGroup::GetFTLibrary();
     359}
     360
    351361bool
    352362gfxPlatformGtk::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
    353363{
  • gfx/thebes/gfxPlatformGtk.h

    diff --git a/gfx/thebes/gfxPlatformGtk.h b/gfx/thebes/gfxPlatformGtk.h
    index 982390d1867b..d0c6079bd943 100644
    a b public: 
    9595     */
    9696    virtual void FlushContentDrawing() override;
    9797
     98    FT_Library GetFTLibrary() override;
     99
    98100#if (MOZ_WIDGET_GTK == 2)
    99101    static void SetGdkDrawable(cairo_surface_t *target,
    100102                               GdkDrawable *drawable);
  • modules/libpref/init/all.js

    diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
    index dd78fec1ee75..198028eeb96c 100644
    a b pref("print.print_edge_right", 0); 
    11061106pref("print.print_edge_bottom", 0);
    11071107
    11081108// Print via the parent process. This is only used when e10s is enabled.
    1109 #if defined(XP_WIN) || defined(XP_MACOSX)
     1109#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
    11101110pref("print.print_via_parent", true);
    11111111#else
    11121112pref("print.print_via_parent", false);