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

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

mercurial