18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * its contributors may be used to endorse or promote products derived 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * from this software without specific prior written permission. 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#ifndef GlyphMetricsMap_h 30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#define GlyphMetricsMap_h 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include <wtf/FixedArray.h> 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/HashMap.h> 348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <wtf/OwnPtr.h> 358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <wtf/unicode/Unicode.h> 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef unsigned short Glyph; 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockconst float cGlyphSizeUnknown = -1; 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochtemplate<class T> class GlyphMetricsMap { 44ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WTF_MAKE_NONCOPYABLE(GlyphMetricsMap); 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic: 46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GlyphMetricsMap() : m_filledPrimaryPage(false) { } 47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ~GlyphMetricsMap() 48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_pages) 50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block deleteAllValues(*m_pages); 51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 52dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 5321939df44de1705786c545cd1bf519d47250322dBen Murdoch T metricsForGlyph(Glyph glyph) 54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return locatePage(glyph / GlyphMetricsPage::size)->metricsForGlyph(glyph); 56dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5821939df44de1705786c545cd1bf519d47250322dBen Murdoch void setMetricsForGlyph(Glyph glyph, const T& metrics) 598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 60dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block locatePage(glyph / GlyphMetricsPage::size)->setMetricsForGlyph(glyph, metrics); 618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprivate: 64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block struct GlyphMetricsPage { 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static const size_t size = 256; // Usually covers Latin-1 in a single page. 66ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block FixedArray<T, size> m_metrics; 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6821939df44de1705786c545cd1bf519d47250322dBen Murdoch T metricsForGlyph(Glyph glyph) const { return m_metrics[glyph % size]; } 6921939df44de1705786c545cd1bf519d47250322dBen Murdoch void setMetricsForGlyph(Glyph glyph, const T& metrics) 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block setMetricsForIndex(glyph % size, metrics); 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7321939df44de1705786c545cd1bf519d47250322dBen Murdoch void setMetricsForIndex(unsigned index, const T& metrics) 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_metrics[index] = metrics; 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project }; 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GlyphMetricsPage* locatePage(unsigned pageNumber) 808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!pageNumber && m_filledPrimaryPage) 828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return &m_primaryPage; 838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return locatePageSlowCase(pageNumber); 848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GlyphMetricsPage* locatePageSlowCase(unsigned pageNumber); 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8821939df44de1705786c545cd1bf519d47250322dBen Murdoch static T unknownMetrics(); 8921939df44de1705786c545cd1bf519d47250322dBen Murdoch 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool m_filledPrimaryPage; 91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GlyphMetricsPage m_primaryPage; // We optimize for the page that contains glyph indices 0-255. 92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block OwnPtr<HashMap<int, GlyphMetricsPage*> > m_pages; 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9521939df44de1705786c545cd1bf519d47250322dBen Murdochtemplate<> inline float GlyphMetricsMap<float>::unknownMetrics() 9621939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 9721939df44de1705786c545cd1bf519d47250322dBen Murdoch return cGlyphSizeUnknown; 9821939df44de1705786c545cd1bf519d47250322dBen Murdoch} 9921939df44de1705786c545cd1bf519d47250322dBen Murdoch 10021939df44de1705786c545cd1bf519d47250322dBen Murdochtemplate<> inline FloatRect GlyphMetricsMap<FloatRect>::unknownMetrics() 10121939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 10221939df44de1705786c545cd1bf519d47250322dBen Murdoch return FloatRect(0, 0, cGlyphSizeUnknown, cGlyphSizeUnknown); 10321939df44de1705786c545cd1bf519d47250322dBen Murdoch} 10421939df44de1705786c545cd1bf519d47250322dBen Murdoch 10521939df44de1705786c545cd1bf519d47250322dBen Murdochtemplate<class T> typename GlyphMetricsMap<T>::GlyphMetricsPage* GlyphMetricsMap<T>::locatePageSlowCase(unsigned pageNumber) 10621939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 10721939df44de1705786c545cd1bf519d47250322dBen Murdoch GlyphMetricsPage* page; 10821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!pageNumber) { 10921939df44de1705786c545cd1bf519d47250322dBen Murdoch ASSERT(!m_filledPrimaryPage); 11021939df44de1705786c545cd1bf519d47250322dBen Murdoch page = &m_primaryPage; 11121939df44de1705786c545cd1bf519d47250322dBen Murdoch m_filledPrimaryPage = true; 11221939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 11321939df44de1705786c545cd1bf519d47250322dBen Murdoch if (m_pages) { 11421939df44de1705786c545cd1bf519d47250322dBen Murdoch if ((page = m_pages->get(pageNumber))) 11521939df44de1705786c545cd1bf519d47250322dBen Murdoch return page; 11621939df44de1705786c545cd1bf519d47250322dBen Murdoch } else 117e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_pages = adoptPtr(new HashMap<int, GlyphMetricsPage*>); 11821939df44de1705786c545cd1bf519d47250322dBen Murdoch page = new GlyphMetricsPage; 11921939df44de1705786c545cd1bf519d47250322dBen Murdoch m_pages->set(pageNumber, page); 12021939df44de1705786c545cd1bf519d47250322dBen Murdoch } 12121939df44de1705786c545cd1bf519d47250322dBen Murdoch 12221939df44de1705786c545cd1bf519d47250322dBen Murdoch // Fill in the whole page with the unknown glyph information. 12321939df44de1705786c545cd1bf519d47250322dBen Murdoch for (unsigned i = 0; i < GlyphMetricsPage::size; i++) 12421939df44de1705786c545cd1bf519d47250322dBen Murdoch page->setMetricsForIndex(i, unknownMetrics()); 12521939df44de1705786c545cd1bf519d47250322dBen Murdoch 12621939df44de1705786c545cd1bf519d47250322dBen Murdoch return page; 12721939df44de1705786c545cd1bf519d47250322dBen Murdoch} 12821939df44de1705786c545cd1bf519d47250322dBen Murdoch 129dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} // namespace WebCore 1308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 132