gfx/skia/trunk/src/ports/SkFontHost_linux.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2  * Copyright 2006 The Android Open Source Project
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkFontHost.h"
     9 #include "SkFontHost_FreeType_common.h"
    10 #include "SkFontDescriptor.h"
    11 #include "SkFontMgr.h"
    12 #include "SkDescriptor.h"
    13 #include "SkOSFile.h"
    14 #include "SkPaint.h"
    15 #include "SkString.h"
    16 #include "SkStream.h"
    17 #include "SkThread.h"
    18 #include "SkTSearch.h"
    19 #include "SkTypefaceCache.h"
    20 #include "SkTArray.h"
    22 #include <limits>
    24 #ifndef SK_FONT_FILE_PREFIX
    25 #    define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/"
    26 #endif
    28 bool find_name_and_attributes(SkStream* stream, SkString* name,
    29                               SkTypeface::Style* style, bool* isFixedPitch);
    31 ///////////////////////////////////////////////////////////////////////////////
    33 /** The base SkTypeface implementation for the custom font manager. */
    34 class SkTypeface_Custom : public SkTypeface_FreeType {
    35 public:
    36     SkTypeface_Custom(Style style, bool sysFont, bool isFixedPitch, const SkString familyName)
    37         : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch)
    38         , fIsSysFont(sysFont), fFamilyName(familyName)
    39     { }
    41     bool isSysFont() const { return fIsSysFont; }
    43     virtual const char* getUniqueString() const = 0;
    45 protected:
    46     virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const SK_OVERRIDE {
    47         desc->setFamilyName(fFamilyName.c_str());
    48         desc->setFontFileName(this->getUniqueString());
    49         *isLocal = !this->isSysFont();
    50     }
    52 private:
    53     bool fIsSysFont;
    54     SkString fFamilyName;
    56     typedef SkTypeface_FreeType INHERITED;
    57 };
    59 /** The empty SkTypeface implementation for the custom font manager.
    60  *  Used as the last resort fallback typeface.
    61  */
    62 class SkTypeface_Empty : public SkTypeface_Custom {
    63 public:
    64     SkTypeface_Empty() : INHERITED(SkTypeface::kNormal, true, false, SkString()) {}
    66     virtual const char* getUniqueString() const SK_OVERRIDE { return NULL; }
    68 protected:
    69     virtual SkStream* onOpenStream(int*) const SK_OVERRIDE { return NULL; }
    71 private:
    72     typedef SkTypeface_Custom INHERITED;
    73 };
    75 /** The stream SkTypeface implementation for the custom font manager. */
    76 class SkTypeface_Stream : public SkTypeface_Custom {
    77 public:
    78     SkTypeface_Stream(Style style, bool sysFont, SkStream* stream,
    79                       bool isFixedPitch, const SkString familyName)
    80         : INHERITED(style, sysFont, isFixedPitch, familyName)
    81         , fStream(SkRef(stream))
    82     { }
    84     virtual const char* getUniqueString() const SK_OVERRIDE { return NULL; }
    86 protected:
    87     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
    88         *ttcIndex = 0;
    89         return SkRef(fStream.get());
    90     }
    92 private:
    93     SkAutoTUnref<SkStream> fStream;
    95     typedef SkTypeface_Custom INHERITED;
    96 };
    98 /** The file SkTypeface implementation for the custom font manager. */
    99 class SkTypeface_File : public SkTypeface_Custom {
   100 public:
   101     SkTypeface_File(Style style, bool sysFont, const char path[],
   102                     bool isFixedPitch, const SkString familyName)
   103         : INHERITED(style, sysFont, isFixedPitch, familyName)
   104         , fPath(path)
   105     { }
   107     virtual const char* getUniqueString() const SK_OVERRIDE {
   108         const char* str = strrchr(fPath.c_str(), '/');
   109         if (str) {
   110             str += 1;   // skip the '/'
   111         }
   112         return str;
   113     }
   115 protected:
   116     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
   117         *ttcIndex = 0;
   118         return SkStream::NewFromFile(fPath.c_str());
   119     }
   121 private:
   122     SkString fPath;
   124     typedef SkTypeface_Custom INHERITED;
   125 };
   127 ///////////////////////////////////////////////////////////////////////////////
   129 /**
   130  *  SkFontStyleSet_Custom
   131  *
   132  *  This class is used by SkFontMgr_Custom to hold SkTypeface_Custom families.
   133  */
   134 class SkFontStyleSet_Custom : public SkFontStyleSet {
   135 public:
   136     explicit SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) { }
   138     virtual int count() SK_OVERRIDE {
   139         return fStyles.count();
   140     }
   142     virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVERRIDE {
   143         SkASSERT(index < fStyles.count());
   144         bool bold = fStyles[index]->isBold();
   145         bool italic = fStyles[index]->isItalic();
   146         *style = SkFontStyle(bold ? SkFontStyle::kBold_Weight : SkFontStyle::kNormal_Weight,
   147                              SkFontStyle::kNormal_Width,
   148                              italic ? SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant);
   149         name->reset();
   150     }
   152     virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
   153         SkASSERT(index < fStyles.count());
   154         return SkRef(fStyles[index].get());
   155     }
   157     static int match_score(const SkFontStyle& pattern, const SkFontStyle& candidate) {
   158         int score = 0;
   159         score += (pattern.width() - candidate.width()) * 100;
   160         score += (pattern.isItalic() == candidate.isItalic()) ? 0 : 1000;
   161         score += pattern.weight() - candidate.weight();
   162         return score;
   163     }
   165     virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE {
   166         if (0 == fStyles.count()) {
   167             return NULL;
   168         }
   170         SkTypeface_Custom* closest = fStyles[0];
   171         int minScore = std::numeric_limits<int>::max();
   172         for (int i = 0; i < fStyles.count(); ++i) {
   173             bool bold = fStyles[i]->isBold();
   174             bool italic = fStyles[i]->isItalic();
   175             SkFontStyle style = SkFontStyle(bold ? SkFontStyle::kBold_Weight
   176                                                  : SkFontStyle::kNormal_Weight,
   177                                             SkFontStyle::kNormal_Width,
   178                                             italic ? SkFontStyle::kItalic_Slant
   179                                                    : SkFontStyle::kUpright_Slant);
   181             int score = match_score(pattern, style);
   182             if (score < minScore) {
   183                 closest = fStyles[i];
   184                 minScore = score;
   185             }
   186         }
   187         return SkRef(closest);
   188     }
   190 private:
   191     SkTArray<SkAutoTUnref<SkTypeface_Custom>, true> fStyles;
   192     SkString fFamilyName;
   194     void appendTypeface(SkTypeface_Custom* typeface) {
   195         fStyles.push_back().reset(typeface);
   196     }
   198     friend class SkFontMgr_Custom;
   199 };
   201 /**
   202  *  SkFontMgr_Custom
   203  *
   204  *  This class is essentially a collection of SkFontStyleSet_Custom,
   205  *  one SkFontStyleSet_Custom for each family. This class may be modified
   206  *  to load fonts from any source by changing the initialization.
   207  */
   208 class SkFontMgr_Custom : public SkFontMgr {
   209 public:
   210     explicit SkFontMgr_Custom(const char* dir) {
   211         this->load_system_fonts(dir);
   212     }
   214 protected:
   215     virtual int onCountFamilies() const SK_OVERRIDE {
   216         return fFamilies.count();
   217     }
   219     virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE {
   220         SkASSERT(index < fFamilies.count());
   221         familyName->set(fFamilies[index]->fFamilyName);
   222     }
   224     virtual SkFontStyleSet_Custom* onCreateStyleSet(int index) const SK_OVERRIDE {
   225         SkASSERT(index < fFamilies.count());
   226         return SkRef(fFamilies[index].get());
   227     }
   229     virtual SkFontStyleSet_Custom* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
   230         for (int i = 0; i < fFamilies.count(); ++i) {
   231             if (fFamilies[i]->fFamilyName.equals(familyName)) {
   232                 return SkRef(fFamilies[i].get());
   233             }
   234         }
   235         return NULL;
   236     }
   238     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
   239                                            const SkFontStyle& fontStyle) const SK_OVERRIDE
   240     {
   241         SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
   242         return sset->matchStyle(fontStyle);
   243     }
   245     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
   246                                          const SkFontStyle& fontStyle) const SK_OVERRIDE
   247     {
   248         for (int i = 0; i < fFamilies.count(); ++i) {
   249             for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
   250                 if (fFamilies[i]->fStyles[j] == familyMember) {
   251                     return fFamilies[i]->matchStyle(fontStyle);
   252                 }
   253             }
   254         }
   255         return NULL;
   256     }
   258     virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
   259         SkAutoTUnref<SkStream> stream(new SkMemoryStream(data));
   260         return this->createFromStream(stream, ttcIndex);
   261     }
   263     virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
   264         if (NULL == stream || stream->getLength() <= 0) {
   265             SkDELETE(stream);
   266             return NULL;
   267         }
   269         bool isFixedPitch;
   270         SkTypeface::Style style;
   271         SkString name;
   272         if (find_name_and_attributes(stream, &name, &style, &isFixedPitch)) {
   273             return SkNEW_ARGS(SkTypeface_Stream, (style, false, stream, isFixedPitch, name));
   274         } else {
   275             return NULL;
   276         }
   277     }
   279     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
   280         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
   281         return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL;
   282     }
   284     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
   285                                                unsigned styleBits) const SK_OVERRIDE
   286     {
   287         SkTypeface::Style oldStyle = (SkTypeface::Style)styleBits;
   288         SkFontStyle style = SkFontStyle(oldStyle & SkTypeface::kBold
   289                                                  ? SkFontStyle::kBold_Weight
   290                                                  : SkFontStyle::kNormal_Weight,
   291                                         SkFontStyle::kNormal_Width,
   292                                         oldStyle & SkTypeface::kItalic
   293                                                  ? SkFontStyle::kItalic_Slant
   294                                                  : SkFontStyle::kUpright_Slant);
   295         SkTypeface* tf = NULL;
   297         if (NULL != familyName) {
   298             tf = this->onMatchFamilyStyle(familyName, style);
   299         }
   301         if (NULL == tf) {
   302             tf = gDefaultFamily->matchStyle(style);
   303         }
   305         return SkSafeRef(tf);
   306     }
   308 private:
   310     static bool get_name_and_style(const char path[], SkString* name,
   311                                    SkTypeface::Style* style, bool* isFixedPitch) {
   312         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
   313         if (stream.get()) {
   314             return find_name_and_attributes(stream, name, style, isFixedPitch);
   315         } else {
   316             SkDebugf("---- failed to open <%s> as a font\n", path);
   317             return false;
   318         }
   319     }
   321     void load_directory_fonts(const SkString& directory) {
   322         SkOSFile::Iter iter(directory.c_str(), ".ttf");
   323         SkString name;
   325         while (iter.next(&name, false)) {
   326             SkString filename(
   327                 SkOSPath::SkPathJoin(directory.c_str(), name.c_str()));
   329             bool isFixedPitch;
   330             SkString realname;
   331             SkTypeface::Style style = SkTypeface::kNormal; // avoid uninitialized warning
   333             if (!get_name_and_style(filename.c_str(), &realname, &style, &isFixedPitch)) {
   334                 SkDebugf("------ can't load <%s> as a font\n", filename.c_str());
   335                 continue;
   336             }
   338             SkTypeface_Custom* tf = SkNEW_ARGS(SkTypeface_File, (
   339                                                 style,
   340                                                 true,  // system-font (cannot delete)
   341                                                 filename.c_str(),
   342                                                 isFixedPitch,
   343                                                 realname));
   345             SkFontStyleSet_Custom* addTo = this->onMatchFamily(realname.c_str());
   346             if (NULL == addTo) {
   347                 addTo = new SkFontStyleSet_Custom(realname);
   348                 fFamilies.push_back().reset(addTo);
   349             }
   350             addTo->appendTypeface(tf);
   351         }
   353         SkOSFile::Iter dirIter(directory.c_str());
   354         while (dirIter.next(&name, true)) {
   355             if (name.startsWith(".")) {
   356                 continue;
   357             }
   358             SkString dirname(
   359                 SkOSPath::SkPathJoin(directory.c_str(), name.c_str()));
   360             load_directory_fonts(dirname);
   361         }
   362     }
   364     void load_system_fonts(const char* dir) {
   365         SkString baseDirectory(dir);
   366         load_directory_fonts(baseDirectory);
   368         if (fFamilies.empty()) {
   369             SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
   370             fFamilies.push_back().reset(family);
   371             family->appendTypeface(SkNEW(SkTypeface_Empty));
   372         }
   374         // Try to pick a default font.
   375         static const char* gDefaultNames[] = {
   376             "Arial", "Verdana", "Times New Roman", "Droid Sans", NULL
   377         };
   378         for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) {
   379             SkFontStyleSet_Custom* set = this->onMatchFamily(gDefaultNames[i]);
   380             if (NULL == set) {
   381                 continue;
   382             }
   384             SkTypeface* tf = set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
   385                                                          SkFontStyle::kNormal_Width,
   386                                                          SkFontStyle::kUpright_Slant));
   387             if (NULL == tf) {
   388                 continue;
   389             }
   391             gDefaultFamily = set;
   392             gDefaultNormal = tf;
   393             break;
   394         }
   395         if (NULL == gDefaultNormal) {
   396             gDefaultFamily = fFamilies[0];
   397             gDefaultNormal = gDefaultFamily->fStyles[0];
   398         }
   399     }
   401     SkTArray<SkAutoTUnref<SkFontStyleSet_Custom>, true> fFamilies;
   402     SkFontStyleSet_Custom* gDefaultFamily;
   403     SkTypeface* gDefaultNormal;
   404 };
   406 SkFontMgr* SkFontMgr::Factory() {
   407     return new SkFontMgr_Custom(SK_FONT_FILE_PREFIX);
   408 }

mercurial