1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/patches/archive/old-android-fonthost.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,530 @@ 1.4 +# HG changeset patch 1.5 +# Parent 9ee29e4aace683ddf6cf8ddb2893cd34fcfc772c 1.6 +# User James Willcox <jwillcox@mozilla.com> 1.7 +diff --git a/gfx/skia/Makefile.in b/gfx/skia/Makefile.in 1.8 +--- a/gfx/skia/Makefile.in 1.9 ++++ b/gfx/skia/Makefile.in 1.10 +@@ -305,21 +305,20 @@ CPPSRCS += \ 1.11 + SkFontHost_mac_coretext.cpp \ 1.12 + SkTime_Unix.cpp \ 1.13 + $(NULL) 1.14 + endif 1.15 + 1.16 + ifeq (android,$(MOZ_WIDGET_TOOLKIT)) 1.17 + CPPSRCS += \ 1.18 + SkFontHost_FreeType.cpp \ 1.19 + SkFontHost_android.cpp \ 1.20 + SkFontHost_gamma.cpp \ 1.21 +- FontHostConfiguration_android.cpp \ 1.22 + SkMMapStream.cpp \ 1.23 + SkTime_Unix.cpp \ 1.24 + $(NULL) 1.25 + 1.26 + DEFINES += -DSK_BUILD_FOR_ANDROID_NDK 1.27 + OS_CXXFLAGS += $(CAIRO_FT_CFLAGS) 1.28 + endif 1.29 + 1.30 + ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT)) 1.31 + CPPSRCS += \ 1.32 +diff --git a/gfx/skia/src/ports/SkFontHost_android.cpp b/gfx/skia/src/ports/SkFontHost_android.cpp 1.33 +--- a/gfx/skia/src/ports/SkFontHost_android.cpp 1.34 ++++ b/gfx/skia/src/ports/SkFontHost_android.cpp 1.35 +@@ -1,38 +1,31 @@ 1.36 ++ 1.37 + /* 1.38 +-** 1.39 +-** Copyright 2006, The Android Open Source Project 1.40 +-** 1.41 +-** Licensed under the Apache License, Version 2.0 (the "License"); 1.42 +-** you may not use this file except in compliance with the License. 1.43 +-** You may obtain a copy of the License at 1.44 +-** 1.45 +-** http://www.apache.org/licenses/LICENSE-2.0 1.46 +-** 1.47 +-** Unless required by applicable law or agreed to in writing, software 1.48 +-** distributed under the License is distributed on an "AS IS" BASIS, 1.49 +-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.50 +-** See the License for the specific language governing permissions and 1.51 +-** limitations under the License. 1.52 +-*/ 1.53 ++ * Copyright 2006 The Android Open Source Project 1.54 ++ * 1.55 ++ * Use of this source code is governed by a BSD-style license that can be 1.56 ++ * found in the LICENSE file. 1.57 ++ */ 1.58 ++ 1.59 + 1.60 + #include "SkFontHost.h" 1.61 + #include "SkDescriptor.h" 1.62 + #include "SkMMapStream.h" 1.63 + #include "SkPaint.h" 1.64 + #include "SkString.h" 1.65 + #include "SkStream.h" 1.66 + #include "SkThread.h" 1.67 + #include "SkTSearch.h" 1.68 +-#include "FontHostConfiguration_android.h" 1.69 + #include <stdio.h> 1.70 + 1.71 ++#define FONT_CACHE_MEMORY_BUDGET (768 * 1024) 1.72 ++ 1.73 + #ifndef SK_FONT_FILE_PREFIX 1.74 + #define SK_FONT_FILE_PREFIX "/fonts/" 1.75 + #endif 1.76 + 1.77 + SkTypeface::Style find_name_and_attributes(SkStream* stream, SkString* name, 1.78 + bool* isFixedWidth); 1.79 + 1.80 + static void GetFullPathForSysFonts(SkString* full, const char name[]) { 1.81 + full->set(getenv("ANDROID_ROOT")); 1.82 + full->append(SK_FONT_FILE_PREFIX); 1.83 +@@ -99,21 +92,21 @@ static SkTypeface* find_best_face(const 1.84 + if (faces[SkTypeface::kNormal] != NULL) { 1.85 + return faces[SkTypeface::kNormal]; 1.86 + } 1.87 + // look for anything 1.88 + for (int i = 0; i < 4; i++) { 1.89 + if (faces[i] != NULL) { 1.90 + return faces[i]; 1.91 + } 1.92 + } 1.93 + // should never get here, since the faces list should not be empty 1.94 +- SkDEBUGFAIL("faces list is empty"); 1.95 ++ SkASSERT(!"faces list is empty"); 1.96 + return NULL; 1.97 + } 1.98 + 1.99 + static FamilyRec* find_family(const SkTypeface* member) { 1.100 + FamilyRec* curr = gFamilyHead; 1.101 + while (curr != NULL) { 1.102 + for (int i = 0; i < 4; i++) { 1.103 + if (curr->fFaces[i] == member) { 1.104 + return curr; 1.105 + } 1.106 +@@ -138,31 +131,27 @@ static SkTypeface* find_from_uniqueID(ui 1.107 + curr = curr->fNext; 1.108 + } 1.109 + return NULL; 1.110 + } 1.111 + 1.112 + /* Remove reference to this face from its family. If the resulting family 1.113 + is empty (has no faces), return that family, otherwise return NULL 1.114 + */ 1.115 + static FamilyRec* remove_from_family(const SkTypeface* face) { 1.116 + FamilyRec* family = find_family(face); 1.117 +- if (family) { 1.118 +- SkASSERT(family->fFaces[face->style()] == face); 1.119 +- family->fFaces[face->style()] = NULL; 1.120 ++ SkASSERT(family->fFaces[face->style()] == face); 1.121 ++ family->fFaces[face->style()] = NULL; 1.122 + 1.123 +- for (int i = 0; i < 4; i++) { 1.124 +- if (family->fFaces[i] != NULL) { // family is non-empty 1.125 +- return NULL; 1.126 +- } 1.127 ++ for (int i = 0; i < 4; i++) { 1.128 ++ if (family->fFaces[i] != NULL) { // family is non-empty 1.129 ++ return NULL; 1.130 + } 1.131 +- } else { 1.132 +-// SkDebugf("remove_from_family(%p) face not found", face); 1.133 + } 1.134 + return family; // return the empty family 1.135 + } 1.136 + 1.137 + // maybe we should make FamilyRec be doubly-linked 1.138 + static void detach_and_delete_family(FamilyRec* family) { 1.139 + FamilyRec* curr = gFamilyHead; 1.140 + FamilyRec* prev = NULL; 1.141 + 1.142 + while (curr != NULL) { 1.143 +@@ -172,21 +161,21 @@ static void detach_and_delete_family(Fam 1.144 + gFamilyHead = next; 1.145 + } else { 1.146 + prev->fNext = next; 1.147 + } 1.148 + SkDELETE(family); 1.149 + return; 1.150 + } 1.151 + prev = curr; 1.152 + curr = next; 1.153 + } 1.154 +- SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete"); 1.155 ++ SkASSERT(!"Yikes, couldn't find family in our list to remove/delete"); 1.156 + } 1.157 + 1.158 + static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) { 1.159 + NameFamilyPair* list = gNameList.begin(); 1.160 + int count = gNameList.count(); 1.161 + 1.162 + int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); 1.163 + 1.164 + if (index >= 0) { 1.165 + return find_best_face(list[index].fFamily, style); 1.166 +@@ -387,111 +376,90 @@ static bool get_name_and_style(const cha 1.167 + } 1.168 + return false; 1.169 + } 1.170 + 1.171 + // used to record our notion of the pre-existing fonts 1.172 + struct FontInitRec { 1.173 + const char* fFileName; 1.174 + const char* const* fNames; // null-terminated list 1.175 + }; 1.176 + 1.177 ++static const char* gSansNames[] = { 1.178 ++ "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL 1.179 ++}; 1.180 ++ 1.181 ++static const char* gSerifNames[] = { 1.182 ++ "serif", "times", "times new roman", "palatino", "georgia", "baskerville", 1.183 ++ "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL 1.184 ++}; 1.185 ++ 1.186 ++static const char* gMonoNames[] = { 1.187 ++ "monospace", "courier", "courier new", "monaco", NULL 1.188 ++}; 1.189 ++ 1.190 + // deliberately empty, but we use the address to identify fallback fonts 1.191 + static const char* gFBNames[] = { NULL }; 1.192 + 1.193 ++/* Fonts must be grouped by family, with the first font in a family having the 1.194 ++ list of names (even if that list is empty), and the following members having 1.195 ++ null for the list. The names list must be NULL-terminated 1.196 ++*/ 1.197 ++static const FontInitRec gSystemFonts[] = { 1.198 ++ { "DroidSans.ttf", gSansNames }, 1.199 ++ { "DroidSans-Bold.ttf", NULL }, 1.200 ++ { "DroidSerif-Regular.ttf", gSerifNames }, 1.201 ++ { "DroidSerif-Bold.ttf", NULL }, 1.202 ++ { "DroidSerif-Italic.ttf", NULL }, 1.203 ++ { "DroidSerif-BoldItalic.ttf", NULL }, 1.204 ++ { "DroidSansMono.ttf", gMonoNames }, 1.205 ++ /* These are optional, and can be ignored if not found in the file system. 1.206 ++ These are appended to gFallbackFonts[] as they are seen, so we list 1.207 ++ them in the order we want them to be accessed by NextLogicalFont(). 1.208 ++ */ 1.209 ++ { "DroidSansArabic.ttf", gFBNames }, 1.210 ++ { "DroidSansHebrew.ttf", gFBNames }, 1.211 ++ { "DroidSansThai.ttf", gFBNames }, 1.212 ++ { "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font 1.213 ++ { "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font 1.214 ++ { "DroidSansJapanese.ttf", gFBNames }, 1.215 ++ { "DroidSansFallback.ttf", gFBNames } 1.216 ++}; 1.217 + 1.218 +-/* Fonts are grouped by family, with the first font in a family having the 1.219 +- list of names (even if that list is empty), and the following members having 1.220 +- null for the list. The names list must be NULL-terminated. 1.221 +-*/ 1.222 +-static FontInitRec *gSystemFonts; 1.223 +-static size_t gNumSystemFonts = 0; 1.224 +- 1.225 +-#define SYSTEM_FONTS_FILE "/system/etc/system_fonts.cfg" 1.226 ++#define DEFAULT_NAMES gSansNames 1.227 + 1.228 + // these globals are assigned (once) by load_system_fonts() 1.229 + static FamilyRec* gDefaultFamily; 1.230 + static SkTypeface* gDefaultNormal; 1.231 +-static char** gDefaultNames = NULL; 1.232 +-static uint32_t *gFallbackFonts; 1.233 + 1.234 +-/* Load info from a configuration file that populates the system/fallback font structures 1.235 +-*/ 1.236 +-static void load_font_info() { 1.237 +-// load_font_info_xml("/system/etc/system_fonts.xml"); 1.238 +- SkTDArray<FontFamily*> fontFamilies; 1.239 +- getFontFamilies(fontFamilies); 1.240 +- 1.241 +- SkTDArray<FontInitRec> fontInfo; 1.242 +- bool firstInFamily = false; 1.243 +- for (int i = 0; i < fontFamilies.count(); ++i) { 1.244 +- FontFamily *family = fontFamilies[i]; 1.245 +- firstInFamily = true; 1.246 +- for (int j = 0; j < family->fFileNames.count(); ++j) { 1.247 +- FontInitRec fontInfoRecord; 1.248 +- fontInfoRecord.fFileName = family->fFileNames[j]; 1.249 +- if (j == 0) { 1.250 +- if (family->fNames.count() == 0) { 1.251 +- // Fallback font 1.252 +- fontInfoRecord.fNames = (char **)gFBNames; 1.253 +- } else { 1.254 +- SkTDArray<const char*> names = family->fNames; 1.255 +- const char **nameList = (const char**) 1.256 +- malloc((names.count() + 1) * sizeof(char*)); 1.257 +- if (nameList == NULL) { 1.258 +- // shouldn't get here 1.259 +- break; 1.260 +- } 1.261 +- if (gDefaultNames == NULL) { 1.262 +- gDefaultNames = (char**) nameList; 1.263 +- } 1.264 +- for (int i = 0; i < names.count(); ++i) { 1.265 +- nameList[i] = names[i]; 1.266 +- } 1.267 +- nameList[names.count()] = NULL; 1.268 +- fontInfoRecord.fNames = nameList; 1.269 +- } 1.270 +- } else { 1.271 +- fontInfoRecord.fNames = NULL; 1.272 +- } 1.273 +- *fontInfo.append() = fontInfoRecord; 1.274 +- } 1.275 +- } 1.276 +- gNumSystemFonts = fontInfo.count(); 1.277 +- gSystemFonts = (FontInitRec*) malloc(gNumSystemFonts * sizeof(FontInitRec)); 1.278 +- gFallbackFonts = (uint32_t*) malloc((gNumSystemFonts + 1) * sizeof(uint32_t)); 1.279 +- if (gSystemFonts == NULL) { 1.280 +- // shouldn't get here 1.281 +- gNumSystemFonts = 0; 1.282 +- } 1.283 +- for (size_t i = 0; i < gNumSystemFonts; ++i) { 1.284 +- gSystemFonts[i].fFileName = fontInfo[i].fFileName; 1.285 +- gSystemFonts[i].fNames = fontInfo[i].fNames; 1.286 +- } 1.287 +- fontFamilies.deleteAll(); 1.288 +-} 1.289 ++/* This is sized conservatively, assuming that it will never be a size issue. 1.290 ++ It will be initialized in load_system_fonts(), and will be filled with the 1.291 ++ fontIDs that can be used for fallback consideration, in sorted order (sorted 1.292 ++ meaning element[0] should be used first, then element[1], etc. When we hit 1.293 ++ a fontID==0 in the array, the list is done, hence our allocation size is 1.294 ++ +1 the total number of possible system fonts. Also see NextLogicalFont(). 1.295 ++ */ 1.296 ++static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1]; 1.297 + 1.298 + /* Called once (ensured by the sentinel check at the beginning of our body). 1.299 + Initializes all the globals, and register the system fonts. 1.300 + */ 1.301 + static void load_system_fonts() { 1.302 + // check if we've already be called 1.303 + if (NULL != gDefaultNormal) { 1.304 + return; 1.305 + } 1.306 + 1.307 +- load_font_info(); 1.308 +- 1.309 + const FontInitRec* rec = gSystemFonts; 1.310 + SkTypeface* firstInFamily = NULL; 1.311 + int fallbackCount = 0; 1.312 + 1.313 +- for (size_t i = 0; i < gNumSystemFonts; i++) { 1.314 ++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { 1.315 + // if we're the first in a new family, clear firstInFamily 1.316 + if (rec[i].fNames != NULL) { 1.317 + firstInFamily = NULL; 1.318 + } 1.319 + 1.320 + bool isFixedWidth; 1.321 + SkString name; 1.322 + SkTypeface::Style style; 1.323 + 1.324 + // we expect all the fonts, except the "fallback" fonts 1.325 +@@ -515,120 +483,75 @@ static void load_system_fonts() { 1.326 + // SkDebugf("---- adding %s as fallback[%d] fontID %d\n", 1.327 + // rec[i].fFileName, fallbackCount, tf->uniqueID()); 1.328 + gFallbackFonts[fallbackCount++] = tf->uniqueID(); 1.329 + } 1.330 + 1.331 + firstInFamily = tf; 1.332 + FamilyRec* family = find_family(tf); 1.333 + const char* const* names = rec[i].fNames; 1.334 + 1.335 + // record the default family if this is it 1.336 +- if (names == gDefaultNames) { 1.337 ++ if (names == DEFAULT_NAMES) { 1.338 + gDefaultFamily = family; 1.339 + } 1.340 + // add the names to map to this family 1.341 + while (*names) { 1.342 + add_name(*names, family); 1.343 + names += 1; 1.344 + } 1.345 + } 1.346 + } 1.347 + 1.348 + // do this after all fonts are loaded. This is our default font, and it 1.349 + // acts as a sentinel so we only execute load_system_fonts() once 1.350 + gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal); 1.351 + // now terminate our fallback list with the sentinel value 1.352 + gFallbackFonts[fallbackCount] = 0; 1.353 + } 1.354 + 1.355 + /////////////////////////////////////////////////////////////////////////////// 1.356 + 1.357 + void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { 1.358 +- // lookup and record if the font is custom (i.e. not a system font) 1.359 +- bool isCustomFont = !((FamilyTypeface*)face)->isSysFont(); 1.360 +- stream->writeBool(isCustomFont); 1.361 ++ const char* name = ((FamilyTypeface*)face)->getUniqueString(); 1.362 + 1.363 +- if (isCustomFont) { 1.364 +- SkStream* fontStream = ((FamilyTypeface*)face)->openStream(); 1.365 ++ stream->write8((uint8_t)face->style()); 1.366 + 1.367 +- // store the length of the custom font 1.368 +- uint32_t len = fontStream->getLength(); 1.369 +- stream->write32(len); 1.370 +- 1.371 +- // store the entire font in the serialized stream 1.372 +- void* fontData = malloc(len); 1.373 +- 1.374 +- fontStream->read(fontData, len); 1.375 +- stream->write(fontData, len); 1.376 +- 1.377 +- fontStream->unref(); 1.378 +- free(fontData); 1.379 +-// SkDebugf("--- fonthost custom serialize %d %d\n", face->style(), len); 1.380 +- 1.381 ++ if (NULL == name || 0 == *name) { 1.382 ++ stream->writePackedUInt(0); 1.383 ++// SkDebugf("--- fonthost serialize null\n"); 1.384 + } else { 1.385 +- const char* name = ((FamilyTypeface*)face)->getUniqueString(); 1.386 +- 1.387 +- stream->write8((uint8_t)face->style()); 1.388 +- 1.389 +- if (NULL == name || 0 == *name) { 1.390 +- stream->writePackedUInt(0); 1.391 +-// SkDebugf("--- fonthost serialize null\n"); 1.392 +- } else { 1.393 +- uint32_t len = strlen(name); 1.394 +- stream->writePackedUInt(len); 1.395 +- stream->write(name, len); 1.396 +-// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style()); 1.397 +- } 1.398 ++ uint32_t len = strlen(name); 1.399 ++ stream->writePackedUInt(len); 1.400 ++ stream->write(name, len); 1.401 ++// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style()); 1.402 + } 1.403 + } 1.404 + 1.405 + SkTypeface* SkFontHost::Deserialize(SkStream* stream) { 1.406 + load_system_fonts(); 1.407 + 1.408 +- // check if the font is a custom or system font 1.409 +- bool isCustomFont = stream->readBool(); 1.410 ++ int style = stream->readU8(); 1.411 + 1.412 +- if (isCustomFont) { 1.413 ++ int len = stream->readPackedUInt(); 1.414 ++ if (len > 0) { 1.415 ++ SkString str; 1.416 ++ str.resize(len); 1.417 ++ stream->read(str.writable_str(), len); 1.418 + 1.419 +- // read the length of the custom font from the stream 1.420 +- uint32_t len = stream->readU32(); 1.421 +- 1.422 +- // generate a new stream to store the custom typeface 1.423 +- SkMemoryStream* fontStream = new SkMemoryStream(len); 1.424 +- stream->read((void*)fontStream->getMemoryBase(), len); 1.425 +- 1.426 +- SkTypeface* face = CreateTypefaceFromStream(fontStream); 1.427 +- 1.428 +- fontStream->unref(); 1.429 +- 1.430 +-// SkDebugf("--- fonthost custom deserialize %d %d\n", face->style(), len); 1.431 +- return face; 1.432 +- 1.433 +- } else { 1.434 +- int style = stream->readU8(); 1.435 +- 1.436 +- int len = stream->readPackedUInt(); 1.437 +- if (len > 0) { 1.438 +- SkString str; 1.439 +- str.resize(len); 1.440 +- stream->read(str.writable_str(), len); 1.441 +- 1.442 +- const FontInitRec* rec = gSystemFonts; 1.443 +- for (size_t i = 0; i < gNumSystemFonts; i++) { 1.444 +- if (strcmp(rec[i].fFileName, str.c_str()) == 0) { 1.445 +- // backup until we hit the fNames 1.446 +- for (int j = i; j >= 0; --j) { 1.447 +- if (rec[j].fNames != NULL) { 1.448 +- return SkFontHost::CreateTypeface(NULL, 1.449 +- rec[j].fNames[0], NULL, 0, 1.450 +- (SkTypeface::Style)style); 1.451 +- } 1.452 ++ const FontInitRec* rec = gSystemFonts; 1.453 ++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { 1.454 ++ if (strcmp(rec[i].fFileName, str.c_str()) == 0) { 1.455 ++ // backup until we hit the fNames 1.456 ++ for (int j = i; j >= 0; --j) { 1.457 ++ if (rec[j].fNames != NULL) { 1.458 ++ return SkFontHost::CreateTypeface(NULL, 1.459 ++ rec[j].fNames[0], NULL, 0, (SkTypeface::Style)style); 1.460 + } 1.461 + } 1.462 + } 1.463 + } 1.464 + } 1.465 + return NULL; 1.466 + } 1.467 + 1.468 + /////////////////////////////////////////////////////////////////////////////// 1.469 + 1.470 +@@ -697,49 +620,32 @@ size_t SkFontHost::GetFileName(SkFontID 1.471 + } 1.472 + return size; 1.473 + } else { 1.474 + return 0; 1.475 + } 1.476 + } 1.477 + 1.478 + SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) { 1.479 + load_system_fonts(); 1.480 + 1.481 +- const SkTypeface* origTypeface = find_from_uniqueID(origFontID); 1.482 +- const SkTypeface* currTypeface = find_from_uniqueID(currFontID); 1.483 +- 1.484 +- SkASSERT(origTypeface != 0); 1.485 +- SkASSERT(currTypeface != 0); 1.486 +- 1.487 +- // Our fallback list always stores the id of the plain in each fallback 1.488 +- // family, so we transform currFontID to its plain equivalent. 1.489 +- currFontID = find_typeface(currTypeface, SkTypeface::kNormal)->uniqueID(); 1.490 +- 1.491 + /* First see if fontID is already one of our fallbacks. If so, return 1.492 + its successor. If fontID is not in our list, then return the first one 1.493 + in our list. Note: list is zero-terminated, and returning zero means 1.494 + we have no more fonts to use for fallbacks. 1.495 + */ 1.496 + const uint32_t* list = gFallbackFonts; 1.497 + for (int i = 0; list[i] != 0; i++) { 1.498 + if (list[i] == currFontID) { 1.499 +- if (list[i+1] == 0) 1.500 +- return 0; 1.501 +- const SkTypeface* nextTypeface = find_from_uniqueID(list[i+1]); 1.502 +- return find_typeface(nextTypeface, origTypeface->style())->uniqueID(); 1.503 ++ return list[i+1]; 1.504 + } 1.505 + } 1.506 +- 1.507 +- // If we get here, currFontID was not a fallback, so we start at the 1.508 +- // beginning of our list. 1.509 +- const SkTypeface* firstTypeface = find_from_uniqueID(list[0]); 1.510 +- return find_typeface(firstTypeface, origTypeface->style())->uniqueID(); 1.511 ++ return list[0]; 1.512 + } 1.513 + 1.514 + /////////////////////////////////////////////////////////////////////////////// 1.515 + 1.516 + SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { 1.517 + if (NULL == stream || stream->getLength() <= 0) { 1.518 + return NULL; 1.519 + } 1.520 + 1.521 + bool isFixedWidth; 1.522 +@@ -754,10 +660,11 @@ SkTypeface* SkFontHost::CreateTypefaceFr 1.523 + } 1.524 + 1.525 + SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { 1.526 + SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path)); 1.527 + SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream); 1.528 + // since we created the stream, we let go of our ref() here 1.529 + stream->unref(); 1.530 + return face; 1.531 + } 1.532 + 1.533 ++///////////////////////////////////////////////////////////////////////////////