Home | History | Annotate | Download | only in fonts
      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