1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "config.h" 6 #include "platform/fonts/GlyphPageTreeNode.h" 7 8 #include "platform/fonts/SegmentedFontData.h" 9 #include "platform/fonts/SimpleFontData.h" 10 #include <gtest/gtest.h> 11 12 namespace blink { 13 14 class TestCustomFontData : public CustomFontData { 15 public: 16 static PassRefPtr<TestCustomFontData> create() { return adoptRef(new TestCustomFontData()); } 17 private: 18 TestCustomFontData() { } 19 virtual bool isLoadingFallback() const OVERRIDE { return true; } 20 }; 21 22 class TestSimpleFontData : public SimpleFontData { 23 public: 24 static PassRefPtr<TestSimpleFontData> create(UChar32 from, UChar32 to) 25 { 26 return adoptRef(new TestSimpleFontData(nullptr, from, to)); 27 } 28 29 static PassRefPtr<TestSimpleFontData> createUnloaded(UChar32 from, UChar32 to) 30 { 31 return adoptRef(new TestSimpleFontData(TestCustomFontData::create(), from, to)); 32 } 33 34 private: 35 TestSimpleFontData(PassRefPtr<CustomFontData> customData, UChar32 from, UChar32 to) 36 : SimpleFontData(customData, 10, false, false) 37 , m_from(from) 38 , m_to(to) 39 { 40 } 41 42 bool fillGlyphPage(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength) const OVERRIDE 43 { 44 const Glyph kGlyph = 1; 45 String bufferString(buffer, bufferLength); 46 unsigned bufferIndex = 0; 47 bool hasGlyphs = false; 48 for (unsigned i = 0; i < length; i++) { 49 UChar32 c = bufferString.characterStartingAt(bufferIndex); 50 bufferIndex += U16_LENGTH(c); 51 if (m_from <= c && c <= m_to) { 52 pageToFill->setGlyphDataForIndex(offset + i, kGlyph, this); 53 hasGlyphs = true; 54 } 55 } 56 return hasGlyphs; 57 } 58 59 UChar32 m_from; 60 UChar32 m_to; 61 }; 62 63 TEST(GlyphPageTreeNode, rootChild) 64 { 65 const unsigned kPageNumber = 0; 66 size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount(); 67 { 68 RefPtr<TestSimpleFontData> data = TestSimpleFontData::create('a', 'z'); 69 GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(data.get(), kPageNumber); 70 EXPECT_EQ(pageCountBeforeTest + 1, GlyphPageTreeNode::treeGlyphPageCount()); 71 EXPECT_TRUE(node->page()->glyphAt('a')); 72 EXPECT_FALSE(node->page()->glyphAt('A')); 73 EXPECT_FALSE(node->isSystemFallback()); 74 EXPECT_EQ(1u, node->level()); 75 EXPECT_EQ(node, node->page()->owner()); 76 } 77 EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount()); 78 } 79 80 TEST(GlyphPageTreeNode, level2) 81 { 82 const unsigned kPageNumber = 0; 83 size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount(); 84 { 85 RefPtr<TestSimpleFontData> dataAtoC = TestSimpleFontData::create('A', 'C'); 86 RefPtr<TestSimpleFontData> dataCtoE = TestSimpleFontData::create('C', 'E'); 87 GlyphPageTreeNode* node1 = GlyphPageTreeNode::getRootChild(dataAtoC.get(), kPageNumber); 88 GlyphPageTreeNode* node2 = node1->getChild(dataCtoE.get(), kPageNumber); 89 EXPECT_EQ(pageCountBeforeTest + 3, GlyphPageTreeNode::treeGlyphPageCount()); 90 91 EXPECT_EQ(2u, node2->level()); 92 EXPECT_EQ(dataAtoC, node2->page()->glyphDataForCharacter('A').fontData); 93 EXPECT_EQ(dataAtoC, node2->page()->glyphDataForCharacter('C').fontData); 94 EXPECT_EQ(dataCtoE, node2->page()->glyphDataForCharacter('E').fontData); 95 } 96 EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount()); 97 } 98 99 TEST(GlyphPageTreeNode, segmentedData) 100 { 101 const unsigned kPageNumber = 0; 102 size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount(); 103 { 104 RefPtr<TestSimpleFontData> dataBtoC = TestSimpleFontData::create('B', 'C'); 105 RefPtr<TestSimpleFontData> dataCtoE = TestSimpleFontData::create('C', 'E'); 106 RefPtr<SegmentedFontData> segmentedData = SegmentedFontData::create(); 107 segmentedData->appendRange(FontDataRange('A', 'C', dataBtoC)); 108 segmentedData->appendRange(FontDataRange('C', 'D', dataCtoE)); 109 GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(segmentedData.get(), kPageNumber); 110 111 EXPECT_EQ(0, node->page()->glyphDataForCharacter('A').fontData); 112 EXPECT_EQ(dataBtoC, node->page()->glyphDataForCharacter('B').fontData); 113 EXPECT_EQ(dataBtoC, node->page()->glyphDataForCharacter('C').fontData); 114 EXPECT_EQ(dataCtoE, node->page()->glyphDataForCharacter('D').fontData); 115 EXPECT_EQ(0, node->page()->glyphDataForCharacter('E').fontData); 116 } 117 EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount()); 118 } 119 120 TEST(GlyphPageTreeNode, outsideBMP) 121 { 122 const unsigned kPageNumber = 0x1f300 / GlyphPage::size; 123 size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount(); 124 { 125 RefPtr<TestSimpleFontData> data = TestSimpleFontData::create(0x1f310, 0x1f320); 126 GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(data.get(), kPageNumber); 127 EXPECT_EQ(pageCountBeforeTest + 1, GlyphPageTreeNode::treeGlyphPageCount()); 128 EXPECT_FALSE(node->page()->glyphForCharacter(0x1f30f)); 129 EXPECT_TRUE(node->page()->glyphForCharacter(0x1f310)); 130 EXPECT_TRUE(node->page()->glyphForCharacter(0x1f320)); 131 EXPECT_FALSE(node->page()->glyphForCharacter(0x1f321)); 132 } 133 EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount()); 134 } 135 136 TEST(GlyphPageTreeNode, customData) 137 { 138 const unsigned kPageNumber = 0; 139 size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount(); 140 { 141 RefPtr<TestSimpleFontData> dataAtoC = TestSimpleFontData::createUnloaded('A', 'C'); 142 RefPtr<TestSimpleFontData> dataBtoD = TestSimpleFontData::create('B', 'D'); 143 RefPtr<TestSimpleFontData> dataCtoE = TestSimpleFontData::createUnloaded('C', 'E'); 144 RefPtr<SegmentedFontData> segmentedData = SegmentedFontData::create(); 145 segmentedData->appendRange(FontDataRange('A', 'C', dataAtoC)); 146 segmentedData->appendRange(FontDataRange('B', 'D', dataBtoD)); 147 segmentedData->appendRange(FontDataRange('C', 'E', dataCtoE)); 148 GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(segmentedData.get(), kPageNumber); 149 150 EXPECT_EQ(0, node->page()->glyphDataForCharacter('A').fontData); 151 EXPECT_EQ(dataBtoD, node->page()->glyphDataForCharacter('B').fontData); 152 EXPECT_EQ(dataBtoD, node->page()->glyphDataForCharacter('C').fontData); 153 EXPECT_EQ(dataBtoD, node->page()->glyphDataForCharacter('D').fontData); 154 EXPECT_EQ(0, node->page()->glyphDataForCharacter('E').fontData); 155 156 EXPECT_EQ(dataAtoC->customFontData(), node->page()->customFontToLoadAt('A')); 157 EXPECT_EQ(dataAtoC->customFontData(), node->page()->customFontToLoadAt('B')); 158 EXPECT_EQ(dataAtoC->customFontData(), node->page()->customFontToLoadAt('C')); 159 EXPECT_EQ(0, node->page()->customFontToLoadAt('D')); 160 EXPECT_EQ(dataCtoE->customFontData(), node->page()->customFontToLoadAt('E')); 161 } 162 EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount()); 163 } 164 165 TEST(GlyphPageTreeNode, customDataWithMultiplePages) 166 { 167 const unsigned kPageNumber = 0; 168 size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount(); 169 { 170 RefPtr<TestSimpleFontData> dataAtoC = TestSimpleFontData::createUnloaded('A', 'C'); 171 RefPtr<TestSimpleFontData> dataBtoD = TestSimpleFontData::create('B', 'D'); 172 RefPtr<TestSimpleFontData> dataCtoE = TestSimpleFontData::createUnloaded('C', 'E'); 173 RefPtr<SegmentedFontData> segmentedData1 = SegmentedFontData::create(); 174 RefPtr<SegmentedFontData> segmentedData2 = SegmentedFontData::create(); 175 RefPtr<SegmentedFontData> segmentedData3 = SegmentedFontData::create(); 176 segmentedData1->appendRange(FontDataRange('A', 'C', dataAtoC)); 177 segmentedData2->appendRange(FontDataRange('B', 'D', dataBtoD)); 178 segmentedData3->appendRange(FontDataRange('C', 'E', dataCtoE)); 179 GlyphPageTreeNode* node1 = GlyphPageTreeNode::getRootChild(segmentedData1.get(), kPageNumber); 180 GlyphPageTreeNode* node2 = node1->getChild(segmentedData2.get(), kPageNumber); 181 GlyphPageTreeNode* node3 = node2->getChild(segmentedData3.get(), kPageNumber); 182 183 EXPECT_EQ(0, node3->page()->glyphDataForCharacter('A').fontData); 184 EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('B').fontData); 185 EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('C').fontData); 186 EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('D').fontData); 187 EXPECT_EQ(0, node3->page()->glyphDataForCharacter('E').fontData); 188 189 EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('A')); 190 EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('B')); 191 EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('C')); 192 EXPECT_EQ(0, node3->page()->customFontToLoadAt('D')); 193 EXPECT_EQ(dataCtoE->customFontData(), node3->page()->customFontToLoadAt('E')); 194 } 195 EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount()); 196 } 197 198 TEST(GlyphPageTreeNode, systemFallback) 199 { 200 const unsigned kPageNumber = 0; 201 size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount(); 202 { 203 RefPtr<TestSimpleFontData> dataAtoC = TestSimpleFontData::createUnloaded('A', 'C'); 204 RefPtr<TestSimpleFontData> dataBtoD = TestSimpleFontData::create('B', 'D'); 205 RefPtr<SegmentedFontData> segmentedData = SegmentedFontData::create(); 206 segmentedData->appendRange(FontDataRange('A', 'C', dataAtoC)); 207 GlyphPageTreeNode* node1 = GlyphPageTreeNode::getRootChild(segmentedData.get(), kPageNumber); 208 GlyphPageTreeNode* node2 = node1->getChild(dataBtoD.get(), kPageNumber); 209 GlyphPageTreeNode* node3 = node2->getChild(0, kPageNumber); 210 211 EXPECT_TRUE(node3->isSystemFallback()); 212 213 EXPECT_EQ(0, node3->page()->glyphDataForCharacter('A').fontData); 214 EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('B').fontData); 215 EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('C').fontData); 216 EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('D').fontData); 217 218 EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('A')); 219 EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('B')); 220 EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('C')); 221 EXPECT_EQ(0, node3->page()->customFontToLoadAt('D')); 222 } 223 EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount()); 224 } 225 226 } // namespace blink 227