[webkit-reviews] review granted: [Bug 137539] [Mac] Spending too much time mapping desired font families to available ones : [Attachment 239513] Patch
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Thu Oct 9 09:05:49 PDT 2014
Darin Adler <darin at apple.com> has granted Chris Dumez <cdumez at apple.com>'s
request for review:
Bug 137539: [Mac] Spending too much time mapping desired font families to
available ones
https://bugs.webkit.org/show_bug.cgi?id=137539
Attachment 239513: Patch
https://bugs.webkit.org/attachment.cgi?id=239513&action=review
------- Additional Comments from Darin Adler <darin at apple.com>
View in context: https://bugs.webkit.org/attachment.cgi?id=239513&action=review
OK to land as is. A few ideas for improvements.
> Source/WebCore/platform/graphics/mac/FontCacheMac.mm:57
> + [WebFontCache invalidate];
I think it’s a little indirect that WebFontCache is only properly invalidated
if WebCore::FontCache is allocated. I suppose that in practice this is not a
problem, but it’s sort of an indirect dependency that could possibly be made
slightly more direct. I could imagine adding a call to fontCache() to the
desiredFamilyToAvailableFamilyDictionary() function, for example, with a
comment explaining the reason and the side effect.
> Source/WebCore/platform/mac/WebFontCache.mm:132
> + if ([desiredFamilyToAvailableFamilyDictionary() count] == maxCacheSize)
{
Might be faster to put the dictionary into a local variable rather than calling
the function at least two times.
> Source/WebCore/platform/mac/WebFontCache.mm:134
> + NSEnumerator *keyEnumerator =
[desiredFamilyToAvailableFamilyDictionary() keyEnumerator];
> + [desiredFamilyToAvailableFamilyDictionary() removeObjectForKey:
[keyEnumerator nextObject]];
Fast enumeration would probably be more efficient and I think reads a little
better.
for (NSString *key in desiredFamilyToAvailableFamilyDictionary()) {
[desiredFamilyToAvailableFamilyDictionary() removeObjectForKey:key];
break;
}
> Source/WebCore/platform/mac/WebFontCache.mm:139
> + if (availableFamily)
> + [desiredFamilyToAvailableFamilyDictionary()
setObject:availableFamily forKey:desiredFamily];
> + else
> + [desiredFamilyToAvailableFamilyDictionary() setObject:@""
forKey:desiredFamily];
Seems a little wordy this way. Might read better like this:
[desiredFamilyToAvailableFamilyDictionary() setObject:availableFamily ?:
@"" forKey:desiredFamily];
Or like this:
NSString *value = availableFamily ? availableFamily : @"";
[desiredFamilyToAvailableFamilyDictionary() setObject:value
forKey:desiredFamily];
Could also consider representing null in the dictionary as NSNull rather than
with an empty string. Downside is you’d have to use id rather than NSString *
when getting values out of the dictionary. Upside is that NSNull is a more
logical direct mapping to/from nil than the empty string is.
> Source/WebCore/platform/mac/WebFontCache.mm:194
> NSFontManager *fontManager = [NSFontManager sharedFontManager];
I’d put this down where it’s used in the non-cached case; seems a little ugly
to do this even in the cached case.
And on reflection, I think this function would be more readable broken into
three pieces:
1) A function that maps a desired family name to an available family name,
without caching.
2) A function that finds a desired family name to an available family name,
with caching, that calls (1) in the "not yet in cache" case.
3) A function that finds an NSFont, which calls (2).
I won’t insist on this refactoring, but I do think it could make the code
easier to read.
> Source/WebCore/platform/mac/WebFontCache.mm:200
> + // Already tried mapping the desired font to an available one in
the past and failed, so
> + // don't try again.
It's good to have a comment here, but this one seems a little too wordy. The
idea that we cache failures as well as successes is a normal part of the
memoization pattern; I wish there was a more straightforward way of separating
“it was cached” from “the cached value happens to be null” that makes this look
less like a special case, and more like “decoding empty string and turning it
into nil”.
> Source/WebCore/platform/mac/WebFontCache.mm:208
> + NSEnumerator *e = [[fontManager availableFontFamilies]
objectEnumerator];
> + while ((availableFamily = [e nextObject])) {
Could use fast enumeration:
for (availableFamily in [fontManager availableFontFamilies]) {
> Source/WebCore/platform/mac/WebFontCache.mm:219
> + NSEnumerator *availableFonts = [[fontManager availableFonts]
objectEnumerator];
> + NSString *availableFont;
> + NSFont *nameMatchedFont = nil;
> + NSFontTraitMask desiredTraitsForNameMatch = desiredTraits |
(desiredWeight >= 7 ? NSBoldFontMask : 0);
> + while ((availableFont = [availableFonts nextObject])) {
Could use fast enumeration:
for (NSString *availableFont in [fontManager availableFonts]) {
More information about the webkit-reviews
mailing list