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 |