1 2 /* 3 * Copyright 2011 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 "SkPaint.h" 14 #include "SkString.h" 15 #include "SkStream.h" 16 #include "SkThread.h" 17 #include "SkTSearch.h" 18 #include <stdio.h> 19 20 #ifdef SK_BUILD_FOR_MAC 21 #define SK_FONT_FILE_PREFIX "/Library/Fonts/" 22 #else 23 #define SK_FONT_FILE_PREFIX "/skimages/" 24 #endif 25 26 bool find_name_and_attributes(SkStream* stream, SkString* name, 27 SkTypeface::Style* style, bool* isFixedWidth); 28 29 static void GetFullPathForSysFonts(SkString* full, const char name[]) { 30 full->set(SK_FONT_FILE_PREFIX); 31 full->append(name); 32 } 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 void construct(const char name[], FamilyRec* family) { 48 fName = strdup(name); 49 fFamily = family; // we don't own this, so just record the referene 50 } 51 52 void destruct() { 53 free((char*)fName); 54 // we don't own family, so just ignore our reference 55 } 56 }; 57 58 // we use atomic_inc to grow this for each typeface we create 59 static int32_t gUniqueFontID; 60 61 // this is the mutex that protects these globals 62 SK_DECLARE_STATIC_MUTEX(gFamilyMutex); 63 static FamilyRec* gFamilyHead; 64 static SkTDArray<NameFamilyPair> gNameList; 65 66 struct FamilyRec { 67 FamilyRec* fNext; 68 SkTypeface* fFaces[4]; 69 70 FamilyRec() 71 { 72 fNext = gFamilyHead; 73 memset(fFaces, 0, sizeof(fFaces)); 74 gFamilyHead = this; 75 } 76 }; 77 78 static SkTypeface* find_best_face(const FamilyRec* family, 79 SkTypeface::Style style) { 80 SkTypeface* const* faces = family->fFaces; 81 82 if (faces[style] != NULL) { // exact match 83 return faces[style]; 84 } 85 // look for a matching bold 86 style = (SkTypeface::Style)(style ^ SkTypeface::kItalic); 87 if (faces[style] != NULL) { 88 return faces[style]; 89 } 90 // look for the plain 91 if (faces[SkTypeface::kNormal] != NULL) { 92 return faces[SkTypeface::kNormal]; 93 } 94 // look for anything 95 for (int i = 0; i < 4; i++) { 96 if (faces[i] != NULL) { 97 return faces[i]; 98 } 99 } 100 // should never get here, since the faces list should not be empty 101 SkDEBUGFAIL("faces list is empty"); 102 return NULL; 103 } 104 105 static FamilyRec* find_family(const SkTypeface* member) { 106 FamilyRec* curr = gFamilyHead; 107 while (curr != NULL) { 108 for (int i = 0; i < 4; i++) { 109 if (curr->fFaces[i] == member) { 110 return curr; 111 } 112 } 113 curr = curr->fNext; 114 } 115 return NULL; 116 } 117 118 /* Returns the matching typeface, or NULL. If a typeface is found, its refcnt 119 is not modified. 120 */ 121 static SkTypeface* find_from_uniqueID(uint32_t uniqueID) { 122 FamilyRec* curr = gFamilyHead; 123 while (curr != NULL) { 124 for (int i = 0; i < 4; i++) { 125 SkTypeface* face = curr->fFaces[i]; 126 if (face != NULL && face->uniqueID() == uniqueID) { 127 return face; 128 } 129 } 130 curr = curr->fNext; 131 } 132 return NULL; 133 } 134 135 /* Remove reference to this face from its family. If the resulting family 136 is empty (has no faces), return that family, otherwise return NULL 137 */ 138 static FamilyRec* remove_from_family(const SkTypeface* face) { 139 FamilyRec* family = find_family(face); 140 SkASSERT(family->fFaces[face->style()] == face); 141 family->fFaces[face->style()] = NULL; 142 143 for (int i = 0; i < 4; i++) { 144 if (family->fFaces[i] != NULL) { // family is non-empty 145 return NULL; 146 } 147 } 148 return family; // return the empty family 149 } 150 151 // maybe we should make FamilyRec be doubly-linked 152 static void detach_and_delete_family(FamilyRec* family) { 153 FamilyRec* curr = gFamilyHead; 154 FamilyRec* prev = NULL; 155 156 while (curr != NULL) { 157 FamilyRec* next = curr->fNext; 158 if (curr == family) { 159 if (prev == NULL) { 160 gFamilyHead = next; 161 } else { 162 prev->fNext = next; 163 } 164 SkDELETE(family); 165 return; 166 } 167 prev = curr; 168 curr = next; 169 } 170 SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete"); 171 } 172 173 static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) { 174 NameFamilyPair* list = gNameList.begin(); 175 int count = gNameList.count(); 176 177 int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); 178 179 if (index >= 0) { 180 return find_best_face(list[index].fFamily, style); 181 } 182 return NULL; 183 } 184 185 static SkTypeface* find_typeface(const SkTypeface* familyMember, 186 SkTypeface::Style style) { 187 const FamilyRec* family = find_family(familyMember); 188 return family ? find_best_face(family, style) : NULL; 189 } 190 191 static void add_name(const char name[], FamilyRec* family) { 192 SkAutoAsciiToLC tolc(name); 193 name = tolc.lc(); 194 195 NameFamilyPair* list = gNameList.begin(); 196 int count = gNameList.count(); 197 198 int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); 199 200 if (index < 0) { 201 list = gNameList.insert(~index); 202 list->construct(name, family); 203 } 204 } 205 206 static void remove_from_names(FamilyRec* emptyFamily) 207 { 208 #ifdef SK_DEBUG 209 for (int i = 0; i < 4; i++) { 210 SkASSERT(emptyFamily->fFaces[i] == NULL); 211 } 212 #endif 213 214 SkTDArray<NameFamilyPair>& list = gNameList; 215 216 // must go backwards when removing 217 for (int i = list.count() - 1; i >= 0; --i) { 218 NameFamilyPair* pair = &list[i]; 219 if (pair->fFamily == emptyFamily) { 220 pair->destruct(); 221 list.remove(i); 222 } 223 } 224 } 225 226 /////////////////////////////////////////////////////////////////////////////// 227 228 class FamilyTypeface : public SkTypeface { 229 public: 230 FamilyTypeface(Style style, bool sysFont, SkTypeface* familyMember) 231 : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1) { 232 fIsSysFont = sysFont; 233 234 SkAutoMutexAcquire ac(gFamilyMutex); 235 236 FamilyRec* rec = NULL; 237 if (familyMember) { 238 rec = find_family(familyMember); 239 SkASSERT(rec); 240 } else { 241 rec = SkNEW(FamilyRec); 242 } 243 rec->fFaces[style] = this; 244 } 245 246 virtual ~FamilyTypeface() { 247 SkAutoMutexAcquire ac(gFamilyMutex); 248 249 // remove us from our family. If the family is now empty, we return 250 // that and then remove that family from the name list 251 FamilyRec* family = remove_from_family(this); 252 if (NULL != family) { 253 remove_from_names(family); 254 detach_and_delete_family(family); 255 } 256 } 257 258 bool isSysFont() const { return fIsSysFont; } 259 260 virtual SkStream* openStream() = 0; 261 virtual const char* getUniqueString() const = 0; 262 virtual const char* getFilePath() const = 0; 263 264 private: 265 bool fIsSysFont; 266 267 typedef SkTypeface INHERITED; 268 }; 269 270 /////////////////////////////////////////////////////////////////////////////// 271 272 class StreamTypeface : public FamilyTypeface { 273 public: 274 StreamTypeface(Style style, bool sysFont, SkTypeface* familyMember, 275 SkStream* stream) 276 : INHERITED(style, sysFont, familyMember) { 277 SkASSERT(stream); 278 stream->ref(); 279 fStream = stream; 280 } 281 virtual ~StreamTypeface() { 282 fStream->unref(); 283 } 284 285 // overrides 286 virtual SkStream* openStream() { 287 // we just ref our existing stream, since the caller will call unref() 288 // when they are through 289 fStream->ref(); 290 return fStream; 291 } 292 virtual const char* getUniqueString() const { return NULL; } 293 virtual const char* getFilePath() const { return NULL; } 294 295 private: 296 SkStream* fStream; 297 298 typedef FamilyTypeface INHERITED; 299 }; 300 301 class FileTypeface : public FamilyTypeface { 302 public: 303 FileTypeface(Style style, bool sysFont, SkTypeface* familyMember, 304 const char path[]) 305 : INHERITED(style, sysFont, familyMember) { 306 SkString fullpath; 307 308 if (sysFont) { 309 GetFullPathForSysFonts(&fullpath, path); 310 path = fullpath.c_str(); 311 } 312 fPath.set(path); 313 } 314 315 // overrides 316 virtual SkStream* openStream() { 317 SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str())); 318 319 // check for failure 320 if (stream->getLength() <= 0) { 321 SkDELETE(stream); 322 // maybe MMAP isn't supported. try FILE 323 stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str())); 324 if (stream->getLength() <= 0) { 325 SkDELETE(stream); 326 stream = NULL; 327 } 328 } 329 return stream; 330 } 331 virtual const char* getUniqueString() const { 332 const char* str = strrchr(fPath.c_str(), '/'); 333 if (str) { 334 str += 1; // skip the '/' 335 } 336 return str; 337 } 338 virtual const char* getFilePath() const { 339 return fPath.c_str(); 340 } 341 342 private: 343 SkString fPath; 344 345 typedef FamilyTypeface INHERITED; 346 }; 347 348 /////////////////////////////////////////////////////////////////////////////// 349 /////////////////////////////////////////////////////////////////////////////// 350 351 static bool get_name_and_style(const char path[], SkString* name, 352 SkTypeface::Style* style, bool isExpected) { 353 SkString fullpath; 354 GetFullPathForSysFonts(&fullpath, path); 355 356 SkMMAPStream stream(fullpath.c_str()); 357 if (stream.getLength() > 0) { 358 return find_name_and_attributes(&stream, name, style, NULL); 359 } 360 else { 361 SkFILEStream stream(fullpath.c_str()); 362 if (stream.getLength() > 0) { 363 return find_name_and_attributes(&stream, name, style, NULL); 364 } 365 } 366 367 if (isExpected) { 368 SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str()); 369 } 370 return false; 371 } 372 373 // used to record our notion of the pre-existing fonts 374 struct FontInitRec { 375 const char* fFileName; 376 const char* const* fNames; // null-terminated list 377 }; 378 379 static const char* gSansNames[] = { 380 "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL 381 }; 382 383 static const char* gSerifNames[] = { 384 "serif", "times", "times new roman", "palatino", "georgia", "baskerville", 385 "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL 386 }; 387 388 static const char* gMonoNames[] = { 389 "monospace", "courier", "courier new", "monaco", NULL 390 }; 391 392 // deliberately empty, but we use the address to identify fallback fonts 393 static const char* gFBNames[] = { NULL }; 394 395 /* Fonts must be grouped by family, with the first font in a family having the 396 list of names (even if that list is empty), and the following members having 397 null for the list. The names list must be NULL-terminated 398 */ 399 static const FontInitRec gSystemFonts[] = { 400 { "Arial.ttf", gSansNames }, 401 { "Times.ttf", gSerifNames }, 402 { "samplefont.ttf", gSansNames }, 403 }; 404 405 #define DEFAULT_NAMES gSansNames 406 407 // these globals are assigned (once) by load_system_fonts() 408 static FamilyRec* gDefaultFamily; 409 static SkTypeface* gDefaultNormal; 410 411 /* This is sized conservatively, assuming that it will never be a size issue. 412 It will be initialized in load_system_fonts(), and will be filled with the 413 fontIDs that can be used for fallback consideration, in sorted order (sorted 414 meaning element[0] should be used first, then element[1], etc. When we hit 415 a fontID==0 in the array, the list is done, hence our allocation size is 416 +1 the total number of possible system fonts. Also see NextLogicalFont(). 417 */ 418 static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1]; 419 420 /* Called once (ensured by the sentinel check at the beginning of our body). 421 Initializes all the globals, and register the system fonts. 422 */ 423 static void load_system_fonts() { 424 // check if we've already be called 425 if (NULL != gDefaultNormal) { 426 return; 427 } 428 429 const FontInitRec* rec = gSystemFonts; 430 SkTypeface* firstInFamily = NULL; 431 int fallbackCount = 0; 432 433 for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { 434 // if we're the first in a new family, clear firstInFamily 435 if (rec[i].fNames != NULL) { 436 firstInFamily = NULL; 437 } 438 439 SkString name; 440 SkTypeface::Style style; 441 442 // we expect all the fonts, except the "fallback" fonts 443 bool isExpected = (rec[i].fNames != gFBNames); 444 if (!get_name_and_style(rec[i].fFileName, &name, &style, isExpected)) { 445 continue; 446 } 447 448 SkTypeface* tf = SkNEW_ARGS(FileTypeface, 449 (style, 450 true, // system-font (cannot delete) 451 firstInFamily, // what family to join 452 rec[i].fFileName) // filename 453 ); 454 455 if (rec[i].fNames != NULL) { 456 // see if this is one of our fallback fonts 457 if (rec[i].fNames == gFBNames) { 458 // SkDebugf("---- adding %s as fallback[%d] fontID %d\n", 459 // rec[i].fFileName, fallbackCount, tf->uniqueID()); 460 gFallbackFonts[fallbackCount++] = tf->uniqueID(); 461 } 462 463 firstInFamily = tf; 464 FamilyRec* family = find_family(tf); 465 const char* const* names = rec[i].fNames; 466 467 // record the default family if this is it 468 if (names == DEFAULT_NAMES) { 469 gDefaultFamily = family; 470 } 471 // add the names to map to this family 472 while (*names) { 473 add_name(*names, family); 474 names += 1; 475 } 476 } 477 } 478 479 // do this after all fonts are loaded. This is our default font, and it 480 // acts as a sentinel so we only execute load_system_fonts() once 481 gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal); 482 // now terminate our fallback list with the sentinel value 483 gFallbackFonts[fallbackCount] = 0; 484 } 485 486 /////////////////////////////////////////////////////////////////////////////// 487 488 void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { 489 const char* name = ((FamilyTypeface*)face)->getUniqueString(); 490 491 stream->write8((uint8_t)face->style()); 492 493 if (NULL == name || 0 == *name) { 494 stream->writePackedUInt(0); 495 // SkDebugf("--- fonthost serialize null\n"); 496 } else { 497 uint32_t len = strlen(name); 498 stream->writePackedUInt(len); 499 stream->write(name, len); 500 // SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style()); 501 } 502 } 503 504 SkTypeface* SkFontHost::Deserialize(SkStream* stream) { 505 load_system_fonts(); 506 507 int style = stream->readU8(); 508 509 int len = stream->readPackedUInt(); 510 if (len > 0) { 511 SkString str; 512 str.resize(len); 513 stream->read(str.writable_str(), len); 514 515 const FontInitRec* rec = gSystemFonts; 516 for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { 517 if (strcmp(rec[i].fFileName, str.c_str()) == 0) { 518 // backup until we hit the fNames 519 for (int j = i; j >= 0; --j) { 520 if (rec[j].fNames != NULL) { 521 return SkFontHost::CreateTypeface(NULL, 522 rec[j].fNames[0], NULL, 0, (SkTypeface::Style)style); 523 } 524 } 525 } 526 } 527 } 528 return NULL; 529 } 530 531 /////////////////////////////////////////////////////////////////////////////// 532 533 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, 534 const char familyName[], 535 const void* data, size_t bytelength, 536 SkTypeface::Style style) { 537 load_system_fonts(); 538 539 SkAutoMutexAcquire ac(gFamilyMutex); 540 541 // clip to legal style bits 542 style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic); 543 544 SkTypeface* tf = NULL; 545 546 if (NULL != familyFace) { 547 tf = find_typeface(familyFace, style); 548 } else if (NULL != familyName) { 549 // SkDebugf("======= familyName <%s>\n", familyName); 550 tf = find_typeface(familyName, style); 551 } 552 553 if (NULL == tf) { 554 tf = find_best_face(gDefaultFamily, style); 555 } 556 557 // we ref(), since the symantic is to return a new instance 558 tf->ref(); 559 return tf; 560 } 561 562 SkStream* SkFontHost::OpenStream(uint32_t fontID) { 563 SkAutoMutexAcquire ac(gFamilyMutex); 564 565 FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID); 566 SkStream* stream = tf ? tf->openStream() : NULL; 567 568 if (stream && stream->getLength() == 0) { 569 stream->unref(); 570 stream = NULL; 571 } 572 return stream; 573 } 574 575 #if 0 576 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( 577 uint32_t fontID, 578 SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) { 579 SkDEBUGFAIL("SkFontHost::GetAdvancedTypefaceMetrics unimplemented"); 580 return NULL; 581 } 582 #endif 583 584 size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length, 585 int32_t* index) { 586 SkAutoMutexAcquire ac(gFamilyMutex); 587 588 FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID); 589 const char* src = tf ? tf->getFilePath() : NULL; 590 591 if (src) { 592 size_t size = strlen(src); 593 if (path) { 594 memcpy(path, src, SkMin32(size, length)); 595 } 596 if (index) { 597 *index = 0; // we don't have collections (yet) 598 } 599 return size; 600 } else { 601 return 0; 602 } 603 } 604 605 SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) { 606 load_system_fonts(); 607 608 /* First see if fontID is already one of our fallbacks. If so, return 609 its successor. If fontID is not in our list, then return the first one 610 in our list. Note: list is zero-terminated, and returning zero means 611 we have no more fonts to use for fallbacks. 612 */ 613 const uint32_t* list = gFallbackFonts; 614 for (int i = 0; list[i] != 0; i++) { 615 if (list[i] == currFontID) { 616 return list[i+1]; 617 } 618 } 619 return list[0]; 620 } 621 622 /////////////////////////////////////////////////////////////////////////////// 623 624 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { 625 if (NULL == stream || stream->getLength() <= 0) { 626 return NULL; 627 } 628 629 SkTypeface::Style style; 630 if (find_name_and_attributes(stream, NULL, &style, NULL)) { 631 return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream)); 632 } else { 633 return NULL; 634 } 635 } 636 637 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { 638 SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path)); 639 SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream); 640 // since we created the stream, we let go of our ref() here 641 stream->unref(); 642 return face; 643 } 644 645