blob: 4e6845b12c02aa0331f6b309e57882530456e7bc [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/engine/platform/fonts/GlyphPageTreeNode.h"
#include <gtest/gtest.h>
#include "sky/engine/platform/fonts/SegmentedFontData.h"
#include "sky/engine/platform/fonts/SimpleFontData.h"
namespace blink {
class TestCustomFontData : public CustomFontData {
public:
static PassRefPtr<TestCustomFontData> create() { return adoptRef(new TestCustomFontData()); }
private:
TestCustomFontData() { }
virtual bool isLoadingFallback() const override { return true; }
};
class TestSimpleFontData : public SimpleFontData {
public:
static PassRefPtr<TestSimpleFontData> create(UChar32 from, UChar32 to)
{
return adoptRef(new TestSimpleFontData(nullptr, from, to));
}
static PassRefPtr<TestSimpleFontData> createUnloaded(UChar32 from, UChar32 to)
{
return adoptRef(new TestSimpleFontData(TestCustomFontData::create(), from, to));
}
private:
TestSimpleFontData(PassRefPtr<CustomFontData> customData, UChar32 from, UChar32 to)
: SimpleFontData(customData, 10, false, false)
, m_from(from)
, m_to(to)
{
}
bool fillGlyphPage(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength) const override
{
const Glyph kGlyph = 1;
String bufferString(buffer, bufferLength);
unsigned bufferIndex = 0;
bool hasGlyphs = false;
for (unsigned i = 0; i < length; i++) {
UChar32 c = bufferString.characterStartingAt(bufferIndex);
bufferIndex += U16_LENGTH(c);
if (m_from <= c && c <= m_to) {
pageToFill->setGlyphDataForIndex(offset + i, kGlyph, this);
hasGlyphs = true;
}
}
return hasGlyphs;
}
UChar32 m_from;
UChar32 m_to;
};
TEST(GlyphPageTreeNode, rootChild)
{
const unsigned kPageNumber = 0;
size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount();
{
RefPtr<TestSimpleFontData> data = TestSimpleFontData::create('a', 'z');
GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(data.get(), kPageNumber);
EXPECT_EQ(pageCountBeforeTest + 1, GlyphPageTreeNode::treeGlyphPageCount());
EXPECT_TRUE(node->page()->glyphAt('a'));
EXPECT_FALSE(node->page()->glyphAt('A'));
EXPECT_FALSE(node->isSystemFallback());
EXPECT_EQ(1u, node->level());
EXPECT_EQ(node, node->page()->owner());
}
EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount());
}
TEST(GlyphPageTreeNode, level2)
{
const unsigned kPageNumber = 0;
size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount();
{
RefPtr<TestSimpleFontData> dataAtoC = TestSimpleFontData::create('A', 'C');
RefPtr<TestSimpleFontData> dataCtoE = TestSimpleFontData::create('C', 'E');
GlyphPageTreeNode* node1 = GlyphPageTreeNode::getRootChild(dataAtoC.get(), kPageNumber);
GlyphPageTreeNode* node2 = node1->getChild(dataCtoE.get(), kPageNumber);
EXPECT_EQ(pageCountBeforeTest + 3, GlyphPageTreeNode::treeGlyphPageCount());
EXPECT_EQ(2u, node2->level());
EXPECT_EQ(dataAtoC, node2->page()->glyphDataForCharacter('A').fontData);
EXPECT_EQ(dataAtoC, node2->page()->glyphDataForCharacter('C').fontData);
EXPECT_EQ(dataCtoE, node2->page()->glyphDataForCharacter('E').fontData);
}
EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount());
}
TEST(GlyphPageTreeNode, segmentedData)
{
const unsigned kPageNumber = 0;
size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount();
{
RefPtr<TestSimpleFontData> dataBtoC = TestSimpleFontData::create('B', 'C');
RefPtr<TestSimpleFontData> dataCtoE = TestSimpleFontData::create('C', 'E');
RefPtr<SegmentedFontData> segmentedData = SegmentedFontData::create();
segmentedData->appendRange(FontDataRange('A', 'C', dataBtoC));
segmentedData->appendRange(FontDataRange('C', 'D', dataCtoE));
GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(segmentedData.get(), kPageNumber);
EXPECT_EQ(0, node->page()->glyphDataForCharacter('A').fontData);
EXPECT_EQ(dataBtoC, node->page()->glyphDataForCharacter('B').fontData);
EXPECT_EQ(dataBtoC, node->page()->glyphDataForCharacter('C').fontData);
EXPECT_EQ(dataCtoE, node->page()->glyphDataForCharacter('D').fontData);
EXPECT_EQ(0, node->page()->glyphDataForCharacter('E').fontData);
}
EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount());
}
TEST(GlyphPageTreeNode, outsideBMP)
{
const unsigned kPageNumber = 0x1f300 / GlyphPage::size;
size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount();
{
RefPtr<TestSimpleFontData> data = TestSimpleFontData::create(0x1f310, 0x1f320);
GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(data.get(), kPageNumber);
EXPECT_EQ(pageCountBeforeTest + 1, GlyphPageTreeNode::treeGlyphPageCount());
EXPECT_FALSE(node->page()->glyphForCharacter(0x1f30f));
EXPECT_TRUE(node->page()->glyphForCharacter(0x1f310));
EXPECT_TRUE(node->page()->glyphForCharacter(0x1f320));
EXPECT_FALSE(node->page()->glyphForCharacter(0x1f321));
}
EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount());
}
TEST(GlyphPageTreeNode, customData)
{
const unsigned kPageNumber = 0;
size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount();
{
RefPtr<TestSimpleFontData> dataAtoC = TestSimpleFontData::createUnloaded('A', 'C');
RefPtr<TestSimpleFontData> dataBtoD = TestSimpleFontData::create('B', 'D');
RefPtr<TestSimpleFontData> dataCtoE = TestSimpleFontData::createUnloaded('C', 'E');
RefPtr<SegmentedFontData> segmentedData = SegmentedFontData::create();
segmentedData->appendRange(FontDataRange('A', 'C', dataAtoC));
segmentedData->appendRange(FontDataRange('B', 'D', dataBtoD));
segmentedData->appendRange(FontDataRange('C', 'E', dataCtoE));
GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(segmentedData.get(), kPageNumber);
EXPECT_EQ(0, node->page()->glyphDataForCharacter('A').fontData);
EXPECT_EQ(dataBtoD, node->page()->glyphDataForCharacter('B').fontData);
EXPECT_EQ(dataBtoD, node->page()->glyphDataForCharacter('C').fontData);
EXPECT_EQ(dataBtoD, node->page()->glyphDataForCharacter('D').fontData);
EXPECT_EQ(0, node->page()->glyphDataForCharacter('E').fontData);
EXPECT_EQ(dataAtoC->customFontData(), node->page()->customFontToLoadAt('A'));
EXPECT_EQ(dataAtoC->customFontData(), node->page()->customFontToLoadAt('B'));
EXPECT_EQ(dataAtoC->customFontData(), node->page()->customFontToLoadAt('C'));
EXPECT_EQ(0, node->page()->customFontToLoadAt('D'));
EXPECT_EQ(dataCtoE->customFontData(), node->page()->customFontToLoadAt('E'));
}
EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount());
}
TEST(GlyphPageTreeNode, customDataWithMultiplePages)
{
const unsigned kPageNumber = 0;
size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount();
{
RefPtr<TestSimpleFontData> dataAtoC = TestSimpleFontData::createUnloaded('A', 'C');
RefPtr<TestSimpleFontData> dataBtoD = TestSimpleFontData::create('B', 'D');
RefPtr<TestSimpleFontData> dataCtoE = TestSimpleFontData::createUnloaded('C', 'E');
RefPtr<SegmentedFontData> segmentedData1 = SegmentedFontData::create();
RefPtr<SegmentedFontData> segmentedData2 = SegmentedFontData::create();
RefPtr<SegmentedFontData> segmentedData3 = SegmentedFontData::create();
segmentedData1->appendRange(FontDataRange('A', 'C', dataAtoC));
segmentedData2->appendRange(FontDataRange('B', 'D', dataBtoD));
segmentedData3->appendRange(FontDataRange('C', 'E', dataCtoE));
GlyphPageTreeNode* node1 = GlyphPageTreeNode::getRootChild(segmentedData1.get(), kPageNumber);
GlyphPageTreeNode* node2 = node1->getChild(segmentedData2.get(), kPageNumber);
GlyphPageTreeNode* node3 = node2->getChild(segmentedData3.get(), kPageNumber);
EXPECT_EQ(0, node3->page()->glyphDataForCharacter('A').fontData);
EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('B').fontData);
EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('C').fontData);
EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('D').fontData);
EXPECT_EQ(0, node3->page()->glyphDataForCharacter('E').fontData);
EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('A'));
EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('B'));
EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('C'));
EXPECT_EQ(0, node3->page()->customFontToLoadAt('D'));
EXPECT_EQ(dataCtoE->customFontData(), node3->page()->customFontToLoadAt('E'));
}
EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount());
}
TEST(GlyphPageTreeNode, systemFallback)
{
const unsigned kPageNumber = 0;
size_t pageCountBeforeTest = GlyphPageTreeNode::treeGlyphPageCount();
{
RefPtr<TestSimpleFontData> dataAtoC = TestSimpleFontData::createUnloaded('A', 'C');
RefPtr<TestSimpleFontData> dataBtoD = TestSimpleFontData::create('B', 'D');
RefPtr<SegmentedFontData> segmentedData = SegmentedFontData::create();
segmentedData->appendRange(FontDataRange('A', 'C', dataAtoC));
GlyphPageTreeNode* node1 = GlyphPageTreeNode::getRootChild(segmentedData.get(), kPageNumber);
GlyphPageTreeNode* node2 = node1->getChild(dataBtoD.get(), kPageNumber);
GlyphPageTreeNode* node3 = node2->getChild(0, kPageNumber);
EXPECT_TRUE(node3->isSystemFallback());
EXPECT_EQ(0, node3->page()->glyphDataForCharacter('A').fontData);
EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('B').fontData);
EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('C').fontData);
EXPECT_EQ(dataBtoD, node3->page()->glyphDataForCharacter('D').fontData);
EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('A'));
EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('B'));
EXPECT_EQ(dataAtoC->customFontData(), node3->page()->customFontToLoadAt('C'));
EXPECT_EQ(0, node3->page()->customFontToLoadAt('D'));
}
EXPECT_EQ(pageCountBeforeTest, GlyphPageTreeNode::treeGlyphPageCount());
}
} // namespace blink