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

Side by Side Diff: Source/platform/fonts/mac/SimpleFontDataMac.mm

Issue 618723003: Revert of Switch to HarfBuzz on Mac and remove CoreText shaper (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 2 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 /*
2 * Copyright (C) 2005, 2006, 2010, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2006 Alexey Proskuryakov
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #import "config.h"
28 #import "platform/fonts/SimpleFontData.h"
29
30 #import <AppKit/AppKit.h>
31 #import <ApplicationServices/ApplicationServices.h>
32 #import <float.h>
33 #import <unicode/uchar.h>
34 #import "platform/LayoutTestSupport.h"
35 #import "platform/RuntimeEnabledFeatures.h"
36 #import "platform/SharedBuffer.h"
37 #import "platform/fonts/Font.h"
38 #import "platform/fonts/FontCache.h"
39 #import "platform/fonts/FontDescription.h"
40 #import "platform/geometry/FloatRect.h"
41 #import "platform/graphics/Color.h"
42 #import "platform/mac/BlockExceptions.h"
43 #import <wtf/Assertions.h>
44 #import <wtf/RetainPtr.h>
45 #import <wtf/StdLibExtras.h>
46
47 @interface NSFont (WebAppKitSecretAPI)
48 - (BOOL)_isFakeFixedPitch;
49 @end
50
51 // The names of these constants were taken from history
52 // /trunk/WebKit/WebCoreSupport.subproj/WebTextRenderer.m@9311. The values
53 // were derived from the assembly of libWebKitSystemInterfaceLeopard.a.
54 enum CGFontRenderingMode {
55 kCGFontRenderingMode1BitPixelAligned = 0x0,
56 kCGFontRenderingModeAntialiasedPixelAligned = 0x1,
57 kCGFontRenderingModeAntialiased = 0xd
58 };
59
60 // Forward declare Mac SPIs.
61 extern "C" {
62 // Request for public API: rdar://13803586
63 bool CGFontGetGlyphAdvancesForStyle(CGFontRef font, CGAffineTransform* transform , CGFontRenderingMode renderingMode, ATSGlyphRef* glyph, size_t count, CGSize* a dvance);
64
65 // Request for public API: rdar://13803619
66 CTLineRef CTLineCreateWithUniCharProvider(const UniChar* (*provide)(CFIndex stri ngIndex, CFIndex* charCount, CFDictionaryRef* attributes, void* context), void ( *dispose)(const UniChar* chars, void* context), void* context);
67 }
68
69 static CGFontRenderingMode cgFontRenderingModeForNSFont(NSFont* font) {
70 if (!font)
71 return kCGFontRenderingModeAntialiasedPixelAligned;
72
73 switch ([font renderingMode]) {
74 case NSFontIntegerAdvancementsRenderingMode: return kCGFontRenderingMode 1BitPixelAligned;
75 case NSFontAntialiasedIntegerAdvancementsRenderingMode: return kCGFontRe nderingModeAntialiasedPixelAligned;
76 default: return kCGFontRenderingModeAntialiased;
77 }
78 }
79
80 namespace blink {
81
82 static bool fontHasVerticalGlyphs(CTFontRef ctFont)
83 {
84 // The check doesn't look neat but this is what AppKit does for vertical wri ting...
85 RetainPtr<CFArrayRef> tableTags(AdoptCF, CTFontCopyAvailableTables(ctFont, k CTFontTableOptionNoOptions));
86 CFIndex numTables = CFArrayGetCount(tableTags.get());
87 for (CFIndex index = 0; index < numTables; ++index) {
88 CTFontTableTag tag = (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(t ableTags.get(), index);
89 if (tag == kCTFontTableVhea || tag == kCTFontTableVORG)
90 return true;
91 }
92 return false;
93 }
94
95 static bool initFontData(SimpleFontData* fontData)
96 {
97 if (!fontData->platformData().cgFont())
98 return false;
99
100 return true;
101 }
102
103 static NSString *webFallbackFontFamily(void)
104 {
105 DEFINE_STATIC_LOCAL(RetainPtr<NSString>, webFallbackFontFamily, ([[NSFont sy stemFontOfSize:16.0f] familyName]));
106 return webFallbackFontFamily.get();
107 }
108
109 static bool useHinting()
110 {
111 // Enable hinting when subpixel font scaling is disabled or
112 // when running the set of standard non-subpixel layout tests,
113 // otherwise use subpixel glyph positioning.
114 return (LayoutTestSupport::isRunningLayoutTest() && !LayoutTestSupport::isFo ntAntialiasingEnabledForTest()) || !RuntimeEnabledFeatures::subpixelFontScalingE nabled();
115 }
116
117 const SimpleFontData* SimpleFontData::getCompositeFontReferenceFontData(NSFont * key) const
118 {
119 if (key && !CFEqual(RetainPtr<CFStringRef>(AdoptCF, CTFontCopyPostScriptName (CTFontRef(key))).get(), CFSTR("LastResort"))) {
120 if (!m_derivedFontData)
121 m_derivedFontData = DerivedFontData::create(isCustomFont());
122 if (!m_derivedFontData->compositeFontReferences)
123 m_derivedFontData->compositeFontReferences.adoptCF(CFDictionaryCreat eMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, NULL));
124 else {
125 const SimpleFontData* found = static_cast<const SimpleFontData*>(CFD ictionaryGetValue(m_derivedFontData->compositeFontReferences.get(), static_cast< const void *>(key)));
126 if (found)
127 return found;
128 }
129 if (CFMutableDictionaryRef dictionary = m_derivedFontData->compositeFont References.get()) {
130 NSFont *substituteFont = [key printerFont];
131
132 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(toCTFontRef(su bstituteFont));
133 bool syntheticBold = platformData().syntheticBold() && !(traits & kC TFontBoldTrait);
134 bool syntheticItalic = platformData().syntheticItalic() && !(traits & kCTFontItalicTrait);
135
136 FontPlatformData substitutePlatform(substituteFont, platformData().s ize(), syntheticBold, syntheticItalic, platformData().orientation(), platformDat a().widthVariant());
137 SimpleFontData* value = new SimpleFontData(substitutePlatform, isCus tomFont() ? CustomFontData::create() : nullptr);
138 if (value) {
139 CFDictionaryAddValue(dictionary, key, value);
140 return value;
141 }
142 }
143 }
144 return 0;
145 }
146
147 void SimpleFontData::platformInit()
148 {
149 m_syntheticBoldOffset = m_platformData.m_syntheticBold ? 1.0f : 0.f;
150
151 bool failedSetup = false;
152 if (!initFontData(this)) {
153 // Ack! Something very bad happened, like a corrupt font.
154 // Try looking for an alternate 'base' font for this renderer.
155
156 // Special case hack to use "Times New Roman" in place of "Times".
157 // "Times RO" is a common font whose family name is "Times".
158 // It overrides the normal "Times" family font.
159 // It also appears to have a corrupt regular variant.
160 NSString *fallbackFontFamily;
161 if ([[m_platformData.font() familyName] isEqual:@"Times"])
162 fallbackFontFamily = @"Times New Roman";
163 else
164 fallbackFontFamily = webFallbackFontFamily();
165
166 // Try setting up the alternate font.
167 // This is a last ditch effort to use a substitute font when something h as gone wrong.
168 #if !ERROR_DISABLED
169 RetainPtr<NSFont> initialFont = m_platformData.font();
170 #endif
171 if (m_platformData.font())
172 m_platformData.setFont([[NSFontManager sharedFontManager] convertFon t:m_platformData.font() toFamily:fallbackFontFamily]);
173 else
174 m_platformData.setFont([NSFont fontWithName:fallbackFontFamily size: m_platformData.size()]);
175
176 if (!initFontData(this)) {
177 if ([fallbackFontFamily isEqual:@"Times New Roman"]) {
178 // OK, couldn't setup Times New Roman as an alternate to Times, fallback
179 // on the system font. If this fails we have no alternative lef t.
180 m_platformData.setFont([[NSFontManager sharedFontManager] conver tFont:m_platformData.font() toFamily:webFallbackFontFamily()]);
181 if (!initFontData(this)) {
182 // We tried, Times, Times New Roman, and the system font. No joy. We have to give up.
183 WTF_LOG_ERROR("unable to initialize with font %@", initialFo nt.get());
184 failedSetup = true;
185 }
186 } else {
187 // We tried the requested font and the system font. No joy. We h ave to give up.
188 WTF_LOG_ERROR("unable to initialize with font %@", initialFont.g et());
189 failedSetup = true;
190 }
191 }
192
193 // Report the problem.
194 WTF_LOG_ERROR("Corrupt font detected, using %@ in place of %@.",
195 [m_platformData.font() familyName], [initialFont.get() familyName]);
196 }
197
198 // If all else fails, try to set up using the system font.
199 // This is probably because Times and Times New Roman are both unavailable.
200 if (failedSetup) {
201 m_platformData.setFont([NSFont systemFontOfSize:[m_platformData.font() p ointSize]]);
202 WTF_LOG_ERROR("failed to set up font, using system font %s", m_platformD ata.font());
203 initFontData(this);
204 }
205
206 int iAscent;
207 int iDescent;
208 int iLineGap;
209 unsigned unitsPerEm;
210
211 iAscent = CGFontGetAscent(m_platformData.cgFont());
212 // Some fonts erroneously specify a positive descender value. We follow Core Text in assuming that
213 // such fonts meant the same distance, but in the reverse direction.
214 iDescent = -abs(CGFontGetDescent(m_platformData.cgFont()));
215 iLineGap = CGFontGetLeading(m_platformData.cgFont());
216 unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont());
217
218 float pointSize = m_platformData.m_textSize;
219 float ascent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
220 float descent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
221 float lineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
222 float underlineThickness = CTFontGetUnderlineThickness(m_platformData.ctFont ());
223 float underlinePosition = CTFontGetUnderlinePosition(m_platformData.ctFont() );
224
225 // We need to adjust Times, Helvetica, and Courier to closely match the
226 // vertical metrics of their Microsoft counterparts that are the de facto
227 // web standard. The AppKit adjustment of 20% is too big and is
228 // incorrectly added to line spacing, so we use a 15% adjustment instead
229 // and add it to the ascent.
230 NSString *familyName = [m_platformData.font() familyName];
231 if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"H elvetica"] || [familyName isEqualToString:@"Courier"])
232 ascent += floorf(((ascent + descent) * 0.15f) + 0.5f);
233
234 // Compute and store line spacing, before the line metrics hacks are applied .
235 m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(li neGap));
236
237 // Hack Hiragino line metrics to allow room for marked text underlines.
238 // <rdar://problem/5386183>
239 if (descent < 3 && lineGap >= 3 && [familyName hasPrefix:@"Hiragino"]) {
240 lineGap -= 3 - descent;
241 descent = 3;
242 }
243
244 if (platformData().orientation() == Vertical && !isTextOrientationFallback() )
245 m_hasVerticalGlyphs = fontHasVerticalGlyphs(m_platformData.ctFont());
246
247 float xHeight;
248
249 if (platformData().orientation() == Horizontal) {
250 // Measure the actual character "x", since it's possible for it to exten d below the baseline, and we need the
251 // reported x-height to only include the portion of the glyph that is ab ove the baseline.
252 GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->pag e();
253 NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphForCharacter('x') : 0;
254 if (xGlyph)
255 xHeight = -CGRectGetMinY(platformBoundsForGlyph(xGlyph));
256 else
257 xHeight = scaleEmToUnits(CGFontGetXHeight(m_platformData.cgFont()), unitsPerEm) * pointSize;
258 } else
259 xHeight = verticalRightOrientationFontData()->fontMetrics().xHeight();
260
261 m_fontMetrics.setUnitsPerEm(unitsPerEm);
262 m_fontMetrics.setAscent(ascent);
263 m_fontMetrics.setDescent(descent);
264 m_fontMetrics.setLineGap(lineGap);
265 m_fontMetrics.setXHeight(xHeight);
266 m_fontMetrics.setUnderlineThickness(underlineThickness);
267 m_fontMetrics.setUnderlinePosition(underlinePosition);
268 }
269
270 static CFDataRef copyFontTableForTag(FontPlatformData& platformData, FourCharCod e tableName)
271 {
272 return CGFontCopyTableForTag(platformData.cgFont(), tableName);
273 }
274
275 void SimpleFontData::platformCharWidthInit()
276 {
277 m_avgCharWidth = 0;
278 m_maxCharWidth = 0;
279
280 RetainPtr<CFDataRef> os2Table(AdoptCF, copyFontTableForTag(m_platformData, ' OS/2'));
281 if (os2Table && CFDataGetLength(os2Table.get()) >= 4) {
282 const UInt8* os2 = CFDataGetBytePtr(os2Table.get());
283 SInt16 os2AvgCharWidth = os2[2] * 256 + os2[3];
284 m_avgCharWidth = scaleEmToUnits(os2AvgCharWidth, m_fontMetrics.unitsPerE m()) * m_platformData.m_textSize;
285 }
286
287 RetainPtr<CFDataRef> headTable(AdoptCF, copyFontTableForTag(m_platformData, 'head'));
288 if (headTable && CFDataGetLength(headTable.get()) >= 42) {
289 const UInt8* head = CFDataGetBytePtr(headTable.get());
290 ushort uxMin = head[36] * 256 + head[37];
291 ushort uxMax = head[40] * 256 + head[41];
292 SInt16 xMin = static_cast<SInt16>(uxMin);
293 SInt16 xMax = static_cast<SInt16>(uxMax);
294 float diff = static_cast<float>(xMax - xMin);
295 m_maxCharWidth = scaleEmToUnits(diff, m_fontMetrics.unitsPerEm()) * m_pl atformData.m_textSize;
296 }
297
298 // Fallback to a cross-platform estimate, which will populate these values i f they are non-positive.
299 initCharWidths();
300 }
301
302 void SimpleFontData::platformDestroy()
303 {
304 if (!isCustomFont() && m_derivedFontData) {
305 // These come from the cache.
306 if (m_derivedFontData->smallCaps)
307 FontCache::fontCache()->releaseFontData(m_derivedFontData->smallCaps .get());
308
309 if (m_derivedFontData->emphasisMark)
310 FontCache::fontCache()->releaseFontData(m_derivedFontData->emphasisM ark.get());
311 }
312 }
313
314 PassRefPtr<SimpleFontData> SimpleFontData::platformCreateScaledFontData(const Fo ntDescription& fontDescription, float scaleFactor) const
315 {
316 if (isCustomFont()) {
317 FontPlatformData scaledFontData(m_platformData);
318 scaledFontData.m_textSize = scaledFontData.m_textSize * scaleFactor;
319 return SimpleFontData::create(scaledFontData, CustomFontData::create());
320 }
321
322 BEGIN_BLOCK_OBJC_EXCEPTIONS;
323 float size = m_platformData.size() * scaleFactor;
324 FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFo nt:m_platformData.font() toSize:size], size, false, false, m_platformData.orient ation());
325
326 // AppKit forgets about hinting property when scaling, so we have to remind it.
327 scaledFontData.setFont(useHinting() ? [scaledFontData.font() screenFont] : [ scaledFontData.font() printerFont]);
328
329 if (scaledFontData.font()) {
330 NSFontManager *fontManager = [NSFontManager sharedFontManager];
331 NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.fo nt()];
332
333 if (m_platformData.m_syntheticBold)
334 fontTraits |= NSBoldFontMask;
335 if (m_platformData.m_syntheticItalic)
336 fontTraits |= NSItalicFontMask;
337
338 NSFontTraitMask scaledFontTraits = [fontManager traitsOfFont:scaledFontD ata.font()];
339 scaledFontData.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(scal edFontTraits & NSBoldFontMask);
340 scaledFontData.m_syntheticItalic = (fontTraits & NSItalicFontMask) && !( scaledFontTraits & NSItalicFontMask);
341
342 // SimpleFontData::platformDestroy() takes care of not deleting the cach ed font data twice.
343 return FontCache::fontCache()->fontDataFromFontPlatformData(&scaledFontD ata);
344 }
345 END_BLOCK_OBJC_EXCEPTIONS;
346
347 return nullptr;
348 }
349
350 void SimpleFontData::determinePitch()
351 {
352 NSFont* f = m_platformData.font();
353 // Special case Osaka-Mono.
354 // According to <rdar://problem/3999467>, we should treat Osaka-Mono as fixe d pitch.
355 // Note that the AppKit does not report Osaka-Mono as fixed pitch.
356
357 // Special case MS-PGothic.
358 // According to <rdar://problem/4032938>, we should not treat MS-PGothic as fixed pitch.
359 // Note that AppKit does report MS-PGothic as fixed pitch.
360
361 // Special case MonotypeCorsiva
362 // According to <rdar://problem/5454704>, we should not treat MonotypeCorsiv a as fixed pitch.
363 // Note that AppKit does report MonotypeCorsiva as fixed pitch.
364
365 NSString *name = [f fontName];
366 m_treatAsFixedPitch = ([f isFixedPitch] || [f _isFakeFixedPitch] ||
367 [name caseInsensitiveCompare:@"Osaka-Mono"] == NSOrderedSame) &&
368 [name caseInsensitiveCompare:@"MS-PGothic"] != NSOrderedSame &&
369 [name caseInsensitiveCompare:@"MonotypeCorsiva"] != NSOrderedSame;
370 }
371
372 FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
373 {
374 FloatRect boundingBox;
375 boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(), platf ormData().orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizo ntalOrientation, &glyph, 0, 1);
376 boundingBox.setY(-boundingBox.maxY());
377 if (m_syntheticBoldOffset)
378 boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
379
380 return boundingBox;
381 }
382
383 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
384 {
385 CGSize advance = CGSizeZero;
386 if (platformData().orientation() == Horizontal || m_isBrokenIdeographFallbac k) {
387 NSFont *font = platformData().font();
388 if (font && platformData().isColorBitmapFont())
389 advance = NSSizeToCGSize([font advancementForGlyph:glyph]);
390 else {
391 float pointSize = platformData().m_textSize;
392 CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSiz e);
393 if (!CGFontGetGlyphAdvancesForStyle(platformData().cgFont(), &m, cgF ontRenderingModeForNSFont(font), &glyph, 1, &advance)) {
394 WTF_LOG_ERROR("Unable to cache glyph widths for %@ %f", [font di splayName], pointSize);
395 advance.width = 0;
396 }
397 }
398 } else
399 CTFontGetAdvancesForGlyphs(m_platformData.ctFont(), kCTFontVerticalOrien tation, &glyph, &advance, 1);
400
401 return advance.width + m_syntheticBoldOffset;
402 }
403
404 struct ProviderInfo {
405 const UChar* characters;
406 size_t length;
407 CFDictionaryRef attributes;
408 };
409
410 static const UniChar* provideStringAndAttributes(CFIndex stringIndex, CFIndex* c ount, CFDictionaryRef* attributes, void* context)
411 {
412 ProviderInfo* info = static_cast<struct ProviderInfo*>(context);
413 if (stringIndex < 0 || static_cast<size_t>(stringIndex) >= info->length)
414 return 0;
415
416 *count = info->length - stringIndex;
417 *attributes = info->attributes;
418 return info->characters + stringIndex;
419 }
420
421 bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters , size_t length) const
422 {
423 ASSERT(isMainThread());
424
425 if (!m_combiningCharacterSequenceSupport)
426 m_combiningCharacterSequenceSupport = adoptPtr(new HashMap<String, bool> );
427
428 WTF::HashMap<String, bool>::AddResult addResult = m_combiningCharacterSequen ceSupport->add(String(characters, length), false);
429 if (!addResult.isNewEntry)
430 return addResult.storedValue->value;
431
432 RetainPtr<CGFontRef> cgFont(AdoptCF, CTFontCopyGraphicsFont(platformData().c tFont(), 0));
433
434 ProviderInfo info = { characters, length, getCFStringAttributes(0, platformD ata().orientation()) };
435 RetainPtr<CTLineRef> line(AdoptCF, CTLineCreateWithUniCharProvider(&provideS tringAndAttributes, 0, &info));
436
437 CFArrayRef runArray = CTLineGetGlyphRuns(line.get());
438 CFIndex runCount = CFArrayGetCount(runArray);
439
440 for (CFIndex r = 0; r < runCount; r++) {
441 CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r));
442 ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID());
443 CFDictionaryRef runAttributes = CTRunGetAttributes(ctRun);
444 CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttri butes, kCTFontAttributeName));
445 RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont, 0));
446 if (!CFEqual(runCGFont.get(), cgFont.get()))
447 return false;
448 }
449
450 addResult.storedValue->value = true;
451 return true;
452 }
453
454 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/fonts/mac/SimpleFontDataCoreText.cpp ('k') | Source/platform/fonts/skia/SimpleFontDataSkia.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698