gfx/skia/patches/archive/old-android-fonthost.patch

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 # HG changeset patch
michael@0 2 # Parent 9ee29e4aace683ddf6cf8ddb2893cd34fcfc772c
michael@0 3 # User James Willcox <jwillcox@mozilla.com>
michael@0 4 diff --git a/gfx/skia/Makefile.in b/gfx/skia/Makefile.in
michael@0 5 --- a/gfx/skia/Makefile.in
michael@0 6 +++ b/gfx/skia/Makefile.in
michael@0 7 @@ -305,21 +305,20 @@ CPPSRCS += \
michael@0 8 SkFontHost_mac_coretext.cpp \
michael@0 9 SkTime_Unix.cpp \
michael@0 10 $(NULL)
michael@0 11 endif
michael@0 12
michael@0 13 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
michael@0 14 CPPSRCS += \
michael@0 15 SkFontHost_FreeType.cpp \
michael@0 16 SkFontHost_android.cpp \
michael@0 17 SkFontHost_gamma.cpp \
michael@0 18 - FontHostConfiguration_android.cpp \
michael@0 19 SkMMapStream.cpp \
michael@0 20 SkTime_Unix.cpp \
michael@0 21 $(NULL)
michael@0 22
michael@0 23 DEFINES += -DSK_BUILD_FOR_ANDROID_NDK
michael@0 24 OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
michael@0 25 endif
michael@0 26
michael@0 27 ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
michael@0 28 CPPSRCS += \
michael@0 29 diff --git a/gfx/skia/src/ports/SkFontHost_android.cpp b/gfx/skia/src/ports/SkFontHost_android.cpp
michael@0 30 --- a/gfx/skia/src/ports/SkFontHost_android.cpp
michael@0 31 +++ b/gfx/skia/src/ports/SkFontHost_android.cpp
michael@0 32 @@ -1,38 +1,31 @@
michael@0 33 +
michael@0 34 /*
michael@0 35 -**
michael@0 36 -** Copyright 2006, The Android Open Source Project
michael@0 37 -**
michael@0 38 -** Licensed under the Apache License, Version 2.0 (the "License");
michael@0 39 -** you may not use this file except in compliance with the License.
michael@0 40 -** You may obtain a copy of the License at
michael@0 41 -**
michael@0 42 -** http://www.apache.org/licenses/LICENSE-2.0
michael@0 43 -**
michael@0 44 -** Unless required by applicable law or agreed to in writing, software
michael@0 45 -** distributed under the License is distributed on an "AS IS" BASIS,
michael@0 46 -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
michael@0 47 -** See the License for the specific language governing permissions and
michael@0 48 -** limitations under the License.
michael@0 49 -*/
michael@0 50 + * Copyright 2006 The Android Open Source Project
michael@0 51 + *
michael@0 52 + * Use of this source code is governed by a BSD-style license that can be
michael@0 53 + * found in the LICENSE file.
michael@0 54 + */
michael@0 55 +
michael@0 56
michael@0 57 #include "SkFontHost.h"
michael@0 58 #include "SkDescriptor.h"
michael@0 59 #include "SkMMapStream.h"
michael@0 60 #include "SkPaint.h"
michael@0 61 #include "SkString.h"
michael@0 62 #include "SkStream.h"
michael@0 63 #include "SkThread.h"
michael@0 64 #include "SkTSearch.h"
michael@0 65 -#include "FontHostConfiguration_android.h"
michael@0 66 #include <stdio.h>
michael@0 67
michael@0 68 +#define FONT_CACHE_MEMORY_BUDGET (768 * 1024)
michael@0 69 +
michael@0 70 #ifndef SK_FONT_FILE_PREFIX
michael@0 71 #define SK_FONT_FILE_PREFIX "/fonts/"
michael@0 72 #endif
michael@0 73
michael@0 74 SkTypeface::Style find_name_and_attributes(SkStream* stream, SkString* name,
michael@0 75 bool* isFixedWidth);
michael@0 76
michael@0 77 static void GetFullPathForSysFonts(SkString* full, const char name[]) {
michael@0 78 full->set(getenv("ANDROID_ROOT"));
michael@0 79 full->append(SK_FONT_FILE_PREFIX);
michael@0 80 @@ -99,21 +92,21 @@ static SkTypeface* find_best_face(const
michael@0 81 if (faces[SkTypeface::kNormal] != NULL) {
michael@0 82 return faces[SkTypeface::kNormal];
michael@0 83 }
michael@0 84 // look for anything
michael@0 85 for (int i = 0; i < 4; i++) {
michael@0 86 if (faces[i] != NULL) {
michael@0 87 return faces[i];
michael@0 88 }
michael@0 89 }
michael@0 90 // should never get here, since the faces list should not be empty
michael@0 91 - SkDEBUGFAIL("faces list is empty");
michael@0 92 + SkASSERT(!"faces list is empty");
michael@0 93 return NULL;
michael@0 94 }
michael@0 95
michael@0 96 static FamilyRec* find_family(const SkTypeface* member) {
michael@0 97 FamilyRec* curr = gFamilyHead;
michael@0 98 while (curr != NULL) {
michael@0 99 for (int i = 0; i < 4; i++) {
michael@0 100 if (curr->fFaces[i] == member) {
michael@0 101 return curr;
michael@0 102 }
michael@0 103 @@ -138,31 +131,27 @@ static SkTypeface* find_from_uniqueID(ui
michael@0 104 curr = curr->fNext;
michael@0 105 }
michael@0 106 return NULL;
michael@0 107 }
michael@0 108
michael@0 109 /* Remove reference to this face from its family. If the resulting family
michael@0 110 is empty (has no faces), return that family, otherwise return NULL
michael@0 111 */
michael@0 112 static FamilyRec* remove_from_family(const SkTypeface* face) {
michael@0 113 FamilyRec* family = find_family(face);
michael@0 114 - if (family) {
michael@0 115 - SkASSERT(family->fFaces[face->style()] == face);
michael@0 116 - family->fFaces[face->style()] = NULL;
michael@0 117 + SkASSERT(family->fFaces[face->style()] == face);
michael@0 118 + family->fFaces[face->style()] = NULL;
michael@0 119
michael@0 120 - for (int i = 0; i < 4; i++) {
michael@0 121 - if (family->fFaces[i] != NULL) { // family is non-empty
michael@0 122 - return NULL;
michael@0 123 - }
michael@0 124 + for (int i = 0; i < 4; i++) {
michael@0 125 + if (family->fFaces[i] != NULL) { // family is non-empty
michael@0 126 + return NULL;
michael@0 127 }
michael@0 128 - } else {
michael@0 129 -// SkDebugf("remove_from_family(%p) face not found", face);
michael@0 130 }
michael@0 131 return family; // return the empty family
michael@0 132 }
michael@0 133
michael@0 134 // maybe we should make FamilyRec be doubly-linked
michael@0 135 static void detach_and_delete_family(FamilyRec* family) {
michael@0 136 FamilyRec* curr = gFamilyHead;
michael@0 137 FamilyRec* prev = NULL;
michael@0 138
michael@0 139 while (curr != NULL) {
michael@0 140 @@ -172,21 +161,21 @@ static void detach_and_delete_family(Fam
michael@0 141 gFamilyHead = next;
michael@0 142 } else {
michael@0 143 prev->fNext = next;
michael@0 144 }
michael@0 145 SkDELETE(family);
michael@0 146 return;
michael@0 147 }
michael@0 148 prev = curr;
michael@0 149 curr = next;
michael@0 150 }
michael@0 151 - SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete");
michael@0 152 + SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
michael@0 153 }
michael@0 154
michael@0 155 static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
michael@0 156 NameFamilyPair* list = gNameList.begin();
michael@0 157 int count = gNameList.count();
michael@0 158
michael@0 159 int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
michael@0 160
michael@0 161 if (index >= 0) {
michael@0 162 return find_best_face(list[index].fFamily, style);
michael@0 163 @@ -387,111 +376,90 @@ static bool get_name_and_style(const cha
michael@0 164 }
michael@0 165 return false;
michael@0 166 }
michael@0 167
michael@0 168 // used to record our notion of the pre-existing fonts
michael@0 169 struct FontInitRec {
michael@0 170 const char* fFileName;
michael@0 171 const char* const* fNames; // null-terminated list
michael@0 172 };
michael@0 173
michael@0 174 +static const char* gSansNames[] = {
michael@0 175 + "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL
michael@0 176 +};
michael@0 177 +
michael@0 178 +static const char* gSerifNames[] = {
michael@0 179 + "serif", "times", "times new roman", "palatino", "georgia", "baskerville",
michael@0 180 + "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL
michael@0 181 +};
michael@0 182 +
michael@0 183 +static const char* gMonoNames[] = {
michael@0 184 + "monospace", "courier", "courier new", "monaco", NULL
michael@0 185 +};
michael@0 186 +
michael@0 187 // deliberately empty, but we use the address to identify fallback fonts
michael@0 188 static const char* gFBNames[] = { NULL };
michael@0 189
michael@0 190 +/* Fonts must be grouped by family, with the first font in a family having the
michael@0 191 + list of names (even if that list is empty), and the following members having
michael@0 192 + null for the list. The names list must be NULL-terminated
michael@0 193 +*/
michael@0 194 +static const FontInitRec gSystemFonts[] = {
michael@0 195 + { "DroidSans.ttf", gSansNames },
michael@0 196 + { "DroidSans-Bold.ttf", NULL },
michael@0 197 + { "DroidSerif-Regular.ttf", gSerifNames },
michael@0 198 + { "DroidSerif-Bold.ttf", NULL },
michael@0 199 + { "DroidSerif-Italic.ttf", NULL },
michael@0 200 + { "DroidSerif-BoldItalic.ttf", NULL },
michael@0 201 + { "DroidSansMono.ttf", gMonoNames },
michael@0 202 + /* These are optional, and can be ignored if not found in the file system.
michael@0 203 + These are appended to gFallbackFonts[] as they are seen, so we list
michael@0 204 + them in the order we want them to be accessed by NextLogicalFont().
michael@0 205 + */
michael@0 206 + { "DroidSansArabic.ttf", gFBNames },
michael@0 207 + { "DroidSansHebrew.ttf", gFBNames },
michael@0 208 + { "DroidSansThai.ttf", gFBNames },
michael@0 209 + { "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font
michael@0 210 + { "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font
michael@0 211 + { "DroidSansJapanese.ttf", gFBNames },
michael@0 212 + { "DroidSansFallback.ttf", gFBNames }
michael@0 213 +};
michael@0 214
michael@0 215 -/* Fonts are grouped by family, with the first font in a family having the
michael@0 216 - list of names (even if that list is empty), and the following members having
michael@0 217 - null for the list. The names list must be NULL-terminated.
michael@0 218 -*/
michael@0 219 -static FontInitRec *gSystemFonts;
michael@0 220 -static size_t gNumSystemFonts = 0;
michael@0 221 -
michael@0 222 -#define SYSTEM_FONTS_FILE "/system/etc/system_fonts.cfg"
michael@0 223 +#define DEFAULT_NAMES gSansNames
michael@0 224
michael@0 225 // these globals are assigned (once) by load_system_fonts()
michael@0 226 static FamilyRec* gDefaultFamily;
michael@0 227 static SkTypeface* gDefaultNormal;
michael@0 228 -static char** gDefaultNames = NULL;
michael@0 229 -static uint32_t *gFallbackFonts;
michael@0 230
michael@0 231 -/* Load info from a configuration file that populates the system/fallback font structures
michael@0 232 -*/
michael@0 233 -static void load_font_info() {
michael@0 234 -// load_font_info_xml("/system/etc/system_fonts.xml");
michael@0 235 - SkTDArray<FontFamily*> fontFamilies;
michael@0 236 - getFontFamilies(fontFamilies);
michael@0 237 -
michael@0 238 - SkTDArray<FontInitRec> fontInfo;
michael@0 239 - bool firstInFamily = false;
michael@0 240 - for (int i = 0; i < fontFamilies.count(); ++i) {
michael@0 241 - FontFamily *family = fontFamilies[i];
michael@0 242 - firstInFamily = true;
michael@0 243 - for (int j = 0; j < family->fFileNames.count(); ++j) {
michael@0 244 - FontInitRec fontInfoRecord;
michael@0 245 - fontInfoRecord.fFileName = family->fFileNames[j];
michael@0 246 - if (j == 0) {
michael@0 247 - if (family->fNames.count() == 0) {
michael@0 248 - // Fallback font
michael@0 249 - fontInfoRecord.fNames = (char **)gFBNames;
michael@0 250 - } else {
michael@0 251 - SkTDArray<const char*> names = family->fNames;
michael@0 252 - const char **nameList = (const char**)
michael@0 253 - malloc((names.count() + 1) * sizeof(char*));
michael@0 254 - if (nameList == NULL) {
michael@0 255 - // shouldn't get here
michael@0 256 - break;
michael@0 257 - }
michael@0 258 - if (gDefaultNames == NULL) {
michael@0 259 - gDefaultNames = (char**) nameList;
michael@0 260 - }
michael@0 261 - for (int i = 0; i < names.count(); ++i) {
michael@0 262 - nameList[i] = names[i];
michael@0 263 - }
michael@0 264 - nameList[names.count()] = NULL;
michael@0 265 - fontInfoRecord.fNames = nameList;
michael@0 266 - }
michael@0 267 - } else {
michael@0 268 - fontInfoRecord.fNames = NULL;
michael@0 269 - }
michael@0 270 - *fontInfo.append() = fontInfoRecord;
michael@0 271 - }
michael@0 272 - }
michael@0 273 - gNumSystemFonts = fontInfo.count();
michael@0 274 - gSystemFonts = (FontInitRec*) malloc(gNumSystemFonts * sizeof(FontInitRec));
michael@0 275 - gFallbackFonts = (uint32_t*) malloc((gNumSystemFonts + 1) * sizeof(uint32_t));
michael@0 276 - if (gSystemFonts == NULL) {
michael@0 277 - // shouldn't get here
michael@0 278 - gNumSystemFonts = 0;
michael@0 279 - }
michael@0 280 - for (size_t i = 0; i < gNumSystemFonts; ++i) {
michael@0 281 - gSystemFonts[i].fFileName = fontInfo[i].fFileName;
michael@0 282 - gSystemFonts[i].fNames = fontInfo[i].fNames;
michael@0 283 - }
michael@0 284 - fontFamilies.deleteAll();
michael@0 285 -}
michael@0 286 +/* This is sized conservatively, assuming that it will never be a size issue.
michael@0 287 + It will be initialized in load_system_fonts(), and will be filled with the
michael@0 288 + fontIDs that can be used for fallback consideration, in sorted order (sorted
michael@0 289 + meaning element[0] should be used first, then element[1], etc. When we hit
michael@0 290 + a fontID==0 in the array, the list is done, hence our allocation size is
michael@0 291 + +1 the total number of possible system fonts. Also see NextLogicalFont().
michael@0 292 + */
michael@0 293 +static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1];
michael@0 294
michael@0 295 /* Called once (ensured by the sentinel check at the beginning of our body).
michael@0 296 Initializes all the globals, and register the system fonts.
michael@0 297 */
michael@0 298 static void load_system_fonts() {
michael@0 299 // check if we've already be called
michael@0 300 if (NULL != gDefaultNormal) {
michael@0 301 return;
michael@0 302 }
michael@0 303
michael@0 304 - load_font_info();
michael@0 305 -
michael@0 306 const FontInitRec* rec = gSystemFonts;
michael@0 307 SkTypeface* firstInFamily = NULL;
michael@0 308 int fallbackCount = 0;
michael@0 309
michael@0 310 - for (size_t i = 0; i < gNumSystemFonts; i++) {
michael@0 311 + for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
michael@0 312 // if we're the first in a new family, clear firstInFamily
michael@0 313 if (rec[i].fNames != NULL) {
michael@0 314 firstInFamily = NULL;
michael@0 315 }
michael@0 316
michael@0 317 bool isFixedWidth;
michael@0 318 SkString name;
michael@0 319 SkTypeface::Style style;
michael@0 320
michael@0 321 // we expect all the fonts, except the "fallback" fonts
michael@0 322 @@ -515,120 +483,75 @@ static void load_system_fonts() {
michael@0 323 // SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
michael@0 324 // rec[i].fFileName, fallbackCount, tf->uniqueID());
michael@0 325 gFallbackFonts[fallbackCount++] = tf->uniqueID();
michael@0 326 }
michael@0 327
michael@0 328 firstInFamily = tf;
michael@0 329 FamilyRec* family = find_family(tf);
michael@0 330 const char* const* names = rec[i].fNames;
michael@0 331
michael@0 332 // record the default family if this is it
michael@0 333 - if (names == gDefaultNames) {
michael@0 334 + if (names == DEFAULT_NAMES) {
michael@0 335 gDefaultFamily = family;
michael@0 336 }
michael@0 337 // add the names to map to this family
michael@0 338 while (*names) {
michael@0 339 add_name(*names, family);
michael@0 340 names += 1;
michael@0 341 }
michael@0 342 }
michael@0 343 }
michael@0 344
michael@0 345 // do this after all fonts are loaded. This is our default font, and it
michael@0 346 // acts as a sentinel so we only execute load_system_fonts() once
michael@0 347 gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal);
michael@0 348 // now terminate our fallback list with the sentinel value
michael@0 349 gFallbackFonts[fallbackCount] = 0;
michael@0 350 }
michael@0 351
michael@0 352 ///////////////////////////////////////////////////////////////////////////////
michael@0 353
michael@0 354 void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
michael@0 355 - // lookup and record if the font is custom (i.e. not a system font)
michael@0 356 - bool isCustomFont = !((FamilyTypeface*)face)->isSysFont();
michael@0 357 - stream->writeBool(isCustomFont);
michael@0 358 + const char* name = ((FamilyTypeface*)face)->getUniqueString();
michael@0 359
michael@0 360 - if (isCustomFont) {
michael@0 361 - SkStream* fontStream = ((FamilyTypeface*)face)->openStream();
michael@0 362 + stream->write8((uint8_t)face->style());
michael@0 363
michael@0 364 - // store the length of the custom font
michael@0 365 - uint32_t len = fontStream->getLength();
michael@0 366 - stream->write32(len);
michael@0 367 -
michael@0 368 - // store the entire font in the serialized stream
michael@0 369 - void* fontData = malloc(len);
michael@0 370 -
michael@0 371 - fontStream->read(fontData, len);
michael@0 372 - stream->write(fontData, len);
michael@0 373 -
michael@0 374 - fontStream->unref();
michael@0 375 - free(fontData);
michael@0 376 -// SkDebugf("--- fonthost custom serialize %d %d\n", face->style(), len);
michael@0 377 -
michael@0 378 + if (NULL == name || 0 == *name) {
michael@0 379 + stream->writePackedUInt(0);
michael@0 380 +// SkDebugf("--- fonthost serialize null\n");
michael@0 381 } else {
michael@0 382 - const char* name = ((FamilyTypeface*)face)->getUniqueString();
michael@0 383 -
michael@0 384 - stream->write8((uint8_t)face->style());
michael@0 385 -
michael@0 386 - if (NULL == name || 0 == *name) {
michael@0 387 - stream->writePackedUInt(0);
michael@0 388 -// SkDebugf("--- fonthost serialize null\n");
michael@0 389 - } else {
michael@0 390 - uint32_t len = strlen(name);
michael@0 391 - stream->writePackedUInt(len);
michael@0 392 - stream->write(name, len);
michael@0 393 -// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style());
michael@0 394 - }
michael@0 395 + uint32_t len = strlen(name);
michael@0 396 + stream->writePackedUInt(len);
michael@0 397 + stream->write(name, len);
michael@0 398 +// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style());
michael@0 399 }
michael@0 400 }
michael@0 401
michael@0 402 SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
michael@0 403 load_system_fonts();
michael@0 404
michael@0 405 - // check if the font is a custom or system font
michael@0 406 - bool isCustomFont = stream->readBool();
michael@0 407 + int style = stream->readU8();
michael@0 408
michael@0 409 - if (isCustomFont) {
michael@0 410 + int len = stream->readPackedUInt();
michael@0 411 + if (len > 0) {
michael@0 412 + SkString str;
michael@0 413 + str.resize(len);
michael@0 414 + stream->read(str.writable_str(), len);
michael@0 415
michael@0 416 - // read the length of the custom font from the stream
michael@0 417 - uint32_t len = stream->readU32();
michael@0 418 -
michael@0 419 - // generate a new stream to store the custom typeface
michael@0 420 - SkMemoryStream* fontStream = new SkMemoryStream(len);
michael@0 421 - stream->read((void*)fontStream->getMemoryBase(), len);
michael@0 422 -
michael@0 423 - SkTypeface* face = CreateTypefaceFromStream(fontStream);
michael@0 424 -
michael@0 425 - fontStream->unref();
michael@0 426 -
michael@0 427 -// SkDebugf("--- fonthost custom deserialize %d %d\n", face->style(), len);
michael@0 428 - return face;
michael@0 429 -
michael@0 430 - } else {
michael@0 431 - int style = stream->readU8();
michael@0 432 -
michael@0 433 - int len = stream->readPackedUInt();
michael@0 434 - if (len > 0) {
michael@0 435 - SkString str;
michael@0 436 - str.resize(len);
michael@0 437 - stream->read(str.writable_str(), len);
michael@0 438 -
michael@0 439 - const FontInitRec* rec = gSystemFonts;
michael@0 440 - for (size_t i = 0; i < gNumSystemFonts; i++) {
michael@0 441 - if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
michael@0 442 - // backup until we hit the fNames
michael@0 443 - for (int j = i; j >= 0; --j) {
michael@0 444 - if (rec[j].fNames != NULL) {
michael@0 445 - return SkFontHost::CreateTypeface(NULL,
michael@0 446 - rec[j].fNames[0], NULL, 0,
michael@0 447 - (SkTypeface::Style)style);
michael@0 448 - }
michael@0 449 + const FontInitRec* rec = gSystemFonts;
michael@0 450 + for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
michael@0 451 + if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
michael@0 452 + // backup until we hit the fNames
michael@0 453 + for (int j = i; j >= 0; --j) {
michael@0 454 + if (rec[j].fNames != NULL) {
michael@0 455 + return SkFontHost::CreateTypeface(NULL,
michael@0 456 + rec[j].fNames[0], NULL, 0, (SkTypeface::Style)style);
michael@0 457 }
michael@0 458 }
michael@0 459 }
michael@0 460 }
michael@0 461 }
michael@0 462 return NULL;
michael@0 463 }
michael@0 464
michael@0 465 ///////////////////////////////////////////////////////////////////////////////
michael@0 466
michael@0 467 @@ -697,49 +620,32 @@ size_t SkFontHost::GetFileName(SkFontID
michael@0 468 }
michael@0 469 return size;
michael@0 470 } else {
michael@0 471 return 0;
michael@0 472 }
michael@0 473 }
michael@0 474
michael@0 475 SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
michael@0 476 load_system_fonts();
michael@0 477
michael@0 478 - const SkTypeface* origTypeface = find_from_uniqueID(origFontID);
michael@0 479 - const SkTypeface* currTypeface = find_from_uniqueID(currFontID);
michael@0 480 -
michael@0 481 - SkASSERT(origTypeface != 0);
michael@0 482 - SkASSERT(currTypeface != 0);
michael@0 483 -
michael@0 484 - // Our fallback list always stores the id of the plain in each fallback
michael@0 485 - // family, so we transform currFontID to its plain equivalent.
michael@0 486 - currFontID = find_typeface(currTypeface, SkTypeface::kNormal)->uniqueID();
michael@0 487 -
michael@0 488 /* First see if fontID is already one of our fallbacks. If so, return
michael@0 489 its successor. If fontID is not in our list, then return the first one
michael@0 490 in our list. Note: list is zero-terminated, and returning zero means
michael@0 491 we have no more fonts to use for fallbacks.
michael@0 492 */
michael@0 493 const uint32_t* list = gFallbackFonts;
michael@0 494 for (int i = 0; list[i] != 0; i++) {
michael@0 495 if (list[i] == currFontID) {
michael@0 496 - if (list[i+1] == 0)
michael@0 497 - return 0;
michael@0 498 - const SkTypeface* nextTypeface = find_from_uniqueID(list[i+1]);
michael@0 499 - return find_typeface(nextTypeface, origTypeface->style())->uniqueID();
michael@0 500 + return list[i+1];
michael@0 501 }
michael@0 502 }
michael@0 503 -
michael@0 504 - // If we get here, currFontID was not a fallback, so we start at the
michael@0 505 - // beginning of our list.
michael@0 506 - const SkTypeface* firstTypeface = find_from_uniqueID(list[0]);
michael@0 507 - return find_typeface(firstTypeface, origTypeface->style())->uniqueID();
michael@0 508 + return list[0];
michael@0 509 }
michael@0 510
michael@0 511 ///////////////////////////////////////////////////////////////////////////////
michael@0 512
michael@0 513 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
michael@0 514 if (NULL == stream || stream->getLength() <= 0) {
michael@0 515 return NULL;
michael@0 516 }
michael@0 517
michael@0 518 bool isFixedWidth;
michael@0 519 @@ -754,10 +660,11 @@ SkTypeface* SkFontHost::CreateTypefaceFr
michael@0 520 }
michael@0 521
michael@0 522 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
michael@0 523 SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path));
michael@0 524 SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream);
michael@0 525 // since we created the stream, we let go of our ref() here
michael@0 526 stream->unref();
michael@0 527 return face;
michael@0 528 }
michael@0 529
michael@0 530 +///////////////////////////////////////////////////////////////////////////////

mercurial