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.

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

mercurial