| OLD | NEW |
| 1 /* libs/graphics/ports/SkFontHost_fontconfig_direct.cpp | 1 /* libs/graphics/ports/SkFontHost_fontconfig_direct.cpp |
| 2 ** | 2 ** |
| 3 ** Copyright 2009, Google Inc. | 3 ** Copyright 2009, Google Inc. |
| 4 ** | 4 ** |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | 5 ** Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 ** you may not use this file except in compliance with the License. | 6 ** you may not use this file except in compliance with the License. |
| 7 ** You may obtain a copy of the License at | 7 ** You may obtain a copy of the License at |
| 8 ** | 8 ** |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | 9 ** http://www.apache.org/licenses/LICENSE-2.0 |
| 10 ** | 10 ** |
| 11 ** Unless required by applicable law or agreed to in writing, software | 11 ** Unless required by applicable law or agreed to in writing, software |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | 12 ** distributed under the License is distributed on an "AS IS" BASIS, |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 ** See the License for the specific language governing permissions and | 14 ** See the License for the specific language governing permissions and |
| 15 ** limitations under the License. | 15 ** limitations under the License. |
| 16 */ | 16 */ |
| 17 | 17 |
| 18 #include "SkFontHost_fontconfig_direct.h" | 18 #include "SkFontHost_fontconfig_direct.h" |
| 19 | 19 |
| 20 #include <unistd.h> | 20 #include <unistd.h> |
| 21 #include <fcntl.h> | 21 #include <fcntl.h> |
| 22 | 22 |
| 23 #include <fontconfig/fontconfig.h> | 23 #include <fontconfig/fontconfig.h> |
| 24 | 24 |
| 25 FontConfigDirect::FontConfigDirect() | 25 namespace { |
| 26 : next_file_id_(0) { | |
| 27 FcInit(); | |
| 28 } | |
| 29 | 26 |
| 30 bool FontConfigDirect::IsMetricCompatibleReplacement(const char* font_a, | 27 // Equivalence classes, used to match the Liberation fonts with their |
| 31 const char* font_b) | 28 // metric-compatible replacements. See the discussion in |
| 29 // GetFontEquivClass(). |
| 30 enum FontEquivClass |
| 31 { |
| 32 OTHER, |
| 33 SANS, |
| 34 SERIF |
| 35 }; |
| 36 |
| 37 // Match the font name against a whilelist of fonts, returning the equivalence |
| 38 // class. |
| 39 FontEquivClass GetFontEquivClass(const char* fontname) |
| 32 { | 40 { |
| 33 // It would be nice for fontconfig to tell us whether a given suggested | 41 // It would be nice for fontconfig to tell us whether a given suggested |
| 34 // replacement is a "strong" match (that is, an equivalent font) or | 42 // replacement is a "strong" match (that is, an equivalent font) or |
| 35 // a "weak" match (that is, fontconfig's next-best attempt at finding a | 43 // a "weak" match (that is, fontconfig's next-best attempt at finding a |
| 36 // substitute). However, I played around with the fontconfig API for | 44 // substitute). However, I played around with the fontconfig API for |
| 37 // a good few hours and could not make it reveal this information. | 45 // a good few hours and could not make it reveal this information. |
| 38 // | 46 // |
| 39 // So instead, we hardcode. These are from | 47 // So instead, we hardcode. Initially this function emulated |
| 40 // /etc/fonts/conf.d/30-metric-aliases.conf on my Ubuntu Karmic | 48 // /etc/fonts/conf.d/30-metric-aliases.conf |
| 41 // system. | 49 // from my Ubuntu system, but we're better off being very conservative. |
| 42 | 50 |
| 43 // We represent the data with a table. Two names with the same | 51 if (strcasecmp(fontname, "Arial") == 0 || |
| 44 // id are in the same class. | 52 strcasecmp(fontname, "Liberation Sans") == 0) { |
| 45 struct FontEquivClass { | 53 return SANS; |
| 46 char id; | 54 } else if (strcasecmp(fontname, "Times New Roman") == 0 || |
| 47 const char name[20]; | 55 strcasecmp(fontname, "Liberation Serif") == 0) { |
| 48 }; | 56 return SERIF; |
| 49 static const FontEquivClass kFontEquivClasses[] = { | 57 } |
| 50 { 0, "Arial" }, | 58 return OTHER; |
| 51 { 0, "Liberation Sans" }, | 59 } |
| 52 { 0, "Albany" }, | |
| 53 { 0, "Albany Amt" }, | |
| 54 | 60 |
| 55 { 1, "Times New Roman" }, | |
| 56 { 1, "Liberation Serif" }, | |
| 57 { 1, "Thorndale" }, | |
| 58 { 1, "Thorndale AMT" }, | |
| 59 | 61 |
| 60 // Note that Liberation Mono doesn't much *look* like Courier New, | 62 // Return true if |font_a| and |font_b| are visually and at the metrics |
| 61 // but it's reportedly metric-compatible. | 63 // level interchangeable. |
| 62 { 2, "Courier New" }, | 64 bool IsMetricCompatibleReplacement(const char* font_a, const char* font_b) |
| 63 { 2, "Liberation Mono" }, | 65 { |
| 64 { 2, "Cumberland" }, | 66 FontEquivClass class_a = GetFontEquivClass(font_a); |
| 65 { 2, "Cumberland AMT" }, | 67 FontEquivClass class_b = GetFontEquivClass(font_b); |
| 66 | 68 |
| 67 { 3, "Helvetica" }, | 69 return class_a != OTHER && class_a == class_b; |
| 68 { 3, "Nimbus Sans L" }, | 70 } |
| 69 | 71 |
| 70 { 4, "Times" }, | 72 } // anonymous namespace |
| 71 { 4, "Nimbus Roman No9 L" }, | |
| 72 | 73 |
| 73 { 5, "Courier" }, | 74 FontConfigDirect::FontConfigDirect() |
| 74 { 5, "Nimbus Mono L" }, | 75 : next_file_id_(0) { |
| 75 }; | 76 FcInit(); |
| 76 static const size_t kClassCount = | |
| 77 sizeof(kFontEquivClasses)/sizeof(kFontEquivClasses[0]); | |
| 78 | |
| 79 int class_a = -1; | |
| 80 for (size_t i = 0; i < kClassCount; ++i) { | |
| 81 if (strcasecmp(kFontEquivClasses[i].name, font_a) == 0) { | |
| 82 class_a = kFontEquivClasses[i].id; | |
| 83 break; | |
| 84 } | |
| 85 } | |
| 86 if (class_a == -1) | |
| 87 return false; | |
| 88 | |
| 89 int class_b = -1; | |
| 90 for (size_t i = 0; i < kClassCount; ++i) { | |
| 91 if (strcasecmp(kFontEquivClasses[i].name, font_b) == 0) { | |
| 92 class_b = kFontEquivClasses[i].id; | |
| 93 break; | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 return class_a == class_b; | |
| 98 } | 77 } |
| 99 | 78 |
| 100 // ----------------------------------------------------------------------------- | 79 // ----------------------------------------------------------------------------- |
| 101 // Normally we only return exactly the font asked for. In last-resort cases, | 80 // Normally we only return exactly the font asked for. In last-resort cases, |
| 102 // the request is for one of the basic font names "Sans", "Serif" or | 81 // the request is for one of the basic font names "Sans", "Serif" or |
| 103 // "Monospace". This function tells you whether a given request is for such a | 82 // "Monospace". This function tells you whether a given request is for such a |
| 104 // fallback. | 83 // fallback. |
| 105 // ----------------------------------------------------------------------------- | 84 // ----------------------------------------------------------------------------- |
| 106 static bool IsFallbackFontAllowed(const std::string& family) | 85 static bool IsFallbackFontAllowed(const std::string& family) |
| 107 { | 86 { |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 | 297 |
| 319 int FontConfigDirect::Open(unsigned fileid) { | 298 int FontConfigDirect::Open(unsigned fileid) { |
| 320 SkAutoMutexAcquire ac(mutex_); | 299 SkAutoMutexAcquire ac(mutex_); |
| 321 const std::map<unsigned, std::string>::const_iterator | 300 const std::map<unsigned, std::string>::const_iterator |
| 322 i = fileid_to_filename_.find(fileid); | 301 i = fileid_to_filename_.find(fileid); |
| 323 if (i == fileid_to_filename_.end()) | 302 if (i == fileid_to_filename_.end()) |
| 324 return -1; | 303 return -1; |
| 325 | 304 |
| 326 return open(i->second.c_str(), O_RDONLY); | 305 return open(i->second.c_str(), O_RDONLY); |
| 327 } | 306 } |
| OLD | NEW |