Wed, 31 Dec 2014 06:09:35 +0100
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 | +/////////////////////////////////////////////////////////////////////////////// |