| 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 |