| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 | 79 |
| 80 | 80 |
| 81 static const unsigned cHarfBuzzCacheMaxSize = 256; | 81 static const unsigned cHarfBuzzCacheMaxSize = 256; |
| 82 | 82 |
| 83 struct CachedShapingResultsLRUNode; | 83 struct CachedShapingResultsLRUNode; |
| 84 struct CachedShapingResults; | 84 struct CachedShapingResults; |
| 85 typedef std::map<std::wstring, CachedShapingResults*> CachedShapingResultsMap; | 85 typedef std::map<std::wstring, CachedShapingResults*> CachedShapingResultsMap; |
| 86 typedef std::list<CachedShapingResultsLRUNode*> CachedShapingResultsLRU; | 86 typedef std::list<CachedShapingResultsLRUNode*> CachedShapingResultsLRU; |
| 87 | 87 |
| 88 struct CachedShapingResults { | 88 struct CachedShapingResults { |
| 89 CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Font* runFont, hb_di
rection_t runDir); | 89 CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Font* runFont, hb_di
rection_t runDir, const String& newLocale); |
| 90 ~CachedShapingResults(); | 90 ~CachedShapingResults(); |
| 91 | 91 |
| 92 hb_buffer_t* buffer; | 92 hb_buffer_t* buffer; |
| 93 Font font; | 93 Font font; |
| 94 hb_direction_t dir; | 94 hb_direction_t dir; |
| 95 String locale; |
| 95 CachedShapingResultsLRU::iterator lru; | 96 CachedShapingResultsLRU::iterator lru; |
| 96 }; | 97 }; |
| 97 | 98 |
| 98 struct CachedShapingResultsLRUNode { | 99 struct CachedShapingResultsLRUNode { |
| 99 CachedShapingResultsLRUNode(const CachedShapingResultsMap::iterator& cacheEn
try); | 100 CachedShapingResultsLRUNode(const CachedShapingResultsMap::iterator& cacheEn
try); |
| 100 ~CachedShapingResultsLRUNode(); | 101 ~CachedShapingResultsLRUNode(); |
| 101 | 102 |
| 102 CachedShapingResultsMap::iterator entry; | 103 CachedShapingResultsMap::iterator entry; |
| 103 }; | 104 }; |
| 104 | 105 |
| 105 CachedShapingResults::CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Fo
nt* fontData, hb_direction_t dirData) | 106 CachedShapingResults::CachedShapingResults(hb_buffer_t* harfBuzzBuffer, const Fo
nt* fontData, hb_direction_t dirData, const String& newLocale) |
| 106 : buffer(harfBuzzBuffer) | 107 : buffer(harfBuzzBuffer) |
| 107 , font(*fontData) | 108 , font(*fontData) |
| 108 , dir(dirData) | 109 , dir(dirData) |
| 110 , locale(newLocale) |
| 109 { | 111 { |
| 110 } | 112 } |
| 111 | 113 |
| 112 CachedShapingResults::~CachedShapingResults() | 114 CachedShapingResults::~CachedShapingResults() |
| 113 { | 115 { |
| 114 hb_buffer_destroy(buffer); | 116 hb_buffer_destroy(buffer); |
| 115 } | 117 } |
| 116 | 118 |
| 117 CachedShapingResultsLRUNode::CachedShapingResultsLRUNode(const CachedShapingResu
ltsMap::iterator& cacheEntry) | 119 CachedShapingResultsLRUNode::CachedShapingResultsLRUNode(const CachedShapingResu
ltsMap::iterator& cacheEntry) |
| 118 : entry(cacheEntry) | 120 : entry(cacheEntry) |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 // a copy of the string. | 787 // a copy of the string. |
| 786 COMPILE_ASSERT(sizeof(UChar) == sizeof(uint16_t), UChar_is_the_same_size_as_
uint16_t); | 788 COMPILE_ASSERT(sizeof(UChar) == sizeof(uint16_t), UChar_is_the_same_size_as_
uint16_t); |
| 787 return reinterpret_cast<const uint16_t*>(src); | 789 return reinterpret_cast<const uint16_t*>(src); |
| 788 } | 790 } |
| 789 | 791 |
| 790 bool HarfBuzzShaper::shapeHarfBuzzRuns() | 792 bool HarfBuzzShaper::shapeHarfBuzzRuns() |
| 791 { | 793 { |
| 792 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_
destroy); | 794 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_
destroy); |
| 793 | 795 |
| 794 HarfBuzzRunCache& runCache = harfBuzzRunCache(); | 796 HarfBuzzRunCache& runCache = harfBuzzRunCache(); |
| 797 const FontDescription& fontDescription = m_font->fontDescription(); |
| 798 const String& localeString = fontDescription.locale(); |
| 799 CString locale = localeString.latin1(); |
| 795 | 800 |
| 796 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { | 801 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { |
| 797 unsigned runIndex = m_run.rtl() ? m_harfBuzzRuns.size() - i - 1 : i; | 802 unsigned runIndex = m_run.rtl() ? m_harfBuzzRuns.size() - i - 1 : i; |
| 798 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get(); | 803 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get(); |
| 799 const SimpleFontData* currentFontData = currentRun->fontData(); | 804 const SimpleFontData* currentFontData = currentRun->fontData(); |
| 800 if (currentFontData->isSVGFont()) | 805 if (currentFontData->isSVGFont()) |
| 801 return false; | 806 return false; |
| 802 | 807 |
| 803 FontPlatformData* platformData = const_cast<FontPlatformData*>(¤tF
ontData->platformData()); | 808 FontPlatformData* platformData = const_cast<FontPlatformData*>(¤tF
ontData->platformData()); |
| 804 HarfBuzzFace* face = platformData->harfBuzzFace(); | 809 HarfBuzzFace* face = platformData->harfBuzzFace(); |
| 805 if (!face) | 810 if (!face) |
| 806 return false; | 811 return false; |
| 807 | 812 |
| 813 hb_buffer_set_language(harfBuzzBuffer.get(), hb_language_from_string(loc
ale.data(), locale.length())); |
| 808 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script()); | 814 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script()); |
| 809 hb_buffer_set_direction(harfBuzzBuffer.get(), currentRun->rtl() ? HB_DIR
ECTION_RTL : HB_DIRECTION_LTR); | 815 hb_buffer_set_direction(harfBuzzBuffer.get(), currentRun->rtl() ? HB_DIR
ECTION_RTL : HB_DIRECTION_LTR); |
| 810 | 816 |
| 811 hb_segment_properties_t props; | 817 hb_segment_properties_t props; |
| 812 hb_buffer_get_segment_properties(harfBuzzBuffer.get(), &props); | 818 hb_buffer_get_segment_properties(harfBuzzBuffer.get(), &props); |
| 813 | 819 |
| 814 const UChar* src = m_normalizedBuffer.get() + currentRun->startIndex(); | 820 const UChar* src = m_normalizedBuffer.get() + currentRun->startIndex(); |
| 815 std::wstring key(src, src + currentRun->numCharacters()); | 821 std::wstring key(src, src + currentRun->numCharacters()); |
| 816 | 822 |
| 817 CachedShapingResults* cachedResults = runCache.find(key); | 823 CachedShapingResults* cachedResults = runCache.find(key); |
| 818 if (cachedResults) { | 824 if (cachedResults) { |
| 819 if (cachedResults->dir == props.direction && cachedResults->font ==
*m_font) { | 825 if (cachedResults->dir == props.direction && cachedResults->font ==
*m_font && cachedResults->locale == localeString) { |
| 820 currentRun->applyShapeResult(cachedResults->buffer); | 826 currentRun->applyShapeResult(cachedResults->buffer); |
| 821 setGlyphPositionsForHarfBuzzRun(currentRun, cachedResults->buffe
r); | 827 setGlyphPositionsForHarfBuzzRun(currentRun, cachedResults->buffe
r); |
| 822 | 828 |
| 823 hb_buffer_clear_contents(harfBuzzBuffer.get()); | 829 hb_buffer_clear_contents(harfBuzzBuffer.get()); |
| 824 | 830 |
| 825 runCache.moveToBack(cachedResults); | 831 runCache.moveToBack(cachedResults); |
| 826 | 832 |
| 827 continue; | 833 continue; |
| 828 } | 834 } |
| 829 | 835 |
| 830 runCache.remove(cachedResults); | 836 runCache.remove(cachedResults); |
| 831 } | 837 } |
| 832 | 838 |
| 833 // Add a space as pre-context to the buffer. This prevents showing dotte
d-circle | 839 // Add a space as pre-context to the buffer. This prevents showing dotte
d-circle |
| 834 // for combining marks at the beginning of runs. | 840 // for combining marks at the beginning of runs. |
| 835 static const uint16_t preContext = ' '; | 841 static const uint16_t preContext = ' '; |
| 836 hb_buffer_add_utf16(harfBuzzBuffer.get(), &preContext, 1, 1, 0); | 842 hb_buffer_add_utf16(harfBuzzBuffer.get(), &preContext, 1, 1, 0); |
| 837 | 843 |
| 838 if (m_font->fontDescription().variant() && u_islower(m_normalizedBuffer[
currentRun->startIndex()])) { | 844 if (fontDescription.variant() && u_islower(m_normalizedBuffer[currentRun
->startIndex()])) { |
| 839 String upperText = String(m_normalizedBuffer.get() + currentRun->sta
rtIndex(), currentRun->numCharacters()).upper(); | 845 String upperText = String(m_normalizedBuffer.get() + currentRun->sta
rtIndex(), currentRun->numCharacters()).upper(); |
| 840 ASSERT(!upperText.is8Bit()); // m_normalizedBuffer is 16 bit, theref
ore upperText is 16 bit, even after we call makeUpper(). | 846 ASSERT(!upperText.is8Bit()); // m_normalizedBuffer is 16 bit, theref
ore upperText is 16 bit, even after we call makeUpper(). |
| 841 hb_buffer_add_utf16(harfBuzzBuffer.get(), toUint16(upperText.charact
ers16()), currentRun->numCharacters(), 0, currentRun->numCharacters()); | 847 hb_buffer_add_utf16(harfBuzzBuffer.get(), toUint16(upperText.charact
ers16()), currentRun->numCharacters(), 0, currentRun->numCharacters()); |
| 842 } else { | 848 } else { |
| 843 hb_buffer_add_utf16(harfBuzzBuffer.get(), toUint16(m_normalizedBuffe
r.get() + currentRun->startIndex()), currentRun->numCharacters(), 0, currentRun-
>numCharacters()); | 849 hb_buffer_add_utf16(harfBuzzBuffer.get(), toUint16(m_normalizedBuffe
r.get() + currentRun->startIndex()), currentRun->numCharacters(), 0, currentRun-
>numCharacters()); |
| 844 } | 850 } |
| 845 | 851 |
| 846 if (m_font->fontDescription().orientation() == Vertical) | 852 if (fontDescription.orientation() == Vertical) |
| 847 face->setScriptForVerticalGlyphSubstitution(harfBuzzBuffer.get()); | 853 face->setScriptForVerticalGlyphSubstitution(harfBuzzBuffer.get()); |
| 848 | 854 |
| 849 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(), hb_font_de
stroy); | 855 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(), hb_font_de
stroy); |
| 850 | 856 |
| 851 hb_shape(harfBuzzFont.get(), harfBuzzBuffer.get(), m_features.isEmpty()
? 0 : m_features.data(), m_features.size()); | 857 hb_shape(harfBuzzFont.get(), harfBuzzBuffer.get(), m_features.isEmpty()
? 0 : m_features.data(), m_features.size()); |
| 852 currentRun->applyShapeResult(harfBuzzBuffer.get()); | 858 currentRun->applyShapeResult(harfBuzzBuffer.get()); |
| 853 setGlyphPositionsForHarfBuzzRun(currentRun, harfBuzzBuffer.get()); | 859 setGlyphPositionsForHarfBuzzRun(currentRun, harfBuzzBuffer.get()); |
| 854 | 860 |
| 855 runCache.insert(key, new CachedShapingResults(harfBuzzBuffer.get(), m_fo
nt, props.direction)); | 861 runCache.insert(key, new CachedShapingResults(harfBuzzBuffer.get(), m_fo
nt, props.direction, localeString)); |
| 856 | 862 |
| 857 harfBuzzBuffer.set(hb_buffer_create()); | 863 harfBuzzBuffer.set(hb_buffer_create()); |
| 858 } | 864 } |
| 859 | 865 |
| 860 return true; | 866 return true; |
| 861 } | 867 } |
| 862 | 868 |
| 863 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb
_buffer_t* harfBuzzBuffer) | 869 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb
_buffer_t* harfBuzzBuffer) |
| 864 { | 870 { |
| 865 const SimpleFontData* currentFontData = currentRun->fontData(); | 871 const SimpleFontData* currentFontData = currentRun->fontData(); |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 point.x() + fromX, point.x() + toX, | 1122 point.x() + fromX, point.x() + toX, |
| 1117 point.y(), height); | 1123 point.y(), height); |
| 1118 } | 1124 } |
| 1119 | 1125 |
| 1120 return Font::pixelSnappedSelectionRect( | 1126 return Font::pixelSnappedSelectionRect( |
| 1121 point.x() + toX, point.x() + fromX, | 1127 point.x() + toX, point.x() + fromX, |
| 1122 point.y(), height); | 1128 point.y(), height); |
| 1123 } | 1129 } |
| 1124 | 1130 |
| 1125 } // namespace WebCore | 1131 } // namespace WebCore |
| OLD | NEW |