Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: skia/ext/SkFontHost_fontconfig.cpp

Issue 112074: Linux: Add support for chrooted renderers. (Closed)
Patch Set: Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /* libs/graphics/ports/SkFontHost_fontconfig.cpp
2 **
3 ** Copyright 2008, Google Inc.
4 **
5 ** Licensed under the Apache License, Version 2.0 (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
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 // -----------------------------------------------------------------------------
19 // This file provides implementations of the font resolution members of
20 // SkFontHost by using the fontconfig[1] library. Fontconfig is usually found
21 // on Linux systems and handles configuration, parsing and caching issues
22 // involved with enumerating and matching fonts.
23 //
24 // [1] http://fontconfig.org
25 // -----------------------------------------------------------------------------
26
27 #include <map>
28 #include <string>
29
30 #include <unistd.h>
31 #include <sys/stat.h>
32
33 #include "SkFontHost.h"
34 #include "SkStream.h"
35 #include "SkFontHost_fontconfig_impl.h"
36 #include "SkFontHost_fontconfig_direct.h"
37 #include "SkFontHost_fontconfig_ipc.h"
38
39 static FontConfigInterface* global_fc_impl = NULL;
40
41 void SkiaFontConfigUseDirectImplementation() {
42 global_fc_impl = new FontConfigDirect;
43 }
44
45 void SkiaFontConfigUseIPCImplementation(int fd) {
46 global_fc_impl = new FontConfigIPC(fd);
47 }
48
49 static SkMutex global_fc_map_lock;
50 static std::map<uint32_t, SkTypeface *> global_fc_typefaces;
51
52 // This is the maximum size of the font cache.
53 static const unsigned kFontCacheMemoryBudget = 2 * 1024 * 1024; // 2MB
54
55 // UniqueIds are encoded as (fileid << 8) | style
56
57 static unsigned UniqueIdToFileId(unsigned uniqueid)
58 {
59 return uniqueid >> 8;
60 }
61
62 static SkTypeface::Style UniqueIdToStyle(unsigned uniqueid)
63 {
64 return static_cast<SkTypeface::Style>(uniqueid & 0xff);
65 }
66
67 static unsigned FileIdAndStyleToUniqueId(unsigned fileid,
68 SkTypeface::Style style)
69 {
70 SkASSERT(style & 0xff == style);
71 return (fileid << 8) | static_cast<int>(style);
72 }
73
74 class FontConfigTypeface : public SkTypeface {
75 public:
76 FontConfigTypeface(Style style, uint32_t id)
77 : SkTypeface(style, id)
78 { }
79 };
80
81 // static
82 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
83 const char familyName[],
84 SkTypeface::Style style)
85 {
86 std::string resolved_family_name;
87
88 if (familyFace) {
89 // Given the fileid we can ask fontconfig for the familyname of the
90 // font.
91 const unsigned fileid = UniqueIdToFileId(familyFace->uniqueID());
92 if (!global_fc_impl->Match(
93 &resolved_family_name, NULL, true /* fileid valid */, fileid, "",
94 -1, -1)) {
95 return NULL;
96 }
97 } else if (familyName) {
98 resolved_family_name = familyName;
99 } else {
100 return NULL;
101 }
102
103 const bool bold = style & SkTypeface::kBold;
104 const bool italic = style & SkTypeface::kItalic;
105 unsigned fileid;
106 if (!global_fc_impl->Match(NULL, &fileid, false, -1, /* no fileid */
107 resolved_family_name, bold, italic)) {
108 return NULL;
109 }
110
111 const unsigned id = FileIdAndStyleToUniqueId(fileid, style);
112 SkTypeface* typeface = SkNEW_ARGS(FontConfigTypeface, (style, id));
113
114 {
115 SkAutoMutexAcquire ac(global_fc_map_lock);
116 global_fc_typefaces[id] = typeface;
117 }
118
119 return typeface;
120 }
121
122 // static
123 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream)
124 {
125 SkASSERT(!"SkFontHost::CreateTypefaceFromStream unimplemented");
126 return NULL;
127 }
128
129 // static
130 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[])
131 {
132 SkASSERT(!"SkFontHost::CreateTypefaceFromFile unimplemented");
133 return NULL;
134 }
135
136 // static
137 bool SkFontHost::ValidFontID(SkFontID uniqueID) {
138 SkAutoMutexAcquire ac(global_fc_map_lock);
139 return global_fc_typefaces.find(uniqueID) != global_fc_typefaces.end();
140 }
141
142 void SkFontHost::Serialize(const SkTypeface*, SkWStream*) {
143 SkASSERT(!"SkFontHost::Serialize unimplemented");
144 }
145
146 SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
147 SkASSERT(!"SkFontHost::Deserialize unimplemented");
148 return NULL;
149 }
150
151 // static
152 uint32_t SkFontHost::NextLogicalFont(SkFontID fontID) {
153 // We don't handle font fallback, WebKit does.
154 return 0;
155 }
156
157 ///////////////////////////////////////////////////////////////////////////////
158
159 class SkFileDescriptorStream : public SkStream {
160 public:
161 SkFileDescriptorStream(int fd)
162 : fd_(fd) {
163 }
164
165 ~SkFileDescriptorStream() {
166 close(fd_);
167 }
168
169 virtual bool rewind() {
170 if (lseek(fd_, 0, SEEK_SET) == -1)
171 return false;
172 return true;
173 }
174
175 // SkStream implementation.
176 virtual size_t read(void* buffer, size_t size) {
177 if (!buffer && !size) {
178 // This is request for the length of the stream.
179 struct stat st;
180 if (fstat(fd_, &st) == -1)
181 return 0;
182 return st.st_size;
183 }
184
185 if (!buffer) {
186 // This is a request to skip bytes.
187 const off_t current_position = lseek(fd_, 0, SEEK_CUR);
188 if (current_position == -1)
189 return 0;
190 const off_t new_position = lseek(fd_, size, SEEK_CUR);
191 if (new_position == -1)
192 return 0;
193 if (new_position < current_position) {
194 lseek(fd_, current_position, SEEK_SET);
195 return 0;
196 }
197 return new_position;
198 }
199
200 // This is a request to read bytes.
201 return ::read(fd_, buffer, size);
202 }
203
204 private:
205 const int fd_;
206 };
207
208 ///////////////////////////////////////////////////////////////////////////////
209
210 // static
211 SkStream* SkFontHost::OpenStream(uint32_t id)
212 {
213 const unsigned fileid = UniqueIdToFileId(id);
214 const int fd = global_fc_impl->Open(fileid);
215 if (fd < 0)
216 return NULL;
217
218 return SkNEW_ARGS(SkFileDescriptorStream, (fd));
219 }
220
221 size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar)
222 {
223 if (sizeAllocatedSoFar > kFontCacheMemoryBudget)
224 return sizeAllocatedSoFar - kFontCacheMemoryBudget;
225 else
226 return 0; // nothing to do
227 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698