OLD | NEW |
---|---|
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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 | 78 |
79 | 79 |
80 static const unsigned cHarfBuzzCacheMaxSize = 256; | 80 static const unsigned cHarfBuzzCacheMaxSize = 256; |
81 | 81 |
82 struct CachedShapingResultsLRUNode; | 82 struct CachedShapingResultsLRUNode; |
83 struct CachedShapingResults; | 83 struct CachedShapingResults; |
84 typedef std::map<std::wstring, CachedShapingResults*> CachedShapingResultsMap; | 84 typedef std::map<std::wstring, CachedShapingResults*> CachedShapingResultsMap; |
85 typedef std::list<CachedShapingResultsLRUNode*> CachedShapingResultsLRU; | 85 typedef std::list<CachedShapingResultsLRUNode*> CachedShapingResultsLRU; |
86 | 86 |
87 struct CachedShapingResults { | 87 struct CachedShapingResults { |
88 CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Font* runFont, hb_di rection_t runDir); | 88 CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Font* runFont, hb_di rection_t runDir, String newLocale); |
89 ~CachedShapingResults(); | 89 ~CachedShapingResults(); |
90 | 90 |
91 hb_buffer_t* buffer; | 91 hb_buffer_t* buffer; |
92 Font font; | 92 Font font; |
93 hb_direction_t dir; | 93 hb_direction_t dir; |
94 String locale; | |
94 CachedShapingResultsLRU::iterator lru; | 95 CachedShapingResultsLRU::iterator lru; |
95 }; | 96 }; |
96 | 97 |
97 struct CachedShapingResultsLRUNode { | 98 struct CachedShapingResultsLRUNode { |
98 CachedShapingResultsLRUNode(const CachedShapingResultsMap::iterator& cacheEn try); | 99 CachedShapingResultsLRUNode(const CachedShapingResultsMap::iterator& cacheEn try); |
99 ~CachedShapingResultsLRUNode(); | 100 ~CachedShapingResultsLRUNode(); |
100 | 101 |
101 CachedShapingResultsMap::iterator entry; | 102 CachedShapingResultsMap::iterator entry; |
102 }; | 103 }; |
103 | 104 |
104 CachedShapingResults::CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Fo nt* fontData, hb_direction_t dirData) | 105 CachedShapingResults::CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Fo nt* fontData, hb_direction_t dirData, String newLocale) |
105 : buffer(harfBuzzBuffer) | 106 : buffer(harfBuzzBuffer) |
106 , font(*fontData) | 107 , font(*fontData) |
107 , dir(dirData) | 108 , dir(dirData) |
109 , locale(newLocale) | |
108 { | 110 { |
109 } | 111 } |
110 | 112 |
111 CachedShapingResults::~CachedShapingResults() | 113 CachedShapingResults::~CachedShapingResults() |
112 { | 114 { |
113 hb_buffer_destroy(buffer); | 115 hb_buffer_destroy(buffer); |
114 } | 116 } |
115 | 117 |
116 CachedShapingResultsLRUNode::CachedShapingResultsLRUNode(const CachedShapingResu ltsMap::iterator& cacheEntry) | 118 CachedShapingResultsLRUNode::CachedShapingResultsLRUNode(const CachedShapingResu ltsMap::iterator& cacheEntry) |
117 : entry(cacheEntry) | 119 : entry(cacheEntry) |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
784 // a copy of the string. | 786 // a copy of the string. |
785 COMPILE_ASSERT(sizeof(UChar) == sizeof(uint16_t), UChar_is_the_same_size_as_ uint16_t); | 787 COMPILE_ASSERT(sizeof(UChar) == sizeof(uint16_t), UChar_is_the_same_size_as_ uint16_t); |
786 return reinterpret_cast<const uint16_t*>(src); | 788 return reinterpret_cast<const uint16_t*>(src); |
787 } | 789 } |
788 | 790 |
789 bool HarfBuzzShaper::shapeHarfBuzzRuns() | 791 bool HarfBuzzShaper::shapeHarfBuzzRuns() |
790 { | 792 { |
791 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_ destroy); | 793 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_ destroy); |
792 | 794 |
793 HarfBuzzRunCache& runCache = harfBuzzRunCache(); | 795 HarfBuzzRunCache& runCache = harfBuzzRunCache(); |
796 const String localeStr = m_font->fontDescription().locale(); | |
794 | 797 |
795 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { | 798 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { |
796 unsigned runIndex = m_run.rtl() ? m_harfBuzzRuns.size() - i - 1 : i; | 799 unsigned runIndex = m_run.rtl() ? m_harfBuzzRuns.size() - i - 1 : i; |
797 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get(); | 800 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get(); |
798 const SimpleFontData* currentFontData = currentRun->fontData(); | 801 const SimpleFontData* currentFontData = currentRun->fontData(); |
799 if (currentFontData->isSVGFont()) | 802 if (currentFontData->isSVGFont()) |
800 return false; | 803 return false; |
801 | 804 |
802 FontPlatformData* platformData = const_cast<FontPlatformData*>(¤tF ontData->platformData()); | 805 FontPlatformData* platformData = const_cast<FontPlatformData*>(¤tF ontData->platformData()); |
803 HarfBuzzFace* face = platformData->harfBuzzFace(); | 806 HarfBuzzFace* face = platformData->harfBuzzFace(); |
804 if (!face) | 807 if (!face) |
805 return false; | 808 return false; |
806 | 809 hb_buffer_set_language(harfBuzzBuffer.get(), hb_language_from_string((co nst char*)(static_cast<const LChar *>(localeStr.characters8())), localeStr.lengt h())); |
bashi
2014/05/14 10:00:01
What happens when localeStr contains invalid value
h.joshi
2014/05/14 10:50:47
As by default its assigned to "en", so I feel it s
bashi
2014/05/14 11:32:27
What happens when the lang attribute is set and it
| |
807 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script()); | 810 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script()); |
808 hb_buffer_set_direction(harfBuzzBuffer.get(), currentRun->rtl() ? HB_DIR ECTION_RTL : HB_DIRECTION_LTR); | 811 hb_buffer_set_direction(harfBuzzBuffer.get(), currentRun->rtl() ? HB_DIR ECTION_RTL : HB_DIRECTION_LTR); |
809 | 812 |
810 hb_segment_properties_t props; | 813 hb_segment_properties_t props; |
811 hb_buffer_get_segment_properties(harfBuzzBuffer.get(), &props); | 814 hb_buffer_get_segment_properties(harfBuzzBuffer.get(), &props); |
812 | 815 |
813 const UChar* src = m_normalizedBuffer.get() + currentRun->startIndex(); | 816 const UChar* src = m_normalizedBuffer.get() + currentRun->startIndex(); |
814 std::wstring key(src, src + currentRun->numCharacters()); | 817 std::wstring key(src, src + currentRun->numCharacters()); |
815 | 818 |
816 CachedShapingResults* cachedResults = runCache.find(key); | 819 CachedShapingResults* cachedResults = runCache.find(key); |
817 if (cachedResults) { | 820 if (cachedResults) { |
818 if (cachedResults->dir == props.direction && cachedResults->font == *m_font) { | 821 if (cachedResults->dir == props.direction && cachedResults->font == *m_font && cachedResults->locale == localeStr) { |
819 currentRun->applyShapeResult(cachedResults->buffer); | 822 currentRun->applyShapeResult(cachedResults->buffer); |
820 setGlyphPositionsForHarfBuzzRun(currentRun, cachedResults->buffe r); | 823 setGlyphPositionsForHarfBuzzRun(currentRun, cachedResults->buffe r); |
821 | 824 |
822 hb_buffer_clear_contents(harfBuzzBuffer.get()); | 825 hb_buffer_clear_contents(harfBuzzBuffer.get()); |
823 | 826 |
824 runCache.moveToBack(cachedResults); | 827 runCache.moveToBack(cachedResults); |
825 | 828 |
826 continue; | 829 continue; |
827 } | 830 } |
828 | 831 |
(...skipping 15 matching lines...) Expand all Loading... | |
844 | 847 |
845 if (m_font->fontDescription().orientation() == Vertical) | 848 if (m_font->fontDescription().orientation() == Vertical) |
846 face->setScriptForVerticalGlyphSubstitution(harfBuzzBuffer.get()); | 849 face->setScriptForVerticalGlyphSubstitution(harfBuzzBuffer.get()); |
847 | 850 |
848 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(), hb_font_de stroy); | 851 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(), hb_font_de stroy); |
849 | 852 |
850 hb_shape(harfBuzzFont.get(), harfBuzzBuffer.get(), m_features.isEmpty() ? 0 : m_features.data(), m_features.size()); | 853 hb_shape(harfBuzzFont.get(), harfBuzzBuffer.get(), m_features.isEmpty() ? 0 : m_features.data(), m_features.size()); |
851 currentRun->applyShapeResult(harfBuzzBuffer.get()); | 854 currentRun->applyShapeResult(harfBuzzBuffer.get()); |
852 setGlyphPositionsForHarfBuzzRun(currentRun, harfBuzzBuffer.get()); | 855 setGlyphPositionsForHarfBuzzRun(currentRun, harfBuzzBuffer.get()); |
853 | 856 |
854 runCache.insert(key, new CachedShapingResults(harfBuzzBuffer.get(), m_fo nt, props.direction)); | 857 runCache.insert(key, new CachedShapingResults(harfBuzzBuffer.get(), m_fo nt, props.direction, localeStr)); |
855 | 858 |
856 harfBuzzBuffer.set(hb_buffer_create()); | 859 harfBuzzBuffer.set(hb_buffer_create()); |
857 } | 860 } |
858 | 861 |
859 return true; | 862 return true; |
860 } | 863 } |
861 | 864 |
862 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb _buffer_t* harfBuzzBuffer) | 865 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb _buffer_t* harfBuzzBuffer) |
863 { | 866 { |
864 const SimpleFontData* currentFontData = currentRun->fontData(); | 867 const SimpleFontData* currentFontData = currentRun->fontData(); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1110 if (!foundToX) | 1113 if (!foundToX) |
1111 toX = m_run.rtl() ? 0 : m_totalWidth; | 1114 toX = m_run.rtl() ? 0 : m_totalWidth; |
1112 | 1115 |
1113 // Using floorf() and roundf() as the same as mac port. | 1116 // Using floorf() and roundf() as the same as mac port. |
1114 if (fromX < toX) | 1117 if (fromX < toX) |
1115 return FloatRect(floorf(point.x() + fromX), point.y(), roundf(toX - from X), height); | 1118 return FloatRect(floorf(point.x() + fromX), point.y(), roundf(toX - from X), height); |
1116 return FloatRect(floorf(point.x() + toX), point.y(), roundf(fromX - toX), he ight); | 1119 return FloatRect(floorf(point.x() + toX), point.y(), roundf(fromX - toX), he ight); |
1117 } | 1120 } |
1118 | 1121 |
1119 } // namespace WebCore | 1122 } // namespace WebCore |
OLD | NEW |