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

Side by Side Diff: Source/core/platform/graphics/mac/MemoryActivatedFont.mm

Issue 99103006: Moving GraphicsContext and dependencies from core to platform. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Final patch - fixes Android Created 7 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * This file is part of the internal font implementation.
3 *
4 * Copyright (c) 2010 Google Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23 // This file provides additional functionality to the Mac FontPlatformData class
24 // defined in WebCore/platform/cocoa/FontPlatformDataCocoa.mm .
25 // Because we want to support loading fonts between processes in the face of
26 // font loading being blocked by the sandbox, we need a mechnasim to both
27 // do the loading of in-memory fonts and keep track of them.
28
29 #import "config.h"
30 #import "core/platform/graphics/mac/MemoryActivatedFont.h"
31
32 #import <AppKit/NSFont.h>
33 #import "core/platform/graphics/FontPlatformData.h"
34 #include "platform/LinkHash.h"
35 #import "public/platform/mac/WebSandboxSupport.h"
36 #import "public/platform/Platform.h"
37 #import "wtf/HashMap.h"
38
39 namespace WebCore {
40
41 namespace {
42
43 typedef HashMap<uint32, MemoryActivatedFont*> FontContainerRefMemoryFontHash;
44 typedef HashMap<WTF::String, MemoryActivatedFont*> FontNameMemoryFontHash;
45
46 // Caching:
47 //
48 // Requesting a font from the browser process is expensive and so is
49 // "activating" said font. Caching of loaded fonts is complicated by the fact
50 // that it's impossible to get a unique identifier for the on-disk font file
51 // from inside the sandboxed renderer process.
52 // This means that when loading a font we need to round-trip through the browser
53 // process in order to get the unique font file identifer which we might already
54 // have activated and cached.
55 //
56 // In order to save as much work as we can, we maintain 2 levels of caching
57 // for the font data:
58 // 1. A dumb cache keyed by the font name/style (information we can determine
59 // from inside the sandbox).
60 // 2. A smarter cache keyed by the real "unique font id".
61 //
62 // In order to perform a lookup in #2 we need to consult with the browser to get
63 // us the lookup key. While this doesn't save us the font load, it does save
64 // us font activation.
65 //
66 // It's important to remember that existing FontPlatformData objects are already
67 // cached, so a cache miss in the code in this file isn't necessarily so bad.
68
69 FontContainerRefMemoryFontHash& fontCacheByFontID()
70 {
71 DEFINE_STATIC_LOCAL(FontContainerRefMemoryFontHash, srcFontIDCache, ());
72 return srcFontIDCache;
73 }
74
75
76 FontNameMemoryFontHash& fontCacheByFontName()
77 {
78 DEFINE_STATIC_LOCAL(FontNameMemoryFontHash, srcFontNameCache, ());
79 return srcFontNameCache;
80 }
81
82 // Given a font specified by |srcFont|, use the information we can query in
83 // the sandbox to construct a key which we hope will be as unique as possible
84 // to the containing font file.
85 WTF::String hashKeyFromNSFont(NSFont* srcFont)
86 {
87 NSFontDescriptor* desc = [srcFont fontDescriptor];
88 NSFontSymbolicTraits traits = [desc symbolicTraits];
89 return WTF::String::format("%s %x", [[srcFont fontName] UTF8String], traits) ;
90 }
91
92 // The only way we can tell that an in-process font has failed to load
93 // is if CTFontCopyGraphicsFont() returns the LastResort font.
94 bool isLastResortFont(CGFontRef cgFont)
95 {
96 NSString* fontName = (NSString*)CGFontCopyPostScriptName(cgFont);
97 return [fontName isEqualToString:@"LastResort"];
98 }
99
100 // Given an in-process font which has failed to load, return a
101 // MemoryActivatedFont* corresponding to an in-memory representation of the
102 // same font loaded from the browser process.
103 // On failure this function returns a PassRefPtr pointing to 0.
104 PassRefPtr<MemoryActivatedFont> loadFontFromBrowserProcess(NSFont* nsFont)
105 {
106 // First try to lookup in our cache with the limited information we have.
107 WTF::String hashKey = hashKeyFromNSFont(nsFont);
108 RefPtr<MemoryActivatedFont> font(fontCacheByFontName().get(hashKey));
109 if (font)
110 return font;
111
112 CGFontRef tmpCGFont;
113 uint32_t fontID;
114 // Send cross-process request to load font.
115 blink::WebSandboxSupport* sandboxSupport = blink::Platform::current()->sandb oxSupport();
116 if (!sandboxSupport) {
117 // This function should only be called in response to an error loading a
118 // font due to being blocked by the sandbox.
119 // This by definition shouldn't happen if there is no sandbox support.
120 ASSERT_NOT_REACHED();
121 return 0;
122 }
123 if (!sandboxSupport->loadFont(nsFont, &tmpCGFont, &fontID))
124 return 0;
125
126 RetainPtr<CGFontRef> cgFont(tmpCGFont);
127 // Now that we have the fontID from the browser process, we can consult
128 // the ID cache.
129 font = fontCacheByFontID().get(fontID);
130 if (font)
131 // FIXME: WebSandboxSupport::loadFont() should consult the id cache
132 // before activating the font.
133 return font;
134
135 return MemoryActivatedFont::create(fontID, nsFont, cgFont.get());
136 }
137
138 } // namespace
139
140 PassRefPtr<MemoryActivatedFont> MemoryActivatedFont::create(uint32_t fontID, NSF ont* nsFont, CGFontRef cgFont)
141 {
142 return adoptRef(new MemoryActivatedFont(fontID, nsFont, cgFont));
143 }
144
145 MemoryActivatedFont::MemoryActivatedFont(uint32_t fontID, NSFont* nsFont, CGFont Ref cgFont)
146 : m_cgFont(cgFont)
147 , m_fontID(fontID)
148 , m_inSandboxHashKey(hashKeyFromNSFont(nsFont))
149 {
150 // Add ourselves to caches.
151 fontCacheByFontID().add(fontID, this);
152 fontCacheByFontName().add(m_inSandboxHashKey, this);
153 }
154
155 // Destructor - Unload font container from memory and remove ourselves
156 // from cache.
157 MemoryActivatedFont::~MemoryActivatedFont()
158 {
159 // First remove ourselves from the caches.
160 ASSERT(fontCacheByFontID().contains(m_fontID));
161 ASSERT(fontCacheByFontName().contains(m_inSandboxHashKey));
162
163 fontCacheByFontID().remove(m_fontID);
164 fontCacheByFontName().remove(m_inSandboxHashKey);
165 }
166
167 // Given an NSFont, try to load a representation of that font into the cgFont
168 // parameter. If loading is blocked by the sandbox, the font may be loaded
169 // cross-process.
170 // If sandbox loading also fails, a fallback font is loaded.
171 //
172 // Considerations:
173 // * cgFont must be CFRelease()ed by the caller when done.
174 //
175 // Parameters:
176 // * nsFont - The font we wish to load.
177 // * fontSize - point size of the font we wish to load.
178 // * outNSFont - The font that was actually loaded or null if loading failed.
179 // * cgFont - on output this contains the CGFontRef corresponding to the NSFont
180 // that was picked in the end. The caller is responsible for calling
181 // CFRelease() on this parameter when done with it.
182 // * fontID - on output, the ID corresponding to nsFont.
183 void FontPlatformData::loadFont(NSFont* nsFont, float fontSize, NSFont*& outNSFo nt, CGFontRef& cgFont)
184 {
185 outNSFont = nsFont;
186 cgFont = CTFontCopyGraphicsFont(toCTFontRef(outNSFont), 0);
187 if (outNSFont && cgFont && isLastResortFont(cgFont)) {
188 // Release old CGFontRef since it points at the LastResort font which we don't want.
189 CFRelease(cgFont);
190 cgFont = 0;
191
192 // Font loading was blocked by the Sandbox.
193 m_inMemoryFont = loadFontFromBrowserProcess(outNSFont);
194 if (m_inMemoryFont) {
195 cgFont = m_inMemoryFont->cgFont();
196
197 // Need to add an extra retain so output semantics of this function
198 // are consistent.
199 CFRetain(cgFont);
200 } else {
201 // If we still can't load the font, set |outNSFont| to null so that FontPlatformData won't be used.
202 outNSFont = 0;
203 }
204 }
205 }
206
207 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/mac/MemoryActivatedFont.h ('k') | Source/core/platform/graphics/mac/SimpleFontDataCoreText.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698