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

Side by Side Diff: Source/platform/fonts/harfbuzz/HarfBuzzShaper.cpp

Issue 167703008: Remove HarfBuzzRun cache (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebase w/HEAD Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 Google Inc. All rights reserved. 2 * Copyright (c) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2013 BlackBerry Limited. All rights reserved. 3 * Copyright (C) 2013 BlackBerry Limited. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 (*m_destroy)(m_ptr); 71 (*m_destroy)(m_ptr);
72 } 72 }
73 73
74 T* get() { return m_ptr; } 74 T* get() { return m_ptr; }
75 void set(T* ptr) { m_ptr = ptr; } 75 void set(T* ptr) { m_ptr = ptr; }
76 private: 76 private:
77 T* m_ptr; 77 T* m_ptr;
78 DestroyFunction m_destroy; 78 DestroyFunction m_destroy;
79 }; 79 };
80 80
81
82 static const unsigned cHarfBuzzCacheMaxSize = 256;
83
84 struct CachedShapingResultsLRUNode;
85 struct CachedShapingResults;
86 typedef std::map<std::wstring, CachedShapingResults*> CachedShapingResultsMap;
87 typedef std::list<CachedShapingResultsLRUNode*> CachedShapingResultsLRU;
88
89 struct CachedShapingResults {
90 CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Font* runFont, hb_di rection_t runDir, const String& newLocale);
91 ~CachedShapingResults();
92
93 hb_buffer_t* buffer;
94 Font font;
95 hb_direction_t dir;
96 String locale;
97 CachedShapingResultsLRU::iterator lru;
98 };
99
100 struct CachedShapingResultsLRUNode {
101 CachedShapingResultsLRUNode(const CachedShapingResultsMap::iterator& cacheEn try);
102 ~CachedShapingResultsLRUNode();
103
104 CachedShapingResultsMap::iterator entry;
105 };
106
107 CachedShapingResults::CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Fo nt* fontData, hb_direction_t dirData, const String& newLocale)
108 : buffer(harfBuzzBuffer)
109 , font(*fontData)
110 , dir(dirData)
111 , locale(newLocale)
112 {
113 }
114
115 CachedShapingResults::~CachedShapingResults()
116 {
117 hb_buffer_destroy(buffer);
118 }
119
120 CachedShapingResultsLRUNode::CachedShapingResultsLRUNode(const CachedShapingResu ltsMap::iterator& cacheEntry)
121 : entry(cacheEntry)
122 {
123 }
124
125 CachedShapingResultsLRUNode::~CachedShapingResultsLRUNode()
126 {
127 }
128
129 class HarfBuzzRunCache {
130 public:
131 HarfBuzzRunCache();
132 ~HarfBuzzRunCache();
133
134 CachedShapingResults* find(const std::wstring& key) const;
135 void remove(CachedShapingResults* node);
136 void moveToBack(CachedShapingResults* node);
137 bool insert(const std::wstring& key, CachedShapingResults* run);
138
139 private:
140 CachedShapingResultsMap m_harfBuzzRunMap;
141 CachedShapingResultsLRU m_harfBuzzRunLRU;
142 };
143
144
145 HarfBuzzRunCache::HarfBuzzRunCache()
146 {
147 }
148
149 HarfBuzzRunCache::~HarfBuzzRunCache()
150 {
151 for (CachedShapingResultsMap::iterator it = m_harfBuzzRunMap.begin(); it != m_harfBuzzRunMap.end(); ++it)
152 delete it->second;
153 for (CachedShapingResultsLRU::iterator it = m_harfBuzzRunLRU.begin(); it != m_harfBuzzRunLRU.end(); ++it)
154 delete *it;
155 }
156
157 bool HarfBuzzRunCache::insert(const std::wstring& key, CachedShapingResults* dat a)
158 {
159 std::pair<CachedShapingResultsMap::iterator, bool> results =
160 m_harfBuzzRunMap.insert(CachedShapingResultsMap::value_type(key, data));
161
162 if (!results.second)
163 return false;
164
165 CachedShapingResultsLRUNode* node = new CachedShapingResultsLRUNode(results. first);
166
167 m_harfBuzzRunLRU.push_back(node);
168 data->lru = --m_harfBuzzRunLRU.end();
169
170 if (m_harfBuzzRunMap.size() > cHarfBuzzCacheMaxSize) {
171 CachedShapingResultsLRUNode* lru = m_harfBuzzRunLRU.front();
172 CachedShapingResults* foo = lru->entry->second;
173 m_harfBuzzRunMap.erase(lru->entry);
174 m_harfBuzzRunLRU.pop_front();
175 delete foo;
176 delete lru;
177 }
178
179 return true;
180 }
181
182 inline CachedShapingResults* HarfBuzzRunCache::find(const std::wstring& key) con st
183 {
184 CachedShapingResultsMap::const_iterator it = m_harfBuzzRunMap.find(key);
185
186 return it != m_harfBuzzRunMap.end() ? it->second : 0;
187 }
188
189 inline void HarfBuzzRunCache::remove(CachedShapingResults* node)
190 {
191 CachedShapingResultsLRUNode* lruNode = *node->lru;
192
193 m_harfBuzzRunLRU.erase(node->lru);
194 m_harfBuzzRunMap.erase(lruNode->entry);
195 delete lruNode;
196 delete node;
197 }
198
199 inline void HarfBuzzRunCache::moveToBack(CachedShapingResults* node)
200 {
201 CachedShapingResultsLRUNode* lruNode = *node->lru;
202 m_harfBuzzRunLRU.erase(node->lru);
203 m_harfBuzzRunLRU.push_back(lruNode);
204 node->lru = --m_harfBuzzRunLRU.end();
205 }
206
207 HarfBuzzRunCache& harfBuzzRunCache()
208 {
209 DEFINE_STATIC_LOCAL(HarfBuzzRunCache, globalHarfBuzzRunCache, ());
210 return globalHarfBuzzRunCache;
211 }
212
213 static inline float harfBuzzPositionToFloat(hb_position_t value) 81 static inline float harfBuzzPositionToFloat(hb_position_t value)
214 { 82 {
215 return static_cast<float>(value) / (1 << 16); 83 return static_cast<float>(value) / (1 << 16);
216 } 84 }
217 85
218 static inline unsigned countGraphemesInCluster(const UChar* normalizedBuffer, un signed normalizedBufferLength, uint16_t startIndex, uint16_t endIndex) 86 static inline unsigned countGraphemesInCluster(const UChar* normalizedBuffer, un signed normalizedBufferLength, uint16_t startIndex, uint16_t endIndex)
219 { 87 {
220 if (startIndex > endIndex) { 88 if (startIndex > endIndex) {
221 uint16_t tempIndex = startIndex; 89 uint16_t tempIndex = startIndex;
222 startIndex = endIndex; 90 startIndex = endIndex;
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 // current versions of all compilers we care about and avoids making 673 // current versions of all compilers we care about and avoids making
806 // a copy of the string. 674 // a copy of the string.
807 COMPILE_ASSERT(sizeof(UChar) == sizeof(uint16_t), UChar_is_the_same_size_as_ uint16_t); 675 COMPILE_ASSERT(sizeof(UChar) == sizeof(uint16_t), UChar_is_the_same_size_as_ uint16_t);
808 return reinterpret_cast<const uint16_t*>(src); 676 return reinterpret_cast<const uint16_t*>(src);
809 } 677 }
810 678
811 bool HarfBuzzShaper::shapeHarfBuzzRuns() 679 bool HarfBuzzShaper::shapeHarfBuzzRuns()
812 { 680 {
813 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_ destroy); 681 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_ destroy);
814 682
815 HarfBuzzRunCache& runCache = harfBuzzRunCache();
816 const FontDescription& fontDescription = m_font->fontDescription(); 683 const FontDescription& fontDescription = m_font->fontDescription();
817 const String& localeString = fontDescription.locale(); 684 const String& localeString = fontDescription.locale();
818 CString locale = localeString.latin1(); 685 CString locale = localeString.latin1();
819 686
820 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { 687 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) {
821 unsigned runIndex = m_run.rtl() ? m_harfBuzzRuns.size() - i - 1 : i; 688 unsigned runIndex = m_run.rtl() ? m_harfBuzzRuns.size() - i - 1 : i;
822 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get(); 689 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get();
823 const SimpleFontData* currentFontData = currentRun->fontData(); 690 const SimpleFontData* currentFontData = currentRun->fontData();
824 if (currentFontData->isSVGFont()) 691 if (currentFontData->isSVGFont())
825 return false; 692 return false;
826 693
827 FontPlatformData* platformData = const_cast<FontPlatformData*>(&currentF ontData->platformData()); 694 FontPlatformData* platformData = const_cast<FontPlatformData*>(&currentF ontData->platformData());
828 HarfBuzzFace* face = platformData->harfBuzzFace(); 695 HarfBuzzFace* face = platformData->harfBuzzFace();
829 if (!face) 696 if (!face)
830 return false; 697 return false;
831 698
832 hb_buffer_set_language(harfBuzzBuffer.get(), hb_language_from_string(loc ale.data(), locale.length())); 699 hb_buffer_set_language(harfBuzzBuffer.get(), hb_language_from_string(loc ale.data(), locale.length()));
833 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script()); 700 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script());
834 hb_buffer_set_direction(harfBuzzBuffer.get(), currentRun->rtl() ? HB_DIR ECTION_RTL : HB_DIRECTION_LTR); 701 hb_buffer_set_direction(harfBuzzBuffer.get(), currentRun->rtl() ? HB_DIR ECTION_RTL : HB_DIRECTION_LTR);
835 702
836 hb_segment_properties_t props; 703 hb_segment_properties_t props;
837 hb_buffer_get_segment_properties(harfBuzzBuffer.get(), &props); 704 hb_buffer_get_segment_properties(harfBuzzBuffer.get(), &props);
838 705
839 const UChar* src = m_normalizedBuffer.get() + currentRun->startIndex(); 706 const UChar* src = m_normalizedBuffer.get() + currentRun->startIndex();
840 std::wstring key(src, src + currentRun->numCharacters()); 707 std::wstring key(src, src + currentRun->numCharacters());
841 708
842 CachedShapingResults* cachedResults = runCache.find(key);
843 if (cachedResults) {
844 if (cachedResults->dir == props.direction && cachedResults->font == *m_font && cachedResults->locale == localeString) {
845 currentRun->applyShapeResult(cachedResults->buffer);
846 setGlyphPositionsForHarfBuzzRun(currentRun, cachedResults->buffe r);
847
848 hb_buffer_clear_contents(harfBuzzBuffer.get());
849
850 runCache.moveToBack(cachedResults);
851
852 continue;
853 }
854
855 runCache.remove(cachedResults);
856 }
857
858 // Add a space as pre-context to the buffer. This prevents showing dotte d-circle 709 // Add a space as pre-context to the buffer. This prevents showing dotte d-circle
859 // for combining marks at the beginning of runs. 710 // for combining marks at the beginning of runs.
860 static const uint16_t preContext = ' '; 711 static const uint16_t preContext = ' ';
861 hb_buffer_add_utf16(harfBuzzBuffer.get(), &preContext, 1, 1, 0); 712 hb_buffer_add_utf16(harfBuzzBuffer.get(), &preContext, 1, 1, 0);
862 713
863 if (fontDescription.variant() == FontVariantSmallCaps && u_islower(m_nor malizedBuffer[currentRun->startIndex()])) { 714 if (fontDescription.variant() == FontVariantSmallCaps && u_islower(m_nor malizedBuffer[currentRun->startIndex()])) {
864 String upperText = String(m_normalizedBuffer.get() + currentRun->sta rtIndex(), currentRun->numCharacters()).upper(); 715 String upperText = String(m_normalizedBuffer.get() + currentRun->sta rtIndex(), currentRun->numCharacters()).upper();
865 ASSERT(!upperText.is8Bit()); // m_normalizedBuffer is 16 bit, theref ore upperText is 16 bit, even after we call makeUpper(). 716 ASSERT(!upperText.is8Bit()); // m_normalizedBuffer is 16 bit, theref ore upperText is 16 bit, even after we call makeUpper().
866 hb_buffer_add_utf16(harfBuzzBuffer.get(), toUint16(upperText.charact ers16()), currentRun->numCharacters(), 0, currentRun->numCharacters()); 717 hb_buffer_add_utf16(harfBuzzBuffer.get(), toUint16(upperText.charact ers16()), currentRun->numCharacters(), 0, currentRun->numCharacters());
867 } else { 718 } else {
868 hb_buffer_add_utf16(harfBuzzBuffer.get(), toUint16(m_normalizedBuffe r.get() + currentRun->startIndex()), currentRun->numCharacters(), 0, currentRun- >numCharacters()); 719 hb_buffer_add_utf16(harfBuzzBuffer.get(), toUint16(m_normalizedBuffe r.get() + currentRun->startIndex()), currentRun->numCharacters(), 0, currentRun- >numCharacters());
869 } 720 }
870 721
871 if (fontDescription.orientation() == Vertical) 722 if (fontDescription.orientation() == Vertical)
872 face->setScriptForVerticalGlyphSubstitution(harfBuzzBuffer.get()); 723 face->setScriptForVerticalGlyphSubstitution(harfBuzzBuffer.get());
873 724
874 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(), hb_font_de stroy); 725 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(), hb_font_de stroy);
875 726
876 hb_shape(harfBuzzFont.get(), harfBuzzBuffer.get(), m_features.isEmpty() ? 0 : m_features.data(), m_features.size()); 727 hb_shape(harfBuzzFont.get(), harfBuzzBuffer.get(), m_features.isEmpty() ? 0 : m_features.data(), m_features.size());
877 currentRun->applyShapeResult(harfBuzzBuffer.get()); 728 currentRun->applyShapeResult(harfBuzzBuffer.get());
878 setGlyphPositionsForHarfBuzzRun(currentRun, harfBuzzBuffer.get()); 729 setGlyphPositionsForHarfBuzzRun(currentRun, harfBuzzBuffer.get());
879 730
880 runCache.insert(key, new CachedShapingResults(harfBuzzBuffer.get(), m_fo nt, props.direction, localeString));
881
882 harfBuzzBuffer.set(hb_buffer_create()); 731 harfBuzzBuffer.set(hb_buffer_create());
883 } 732 }
884 733
885 return true; 734 return true;
886 } 735 }
887 736
888 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb _buffer_t* harfBuzzBuffer) 737 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb _buffer_t* harfBuzzBuffer)
889 { 738 {
890 const SimpleFontData* currentFontData = currentRun->fontData(); 739 const SimpleFontData* currentFontData = currentRun->fontData();
891 hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(harfBuzzBuffer, 0); 740 hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(harfBuzzBuffer, 0);
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 point.x() + fromX, point.x() + toX, 990 point.x() + fromX, point.x() + toX,
1142 point.y(), height); 991 point.y(), height);
1143 } 992 }
1144 993
1145 return Font::pixelSnappedSelectionRect( 994 return Font::pixelSnappedSelectionRect(
1146 point.x() + toX, point.x() + fromX, 995 point.x() + toX, point.x() + fromX,
1147 point.y(), height); 996 point.y(), height);
1148 } 997 }
1149 998
1150 } // namespace blink 999 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698