Changeset 177876 in webkit
- Timestamp:
- Jan 4, 2015 1:26:17 PM (9 years ago)
- Location:
- trunk/Source
- Files:
-
- 2 deleted
- 28 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r177869 r177876 2077 2077 platform/graphics/GeneratedImage.cpp 2078 2078 platform/graphics/GeometryUtilities.cpp 2079 platform/graphics/GlyphPageTreeNode.cpp2080 2079 platform/graphics/Gradient.cpp 2081 2080 platform/graphics/GradientImage.cpp -
trunk/Source/WebCore/ChangeLog
r177874 r177876 1 2015-01-02 Antti Koivisto <antti@apple.com> 2 3 Remove GlyphPageTree 4 https://bugs.webkit.org/show_bug.cgi?id=140015 5 6 Reviewed by Darin Adler. 7 8 GlyphPageTree is a global cache consisting of a tree of nodes that match SimpleFontData instances. 9 The tree levels correspond to font fallback lists so that higher levels fill holes (missing glyphs) 10 in the lower levels. This patch replaces it with a simpler and easier to understand caching scheme. 11 In particular the goal is to have clearer ownership relations and better control over mutability. 12 13 The new scheme looks like this: 14 15 SimpleFontData instances cache GlyphPages for themselves. These pages are immutable after construction 16 and may contain holes. This is a global cache (since SimpleFontDatas are cached globally) with the same 17 lifetime as the GlyphPageTree used to have. 18 19 FontGlyphs instances cache resolved GlyphPages for the normal font variant. These are build by traversing 20 the fallback list as necessary and collecting glyphs from SimpleFontDatas. As a common case case optimization 21 the page from the primary font is cached directly as long as it has the requested glyphs. 22 FontGlyphs are shared between sufficiently similar Font instances so this is a shared cache as well. 23 24 * CMakeLists.txt: 25 * WebCore.exp.in: 26 * WebCore.vcxproj/WebCore.vcxproj: 27 * WebCore.xcodeproj/project.pbxproj: 28 * platform/graphics/FontCache.h: 29 (WebCore::FontDescriptionFontDataCacheKey::makeFlagKey): 30 31 nonCJKGlyphOrientation matters for glyph selection too and needs to be part of the FontDescription cache key. 32 33 * platform/graphics/FontData.h: 34 (WebCore::FontData::FontData): 35 (WebCore::FontData::setMaxGlyphPageTreeLevel): Deleted. 36 (WebCore::FontData::maxGlyphPageTreeLevel): Deleted. 37 * platform/graphics/FontFastPath.cpp: 38 (WebCore::Font::primaryFontHasGlyphForCharacter): 39 * platform/graphics/FontGlyphs.cpp: 40 (WebCore::FontGlyphs::FontGlyphs): 41 (WebCore::glyphDataForCJKCharacterWithoutSyntheticItalic): 42 (WebCore::glyphDataForNonCJKCharacterWithGlyphOrientation): 43 (WebCore::FontGlyphs::glyphDataForSystemFallback): 44 (WebCore::FontGlyphs::glyphDataForVariant): 45 (WebCore::FontGlyphs::glyphDataForNormalCharacter): 46 47 Traverse the fallback list by using simple index instead of indirectly via GlyphPageTreeNode traversal. 48 49 (WebCore::pageFromFontData): 50 51 Fetch a page from the primary font and see if we can use it as-is. 52 Vertical fonts have special glyph selection and can't use this path. 53 54 (WebCore::FontGlyphs::createFlattenedGlyphPage): 55 56 Build a hole-free glyph page by pulling characters from the fallback list. 57 58 (WebCore::FontGlyphs::glyphDataForCharacter): 59 * platform/graphics/FontGlyphs.h: 60 (WebCore::FontGlyphs::primarySimpleFontData): 61 * platform/graphics/GlyphPage.h: 62 (WebCore::GlyphPage::createForMixedFontData): 63 (WebCore::GlyphPage::createCopyForMixedFontData): 64 65 Add copy version. 66 67 (WebCore::GlyphPage::createForSingleFontData): 68 69 Remove owner node field. 70 71 (WebCore::GlyphPage::~GlyphPage): 72 (WebCore::GlyphPage::count): 73 (WebCore::GlyphPage::GlyphPage): 74 (WebCore::GlyphPage::createCopiedSystemFallbackPage): Deleted. 75 (WebCore::GlyphPage::owner): Deleted. 76 * platform/graphics/GlyphPageTreeNode.cpp: Removed. 77 * platform/graphics/GlyphPageTreeNode.h: Removed. 78 * platform/graphics/SegmentedFontData.cpp: 79 (WebCore::SegmentedFontData::SegmentedFontData): 80 (WebCore::SegmentedFontData::~SegmentedFontData): 81 (WebCore::SegmentedFontData::simpleFontDataForCharacter): 82 83 Return null when there is no usable range so the client can tell the difference. 84 Rename for clarity. 85 86 (WebCore::SegmentedFontData::simpleFontDataForFirstRange): 87 88 Add a way to get the fallback font separately. This is always available. 89 90 (WebCore::SegmentedFontData::isLoading): 91 (WebCore::SegmentedFontData::fontDataForCharacter): Deleted. 92 * platform/graphics/SegmentedFontData.h: 93 (WebCore::SegmentedFontData::SegmentedFontData): Deleted. 94 * platform/graphics/SimpleFontData.cpp: 95 (WebCore::SimpleFontData::initCharWidths): 96 (WebCore::SimpleFontData::platformGlyphInit): 97 (WebCore::SimpleFontData::~SimpleFontData): 98 (WebCore::SimpleFontData::simpleFontDataForCharacter): 99 (WebCore::fillGlyphPage): 100 (WebCore::createAndFillGlyphPage): 101 102 Move code for initializing glyph pages here. The code is from GlyphPageTreeNode. 103 104 (WebCore::SimpleFontData::glyphPage): 105 106 Cache glyphs for this font. These pages may have holes. 107 108 (WebCore::SimpleFontData::glyphForCharacter): 109 (WebCore::SimpleFontData::glyphDataForCharacter): 110 (WebCore::SimpleFontData::DerivedFontData::~DerivedFontData): 111 112 Since the cache is now owned by the SimpleFontData all the custom pruning can go away. 113 The glyph page cache dies along with it owner. 114 115 (WebCore::SimpleFontData::fontDataForCharacter): Deleted. 116 * platform/graphics/SimpleFontData.h: 117 * platform/graphics/mac/ComplexTextControllerCoreText.mm: 118 (-[WebCascadeList objectAtIndex:]): 119 (WebCore::ComplexTextController::collectComplexTextRunsForCharacters): 120 * platform/graphics/mac/FontComplexTextMac.cpp: 121 (WebCore::Font::fontDataForCombiningCharacterSequence): 122 * platform/graphics/mac/GlyphPageMac.cpp: Copied from Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp. 123 124 This was already misnamed. 125 126 (WebCore::GlyphPage::fill): 127 * platform/graphics/mac/GlyphPageTreeNodeMac.cpp: Removed. 128 * platform/graphics/mac/SimpleFontDataMac.mm: 129 (WebCore::SimpleFontData::platformInit): 130 * platform/graphics/win/GlyphPageTreeNodeCGWin.cpp: 131 * platform/graphics/win/GlyphPageTreeNodeCairoWin.cpp: 132 * platform/graphics/win/SimpleFontDataCGWin.cpp: 133 (WebCore::SimpleFontData::platformInit): 134 * platform/mac/DragImageMac.mm: 135 136 Add missing FontCachePurgePreventer. 137 138 (WebCore::createDragImageForLink): 139 * svg/SVGFontData.cpp: 140 (WebCore::SVGFontData::initializeFontData): 141 * svg/SVGFontElement.cpp: 142 1 143 2015-01-04 Anders Carlsson <andersca@apple.com> 2 144 -
trunk/Source/WebCore/WebCore.exp.in
r177857 r177876 762 762 __ZN7WebCore17DOMImplementation14isTextMIMETypeERKN3WTF6StringE 763 763 __ZN7WebCore17DebugPageOverlays15settingsChangedERNS_9MainFrameE 764 __ZN7WebCore17GlyphPageTreeNode18treeGlyphPageCountEv765 764 __ZN7WebCore17HTMLOptionElement8selectedEv 766 765 __ZN7WebCore17HTMLSelectElement20optionSelectedByUserEibb … … 1494 1493 __ZN7WebCore9FrameView52disableLayerFlushThrottlingTemporarilyForInteractionEv 1495 1494 __ZN7WebCore9FrameView6createERNS_5FrameE 1495 __ZN7WebCore9GlyphPage7s_countE 1496 1496 __ZN7WebCore9HTMLNames10actionAttrE 1497 1497 __ZN7WebCore9HTMLNames10listingTagE -
trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
r177857 r177876 8056 8056 <ClCompile Include="..\platform\graphics\GeometryUtilities.cpp" /> 8057 8057 <ClCompile Include="..\platform\graphics\GeneratedImage.cpp" /> 8058 <ClCompile Include="..\platform\graphics\GlyphPageTreeNode.cpp" />8059 8058 <ClCompile Include="..\platform\graphics\Gradient.cpp" /> 8060 8059 <ClCompile Include="..\platform\graphics\GradientImage.cpp" /> … … 19611 19610 <ClInclude Include="..\platform\graphics\GlyphMetricsMap.h" /> 19612 19611 <ClInclude Include="..\platform\graphics\GlyphPage.h" /> 19613 <ClInclude Include="..\platform\graphics\GlyphPageTreeNode.h" />19614 19612 <ClInclude Include="..\platform\graphics\Gradient.h" /> 19615 19613 <ClInclude Include="..\platform\graphics\GraphicsContext.h" /> -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r177869 r177876 4678 4678 B2AFFC7F0D00A5C10030074D /* SimpleFontDataMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = B2AFFC770D00A5C10030074D /* SimpleFontDataMac.mm */; }; 4679 4679 B2AFFC800D00A5C10030074D /* FontMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = B2AFFC780D00A5C10030074D /* FontMac.mm */; }; 4680 B2AFFC830D00A5C10030074D /* GlyphPage TreeNodeMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2AFFC7B0D00A5C10030074D /* GlyphPageTreeNodeMac.cpp */; };4680 B2AFFC830D00A5C10030074D /* GlyphPageMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2AFFC7B0D00A5C10030074D /* GlyphPageMac.cpp */; }; 4681 4681 B2AFFC970D00A5DF0030074D /* TextBoundaries.mm in Sources */ = {isa = PBXBuildFile; fileRef = B2AFFC8C0D00A5DF0030074D /* TextBoundaries.mm */; }; 4682 4682 B2AFFC980D00A5DF0030074D /* TextBreakIteratorInternalICUMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = B2AFFC8D0D00A5DF0030074D /* TextBreakIteratorInternalICUMac.mm */; }; … … 4722 4722 B2C3DA6B0D006CD600EF6F26 /* FontSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C3DA5A0D006CD600EF6F26 /* FontSelector.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4723 4723 B2C3DA6C0D006CD600EF6F26 /* GlyphBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C3DA5B0D006CD600EF6F26 /* GlyphBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4724 B2C3DA6D0D006CD600EF6F26 /* GlyphPageTreeNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2C3DA5C0D006CD600EF6F26 /* GlyphPageTreeNode.cpp */; };4725 B2C3DA6E0D006CD600EF6F26 /* GlyphPageTreeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C3DA5D0D006CD600EF6F26 /* GlyphPageTreeNode.h */; settings = {ATTRIBUTES = (Private, ); }; };4726 4724 B2C96D8D0B3AF2B7005E80EC /* JSSVGPathSegCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2C96D8C0B3AF2B7005E80EC /* JSSVGPathSegCustom.cpp */; }; 4727 4725 B2CB92420B5BD966009BAA78 /* JSSVGElementInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2CB923B0B5BD941009BAA78 /* JSSVGElementInstance.cpp */; }; … … 12086 12084 B2AFFC770D00A5C10030074D /* SimpleFontDataMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = SimpleFontDataMac.mm; sourceTree = "<group>"; }; 12087 12085 B2AFFC780D00A5C10030074D /* FontMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = FontMac.mm; sourceTree = "<group>"; }; 12088 B2AFFC7B0D00A5C10030074D /* GlyphPage TreeNodeMac.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GlyphPageTreeNodeMac.cpp; sourceTree = "<group>"; };12086 B2AFFC7B0D00A5C10030074D /* GlyphPageMac.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GlyphPageMac.cpp; sourceTree = "<group>"; }; 12089 12087 B2AFFC850D00A5DF0030074D /* character-sets.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "character-sets.txt"; sourceTree = "<group>"; }; 12090 12088 B2AFFC860D00A5DF0030074D /* mac-encodings.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "mac-encodings.txt"; sourceTree = "<group>"; }; … … 12133 12131 B2C3DA5A0D006CD600EF6F26 /* FontSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FontSelector.h; sourceTree = "<group>"; }; 12134 12132 B2C3DA5B0D006CD600EF6F26 /* GlyphBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GlyphBuffer.h; sourceTree = "<group>"; }; 12135 B2C3DA5C0D006CD600EF6F26 /* GlyphPageTreeNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GlyphPageTreeNode.cpp; sourceTree = "<group>"; };12136 B2C3DA5D0D006CD600EF6F26 /* GlyphPageTreeNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GlyphPageTreeNode.h; sourceTree = "<group>"; };12137 12133 B2C96D8C0B3AF2B7005E80EC /* JSSVGPathSegCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGPathSegCustom.cpp; sourceTree = "<group>"; }; 12138 12134 B2CB923B0B5BD941009BAA78 /* JSSVGElementInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGElementInstance.cpp; sourceTree = "<group>"; }; … … 20443 20439 B2AFFC760D00A5C10030074D /* FontCustomPlatformData.h */, 20444 20440 B2AFFC780D00A5C10030074D /* FontMac.mm */, 20445 B2AFFC7B0D00A5C10030074D /* GlyphPage TreeNodeMac.cpp */,20441 B2AFFC7B0D00A5C10030074D /* GlyphPageMac.cpp */, 20446 20442 49FFBF1C11C8550E006A7118 /* GraphicsContext3DMac.mm */, 20447 20443 B277B4030B22F37C0004BEC6 /* GraphicsContextMac.mm */, … … 20551 20547 C5D4AA78116BAFB60069CA93 /* GlyphMetricsMap.h */, 20552 20548 0873B86A136064EA00A522C2 /* GlyphPage.h */, 20553 B2C3DA5C0D006CD600EF6F26 /* GlyphPageTreeNode.cpp */,20554 B2C3DA5D0D006CD600EF6F26 /* GlyphPageTreeNode.h */,20555 20549 BC53C6070DA56C570021EB5D /* Gradient.cpp */, 20556 20550 BC53C5F40DA56B920021EB5D /* Gradient.h */, … … 24472 24466 C5D4AA7A116BAFB60069CA93 /* GlyphMetricsMap.h in Headers */, 24473 24467 0873B86B136064EA00A522C2 /* GlyphPage.h in Headers */, 24474 B2C3DA6E0D006CD600EF6F26 /* GlyphPageTreeNode.h in Headers */,24475 24468 BC53C5F50DA56B920021EB5D /* Gradient.h in Headers */, 24476 24469 B22279640D00BF220071B782 /* GradientAttributes.h in Headers */, … … 27972 27965 9746AF2614F4DDE6003E7A70 /* GeolocationController.cpp in Sources */, 27973 27966 0FB6252E18DE1B1500A07C05 /* GeometryUtilities.cpp in Sources */, 27974 B2C3DA6D0D006CD600EF6F26 /* GlyphPageTreeNode.cpp in Sources */, 27975 B2AFFC830D00A5C10030074D /* GlyphPageTreeNodeMac.cpp in Sources */, 27967 B2AFFC830D00A5C10030074D /* GlyphPageMac.cpp in Sources */, 27976 27968 BC53C6080DA56C570021EB5D /* Gradient.cpp in Sources */, 27977 27969 BC53C60B0DA56CF10021EB5D /* GradientCG.cpp in Sources */, -
trunk/Source/WebCore/platform/graphics/FontCache.h
r175013 r177876 80 80 static unsigned makeFlagKey(const FontDescription& description) 81 81 { 82 return static_cast<unsigned>(description.widthVariant()) << 4 82 return static_cast<unsigned>(description.widthVariant()) << 5 83 | static_cast<unsigned>(description.nonCJKGlyphOrientation()) << 4 83 84 | static_cast<unsigned>(description.orientation()) << 3 84 85 | static_cast<unsigned>(description.italic()) << 2 -
trunk/Source/WebCore/platform/graphics/FontData.h
r177847 r177876 1 1 /* 2 * Copyright (C) 2008 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 42 42 public: 43 43 FontData() 44 : m_maxGlyphPageTreeLevel(0)45 44 { 46 45 } … … 48 47 virtual ~FontData(); 49 48 50 virtual const SimpleFontData* fontDataForCharacter(UChar32) const = 0; 49 virtual const SimpleFontData* simpleFontDataForCharacter(UChar32) const = 0; 50 virtual const SimpleFontData& simpleFontDataForFirstRange() const = 0; 51 51 virtual bool isCustomFont() const = 0; 52 52 virtual bool isLoading() const = 0; 53 53 virtual bool isSegmented() const = 0; 54 54 55 void setMaxGlyphPageTreeLevel(unsigned level) const { m_maxGlyphPageTreeLevel = level; }56 unsigned maxGlyphPageTreeLevel() const { return m_maxGlyphPageTreeLevel; }57 58 55 #ifndef NDEBUG 59 56 virtual String description() const = 0; 60 57 #endif 61 62 private:63 mutable unsigned m_maxGlyphPageTreeLevel;64 58 }; 65 59 -
trunk/Source/WebCore/platform/graphics/FontFastPath.cpp
r170947 r177876 28 28 #include "FontGlyphs.h" 29 29 #include "GlyphBuffer.h" 30 #include "GlyphPageTreeNode.h"31 30 #include "LayoutRect.h" 32 31 #include "SimpleFontData.h" … … 44 43 bool Font::primaryFontHasGlyphForCharacter(UChar32 character) const 45 44 { 46 unsigned pageNumber = (character / GlyphPage::size); 47 48 GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(primaryFont(), pageNumber); 49 GlyphPage* page = node->page(); 50 51 return page && page->fontDataForCharacter(character); 45 return primaryFont()->glyphForCharacter(character); 52 46 } 53 47 -
trunk/Source/WebCore/platform/graphics/FontGlyphs.cpp
r177637 r177876 1 1 /* 2 * Copyright (C) 2006, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2006, 2013-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 #include "Font.h" 33 33 #include "FontCache.h" 34 #include "GlyphPage TreeNode.h"34 #include "GlyphPage.h" 35 35 #include "SegmentedFontData.h" 36 36 … … 39 39 40 40 FontGlyphs::FontGlyphs(PassRefPtr<FontSelector> fontSelector) 41 : m_pageZero(0) 42 , m_cachedPrimarySimpleFontData(0) 41 : m_cachedPrimarySimpleFontData(0) 43 42 , m_fontSelector(fontSelector) 44 43 , m_fontSelectorVersion(m_fontSelector ? m_fontSelector->version() : 0) … … 52 51 53 52 FontGlyphs::FontGlyphs(const FontPlatformData& platformData) 54 : m_pageZero(0) 55 , m_cachedPrimarySimpleFontData(0) 53 : m_cachedPrimarySimpleFontData(0) 56 54 , m_fontSelector(0) 57 55 , m_fontSelectorVersion(0) … … 212 210 213 211 #if PLATFORM(COCOA) 214 static GlyphData glyphDataForCJKCharacterWithoutSyntheticItalic(UChar32 character, GlyphData& data, unsigned pageNumber) 215 { 216 RefPtr<SimpleFontData> nonItalicFontData = data.fontData->nonSyntheticItalicFontData(); 217 GlyphPageTreeNode* nonItalicNode = GlyphPageTreeNode::getRootChild(nonItalicFontData.get(), pageNumber); 218 GlyphPage* nonItalicPage = nonItalicNode->page(); 219 if (nonItalicPage) { 220 GlyphData nonItalicData = nonItalicPage->glyphDataForCharacter(character); 221 if (nonItalicData.fontData) 222 return nonItalicData; 223 } 212 static GlyphData glyphDataForCJKCharacterWithoutSyntheticItalic(UChar32 character, GlyphData& data) 213 { 214 GlyphData nonItalicData = data.fontData->nonSyntheticItalicFontData()->glyphDataForCharacter(character); 215 if (nonItalicData.fontData) 216 return nonItalicData; 224 217 return data; 225 218 } 226 219 #endif 227 220 228 static GlyphData glyphDataForNonCJKCharacterWithGlyphOrientation(UChar32 character, NonCJKGlyphOrientation orientation, GlyphData& data, unsigned pageNumber)221 static GlyphData glyphDataForNonCJKCharacterWithGlyphOrientation(UChar32 character, NonCJKGlyphOrientation orientation, const GlyphData& data) 229 222 { 230 223 if (orientation == NonCJKGlyphOrientationUpright || shouldIgnoreRotation(character)) { 231 RefPtr<SimpleFontData> uprightFontData = data.fontData->uprightOrientationFontData(); 232 GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getRootChild(uprightFontData.get(), pageNumber); 233 GlyphPage* uprightPage = uprightNode->page(); 234 if (uprightPage) { 235 GlyphData uprightData = uprightPage->glyphDataForCharacter(character); 236 // If the glyphs are the same, then we know we can just use the horizontal glyph rotated vertically to be upright. 237 if (data.glyph == uprightData.glyph) 224 GlyphData uprightData = data.fontData->uprightOrientationFontData()->glyphDataForCharacter(character); 225 // If the glyphs are the same, then we know we can just use the horizontal glyph rotated vertically to be upright. 226 if (data.glyph == uprightData.glyph) 227 return data; 228 // The glyphs are distinct, meaning that the font has a vertical-right glyph baked into it. We can't use that 229 // glyph, so we fall back to the upright data and use the horizontal glyph. 230 if (uprightData.fontData) 231 return uprightData; 232 } else if (orientation == NonCJKGlyphOrientationVerticalRight) { 233 GlyphData verticalRightData = data.fontData->verticalRightOrientationFontData()->glyphDataForCharacter(character); 234 // If the glyphs are distinct, we will make the assumption that the font has a vertical-right glyph baked 235 // into it. 236 if (data.glyph != verticalRightData.glyph) 237 return data; 238 // The glyphs are identical, meaning that we should just use the horizontal glyph. 239 if (verticalRightData.fontData) 240 return verticalRightData; 241 } 242 return data; 243 } 244 245 GlyphData FontGlyphs::glyphDataForSystemFallback(UChar32 c, const FontDescription& description, FontDataVariant variant) 246 { 247 // System fallback is character-dependent. 248 auto* originalFontData = primaryFontData(description)->simpleFontDataForCharacter(c); 249 if (!originalFontData) 250 originalFontData = &primaryFontData(description)->simpleFontDataForFirstRange(); 251 252 RefPtr<SimpleFontData> systemFallbackFontData = originalFontData->systemFallbackFontDataForCharacter(c, description, m_isForPlatformFont); 253 if (!systemFallbackFontData) 254 return GlyphData(); 255 256 if (systemFallbackFontData->platformData().orientation() == Vertical && !systemFallbackFontData->hasVerticalGlyphs() && Font::isCJKIdeographOrSymbol(c)) 257 variant = BrokenIdeographVariant; 258 259 GlyphData fallbackGlyphData; 260 if (variant == NormalVariant) 261 fallbackGlyphData = systemFallbackFontData->glyphDataForCharacter(c); 262 else 263 fallbackGlyphData = systemFallbackFontData->variantFontData(description, variant)->glyphDataForCharacter(c); 264 265 if (variant == NormalVariant && fallbackGlyphData.fontData) { 266 if (!Font::isCJKIdeographOrSymbol(c) && fallbackGlyphData.fontData->platformData().orientation() == Vertical && !fallbackGlyphData.fontData->isTextOrientationFallback()) 267 fallbackGlyphData = glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), fallbackGlyphData); 268 } 269 270 // Keep the system fallback fonts we use alive. 271 if (fallbackGlyphData.glyph) 272 m_systemFallbackFontDataSet.add(systemFallbackFontData.release()); 273 274 return fallbackGlyphData; 275 } 276 277 GlyphData FontGlyphs::glyphDataForVariant(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned fallbackLevel) 278 { 279 for (; fallbackLevel <= description.familyCount(); ++fallbackLevel) { 280 auto* fontData = realizeFontDataAt(description, fallbackLevel); 281 if (!fontData) 282 return glyphDataForSystemFallback(c, description, variant); 283 284 auto* simpleFontData = fontData->simpleFontDataForCharacter(c); 285 GlyphData data = simpleFontData ? simpleFontData->glyphDataForCharacter(c) : GlyphData(); 286 if (data.fontData) { 287 // The variantFontData function should not normally return 0. 288 // But if it does, we will just render the capital letter big. 289 RefPtr<SimpleFontData> variantFontData = data.fontData->variantFontData(description, variant); 290 if (!variantFontData) 238 291 return data; 239 // The glyphs are distinct, meaning that the font has a vertical-right glyph baked into it. We can't use that 240 // glyph, so we fall back to the upright data and use the horizontal glyph. 241 if (uprightData.fontData) 242 return uprightData; 292 293 return variantFontData->glyphDataForCharacter(c); 243 294 } 244 } else if (orientation == NonCJKGlyphOrientationVerticalRight) { 245 RefPtr<SimpleFontData> verticalRightFontData = data.fontData->verticalRightOrientationFontData(); 246 GlyphPageTreeNode* verticalRightNode = GlyphPageTreeNode::getRootChild(verticalRightFontData.get(), pageNumber); 247 GlyphPage* verticalRightPage = verticalRightNode->page(); 248 if (verticalRightPage) { 249 GlyphData verticalRightData = verticalRightPage->glyphDataForCharacter(character); 250 // If the glyphs are distinct, we will make the assumption that the font has a vertical-right glyph baked 251 // into it. 252 if (data.glyph != verticalRightData.glyph) 253 return data; 254 // The glyphs are identical, meaning that we should just use the horizontal glyph. 255 if (verticalRightData.fontData) 256 return verticalRightData; 295 } 296 ASSERT_NOT_REACHED(); 297 return GlyphData(); 298 } 299 300 GlyphData FontGlyphs::glyphDataForNormalVariant(UChar32 c, const FontDescription& description) 301 { 302 const unsigned pageNumber = c / GlyphPage::size; 303 304 for (unsigned fallbackLevel = 0; fallbackLevel <= description.familyCount(); ++fallbackLevel) { 305 auto* fontData = realizeFontDataAt(description, fallbackLevel); 306 if (!fontData) 307 return glyphDataForSystemFallback(c, description, NormalVariant); 308 309 auto* simpleFontData = fontData->simpleFontDataForCharacter(c); 310 auto* page = simpleFontData ? simpleFontData->glyphPage(pageNumber) : nullptr; 311 if (!page) 312 continue; 313 GlyphData data = page->glyphDataForCharacter(c); 314 if (data.fontData) { 315 if (data.fontData->platformData().orientation() == Vertical && !data.fontData->isTextOrientationFallback()) { 316 if (!Font::isCJKIdeographOrSymbol(c)) 317 return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data); 318 319 if (!data.fontData->hasVerticalGlyphs()) { 320 // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs 321 // to make sure you get a square (even for broken glyphs like symbols used for punctuation). 322 return glyphDataForVariant(c, description, BrokenIdeographVariant, fallbackLevel); 323 } 324 #if PLATFORM(COCOA) 325 if (data.fontData->platformData().syntheticOblique()) 326 return glyphDataForCJKCharacterWithoutSyntheticItalic(c, data); 327 #endif 328 } 329 330 return data; 257 331 } 258 332 } 259 return data; 260 } 261 262 GlyphData FontGlyphs::glyphDataForSystemFallback(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned pageNumber, GlyphPageTreeNode& node) 263 { 264 ASSERT(node.page()); 265 ASSERT(node.isSystemFallback()); 266 // System fallback is character-dependent. When we get here, we 267 // know that the character in question isn't in the system fallback 268 // font's glyph page. Try to lazily create it here. 269 UChar codeUnits[2]; 270 int codeUnitsLength; 271 if (c <= 0xFFFF) { 272 codeUnits[0] = Font::normalizeSpaces(c); 273 codeUnitsLength = 1; 274 } else { 275 codeUnits[0] = U16_LEAD(c); 276 codeUnits[1] = U16_TRAIL(c); 277 codeUnitsLength = 2; 278 } 279 const SimpleFontData* originalFontData = primaryFontData(description)->fontDataForCharacter(c); 280 RefPtr<SimpleFontData> characterFontData = fontCache().systemFallbackForCharacters(description, originalFontData, m_isForPlatformFont, codeUnits, codeUnitsLength); 281 if (!characterFontData) 282 return GlyphData(); 283 284 if (characterFontData->platformData().orientation() == Vertical && !characterFontData->hasVerticalGlyphs() && Font::isCJKIdeographOrSymbol(c)) 285 variant = BrokenIdeographVariant; 286 if (variant != NormalVariant) { 287 characterFontData = characterFontData->variantFontData(description, variant); 288 ASSERT(characterFontData); 289 } 290 291 GlyphData data; 292 if (GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontData.get(), pageNumber)->page()) 293 data = fallbackPage->glyphDataForCharacter(c); 294 295 // Cache it so we don't have to do system fallback again next time. 296 if (variant == NormalVariant && data.glyph) { 297 node.page()->setGlyphDataForCharacter(c, data.glyph, data.fontData); 298 data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyphPageTreeLevel(), node.level())); 299 if (!Font::isCJKIdeographOrSymbol(c) && data.fontData->platformData().orientation() != Horizontal && !data.fontData->isTextOrientationFallback()) 300 return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, pageNumber); 301 } 302 return data; 303 } 304 305 GlyphData FontGlyphs::glyphDataForVariant(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned pageNumber, GlyphPageTreeNode*& node) 306 { 307 while (true) { 308 if (GlyphPage* page = node->page()) { 309 GlyphData data = page->glyphDataForCharacter(c); 310 if (data.fontData) { 311 // The variantFontData function should not normally return 0. 312 // But if it does, we will just render the capital letter big. 313 RefPtr<SimpleFontData> variantFontData = data.fontData->variantFontData(description, variant); 314 if (!variantFontData) 315 return data; 316 317 GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootChild(variantFontData.get(), pageNumber); 318 GlyphPage* variantPage = variantNode->page(); 319 if (variantPage) 320 return variantPage->glyphDataForCharacter(c); 321 322 // Do not attempt system fallback off the variantFontData. This is the very unlikely case that 323 // a font has the lowercase character but the small caps font does not have its uppercase version. 324 return GlyphData(); 333 334 ASSERT_NOT_REACHED(); 335 return GlyphData(); 336 } 337 338 static RefPtr<GlyphPage> glyphPageFromFontData(unsigned pageNumber, const FontData& fontData) 339 { 340 const SimpleFontData* simpleFontData = nullptr; 341 if (fontData.isSegmented()) { 342 UChar32 pageRangeFrom = pageNumber * GlyphPage::size; 343 UChar32 pageRangeTo = pageRangeFrom + GlyphPage::size - 1; 344 auto& segmentedFontData = downcast<SegmentedFontData>(fontData); 345 for (unsigned i = 0; i < segmentedFontData.numRanges(); ++i) { 346 auto& range = segmentedFontData.rangeAt(i); 347 if (range.to()) { 348 if (range.from() <= pageRangeFrom && pageRangeTo <= range.to()) 349 simpleFontData = range.fontData().get(); 350 break; 325 351 } 326 327 if (node->isSystemFallback())328 return glyphDataForSystemFallback(c, description, variant, pageNumber, *node);329 352 } 330 331 node = node->getChild(realizeFontDataAt(description, node->level()), pageNumber); 332 } 353 if (!simpleFontData) 354 return nullptr; 355 } else 356 simpleFontData = &downcast<SimpleFontData>(fontData); 357 358 if (simpleFontData->platformData().orientation() == Vertical) 359 return nullptr; 360 361 return const_cast<GlyphPage*>(simpleFontData->glyphPage(pageNumber)); 333 362 } 334 363 … … 352 381 c = u_charMirror(c); 353 382 354 const unsigned pageNumber = (c / GlyphPage::size);355 356 GlyphPageTreeNode*& node = pageNumber ? m_pages.add(pageNumber, nullptr).iterator->value : m_pageZero;357 if (!node)358 node = GlyphPageTreeNode::getRootChild(realizeFontDataAt(description, 0), pageNumber);359 360 383 if (variant != NormalVariant) 361 return glyphDataForVariant(c, description, variant, pageNumber, node); 362 363 while (true) { 364 if (GlyphPage* page = node->page()) { 365 GlyphData data = page->glyphDataForCharacter(c); 366 if (data.fontData) { 367 if (data.fontData->platformData().orientation() == Vertical && !data.fontData->isTextOrientationFallback()) { 368 if (!Font::isCJKIdeographOrSymbol(c)) 369 return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, pageNumber); 370 371 if (!data.fontData->hasVerticalGlyphs()) { 372 // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs 373 // to make sure you get a square (even for broken glyphs like symbols used for punctuation). 374 return glyphDataForVariant(c, description, BrokenIdeographVariant, pageNumber, node); 375 } 376 #if PLATFORM(COCOA) 377 if (data.fontData->platformData().syntheticOblique()) 378 return glyphDataForCJKCharacterWithoutSyntheticItalic(c, data, pageNumber); 379 #endif 380 } 381 382 return data; 383 } 384 385 if (node->isSystemFallback()) 386 return glyphDataForSystemFallback(c, description, variant, pageNumber, *node); 387 } 388 389 node = node->getChild(realizeFontDataAt(description, node->level()), pageNumber); 390 } 391 } 392 393 } 384 return glyphDataForVariant(c, description, variant, 0); 385 386 const unsigned pageNumber = c / GlyphPage::size; 387 388 RefPtr<GlyphPage>& cachedPage = pageNumber ? m_cachedPages.add(pageNumber, nullptr).iterator->value : m_cachedPageZero; 389 if (!cachedPage) 390 cachedPage = glyphPageFromFontData(pageNumber, *primaryFontData(description)); 391 392 GlyphData glyphData = cachedPage ? cachedPage->glyphDataForCharacter(c) : GlyphData(); 393 if (!glyphData.glyph) { 394 if (!cachedPage) 395 cachedPage = GlyphPage::createForMixedFontData(); 396 else if (cachedPage->isImmutable()) 397 cachedPage = GlyphPage::createCopyForMixedFontData(*cachedPage); 398 399 glyphData = glyphDataForNormalVariant(c, description); 400 cachedPage->setGlyphDataForCharacter(c, glyphData.glyph, glyphData.fontData); 401 } 402 return glyphData; 403 } 404 405 } -
trunk/Source/WebCore/platform/graphics/FontGlyphs.h
r177637 r177876 1 1 /* 2 * Copyright (C) 2006, 2010, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2006, 2010, 2013-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * This library is free software; you can redistribute it and/or … … 35 35 namespace WebCore { 36 36 37 class GlyphPageTreeNode;38 37 class GraphicsContext; 39 38 class IntRect; … … 47 46 WTF_MAKE_NONCOPYABLE(FontGlyphs); 48 47 public: 49 typedef HashMap<int, GlyphPageTreeNode*, DefaultHash<int>::Hash> GlyphPages;50 51 48 static Ref<FontGlyphs> create(PassRefPtr<FontSelector> fontSelector) { return adoptRef(*new FontGlyphs(fontSelector)); } 52 49 static Ref<FontGlyphs> createForPlatformFont(const FontPlatformData& platformData) { return adoptRef(*new FontGlyphs(platformData)); } … … 79 76 FontGlyphs(const FontPlatformData&); 80 77 81 GlyphData glyphDataForSystemFallback(UChar32, const FontDescription&, FontDataVariant, unsigned pageNumber, GlyphPageTreeNode&); 82 GlyphData glyphDataForVariant(UChar32, const FontDescription&, FontDataVariant, unsigned pageNumber, GlyphPageTreeNode*&); 78 GlyphData glyphDataForSystemFallback(UChar32, const FontDescription&, FontDataVariant); 79 GlyphData glyphDataForNormalVariant(UChar32, const FontDescription&); 80 GlyphData glyphDataForVariant(UChar32, const FontDescription&, FontDataVariant, unsigned fallbackLevel); 83 81 84 82 WEBCORE_EXPORT void releaseFontData(); 85 83 86 84 Vector<RefPtr<FontData>, 1> m_realizedFontData; 87 GlyphPages m_pages; 88 GlyphPageTreeNode* m_pageZero; 85 86 RefPtr<GlyphPage> m_cachedPageZero; 87 HashMap<int, RefPtr<GlyphPage>> m_cachedPages; 88 89 HashSet<RefPtr<SimpleFontData>> m_systemFallbackFontDataSet; 90 89 91 const SimpleFontData* m_cachedPrimarySimpleFontData; 90 92 RefPtr<FontSelector> m_fontSelector; … … 108 110 { 109 111 ASSERT(isMainThread()); 110 if (!m_cachedPrimarySimpleFontData) 111 m_cachedPrimarySimpleFontData = primaryFontData(description)->fontDataForCharacter(' '); 112 if (!m_cachedPrimarySimpleFontData) { 113 auto* fontData = primaryFontData(description); 114 m_cachedPrimarySimpleFontData = fontData->simpleFontDataForCharacter(' '); 115 if (!m_cachedPrimarySimpleFontData) 116 m_cachedPrimarySimpleFontData = &fontData->simpleFontDataForFirstRange(); 117 } 112 118 return m_cachedPrimarySimpleFontData; 113 119 } -
trunk/Source/WebCore/platform/graphics/GlyphPage.h
r176372 r177876 41 41 42 42 class SimpleFontData; 43 class GlyphPageTreeNode;44 43 45 44 // Holds the glyph index and the corresponding SimpleFontData information for a given … … 65 64 // 66 65 // One page may actually include glyphs from other fonts if the characters are 67 // missing in the primary font. It is owned by exactly one GlyphPageTreeNode, 68 // although multiple nodes may reference it as their "page" if they are supposed 69 // to be overriding the parent's node, but provide no additional information. 66 // missing in the primary font. 70 67 class GlyphPage : public RefCounted<GlyphPage> { 71 68 public: 72 static PassRefPtr<GlyphPage> createForMixedFontData( GlyphPageTreeNode* owner)69 static PassRefPtr<GlyphPage> createForMixedFontData() 73 70 { 74 71 void* slot = fastMalloc(sizeof(GlyphPage) + sizeof(SimpleFontData*) * GlyphPage::size); 75 return adoptRef(new (NotNull, slot) GlyphPage( owner));72 return adoptRef(new (NotNull, slot) GlyphPage(nullptr)); 76 73 } 77 74 78 static PassRefPtr<GlyphPage> create ForSingleFontData(GlyphPageTreeNode* owner, const SimpleFontData* fontData)75 static PassRefPtr<GlyphPage> createCopyForMixedFontData(const GlyphPage& original) 79 76 { 80 ASSERT(fontData); 81 return adoptRef(new GlyphPage(owner, fontData)); 82 } 83 84 PassRefPtr<GlyphPage> createCopiedSystemFallbackPage(GlyphPageTreeNode* owner) const 85 { 86 RefPtr<GlyphPage> page = GlyphPage::createForMixedFontData(owner); 87 memcpy(page->m_glyphs, m_glyphs, sizeof(m_glyphs)); 88 if (hasPerGlyphFontData()) 89 memcpy(page->m_perGlyphFontData, m_perGlyphFontData, sizeof(SimpleFontData*) * GlyphPage::size); 90 else { 91 for (size_t i = 0; i < GlyphPage::size; ++i) { 92 page->m_perGlyphFontData[i] = m_glyphs[i] ? m_fontDataForAllGlyphs : 0; 93 } 94 } 77 RefPtr<GlyphPage> page = createForMixedFontData(); 78 for (unsigned i = 0; i < GlyphPage::size; ++i) 79 page->setGlyphDataForIndex(i, original.glyphDataForIndex(i)); 95 80 return page.release(); 96 81 } 97 82 98 ~GlyphPage() { } 83 static PassRefPtr<GlyphPage> createForSingleFontData(const SimpleFontData* fontData) 84 { 85 ASSERT(fontData); 86 return adoptRef(new GlyphPage(fontData)); 87 } 88 89 ~GlyphPage() 90 { 91 --s_count; 92 } 93 94 bool isImmutable() const { return m_isImmutable; } 95 void setImmutable() { m_isImmutable = true; } 96 97 static unsigned count() { return s_count; } 99 98 100 99 static const size_t size = 256; // Covers Latin-1 in a single page. … … 138 137 { 139 138 ASSERT_WITH_SECURITY_IMPLICATION(index < size); 139 ASSERT(!m_isImmutable); 140 140 141 m_glyphs[index] = glyph; 141 142 … … 155 156 } 156 157 157 void removeFontDataFromSystemFallbackPage(const SimpleFontData* fontData)158 {159 // This method should only be called on the system fallback page, which is never single-font.160 ASSERT(hasPerGlyphFontData());161 for (size_t i = 0; i < size; ++i) {162 if (m_perGlyphFontData[i] == fontData) {163 m_glyphs[i] = 0;164 m_perGlyphFontData[i] = 0;165 }166 }167 }168 169 GlyphPageTreeNode* owner() const { return m_owner; }170 171 158 // Implemented by the platform. 172 159 bool fill(unsigned offset, unsigned length, UChar* characterBuffer, unsigned bufferLength, const SimpleFontData*); … … 178 165 179 166 private: 180 explicit GlyphPage( GlyphPageTreeNode* owner, const SimpleFontData* fontDataForAllGlyphs = 0)167 explicit GlyphPage(const SimpleFontData* fontDataForAllGlyphs) 181 168 : m_fontDataForAllGlyphs(fontDataForAllGlyphs) 182 , m_owner(owner)183 169 { 184 170 memset(m_glyphs, 0, sizeof(m_glyphs)); 185 171 if (hasPerGlyphFontData()) 186 172 memset(m_perGlyphFontData, 0, sizeof(SimpleFontData*) * GlyphPage::size); 173 ++s_count; 187 174 } 188 175 … … 190 177 191 178 const SimpleFontData* m_fontDataForAllGlyphs; 192 GlyphPageTreeNode* m_owner;193 179 Glyph m_glyphs[size]; 194 180 181 bool m_isImmutable { false }; 195 182 // NOTE: This array has (GlyphPage::size) elements if m_fontDataForAllGlyphs is null. 196 183 const SimpleFontData* m_perGlyphFontData[0]; 184 185 static unsigned s_count; 197 186 }; 198 187 -
trunk/Source/WebCore/platform/graphics/SegmentedFontData.cpp
r177847 r177876 1 1 /* 2 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2009, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "SegmentedFontData.h" 28 28 29 #include "GlyphPageTreeNode.h"30 29 #include "SimpleFontData.h" 31 30 #include <wtf/Assertions.h> … … 34 33 namespace WebCore { 35 34 35 SegmentedFontData::SegmentedFontData() 36 { 37 38 } 39 36 40 SegmentedFontData::~SegmentedFontData() 37 41 { 38 GlyphPageTreeNode::pruneTreeCustomFontData(this);39 42 } 40 43 41 const SimpleFontData* SegmentedFontData:: fontDataForCharacter(UChar32 c) const44 const SimpleFontData* SegmentedFontData::simpleFontDataForCharacter(UChar32 c) const 42 45 { 43 Vector<FontDataRange>::const_iterator end = m_ranges.end(); 44 for (Vector<FontDataRange>::const_iterator it = m_ranges.begin(); it != end; ++it) { 45 if (it->from() <= c && it->to() >= c) 46 return it->fontData().get(); 46 for (auto& range : m_ranges) { 47 if (range.from() <= c && c <= range.to()) 48 return range.fontData().get(); 47 49 } 48 return m_ranges[0].fontData().get(); 50 return nullptr; 51 } 52 53 const SimpleFontData& SegmentedFontData::simpleFontDataForFirstRange() const 54 { 55 return *m_ranges[0].fontData(); 49 56 } 50 57 … … 57 64 bool SegmentedFontData::isLoading() const 58 65 { 59 Vector<FontDataRange>::const_iterator end = m_ranges.end(); 60 for (Vector<FontDataRange>::const_iterator it = m_ranges.begin(); it != end; ++it) { 61 if (it->fontData()->isLoading()) 66 for (auto& range : m_ranges) { 67 if (range.fontData()->isLoading()) 62 68 return true; 63 69 } -
trunk/Source/WebCore/platform/graphics/SegmentedFontData.h
r177847 r177876 1 1 /* 2 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2009, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 68 68 69 69 private: 70 SegmentedFontData() { }70 SegmentedFontData(); 71 71 72 virtual const SimpleFontData* fontDataForCharacter(UChar32) const; 72 virtual const SimpleFontData* simpleFontDataForCharacter(UChar32) const override; 73 virtual const SimpleFontData& simpleFontDataForFirstRange() const override; 73 74 74 75 virtual bool isCustomFont() const; … … 76 77 virtual bool isSegmented() const; 77 78 79 RefPtr<SimpleFontData> m_nullFontData; 78 80 Vector<FontDataRange, 1> m_ranges; 79 81 }; -
trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp
r177637 r177876 1 1 /* 2 * Copyright (C) 2005, 2008, 2010 Apple Inc. All rights reserved.2 * Copyright (C) 2005, 2008, 2010, 2015 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2006 Alexey Proskuryakov 4 4 * … … 36 36 #include "Font.h" 37 37 #include "FontCache.h" 38 #include "GlyphPageTreeNode.h"39 38 #include "OpenTypeMathData.h" 40 39 #include <wtf/MathExtras.h> 40 #include <wtf/NeverDestroyed.h> 41 41 42 42 #if ENABLE(OPENTYPE_VERTICAL) … … 45 45 46 46 namespace WebCore { 47 48 unsigned GlyphPage::s_count = 0; 47 49 48 50 const float smallCapsFontSizeMultiplier = 0.7f; … … 98 100 void SimpleFontData::initCharWidths() 99 101 { 100 GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();102 auto* glyphPageZero = glyphPage(0); 101 103 102 104 // Treat the width of a '0' as the avgCharWidth. … … 118 120 void SimpleFontData::platformGlyphInit() 119 121 { 120 GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();122 auto* glyphPageZero = glyphPage(0); 121 123 if (!glyphPageZero) { 122 124 m_spaceGlyph = 0; … … 155 157 if (!m_fontData) 156 158 platformDestroy(); 157 158 if (isCustomFont()) 159 GlyphPageTreeNode::pruneTreeCustomFontData(this); 159 } 160 161 const SimpleFontData* SimpleFontData::simpleFontDataForCharacter(UChar32) const 162 { 163 return this; 164 } 165 166 const SimpleFontData& SimpleFontData::simpleFontDataForFirstRange() const 167 { 168 return *this; 169 } 170 171 static bool fillGlyphPage(GlyphPage& pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) 172 { 173 #if ENABLE(SVG_FONTS) 174 if (SimpleFontData::AdditionalFontData* additionalFontData = fontData->fontData()) 175 return additionalFontData->fillSVGGlyphPage(&pageToFill, offset, length, buffer, bufferLength, fontData); 176 #endif 177 bool hasGlyphs = pageToFill.fill(offset, length, buffer, bufferLength, fontData); 178 #if ENABLE(OPENTYPE_VERTICAL) 179 if (hasGlyphs && fontData->verticalData()) 180 fontData->verticalData()->substituteWithVerticalGlyphs(fontData, &pageToFill, offset, length); 181 #endif 182 return hasGlyphs; 183 } 184 185 static RefPtr<GlyphPage> createAndFillGlyphPage(unsigned pageNumber, const SimpleFontData* fontData) 186 { 187 #if PLATFORM(IOS) 188 // FIXME: Times New Roman contains Arabic glyphs, but Core Text doesn't know how to shape them. See <rdar://problem/9823975>. 189 // Once we have the fix for <rdar://problem/9823975> then remove this code together with SimpleFontData::shouldNotBeUsedForArabic() 190 // in <rdar://problem/12096835>. 191 if (pageNumber == 6 && shouldNotBeUsedForArabic()) 192 return nullptr; 193 #endif 194 195 unsigned start = pageNumber * GlyphPage::size; 196 UChar buffer[GlyphPage::size * 2 + 2]; 197 unsigned bufferLength; 198 // Fill in a buffer with the entire "page" of characters that we want to look up glyphs for. 199 if (start < 0x10000) { 200 bufferLength = GlyphPage::size; 201 for (unsigned i = 0; i < GlyphPage::size; i++) 202 buffer[i] = start + i; 203 204 if (start == 0) { 205 // Control characters must not render at all. 206 for (unsigned i = 0; i < 0x20; ++i) 207 buffer[i] = zeroWidthSpace; 208 for (unsigned i = 0x7F; i < 0xA0; i++) 209 buffer[i] = zeroWidthSpace; 210 buffer[softHyphen] = zeroWidthSpace; 211 212 // \n, \t, and nonbreaking space must render as a space. 213 buffer[(int)'\n'] = ' '; 214 buffer[(int)'\t'] = ' '; 215 buffer[noBreakSpace] = ' '; 216 } else if (start == (leftToRightMark & ~(GlyphPage::size - 1))) { 217 // LRM, RLM, LRE, RLE, ZWNJ, ZWJ, and PDF must not render at all. 218 buffer[leftToRightMark - start] = zeroWidthSpace; 219 buffer[rightToLeftMark - start] = zeroWidthSpace; 220 buffer[leftToRightEmbed - start] = zeroWidthSpace; 221 buffer[rightToLeftEmbed - start] = zeroWidthSpace; 222 buffer[leftToRightOverride - start] = zeroWidthSpace; 223 buffer[rightToLeftOverride - start] = zeroWidthSpace; 224 buffer[zeroWidthNonJoiner - start] = zeroWidthSpace; 225 buffer[zeroWidthJoiner - start] = zeroWidthSpace; 226 buffer[popDirectionalFormatting - start] = zeroWidthSpace; 227 } else if (start == (objectReplacementCharacter & ~(GlyphPage::size - 1))) { 228 // Object replacement character must not render at all. 229 buffer[objectReplacementCharacter - start] = zeroWidthSpace; 230 } else if (start == (zeroWidthNoBreakSpace & ~(GlyphPage::size - 1))) { 231 // ZWNBS/BOM must not render at all. 232 buffer[zeroWidthNoBreakSpace - start] = zeroWidthSpace; 233 } 234 } else { 235 bufferLength = GlyphPage::size * 2; 236 for (unsigned i = 0; i < GlyphPage::size; i++) { 237 int c = i + start; 238 buffer[i * 2] = U16_LEAD(c); 239 buffer[i * 2 + 1] = U16_TRAIL(c); 240 } 241 } 242 243 // Now that we have a buffer full of characters, we want to get back an array 244 // of glyph indices. This part involves calling into the platform-specific 245 // routine of our glyph map for actually filling in the page with the glyphs. 246 // Success is not guaranteed. For example, Times fails to fill page 260, giving glyph data 247 // for only 128 out of 256 characters. 248 RefPtr<GlyphPage> glyphPage; 249 if (GlyphPage::mayUseMixedFontDataWhenFilling(buffer, bufferLength, fontData)) 250 glyphPage = GlyphPage::createForMixedFontData(); 160 251 else 161 GlyphPageTreeNode::pruneTreeFontData(this); 162 } 163 164 const SimpleFontData* SimpleFontData::fontDataForCharacter(UChar32) const 165 { 166 return this; 252 glyphPage = GlyphPage::createForSingleFontData(fontData); 253 254 bool haveGlyphs = fillGlyphPage(*glyphPage, 0, GlyphPage::size, buffer, bufferLength, fontData); 255 if (!haveGlyphs) 256 return nullptr; 257 258 glyphPage->setImmutable(); 259 return glyphPage; 260 } 261 262 const GlyphPage* SimpleFontData::glyphPage(unsigned pageNumber) const 263 { 264 if (pageNumber == 0) { 265 if (!m_glyphPageZero) 266 m_glyphPageZero = createAndFillGlyphPage(0, this); 267 return m_glyphPageZero.get(); 268 } 269 auto addResult = m_glyphPages.add(pageNumber, nullptr); 270 if (addResult.isNewEntry) 271 addResult.iterator->value = createAndFillGlyphPage(pageNumber, this); 272 273 return addResult.iterator->value.get(); 167 274 } 168 275 169 276 Glyph SimpleFontData::glyphForCharacter(UChar32 character) const 170 277 { 171 GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(this, character / GlyphPage::size); 172 return node->page() ? node->page()->glyphAt(character % GlyphPage::size) : 0; 278 auto* page = glyphPage(character / GlyphPage::size); 279 if (!page) 280 return 0; 281 return page->glyphAt(character % GlyphPage::size); 282 } 283 284 GlyphData SimpleFontData::glyphDataForCharacter(UChar32 character) const 285 { 286 auto* page = glyphPage(character / GlyphPage::size); 287 if (!page) 288 return GlyphData(); 289 return page->glyphDataForCharacter(character); 173 290 } 174 291 … … 270 387 SimpleFontData::DerivedFontData::~DerivedFontData() 271 388 { 272 if (!forCustomFont)273 return;274 275 if (smallCaps)276 GlyphPageTreeNode::pruneTreeCustomFontData(smallCaps.get());277 if (emphasisMark)278 GlyphPageTreeNode::pruneTreeCustomFontData(emphasisMark.get());279 if (brokenIdeograph)280 GlyphPageTreeNode::pruneTreeCustomFontData(brokenIdeograph.get());281 if (verticalRightOrientation)282 GlyphPageTreeNode::pruneTreeCustomFontData(verticalRightOrientation.get());283 if (uprightOrientation)284 GlyphPageTreeNode::pruneTreeCustomFontData(uprightOrientation.get());285 389 #if PLATFORM(COCOA) 286 390 if (compositeFontReferences) { 391 // FIXME: Why don't we use WebKit types here? 287 392 CFDictionaryRef dictionary = CFDictionaryRef(compositeFontReferences.get()); 288 393 CFIndex count = CFDictionaryGetCount(dictionary); … … 291 396 SimpleFontData** fonts = stash.data(); 292 397 CFDictionaryGetKeysAndValues(dictionary, 0, (const void **)fonts); 293 while (count-- > 0 && *fonts) { 294 RefPtr<SimpleFontData> afont = adoptRef(*fonts++); 295 GlyphPageTreeNode::pruneTreeCustomFontData(afont.get()); 296 } 398 // This deletes the fonts. 399 while (count-- > 0 && *fonts) 400 adoptRef(*fonts++); 297 401 } 298 402 } … … 325 429 } 326 430 431 RefPtr<SimpleFontData> SimpleFontData::systemFallbackFontDataForCharacter(UChar32 c, const FontDescription& description, bool isForPlatformFont) const 432 { 433 UChar codeUnits[2]; 434 int codeUnitsLength; 435 if (c <= 0xFFFF) { 436 codeUnits[0] = Font::normalizeSpaces(c); 437 codeUnitsLength = 1; 438 } else { 439 codeUnits[0] = U16_LEAD(c); 440 codeUnits[1] = U16_TRAIL(c); 441 codeUnitsLength = 2; 442 } 443 444 return fontCache().systemFallbackForCharacters(description, this, isForPlatformFont, codeUnits, codeUnitsLength); 445 } 446 327 447 } // namespace WebCore -
trunk/Source/WebCore/platform/graphics/SimpleFontData.h
r177847 r177876 2 2 * This file is part of the internal font implementation. 3 3 * 4 * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved.4 * Copyright (C) 2006, 2008, 2010, 2015 Apple Inc. All rights reserved. 5 5 * Copyright (C) 2007-2008 Torch Mobile, Inc. 6 6 * … … 32 32 #include "GlyphBuffer.h" 33 33 #include "GlyphMetricsMap.h" 34 #include "GlyphPage.h" 34 35 #include "OpenTypeMathData.h" 35 36 #if ENABLE(OPENTYPE_VERTICAL) … … 166 167 void setZeroGlyph(Glyph zeroGlyph) { m_zeroGlyph = zeroGlyph; } 167 168 168 virtual const SimpleFontData* fontDataForCharacter(UChar32) const override; 169 169 GlyphData glyphDataForCharacter(UChar32) const; 170 170 Glyph glyphForCharacter(UChar32) const; 171 172 RefPtr<SimpleFontData> systemFallbackFontDataForCharacter(UChar32, const FontDescription&, bool isForPlatformFont) const; 173 174 const GlyphPage* glyphPage(unsigned pageNumber) const; 171 175 172 176 void determinePitch(); … … 227 231 PassRefPtr<SimpleFontData> platformCreateScaledFontData(const FontDescription&, float scaleFactor) const; 228 232 233 virtual const SimpleFontData* simpleFontDataForCharacter(UChar32) const override; 234 virtual const SimpleFontData& simpleFontDataForFirstRange() const override; 235 229 236 #if PLATFORM(WIN) 230 237 void initGDIFont(); … … 247 254 std::unique_ptr<AdditionalFontData> m_fontData; 248 255 256 mutable RefPtr<GlyphPage> m_glyphPageZero; 257 mutable HashMap<unsigned, RefPtr<GlyphPage>> m_glyphPages; 249 258 mutable std::unique_ptr<GlyphMetricsMap<FloatRect>> m_glyphToBoundsMap; 250 259 mutable GlyphMetricsMap<float> m_glyphToWidthMap; -
trunk/Source/WebCore/platform/graphics/freetype/GlyphPageTreeNodeFreeType.cpp
r165676 r177876 30 30 31 31 #include "config.h" 32 #include "GlyphPage TreeNode.h"32 #include "GlyphPage.h" 33 33 34 34 #include "SimpleFontData.h" -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm
r177689 r177876 83 83 _fontDescriptors.grow(index + 1); 84 84 85 const WebCore::SimpleFontData* fontData = _font->fontDataAt(index)->fontDataForCharacter(_character); 86 fontDescriptor = CTFontCopyFontDescriptor(fontData->platformData().ctFont()); 85 const WebCore::SimpleFontData* simpleFontData = _font->fontDataAt(index)->simpleFontDataForCharacter(_character); 86 if (!simpleFontData) 87 simpleFontData = &_font->fontDataAt(index)->simpleFontDataForFirstRange(); 88 fontDescriptor = CTFontCopyFontDescriptor(simpleFontData->platformData().ctFont()); 87 89 _fontDescriptors[index] = adoptCF(fontDescriptor); 88 90 return (id)fontDescriptor; … … 200 202 201 203 U16_GET(cp, 0, 0, length, baseCharacter); 202 fontData = m_font.fontDataAt(0)->fontDataForCharacter(baseCharacter); 204 fontData = m_font.fontDataAt(0)->simpleFontDataForCharacter(baseCharacter); 205 if (!fontData) 206 fontData = &m_font.fontDataAt(0)->simpleFontDataForFirstRange(); 203 207 204 208 RetainPtr<WebCascadeList> cascadeList = adoptNS([[WebCascadeList alloc] initWithFont:&m_font character:baseCharacter]); … … 255 259 unsigned i = 0; 256 260 for (const FontData* candidateFontData = m_font.fontDataAt(i); candidateFontData; candidateFontData = m_font.fontDataAt(++i)) { 257 runFontData = candidateFontData->fontDataForCharacter(baseCharacter); 261 runFontData = candidateFontData->simpleFontDataForCharacter(baseCharacter); 262 if (!runFontData) 263 continue; 258 264 RetainPtr<CFTypeRef> runFontEqualityObject = runFontData->platformData().objectForEqualityCheck(); 259 265 if (CFEqual(runFontEqualityObject.get(), runFontEqualityObject.get())) -
trunk/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
r170947 r177876 141 141 unsigned i = 0; 142 142 for (const FontData* fontData = fontDataAt(0); fontData; fontData = fontDataAt(++i)) { 143 const SimpleFontData* simpleFontData = fontData->fontDataForCharacter(baseCharacter); 143 const SimpleFontData* simpleFontData = fontData->simpleFontDataForCharacter(baseCharacter); 144 if (!simpleFontData) 145 continue; 144 146 #if PLATFORM(IOS) 145 147 if (baseCharacter >= 0x0600 && baseCharacter <= 0x06ff && simpleFontData->shouldNotBeUsedForArabic()) -
trunk/Source/WebCore/platform/graphics/mac/GlyphPageMac.cpp
r177858 r177876 28 28 29 29 #include "config.h" 30 #include "GlyphPage TreeNode.h"30 #include "GlyphPage.h" 31 31 32 32 #include "CoreGraphicsSPI.h" … … 81 81 } 82 82 } 83 } else if (!fontData->platformData().isCompositeFontReference() && ((fontData->platformData().widthVariant() == RegularWidth) ? CTFontGetVerticalGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength) 84 : CTFontGetGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength))) { 83 } else if (!fontData->platformData().isCompositeFontReference() && ((fontData->platformData().widthVariant() == RegularWidth) 84 ? CTFontGetVerticalGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength) 85 : CTFontGetGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength))) { 85 86 // When buffer consists of surrogate pairs, CTFontGetVerticalGlyphsForCharacters and CTFontGetGlyphsForCharacters 86 87 // place the glyphs at indices corresponding to the first character of each pair. -
trunk/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
r177847 r177876 36 36 #import "FontCache.h" 37 37 #import "FontDescription.h" 38 #import "GlyphPageTreeNode.h"39 38 #import "SharedBuffer.h" 40 39 #import "WebCoreSystemInterface.h" … … 223 222 // Measure the actual character "x", since it's possible for it to extend below the baseline, and we need the 224 223 // reported x-height to only include the portion of the glyph that is above the baseline. 225 GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page(); 226 NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0; 224 NSGlyph xGlyph = glyphForCharacter('x'); 227 225 if (xGlyph) 228 226 xHeight = -CGRectGetMinY(platformBoundsForGlyph(xGlyph)); -
trunk/Source/WebCore/platform/graphics/win/GlyphPageTreeNodeCGWin.cpp
r165676 r177876 28 28 29 29 #include "config.h" 30 #include "GlyphPage TreeNode.h"30 #include "GlyphPage.h" 31 31 32 32 #include "SimpleFontData.h" -
trunk/Source/WebCore/platform/graphics/win/GlyphPageTreeNodeCairoWin.cpp
r165676 r177876 28 28 29 29 #include "config.h" 30 #include "GlyphPage TreeNode.h"30 #include "GlyphPage.h" 31 31 32 32 #include "HWndDC.h" -
trunk/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
r177642 r177876 34 34 #include "FontCache.h" 35 35 #include "FontDescription.h" 36 #include "GlyphPage TreeNode.h"36 #include "GlyphPage.h" 37 37 #include "HWndDC.h" 38 38 #include <ApplicationServices/ApplicationServices.h> … … 90 90 m_fontMetrics.setLineSpacing(lroundf(fAscent) + lroundf(fDescent) + lroundf(fLineGap)); 91 91 92 GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page(); 93 Glyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0; 92 Glyph xGlyph = glyphDataForCharacter('x').glyph; 94 93 if (xGlyph) { 95 94 // Measure the actual character "x", since it's possible for it to extend below the baseline, and we need the -
trunk/Source/WebCore/platform/mac/DragImageMac.mm
r174623 r177876 273 273 DragImageRef createDragImageForLink(URL& url, const String& title, FontRenderingMode) 274 274 { 275 FontCachePurgePreventer fontCachePurgePreventer; 276 275 277 NSString *label = nsStringNilIfEmpty(title); 276 278 NSURL *cocoaURL = url; -
trunk/Source/WebCore/svg/SVGFontData.cpp
r177637 r177876 23 23 #include "SVGFontData.h" 24 24 25 #include "GlyphPage TreeNode.h"25 #include "GlyphPage.h" 26 26 #include "RenderElement.h" 27 27 #include "SVGAltGlyphElement.h" … … 75 75 float lineGap = 0.1f * fontSize; 76 76 77 GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(fontData, 0)->page();77 const GlyphPage* glyphPageZero = fontData->glyphPage(0); 78 78 79 79 if (!xHeight && glyphPageZero) { -
trunk/Source/WebCore/svg/SVGFontElement.cpp
r177316 r177876 28 28 #include "ElementIterator.h" 29 29 #include "Font.h" 30 #include "GlyphPageTreeNode.h"31 30 #include "SVGGlyphElement.h" 32 31 #include "SVGHKernElement.h" -
trunk/Source/WebKit/mac/Misc/WebCoreStatistics.mm
r175443 r177876 37 37 #import <WebCore/Frame.h> 38 38 #import <WebCore/GCController.h> 39 #import <WebCore/GlyphPage TreeNode.h>39 #import <WebCore/GlyphPage.h> 40 40 #import <WebCore/GraphicsContext.h> 41 41 #import <WebCore/IconDatabase.h> … … 163 163 + (size_t)glyphPageCount 164 164 { 165 return GlyphPage TreeNode::treeGlyphPageCount();165 return GlyphPage::count(); 166 166 } 167 167 -
trunk/Source/WebKit/win/WebCoreStatistics.cpp
r176892 r177876 32 32 #include <WebCore/FontCache.h> 33 33 #include <WebCore/GCController.h> 34 #include <WebCore/GlyphPage TreeNode.h>34 #include <WebCore/GlyphPage.h> 35 35 #include <WebCore/IconDatabase.h> 36 36 #include <WebCore/JSDOMWindow.h> … … 240 240 if (!count) 241 241 return E_POINTER; 242 *count = (UINT) GlyphPage TreeNode::treeGlyphPageCount();242 *count = (UINT) GlyphPage::count(); 243 243 return S_OK; 244 244 } -
trunk/Source/WebKit2/WebProcess/WebProcess.cpp
r177875 r177876 72 72 #include <WebCore/FrameLoader.h> 73 73 #include <WebCore/GCController.h> 74 #include <WebCore/GlyphPage TreeNode.h>74 #include <WebCore/GlyphPage.h> 75 75 #include <WebCore/IconDatabase.h> 76 76 #include <WebCore/JSDOMWindow.h> … … 932 932 933 933 // Gather glyph page statistics. 934 data.statisticsNumbers.set(ASCIILiteral("GlyphPageCount"), GlyphPage TreeNode::treeGlyphPageCount());934 data.statisticsNumbers.set(ASCIILiteral("GlyphPageCount"), GlyphPage::count()); 935 935 936 936 // Get WebCore memory cache statistics
Note: See TracChangeset
for help on using the changeset viewer.