OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 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 "SkFontHost.h" | 8 #include "SkFontHost.h" |
9 #include "SkFontHost_FreeType_common.h" | 9 #include "SkFontHost_FreeType_common.h" |
10 #include "SkFontDescriptor.h" | 10 #include "SkFontDescriptor.h" |
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 | 871 |
872 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { | 872 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { |
873 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); | 873 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); |
874 return stream.get() ? SkFontHost::CreateTypefaceFromStream(stream) : NULL; | 874 return stream.get() ? SkFontHost::CreateTypefaceFromStream(stream) : NULL; |
875 } | 875 } |
876 | 876 |
877 /////////////////////////////////////////////////////////////////////////////// | 877 /////////////////////////////////////////////////////////////////////////////// |
878 // Function from SkTypeface_android.h | 878 // Function from SkTypeface_android.h |
879 /////////////////////////////////////////////////////////////////////////////// | 879 /////////////////////////////////////////////////////////////////////////////// |
880 | 880 |
881 struct FBScriptInfo { | |
882 const FallbackScripts fScript; | |
883 const char* fScriptID; | |
884 const SkTypeface::Style fStyle; | |
885 const SkUnichar fChar; // representative character for that script type | |
886 SkFontID fFontID; | |
887 }; | |
888 | |
889 #define SK_DEFINE_SCRIPT_ENTRY(script, style, unichar) \ | |
890 { script, #script, style, unichar, 0 } | |
891 | |
892 static FBScriptInfo gFBScriptInfo[] = { | |
893 SK_DEFINE_SCRIPT_ENTRY(kArabic_FallbackScript, SkTypeface::kNormal, 0
x0627), | |
894 SK_DEFINE_SCRIPT_ENTRY(kArmenian_FallbackScript, SkTypeface::kNormal, 0
x0531), | |
895 SK_DEFINE_SCRIPT_ENTRY(kBengali_FallbackScript, SkTypeface::kNormal, 0
x0981), | |
896 SK_DEFINE_SCRIPT_ENTRY(kDevanagari_FallbackScript, SkTypeface::kNormal, 0
x0901), | |
897 SK_DEFINE_SCRIPT_ENTRY(kEthiopic_FallbackScript, SkTypeface::kNormal, 0
x1200), | |
898 SK_DEFINE_SCRIPT_ENTRY(kGeorgian_FallbackScript, SkTypeface::kNormal, 0
x10A0), | |
899 SK_DEFINE_SCRIPT_ENTRY(kHebrewRegular_FallbackScript, SkTypeface::kNormal, 0
x0591), | |
900 SK_DEFINE_SCRIPT_ENTRY(kHebrewBold_FallbackScript, SkTypeface::kBold, 0
x0591), | |
901 SK_DEFINE_SCRIPT_ENTRY(kKannada_FallbackScript, SkTypeface::kNormal, 0
x0C90), | |
902 SK_DEFINE_SCRIPT_ENTRY(kMalayalam_FallbackScript, SkTypeface::kNormal, 0
x0D10), | |
903 SK_DEFINE_SCRIPT_ENTRY(kTamilRegular_FallbackScript, SkTypeface::kNormal, 0
x0B82), | |
904 SK_DEFINE_SCRIPT_ENTRY(kTamilBold_FallbackScript, SkTypeface::kBold, 0
x0B82), | |
905 SK_DEFINE_SCRIPT_ENTRY(kThai_FallbackScript, SkTypeface::kNormal, 0
x0E01), | |
906 SK_DEFINE_SCRIPT_ENTRY(kTelugu_FallbackScript, SkTypeface::kNormal, 0
x0C10), | |
907 }; | |
908 | |
909 static bool gFBScriptInitialized = false; | |
910 static const int gFBScriptInfoCount = sizeof(gFBScriptInfo) / sizeof(FBScriptInf
o); | |
911 | |
912 // ensure that if any value is added to the public enum it is also added here | |
913 SK_COMPILE_ASSERT(gFBScriptInfoCount == kFallbackScriptNumber, FBScript_count_mi
smatch); | |
914 | |
915 // this function can't be called if the gFamilyHeadAndNameListMutex is already l
ocked | 881 // this function can't be called if the gFamilyHeadAndNameListMutex is already l
ocked |
916 static bool typefaceContainsChar(SkTypeface* face, SkUnichar uni) { | 882 static bool typefaceContainsChar(SkTypeface* face, SkUnichar uni) { |
917 SkPaint paint; | 883 SkPaint paint; |
918 paint.setTypeface(face); | 884 paint.setTypeface(face); |
919 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); | 885 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); |
920 | 886 |
921 uint16_t glyphID; | 887 uint16_t glyphID; |
922 paint.textToGlyphs(&uni, sizeof(uni), &glyphID); | 888 paint.textToGlyphs(&uni, sizeof(uni), &glyphID); |
923 return glyphID != 0; | 889 return glyphID != 0; |
924 } | 890 } |
925 | 891 |
926 // this function can't be called if the gFamilyHeadAndNameListMutex is already l
ocked | 892 // this function can't be called if the gFamilyHeadAndNameListMutex is already l
ocked |
927 static SkTypeface* findFallbackTypefaceForChar(SkUnichar uni) { | 893 static SkTypeface* findFallbackTypefaceForChar(SkUnichar uni) { |
928 SkASSERT(gFallbackFonts); | 894 SkASSERT(gFallbackFonts); |
929 const uint32_t* list = gFallbackFonts; | 895 const uint32_t* list = gFallbackFonts; |
930 for (int i = 0; list[i] != 0; i++) { | 896 for (int i = 0; list[i] != 0; i++) { |
931 SkTypeface* face; | 897 SkTypeface* face; |
932 { | 898 { |
933 SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex); | 899 SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex); |
934 face = find_from_uniqueID(list[i]); | 900 face = find_from_uniqueID(list[i]); |
935 } | 901 } |
936 if (typefaceContainsChar(face, uni)) { | 902 if (typefaceContainsChar(face, uni)) { |
937 return face; | 903 return face; |
938 } | 904 } |
939 } | 905 } |
940 return 0; | 906 return 0; |
941 } | 907 } |
942 | 908 |
943 // this function can't be called if the gFamilyHeadAndNameListMutex is already l
ocked | |
944 static SkFontID findFallbackFontIDForChar(SkUnichar uni, SkTypeface::Style style
) { | |
945 const SkTypeface* tf = findFallbackTypefaceForChar(uni); | |
946 if (!tf) { | |
947 return 0; | |
948 } | |
949 return find_typeface(tf, style)->uniqueID(); | |
950 } | |
951 | |
952 // this function can't be called if the gFamilyHeadAndNameListMutex is already l
ocked | |
953 static void initFBScriptInfo() { | |
954 if (gFBScriptInitialized) { | |
955 return; | |
956 } | |
957 | |
958 // ensure the system fonts are loaded | |
959 gFamilyHeadAndNameListMutex.acquire(); | |
960 load_system_fonts(); | |
961 gFamilyHeadAndNameListMutex.release(); | |
962 | |
963 for (int i = 0; i < gFBScriptInfoCount; i++) { | |
964 FBScriptInfo& scriptInfo = gFBScriptInfo[i]; | |
965 // selects the best available style for the desired font. However, if | |
966 // bold is requested and no bold font exists for the typeface containing | |
967 // the character the next best style is chosen (e.g. normal). | |
968 scriptInfo.fFontID = findFallbackFontIDForChar(scriptInfo.fChar, scriptI
nfo.fStyle); | |
969 #if SK_DEBUG_FONTS | |
970 SkDebugf("gFBScriptInfo[%s] --> %d", scriptInfo.fScriptID, scriptInfo.fF
ontID); | |
971 #endif | |
972 } | |
973 // mark the value as initialized so we don't repeat our work unnecessarily | |
974 gFBScriptInitialized = true; | |
975 } | |
976 | |
977 SkTypeface* SkCreateTypefaceForScript(FallbackScripts script) { | |
978 if (!SkTypeface_ValidScript(script)) { | |
979 return NULL; | |
980 } | |
981 | |
982 // ensure that our table is populated | |
983 initFBScriptInfo(); | |
984 | |
985 FBScriptInfo& scriptInfo = gFBScriptInfo[script]; | |
986 | |
987 // ensure the element with that index actually maps to the correct script | |
988 SkASSERT(scriptInfo.fScript == script); | |
989 | |
990 // if a suitable script could not be found then return NULL | |
991 if (scriptInfo.fFontID == 0) { | |
992 return NULL; | |
993 } | |
994 | |
995 SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex); | |
996 | |
997 // retrieve the typeface the corresponds to this fontID | |
998 SkTypeface* tf = find_from_uniqueID(scriptInfo.fFontID); | |
999 // we ref(), since the semantic is to return a new instance | |
1000 tf->ref(); | |
1001 return tf; | |
1002 } | |
1003 | |
1004 const char* SkGetFallbackScriptID(FallbackScripts script) { | |
1005 for (int i = 0; i < gFBScriptInfoCount; i++) { | |
1006 if (gFBScriptInfo[i].fScript == script) { | |
1007 return gFBScriptInfo[i].fScriptID; | |
1008 } | |
1009 } | |
1010 return NULL; | |
1011 } | |
1012 | |
1013 FallbackScripts SkGetFallbackScriptFromID(const char* id) { | |
1014 for (int i = 0; i < gFBScriptInfoCount; i++) { | |
1015 if (strcmp(gFBScriptInfo[i].fScriptID, id) == 0) { | |
1016 return gFBScriptInfo[i].fScript; | |
1017 } | |
1018 } | |
1019 return kFallbackScriptNumber; // Use kFallbackScriptNumber as an invalid val
ue. | |
1020 } | |
1021 | |
1022 SkTypeface* SkCreateFallbackTypefaceForChar(SkUnichar uni, | |
1023 SkTypeface::Style style) { | |
1024 { | |
1025 SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex); | |
1026 load_system_fonts(); | |
1027 } | |
1028 | |
1029 SkTypeface* tf = findFallbackTypefaceForChar(uni); | |
1030 if (!tf) { | |
1031 return NULL; | |
1032 } | |
1033 SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex); | |
1034 tf = find_typeface(tf, style); | |
1035 // we ref(), since the semantic is to return a new instance | |
1036 tf->ref(); | |
1037 return tf; | |
1038 } | |
1039 | |
1040 bool SkGetFallbackFamilyNameForChar(SkUnichar uni, SkString* name) { | 909 bool SkGetFallbackFamilyNameForChar(SkUnichar uni, SkString* name) { |
1041 SkASSERT(name); | 910 SkASSERT(name); |
1042 { | 911 { |
1043 SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex); | 912 SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex); |
1044 load_system_fonts(); | 913 load_system_fonts(); |
1045 } | 914 } |
1046 | 915 |
1047 const SkTypeface* tf = findFallbackTypefaceForChar(uni); | 916 const SkTypeface* tf = findFallbackTypefaceForChar(uni); |
1048 if (!tf) { | 917 if (!tf) { |
1049 return false; | 918 return false; |
(...skipping 16 matching lines...) Expand all Loading... |
1066 } | 935 } |
1067 | 936 |
1068 /////////////////////////////////////////////////////////////////////////////// | 937 /////////////////////////////////////////////////////////////////////////////// |
1069 | 938 |
1070 #include "SkFontMgr.h" | 939 #include "SkFontMgr.h" |
1071 | 940 |
1072 SkFontMgr* SkFontMgr::Factory() { | 941 SkFontMgr* SkFontMgr::Factory() { |
1073 // todo | 942 // todo |
1074 return NULL; | 943 return NULL; |
1075 } | 944 } |
OLD | NEW |