00001 /* 00002 * Copyright (C) 2006, 2007 Apple Computer, Inc. All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions 00006 * are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 00014 * its contributors may be used to endorse or promote products derived 00015 * from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 00018 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00019 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00020 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 00021 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00022 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00023 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00024 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00029 #ifndef BTGlyphPageTreeNode_h 00030 #define BTGlyphPageTreeNode_h 00031 00032 #include "Shared.h" 00033 #include <wtf/unicode/Unicode.h> 00034 #include <wtf/Noncopyable.h> 00035 #include <wtf/HashMap.h> 00036 00037 namespace WebCore { 00038 00039 #ifndef __OWB__ 00040 class FontData; 00041 class GlyphPageTreeNode; 00042 #endif 00043 00044 #ifdef __OWB__ 00045 } 00046 00047 using WebCore::Shared; 00048 00049 namespace BAL { 00050 00051 class BTFontData; 00052 class GlyphPageTreeNode; 00053 00054 #endif //__OWB__ 00055 typedef unsigned short Glyph; 00056 00057 // Holds the glyph index and the corresponding FontData information for a given 00058 // character. 00059 struct GlyphData { 00060 Glyph glyph; 00061 const BTFontData* fontData; 00062 }; 00063 00064 // A GlyphPage contains a fixed-size set of GlyphData mappings for a contiguous 00065 // range of characters in the Unicode code space. GlyphPages are indexed 00066 // starting from 0 and incrementing for each 256 glyphs. 00067 // 00068 // One page may actually include glyphs from other fonts if the characters are 00069 // missing in the parimary font. It is owned by exactly one GlyphPageTreeNode, 00070 // although multiple nodes may reference it as their "page" if they are supposed 00071 // to be overriding the parent's node, but provide no additional information. 00072 00073 struct BTGlyphPage : public Shared<BTGlyphPage> { 00074 BTGlyphPage() 00075 : m_owner(0) 00076 { 00077 } 00078 00079 BTGlyphPage(GlyphPageTreeNode* owner) 00080 : m_owner(owner) 00081 { 00082 } 00083 00084 static const size_t size = 256; // Covers Latin-1 in a single page. 00085 GlyphData m_glyphs[size]; 00086 GlyphPageTreeNode* m_owner; 00087 00088 const GlyphData& glyphDataForCharacter(UChar32 c) const { return m_glyphs[c % size]; } 00089 void setGlyphDataForCharacter(UChar32 c, Glyph g, const BTFontData* f) 00090 { 00091 setGlyphDataForIndex(c % size, g, f); 00092 } 00093 void setGlyphDataForIndex(unsigned index, Glyph g, const BTFontData* f) 00094 { 00095 m_glyphs[index].glyph = g; 00096 m_glyphs[index].fontData = f; 00097 } 00098 GlyphPageTreeNode* owner() const { return m_owner; } 00099 // Implemented by the platform. 00100 bool fill(UChar* characterBuffer, unsigned bufferLength, const BTFontData* fontData); 00101 }; 00102 00103 // The glyph page tree is a data structure that maps (FontData, glyph page number) 00104 // to a GlyphPage. Level 0 (the "root") is special. There is one root 00105 // GlyphPageTreeNode for each glyph page number. The roots do not have a 00106 // GlyphPage associated with them, and their initializePage() function is never 00107 // called to fill the glyphs. 00108 // 00109 // Each root node maps a FontData pointer to another GlyphPageTreeNode at 00110 // level 1 (the "root child") that stores the actual glyphs for a specific font data. 00111 // These nodes will only have a GlyphPage if they have glyphs for that range. 00112 // 00113 // Levels greater than one correspond to subsequent levels of the fallback list 00114 // for that font. These levels override their parent's page of glyphs by 00115 // filling in holes with the new font (thus making a more complete page). 00116 // 00117 // A NULL FontData pointer corresponds to the system fallback 00118 // font. It is tracked separately from the regular pages and overrides so that 00119 // the glyph pages do not get polluted with these last-resort glyphs. The 00120 // system fallback page is not populated at construction like the other pages, 00121 // but on demand for each glyph, because the system may need to use different 00122 // fallback fonts for each. This lazy population is done by the Font. 00123 class GlyphPageTreeNode { 00124 public: 00125 GlyphPageTreeNode() 00126 : m_parent(0) 00127 , m_level(0) 00128 , m_isSystemFallback(false) 00129 , m_systemFallbackChild(0) 00130 , m_customFontCount(0) 00131 #ifndef NDEBUG 00132 , m_pageNumber(0) 00133 #endif 00134 { 00135 } 00136 00137 ~GlyphPageTreeNode(); 00138 00139 static HashMap<int, GlyphPageTreeNode*>* roots; 00140 static GlyphPageTreeNode* pageZeroRoot; 00141 00142 static GlyphPageTreeNode* getRootChild(const BTFontData* fontData, unsigned pageNumber) 00143 { 00144 return getRoot(pageNumber)->getChild(fontData, pageNumber); 00145 } 00146 00147 static void pruneTreeCustomFontData(const BTFontData*); 00148 00149 void pruneCustomFontData(const BTFontData*); 00150 00151 GlyphPageTreeNode* parent() const { return m_parent; } 00152 GlyphPageTreeNode* getChild(const BTFontData*, unsigned pageNumber); 00153 00154 // Returns a page of glyphs (or NULL if there are no glyphs in this page's character range). 00155 BTGlyphPage* page() const { return m_page.get(); } 00156 00157 // Returns the level of this node. See class-level comment. 00158 unsigned level() const { return m_level; } 00159 00160 // The system fallback font has special rules (see above). 00161 bool isSystemFallback() const { return m_isSystemFallback; } 00162 00163 private: 00164 static GlyphPageTreeNode* getRoot(unsigned pageNumber); 00165 void initializePage(const BTFontData*, unsigned pageNumber); 00166 00167 GlyphPageTreeNode* m_parent; 00168 RefPtr<BTGlyphPage> m_page; 00169 unsigned m_level; 00170 bool m_isSystemFallback; 00171 HashMap<const BTFontData*, GlyphPageTreeNode*> m_children; 00172 GlyphPageTreeNode* m_systemFallbackChild; 00173 unsigned m_customFontCount; 00174 00175 #ifndef NDEBUG 00176 unsigned m_pageNumber; 00177 #endif 00178 }; 00179 00180 } // namespace WebCore 00181 00182 #endif // BTGlyphPageTreeNode_h