summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accessible/base/TextAttrs.cpp34
-rw-r--r--build/valgrind/i386-redhat-linux-gnu.sup10
-rw-r--r--build/valgrind/x86_64-redhat-linux-gnu.sup10
-rw-r--r--gfx/thebes/gfxFontconfigFonts.cpp2255
-rw-r--r--gfx/thebes/gfxFontconfigFonts.h124
-rw-r--r--gfx/thebes/gfxFontconfigUtils.cpp1100
-rw-r--r--gfx/thebes/gfxFontconfigUtils.h281
-rw-r--r--gfx/thebes/gfxPlatform.cpp17
-rw-r--r--gfx/thebes/gfxPlatformGtk.cpp90
-rw-r--r--gfx/thebes/gfxPlatformGtk.h6
-rw-r--r--gfx/thebes/gfxTextRun.cpp17
-rw-r--r--gfx/thebes/gfxTextRun.h3
-rw-r--r--gfx/thebes/gfxUserFontSet.cpp26
-rw-r--r--gfx/thebes/gfxUserFontSet.h8
-rw-r--r--gfx/thebes/moz.build3
-rw-r--r--layout/base/nsPresContext.cpp13
-rw-r--r--modules/libpref/init/all.js6
17 files changed, 37 insertions, 3966 deletions
diff --git a/accessible/base/TextAttrs.cpp b/accessible/base/TextAttrs.cpp
index 0f9e4f6fea..a03730ad76 100644
--- a/accessible/base/TextAttrs.cpp
+++ b/accessible/base/TextAttrs.cpp
@@ -18,10 +18,6 @@
#include "mozilla/AppUnits.h"
#include "mozilla/gfx/2D.h"
-#if defined(MOZ_WIDGET_GTK)
-#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
-#endif
-
using namespace mozilla;
using namespace mozilla::a11y;
@@ -653,28 +649,14 @@ TextAttrsMgr::FontWeightTextAttr::
if (font->IsSyntheticBold())
return 700;
- bool useFontEntryWeight = true;
-
- // Under Linux, when gfxPangoFontGroup code is used,
- // font->GetStyle()->weight will give the absolute weight requested of the
- // font face. The gfxPangoFontGroup code uses the gfxFontEntry constructor
- // which doesn't initialize the weight field.
-#if defined(MOZ_WIDGET_GTK)
- useFontEntryWeight = gfxPlatformGtk::UseFcFontList();
-#endif
-
- if (useFontEntryWeight) {
- // On Windows, font->GetStyle()->weight will give the same weight as
- // fontEntry->Weight(), the weight of the first font in the font group,
- // which may not be the weight of the font face used to render the
- // characters. On Mac, font->GetStyle()->weight will just give the same
- // number as getComputedStyle(). fontEntry->Weight() will give the weight
- // of the font face used.
- gfxFontEntry *fontEntry = font->GetFontEntry();
- return fontEntry->Weight();
- } else {
- return font->GetStyle()->weight;
- }
+ // On Windows, font->GetStyle()->weight will give the same weight as
+ // fontEntry->Weight(), the weight of the first font in the font group,
+ // which may not be the weight of the font face used to render the
+ // characters. On Mac, font->GetStyle()->weight will just give the same
+ // number as getComputedStyle(). fontEntry->Weight() will give the weight
+ // of the font face used.
+ gfxFontEntry *fontEntry = font->GetFontEntry();
+ return fontEntry->Weight();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/build/valgrind/i386-redhat-linux-gnu.sup b/build/valgrind/i386-redhat-linux-gnu.sup
index c1d39cd244..cfdc37bb00 100644
--- a/build/valgrind/i386-redhat-linux-gnu.sup
+++ b/build/valgrind/i386-redhat-linux-gnu.sup
@@ -19,16 +19,6 @@
...
}
{
- Bug 793600
- Memcheck:Leak
- fun:realloc
- obj:/usr/lib/libfontconfig.so.1.4.4
- ...
- fun:FcDefaultSubstitute
- fun:_ZN17gfxPangoFontGroup11MakeFontSetEP14_PangoLanguagedP9nsAutoRefI10_FcPatternE
- ...
-}
-{
Bug 794366
Memcheck:Leak
...
diff --git a/build/valgrind/x86_64-redhat-linux-gnu.sup b/build/valgrind/x86_64-redhat-linux-gnu.sup
index 28656e4180..6bc40289a4 100644
--- a/build/valgrind/x86_64-redhat-linux-gnu.sup
+++ b/build/valgrind/x86_64-redhat-linux-gnu.sup
@@ -18,16 +18,6 @@
obj:/lib64/libdbus-1.so.3.4.0
...
}
-{
- Bug 793600
- Memcheck:Leak
- fun:realloc
- obj:/usr/lib64/libfontconfig.so.1.4.4
- ...
- fun:FcDefaultSubstitute
- fun:_ZN17gfxPangoFontGroup11MakeFontSetEP14_PangoLanguagedP9nsAutoRefI10_FcPatternE
- ...
-}
# Fontconfig is going fancy with its cache structure and that confuses valgrind.
# https://bugs.freedesktop.org/show_bug.cgi?id=8215
# https://bugs.freedesktop.org/show_bug.cgi?id=8428
diff --git a/gfx/thebes/gfxFontconfigFonts.cpp b/gfx/thebes/gfxFontconfigFonts.cpp
deleted file mode 100644
index 9caecc4c07..0000000000
--- a/gfx/thebes/gfxFontconfigFonts.cpp
+++ /dev/null
@@ -1,2255 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "prlink.h"
-#include "gfxTypes.h"
-
-#include "nsTArray.h"
-
-#include "gfxContext.h"
-#ifdef MOZ_WIDGET_GTK
-#include "gfxPlatformGtk.h"
-#endif
-#include "gfxFontconfigFonts.h"
-#include "gfxFT2FontBase.h"
-#include "gfxFT2Utils.h"
-#include "harfbuzz/hb.h"
-#include "harfbuzz/hb-glib.h"
-#include "harfbuzz/hb-ot.h"
-#include "nsUnicodeProperties.h"
-#include "nsUnicodeScriptCodes.h"
-#include "gfxFontconfigUtils.h"
-#include "gfxUserFontSet.h"
-#include "gfxFontConstants.h"
-#include "nsGkAtoms.h"
-#include "nsILanguageAtomService.h"
-#include "nsServiceManagerUtils.h"
-
-#include <cairo.h>
-#include <cairo-ft.h>
-#include "mozilla/gfx/HelpersCairo.h"
-
-#include <fontconfig/fcfreetype.h>
-#include <pango/pango.h>
-
-#include FT_TRUETYPE_TABLES_H
-
-#ifdef MOZ_WIDGET_GTK
-#include <gdk/gdk.h>
-#endif
-
-#include <math.h>
-
-using namespace mozilla;
-using namespace mozilla::unicode;
-
-#define PRINTING_FC_PROPERTY "gfx.printing"
-
-static PangoLanguage *GuessPangoLanguage(nsIAtom *aLanguage);
-
-static cairo_scaled_font_t *
-CreateScaledFont(FcPattern *aPattern, cairo_font_face_t *aFace);
-
-static FT_Library gFTLibrary;
-
-// FC_FAMILYLANG and FC_FULLNAME were introduced in fontconfig-2.2.97
-// and so fontconfig-2.3.0 (2005).
-#ifndef FC_FAMILYLANG
-#define FC_FAMILYLANG "familylang"
-#endif
-#ifndef FC_FULLNAME
-#define FC_FULLNAME "fullname"
-#endif
-
-static PRFuncPtr
-FindFunctionSymbol(const char *name)
-{
- PRLibrary *lib = nullptr;
- PRFuncPtr result = PR_FindFunctionSymbolAndLibrary(name, &lib);
- if (lib) {
- PR_UnloadLibrary(lib);
- }
-
- return result;
-}
-
-static bool HasChar(FcPattern *aFont, FcChar32 wc)
-{
- FcCharSet *charset = nullptr;
- FcPatternGetCharSet(aFont, FC_CHARSET, 0, &charset);
-
- return charset && FcCharSetHasChar(charset, wc);
-}
-
-/**
- * gfxFcFontEntry:
- *
- * An abstract base class of for gfxFontEntry implementations used by
- * gfxFcFont and gfxUserFontSet.
- */
-
-class gfxFcFontEntry : public gfxFontEntry {
-public:
- // For all FontEntrys attached to gfxFcFonts, there will be only one
- // pattern in this array. This is always a font pattern, not a fully
- // resolved pattern. gfxFcFont only uses this to construct a PangoFont.
- //
- // FontEntrys for src:local() fonts in gfxUserFontSet may return more than
- // one pattern. (See comment in gfxUserFcFontEntry.)
- const nsTArray< nsCountedRef<FcPattern> >& GetPatterns()
- {
- return mPatterns;
- }
-
- static gfxFcFontEntry *LookupFontEntry(cairo_font_face_t *aFace)
- {
- return static_cast<gfxFcFontEntry*>
- (cairo_font_face_get_user_data(aFace, &sFontEntryKey));
- }
-
- // override the gfxFontEntry impl to read the name from fontconfig
- // instead of trying to get the 'name' table, as we don't implement
- // GetFontTable() here
- virtual nsString RealFaceName();
-
- // This is needed to make gfxFontEntry::HasCharacter(aCh) work.
- virtual bool TestCharacterMap(uint32_t aCh)
- {
- for (uint32_t i = 0; i < mPatterns.Length(); ++i) {
- if (HasChar(mPatterns[i], aCh)) {
- return true;
- }
- }
- return false;
- }
-
-protected:
- explicit gfxFcFontEntry(const nsAString& aName)
- : gfxFontEntry(aName)
- {
- }
-
- // One pattern is the common case and some subclasses rely on successful
- // addition of the first element to the array.
- AutoTArray<nsCountedRef<FcPattern>,1> mPatterns;
-
- static cairo_user_data_key_t sFontEntryKey;
-};
-
-cairo_user_data_key_t gfxFcFontEntry::sFontEntryKey;
-
-nsString
-gfxFcFontEntry::RealFaceName()
-{
- FcChar8 *name;
- if (!mPatterns.IsEmpty()) {
- if (FcPatternGetString(mPatterns[0],
- FC_FULLNAME, 0, &name) == FcResultMatch) {
- return NS_ConvertUTF8toUTF16((const char*)name);
- }
- if (FcPatternGetString(mPatterns[0],
- FC_FAMILY, 0, &name) == FcResultMatch) {
- NS_ConvertUTF8toUTF16 result((const char*)name);
- if (FcPatternGetString(mPatterns[0],
- FC_STYLE, 0, &name) == FcResultMatch) {
- result.Append(' ');
- AppendUTF8toUTF16((const char*)name, result);
- }
- return result;
- }
- }
- // fall back to gfxFontEntry implementation (only works for sfnt fonts)
- return gfxFontEntry::RealFaceName();
-}
-
-/**
- * gfxSystemFcFontEntry:
- *
- * An implementation of gfxFcFontEntry used by gfxFcFonts for system fonts,
- * including those from regular family-name based font selection as well as
- * those from src:local().
- *
- * All gfxFcFonts using the same cairo_font_face_t share the same FontEntry.
- */
-
-class gfxSystemFcFontEntry : public gfxFcFontEntry {
-public:
- // For memory efficiency, aFontPattern should be a font pattern,
- // not a fully resolved pattern.
- gfxSystemFcFontEntry(cairo_font_face_t *aFontFace,
- FcPattern *aFontPattern,
- const nsAString& aName)
- : gfxFcFontEntry(aName), mFontFace(aFontFace),
- mFTFace(nullptr), mFTFaceInitialized(false)
- {
- cairo_font_face_reference(mFontFace);
- cairo_font_face_set_user_data(mFontFace, &sFontEntryKey, this, nullptr);
-
- // mPatterns is an AutoTArray with 1 space always available, so the
- // AppendElement always succeeds.
- // FIXME: Make this infallible after bug 968520 is done.
- MOZ_ALWAYS_TRUE(mPatterns.AppendElement(fallible));
- mPatterns[0] = aFontPattern;
-
- FcChar8 *name;
- if (FcPatternGetString(aFontPattern,
- FC_FAMILY, 0, &name) == FcResultMatch) {
- mFamilyName = NS_ConvertUTF8toUTF16((const char*)name);
- }
- }
-
- ~gfxSystemFcFontEntry()
- {
- cairo_font_face_set_user_data(mFontFace,
- &sFontEntryKey,
- nullptr,
- nullptr);
- cairo_font_face_destroy(mFontFace);
- }
-
- virtual void ForgetHBFace() override;
- virtual void ReleaseGrFace(gr_face* aFace) override;
-
-protected:
- virtual nsresult
- CopyFontTable(uint32_t aTableTag, nsTArray<uint8_t>& aBuffer) override;
-
- void MaybeReleaseFTFace();
-
-private:
- cairo_font_face_t *mFontFace;
- FT_Face mFTFace;
- bool mFTFaceInitialized;
-};
-
-nsresult
-gfxSystemFcFontEntry::CopyFontTable(uint32_t aTableTag,
- nsTArray<uint8_t>& aBuffer)
-{
- if (!mFTFaceInitialized) {
- mFTFaceInitialized = true;
- FcChar8 *filename;
- if (FcPatternGetString(mPatterns[0], FC_FILE, 0, &filename) != FcResultMatch) {
- return NS_ERROR_FAILURE;
- }
- int index;
- if (FcPatternGetInteger(mPatterns[0], FC_INDEX, 0, &index) != FcResultMatch) {
- index = 0; // default to 0 if not found in pattern
- }
- if (FT_New_Face(gfxPangoFontGroup::GetFTLibrary(),
- (const char*)filename, index, &mFTFace) != 0) {
- return NS_ERROR_FAILURE;
- }
- }
-
- if (!mFTFace) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- FT_ULong length = 0;
- if (FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, nullptr, &length) != 0) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- if (!aBuffer.SetLength(length, fallible)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- if (FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, aBuffer.Elements(), &length) != 0) {
- aBuffer.Clear();
- return NS_ERROR_FAILURE;
- }
-
- return NS_OK;
-}
-
-void
-gfxSystemFcFontEntry::MaybeReleaseFTFace()
-{
- // don't release if either HB or Gr face still exists
- if (mHBFace || mGrFace) {
- return;
- }
- if (mFTFace) {
- FT_Done_Face(mFTFace);
- mFTFace = nullptr;
- }
- mFTFaceInitialized = false;
-}
-
-void
-gfxSystemFcFontEntry::ForgetHBFace()
-{
- gfxFontEntry::ForgetHBFace();
- MaybeReleaseFTFace();
-}
-
-void
-gfxSystemFcFontEntry::ReleaseGrFace(gr_face* aFace)
-{
- gfxFontEntry::ReleaseGrFace(aFace);
- MaybeReleaseFTFace();
-}
-
-// A namespace for @font-face family names in FcPatterns so that fontconfig
-// aliases do not pick up families from @font-face rules and so that
-// fontconfig rules can distinguish between web fonts and platform fonts.
-// http://lists.freedesktop.org/archives/fontconfig/2008-November/003037.html
-#define FONT_FACE_FAMILY_PREFIX "@font-face:"
-
-/**
- * gfxUserFcFontEntry:
- *
- * An abstract class for objects in a gfxUserFontSet that can provide
- * FcPattern* handles to fonts.
- *
- * Separate implementations of this class support local fonts from src:local()
- * and web fonts from src:url().
- */
-
-// There is a one-to-one correspondence between gfxUserFcFontEntry objects and
-// @font-face rules, but sometimes a one-to-many correspondence between font
-// entries and font patterns.
-//
-// http://www.w3.org/TR/2002/WD-css3-webfonts-20020802#font-descriptions
-// provided a font-size descriptor to specify the sizes supported by the face,
-// but the "Editor's Draft 27 June 2008"
-// http://dev.w3.org/csswg/css3-fonts/#font-resources does not provide such a
-// descriptor, and Mozilla does not recognize such a descriptor.
-//
-// Font face names used in src:local() also do not usually specify a size.
-//
-// PCF format fonts have each size in a different file, and each of these
-// files is referenced by its own pattern, but really these are each
-// different sizes of one face with one name.
-//
-// Multiple patterns in an entry also effectively deals with a set of
-// PostScript Type 1 font files that all have the same face name but are in
-// several files because of the limit on the number of glyphs in a Type 1 font
-// file. (e.g. Computer Modern.)
-
-class gfxUserFcFontEntry : public gfxFcFontEntry {
-protected:
- explicit gfxUserFcFontEntry(const nsAString& aFontName,
- uint16_t aWeight,
- int16_t aStretch,
- uint8_t aStyle)
- : gfxFcFontEntry(aFontName)
- {
- mStyle = aStyle;
- mWeight = aWeight;
- mStretch = aStretch;
- }
-
- // Helper function to change a pattern so that it matches the CSS style
- // descriptors and so gets properly sorted in font selection. This also
- // avoids synthetic style effects being added by the renderer when the
- // style of the font itself does not match the descriptor provided by the
- // author.
- void AdjustPatternToCSS(FcPattern *aPattern);
-};
-
-void
-gfxUserFcFontEntry::AdjustPatternToCSS(FcPattern *aPattern)
-{
- int fontWeight = -1;
- FcPatternGetInteger(aPattern, FC_WEIGHT, 0, &fontWeight);
- int cssWeight = gfxFontconfigUtils::FcWeightForBaseWeight(mWeight / 100);
- if (cssWeight != fontWeight) {
- FcPatternDel(aPattern, FC_WEIGHT);
- FcPatternAddInteger(aPattern, FC_WEIGHT, cssWeight);
- }
-
- int fontSlant;
- FcResult res = FcPatternGetInteger(aPattern, FC_SLANT, 0, &fontSlant);
- // gfxFontEntry doesn't understand the difference between oblique
- // and italic.
- if (res != FcResultMatch ||
- IsItalic() != (fontSlant != FC_SLANT_ROMAN)) {
- FcPatternDel(aPattern, FC_SLANT);
- FcPatternAddInteger(aPattern, FC_SLANT,
- IsItalic() ? FC_SLANT_OBLIQUE : FC_SLANT_ROMAN);
- }
-
- int fontWidth = -1;
- FcPatternGetInteger(aPattern, FC_WIDTH, 0, &fontWidth);
- int cssWidth = gfxFontconfigUtils::FcWidthForThebesStretch(mStretch);
- if (cssWidth != fontWidth) {
- FcPatternDel(aPattern, FC_WIDTH);
- FcPatternAddInteger(aPattern, FC_WIDTH, cssWidth);
- }
-
- // Ensure that there is a fullname property (if there is a family
- // property) so that fontconfig rules can identify the real name of the
- // font, because the family property will be replaced.
- FcChar8 *unused;
- if (FcPatternGetString(aPattern,
- FC_FULLNAME, 0, &unused) == FcResultNoMatch) {
- nsAutoCString fullname;
- if (gfxFontconfigUtils::GetFullnameFromFamilyAndStyle(aPattern,
- &fullname)) {
- FcPatternAddString(aPattern, FC_FULLNAME,
- gfxFontconfigUtils::ToFcChar8(fullname));
- }
- }
-
- nsAutoCString family;
- family.Append(FONT_FACE_FAMILY_PREFIX);
- AppendUTF16toUTF8(Name(), family);
-
- FcPatternDel(aPattern, FC_FAMILY);
- FcPatternDel(aPattern, FC_FAMILYLANG);
- FcPatternAddString(aPattern, FC_FAMILY,
- gfxFontconfigUtils::ToFcChar8(family));
-}
-
-/**
- * gfxLocalFcFontEntry:
- *
- * An implementation of gfxUserFcFontEntry for local fonts from src:local().
- *
- * This class is used only in gfxUserFontSet and for providing FcPattern*
- * handles to system fonts for font selection. gfxFcFonts created from these
- * patterns will use gfxSystemFcFontEntrys, which may be shared with
- * gfxFcFonts from regular family-name based font selection.
- */
-
-class gfxLocalFcFontEntry : public gfxUserFcFontEntry {
-public:
- gfxLocalFcFontEntry(const nsAString& aFontName,
- uint16_t aWeight,
- int16_t aStretch,
- uint8_t aStyle,
- const nsTArray< nsCountedRef<FcPattern> >& aPatterns)
- : gfxUserFcFontEntry(aFontName, aWeight, aStretch, aStyle)
- {
- if (!mPatterns.SetCapacity(aPatterns.Length(), fallible))
- return; // OOM
-
- for (uint32_t i = 0; i < aPatterns.Length(); ++i) {
- FcPattern *pattern = FcPatternDuplicate(aPatterns.ElementAt(i));
- if (!pattern)
- return; // OOM
-
- AdjustPatternToCSS(pattern);
-
- // FIXME: Make this infallible after bug 968520 is done.
- MOZ_ALWAYS_TRUE(mPatterns.AppendElement(fallible));
- mPatterns[i].own(pattern);
- }
- mIsLocalUserFont = true;
- }
-};
-
-/**
- * gfxDownloadedFcFontEntry:
- *
- * An implementation of gfxFcFontEntry for web fonts from src:url().
- *
- * When a cairo_font_face_t is created for these fonts, the cairo_font_face_t
- * keeps a reference to the FontEntry to keep the font data alive.
- */
-
-class gfxDownloadedFcFontEntry : public gfxUserFcFontEntry {
-public:
- // This takes ownership of the face and its underlying data
- gfxDownloadedFcFontEntry(const nsAString& aFontName,
- uint16_t aWeight,
- int16_t aStretch,
- uint8_t aStyle,
- const uint8_t *aData, FT_Face aFace)
- : gfxUserFcFontEntry(aFontName, aWeight, aStretch, aStyle),
- mFontData(aData), mFace(aFace)
- {
- NS_PRECONDITION(aFace != nullptr, "aFace is NULL!");
- mIsDataUserFont = true;
- InitPattern();
- }
-
- virtual ~gfxDownloadedFcFontEntry();
-
- // Returns true on success
- bool SetCairoFace(cairo_font_face_t *aFace);
-
- virtual hb_blob_t* GetFontTable(uint32_t aTableTag) override;
-
-protected:
- void InitPattern();
-
- // mFontData holds the data used to instantiate the FT_Face;
- // this has to persist until we are finished with the face,
- // then be released with free().
- const uint8_t* mFontData;
-
- FT_Face mFace;
-};
-
-// A property for recording gfxDownloadedFcFontEntrys on FcPatterns.
-static const char *kFontEntryFcProp = "-moz-font-entry";
-
-static FcBool AddDownloadedFontEntry(FcPattern *aPattern,
- gfxDownloadedFcFontEntry *aFontEntry)
-{
- FcValue value;
- value.type = FcTypeFTFace; // void* field of union
- value.u.f = aFontEntry;
-
- return FcPatternAdd(aPattern, kFontEntryFcProp, value, FcFalse);
-}
-
-static FcBool DelDownloadedFontEntry(FcPattern *aPattern)
-{
- return FcPatternDel(aPattern, kFontEntryFcProp);
-}
-
-static gfxDownloadedFcFontEntry *GetDownloadedFontEntry(FcPattern *aPattern)
-{
- FcValue value;
- if (FcPatternGet(aPattern, kFontEntryFcProp, 0, &value) != FcResultMatch)
- return nullptr;
-
- if (value.type != FcTypeFTFace) {
- NS_NOTREACHED("Wrong type for -moz-font-entry font property");
- return nullptr;
- }
-
- return static_cast<gfxDownloadedFcFontEntry*>(value.u.f);
-}
-
-gfxDownloadedFcFontEntry::~gfxDownloadedFcFontEntry()
-{
- if (mPatterns.Length() != 0) {
- // Remove back reference to this font entry and the face in case
- // anyone holds a reference to the pattern.
- NS_ASSERTION(mPatterns.Length() == 1,
- "More than one pattern in gfxDownloadedFcFontEntry!");
- DelDownloadedFontEntry(mPatterns[0]);
- FcPatternDel(mPatterns[0], FC_FT_FACE);
- }
- FT_Done_Face(mFace);
- free((void*)mFontData);
-}
-
-typedef FcPattern* (*QueryFaceFunction)(const FT_Face face,
- const FcChar8 *file, int id,
- FcBlanks *blanks);
-
-void
-gfxDownloadedFcFontEntry::InitPattern()
-{
- static QueryFaceFunction sQueryFacePtr =
- reinterpret_cast<QueryFaceFunction>
- (FindFunctionSymbol("FcFreeTypeQueryFace"));
- FcPattern *pattern;
-
- // FcFreeTypeQueryFace is the same function used to construct patterns for
- // system fonts and so is the preferred function to use for this purpose.
- // This will set up the langset property, which helps with sorting, and
- // the foundry, fullname, and fontversion properties, which properly
- // identify the font to fontconfig rules. However, FcFreeTypeQueryFace is
- // available only from fontconfig-2.4.2 (December 2006). (CentOS 5.0 has
- // fontconfig-2.4.1.)
- if (sQueryFacePtr) {
- // The "file" argument cannot be nullptr (in fontconfig-2.6.0 at
- // least). The dummy file passed here is removed below.
- //
- // When fontconfig scans the system fonts, FcConfigGetBlanks(nullptr)
- // is passed as the "blanks" argument, which provides that unexpectedly
- // blank glyphs are elided. Here, however, we pass nullptr for
- // "blanks", effectively assuming that, if the font has a blank glyph,
- // then the author intends any associated character to be rendered
- // blank.
- pattern =
- (*sQueryFacePtr)(mFace,
- gfxFontconfigUtils::ToFcChar8(""),
- 0,
- nullptr);
- if (!pattern)
- // Either OOM, or fontconfig chose to skip this font because it
- // has "no encoded characters", which I think means "BDF and PCF
- // fonts which are not in Unicode (or the effectively equivalent
- // ISO Latin-1) encoding".
- return;
-
- // These properties don't make sense for this face without a file.
- FcPatternDel(pattern, FC_FILE);
- FcPatternDel(pattern, FC_INDEX);
-
- } else {
- // Do the minimum necessary to construct a pattern for sorting.
-
- // FC_CHARSET is vital to determine which characters are supported.
- nsAutoRef<FcCharSet> charset(FcFreeTypeCharSet(mFace, nullptr));
- // If there are no characters then assume we don't know how to read
- // this font.
- if (!charset || FcCharSetCount(charset) == 0)
- return;
-
- pattern = FcPatternCreate();
- FcPatternAddCharSet(pattern, FC_CHARSET, charset);
-
- // FC_PIXEL_SIZE can be important for font selection of fixed-size
- // fonts.
- if (!(mFace->face_flags & FT_FACE_FLAG_SCALABLE)) {
- for (FT_Int i = 0; i < mFace->num_fixed_sizes; ++i) {
-#if HAVE_FT_BITMAP_SIZE_Y_PPEM
- double size = FLOAT_FROM_26_6(mFace->available_sizes[i].y_ppem);
-#else
- double size = mFace->available_sizes[i].height;
-#endif
- FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
- }
-
- // Not sure whether this is important;
- // imitating FcFreeTypeQueryFace:
- FcPatternAddBool (pattern, FC_ANTIALIAS, FcFalse);
- }
-
- // Setting up the FC_LANGSET property is very difficult with the APIs
- // available prior to FcFreeTypeQueryFace. Having no FC_LANGSET
- // property seems better than having a property with an empty LangSet.
- // With no FC_LANGSET property, fontconfig sort functions will
- // consider this face to have the same priority as (otherwise equal)
- // faces that have support for the primary requested language, but
- // will not consider any language to have been satisfied (and so will
- // continue to look for a face with language support in fallback
- // fonts).
- }
-
- AdjustPatternToCSS(pattern);
-
- FcPatternAddFTFace(pattern, FC_FT_FACE, mFace);
- AddDownloadedFontEntry(pattern, this);
-
- // There is never more than one pattern
- // FIXME: Make this infallible after bug 968520 is done.
- MOZ_ALWAYS_TRUE(mPatterns.AppendElement(fallible));
- mPatterns[0].own(pattern);
-}
-
-static void ReleaseDownloadedFontEntry(void *data)
-{
- gfxDownloadedFcFontEntry *downloadedFontEntry =
- static_cast<gfxDownloadedFcFontEntry*>(data);
- NS_RELEASE(downloadedFontEntry);
-}
-
-bool gfxDownloadedFcFontEntry::SetCairoFace(cairo_font_face_t *aFace)
-{
- if (CAIRO_STATUS_SUCCESS !=
- cairo_font_face_set_user_data(aFace, &sFontEntryKey, this,
- ReleaseDownloadedFontEntry))
- return false;
-
- // Hold a reference to this font entry to keep the font face data.
- NS_ADDREF(this);
- return true;
-}
-
-hb_blob_t *
-gfxDownloadedFcFontEntry::GetFontTable(uint32_t aTableTag)
-{
- // The entry already owns the (sanitized) sfnt data in mFontData,
- // so we can just return a blob that "wraps" the appropriate chunk of it.
- // The blob should not attempt to free its data, as the entire sfnt data
- // will be freed when the font entry is deleted.
- return gfxFontUtils::GetTableFromFontData(mFontData, aTableTag);
-}
-
-/*
- * gfxFcFont
- *
- * This is a gfxFont implementation using a CAIRO_FONT_TYPE_FT
- * cairo_scaled_font created from an FcPattern.
- */
-
-class gfxFcFont : public gfxFontconfigFontBase {
-public:
- virtual ~gfxFcFont();
- static already_AddRefed<gfxFcFont>
- GetOrMakeFont(FcPattern *aRequestedPattern, FcPattern *aFontPattern,
- const gfxFontStyle *aFontStyle);
-
- // return a cloned font resized and offset to simulate sub/superscript glyphs
- virtual already_AddRefed<gfxFont>
- GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel) override;
-
-protected:
- virtual already_AddRefed<gfxFont> MakeScaledFont(gfxFontStyle *aFontStyle,
- gfxFloat aFontScale);
- virtual already_AddRefed<gfxFont> GetSmallCapsFont() override;
-
-private:
- gfxFcFont(cairo_scaled_font_t *aCairoFont,
- FcPattern *aPattern,
- gfxFcFontEntry *aFontEntry,
- const gfxFontStyle *aFontStyle);
-
- // key for locating a gfxFcFont corresponding to a cairo_scaled_font
- static cairo_user_data_key_t sGfxFontKey;
-};
-
-/**
- * gfxFcFontSet:
- *
- * Translation from a desired FcPattern to a sorted set of font references
- * (fontconfig cache data) and (when needed) fonts.
- */
-
-class gfxFcFontSet final {
-public:
- NS_INLINE_DECL_REFCOUNTING(gfxFcFontSet)
-
- explicit gfxFcFontSet(FcPattern *aPattern,
- gfxUserFontSet *aUserFontSet)
- : mSortPattern(aPattern), mUserFontSet(aUserFontSet),
- mFcFontsTrimmed(0),
- mHaveFallbackFonts(false)
- {
- bool waitForUserFont;
- mFcFontSet = SortPreferredFonts(waitForUserFont);
- mWaitingForUserFont = waitForUserFont;
- }
-
- // A reference is held by the FontSet.
- // The caller may add a ref to keep the font alive longer than the FontSet.
- gfxFcFont *GetFontAt(uint32_t i, const gfxFontStyle *aFontStyle)
- {
- if (i >= mFonts.Length() || !mFonts[i].mFont) {
- // GetFontPatternAt sets up mFonts
- FcPattern *fontPattern = GetFontPatternAt(i);
- if (!fontPattern)
- return nullptr;
-
- mFonts[i].mFont =
- gfxFcFont::GetOrMakeFont(mSortPattern, fontPattern,
- aFontStyle);
- }
- return mFonts[i].mFont;
- }
-
- FcPattern *GetFontPatternAt(uint32_t i);
-
- bool WaitingForUserFont() const {
- return mWaitingForUserFont;
- }
-
-private:
- // Private destructor, to discourage deletion outside of Release():
- ~gfxFcFontSet()
- {
- }
-
- nsReturnRef<FcFontSet> SortPreferredFonts(bool& aWaitForUserFont);
- nsReturnRef<FcFontSet> SortFallbackFonts();
-
- struct FontEntry {
- explicit FontEntry(FcPattern *aPattern) : mPattern(aPattern) {}
- nsCountedRef<FcPattern> mPattern;
- RefPtr<gfxFcFont> mFont;
- };
-
- struct LangSupportEntry {
- LangSupportEntry(FcChar8 *aLang, FcLangResult aSupport) :
- mLang(aLang), mBestSupport(aSupport) {}
- FcChar8 *mLang;
- FcLangResult mBestSupport;
- };
-
-public:
- // public for nsTArray
- class LangComparator {
- public:
- bool Equals(const LangSupportEntry& a, const FcChar8 *b) const
- {
- return FcStrCmpIgnoreCase(a.mLang, b) == 0;
- }
- };
-
-private:
- // The requested pattern
- nsCountedRef<FcPattern> mSortPattern;
- // Fonts from @font-face rules
- RefPtr<gfxUserFontSet> mUserFontSet;
- // A (trimmed) list of font patterns and fonts that is built up as
- // required.
- nsTArray<FontEntry> mFonts;
- // Holds a list of font patterns that will be trimmed. This is first set
- // to a list of preferred fonts. Then, if/when all the preferred fonts
- // have been trimmed and added to mFonts, this is set to a list of
- // fallback fonts.
- nsAutoRef<FcFontSet> mFcFontSet;
- // The set of characters supported by the fonts in mFonts.
- nsAutoRef<FcCharSet> mCharSet;
- // The index of the next font in mFcFontSet that has not yet been
- // considered for mFonts.
- int mFcFontsTrimmed;
- // True iff fallback fonts are either stored in mFcFontSet or have been
- // trimmed and added to mFonts (so that mFcFontSet is nullptr).
- bool mHaveFallbackFonts;
- // True iff there was a user font set with pending downloads,
- // so the set may be updated when downloads complete
- bool mWaitingForUserFont;
-};
-
-// Find the FcPattern for an @font-face font suitable for CSS family |aFamily|
-// and style |aStyle| properties.
-static const nsTArray< nsCountedRef<FcPattern> >*
-FindFontPatterns(gfxUserFontSet *mUserFontSet,
- const nsACString &aFamily, uint8_t aStyle,
- uint16_t aWeight, int16_t aStretch,
- bool& aWaitForUserFont)
-{
- // Convert to UTF16
- NS_ConvertUTF8toUTF16 utf16Family(aFamily);
-
- // needsBold is not used here. Instead synthetic bold is enabled through
- // FcFontRenderPrepare when the weight in the requested pattern is
- // compared against the weight in the font pattern.
- bool needsBold;
-
- gfxFontStyle style;
- style.style = aStyle;
- style.weight = aWeight;
- style.stretch = aStretch;
-
- gfxUserFcFontEntry *fontEntry = nullptr;
- gfxFontFamily *family = mUserFontSet->LookupFamily(utf16Family);
- if (family) {
- gfxUserFontEntry* userFontEntry =
- mUserFontSet->FindUserFontEntryAndLoad(family, style, needsBold,
- aWaitForUserFont);
- if (userFontEntry) {
- fontEntry = static_cast<gfxUserFcFontEntry*>
- (userFontEntry->GetPlatformFontEntry());
- }
-
- // Accept synthetic oblique for italic and oblique.
- // xxx - this isn't really ideal behavior, for docs that only use a
- // single italic face it will also pull down the normal face
- // and probably never use it
- if (!fontEntry && aStyle != NS_FONT_STYLE_NORMAL) {
- style.style = NS_FONT_STYLE_NORMAL;
- userFontEntry =
- mUserFontSet->FindUserFontEntryAndLoad(family, style,
- needsBold,
- aWaitForUserFont);
- if (userFontEntry) {
- fontEntry = static_cast<gfxUserFcFontEntry*>
- (userFontEntry->GetPlatformFontEntry());
- }
- }
- }
-
- if (!fontEntry) {
- return nullptr;
- }
-
- return &fontEntry->GetPatterns();
-}
-
-typedef FcBool (*FcPatternRemoveFunction)(FcPattern *p, const char *object,
- int id);
-
-// FcPatternRemove is available in fontconfig-2.3.0 (2005)
-static FcBool
-moz_FcPatternRemove(FcPattern *p, const char *object, int id)
-{
- static FcPatternRemoveFunction sFcPatternRemovePtr =
- reinterpret_cast<FcPatternRemoveFunction>
- (FindFunctionSymbol("FcPatternRemove"));
-
- if (!sFcPatternRemovePtr)
- return FcFalse;
-
- return (*sFcPatternRemovePtr)(p, object, id);
-}
-
-// fontconfig prefers a matching family or lang to pixelsize of bitmap
-// fonts. CSS suggests a tolerance of 20% on pixelsize.
-static bool
-SizeIsAcceptable(FcPattern *aFont, double aRequestedSize)
-{
- double size;
- int v = 0;
- while (FcPatternGetDouble(aFont,
- FC_PIXEL_SIZE, v, &size) == FcResultMatch) {
- ++v;
- if (5.0 * fabs(size - aRequestedSize) < aRequestedSize)
- return true;
- }
-
- // No size means scalable
- return v == 0;
-}
-
-// Sorting only the preferred fonts first usually saves having to sort through
-// every font on the system.
-nsReturnRef<FcFontSet>
-gfxFcFontSet::SortPreferredFonts(bool &aWaitForUserFont)
-{
- aWaitForUserFont = false;
-
- gfxFontconfigUtils *utils = gfxFontconfigUtils::GetFontconfigUtils();
- if (!utils)
- return nsReturnRef<FcFontSet>();
-
- // The list of families in mSortPattern has values with both weak and
- // strong bindings. Values with strong bindings should be preferred.
- // Values with weak bindings are default fonts that should be considered
- // only when the font provides the best support for a requested language
- // or after other fonts have satisfied all the requested languages.
- //
- // There are no direct fontconfig APIs to get the binding type. The
- // binding only takes effect in the sort and match functions.
-
- // |requiredLangs| is a list of requested languages that have not yet been
- // satisfied. gfxFontconfigUtils only sets one FC_LANG property value,
- // but FcConfigSubstitute may add more values (e.g. prepending "en" to
- // "ja" will use western fonts to render Latin/Arabic numerals in Japanese
- // text.)
- AutoTArray<LangSupportEntry,10> requiredLangs;
- for (int v = 0; ; ++v) {
- FcChar8 *lang;
- FcResult result = FcPatternGetString(mSortPattern, FC_LANG, v, &lang);
- if (result != FcResultMatch) {
- // No need to check FcPatternGetLangSet() because
- // gfxFontconfigUtils sets only a string value for FC_LANG and
- // FcConfigSubstitute cannot add LangSets.
- NS_ASSERTION(result != FcResultTypeMismatch,
- "Expected a string for FC_LANG");
- break;
- }
-
- if (!requiredLangs.Contains(lang, LangComparator())) {
- FcLangResult bestLangSupport = utils->GetBestLangSupport(lang);
- if (bestLangSupport != FcLangDifferentLang) {
- requiredLangs.
- AppendElement(LangSupportEntry(lang, bestLangSupport));
- }
- }
- }
-
- nsAutoRef<FcFontSet> fontSet(FcFontSetCreate());
- if (!fontSet)
- return fontSet.out();
-
- // FcDefaultSubstitute() ensures a slant on mSortPattern, but, if that ever
- // doesn't happen, Roman will be used.
- int requestedSlant = FC_SLANT_ROMAN;
- FcPatternGetInteger(mSortPattern, FC_SLANT, 0, &requestedSlant);
- double requestedSize = -1.0;
- FcPatternGetDouble(mSortPattern, FC_PIXEL_SIZE, 0, &requestedSize);
-
- nsTHashtable<gfxFontconfigUtils::DepFcStrEntry> existingFamilies(32);
- FcChar8 *family;
- for (int v = 0;
- FcPatternGetString(mSortPattern,
- FC_FAMILY, v, &family) == FcResultMatch; ++v) {
- const nsTArray< nsCountedRef<FcPattern> > *familyFonts = nullptr;
-
- // Is this an @font-face family?
- bool isUserFont = false;
- if (mUserFontSet) {
- // Have some @font-face definitions
-
- nsDependentCString cFamily(gfxFontconfigUtils::ToCString(family));
- NS_NAMED_LITERAL_CSTRING(userPrefix, FONT_FACE_FAMILY_PREFIX);
-
- if (StringBeginsWith(cFamily, userPrefix)) {
- isUserFont = true;
-
- // Trim off the prefix
- nsDependentCSubstring cssFamily(cFamily, userPrefix.Length());
-
- uint8_t thebesStyle =
- gfxFontconfigUtils::FcSlantToThebesStyle(requestedSlant);
- uint16_t thebesWeight =
- gfxFontconfigUtils::GetThebesWeight(mSortPattern);
- int16_t thebesStretch =
- gfxFontconfigUtils::GetThebesStretch(mSortPattern);
-
- bool waitForUserFont;
- familyFonts = FindFontPatterns(mUserFontSet, cssFamily,
- thebesStyle,
- thebesWeight, thebesStretch,
- waitForUserFont);
- if (waitForUserFont) {
- aWaitForUserFont = true;
- }
- }
- }
-
- if (!isUserFont) {
- familyFonts = &utils->GetFontsForFamily(family);
- }
-
- if (!familyFonts || familyFonts->Length() == 0) {
- // There are no fonts matching this family, so there is no point
- // in searching for this family in the FontSort.
- //
- // Perhaps the original pattern should be retained for
- // FcFontRenderPrepare. However, the only a useful config
- // substitution test against missing families that i can imagine
- // would only be interested in the preferred family
- // (qual="first"), so always keep the first family and use the
- // same pattern for Sort and RenderPrepare.
- if (v != 0 && moz_FcPatternRemove(mSortPattern, FC_FAMILY, v)) {
- --v;
- }
- continue;
- }
-
- // Aliases seem to often end up occurring more than once, but
- // duplicate families can't be removed from the sort pattern without
- // knowing whether duplicates have the same binding.
- gfxFontconfigUtils::DepFcStrEntry *familyEntry =
- existingFamilies.PutEntry(family);
- if (familyEntry) {
- if (familyEntry->mKey) // old entry
- continue;
-
- familyEntry->mKey = family; // initialize new entry
- }
-
- for (uint32_t f = 0; f < familyFonts->Length(); ++f) {
- FcPattern *font = familyFonts->ElementAt(f);
-
- // Fix up the family name of user-font patterns, as the same
- // font entry may be used (via the UserFontCache) for multiple
- // CSS family names
- if (isUserFont) {
- font = FcPatternDuplicate(font);
- FcPatternDel(font, FC_FAMILY);
- FcPatternAddString(font, FC_FAMILY, family);
- }
-
- // User fonts are already filtered by slant (but not size) in
- // mUserFontSet->FindUserFontEntry().
- if (requestedSize != -1.0 && !SizeIsAcceptable(font, requestedSize))
- continue;
-
- for (uint32_t r = 0; r < requiredLangs.Length(); ++r) {
- const LangSupportEntry& langEntry = requiredLangs[r];
- FcLangResult support =
- gfxFontconfigUtils::GetLangSupport(font, langEntry.mLang);
- if (support <= langEntry.mBestSupport) { // lower is better
- requiredLangs.RemoveElementAt(r);
- --r;
- }
- }
-
- // FcFontSetDestroy will remove a reference but FcFontSetAdd
- // does _not_ take a reference!
- if (FcFontSetAdd(fontSet, font)) {
- // We don't add a reference here for user fonts, because we're
- // using a local clone of the pattern (see above) in order to
- // override the family name
- if (!isUserFont) {
- FcPatternReference(font);
- }
- }
- }
- }
-
- FcPattern *truncateMarker = nullptr;
- for (uint32_t r = 0; r < requiredLangs.Length(); ++r) {
- const nsTArray< nsCountedRef<FcPattern> >& langFonts =
- utils->GetFontsForLang(requiredLangs[r].mLang);
-
- bool haveLangFont = false;
- for (uint32_t f = 0; f < langFonts.Length(); ++f) {
- FcPattern *font = langFonts[f];
- if (requestedSize != -1.0 && !SizeIsAcceptable(font, requestedSize))
- continue;
-
- haveLangFont = true;
- if (FcFontSetAdd(fontSet, font)) {
- FcPatternReference(font);
- }
- }
-
- if (!haveLangFont && langFonts.Length() > 0) {
- // There is a font that supports this language but it didn't pass
- // the slant and size criteria. Weak default font families should
- // not be considered until the language has been satisfied.
- //
- // Insert a font that supports the language so that it will mark
- // the position of fonts from weak families in the sorted set and
- // they can be removed. The language and weak families will be
- // considered in the fallback fonts, which use fontconfig's
- // algorithm.
- //
- // Of the fonts that don't meet slant and size criteria, strong
- // default font families should be considered before (other) fonts
- // for this language, so this marker font will be removed (as well
- // as the fonts from weak families), and strong families will be
- // reconsidered in the fallback fonts.
- FcPattern *font = langFonts[0];
- if (FcFontSetAdd(fontSet, font)) {
- FcPatternReference(font);
- truncateMarker = font;
- }
- break;
- }
- }
-
- FcFontSet *sets[1] = { fontSet };
- FcResult result;
- fontSet.own(FcFontSetSort(nullptr, sets, 1, mSortPattern,
- FcFalse, nullptr, &result));
-
- if (truncateMarker != nullptr && fontSet) {
- nsAutoRef<FcFontSet> truncatedSet(FcFontSetCreate());
-
- for (int f = 0; f < fontSet->nfont; ++f) {
- FcPattern *font = fontSet->fonts[f];
- if (font == truncateMarker)
- break;
-
- if (FcFontSetAdd(truncatedSet, font)) {
- FcPatternReference(font);
- }
- }
-
- fontSet.steal(truncatedSet);
- }
-
- return fontSet.out();
-}
-
-nsReturnRef<FcFontSet>
-gfxFcFontSet::SortFallbackFonts()
-{
- // Setting trim to FcTrue would provide a much smaller (~ 1/10) FcFontSet,
- // but would take much longer due to comparing all the character sets.
- //
- // The references to fonts in this FcFontSet are almost free
- // as they are pointers into mmaped cache files.
- //
- // GetFontPatternAt() will trim lazily if and as needed, which will also
- // remove duplicates of preferred fonts.
- FcResult result;
- return nsReturnRef<FcFontSet>(FcFontSort(nullptr, mSortPattern,
- FcFalse, nullptr, &result));
-}
-
-// GetFontAt relies on this setting up all patterns up to |i|.
-FcPattern *
-gfxFcFontSet::GetFontPatternAt(uint32_t i)
-{
- while (i >= mFonts.Length()) {
- while (!mFcFontSet) {
- if (mHaveFallbackFonts)
- return nullptr;
-
- mFcFontSet = SortFallbackFonts();
- mHaveFallbackFonts = true;
- mFcFontsTrimmed = 0;
- // Loop to test that mFcFontSet is non-nullptr.
- }
-
- while (mFcFontsTrimmed < mFcFontSet->nfont) {
- FcPattern *font = mFcFontSet->fonts[mFcFontsTrimmed];
- ++mFcFontsTrimmed;
-
- if (mFonts.Length() != 0) {
- // See if the next font provides support for any extra
- // characters. Most often the next font is not going to
- // support more characters so check for a SubSet first before
- // allocating a new CharSet with Union.
- FcCharSet *supportedChars = mCharSet;
- if (!supportedChars) {
- FcPatternGetCharSet(mFonts[mFonts.Length() - 1].mPattern,
- FC_CHARSET, 0, &supportedChars);
- }
-
- if (supportedChars) {
- FcCharSet *newChars = nullptr;
- FcPatternGetCharSet(font, FC_CHARSET, 0, &newChars);
- if (newChars) {
- if (FcCharSetIsSubset(newChars, supportedChars))
- continue;
-
- mCharSet.own(FcCharSetUnion(supportedChars, newChars));
- } else if (!mCharSet) {
- mCharSet.own(FcCharSetCopy(supportedChars));
- }
- }
- }
-
- mFonts.AppendElement(font);
- if (mFonts.Length() >= i)
- break;
- }
-
- if (mFcFontsTrimmed == mFcFontSet->nfont) {
- // finished with this font set
- mFcFontSet.reset();
- }
- }
-
- return mFonts[i].mPattern;
-}
-
-#ifdef MOZ_WIDGET_GTK
-static void ApplyGdkScreenFontOptions(FcPattern *aPattern);
-#endif
-
-// Apply user settings and defaults to pattern in preparation for matching.
-static void
-PrepareSortPattern(FcPattern *aPattern, double aFallbackSize,
- double aSizeAdjustFactor, bool aIsPrinterFont)
-{
- FcConfigSubstitute(nullptr, aPattern, FcMatchPattern);
-
- // This gets cairo_font_options_t for the Screen. We should have
- // different font options for printing (no hinting) but we are not told
- // what we are measuring for.
- //
- // If cairo adds support for lcd_filter, gdk will not provide the default
- // setting for that option. We could get the default setting by creating
- // an xlib surface once, recording its font_options, and then merging the
- // gdk options.
- //
- // Using an xlib surface would also be an option to get Screen font
- // options for non-GTK X11 toolkits, but less efficient than using GDK to
- // pick up dynamic changes.
- if(aIsPrinterFont) {
- cairo_font_options_t *options = cairo_font_options_create();
- cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
- cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY);
- cairo_ft_font_options_substitute(options, aPattern);
- cairo_font_options_destroy(options);
- FcPatternAddBool(aPattern, PRINTING_FC_PROPERTY, FcTrue);
- } else {
-#ifdef MOZ_WIDGET_GTK
- ApplyGdkScreenFontOptions(aPattern);
-#endif
- }
-
- // Protect against any fontconfig settings that may have incorrectly
- // modified the pixelsize, and consider aSizeAdjustFactor.
- double size = aFallbackSize;
- if (FcPatternGetDouble(aPattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch
- || aSizeAdjustFactor != 1.0) {
- FcPatternDel(aPattern, FC_PIXEL_SIZE);
- FcPatternAddDouble(aPattern, FC_PIXEL_SIZE, size * aSizeAdjustFactor);
- }
-
- FcDefaultSubstitute(aPattern);
-}
-
-/**
- ** gfxPangoFontGroup
- **/
-
-gfxPangoFontGroup::gfxPangoFontGroup(const FontFamilyList& aFontFamilyList,
- const gfxFontStyle *aStyle,
- gfxUserFontSet *aUserFontSet,
- gfxFloat aDevToCssSize)
- : gfxFontGroup(aFontFamilyList, aStyle, nullptr, aUserFontSet, aDevToCssSize),
- mPangoLanguage(GuessPangoLanguage(aStyle->language))
-{
- // This language is passed to the font for shaping.
- // Shaping doesn't know about lang groups so make it a real language.
- if (mPangoLanguage) {
- mStyle.language = NS_Atomize(pango_language_to_string(mPangoLanguage));
- }
-
- // dummy entry, will be replaced when actually needed
- mFonts.AppendElement(FamilyFace());
- mSkipUpdateUserFonts = true;
-}
-
-gfxPangoFontGroup::~gfxPangoFontGroup()
-{
-}
-
-gfxFontGroup *
-gfxPangoFontGroup::Copy(const gfxFontStyle *aStyle)
-{
- return new gfxPangoFontGroup(mFamilyList, aStyle, mUserFontSet, mDevToCssSize);
-}
-
-void
-gfxPangoFontGroup::FindGenericFontsPFG(FontFamilyType aGenericType,
- nsIAtom *aLanguage,
- void *aClosure)
-{
- AutoTArray<nsString, 5> resolvedGenerics;
- ResolveGenericFontNamesPFG(aGenericType, aLanguage, resolvedGenerics);
- uint32_t g = 0, numGenerics = resolvedGenerics.Length();
- for (g = 0; g < numGenerics; g++) {
- FindPlatformFontPFG(resolvedGenerics[g], false, aClosure);
- }
-}
-
-/* static */ void
-gfxPangoFontGroup::ResolveGenericFontNamesPFG(FontFamilyType aGenericType,
- nsIAtom *aLanguage,
- nsTArray<nsString>& aGenericFamilies)
-{
- static const char kGeneric_serif[] = "serif";
- static const char kGeneric_sans_serif[] = "sans-serif";
- static const char kGeneric_monospace[] = "monospace";
- static const char kGeneric_cursive[] = "cursive";
- static const char kGeneric_fantasy[] = "fantasy";
-
- // treat -moz-fixed as monospace
- if (aGenericType == eFamily_moz_fixed) {
- aGenericType = eFamily_monospace;
- }
-
- // type should be standard generic type at this point
- NS_ASSERTION(aGenericType >= eFamily_serif &&
- aGenericType <= eFamily_fantasy,
- "standard generic font family type required");
-
- // create the lang string
- nsIAtom *langGroupAtom = nullptr;
- nsAutoCString langGroupString;
- if (aLanguage) {
- if (!gLangService) {
- CallGetService(NS_LANGUAGEATOMSERVICE_CONTRACTID, &gLangService);
- }
- if (gLangService) {
- nsresult rv;
- langGroupAtom = gLangService->GetLanguageGroup(aLanguage, &rv);
- }
- }
- if (!langGroupAtom) {
- langGroupAtom = nsGkAtoms::Unicode;
- }
- langGroupAtom->ToUTF8String(langGroupString);
-
- // map generic type to string
- const char *generic = nullptr;
- switch (aGenericType) {
- case eFamily_serif:
- generic = kGeneric_serif;
- break;
- case eFamily_sans_serif:
- generic = kGeneric_sans_serif;
- break;
- case eFamily_monospace:
- generic = kGeneric_monospace;
- break;
- case eFamily_cursive:
- generic = kGeneric_cursive;
- break;
- case eFamily_fantasy:
- generic = kGeneric_fantasy;
- break;
- default:
- break;
- }
-
- if (!generic) {
- return;
- }
-
- aGenericFamilies.Clear();
-
- // load family for "font.name.generic.lang"
- nsAutoCString prefFontName("font.name.");
- prefFontName.Append(generic);
- prefFontName.Append('.');
- prefFontName.Append(langGroupString);
- gfxFontUtils::AppendPrefsFontList(prefFontName.get(),
- aGenericFamilies);
-
- // if lang has pref fonts, also load fonts for "font.name-list.generic.lang"
- if (!aGenericFamilies.IsEmpty()) {
- nsAutoCString prefFontListName("font.name-list.");
- prefFontListName.Append(generic);
- prefFontListName.Append('.');
- prefFontListName.Append(langGroupString);
- gfxFontUtils::AppendPrefsFontList(prefFontListName.get(),
- aGenericFamilies);
- }
-
-#if 0 // dump out generic mappings
- printf("%s ===> ", prefFontName.get());
- for (uint32_t k = 0; k < aGenericFamilies.Length(); k++) {
- if (k > 0) printf(", ");
- printf("%s", NS_ConvertUTF16toUTF8(aGenericFamilies[k]).get());
- }
- printf("\n");
-#endif
-}
-
-void gfxPangoFontGroup::EnumerateFontListPFG(nsIAtom *aLanguage, void *aClosure)
-{
- // initialize fonts in the font family list
- const nsTArray<FontFamilyName>& fontlist = mFamilyList.GetFontlist();
-
- // lookup fonts in the fontlist
- uint32_t i, numFonts = fontlist.Length();
- for (i = 0; i < numFonts; i++) {
- const FontFamilyName& name = fontlist[i];
- if (name.IsNamed()) {
- FindPlatformFontPFG(name.mName, true, aClosure);
- } else {
- FindGenericFontsPFG(name.mType, aLanguage, aClosure);
- }
- }
-
- // if necessary, append default generic onto the end
- if (mFamilyList.GetDefaultFontType() != eFamily_none &&
- !mFamilyList.HasDefaultGeneric()) {
- FindGenericFontsPFG(mFamilyList.GetDefaultFontType(),
- aLanguage, aClosure);
- }
-}
-
-void
-gfxPangoFontGroup::FindPlatformFontPFG(const nsAString& fontName,
- bool aUseFontSet,
- void *aClosure)
-{
- nsTArray<nsString> *list = static_cast<nsTArray<nsString>*>(aClosure);
-
- if (!list->Contains(fontName)) {
- // names present in the user fontset are not matched against system fonts
- if (aUseFontSet && mUserFontSet && mUserFontSet->HasFamily(fontName)) {
- nsAutoString userFontName =
- NS_LITERAL_STRING(FONT_FACE_FAMILY_PREFIX) + fontName;
- list->AppendElement(userFontName);
- } else {
- list->AppendElement(fontName);
- }
- }
-}
-
-gfxFcFont *
-gfxPangoFontGroup::GetBaseFont()
-{
- if (mFonts[0].Font() == nullptr) {
- gfxFont* font = GetBaseFontSet()->GetFontAt(0, GetStyle());
- mFonts[0] = FamilyFace(nullptr, font);
- }
-
- return static_cast<gfxFcFont*>(mFonts[0].Font());
-}
-
-gfxFont*
-gfxPangoFontGroup::GetFirstValidFont(uint32_t aCh)
-{
- return GetFontAt(0);
-}
-
-gfxFont *
-gfxPangoFontGroup::GetFontAt(int32_t i, uint32_t aCh)
-{
- // If it turns out to be hard for all clients that cache font
- // groups to call UpdateUserFonts at appropriate times, we could
- // instead consider just calling UpdateUserFonts from someplace
- // more central (such as here).
- NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(),
- "Whoever was caching this font group should have "
- "called UpdateUserFonts on it");
-
- NS_PRECONDITION(i == 0, "Only have one font");
-
- return GetBaseFont();
-}
-
-void
-gfxPangoFontGroup::UpdateUserFonts()
-{
- uint64_t newGeneration = GetGeneration();
- if (newGeneration == mCurrGeneration)
- return;
-
- mFonts[0] = FamilyFace();
- mFontSets.Clear();
- ClearCachedData();
- mCurrGeneration = newGeneration;
-}
-
-already_AddRefed<gfxFcFontSet>
-gfxPangoFontGroup::MakeFontSet(PangoLanguage *aLang, gfxFloat aSizeAdjustFactor,
- nsAutoRef<FcPattern> *aMatchPattern)
-{
- const char *lang = pango_language_to_string(aLang);
-
- RefPtr<nsIAtom> langGroup;
- if (aLang != mPangoLanguage) {
- // Set up langGroup for Mozilla's font prefs.
- langGroup = NS_Atomize(lang);
- }
-
- AutoTArray<nsString, 20> fcFamilyList;
- EnumerateFontListPFG(langGroup ? langGroup.get() : mStyle.language.get(),
- &fcFamilyList);
-
- // To consider: A fontset cache here could be helpful.
-
- // Get a pattern suitable for matching.
- nsAutoRef<FcPattern> pattern
- (gfxFontconfigUtils::NewPattern(fcFamilyList, mStyle, lang));
-
- PrepareSortPattern(pattern, mStyle.size, aSizeAdjustFactor, mStyle.printerFont);
-
- RefPtr<gfxFcFontSet> fontset =
- new gfxFcFontSet(pattern, mUserFontSet);
-
- mSkipDrawing = fontset->WaitingForUserFont();
-
- if (aMatchPattern)
- aMatchPattern->steal(pattern);
-
- return fontset.forget();
-}
-
-gfxPangoFontGroup::
-FontSetByLangEntry::FontSetByLangEntry(PangoLanguage *aLang,
- gfxFcFontSet *aFontSet)
- : mLang(aLang), mFontSet(aFontSet)
-{
-}
-
-gfxFcFontSet *
-gfxPangoFontGroup::GetFontSet(PangoLanguage *aLang)
-{
- GetBaseFontSet(); // sets mSizeAdjustFactor and mFontSets[0]
-
- if (!aLang)
- return mFontSets[0].mFontSet;
-
- for (uint32_t i = 0; i < mFontSets.Length(); ++i) {
- if (mFontSets[i].mLang == aLang)
- return mFontSets[i].mFontSet;
- }
-
- RefPtr<gfxFcFontSet> fontSet =
- MakeFontSet(aLang, mSizeAdjustFactor);
- mFontSets.AppendElement(FontSetByLangEntry(aLang, fontSet));
-
- return fontSet;
-}
-
-already_AddRefed<gfxFont>
-gfxPangoFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
- uint32_t aNextCh, Script aRunScript,
- gfxFont *aPrevMatchedFont,
- uint8_t *aMatchType)
-{
- if (aPrevMatchedFont) {
- // Don't switch fonts for control characters, regardless of
- // whether they are present in the current font, as they won't
- // actually be rendered (see bug 716229)
- uint8_t category = GetGeneralCategory(aCh);
- if (category == HB_UNICODE_GENERAL_CATEGORY_CONTROL) {
- return RefPtr<gfxFont>(aPrevMatchedFont).forget();
- }
-
- // if this character is a join-control or the previous is a join-causer,
- // use the same font as the previous range if we can
- if (gfxFontUtils::IsJoinControl(aCh) ||
- gfxFontUtils::IsJoinCauser(aPrevCh)) {
- if (aPrevMatchedFont->HasCharacter(aCh)) {
- return RefPtr<gfxFont>(aPrevMatchedFont).forget();
- }
- }
- }
-
- // if this character is a variation selector,
- // use the previous font regardless of whether it supports VS or not.
- // otherwise the text run will be divided.
- if (gfxFontUtils::IsVarSelector(aCh)) {
- if (aPrevMatchedFont) {
- return RefPtr<gfxFont>(aPrevMatchedFont).forget();
- }
- // VS alone. it's meaningless to search different fonts
- return nullptr;
- }
-
- // The real fonts that fontconfig provides for generic/fallback families
- // depend on the language used, so a different FontSet is used for each
- // language (except for the variation below).
- //
- // With most fontconfig configurations any real family names prior to a
- // fontconfig generic with corresponding fonts installed will still lead
- // to the same leading fonts in each FontSet.
- //
- // There is an inefficiency here therefore because the same base FontSet
- // could often be used if these real families support the character.
- // However, with fontconfig aliases, it is difficult to distinguish
- // where exactly alias fonts end and generic/fallback fonts begin.
- //
- // The variation from pure language-based matching used here is that the
- // same primary/base font is always used irrespective of the language.
- // This provides that SCRIPT_COMMON characters are consistently rendered
- // with the same font (bug 339513 and bug 416725). This is particularly
- // important with the word cache as script can't be reliably determined
- // from surrounding words. It also often avoids the unnecessary extra
- // FontSet efficiency mentioned above.
- //
- // However, in two situations, the base font is not checked before the
- // language-specific FontSet.
- //
- // 1. When we don't have a language to make a good choice for
- // the base font.
- //
- // 2. For system fonts, use the default Pango behavior to give
- // consistency with other apps. This is relevant when un-localized
- // builds are run in non-Latin locales. This special-case probably
- // wouldn't be necessary but for bug 91190.
-
- gfxFcFontSet *fontSet = GetBaseFontSet();
- uint32_t nextFont = 0;
- FcPattern *basePattern = nullptr;
- if (!mStyle.systemFont && mPangoLanguage) {
- basePattern = fontSet->GetFontPatternAt(0);
- if (HasChar(basePattern, aCh)) {
- *aMatchType = gfxTextRange::kFontGroup;
- return RefPtr<gfxFont>(GetBaseFont()).forget();
- }
-
- nextFont = 1;
- }
-
- // Our MOZ_SCRIPT_* codes may not match the PangoScript enumeration values
- // (if we're using ICU's codes), so convert by mapping through ISO 15924 tag.
- // Note that PangoScript is defined to be compatible with GUnicodeScript:
- // https://developer.gnome.org/pango/stable/pango-Scripts-and-Languages.html#PangoScript
- const hb_tag_t scriptTag = GetScriptTagForCode(aRunScript);
- const PangoScript script =
- (const PangoScript)hb_glib_script_from_script(hb_script_from_iso15924_tag(scriptTag));
-
- // Might be nice to call pango_language_includes_script only once for the
- // run rather than for each character.
- PangoLanguage *scriptLang;
- if ((!basePattern ||
- !pango_language_includes_script(mPangoLanguage, script)) &&
- (scriptLang = pango_script_get_sample_language(script))) {
- fontSet = GetFontSet(scriptLang);
- nextFont = 0;
- }
-
- for (uint32_t i = nextFont;
- FcPattern *pattern = fontSet->GetFontPatternAt(i);
- ++i) {
- if (pattern == basePattern) {
- continue; // already checked basePattern
- }
-
- if (HasChar(pattern, aCh)) {
- *aMatchType = gfxTextRange::kFontGroup;
- return RefPtr<gfxFont>(fontSet->GetFontAt(i, GetStyle())).forget();
- }
- }
-
- return nullptr;
-}
-
-/**
- ** gfxFcFont
- **/
-
-cairo_user_data_key_t gfxFcFont::sGfxFontKey;
-
-gfxFcFont::gfxFcFont(cairo_scaled_font_t *aCairoFont,
- FcPattern *aPattern,
- gfxFcFontEntry *aFontEntry,
- const gfxFontStyle *aFontStyle)
- : gfxFontconfigFontBase(aCairoFont, aPattern, aFontEntry, aFontStyle)
-{
- cairo_scaled_font_set_user_data(mScaledFont, &sGfxFontKey, this, nullptr);
-}
-
-gfxFcFont::~gfxFcFont()
-{
- cairo_scaled_font_set_user_data(mScaledFont,
- &sGfxFontKey,
- nullptr,
- nullptr);
-}
-
-already_AddRefed<gfxFont>
-gfxFcFont::GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel)
-{
- gfxFontStyle style(*GetStyle());
- style.AdjustForSubSuperscript(aAppUnitsPerDevPixel);
- return MakeScaledFont(&style, style.size / GetStyle()->size);
-}
-
-already_AddRefed<gfxFont>
-gfxFcFont::MakeScaledFont(gfxFontStyle *aFontStyle, gfxFloat aScaleFactor)
-{
- gfxFcFontEntry* fe = static_cast<gfxFcFontEntry*>(GetFontEntry());
- RefPtr<gfxFont> font =
- gfxFontCache::GetCache()->Lookup(fe, aFontStyle, nullptr);
- if (font) {
- return font.forget();
- }
-
- cairo_matrix_t fontMatrix;
- cairo_scaled_font_get_font_matrix(mScaledFont, &fontMatrix);
- cairo_matrix_scale(&fontMatrix, aScaleFactor, aScaleFactor);
-
- cairo_matrix_t ctm;
- cairo_scaled_font_get_ctm(mScaledFont, &ctm);
-
- cairo_font_options_t *options = cairo_font_options_create();
- cairo_scaled_font_get_font_options(mScaledFont, options);
-
- cairo_scaled_font_t *newFont =
- cairo_scaled_font_create(cairo_scaled_font_get_font_face(mScaledFont),
- &fontMatrix, &ctm, options);
- cairo_font_options_destroy(options);
-
- font = new gfxFcFont(newFont, GetPattern(), fe, aFontStyle);
- gfxFontCache::GetCache()->AddNew(font);
- cairo_scaled_font_destroy(newFont);
-
- return font.forget();
-}
-
-already_AddRefed<gfxFont>
-gfxFcFont::GetSmallCapsFont()
-{
- gfxFontStyle style(*GetStyle());
- style.size *= SMALL_CAPS_SCALE_FACTOR;
- style.variantCaps = NS_FONT_VARIANT_CAPS_NORMAL;
- return MakeScaledFont(&style, SMALL_CAPS_SCALE_FACTOR);
-}
-
-/* static */ void
-gfxPangoFontGroup::Shutdown()
-{
- // Resetting gFTLibrary in case this is wanted again after a
- // cairo_debug_reset_static_data.
- gFTLibrary = nullptr;
-}
-
-/* static */ gfxFontEntry *
-gfxPangoFontGroup::NewFontEntry(const nsAString& aFontName,
- uint16_t aWeight,
- int16_t aStretch,
- uint8_t aStyle)
-{
- gfxFontconfigUtils *utils = gfxFontconfigUtils::GetFontconfigUtils();
- if (!utils)
- return nullptr;
-
- // The font face name from @font-face { src: local() } is not well
- // defined.
- //
- // On MS Windows, this name gets compared with
- // ENUMLOGFONTEXW::elfFullName, which for OpenType fonts seems to be the
- // full font name from the name table. For CFF OpenType fonts this is the
- // same as the PostScript name, but for TrueType fonts it is usually
- // different.
- //
- // On Mac, the font face name is compared with the PostScript name, even
- // for TrueType fonts.
- //
- // Fontconfig only records the full font names, so the behavior here
- // follows that on MS Windows. However, to provide the possibility
- // of aliases to compensate for variations, the font face name is passed
- // through FcConfigSubstitute.
-
- nsAutoRef<FcPattern> pattern(FcPatternCreate());
- if (!pattern)
- return nullptr;
-
- NS_ConvertUTF16toUTF8 fullname(aFontName);
- FcPatternAddString(pattern, FC_FULLNAME,
- gfxFontconfigUtils::ToFcChar8(fullname));
- FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
-
- FcChar8 *name;
- for (int v = 0;
- FcPatternGetString(pattern, FC_FULLNAME, v, &name) == FcResultMatch;
- ++v) {
- const nsTArray< nsCountedRef<FcPattern> >& fonts =
- utils->GetFontsForFullname(name);
-
- if (fonts.Length() != 0)
- return new gfxLocalFcFontEntry(aFontName,
- aWeight,
- aStretch,
- aStyle,
- fonts);
- }
-
- return nullptr;
-}
-
-/* static */ FT_Library
-gfxPangoFontGroup::GetFTLibrary()
-{
- if (!gFTLibrary) {
- // Use cairo's FT_Library so that cairo takes care of shutdown of the
- // FT_Library after it has destroyed its font_faces, and FT_Done_Face
- // has been called on each FT_Face, at least until this bug is fixed:
- // https://bugs.freedesktop.org/show_bug.cgi?id=18857
- //
- // Cairo's FT_Library can be obtained from any cairo_scaled_font. The
- // font properties requested here are chosen to get an FT_Face that is
- // likely to be also used elsewhere.
- gfxFontStyle style;
- RefPtr<gfxPangoFontGroup> fontGroup =
- new gfxPangoFontGroup(FontFamilyList(eFamily_sans_serif),
- &style, nullptr, 1.0);
-
- gfxFcFont *font = fontGroup->GetBaseFont();
- if (!font)
- return nullptr;
-
- gfxFT2LockedFace face(font);
- if (!face.get())
- return nullptr;
-
- gFTLibrary = face.get()->glyph->library;
- }
-
- return gFTLibrary;
-}
-
-/* static */ gfxFontEntry *
-gfxPangoFontGroup::NewFontEntry(const nsAString& aFontName,
- uint16_t aWeight,
- int16_t aStretch,
- uint8_t aStyle,
- const uint8_t* aFontData,
- uint32_t aLength)
-{
- // Ownership of aFontData is passed in here, and transferred to the
- // new fontEntry, which will release it when no longer needed.
-
- // Using face_index = 0 for the first face in the font, as we have no
- // other information. FT_New_Memory_Face checks for a nullptr FT_Library.
- FT_Face face;
- FT_Error error =
- FT_New_Memory_Face(GetFTLibrary(), aFontData, aLength, 0, &face);
- if (error != 0) {
- free((void*)aFontData);
- return nullptr;
- }
-
- return new gfxDownloadedFcFontEntry(aFontName, aWeight,
- aStretch, aStyle,
- aFontData, face);
-}
-
-
-static double
-GetPixelSize(FcPattern *aPattern)
-{
- double size;
- if (FcPatternGetDouble(aPattern,
- FC_PIXEL_SIZE, 0, &size) == FcResultMatch)
- return size;
-
- NS_NOTREACHED("No size on pattern");
- return 0.0;
-}
-
-/**
- * The following gfxFcFonts are accessed from the cairo_scaled_font or created
- * from the FcPattern, not from the gfxFontCache hash table. The gfxFontCache
- * hash table is keyed by desired family and style, whereas here we only know
- * actual family and style. There may be more than one of these fonts with
- * the same family and style, but different PangoFont and actual font face.
- *
- * The point of this is to record the exact font face for gfxTextRun glyph
- * indices. The style of this font does not necessarily represent the exact
- * gfxFontStyle used to build the text run. Notably, the language is not
- * recorded.
- */
-
-/* static */
-already_AddRefed<gfxFcFont>
-gfxFcFont::GetOrMakeFont(FcPattern *aRequestedPattern, FcPattern *aFontPattern,
- const gfxFontStyle *aFontStyle)
-{
- nsAutoRef<FcPattern> renderPattern
- (FcFontRenderPrepare(nullptr, aRequestedPattern, aFontPattern));
-
- // If synthetic bold/italic is not allowed by the style, adjust the
- // resulting pattern to match the actual properties of the font.
- if (!aFontStyle->allowSyntheticWeight) {
- int weight;
- if (FcPatternGetInteger(aFontPattern, FC_WEIGHT, 0,
- &weight) == FcResultMatch) {
- FcPatternDel(renderPattern, FC_WEIGHT);
- FcPatternAddInteger(renderPattern, FC_WEIGHT, weight);
- }
- }
- if (!aFontStyle->allowSyntheticStyle) {
- int slant;
- if (FcPatternGetInteger(aFontPattern, FC_SLANT, 0,
- &slant) == FcResultMatch) {
- FcPatternDel(renderPattern, FC_SLANT);
- FcPatternAddInteger(renderPattern, FC_SLANT, slant);
- }
- }
-
- cairo_font_face_t *face =
- cairo_ft_font_face_create_for_pattern(renderPattern);
-
- // Reuse an existing font entry if available.
- RefPtr<gfxFcFontEntry> fe = gfxFcFontEntry::LookupFontEntry(face);
- if (!fe) {
- gfxDownloadedFcFontEntry *downloadedFontEntry =
- GetDownloadedFontEntry(aFontPattern);
- if (downloadedFontEntry) {
- // Web font
- fe = downloadedFontEntry;
- if (cairo_font_face_status(face) == CAIRO_STATUS_SUCCESS) {
- // cairo_font_face_t is using the web font data.
- // Hold a reference to the font entry to keep the font face
- // data.
- if (!downloadedFontEntry->SetCairoFace(face)) {
- // OOM. Let cairo pick a fallback font
- cairo_font_face_destroy(face);
- face = cairo_ft_font_face_create_for_pattern(aRequestedPattern);
- fe = gfxFcFontEntry::LookupFontEntry(face);
- }
- }
- }
- if (!fe) {
- // Get a unique name for the font face from the file and id.
- nsAutoString name;
- FcChar8 *fc_file;
- if (FcPatternGetString(renderPattern,
- FC_FILE, 0, &fc_file) == FcResultMatch) {
- int index;
- if (FcPatternGetInteger(renderPattern,
- FC_INDEX, 0, &index) != FcResultMatch) {
- // cairo defaults to 0.
- index = 0;
- }
-
- AppendUTF8toUTF16(gfxFontconfigUtils::ToCString(fc_file), name);
- if (index != 0) {
- name.Append('/');
- name.AppendInt(index);
- }
- }
-
- fe = new gfxSystemFcFontEntry(face, aFontPattern, name);
- }
- }
-
- gfxFontStyle style(*aFontStyle);
- style.size = GetPixelSize(renderPattern);
- style.style = gfxFontconfigUtils::GetThebesStyle(renderPattern);
- style.weight = gfxFontconfigUtils::GetThebesWeight(renderPattern);
-
- RefPtr<gfxFont> font =
- gfxFontCache::GetCache()->Lookup(fe, &style, nullptr);
- if (!font) {
- // Note that a file/index pair (or FT_Face) and the gfxFontStyle are
- // not necessarily enough to provide a key that will describe a unique
- // font. cairoFont contains information from renderPattern, which is a
- // fully resolved pattern from FcFontRenderPrepare.
- // FcFontRenderPrepare takes the requested pattern and the face
- // pattern as input and can modify elements of the resulting pattern
- // that affect rendering but are not included in the gfxFontStyle.
- cairo_scaled_font_t *cairoFont = CreateScaledFont(renderPattern, face);
- font = new gfxFcFont(cairoFont, renderPattern, fe, &style);
- gfxFontCache::GetCache()->AddNew(font);
- cairo_scaled_font_destroy(cairoFont);
- }
-
- cairo_font_face_destroy(face);
-
- RefPtr<gfxFcFont> retval(static_cast<gfxFcFont*>(font.get()));
- return retval.forget();
-}
-
-gfxFcFontSet *
-gfxPangoFontGroup::GetBaseFontSet()
-{
- if (mFontSets.Length() > 0)
- return mFontSets[0].mFontSet;
-
- mSizeAdjustFactor = 1.0; // will be adjusted below if necessary
- nsAutoRef<FcPattern> pattern;
- RefPtr<gfxFcFontSet> fontSet =
- MakeFontSet(mPangoLanguage, mSizeAdjustFactor, &pattern);
-
- double size = GetPixelSize(pattern);
- if (size != 0.0 && mStyle.sizeAdjust > 0.0) {
- gfxFcFont *font = fontSet->GetFontAt(0, GetStyle());
- if (font) {
- const gfxFont::Metrics& metrics =
- font->GetMetrics(gfxFont::eHorizontal); // XXX vertical?
-
- // The factor of 0.1 ensures that xHeight is sane so fonts don't
- // become huge. Strictly ">" ensures that xHeight and emHeight are
- // not both zero.
- if (metrics.xHeight > 0.1 * metrics.emHeight) {
- mSizeAdjustFactor =
- mStyle.sizeAdjust * metrics.emHeight / metrics.xHeight;
-
- size *= mSizeAdjustFactor;
- FcPatternDel(pattern, FC_PIXEL_SIZE);
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size);
-
- fontSet = new gfxFcFontSet(pattern, mUserFontSet);
- }
- }
- }
-
- PangoLanguage *pangoLang = mPangoLanguage;
- FcChar8 *fcLang;
- if (!pangoLang &&
- FcPatternGetString(pattern, FC_LANG, 0, &fcLang) == FcResultMatch) {
- pangoLang =
- pango_language_from_string(gfxFontconfigUtils::ToCString(fcLang));
- }
-
- mFontSets.AppendElement(FontSetByLangEntry(pangoLang, fontSet));
-
- return fontSet;
-}
-
-/**
- ** gfxTextRun
- *
- * A serious problem:
- *
- * -- We draw with a font that's hinted for the CTM, but we measure with a font
- * hinted to the identity matrix, so our "bounding metrics" may not be accurate.
- *
- **/
-
-// This will fetch an existing scaled_font if one exists.
-static cairo_scaled_font_t *
-CreateScaledFont(FcPattern *aPattern, cairo_font_face_t *aFace)
-{
- double size = GetPixelSize(aPattern);
-
- cairo_matrix_t fontMatrix;
- FcMatrix *fcMatrix;
- if (FcPatternGetMatrix(aPattern, FC_MATRIX, 0, &fcMatrix) == FcResultMatch)
- cairo_matrix_init(&fontMatrix, fcMatrix->xx, -fcMatrix->yx, -fcMatrix->xy, fcMatrix->yy, 0, 0);
- else
- cairo_matrix_init_identity(&fontMatrix);
- cairo_matrix_scale(&fontMatrix, size, size);
-
- FcBool printing;
- if (FcPatternGetBool(aPattern, PRINTING_FC_PROPERTY, 0, &printing) != FcResultMatch) {
- printing = FcFalse;
- }
-
- // The cairo_scaled_font is created with a unit ctm so that metrics and
- // positions are in user space, but this means that hinting effects will
- // not be estimated accurately for non-unit transformations.
- cairo_matrix_t identityMatrix;
- cairo_matrix_init_identity(&identityMatrix);
-
- // Font options are set explicitly here to improve cairo's caching
- // behavior and to record the relevant parts of the pattern for
- // SetupCairoFont (so that the pattern can be released).
- //
- // Most font_options have already been set as defaults on the FcPattern
- // with cairo_ft_font_options_substitute(), then user and system
- // fontconfig configurations were applied. The resulting font_options
- // have been recorded on the face during
- // cairo_ft_font_face_create_for_pattern().
- //
- // None of the settings here cause this scaled_font to behave any
- // differently from how it would behave if it were created from the same
- // face with default font_options.
- //
- // We set options explicitly so that the same scaled_font will be found in
- // the cairo_scaled_font_map when cairo loads glyphs from a context with
- // the same font_face, font_matrix, ctm, and surface font_options.
- //
- // Unfortunately, _cairo_scaled_font_keys_equal doesn't know about the
- // font_options on the cairo_ft_font_face, and doesn't consider default
- // option values to not match any explicit values.
- //
- // Even after cairo_set_scaled_font is used to set font_options for the
- // cairo context, when cairo looks for a scaled_font for the context, it
- // will look for a font with some option values from the target surface if
- // any values are left default on the context font_options. If this
- // scaled_font is created with default font_options, cairo will not find
- // it.
- cairo_font_options_t *fontOptions = cairo_font_options_create();
-
- // The one option not recorded in the pattern is hint_metrics, which will
- // affect glyph metrics. The default behaves as CAIRO_HINT_METRICS_ON.
- // We should be considering the font_options of the surface on which this
- // font will be used, but currently we don't have different gfxFonts for
- // different surface font_options, so we'll create a font suitable for the
- // Screen. Image and xlib surfaces default to CAIRO_HINT_METRICS_ON.
- if (printing) {
- cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
- } else {
- cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_ON);
- }
-
- // The remaining options have been recorded on the pattern and the face.
- // _cairo_ft_options_merge has some logic to decide which options from the
- // scaled_font or from the cairo_ft_font_face take priority in the way the
- // font behaves.
- //
- // In the majority of cases, _cairo_ft_options_merge uses the options from
- // the cairo_ft_font_face, so sometimes it is not so important which
- // values are set here so long as they are not defaults, but we'll set
- // them to the exact values that we expect from the font, to be consistent
- // and to protect against changes in cairo.
- //
- // In some cases, _cairo_ft_options_merge uses some options from the
- // scaled_font's font_options rather than options on the
- // cairo_ft_font_face (from fontconfig).
- // https://bugs.freedesktop.org/show_bug.cgi?id=11838
- //
- // Surface font options were set on the pattern in
- // cairo_ft_font_options_substitute. If fontconfig has changed the
- // hint_style then that is what the user (or distribution) wants, so we
- // use the setting from the FcPattern.
- //
- // Fallback values here mirror treatment of defaults in cairo-ft-font.c.
- FcBool hinting = FcFalse;
- if (FcPatternGetBool(aPattern, FC_HINTING, 0, &hinting) != FcResultMatch) {
- hinting = FcTrue;
- }
-
- cairo_hint_style_t hint_style;
- if (printing || !hinting) {
- hint_style = CAIRO_HINT_STYLE_NONE;
- } else {
-#ifdef FC_HINT_STYLE // FC_HINT_STYLE is available from fontconfig 2.2.91.
- int fc_hintstyle;
- if (FcPatternGetInteger(aPattern, FC_HINT_STYLE,
- 0, &fc_hintstyle ) != FcResultMatch) {
- fc_hintstyle = FC_HINT_FULL;
- }
- switch (fc_hintstyle) {
- case FC_HINT_NONE:
- hint_style = CAIRO_HINT_STYLE_NONE;
- break;
- case FC_HINT_SLIGHT:
- hint_style = CAIRO_HINT_STYLE_SLIGHT;
- break;
- case FC_HINT_MEDIUM:
- default: // This fallback mirrors _get_pattern_ft_options in cairo.
- hint_style = CAIRO_HINT_STYLE_MEDIUM;
- break;
- case FC_HINT_FULL:
- hint_style = CAIRO_HINT_STYLE_FULL;
- break;
- }
-#else // no FC_HINT_STYLE
- hint_style = CAIRO_HINT_STYLE_FULL;
-#endif
- }
- cairo_font_options_set_hint_style(fontOptions, hint_style);
-
- int rgba;
- if (FcPatternGetInteger(aPattern,
- FC_RGBA, 0, &rgba) != FcResultMatch) {
- rgba = FC_RGBA_UNKNOWN;
- }
- cairo_subpixel_order_t subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
- switch (rgba) {
- case FC_RGBA_UNKNOWN:
- case FC_RGBA_NONE:
- default:
- // There is no CAIRO_SUBPIXEL_ORDER_NONE. Subpixel antialiasing
- // is disabled through cairo_antialias_t.
- rgba = FC_RGBA_NONE;
- // subpixel_order won't be used by the font as we won't use
- // CAIRO_ANTIALIAS_SUBPIXEL, but don't leave it at default for
- // caching reasons described above. Fall through:
- MOZ_FALLTHROUGH;
- case FC_RGBA_RGB:
- subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
- break;
- case FC_RGBA_BGR:
- subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
- break;
- case FC_RGBA_VRGB:
- subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
- break;
- case FC_RGBA_VBGR:
- subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
- break;
- }
- cairo_font_options_set_subpixel_order(fontOptions, subpixel_order);
-
- FcBool fc_antialias;
- if (FcPatternGetBool(aPattern,
- FC_ANTIALIAS, 0, &fc_antialias) != FcResultMatch) {
- fc_antialias = FcTrue;
- }
- cairo_antialias_t antialias;
- if (!fc_antialias) {
- antialias = CAIRO_ANTIALIAS_NONE;
- } else if (rgba == FC_RGBA_NONE) {
- antialias = CAIRO_ANTIALIAS_GRAY;
- } else {
- antialias = CAIRO_ANTIALIAS_SUBPIXEL;
- }
- cairo_font_options_set_antialias(fontOptions, antialias);
-
- cairo_scaled_font_t *scaledFont =
- cairo_scaled_font_create(aFace, &fontMatrix, &identityMatrix,
- fontOptions);
-
- cairo_font_options_destroy(fontOptions);
-
- NS_ASSERTION(cairo_scaled_font_status(scaledFont) == CAIRO_STATUS_SUCCESS,
- "Failed to create scaled font");
- return scaledFont;
-}
-
-/* static */
-PangoLanguage *
-GuessPangoLanguage(nsIAtom *aLanguage)
-{
- if (!aLanguage)
- return nullptr;
-
- // Pango and fontconfig won't understand mozilla's internal langGroups, so
- // find a real language.
- nsAutoCString lang;
- gfxFontconfigUtils::GetSampleLangForGroup(aLanguage, &lang);
- if (lang.IsEmpty())
- return nullptr;
-
- return pango_language_from_string(lang.get());
-}
-
-#ifdef MOZ_WIDGET_GTK
-/***************************************************************************
- *
- * This function must be last in the file because it uses the system cairo
- * library. Above this point the cairo library used is the tree cairo if
- * MOZ_TREE_CAIRO.
- */
-
-#if MOZ_TREE_CAIRO
-// Tree cairo symbols have different names. Disable their activation through
-// preprocessor macros.
-#undef cairo_ft_font_options_substitute
-
-// The system cairo functions are not declared because the include paths cause
-// the gdk headers to pick up the tree cairo.h.
-extern "C" {
-NS_VISIBILITY_DEFAULT void
-cairo_ft_font_options_substitute (const cairo_font_options_t *options,
- FcPattern *pattern);
-}
-#endif
-
-static void
-ApplyGdkScreenFontOptions(FcPattern *aPattern)
-{
- const cairo_font_options_t *options =
- gdk_screen_get_font_options(gdk_screen_get_default());
-
- cairo_ft_font_options_substitute(options, aPattern);
-}
-
-#endif // MOZ_WIDGET_GTK
-
diff --git a/gfx/thebes/gfxFontconfigFonts.h b/gfx/thebes/gfxFontconfigFonts.h
deleted file mode 100644
index cea9d0dbfa..0000000000
--- a/gfx/thebes/gfxFontconfigFonts.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef GFX_FONTCONFIG_FONTS_H
-#define GFX_FONTCONFIG_FONTS_H
-
-#include "cairo.h"
-#include "gfxTypes.h"
-#include "gfxTextRun.h"
-
-#include "nsAutoRef.h"
-#include "nsTArray.h"
-
-#include <pango/pango.h>
-
-class gfxFcFontSet;
-class gfxFcFont;
-typedef struct _FcPattern FcPattern;
-typedef struct FT_FaceRec_* FT_Face;
-typedef struct FT_LibraryRec_ *FT_Library;
-
-class gfxPangoFontGroup : public gfxFontGroup {
-public:
- gfxPangoFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
- const gfxFontStyle *aStyle,
- gfxUserFontSet *aUserFontSet,
- gfxFloat aDevToCssSize);
- virtual ~gfxPangoFontGroup();
-
- virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
-
- virtual gfxFont* GetFirstValidFont(uint32_t aCh = 0x20);
-
- virtual void UpdateUserFonts();
-
- virtual already_AddRefed<gfxFont>
- FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
- Script aRunScript, gfxFont *aPrevMatchedFont,
- uint8_t *aMatchType);
-
- static void Shutdown();
-
- // Used for @font-face { src: local(); }
- static gfxFontEntry *NewFontEntry(const nsAString& aFontName,
- uint16_t aWeight,
- int16_t aStretch,
- uint8_t aStyle);
- // Used for @font-face { src: url(); }
- static gfxFontEntry *NewFontEntry(const nsAString& aFontName,
- uint16_t aWeight,
- int16_t aStretch,
- uint8_t aStyle,
- const uint8_t* aFontData,
- uint32_t aLength);
-
-private:
-
- virtual gfxFont *GetFontAt(int32_t i, uint32_t aCh = 0x20);
-
- // @param aLang [in] language to use for pref fonts and system default font
- // selection, or nullptr for the language guessed from the
- // gfxFontStyle.
- // The FontGroup holds a reference to this set.
- gfxFcFontSet *GetFontSet(PangoLanguage *aLang = nullptr);
-
- class FontSetByLangEntry {
- public:
- FontSetByLangEntry(PangoLanguage *aLang, gfxFcFontSet *aFontSet);
- PangoLanguage *mLang;
- RefPtr<gfxFcFontSet> mFontSet;
- };
- // There is only one of entry in this array unless characters from scripts
- // of other languages are measured.
- AutoTArray<FontSetByLangEntry,1> mFontSets;
-
- gfxFloat mSizeAdjustFactor;
- PangoLanguage *mPangoLanguage;
-
- // @param aLang [in] language to use for pref fonts and system font
- // resolution, or nullptr to guess a language from the gfxFontStyle.
- // @param aMatchPattern [out] if non-nullptr, will return the pattern used.
- already_AddRefed<gfxFcFontSet>
- MakeFontSet(PangoLanguage *aLang, gfxFloat aSizeAdjustFactor,
- nsAutoRef<FcPattern> *aMatchPattern = nullptr);
-
- gfxFcFontSet *GetBaseFontSet();
- gfxFcFont *GetBaseFont();
-
- gfxFloat GetSizeAdjustFactor()
- {
- if (mFontSets.Length() == 0)
- GetBaseFontSet();
- return mSizeAdjustFactor;
- }
-
- // old helper methods from gfxFontGroup, moved here so that those methods
- // can be revamped without affecting the legacy code here
-
- // iterate over the fontlist, lookup names and expand generics
- void EnumerateFontListPFG(nsIAtom *aLanguage, void *aClosure);
-
- // expand a generic to a list of specific names based on prefs
- void FindGenericFontsPFG(mozilla::FontFamilyType aGenericType,
- nsIAtom *aLanguage,
- void *aClosure);
-
- // lookup and add a font with a given name (i.e. *not* a generic!)
- void FindPlatformFontPFG(const nsAString& aName,
- bool aUseFontSet,
- void *aClosure);
-
- static void
- ResolveGenericFontNamesPFG(mozilla::FontFamilyType aGenericType,
- nsIAtom *aLanguage,
- nsTArray<nsString>& aGenericFamilies);
-
-
- friend class gfxSystemFcFontEntry;
- static FT_Library GetFTLibrary();
-};
-
-#endif /* GFX_FONTCONFIG_FONTS_H */
diff --git a/gfx/thebes/gfxFontconfigUtils.cpp b/gfx/thebes/gfxFontconfigUtils.cpp
deleted file mode 100644
index 5bf606c13e..0000000000
--- a/gfx/thebes/gfxFontconfigUtils.cpp
+++ /dev/null
@@ -1,1100 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/ArrayUtils.h"
-
-#include "gfxFontconfigUtils.h"
-#include "gfxFont.h"
-#include "nsGkAtoms.h"
-
-#include <locale.h>
-#include <fontconfig/fontconfig.h>
-
-#include "nsServiceManagerUtils.h"
-#include "nsILanguageAtomService.h"
-#include "nsTArray.h"
-#include "mozilla/Preferences.h"
-#include "nsDirectoryServiceUtils.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsAppDirectoryServiceDefs.h"
-
-#include "nsIAtom.h"
-#include "nsCRT.h"
-#include "gfxFontConstants.h"
-#include "mozilla/gfx/2D.h"
-
-using namespace mozilla;
-
-/* static */ gfxFontconfigUtils* gfxFontconfigUtils::sUtils = nullptr;
-static nsILanguageAtomService* gLangService = nullptr;
-
-/* static */ void
-gfxFontconfigUtils::Shutdown() {
- if (sUtils) {
- delete sUtils;
- sUtils = nullptr;
- }
- NS_IF_RELEASE(gLangService);
-}
-
-/* static */ uint8_t
-gfxFontconfigUtils::FcSlantToThebesStyle(int aFcSlant)
-{
- switch (aFcSlant) {
- case FC_SLANT_ITALIC:
- return NS_FONT_STYLE_ITALIC;
- case FC_SLANT_OBLIQUE:
- return NS_FONT_STYLE_OBLIQUE;
- default:
- return NS_FONT_STYLE_NORMAL;
- }
-}
-
-/* static */ uint8_t
-gfxFontconfigUtils::GetThebesStyle(FcPattern *aPattern)
-{
- int slant;
- if (FcPatternGetInteger(aPattern, FC_SLANT, 0, &slant) != FcResultMatch) {
- return NS_FONT_STYLE_NORMAL;
- }
-
- return FcSlantToThebesStyle(slant);
-}
-
-/* static */ int
-gfxFontconfigUtils::GetFcSlant(const gfxFontStyle& aFontStyle)
-{
- if (aFontStyle.style == NS_FONT_STYLE_ITALIC)
- return FC_SLANT_ITALIC;
- if (aFontStyle.style == NS_FONT_STYLE_OBLIQUE)
- return FC_SLANT_OBLIQUE;
-
- return FC_SLANT_ROMAN;
-}
-
-// OS/2 weight classes were introduced in fontconfig-2.1.93 (2003).
-#ifndef FC_WEIGHT_THIN
-#define FC_WEIGHT_THIN 0 // 2.1.93
-#define FC_WEIGHT_EXTRALIGHT 40 // 2.1.93
-#define FC_WEIGHT_REGULAR 80 // 2.1.93
-#define FC_WEIGHT_EXTRABOLD 205 // 2.1.93
-#endif
-// book was introduced in fontconfig-2.2.90 (and so fontconfig-2.3.0 in 2005)
-#ifndef FC_WEIGHT_BOOK
-#define FC_WEIGHT_BOOK 75
-#endif
-// extra black was introduced in fontconfig-2.4.91 (2007)
-#ifndef FC_WEIGHT_EXTRABLACK
-#define FC_WEIGHT_EXTRABLACK 215
-#endif
-
-/* static */ uint16_t
-gfxFontconfigUtils::GetThebesWeight(FcPattern *aPattern)
-{
- int weight;
- if (FcPatternGetInteger(aPattern, FC_WEIGHT, 0, &weight) != FcResultMatch)
- return NS_FONT_WEIGHT_NORMAL;
-
- if (weight <= (FC_WEIGHT_THIN + FC_WEIGHT_EXTRALIGHT) / 2)
- return 100;
- if (weight <= (FC_WEIGHT_EXTRALIGHT + FC_WEIGHT_LIGHT) / 2)
- return 200;
- if (weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_BOOK) / 2)
- return 300;
- if (weight <= (FC_WEIGHT_REGULAR + FC_WEIGHT_MEDIUM) / 2)
- // This includes FC_WEIGHT_BOOK
- return 400;
- if (weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2)
- return 500;
- if (weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2)
- return 600;
- if (weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_EXTRABOLD) / 2)
- return 700;
- if (weight <= (FC_WEIGHT_EXTRABOLD + FC_WEIGHT_BLACK) / 2)
- return 800;
- if (weight <= FC_WEIGHT_BLACK)
- return 900;
-
- // including FC_WEIGHT_EXTRABLACK
- return 901;
-}
-
-/* static */ int
-gfxFontconfigUtils::FcWeightForBaseWeight(int8_t aBaseWeight)
-{
- NS_PRECONDITION(aBaseWeight >= 0 && aBaseWeight <= 10,
- "base weight out of range");
-
- switch (aBaseWeight) {
- case 2:
- return FC_WEIGHT_EXTRALIGHT;
- case 3:
- return FC_WEIGHT_LIGHT;
- case 4:
- return FC_WEIGHT_REGULAR;
- case 5:
- return FC_WEIGHT_MEDIUM;
- case 6:
- return FC_WEIGHT_DEMIBOLD;
- case 7:
- return FC_WEIGHT_BOLD;
- case 8:
- return FC_WEIGHT_EXTRABOLD;
- case 9:
- return FC_WEIGHT_BLACK;
- }
-
- // extremes
- return aBaseWeight < 2 ? FC_WEIGHT_THIN : FC_WEIGHT_EXTRABLACK;
-}
-
-/* static */ int16_t
-gfxFontconfigUtils::GetThebesStretch(FcPattern *aPattern)
-{
- int width;
- if (FcPatternGetInteger(aPattern, FC_WIDTH, 0, &width) != FcResultMatch) {
- return NS_FONT_STRETCH_NORMAL;
- }
-
- if (width <= (FC_WIDTH_ULTRACONDENSED + FC_WIDTH_EXTRACONDENSED) / 2) {
- return NS_FONT_STRETCH_ULTRA_CONDENSED;
- }
- if (width <= (FC_WIDTH_EXTRACONDENSED + FC_WIDTH_CONDENSED) / 2) {
- return NS_FONT_STRETCH_EXTRA_CONDENSED;
- }
- if (width <= (FC_WIDTH_CONDENSED + FC_WIDTH_SEMICONDENSED) / 2) {
- return NS_FONT_STRETCH_CONDENSED;
- }
- if (width <= (FC_WIDTH_SEMICONDENSED + FC_WIDTH_NORMAL) / 2) {
- return NS_FONT_STRETCH_SEMI_CONDENSED;
- }
- if (width <= (FC_WIDTH_NORMAL + FC_WIDTH_SEMIEXPANDED) / 2) {
- return NS_FONT_STRETCH_NORMAL;
- }
- if (width <= (FC_WIDTH_SEMIEXPANDED + FC_WIDTH_EXPANDED) / 2) {
- return NS_FONT_STRETCH_SEMI_EXPANDED;
- }
- if (width <= (FC_WIDTH_EXPANDED + FC_WIDTH_EXTRAEXPANDED) / 2) {
- return NS_FONT_STRETCH_EXPANDED;
- }
- if (width <= (FC_WIDTH_EXTRAEXPANDED + FC_WIDTH_ULTRAEXPANDED) / 2) {
- return NS_FONT_STRETCH_EXTRA_EXPANDED;
- }
- return NS_FONT_STRETCH_ULTRA_EXPANDED;
-}
-
-/* static */ int
-gfxFontconfigUtils::FcWidthForThebesStretch(int16_t aStretch)
-{
- switch (aStretch) {
- default: // this will catch "normal" (0) as well as out-of-range values
- return FC_WIDTH_NORMAL;
- case NS_FONT_STRETCH_ULTRA_CONDENSED:
- return FC_WIDTH_ULTRACONDENSED;
- case NS_FONT_STRETCH_EXTRA_CONDENSED:
- return FC_WIDTH_EXTRACONDENSED;
- case NS_FONT_STRETCH_CONDENSED:
- return FC_WIDTH_CONDENSED;
- case NS_FONT_STRETCH_SEMI_CONDENSED:
- return FC_WIDTH_SEMICONDENSED;
- case NS_FONT_STRETCH_SEMI_EXPANDED:
- return FC_WIDTH_SEMIEXPANDED;
- case NS_FONT_STRETCH_EXPANDED:
- return FC_WIDTH_EXPANDED;
- case NS_FONT_STRETCH_EXTRA_EXPANDED:
- return FC_WIDTH_EXTRAEXPANDED;
- case NS_FONT_STRETCH_ULTRA_EXPANDED:
- return FC_WIDTH_ULTRAEXPANDED;
- }
-}
-
-// This makes a guess at an FC_WEIGHT corresponding to a base weight and
-// offset (without any knowledge of which weights are available).
-
-/* static */ int
-GuessFcWeight(const gfxFontStyle& aFontStyle)
-{
- /*
- * weights come in two parts crammed into one
- * integer -- the "base" weight is weight / 100,
- * the rest of the value is the "offset" from that
- * weight -- the number of steps to move to adjust
- * the weight in the list of supported font weights,
- * this value can be negative or positive.
- */
- int8_t weight = aFontStyle.ComputeWeight();
-
- // ComputeWeight trimmed the range of weights for us
- NS_ASSERTION(weight >= 0 && weight <= 10,
- "base weight out of range");
-
- return gfxFontconfigUtils::FcWeightForBaseWeight(weight);
-}
-
-static void
-AddString(FcPattern *aPattern, const char *object, const char *aString)
-{
- FcPatternAddString(aPattern, object,
- gfxFontconfigUtils::ToFcChar8(aString));
-}
-
-static void
-AddWeakString(FcPattern *aPattern, const char *object, const char *aString)
-{
- FcValue value;
- value.type = FcTypeString;
- value.u.s = gfxFontconfigUtils::ToFcChar8(aString);
-
- FcPatternAddWeak(aPattern, object, value, FcTrue);
-}
-
-static void
-AddLangGroup(FcPattern *aPattern, nsIAtom *aLangGroup)
-{
- // Translate from mozilla's internal mapping into fontconfig's
- nsAutoCString lang;
- gfxFontconfigUtils::GetSampleLangForGroup(aLangGroup, &lang);
-
- if (!lang.IsEmpty()) {
- AddString(aPattern, FC_LANG, lang.get());
- }
-}
-
-nsReturnRef<FcPattern>
-gfxFontconfigUtils::NewPattern(const nsTArray<nsString>& aFamilies,
- const gfxFontStyle& aFontStyle,
- const char *aLang)
-{
- static const char* sFontconfigGenerics[] =
- { "sans-serif", "serif", "monospace", "fantasy", "cursive" };
-
- nsAutoRef<FcPattern> pattern(FcPatternCreate());
- if (!pattern)
- return nsReturnRef<FcPattern>();
-
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, aFontStyle.size);
- FcPatternAddInteger(pattern, FC_SLANT, GetFcSlant(aFontStyle));
- FcPatternAddInteger(pattern, FC_WEIGHT, GuessFcWeight(aFontStyle));
- FcPatternAddInteger(pattern, FC_WIDTH, FcWidthForThebesStretch(aFontStyle.stretch));
-
- if (aLang) {
- AddString(pattern, FC_LANG, aLang);
- }
-
- bool useWeakBinding = false;
- for (uint32_t i = 0; i < aFamilies.Length(); ++i) {
- NS_ConvertUTF16toUTF8 family(aFamilies[i]);
- if (!useWeakBinding) {
- AddString(pattern, FC_FAMILY, family.get());
-
- // fontconfig generic families are typically implemented with weak
- // aliases (so that the preferred font depends on language).
- // However, this would give them lower priority than subsequent
- // non-generic families in the list. To ensure that subsequent
- // families do not have a higher priority, they are given weak
- // bindings.
- for (uint32_t g = 0;
- g < ArrayLength(sFontconfigGenerics);
- ++g) {
- if (0 == FcStrCmpIgnoreCase(ToFcChar8(sFontconfigGenerics[g]),
- ToFcChar8(family.get()))) {
- useWeakBinding = true;
- break;
- }
- }
- } else {
- AddWeakString(pattern, FC_FAMILY, family.get());
- }
- }
-
- return pattern.out();
-}
-
-gfxFontconfigUtils::gfxFontconfigUtils()
- : mFontsByFamily(32)
- , mFontsByFullname(32)
- , mLangSupportTable(32)
- , mLastConfig(nullptr)
-#ifdef MOZ_BUNDLED_FONTS
- , mBundledFontsInitialized(false)
-#endif
-{
- UpdateFontListInternal();
-}
-
-nsresult
-gfxFontconfigUtils::GetFontList(nsIAtom *aLangGroup,
- const nsACString& aGenericFamily,
- nsTArray<nsString>& aListOfFonts)
-{
- aListOfFonts.Clear();
-
- nsTArray<nsCString> fonts;
- nsresult rv = GetFontListInternal(fonts, aLangGroup);
- if (NS_FAILED(rv))
- return rv;
-
- for (uint32_t i = 0; i < fonts.Length(); ++i) {
- aListOfFonts.AppendElement(NS_ConvertUTF8toUTF16(fonts[i]));
- }
-
- aListOfFonts.Sort();
-
- int32_t serif = 0, sansSerif = 0, monospace = 0;
-
- // Fontconfig supports 3 generic fonts, "serif", "sans-serif", and
- // "monospace", slightly different from CSS's 5.
- if (aGenericFamily.IsEmpty())
- serif = sansSerif = monospace = 1;
- else if (aGenericFamily.LowerCaseEqualsLiteral("serif"))
- serif = 1;
- else if (aGenericFamily.LowerCaseEqualsLiteral("sans-serif"))
- sansSerif = 1;
- else if (aGenericFamily.LowerCaseEqualsLiteral("monospace"))
- monospace = 1;
- else if (aGenericFamily.LowerCaseEqualsLiteral("cursive") ||
- aGenericFamily.LowerCaseEqualsLiteral("fantasy"))
- serif = sansSerif = 1;
- else
- NS_NOTREACHED("unexpected CSS generic font family");
-
- // The first in the list becomes the default in
- // FontBuilder.readFontSelection() if the preference-selected font is not
- // available, so put system configured defaults first.
- if (monospace)
- aListOfFonts.InsertElementAt(0, NS_LITERAL_STRING("monospace"));
- if (sansSerif)
- aListOfFonts.InsertElementAt(0, NS_LITERAL_STRING("sans-serif"));
- if (serif)
- aListOfFonts.InsertElementAt(0, NS_LITERAL_STRING("serif"));
-
- return NS_OK;
-}
-
-struct MozLangGroupData {
- nsIAtom* const& mozLangGroup;
- const char *defaultLang;
-};
-
-const MozLangGroupData MozLangGroups[] = {
- { nsGkAtoms::x_western, "en" },
- { nsGkAtoms::x_cyrillic, "ru" },
- { nsGkAtoms::x_devanagari, "hi" },
- { nsGkAtoms::x_tamil, "ta" },
- { nsGkAtoms::x_armn, "hy" },
- { nsGkAtoms::x_beng, "bn" },
- { nsGkAtoms::x_cans, "iu" },
- { nsGkAtoms::x_ethi, "am" },
- { nsGkAtoms::x_geor, "ka" },
- { nsGkAtoms::x_gujr, "gu" },
- { nsGkAtoms::x_guru, "pa" },
- { nsGkAtoms::x_khmr, "km" },
- { nsGkAtoms::x_knda, "kn" },
- { nsGkAtoms::x_mlym, "ml" },
- { nsGkAtoms::x_orya, "or" },
- { nsGkAtoms::x_sinh, "si" },
- { nsGkAtoms::x_telu, "te" },
- { nsGkAtoms::x_tibt, "bo" },
- { nsGkAtoms::Unicode, 0 },
-};
-
-static bool
-TryLangForGroup(const nsACString& aOSLang, nsIAtom *aLangGroup,
- nsACString *aFcLang)
-{
- // Truncate at '.' or '@' from aOSLang, and convert '_' to '-'.
- // aOSLang is in the form "language[_territory][.codeset][@modifier]".
- // fontconfig takes languages in the form "language-territory".
- // nsILanguageAtomService takes languages in the form language-subtag,
- // where subtag may be a territory. fontconfig and nsILanguageAtomService
- // handle case-conversion for us.
- const char *pos, *end;
- aOSLang.BeginReading(pos);
- aOSLang.EndReading(end);
- aFcLang->Truncate();
- while (pos < end) {
- switch (*pos) {
- case '.':
- case '@':
- end = pos;
- break;
- case '_':
- aFcLang->Append('-');
- break;
- default:
- aFcLang->Append(*pos);
- }
- ++pos;
- }
-
- nsIAtom *atom =
- gLangService->LookupLanguage(*aFcLang);
-
- return atom == aLangGroup;
-}
-
-/* static */ void
-gfxFontconfigUtils::GetSampleLangForGroup(nsIAtom *aLangGroup,
- nsACString *aFcLang)
-{
- NS_PRECONDITION(aFcLang != nullptr, "aFcLang must not be NULL");
-
- const MozLangGroupData *langGroup = nullptr;
-
- for (unsigned int i = 0; i < ArrayLength(MozLangGroups); ++i) {
- if (aLangGroup == MozLangGroups[i].mozLangGroup) {
- langGroup = &MozLangGroups[i];
- break;
- }
- }
-
- if (!langGroup) {
- // Not a special mozilla language group.
- // Use aLangGroup as a language code.
- aLangGroup->ToUTF8String(*aFcLang);
- return;
- }
-
- // Check the environment for the users preferred language that corresponds
- // to this langGroup.
- if (!gLangService) {
- CallGetService(NS_LANGUAGEATOMSERVICE_CONTRACTID, &gLangService);
- }
-
- if (gLangService) {
- const char *languages = getenv("LANGUAGE");
- if (languages) {
- const char separator = ':';
-
- for (const char *pos = languages; true; ++pos) {
- if (*pos == '\0' || *pos == separator) {
- if (languages < pos &&
- TryLangForGroup(Substring(languages, pos),
- aLangGroup, aFcLang))
- return;
-
- if (*pos == '\0')
- break;
-
- languages = pos + 1;
- }
- }
- }
- const char *ctype = setlocale(LC_CTYPE, nullptr);
- if (ctype &&
- TryLangForGroup(nsDependentCString(ctype), aLangGroup, aFcLang))
- return;
- }
-
- if (langGroup->defaultLang) {
- aFcLang->Assign(langGroup->defaultLang);
- } else {
- aFcLang->Truncate();
- }
-}
-
-nsresult
-gfxFontconfigUtils::GetFontListInternal(nsTArray<nsCString>& aListOfFonts,
- nsIAtom *aLangGroup)
-{
- FcPattern *pat = nullptr;
- FcObjectSet *os = nullptr;
- FcFontSet *fs = nullptr;
- nsresult rv = NS_ERROR_FAILURE;
-
- aListOfFonts.Clear();
-
- pat = FcPatternCreate();
- if (!pat)
- goto end;
-
- os = FcObjectSetBuild(FC_FAMILY, nullptr);
- if (!os)
- goto end;
-
- // take the pattern and add the lang group to it
- if (aLangGroup) {
- AddLangGroup(pat, aLangGroup);
- }
-
- fs = FcFontList(nullptr, pat, os);
- if (!fs)
- goto end;
-
- for (int i = 0; i < fs->nfont; i++) {
- char *family;
-
- if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0,
- (FcChar8 **) &family) != FcResultMatch)
- {
- continue;
- }
-
- // Remove duplicates...
- nsAutoCString strFamily(family);
- if (aListOfFonts.Contains(strFamily))
- continue;
-
- aListOfFonts.AppendElement(strFamily);
- }
-
- rv = NS_OK;
-
- end:
- if (NS_FAILED(rv))
- aListOfFonts.Clear();
-
- if (pat)
- FcPatternDestroy(pat);
- if (os)
- FcObjectSetDestroy(os);
- if (fs)
- FcFontSetDestroy(fs);
-
- return rv;
-}
-
-nsresult
-gfxFontconfigUtils::UpdateFontList()
-{
- return UpdateFontListInternal(true);
-}
-
-nsresult
-gfxFontconfigUtils::UpdateFontListInternal(bool aForce)
-{
- if (!aForce) {
- // This checks periodically according to fontconfig's configured
- // <rescan> interval.
- FcInitBringUptoDate();
- } else if (!FcConfigUptoDate(nullptr)) { // check now with aForce
- mLastConfig = nullptr;
- FcInitReinitialize();
- }
-
- // FcInitReinitialize() (used by FcInitBringUptoDate) creates a new config
- // before destroying the old config, so the only way that we'd miss an
- // update is if fontconfig did more than one update and the memory for the
- // most recent config happened to be at the same location as the original
- // config.
- FcConfig *currentConfig = FcConfigGetCurrent();
- if (currentConfig == mLastConfig)
- return NS_OK;
-
-#ifdef MOZ_BUNDLED_FONTS
- ActivateBundledFonts();
-#endif
-
- // These FcFontSets are owned by fontconfig
- FcFontSet *fontSets[] = {
- FcConfigGetFonts(currentConfig, FcSetSystem)
-#ifdef MOZ_BUNDLED_FONTS
- , FcConfigGetFonts(currentConfig, FcSetApplication)
-#endif
- };
-
- mFontsByFamily.Clear();
- mFontsByFullname.Clear();
- mLangSupportTable.Clear();
-
- // Record the existing font families
- for (unsigned fs = 0; fs < ArrayLength(fontSets); ++fs) {
- FcFontSet *fontSet = fontSets[fs];
- if (!fontSet) { // the application set might not exist
- continue;
- }
- for (int f = 0; f < fontSet->nfont; ++f) {
- FcPattern *font = fontSet->fonts[f];
-
- FcChar8 *family;
- for (int v = 0;
- FcPatternGetString(font, FC_FAMILY, v, &family) == FcResultMatch;
- ++v) {
- FontsByFcStrEntry *entry = mFontsByFamily.PutEntry(family);
- if (entry) {
- bool added = entry->AddFont(font);
-
- if (!entry->mKey) {
- // The reference to the font pattern keeps the pointer
- // to string for the key valid. If adding the font
- // failed then the entry must be removed.
- if (added) {
- entry->mKey = family;
- } else {
- mFontsByFamily.RemoveEntry(entry);
- }
- }
- }
- }
- }
- }
-
- mLastConfig = currentConfig;
- return NS_OK;
-}
-
-nsresult
-gfxFontconfigUtils::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
-{
- aFamilyName.Truncate();
-
- // The fontconfig has generic family names in the font list.
- if (aFontName.EqualsLiteral("serif") ||
- aFontName.EqualsLiteral("sans-serif") ||
- aFontName.EqualsLiteral("monospace")) {
- aFamilyName.Assign(aFontName);
- return NS_OK;
- }
-
- nsresult rv = UpdateFontListInternal();
- if (NS_FAILED(rv))
- return rv;
-
- NS_ConvertUTF16toUTF8 fontname(aFontName);
-
- // return empty string if no such family exists
- if (!IsExistingFamily(fontname))
- return NS_OK;
-
- FcPattern *pat = nullptr;
- FcObjectSet *os = nullptr;
- FcFontSet *givenFS = nullptr;
- nsTArray<nsCString> candidates;
- FcFontSet *candidateFS = nullptr;
- rv = NS_ERROR_FAILURE;
-
- pat = FcPatternCreate();
- if (!pat)
- goto end;
-
- FcPatternAddString(pat, FC_FAMILY, (FcChar8 *)fontname.get());
-
- os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, nullptr);
- if (!os)
- goto end;
-
- givenFS = FcFontList(nullptr, pat, os);
- if (!givenFS)
- goto end;
-
- // The first value associated with a FC_FAMILY property is the family
- // returned by GetFontList(), so use this value if appropriate.
-
- // See if there is a font face with first family equal to the given family.
- for (int i = 0; i < givenFS->nfont; ++i) {
- char *firstFamily;
- if (FcPatternGetString(givenFS->fonts[i], FC_FAMILY, 0,
- (FcChar8 **) &firstFamily) != FcResultMatch)
- continue;
-
- nsDependentCString first(firstFamily);
- if (!candidates.Contains(first)) {
- candidates.AppendElement(first);
-
- if (fontname.Equals(first)) {
- aFamilyName.Assign(aFontName);
- rv = NS_OK;
- goto end;
- }
- }
- }
-
- // See if any of the first family names represent the same set of font
- // faces as the given family.
- for (uint32_t j = 0; j < candidates.Length(); ++j) {
- FcPatternDel(pat, FC_FAMILY);
- FcPatternAddString(pat, FC_FAMILY, (FcChar8 *)candidates[j].get());
-
- candidateFS = FcFontList(nullptr, pat, os);
- if (!candidateFS)
- goto end;
-
- if (candidateFS->nfont != givenFS->nfont)
- continue;
-
- bool equal = true;
- for (int i = 0; i < givenFS->nfont; ++i) {
- if (!FcPatternEqual(candidateFS->fonts[i], givenFS->fonts[i])) {
- equal = false;
- break;
- }
- }
- if (equal) {
- AppendUTF8toUTF16(candidates[j], aFamilyName);
- rv = NS_OK;
- goto end;
- }
- }
-
- // No match found; return empty string.
- rv = NS_OK;
-
- end:
- if (pat)
- FcPatternDestroy(pat);
- if (os)
- FcObjectSetDestroy(os);
- if (givenFS)
- FcFontSetDestroy(givenFS);
- if (candidateFS)
- FcFontSetDestroy(candidateFS);
-
- return rv;
-}
-
-bool
-gfxFontconfigUtils::IsExistingFamily(const nsCString& aFamilyName)
-{
- return mFontsByFamily.GetEntry(ToFcChar8(aFamilyName)) != nullptr;
-}
-
-const nsTArray< nsCountedRef<FcPattern> >&
-gfxFontconfigUtils::GetFontsForFamily(const FcChar8 *aFamilyName)
-{
- FontsByFcStrEntry *entry = mFontsByFamily.GetEntry(aFamilyName);
-
- if (!entry)
- return mEmptyPatternArray;
-
- return entry->GetFonts();
-}
-
-// Fontconfig only provides a fullname property for fonts in formats with SFNT
-// wrappers. For other font formats (including PCF and PS Type 1), a fullname
-// must be generated from the family and style properties. Only the first
-// family and style is checked, but that should be OK, as I don't expect
-// non-SFNT fonts to have multiple families or styles.
-bool
-gfxFontconfigUtils::GetFullnameFromFamilyAndStyle(FcPattern *aFont,
- nsACString *aFullname)
-{
- FcChar8 *family;
- if (FcPatternGetString(aFont, FC_FAMILY, 0, &family) != FcResultMatch)
- return false;
-
- aFullname->Truncate();
- aFullname->Append(ToCString(family));
-
- FcChar8 *style;
- if (FcPatternGetString(aFont, FC_STYLE, 0, &style) == FcResultMatch &&
- strcmp(ToCString(style), "Regular") != 0) {
- aFullname->Append(' ');
- aFullname->Append(ToCString(style));
- }
-
- return true;
-}
-
-bool
-gfxFontconfigUtils::FontsByFullnameEntry::KeyEquals(KeyTypePointer aKey) const
-{
- const FcChar8 *key = mKey;
- // If mKey is nullptr, key comes from the style and family of the first
- // font.
- nsAutoCString fullname;
- if (!key) {
- NS_ASSERTION(mFonts.Length(), "No font in FontsByFullnameEntry!");
- GetFullnameFromFamilyAndStyle(mFonts[0], &fullname);
-
- key = ToFcChar8(fullname);
- }
-
- return FcStrCmpIgnoreCase(aKey, key) == 0;
-}
-
-void
-gfxFontconfigUtils::AddFullnameEntries()
-{
- // These FcFontSets are owned by fontconfig
- FcFontSet *fontSets[] = {
- FcConfigGetFonts(nullptr, FcSetSystem)
-#ifdef MOZ_BUNDLED_FONTS
- , FcConfigGetFonts(nullptr, FcSetApplication)
-#endif
- };
-
- for (unsigned fs = 0; fs < ArrayLength(fontSets); ++fs) {
- FcFontSet *fontSet = fontSets[fs];
- if (!fontSet) {
- continue;
- }
- // Record the existing font families
- for (int f = 0; f < fontSet->nfont; ++f) {
- FcPattern *font = fontSet->fonts[f];
-
- int v = 0;
- FcChar8 *fullname;
- while (FcPatternGetString(font,
- FC_FULLNAME, v, &fullname) == FcResultMatch) {
- FontsByFullnameEntry *entry =
- mFontsByFullname.PutEntry(fullname);
- if (entry) {
- // entry always has space for one font, so the first
- // AddFont will always succeed, and so the entry will
- // always have a font from which to obtain the key.
- bool added = entry->AddFont(font);
- // The key may be nullptr either if this is the first
- // font, or if the first font does not have a fullname
- // property, and so the key is obtained from the font.
- // Set the key in both cases. The check that AddFont
- // succeeded is required for the second case.
- if (!entry->mKey && added) {
- entry->mKey = fullname;
- }
- }
-
- ++v;
- }
-
- // Fontconfig does not provide a fullname property for all fonts.
- if (v == 0) {
- nsAutoCString name;
- if (!GetFullnameFromFamilyAndStyle(font, &name))
- continue;
-
- FontsByFullnameEntry *entry =
- mFontsByFullname.PutEntry(ToFcChar8(name));
- if (entry) {
- entry->AddFont(font);
- // Either entry->mKey has been set for a previous font or it
- // remains nullptr to indicate that the key is obtained from
- // the first font.
- }
- }
- }
- }
-}
-
-const nsTArray< nsCountedRef<FcPattern> >&
-gfxFontconfigUtils::GetFontsForFullname(const FcChar8 *aFullname)
-{
- if (mFontsByFullname.Count() == 0) {
- AddFullnameEntries();
- }
-
- FontsByFullnameEntry *entry = mFontsByFullname.GetEntry(aFullname);
-
- if (!entry)
- return mEmptyPatternArray;
-
- return entry->GetFonts();
-}
-
-static FcLangResult
-CompareLangString(const FcChar8 *aLangA, const FcChar8 *aLangB) {
- FcLangResult result = FcLangDifferentLang;
- for (uint32_t i = 0; ; ++i) {
- FcChar8 a = FcToLower(aLangA[i]);
- FcChar8 b = FcToLower(aLangB[i]);
-
- if (a != b) {
- if ((a == '\0' && b == '-') || (a == '-' && b == '\0'))
- return FcLangDifferentCountry;
-
- return result;
- }
- if (a == '\0')
- return FcLangEqual;
-
- if (a == '-') {
- result = FcLangDifferentCountry;
- }
- }
-}
-
-/* static */
-FcLangResult
-gfxFontconfigUtils::GetLangSupport(FcPattern *aFont, const FcChar8 *aLang)
-{
- // When fontconfig builds a pattern for a system font, it will set a
- // single LangSet property value for the font. That value may be removed
- // and additional string values may be added through FcConfigSubsitute
- // with FcMatchScan. Values that are neither LangSet nor string are
- // considered errors in fontconfig sort and match functions.
- //
- // If no string nor LangSet value is found, then either the font is a
- // system font and the LangSet has been removed through FcConfigSubsitute,
- // or the font is a web font and its language support is unknown.
- // Returning FcLangDifferentLang for these fonts ensures that this font
- // will not be assumed to satisfy the language, and so language will be
- // prioritized in sorting fallback fonts.
- FcValue value;
- FcLangResult best = FcLangDifferentLang;
- for (int v = 0;
- FcPatternGet(aFont, FC_LANG, v, &value) == FcResultMatch;
- ++v) {
-
- FcLangResult support;
- switch (value.type) {
- case FcTypeLangSet:
- support = FcLangSetHasLang(value.u.l, aLang);
- break;
- case FcTypeString:
- support = CompareLangString(value.u.s, aLang);
- break;
- default:
- // error. continue to see if there is a useful value.
- continue;
- }
-
- if (support < best) { // lower is better
- if (support == FcLangEqual)
- return support;
- best = support;
- }
- }
-
- return best;
-}
-
-gfxFontconfigUtils::LangSupportEntry *
-gfxFontconfigUtils::GetLangSupportEntry(const FcChar8 *aLang, bool aWithFonts)
-{
- // Currently any unrecognized languages from documents will be converted
- // to x-unicode by nsILanguageAtomService, so there is a limit on the
- // langugages that will be added here. Reconsider when/if document
- // languages are passed to this routine.
-
- LangSupportEntry *entry = mLangSupportTable.PutEntry(aLang);
- if (!entry)
- return nullptr;
-
- FcLangResult best = FcLangDifferentLang;
-
- if (!entry->IsKeyInitialized()) {
- entry->InitKey(aLang);
- } else {
- // mSupport is already initialized.
- if (!aWithFonts)
- return entry;
-
- best = entry->mSupport;
- // If there is support for this language, an empty font list indicates
- // that the list hasn't been initialized yet.
- if (best == FcLangDifferentLang || entry->mFonts.Length() > 0)
- return entry;
- }
-
- // These FcFontSets are owned by fontconfig
- FcFontSet *fontSets[] = {
- FcConfigGetFonts(nullptr, FcSetSystem)
-#ifdef MOZ_BUNDLED_FONTS
- , FcConfigGetFonts(nullptr, FcSetApplication)
-#endif
- };
-
- AutoTArray<FcPattern*,100> fonts;
-
- for (unsigned fs = 0; fs < ArrayLength(fontSets); ++fs) {
- FcFontSet *fontSet = fontSets[fs];
- if (!fontSet) {
- continue;
- }
- for (int f = 0; f < fontSet->nfont; ++f) {
- FcPattern *font = fontSet->fonts[f];
-
- FcLangResult support = GetLangSupport(font, aLang);
-
- if (support < best) { // lower is better
- best = support;
- if (aWithFonts) {
- fonts.Clear();
- } else if (best == FcLangEqual) {
- break;
- }
- }
-
- // The font list in the LangSupportEntry is expected to be used
- // only when no default fonts support the language. There would
- // be a large number of fonts in entries for languages using Latin
- // script but these do not need to be created because default
- // fonts already support these languages.
- if (aWithFonts && support != FcLangDifferentLang &&
- support == best) {
- fonts.AppendElement(font);
- }
- }
- }
-
- entry->mSupport = best;
- if (aWithFonts) {
- if (fonts.Length() != 0) {
- entry->mFonts.AppendElements(fonts.Elements(), fonts.Length());
- } else if (best != FcLangDifferentLang) {
- // Previously there was a font that supported this language at the
- // level of entry->mSupport, but it has now disappeared. At least
- // entry->mSupport needs to be recalculated, but this is an
- // indication that the set of installed fonts has changed, so
- // update all caches.
- mLastConfig = nullptr; // invalidates caches
- UpdateFontListInternal(true);
- return GetLangSupportEntry(aLang, aWithFonts);
- }
- }
-
- return entry;
-}
-
-FcLangResult
-gfxFontconfigUtils::GetBestLangSupport(const FcChar8 *aLang)
-{
- UpdateFontListInternal();
-
- LangSupportEntry *entry = GetLangSupportEntry(aLang, false);
- if (!entry)
- return FcLangEqual;
-
- return entry->mSupport;
-}
-
-const nsTArray< nsCountedRef<FcPattern> >&
-gfxFontconfigUtils::GetFontsForLang(const FcChar8 *aLang)
-{
- LangSupportEntry *entry = GetLangSupportEntry(aLang, true);
- if (!entry)
- return mEmptyPatternArray;
-
- return entry->mFonts;
-}
-
-#ifdef MOZ_BUNDLED_FONTS
-
-void
-gfxFontconfigUtils::ActivateBundledFonts()
-{
- if (!mBundledFontsInitialized) {
- mBundledFontsInitialized = true;
- nsCOMPtr<nsIFile> localDir;
- nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir));
- if (NS_FAILED(rv)) {
- return;
- }
- if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("fonts")))) {
- return;
- }
- bool isDir;
- if (NS_FAILED(localDir->IsDirectory(&isDir)) || !isDir) {
- return;
- }
- if (NS_FAILED(localDir->GetNativePath(mBundledFontsPath))) {
- return;
- }
- }
- if (!mBundledFontsPath.IsEmpty()) {
- FcConfigAppFontAddDir(nullptr, (const FcChar8*)mBundledFontsPath.get());
- }
-}
-
-#endif
-
-gfxFontconfigFontBase::gfxFontconfigFontBase(cairo_scaled_font_t *aScaledFont,
- FcPattern *aPattern,
- gfxFontEntry *aFontEntry,
- const gfxFontStyle *aFontStyle)
- : gfxFT2FontBase(aScaledFont, aFontEntry, aFontStyle)
- , mPattern(aPattern)
-{
-}
-
diff --git a/gfx/thebes/gfxFontconfigUtils.h b/gfx/thebes/gfxFontconfigUtils.h
index eee69e4816..3f502c1243 100644
--- a/gfx/thebes/gfxFontconfigUtils.h
+++ b/gfx/thebes/gfxFontconfigUtils.h
@@ -8,11 +8,7 @@
#include "gfxPlatform.h"
-#include "mozilla/MathAlgorithms.h"
#include "nsAutoRef.h"
-#include "nsTArray.h"
-#include "nsTHashtable.h"
-#include "nsISupportsImpl.h"
#include "gfxFT2FontBase.h"
#include <fontconfig/fontconfig.h>
@@ -40,285 +36,14 @@ public:
static void Release(FcCharSet *ptr) { FcCharSetDestroy(ptr); }
};
-class gfxIgnoreCaseCStringComparator
-{
- public:
- bool Equals(const nsACString& a, const nsACString& b) const
- {
- return nsCString(a).Equals(b, nsCaseInsensitiveCStringComparator());
- }
-
- bool LessThan(const nsACString& a, const nsACString& b) const
- {
- return a < b;
- }
-};
-
-class gfxFontconfigUtils {
-public:
- gfxFontconfigUtils();
-
- static gfxFontconfigUtils* GetFontconfigUtils() {
- if (!sUtils)
- sUtils = new gfxFontconfigUtils();
- return sUtils;
- }
-
- static void Shutdown();
-
- nsresult GetFontList(nsIAtom *aLangGroup,
- const nsACString& aGenericFamily,
- nsTArray<nsString>& aListOfFonts);
-
- nsresult UpdateFontList();
-
- nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
-
- const nsTArray< nsCountedRef<FcPattern> >&
- GetFontsForFamily(const FcChar8 *aFamilyName);
-
- const nsTArray< nsCountedRef<FcPattern> >&
- GetFontsForFullname(const FcChar8 *aFullname);
-
- // Returns the best support that any font offers for |aLang|.
- FcLangResult GetBestLangSupport(const FcChar8 *aLang);
- // Returns the fonts offering this best level of support.
- const nsTArray< nsCountedRef<FcPattern> >&
- GetFontsForLang(const FcChar8 *aLang);
-
- // Retuns the language support for a fontconfig font pattern
- static FcLangResult GetLangSupport(FcPattern *aFont, const FcChar8 *aLang);
-
- // Conversions between FcChar8*, which is unsigned char*,
- // and (signed) char*, that check the type of the argument.
- static const FcChar8 *ToFcChar8(const char *aCharPtr)
- {
- return reinterpret_cast<const FcChar8*>(aCharPtr);
- }
- static const FcChar8 *ToFcChar8(const nsCString& aCString)
- {
- return ToFcChar8(aCString.get());
- }
- static const char *ToCString(const FcChar8 *aChar8Ptr)
- {
- return reinterpret_cast<const char*>(aChar8Ptr);
- }
-
- static uint8_t FcSlantToThebesStyle(int aFcSlant);
- static uint8_t GetThebesStyle(FcPattern *aPattern); // slant
- static uint16_t GetThebesWeight(FcPattern *aPattern);
- static int16_t GetThebesStretch(FcPattern *aPattern);
-
- static int GetFcSlant(const gfxFontStyle& aFontStyle);
- // Returns a precise FC_WEIGHT from |aBaseWeight|,
- // which is a CSS absolute weight / 100.
- static int FcWeightForBaseWeight(int8_t aBaseWeight);
-
- static int FcWidthForThebesStretch(int16_t aStretch);
-
- static bool GetFullnameFromFamilyAndStyle(FcPattern *aFont,
- nsACString *aFullname);
-
- // This doesn't consider which faces exist, and so initializes the pattern
- // using a guessed weight, and doesn't consider sizeAdjust.
- static nsReturnRef<FcPattern>
- NewPattern(const nsTArray<nsString>& aFamilies,
- const gfxFontStyle& aFontStyle, const char *aLang);
-
- /**
- * @param aLangGroup [in] a Mozilla langGroup.
- * @param aFcLang [out] returns a language suitable for fontconfig
- * matching |aLangGroup| or an empty string if no match is found.
- */
- static void GetSampleLangForGroup(nsIAtom *aLangGroup,
- nsACString *aFcLang);
-
-protected:
- // Base class for hash table entries with case-insensitive FcChar8
- // string keys.
- class FcStrEntryBase : public PLDHashEntryHdr {
- public:
- typedef const FcChar8 *KeyType;
- typedef const FcChar8 *KeyTypePointer;
-
- static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
- // Case-insensitive hash.
- //
- // fontconfig always ignores case of ASCII characters in family
- // names and languages, but treatment of whitespace in families is
- // not consistent. FcFontSort and FcFontMatch ignore whitespace
- // except for whitespace in the first character, while FcFontList
- // and config subsitution tests require whitespace to match
- // exactly. CSS 2.1 implies that whitespace is important in the
- // font-family property. FcStrCmpIgnoreCase considers whitespace
- // important.
- static PLDHashNumber HashKey(const FcChar8 *aKey) {
- uint32_t hash = 0;
- for (const FcChar8 *c = aKey; *c != '\0'; ++c) {
- hash = mozilla::RotateLeft(hash, 3) ^ FcToLower(*c);
- }
- return hash;
- }
- enum { ALLOW_MEMMOVE = true };
- };
-
-public:
- // Hash entry with a dependent const FcChar8* pointer to an external
- // string for a key (and no data). The user must ensure that the string
- // associated with the pointer is not destroyed. This entry type is
- // useful for family name keys as the family name string is held in the
- // font pattern.
- class DepFcStrEntry : public FcStrEntryBase {
- public:
- // When constructing a new entry in the hashtable, the key is left
- // nullptr. The caller of PutEntry() must fill in mKey when nullptr.
- // This provides a mechanism for the caller of PutEntry() to determine
- // whether the entry has been initialized.
- explicit DepFcStrEntry(KeyTypePointer aName)
- : mKey(nullptr) { }
-
- DepFcStrEntry(const DepFcStrEntry& toCopy)
- : mKey(toCopy.mKey) { }
-
- bool KeyEquals(KeyTypePointer aKey) const {
- return FcStrCmpIgnoreCase(aKey, mKey) == 0;
- }
-
- const FcChar8 *mKey;
- };
-
- // Hash entry that uses a copy of an FcChar8 string to store the key.
- // This entry type is useful for language keys, as languages are usually
- // not stored as strings in font patterns.
- class CopiedFcStrEntry : public FcStrEntryBase {
- public:
- // When constructing a new entry in the hashtable, the key is void.
- // The caller of PutEntry() must call InitKey() when IsKeyInitialized()
- // returns false. This provides a mechanism for the caller of
- // PutEntry() to determine whether the entry has been initialized.
- explicit CopiedFcStrEntry(KeyTypePointer aName) {
- mKey.SetIsVoid(true);
- }
-
- CopiedFcStrEntry(const CopiedFcStrEntry& toCopy)
- : mKey(toCopy.mKey) { }
-
- bool KeyEquals(KeyTypePointer aKey) const {
- return FcStrCmpIgnoreCase(aKey, ToFcChar8(mKey)) == 0;
- }
-
- bool IsKeyInitialized() { return !mKey.IsVoid(); }
- void InitKey(const FcChar8* aKey) { mKey.Assign(ToCString(aKey)); }
-
- private:
- nsCString mKey;
- };
-
-protected:
- class FontsByFcStrEntry : public DepFcStrEntry {
- public:
- explicit FontsByFcStrEntry(KeyTypePointer aName)
- : DepFcStrEntry(aName) { }
-
- FontsByFcStrEntry(const FontsByFcStrEntry& toCopy)
- : DepFcStrEntry(toCopy), mFonts(toCopy.mFonts) { }
-
- bool AddFont(FcPattern *aFont) {
- return mFonts.AppendElement(aFont) != nullptr;
- }
- const nsTArray< nsCountedRef<FcPattern> >& GetFonts() {
- return mFonts;
- }
- private:
- nsTArray< nsCountedRef<FcPattern> > mFonts;
- };
-
- // FontsByFullnameEntry is similar to FontsByFcStrEntry (used for
- // mFontsByFamily) except for two differences:
- //
- // * The font does not always contain a single string for the fullname, so
- // the key is sometimes a combination of family and style.
- //
- // * There is usually only one font.
- class FontsByFullnameEntry : public DepFcStrEntry {
- public:
- // When constructing a new entry in the hashtable, the key is left
- // nullptr. The caller of PutEntry() is must fill in mKey when adding
- // the first font if the key is not derived from the family and style.
- // If the key is derived from family and style, a font must be added.
- explicit FontsByFullnameEntry(KeyTypePointer aName)
- : DepFcStrEntry(aName) { }
-
- FontsByFullnameEntry(const FontsByFullnameEntry& toCopy)
- : DepFcStrEntry(toCopy), mFonts(toCopy.mFonts) { }
-
- bool KeyEquals(KeyTypePointer aKey) const;
-
- bool AddFont(FcPattern *aFont) {
- return mFonts.AppendElement(aFont) != nullptr;
- }
- const nsTArray< nsCountedRef<FcPattern> >& GetFonts() {
- return mFonts;
- }
-
- // Don't memmove the AutoTArray.
- enum { ALLOW_MEMMOVE = false };
- private:
- // There is usually only one font, but sometimes more.
- AutoTArray<nsCountedRef<FcPattern>,1> mFonts;
- };
-
- class LangSupportEntry : public CopiedFcStrEntry {
- public:
- explicit LangSupportEntry(KeyTypePointer aName)
- : CopiedFcStrEntry(aName) { }
-
- LangSupportEntry(const LangSupportEntry& toCopy)
- : CopiedFcStrEntry(toCopy), mSupport(toCopy.mSupport) { }
-
- FcLangResult mSupport;
- nsTArray< nsCountedRef<FcPattern> > mFonts;
- };
-
- static gfxFontconfigUtils* sUtils;
-
- bool IsExistingFamily(const nsCString& aFamilyName);
-
- nsresult GetFontListInternal(nsTArray<nsCString>& aListOfFonts,
- nsIAtom *aLangGroup);
- nsresult UpdateFontListInternal(bool aForce = false);
-
- void AddFullnameEntries();
-
- LangSupportEntry *GetLangSupportEntry(const FcChar8 *aLang,
- bool aWithFonts);
-
- // mFontsByFamily and mFontsByFullname contain entries only for families
- // and fullnames for which there are fonts.
- nsTHashtable<FontsByFcStrEntry> mFontsByFamily;
- nsTHashtable<FontsByFullnameEntry> mFontsByFullname;
- // mLangSupportTable contains an entry for each language that has been
- // looked up through GetLangSupportEntry, even when the language is not
- // supported.
- nsTHashtable<LangSupportEntry> mLangSupportTable;
- const nsTArray< nsCountedRef<FcPattern> > mEmptyPatternArray;
-
- FcConfig *mLastConfig;
-
-#ifdef MOZ_BUNDLED_FONTS
- void ActivateBundledFonts();
-
- nsCString mBundledFontsPath;
- bool mBundledFontsInitialized;
-#endif
-};
-
class gfxFontconfigFontBase : public gfxFT2FontBase {
public:
gfxFontconfigFontBase(cairo_scaled_font_t *aScaledFont,
FcPattern *aPattern,
gfxFontEntry *aFontEntry,
- const gfxFontStyle *aFontStyle);
+ const gfxFontStyle *aFontStyle)
+ : gfxFT2FontBase(aScaledFont, aFontEntry, aFontStyle)
+ , mPattern(aPattern) { }
virtual FontType GetType() const override { return FONT_TYPE_FONTCONFIG; }
virtual FcPattern *GetPattern() const { return mPattern; }
diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
index 7ec9139c0a..0fc596e828 100644
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -83,10 +83,6 @@
#include "GLContextProvider.h"
#include "mozilla/gfx/Logging.h"
-#if defined(MOZ_WIDGET_GTK)
-#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
-#endif
-
#ifdef USE_SKIA
# ifdef __GNUC__
# pragma GCC diagnostic push
@@ -616,16 +612,9 @@ gfxPlatform::Init()
nsresult rv;
- bool usePlatformFontList = true;
-#if defined(MOZ_WIDGET_GTK)
- usePlatformFontList = gfxPlatformGtk::UseFcFontList();
-#endif
-
- if (usePlatformFontList) {
- rv = gfxPlatformFontList::Init();
- if (NS_FAILED(rv)) {
- NS_RUNTIMEABORT("Could not initialize gfxPlatformFontList");
- }
+ rv = gfxPlatformFontList::Init();
+ if (NS_FAILED(rv)) {
+ NS_RUNTIMEABORT("Could not initialize gfxPlatformFontList");
}
gPlatform->mScreenReferenceSurface =
diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp
index 73d1741922..d8bafac918 100644
--- a/gfx/thebes/gfxPlatformGtk.cpp
+++ b/gfx/thebes/gfxPlatformGtk.cpp
@@ -14,13 +14,13 @@
#include "gfx2DGlue.h"
#include "gfxFcPlatformFontList.h"
#include "gfxFontconfigUtils.h"
-#include "gfxFontconfigFonts.h"
#include "gfxConfig.h"
#include "gfxContext.h"
#include "gfxUserFontSet.h"
#include "gfxUtils.h"
#include "gfxFT2FontBase.h"
#include "gfxPrefs.h"
+#include "gfxTextRun.h"
#include "VsyncSource.h"
#include "mozilla/Atomics.h"
#include "mozilla/Monitor.h"
@@ -67,23 +67,14 @@ using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::unicode;
-gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nullptr;
-
#if (MOZ_WIDGET_GTK == 2)
static cairo_user_data_key_t cairo_gdk_drawable_key;
#endif
-bool gfxPlatformGtk::sUseFcFontList = false;
-
gfxPlatformGtk::gfxPlatformGtk()
{
gtk_init(nullptr, nullptr);
- sUseFcFontList = mozilla::Preferences::GetBool("gfx.font_rendering.fontconfig.fontlist.enabled");
- if (!sUseFcFontList && !sFontconfigUtils) {
- sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
- }
-
mMaxGenericSubstitutions = UNINITIALIZED_VALUE;
#ifdef MOZ_X11
@@ -117,12 +108,6 @@ gfxPlatformGtk::gfxPlatformGtk()
gfxPlatformGtk::~gfxPlatformGtk()
{
- if (!sUseFcFontList) {
- gfxFontconfigUtils::Shutdown();
- sFontconfigUtils = nullptr;
- gfxPangoFontGroup::Shutdown();
- }
-
#ifdef MOZ_X11
if (mCompositorDisplay) {
XCloseDisplay(mCompositorDisplay);
@@ -197,27 +182,17 @@ gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
const nsACString& aGenericFamily,
nsTArray<nsString>& aListOfFonts)
{
- if (sUseFcFontList) {
- gfxPlatformFontList::PlatformFontList()->GetFontList(aLangGroup,
- aGenericFamily,
- aListOfFonts);
- return NS_OK;
- }
-
- return sFontconfigUtils->GetFontList(aLangGroup,
- aGenericFamily,
- aListOfFonts);
+ gfxPlatformFontList::PlatformFontList()->GetFontList(aLangGroup,
+ aGenericFamily,
+ aListOfFonts);
+ return NS_OK;
}
nsresult
gfxPlatformGtk::UpdateFontList()
{
- if (sUseFcFontList) {
- gfxPlatformFontList::PlatformFontList()->UpdateFontList();
- return NS_OK;
- }
-
- return sFontconfigUtils->UpdateFontList();
+ gfxPlatformFontList::PlatformFontList()->UpdateFontList();
+ return NS_OK;
}
// xxx - this is ubuntu centric, need to go through other distros and flesh
@@ -280,13 +255,9 @@ gfxPlatformGtk::CreatePlatformFontList()
nsresult
gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
- if (sUseFcFontList) {
- gfxPlatformFontList::PlatformFontList()->
- GetStandardFamilyName(aFontName, aFamilyName);
- return NS_OK;
- }
-
- return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
+ gfxPlatformFontList::PlatformFontList()->
+ GetStandardFamilyName(aFontName, aFamilyName);
+ return NS_OK;
}
gfxFontGroup *
@@ -296,13 +267,8 @@ gfxPlatformGtk::CreateFontGroup(const FontFamilyList& aFontFamilyList,
gfxUserFontSet* aUserFontSet,
gfxFloat aDevToCssSize)
{
- if (sUseFcFontList) {
- return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
- aUserFontSet, aDevToCssSize);
- }
-
- return new gfxPangoFontGroup(aFontFamilyList, aStyle,
- aUserFontSet, aDevToCssSize);
+ return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
+ aUserFontSet, aDevToCssSize);
}
gfxFontEntry*
@@ -311,14 +277,9 @@ gfxPlatformGtk::LookupLocalFont(const nsAString& aFontName,
int16_t aStretch,
uint8_t aStyle)
{
- if (sUseFcFontList) {
- gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
- return pfl->LookupLocalFont(aFontName, aWeight, aStretch,
- aStyle);
- }
-
- return gfxPangoFontGroup::NewFontEntry(aFontName, aWeight,
- aStretch, aStyle);
+ gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
+ return pfl->LookupLocalFont(aFontName, aWeight, aStretch,
+ aStyle);
}
gfxFontEntry*
@@ -329,16 +290,9 @@ gfxPlatformGtk::MakePlatformFont(const nsAString& aFontName,
const uint8_t* aFontData,
uint32_t aLength)
{
- if (sUseFcFontList) {
- gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
- return pfl->MakePlatformFont(aFontName, aWeight, aStretch,
- aStyle, aFontData, aLength);
- }
-
- // passing ownership of the font data to the new font entry
- return gfxPangoFontGroup::NewFontEntry(aFontName, aWeight,
- aStretch, aStyle,
- aFontData, aLength);
+ gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
+ return pfl->MakePlatformFont(aFontName, aWeight, aStretch,
+ aStyle, aFontData, aLength);
}
bool
@@ -429,11 +383,9 @@ void gfxPlatformGtk::FontsPrefsChanged(const char *aPref)
}
mMaxGenericSubstitutions = UNINITIALIZED_VALUE;
- if (sUseFcFontList) {
- gfxFcPlatformFontList* pfl = gfxFcPlatformFontList::PlatformFontList();
- pfl->ClearGenericMappings();
- FlushFontAndWordCaches();
- }
+ gfxFcPlatformFontList* pfl = gfxFcPlatformFontList::PlatformFontList();
+ pfl->ClearGenericMappings();
+ FlushFontAndWordCaches();
}
uint32_t gfxPlatformGtk::MaxGenericSubstitions()
diff --git a/gfx/thebes/gfxPlatformGtk.h b/gfx/thebes/gfxPlatformGtk.h
index 22ed4b08fd..cfaca45074 100644
--- a/gfx/thebes/gfxPlatformGtk.h
+++ b/gfx/thebes/gfxPlatformGtk.h
@@ -111,8 +111,6 @@ public:
}
#endif
- static bool UseFcFontList() { return sUseFcFontList; }
-
bool UseImageOffscreenSurfaces();
virtual gfxImageFormat GetOffscreenFormat() override;
@@ -154,10 +152,6 @@ private:
#ifdef MOZ_X11
Display* mCompositorDisplay;
#endif
-
- // xxx - this will be removed once the new fontconfig platform font list
- // replaces gfxPangoFontGroup
- static bool sUseFcFontList;
};
#endif /* GFX_PLATFORM_GTK_H */
diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp
index 438f6f61ae..100af6da7b 100644
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -26,10 +26,6 @@
#include "mozilla/gfx/Logging.h" // for gfxCriticalError
#include "mozilla/UniquePtr.h"
-#if defined(MOZ_WIDGET_GTK)
-#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
-#endif
-
#ifdef XP_WIN
#include "gfxWindowsPlatform.h"
#endif
@@ -1599,7 +1595,6 @@ gfxFontGroup::gfxFontGroup(const FontFamilyList& aFontFamilyList,
, mPageLang(gfxPlatformFontList::GetFontPrefLangFor(aStyle->language))
, mLastPrefFirstFont(false)
, mSkipDrawing(false)
- , mSkipUpdateUserFonts(false)
{
// We don't use SetUserFontSet() here, as we want to unconditionally call
// BuildFontList() rather than only do UpdateUserFonts() if it changed.
@@ -1616,14 +1611,6 @@ gfxFontGroup::BuildFontList()
{
bool enumerateFonts = true;
-#if defined(MOZ_WIDGET_GTK)
- // xxx - eliminate this once gfxPangoFontGroup is no longer needed
- enumerateFonts = gfxPlatformGtk::UseFcFontList();
-#endif
- if (!enumerateFonts) {
- return;
- }
-
// initialize fonts in the font family list
AutoTArray<gfxFontFamily*,10> fonts;
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
@@ -2338,7 +2325,7 @@ gfxFontGroup::InitScriptRun(DrawTarget* aDrawTarget,
"don't call InitScriptRun with aborted shaping state");
// confirm the load state of userfonts in the list
- if (!mSkipUpdateUserFonts && mUserFontSet &&
+ if (mUserFontSet &&
mCurrGeneration != mUserFontSet->GetGeneration()) {
UpdateUserFonts();
}
@@ -3076,8 +3063,6 @@ gfxFontGroup::GetRebuildGeneration()
return mUserFontSet->GetRebuildGeneration();
}
-// note: gfxPangoFontGroup overrides UpdateUserFonts, such that
-// BuildFontList is never used
void
gfxFontGroup::UpdateUserFonts()
{
diff --git a/gfx/thebes/gfxTextRun.h b/gfx/thebes/gfxTextRun.h
index 2ef835f189..8189861756 100644
--- a/gfx/thebes/gfxTextRun.h
+++ b/gfx/thebes/gfxTextRun.h
@@ -1108,9 +1108,6 @@ protected:
// download to complete (or fallback
// timer to fire)
- // xxx - gfxPangoFontGroup skips UpdateUserFonts
- bool mSkipUpdateUserFonts;
-
/**
* Textrun creation short-cuts for special cases where we don't need to
* call a font shaper to generate glyphs.
diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp
index 585bd14d02..4b487552cc 100644
--- a/gfx/thebes/gfxUserFontSet.cpp
+++ b/gfx/thebes/gfxUserFontSet.cpp
@@ -926,32 +926,6 @@ gfxUserFontSet::AddUserFontEntry(const nsAString& aFamilyName,
}
}
-gfxUserFontEntry*
-gfxUserFontSet::FindUserFontEntryAndLoad(gfxFontFamily* aFamily,
- const gfxFontStyle& aFontStyle,
- bool& aNeedsBold,
- bool& aWaitForUserFont)
-{
- aWaitForUserFont = false;
- gfxFontEntry* fe = aFamily->FindFontForStyle(aFontStyle, aNeedsBold);
- NS_ASSERTION(!fe || fe->mIsUserFontContainer,
- "should only have userfont entries in userfont families");
- if (!fe) {
- return nullptr;
- }
-
- gfxUserFontEntry* userFontEntry = static_cast<gfxUserFontEntry*>(fe);
-
- // start the load if it hasn't been loaded
- userFontEntry->Load();
- if (userFontEntry->GetPlatformFontEntry()) {
- return userFontEntry;
- }
-
- aWaitForUserFont = userFontEntry->WaitForUserFont();
- return nullptr;
-}
-
void
gfxUserFontSet::IncrementGeneration(bool aIsRebuild)
{
diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h
index 896c6951e9..3a13573ac2 100644
--- a/gfx/thebes/gfxUserFontSet.h
+++ b/gfx/thebes/gfxUserFontSet.h
@@ -248,14 +248,6 @@ public:
// Look up names in a fontlist and return true if any are in the set
bool ContainsUserFontSetFonts(const mozilla::FontFamilyList& aFontList) const;
- // Lookup a font entry for a given style, returns null if not loaded.
- // aFamily must be a family returned by our LookupFamily method.
- // (only used by gfxPangoFontGroup for now)
- gfxUserFontEntry* FindUserFontEntryAndLoad(gfxFontFamily* aFamily,
- const gfxFontStyle& aFontStyle,
- bool& aNeedsBold,
- bool& aWaitForUserFont);
-
// check whether the given source is allowed to be loaded;
// returns the Principal (for use in the key when caching the loaded font),
// and whether the load should bypass the cache (force-reload).
diff --git a/gfx/thebes/moz.build b/gfx/thebes/moz.build
index 2d4dc41a40..036df875cf 100644
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -76,7 +76,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
]
elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
EXPORTS += [
- 'gfxFontconfigFonts.h',
'gfxFT2FontBase.h',
'gfxGdkNativeRenderer.h',
'gfxPlatformGtk.h',
@@ -87,8 +86,6 @@ elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
]
SOURCES += [
'gfxFcPlatformFontList.cpp',
- 'gfxFontconfigFonts.cpp',
- 'gfxFontconfigUtils.cpp',
'gfxFT2FontBase.cpp',
'gfxFT2Utils.cpp',
'gfxGdkNativeRenderer.cpp',
diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp
index f7be42b5ff..2d250f61b6 100644
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -77,10 +77,6 @@
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
-#if defined(MOZ_WIDGET_GTK)
-#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
-#endif
-
// Needed for Start/Stop of Image Animation
#include "imgIContainer.h"
@@ -2068,19 +2064,12 @@ nsPresContext::UserFontSetUpdated(gfxUserFontEntry* aUpdatedFont)
if (!mShell)
return;
- bool usePlatformFontList = true;
-#if defined(MOZ_WIDGET_GTK)
- usePlatformFontList = gfxPlatformGtk::UseFcFontList();
-#endif
-
- // xxx - until the Linux platform font list is always used, use full
- // restyle to force updates with gfxPangoFontGroup usage
// Note: this method is called without a font when rules in the userfont set
// are updated, which may occur during reflow as a result of the lazy
// initialization of the userfont set. It would be better to avoid a full
// restyle but until this method is only called outside of reflow, schedule a
// full restyle in these cases.
- if (!usePlatformFontList || !aUpdatedFont) {
+ if (!aUpdatedFont) {
PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW, eRestyle_ForceDescendants);
return;
}
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 81ff58a16c..8c4c0b662d 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4066,13 +4066,7 @@ pref("intl.ime.use_simple_context_on_password_field", true);
pref("intl.ime.use_simple_context_on_password_field", false);
#endif
-# enable new platform fontlist for linux on GTK platforms
-# temporary pref to allow flipping back to the existing
-# gfxPangoFontGroup/gfxFontconfigUtils code for handling system fonts
-
#ifdef MOZ_WIDGET_GTK
-pref("gfx.font_rendering.fontconfig.fontlist.enabled", true);
-
// maximum number of fonts to substitute for a generic
pref("gfx.font_rendering.fontconfig.max_generic_substitutions", 3);
#endif