1 :
2 : /*
3 : * Copyright 2006 The Android Open Source Project
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 : #include "SkFontHost.h"
11 : #include "SkDescriptor.h"
12 : #include "SkMMapStream.h"
13 : #include "SkOSFile.h"
14 : #include "SkPaint.h"
15 : #include "SkString.h"
16 : #include "SkStream.h"
17 : #include "SkThread.h"
18 : #include "SkTSearch.h"
19 : #include <stdio.h>
20 :
21 : #ifndef SK_FONT_FILE_PREFIX
22 : #define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/msttcorefonts/"
23 : #endif
24 :
25 : SkTypeface::Style find_name_and_attributes(SkStream* stream, SkString* name,
26 : bool* isFixedWidth);
27 :
28 0 : static void GetFullPathForSysFonts(SkString* full, const char name[])
29 : {
30 0 : full->append(SK_FONT_FILE_PREFIX);
31 0 : full->append(name);
32 0 : }
33 :
34 : ///////////////////////////////////////////////////////////////////////////////
35 :
36 : struct FamilyRec;
37 :
38 : /* This guy holds a mapping of a name -> family, used for looking up fonts.
39 : Since it is stored in a stretchy array that doesn't preserve object
40 : semantics, we don't use constructor/destructors, but just have explicit
41 : helpers to manage our internal bookkeeping.
42 : */
43 : struct NameFamilyPair {
44 : const char* fName; // we own this
45 : FamilyRec* fFamily; // we don't own this, we just reference it
46 :
47 0 : void construct(const char name[], FamilyRec* family)
48 : {
49 0 : fName = strdup(name);
50 0 : fFamily = family; // we don't own this, so just record the referene
51 0 : }
52 0 : void destruct()
53 : {
54 0 : free((char*)fName);
55 : // we don't own family, so just ignore our reference
56 0 : }
57 : };
58 :
59 : // we use atomic_inc to grow this for each typeface we create
60 : static int32_t gUniqueFontID;
61 :
62 : // this is the mutex that protects these globals
63 1464 : static SkMutex gFamilyMutex;
64 : static FamilyRec* gFamilyHead;
65 1464 : static SkTDArray<NameFamilyPair> gNameList;
66 :
67 : struct FamilyRec {
68 : FamilyRec* fNext;
69 : SkTypeface* fFaces[4];
70 :
71 0 : FamilyRec()
72 : {
73 0 : fNext = gFamilyHead;
74 0 : memset(fFaces, 0, sizeof(fFaces));
75 0 : gFamilyHead = this;
76 0 : }
77 : };
78 :
79 0 : static SkTypeface* find_best_face(const FamilyRec* family,
80 : SkTypeface::Style style) {
81 0 : SkTypeface* const* faces = family->fFaces;
82 :
83 0 : if (faces[style] != NULL) { // exact match
84 0 : return faces[style];
85 : }
86 : // look for a matching bold
87 0 : style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
88 0 : if (faces[style] != NULL) {
89 0 : return faces[style];
90 : }
91 : // look for the plain
92 0 : if (faces[SkTypeface::kNormal] != NULL) {
93 0 : return faces[SkTypeface::kNormal];
94 : }
95 : // look for anything
96 0 : for (int i = 0; i < 4; i++) {
97 0 : if (faces[i] != NULL) {
98 0 : return faces[i];
99 : }
100 : }
101 : // should never get here, since the faces list should not be empty
102 0 : SkDEBUGFAIL("faces list is empty");
103 0 : return NULL;
104 : }
105 :
106 0 : static FamilyRec* find_family(const SkTypeface* member) {
107 0 : FamilyRec* curr = gFamilyHead;
108 0 : while (curr != NULL) {
109 0 : for (int i = 0; i < 4; i++) {
110 0 : if (curr->fFaces[i] == member) {
111 0 : return curr;
112 : }
113 : }
114 0 : curr = curr->fNext;
115 : }
116 0 : return NULL;
117 : }
118 :
119 0 : static SkTypeface* find_from_uniqueID(uint32_t uniqueID) {
120 0 : FamilyRec* curr = gFamilyHead;
121 0 : while (curr != NULL) {
122 0 : for (int i = 0; i < 4; i++) {
123 0 : SkTypeface* face = curr->fFaces[i];
124 0 : if (face != NULL && face->uniqueID() == uniqueID) {
125 0 : return face;
126 : }
127 : }
128 0 : curr = curr->fNext;
129 : }
130 0 : return NULL;
131 : }
132 :
133 0 : static bool valid_uniqueID(uint32_t uniqueID) {
134 0 : return find_from_uniqueID(uniqueID) != NULL;
135 : }
136 :
137 : /* Remove reference to this face from its family. If the resulting family
138 : is empty (has no faces), return that family, otherwise return NULL
139 : */
140 0 : static FamilyRec* remove_from_family(const SkTypeface* face) {
141 0 : FamilyRec* family = find_family(face);
142 0 : SkASSERT(family->fFaces[face->style()] == face);
143 0 : family->fFaces[face->style()] = NULL;
144 :
145 0 : for (int i = 0; i < 4; i++) {
146 0 : if (family->fFaces[i] != NULL) { // family is non-empty
147 0 : return NULL;
148 : }
149 : }
150 0 : return family; // return the empty family
151 : }
152 :
153 : // maybe we should make FamilyRec be doubly-linked
154 0 : static void detach_and_delete_family(FamilyRec* family) {
155 0 : FamilyRec* curr = gFamilyHead;
156 0 : FamilyRec* prev = NULL;
157 :
158 0 : while (curr != NULL) {
159 0 : FamilyRec* next = curr->fNext;
160 0 : if (curr == family) {
161 0 : if (prev == NULL) {
162 0 : gFamilyHead = next;
163 : } else {
164 0 : prev->fNext = next;
165 : }
166 0 : SkDELETE(family);
167 0 : return;
168 : }
169 0 : prev = curr;
170 0 : curr = next;
171 : }
172 0 : SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete");
173 : }
174 :
175 0 : static FamilyRec* find_familyrec(const char name[]) {
176 0 : const NameFamilyPair* list = gNameList.begin();
177 : int index = SkStrLCSearch(&list[0].fName, gNameList.count(), name,
178 0 : sizeof(list[0]));
179 0 : return index >= 0 ? list[index].fFamily : NULL;
180 : }
181 :
182 0 : static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
183 0 : FamilyRec* rec = find_familyrec(name);
184 0 : return rec ? find_best_face(rec, style) : NULL;
185 : }
186 :
187 0 : static SkTypeface* find_typeface(const SkTypeface* familyMember,
188 : SkTypeface::Style style) {
189 0 : const FamilyRec* family = find_family(familyMember);
190 0 : return family ? find_best_face(family, style) : NULL;
191 : }
192 :
193 0 : static void add_name(const char name[], FamilyRec* family) {
194 0 : SkAutoAsciiToLC tolc(name);
195 0 : name = tolc.lc();
196 :
197 0 : NameFamilyPair* list = gNameList.begin();
198 0 : int count = gNameList.count();
199 :
200 0 : int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
201 :
202 0 : if (index < 0) {
203 0 : list = gNameList.insert(~index);
204 0 : list->construct(name, family);
205 : }
206 0 : }
207 :
208 0 : static void remove_from_names(FamilyRec* emptyFamily) {
209 : #ifdef SK_DEBUG
210 0 : for (int i = 0; i < 4; i++) {
211 0 : SkASSERT(emptyFamily->fFaces[i] == NULL);
212 : }
213 : #endif
214 :
215 0 : SkTDArray<NameFamilyPair>& list = gNameList;
216 :
217 : // must go backwards when removing
218 0 : for (int i = list.count() - 1; i >= 0; --i) {
219 0 : NameFamilyPair* pair = &list[i];
220 0 : if (pair->fFamily == emptyFamily) {
221 0 : pair->destruct();
222 0 : list.remove(i);
223 : }
224 : }
225 0 : }
226 :
227 : ///////////////////////////////////////////////////////////////////////////////
228 :
229 : class FamilyTypeface : public SkTypeface {
230 : public:
231 0 : FamilyTypeface(Style style, bool sysFont, FamilyRec* family, bool isFixedWidth)
232 0 : : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) {
233 0 : fIsSysFont = sysFont;
234 :
235 0 : SkAutoMutexAcquire ac(gFamilyMutex);
236 :
237 0 : if (NULL == family) {
238 0 : family = SkNEW(FamilyRec);
239 : }
240 0 : family->fFaces[style] = this;
241 0 : fFamilyRec = family; // just record it so we can return it if asked
242 0 : }
243 :
244 0 : virtual ~FamilyTypeface() {
245 0 : SkAutoMutexAcquire ac(gFamilyMutex);
246 :
247 : // remove us from our family. If the family is now empty, we return
248 : // that and then remove that family from the name list
249 0 : FamilyRec* family = remove_from_family(this);
250 0 : if (NULL != family) {
251 0 : remove_from_names(family);
252 0 : detach_and_delete_family(family);
253 : }
254 0 : }
255 :
256 : bool isSysFont() const { return fIsSysFont; }
257 0 : FamilyRec* getFamily() const { return fFamilyRec; }
258 : // openStream returns a SkStream that has been ref-ed
259 : virtual SkStream* openStream() = 0;
260 : virtual const char* getUniqueString() const = 0;
261 :
262 : private:
263 : FamilyRec* fFamilyRec; // we don't own this, just point to it
264 : bool fIsSysFont;
265 :
266 : typedef SkTypeface INHERITED;
267 : };
268 :
269 : ///////////////////////////////////////////////////////////////////////////////
270 :
271 : /* This subclass is just a place holder for when we have no fonts available.
272 : It exists so that our globals (e.g. gFamilyHead) that expect *something*
273 : will not be null.
274 : */
275 0 : class EmptyTypeface : public FamilyTypeface {
276 : public:
277 0 : EmptyTypeface() : INHERITED(SkTypeface::kNormal, true, NULL, false) {}
278 :
279 : // overrides
280 0 : virtual SkStream* openStream() { return NULL; }
281 0 : virtual const char* getUniqueString() const { return NULL; }
282 :
283 : private:
284 : typedef FamilyTypeface INHERITED;
285 : };
286 :
287 : class StreamTypeface : public FamilyTypeface {
288 : public:
289 0 : StreamTypeface(Style style, bool sysFont, FamilyRec* family,
290 : SkStream* stream, bool isFixedWidth)
291 0 : : INHERITED(style, sysFont, family, isFixedWidth) {
292 0 : stream->ref();
293 0 : fStream = stream;
294 0 : }
295 0 : virtual ~StreamTypeface() {
296 0 : fStream->unref();
297 0 : }
298 :
299 : // overrides
300 0 : virtual SkStream* openStream()
301 : {
302 : // openStream returns a refed stream.
303 0 : fStream->ref();
304 0 : return fStream;
305 : }
306 0 : virtual const char* getUniqueString() const { return NULL; }
307 :
308 : private:
309 : SkStream* fStream;
310 :
311 : typedef FamilyTypeface INHERITED;
312 : };
313 :
314 0 : class FileTypeface : public FamilyTypeface {
315 : public:
316 0 : FileTypeface(Style style, bool sysFont, FamilyRec* family,
317 : const char path[], bool isFixedWidth)
318 0 : : INHERITED(style, sysFont, family, isFixedWidth) {
319 0 : fPath.set(path);
320 0 : }
321 :
322 : // overrides
323 0 : virtual SkStream* openStream()
324 : {
325 0 : SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str()));
326 :
327 : // check for failure
328 0 : if (stream->getLength() <= 0) {
329 0 : SkDELETE(stream);
330 : // maybe MMAP isn't supported. try FILE
331 0 : stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str()));
332 0 : if (stream->getLength() <= 0) {
333 0 : SkDELETE(stream);
334 0 : stream = NULL;
335 : }
336 : }
337 0 : return stream;
338 : }
339 :
340 0 : virtual const char* getUniqueString() const {
341 0 : const char* str = strrchr(fPath.c_str(), '/');
342 0 : if (str) {
343 0 : str += 1; // skip the '/'
344 : }
345 0 : return str;
346 : }
347 :
348 : private:
349 : SkString fPath;
350 :
351 : typedef FamilyTypeface INHERITED;
352 : };
353 :
354 : ///////////////////////////////////////////////////////////////////////////////
355 : ///////////////////////////////////////////////////////////////////////////////
356 :
357 0 : static bool get_name_and_style(const char path[], SkString* name,
358 : SkTypeface::Style* style, bool* isFixedWidth) {
359 0 : SkMMAPStream stream(path);
360 0 : if (stream.getLength() > 0) {
361 0 : *style = find_name_and_attributes(&stream, name, isFixedWidth);
362 0 : return true;
363 : }
364 : else {
365 0 : SkFILEStream stream(path);
366 0 : if (stream.getLength() > 0) {
367 0 : *style = find_name_and_attributes(&stream, name, isFixedWidth);
368 0 : return true;
369 : }
370 : }
371 :
372 0 : SkDebugf("---- failed to open <%s> as a font\n", path);
373 0 : return false;
374 : }
375 :
376 : // these globals are assigned (once) by load_system_fonts()
377 : static SkTypeface* gFallBackTypeface;
378 : static FamilyRec* gDefaultFamily;
379 : static SkTypeface* gDefaultNormal;
380 :
381 0 : static void load_system_fonts() {
382 : // check if we've already be called
383 0 : if (NULL != gDefaultNormal) {
384 : // printf("---- default font %p\n", gDefaultNormal);
385 0 : return;
386 : }
387 :
388 0 : SkOSFile::Iter iter(SK_FONT_FILE_PREFIX, ".ttf");
389 0 : SkString name;
390 0 : int count = 0;
391 :
392 0 : while (iter.next(&name, false)) {
393 0 : SkString filename;
394 0 : GetFullPathForSysFonts(&filename, name.c_str());
395 :
396 : bool isFixedWidth;
397 0 : SkString realname;
398 0 : SkTypeface::Style style = SkTypeface::kNormal; // avoid uninitialized warning
399 :
400 0 : if (!get_name_and_style(filename.c_str(), &realname, &style, &isFixedWidth)) {
401 0 : SkDebugf("------ can't load <%s> as a font\n", filename.c_str());
402 0 : continue;
403 : }
404 :
405 : // SkDebugf("font: <%s> %d <%s>\n", realname.c_str(), style, filename.c_str());
406 :
407 0 : FamilyRec* family = find_familyrec(realname.c_str());
408 0 : if (family && family->fFaces[style]) {
409 : // SkDebugf("---- skipping duplicate typeface %s style %d\n",
410 : // realname.c_str(), style);
411 0 : continue;
412 : }
413 :
414 : // this constructor puts us into the global gFamilyHead llist
415 0 : FamilyTypeface* tf = SkNEW_ARGS(FileTypeface,
416 : (style,
417 : true, // system-font (cannot delete)
418 : family, // what family to join
419 : filename.c_str(),
420 : isFixedWidth) // filename
421 : );
422 :
423 0 : if (NULL == family) {
424 0 : add_name(realname.c_str(), tf->getFamily());
425 : }
426 0 : count += 1;
427 : }
428 :
429 0 : if (0 == count) {
430 0 : SkNEW(EmptyTypeface);
431 : }
432 :
433 : // do this after all fonts are loaded. This is our default font, and it
434 : // acts as a sentinel so we only execute load_system_fonts() once
435 : static const char* gDefaultNames[] = {
436 : "Arial", "Verdana", "Times New Roman", NULL
437 : };
438 0 : const char** names = gDefaultNames;
439 0 : while (*names) {
440 0 : SkTypeface* tf = find_typeface(*names++, SkTypeface::kNormal);
441 0 : if (tf) {
442 0 : gDefaultNormal = tf;
443 0 : break;
444 : }
445 : }
446 : // check if we found *something*
447 0 : if (NULL == gDefaultNormal) {
448 0 : if (NULL == gFamilyHead) {
449 0 : sk_throw();
450 : }
451 0 : for (int i = 0; i < 4; i++) {
452 0 : if ((gDefaultNormal = gFamilyHead->fFaces[i]) != NULL) {
453 0 : break;
454 : }
455 : }
456 : }
457 0 : if (NULL == gDefaultNormal) {
458 0 : sk_throw();
459 : }
460 0 : gFallBackTypeface = gDefaultNormal;
461 0 : gDefaultFamily = find_family(gDefaultNormal);
462 :
463 : // SkDebugf("---- default %p head %p family %p\n", gDefaultNormal, gFamilyHead, gDefaultFamily);
464 : }
465 :
466 : ///////////////////////////////////////////////////////////////////////////////
467 :
468 0 : void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
469 : #if 0
470 : const char* name = ((FamilyTypeface*)face)->getUniqueString();
471 :
472 : stream->write8((uint8_t)face->getStyle());
473 :
474 : if (NULL == name || 0 == *name) {
475 : stream->writePackedUInt(0);
476 : // SkDebugf("--- fonthost serialize null\n");
477 : } else {
478 : uint32_t len = strlen(name);
479 : stream->writePackedUInt(len);
480 : stream->write(name, len);
481 : // SkDebugf("--- fonthost serialize <%s> %d\n", name, face->getStyle());
482 : }
483 : #endif
484 0 : sk_throw();
485 0 : }
486 :
487 0 : SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
488 : #if 0
489 : load_system_fonts();
490 :
491 : int style = stream->readU8();
492 :
493 : int len = stream->readPackedUInt();
494 : if (len > 0) {
495 : SkString str;
496 : str.resize(len);
497 : stream->read(str.writable_str(), len);
498 :
499 : const FontInitRec* rec = gSystemFonts;
500 : for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
501 : if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
502 : // backup until we hit the fNames
503 : for (int j = i; j >= 0; --j) {
504 : if (rec[j].fNames != NULL) {
505 : return SkFontHost::CreateTypeface(NULL, rec[j].fNames[0], NULL, 0,
506 : (SkTypeface::Style)style);
507 : }
508 : }
509 : }
510 : }
511 : }
512 : return SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, (SkTypeface::Style)style);
513 : #endif
514 0 : sk_throw();
515 0 : return NULL;
516 : }
517 :
518 : ///////////////////////////////////////////////////////////////////////////////
519 :
520 0 : SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
521 : const char familyName[],
522 : const void* data, size_t bytelength,
523 : SkTypeface::Style style) {
524 0 : load_system_fonts();
525 :
526 0 : SkAutoMutexAcquire ac(gFamilyMutex);
527 :
528 : // clip to legal style bits
529 0 : style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
530 :
531 0 : SkTypeface* tf = NULL;
532 :
533 0 : if (NULL != familyFace) {
534 0 : tf = find_typeface(familyFace, style);
535 0 : } else if (NULL != familyName) {
536 : // SkDebugf("======= familyName <%s>\n", familyName);
537 0 : tf = find_typeface(familyName, style);
538 : }
539 :
540 0 : if (NULL == tf) {
541 0 : tf = find_best_face(gDefaultFamily, style);
542 : }
543 :
544 0 : SkSafeRef(tf);
545 0 : return tf;
546 : }
547 :
548 0 : bool SkFontHost::ValidFontID(uint32_t fontID) {
549 0 : SkAutoMutexAcquire ac(gFamilyMutex);
550 :
551 0 : return valid_uniqueID(fontID);
552 : }
553 :
554 0 : SkStream* SkFontHost::OpenStream(uint32_t fontID) {
555 0 : FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
556 0 : SkStream* stream = tf ? tf->openStream() : NULL;
557 :
558 0 : if (stream && stream->getLength() == 0) {
559 0 : stream->unref();
560 0 : stream = NULL;
561 : }
562 0 : return stream;
563 : }
564 :
565 0 : size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
566 : int32_t* index) {
567 0 : SkDebugf("SkFontHost::GetFileName unimplemented\n");
568 0 : return 0;
569 : }
570 :
571 0 : SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
572 0 : return 0;
573 : }
574 :
575 : ///////////////////////////////////////////////////////////////////////////////
576 :
577 0 : SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
578 0 : if (NULL == stream || stream->getLength() <= 0) {
579 0 : SkDELETE(stream);
580 0 : return NULL;
581 : }
582 :
583 : bool isFixedWidth;
584 0 : SkString name;
585 0 : SkTypeface::Style style = find_name_and_attributes(stream, &name, &isFixedWidth);
586 :
587 0 : return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream, isFixedWidth));
588 : }
589 :
590 0 : SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
591 0 : SkTypeface* face = NULL;
592 0 : SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
593 :
594 0 : if (stream->isValid()) {
595 0 : face = CreateTypefaceFromStream(stream);
596 : }
597 0 : stream->unref();
598 0 : return face;
599 4392 : }
600 :
|