737 static void initSystemFontsLocked() {
738
739 if (gDefaultNormal) {
740 return;
741 }
742
743 SkASSERT(gUniqueFontID == 0);
744
745 loadFontInfoLocked();
746
747 SkTypeface* firstInFamily = NULL;
748 for (int i = 0; i < gSystemFonts.count(); i++) {
749
750 const char* const* names = gSystemFonts[i].fNames;
751 if (names != NULL) {
752 firstInFamily = NULL;
753 }
754
755 bool isFixedWidth;
756 SkString name;
757 SkTypeface::Style style;
758
759
760 bool isExpected = (names != gFBNames);
761 if (!getNameAndStyle(gSystemFonts[i].fFileName, &name, &style,
762 &isFixedWidth, isExpected)) {
763
764
765
766 sk_atomic_inc(&gUniqueFontID);
767 continue;
768 }
769
770 SkString fullpath;
771 getFullPathForSysFonts(&fullpath, gSystemFonts[i].fFileName);
772
773 SkTypeface* tf = SkNEW_ARGS(FileTypeface, (style,
774 true,
775 fullpath.c_str(),
776 isFixedWidth));
777 addTypefaceLocked(tf, firstInFamily);
778
779 SkDEBUGF(("---- SkTypeface[%d] %s fontID %d\n",
780 i, gSystemFonts[i].fFileName, tf->uniqueID()));
781
782 if (names != NULL) {
783
784 if (names == gFBNames) {
785
786 FallbackFontRec fallbackRec;
787 fallbackRec.fFontID = tf->uniqueID();
788 fallbackRec.fVariant = gSystemFonts[i].fVariant;
789 addFallbackFontLocked(fallbackRec, gSystemFonts[i].fLanguage);
790 }
791
792 firstInFamily = tf;
793 FamilyRec* family = findFamilyLocked(tf);
794
795
796 if (names == gDefaultNames) {
797 gDefaultFamily = family;
798 }
799
800 while (*names) {
801 addNameLocked(*names, family);
802 names += 1;
803 }
804 }
805 }
806 finaliseFallbackFontListsLocked();
807
808
809
810 gDefaultNormal = findBestFaceLocked(gDefaultFamily, SkTypeface::kNormal);
811
812 SkDEBUGCODE(dumpGlobalsLocked());
813 }
53 static bool getNameAndStyle(const char path[], SkString* name,
54 SkTypeface::Style* style,
55 bool* isFixedWidth, bool isExpected) {
56 SkString fullpath;
57 getFullPathForSysFonts(&fullpath, path);
58
59 SkMMAPStream stream(fullpath.c_str());
60 if (stream.getLength() > 0) {
61 return find_name_and_attributes(&stream, name, style, isFixedWidth);
62 }
63 else {
64 SkFILEStream stream(fullpath.c_str());
65 if (stream.getLength() > 0) {
66 return find_name_and_attributes(&stream, name, style, isFixedWidth);
67 }
68 }
69
70 if (isExpected) {
71 SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str());
72 }
73 return false;
74 }
1726 bool find_name_and_attributes(SkStream* stream, SkString* name,
1727 SkTypeface::Style* style, bool* isFixedWidth) {
1728 FT_Library library;
1729 if (FT_Init_FreeType(&library)) {
1730 return false;
1731 }
1732
1733 FT_Open_Args args;
1734 memset(&args, 0, sizeof(args));
1735
1736 const void* memoryBase = stream->getMemoryBase();
1737 FT_StreamRec streamRec;
1738
1739 if (NULL != memoryBase) {
1740 args.flags = FT_OPEN_MEMORY;
1741 args.memory_base = (const FT_Byte*)memoryBase;
1742 args.memory_size = stream->getLength();
1743 } else {
1744 memset(&streamRec, 0, sizeof(streamRec));
1745 streamRec.size = stream->read(NULL, 0);
1746 streamRec.descriptor.pointer = stream;
1747 streamRec.read = sk_stream_read;
1748 streamRec.close = sk_stream_close;
1749
1750 args.flags = FT_OPEN_STREAM;
1751 args.stream = &streamRec;
1752 }
1753
1754 FT_Face face;
1755 if (FT_Open_Face(library, &args, 0, &face)) {
1756 FT_Done_FreeType(library);
1757 return false;
1758 }
1759
1760 int tempStyle = SkTypeface::kNormal;
1761 if (face->style_flags & FT_STYLE_FLAG_BOLD) {
1762 tempStyle |= SkTypeface::kBold;
1763 }
1764 if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
1765 tempStyle |= SkTypeface::kItalic;
1766 }
1767
1768 if (name) {
1769 name->set(face->family_name);
1770 }
1771 if (style) {
1772 *style = (SkTypeface::Style) tempStyle;
1773 }
1774 if (isFixedWidth) {
1775 *isFixedWidth = FT_IS_FIXED_WIDTH(face);
1776 }
1777
1778 FT_Done_Face(face);
1779 FT_Done_FreeType(library);
1780 return true;
1781 }