OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 The Android Open Source Project | 2 * Copyright 2011 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkFontConfigParser_android.h" | 8 #include "SkFontMgr_android_parser.h" |
9 #include "SkFontMgr_android.h" | |
10 #include "SkStream.h" | 9 #include "SkStream.h" |
11 #include "SkTDArray.h" | 10 #include "SkTDArray.h" |
12 #include "SkTSearch.h" | 11 #include "SkTSearch.h" |
13 #include "SkTypeface.h" | 12 #include "SkTypeface.h" |
14 | 13 |
15 #include <expat.h> | 14 #include <expat.h> |
16 #include <dirent.h> | 15 #include <dirent.h> |
17 | 16 |
18 #include <stdlib.h> | 17 #include <stdlib.h> |
19 | 18 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 SkTDArray<const TagHandler*> fHandler; // The stack of current tag handle
rs. | 108 SkTDArray<const TagHandler*> fHandler; // The stack of current tag handle
rs. |
110 }; | 109 }; |
111 | 110 |
112 static bool memeq(const char* s1, const char* s2, size_t n1, size_t n2) { | 111 static bool memeq(const char* s1, const char* s2, size_t n1, size_t n2) { |
113 return n1 == n2 && 0 == memcmp(s1, s2, n1); | 112 return n1 == n2 && 0 == memcmp(s1, s2, n1); |
114 } | 113 } |
115 #define MEMEQ(c, s, n) memeq(c, s, sizeof(c) - 1, n) | 114 #define MEMEQ(c, s, n) memeq(c, s, sizeof(c) - 1, n) |
116 | 115 |
117 #define ATTS_NON_NULL(a, i) (a[i] != NULL && a[i+1] != NULL) | 116 #define ATTS_NON_NULL(a, i) (a[i] != NULL && a[i+1] != NULL) |
118 | 117 |
119 #define SK_FONTCONFIGPARSER_PREFIX "[SkFontConfigParser] " | 118 #define SK_FONTMGR_ANDROID_PARSER_PREFIX "[SkFontMgr Android Parser] " |
120 | 119 |
121 #define SK_FONTCONFIGPARSER_WARNING(message, ...) SkDebugf( \ | 120 #define SK_FONTCONFIGPARSER_WARNING(message, ...) SkDebugf( \ |
122 SK_FONTCONFIGPARSER_PREFIX "%s:%d:%d: warning: " message "\n", \ | 121 SK_FONTMGR_ANDROID_PARSER_PREFIX "%s:%d:%d: warning: " message "\n", \ |
123 self->fFilename, \ | 122 self->fFilename, \ |
124 XML_GetCurrentLineNumber(self->fParser), \ | 123 XML_GetCurrentLineNumber(self->fParser), \ |
125 XML_GetCurrentColumnNumber(self->fParser), \ | 124 XML_GetCurrentColumnNumber(self->fParser), \ |
126 ##__VA_ARGS__); | 125 ##__VA_ARGS__); |
127 | 126 |
128 static bool is_whitespace(char c) { | 127 static bool is_whitespace(char c) { |
129 return c == ' ' || c == '\n'|| c == '\r' || c == '\t'; | 128 return c == ' ' || c == '\n'|| c == '\r' || c == '\t'; |
130 } | 129 } |
131 | 130 |
132 static void trim_string(SkString* s) { | 131 static void trim_string(SkString* s) { |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 * families array. Returns the version of the file, negative if the file does no
t exist. | 584 * families array. Returns the version of the file, negative if the file does no
t exist. |
586 */ | 585 */ |
587 static int parse_config_file(const char* filename, SkTDArray<FontFamily*>& famil
ies, | 586 static int parse_config_file(const char* filename, SkTDArray<FontFamily*>& famil
ies, |
588 const SkString& basePath, bool isFallback) | 587 const SkString& basePath, bool isFallback) |
589 { | 588 { |
590 SkFILEStream file(filename); | 589 SkFILEStream file(filename); |
591 | 590 |
592 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac
k_fonts.xml) | 591 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac
k_fonts.xml) |
593 // are optional - failure here is okay because one of these optional files m
ay not exist. | 592 // are optional - failure here is okay because one of these optional files m
ay not exist. |
594 if (!file.isValid()) { | 593 if (!file.isValid()) { |
595 SkDebugf(SK_FONTCONFIGPARSER_PREFIX "'%s' could not be opened\n", filena
me); | 594 SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' could not be opened\n",
filename); |
596 return -1; | 595 return -1; |
597 } | 596 } |
598 | 597 |
599 SkAutoTCallVProc<remove_ptr<XML_Parser>::type, XML_ParserFree> parser( | 598 SkAutoTCallVProc<remove_ptr<XML_Parser>::type, XML_ParserFree> parser( |
600 XML_ParserCreate_MM(NULL, &sk_XML_alloc, NULL)); | 599 XML_ParserCreate_MM(NULL, &sk_XML_alloc, NULL)); |
601 if (!parser) { | 600 if (!parser) { |
602 SkDebugf(SK_FONTCONFIGPARSER_PREFIX "could not create XML parser\n"); | 601 SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "could not create XML parser\n
"); |
603 return -1; | 602 return -1; |
604 } | 603 } |
605 | 604 |
606 FamilyData self(parser, families, basePath, isFallback, filename, &topLevelH
andler); | 605 FamilyData self(parser, families, basePath, isFallback, filename, &topLevelH
andler); |
607 XML_SetUserData(parser, &self); | 606 XML_SetUserData(parser, &self); |
608 | 607 |
609 // Disable entity processing, to inhibit internal entity expansion. See expa
t CVE-2013-0340 | 608 // Disable entity processing, to inhibit internal entity expansion. See expa
t CVE-2013-0340 |
610 XML_SetEntityDeclHandler(parser, xml_entity_decl_handler); | 609 XML_SetEntityDeclHandler(parser, xml_entity_decl_handler); |
611 | 610 |
612 // Start parsing oldschool; switch these in flight if we detect a newer vers
ion of the file. | 611 // Start parsing oldschool; switch these in flight if we detect a newer vers
ion of the file. |
613 XML_SetElementHandler(parser, start_element_handler, end_element_handler); | 612 XML_SetElementHandler(parser, start_element_handler, end_element_handler); |
614 | 613 |
615 // One would assume it would be faster to have a buffer on the stack and cal
l XML_Parse. | 614 // One would assume it would be faster to have a buffer on the stack and cal
l XML_Parse. |
616 // But XML_Parse will call XML_GetBuffer anyway and memmove the passed buffe
r into it. | 615 // But XML_Parse will call XML_GetBuffer anyway and memmove the passed buffe
r into it. |
617 // (Unless XML_CONTEXT_BYTES is undefined, but all users define it.) | 616 // (Unless XML_CONTEXT_BYTES is undefined, but all users define it.) |
618 // In debug, buffer a small odd number of bytes to detect slicing in XML_Cha
racterDataHandler. | 617 // In debug, buffer a small odd number of bytes to detect slicing in XML_Cha
racterDataHandler. |
619 static const int bufferSize = 512 SkDEBUGCODE( - 507); | 618 static const int bufferSize = 512 SkDEBUGCODE( - 507); |
620 bool done = false; | 619 bool done = false; |
621 while (!done) { | 620 while (!done) { |
622 void* buffer = XML_GetBuffer(parser, bufferSize); | 621 void* buffer = XML_GetBuffer(parser, bufferSize); |
623 if (!buffer) { | 622 if (!buffer) { |
624 SkDebugf(SK_FONTCONFIGPARSER_PREFIX "could not buffer enough to cont
inue\n"); | 623 SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "could not buffer enough t
o continue\n"); |
625 return -1; | 624 return -1; |
626 } | 625 } |
627 size_t len = file.read(buffer, bufferSize); | 626 size_t len = file.read(buffer, bufferSize); |
628 done = file.isAtEnd(); | 627 done = file.isAtEnd(); |
629 XML_Status status = XML_ParseBuffer(parser, len, done); | 628 XML_Status status = XML_ParseBuffer(parser, len, done); |
630 if (XML_STATUS_ERROR == status) { | 629 if (XML_STATUS_ERROR == status) { |
631 XML_Error error = XML_GetErrorCode(parser); | 630 XML_Error error = XML_GetErrorCode(parser); |
632 int line = XML_GetCurrentLineNumber(parser); | 631 int line = XML_GetCurrentLineNumber(parser); |
633 int column = XML_GetCurrentColumnNumber(parser); | 632 int column = XML_GetCurrentColumnNumber(parser); |
634 const XML_LChar* errorString = XML_ErrorString(error); | 633 const XML_LChar* errorString = XML_ErrorString(error); |
635 SkDebugf(SK_FONTCONFIGPARSER_PREFIX "%s:%d:%d error %d: %s.\n", | 634 SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "%s:%d:%d error %d: %s.\n"
, |
636 filename, line, column, error, errorString); | 635 filename, line, column, error, errorString); |
637 return -1; | 636 return -1; |
638 } | 637 } |
639 } | 638 } |
640 return self.fVersion; | 639 return self.fVersion; |
641 } | 640 } |
642 | 641 |
643 /** Returns the version of the system font file actually found, negative if none
. */ | 642 /** Returns the version of the system font file actually found, negative if none
. */ |
644 static int append_system_font_families(SkTDArray<FontFamily*>& fontFamilies, | 643 static int append_system_font_families(SkTDArray<FontFamily*>& fontFamilies, |
645 const SkString& basePath) | 644 const SkString& basePath) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 } | 740 } |
742 } else { | 741 } else { |
743 // Add the font into the fallback list in the specified order. Set | 742 // Add the font into the fallback list in the specified order. Set |
744 // currentOrder for correct placement of other fonts in the vendor l
ist. | 743 // currentOrder for correct placement of other fonts in the vendor l
ist. |
745 *fallbackFonts.insert(order) = family; | 744 *fallbackFonts.insert(order) = family; |
746 currentOrder = order + 1; | 745 currentOrder = order + 1; |
747 } | 746 } |
748 } | 747 } |
749 } | 748 } |
750 | 749 |
751 void SkFontConfigParser::GetSystemFontFamilies(SkTDArray<FontFamily*>& fontFamil
ies) { | 750 void SkFontMgr_Android_Parser::GetSystemFontFamilies(SkTDArray<FontFamily*>& fon
tFamilies) { |
752 // Version 21 of the system font configuration does not need any fallback co
nfiguration files. | 751 // Version 21 of the system font configuration does not need any fallback co
nfiguration files. |
753 SkString basePath(getenv("ANDROID_ROOT")); | 752 SkString basePath(getenv("ANDROID_ROOT")); |
754 basePath.append(SK_FONT_FILE_PREFIX, sizeof(SK_FONT_FILE_PREFIX) - 1); | 753 basePath.append(SK_FONT_FILE_PREFIX, sizeof(SK_FONT_FILE_PREFIX) - 1); |
755 | 754 |
756 if (append_system_font_families(fontFamilies, basePath) >= 21) { | 755 if (append_system_font_families(fontFamilies, basePath) >= 21) { |
757 return; | 756 return; |
758 } | 757 } |
759 | 758 |
760 // Append all the fallback fonts to system fonts | 759 // Append all the fallback fonts to system fonts |
761 SkTDArray<FontFamily*> fallbackFonts; | 760 SkTDArray<FontFamily*> fallbackFonts; |
762 append_system_fallback_font_families(fallbackFonts, basePath); | 761 append_system_fallback_font_families(fallbackFonts, basePath); |
763 mixin_vendor_fallback_font_families(fallbackFonts, basePath); | 762 mixin_vendor_fallback_font_families(fallbackFonts, basePath); |
764 fontFamilies.append(fallbackFonts.count(), fallbackFonts.begin()); | 763 fontFamilies.append(fallbackFonts.count(), fallbackFonts.begin()); |
765 } | 764 } |
766 | 765 |
767 void SkFontConfigParser::GetCustomFontFamilies(SkTDArray<FontFamily*>& fontFamil
ies, | 766 void SkFontMgr_Android_Parser::GetCustomFontFamilies(SkTDArray<FontFamily*>& fon
tFamilies, |
768 const SkString& basePath, | 767 const SkString& basePath, |
769 const char* fontsXml, | 768 const char* fontsXml, |
770 const char* fallbackFontsXml, | 769 const char* fallbackFontsXm
l, |
771 const char* langFallbackFontsDir) | 770 const char* langFallbackFon
tsDir) |
772 { | 771 { |
773 if (fontsXml) { | 772 if (fontsXml) { |
774 parse_config_file(fontsXml, fontFamilies, basePath, false); | 773 parse_config_file(fontsXml, fontFamilies, basePath, false); |
775 } | 774 } |
776 if (fallbackFontsXml) { | 775 if (fallbackFontsXml) { |
777 parse_config_file(fallbackFontsXml, fontFamilies, basePath, true); | 776 parse_config_file(fallbackFontsXml, fontFamilies, basePath, true); |
778 } | 777 } |
779 if (langFallbackFontsDir) { | 778 if (langFallbackFontsDir) { |
780 append_fallback_font_families_for_locale(fontFamilies, | 779 append_fallback_font_families_for_locale(fontFamilies, |
781 langFallbackFontsDir, | 780 langFallbackFontsDir, |
782 basePath); | 781 basePath); |
783 } | 782 } |
784 } | 783 } |
785 | 784 |
786 SkLanguage SkLanguage::getParent() const { | 785 SkLanguage SkLanguage::getParent() const { |
787 SkASSERT(!fTag.isEmpty()); | 786 SkASSERT(!fTag.isEmpty()); |
788 const char* tag = fTag.c_str(); | 787 const char* tag = fTag.c_str(); |
789 | 788 |
790 // strip off the rightmost "-.*" | 789 // strip off the rightmost "-.*" |
791 const char* parentTagEnd = strrchr(tag, '-'); | 790 const char* parentTagEnd = strrchr(tag, '-'); |
792 if (parentTagEnd == NULL) { | 791 if (parentTagEnd == NULL) { |
793 return SkLanguage(); | 792 return SkLanguage(); |
794 } | 793 } |
795 size_t parentTagLen = parentTagEnd - tag; | 794 size_t parentTagLen = parentTagEnd - tag; |
796 return SkLanguage(tag, parentTagLen); | 795 return SkLanguage(tag, parentTagLen); |
797 } | 796 } |
OLD | NEW |