Files
pdf/engine/tests/font_loader_descriptor_test.cpp
T
2026-06-29 10:51:04 +05:30

174 lines
5.9 KiB
C++

#include "fonts_test_helpers.hpp"
namespace pdfengine::fonts {
TEST(FontLoaderTest, FontFaceLoadFromMemorySuccess) {
std::string fontPath = getSystemFontPath();
if (fontPath.empty()) {
GTEST_SKIP() << "No system font found to run load from memory success test.";
}
std::ifstream file(fontPath, std::ios::binary | std::ios::ate);
ASSERT_TRUE(file.is_open());
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> buffer(size);
ASSERT_TRUE(file.read(reinterpret_cast<char*>(buffer.data()), size));
FontFace face;
ASSERT_TRUE(face.loadFromMemory(buffer));
ASSERT_NE(face.getFace(), nullptr);
unsigned int glyphIndex = FT_Get_Char_Index(face.getFace(), 'M');
ASSERT_GT(glyphIndex, 0u);
auto glyph = face.renderGlyph(glyphIndex, 16);
ASSERT_TRUE(glyph.has_value());
EXPECT_GT(glyph->width, 0);
EXPECT_GT(glyph->height, 0);
EXPECT_GT(glyph->advance, 0.0);
}
TEST(FontLoaderTest, FontFaceLoadFromMemoryInvalid) {
FontFace face;
std::vector<uint8_t> emptyData;
EXPECT_FALSE(face.loadFromMemory(emptyData));
EXPECT_EQ(face.getFace(), nullptr);
std::vector<uint8_t> corruptData = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
EXPECT_FALSE(face.loadFromMemory(corruptData));
EXPECT_EQ(face.getFace(), nullptr);
}
TEST(FontLoaderTest, FontLoaderTrueTypeSuccess) {
std::string fontPath = getSystemFontPath();
if (fontPath.empty()) {
GTEST_SKIP() << "No system font found to run PDF font loader test.";
}
std::ifstream file(fontPath, std::ios::binary | std::ios::ate);
ASSERT_TRUE(file.is_open());
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> buffer(size);
ASSERT_TRUE(file.read(reinterpret_cast<char*>(buffer.data()), size));
auto pdfFont = pdfengine::fonts::pdf_fonts::FontLoader::loadTrueTypeFromMemory("Arial", buffer);
ASSERT_NE(pdfFont, nullptr);
EXPECT_EQ(pdfFont->getBaseFont(), "Arial");
EXPECT_EQ(pdfFont->getType(), pdfengine::fonts::pdf_fonts::FontType::TrueType);
EXPECT_TRUE(pdfFont->isEmbedded());
HbShaper shaper;
auto glyphs = shaper.shapeRun("Test Memory Load", pdfFont->getFontFace(), 16);
EXPECT_FALSE(glyphs.empty());
}
TEST(FontDescriptorTest, DescriptorDefaultValues) {
pdfengine::fonts::pdf_fonts::FontDescriptor desc;
EXPECT_EQ(desc.getFontName(), "");
EXPECT_EQ(desc.getFlags(), 0);
EXPECT_EQ(desc.getItalicAngle(), 0.0);
EXPECT_EQ(desc.getAscent(), 0.0);
EXPECT_EQ(desc.getDescent(), 0.0);
EXPECT_EQ(desc.getCapHeight(), 0.0);
EXPECT_EQ(desc.getStemV(), 0.0);
pdfengine::fonts::pdf_fonts::FontBBox bbox = desc.getFontBBox();
EXPECT_EQ(bbox.llx, 0);
EXPECT_EQ(bbox.lly, 0);
EXPECT_EQ(bbox.urx, 0);
EXPECT_EQ(bbox.ury, 0);
EXPECT_FALSE(desc.isFixedPitch());
EXPECT_FALSE(desc.isSerif());
EXPECT_FALSE(desc.isSymbolic());
EXPECT_FALSE(desc.isItalic());
}
TEST(FontDescriptorTest, DescriptorParsingSuccess) {
std::string dict =
"<< /Type /FontDescriptor\n"
" /FontName /ArialMT\n"
" /Flags 32\n"
" /FontBBox [-166 -225 1000 931]\n"
" /ItalicAngle 0\n"
" /Ascent 905\n"
" /Descent -211\n"
" /CapHeight 728\n"
" /StemV 94\n"
">>";
pdfengine::fonts::pdf_fonts::FontDescriptor desc;
ASSERT_TRUE(desc.parseFromDictionaryString(dict));
EXPECT_EQ(desc.getFontName(), "ArialMT");
EXPECT_EQ(desc.getFlags(), 32);
pdfengine::fonts::pdf_fonts::FontBBox bbox = desc.getFontBBox();
EXPECT_EQ(bbox.llx, -166);
EXPECT_EQ(bbox.lly, -225);
EXPECT_EQ(bbox.urx, 1000);
EXPECT_EQ(bbox.ury, 931);
EXPECT_DOUBLE_EQ(desc.getItalicAngle(), 0.0);
EXPECT_DOUBLE_EQ(desc.getAscent(), 905.0);
EXPECT_DOUBLE_EQ(desc.getDescent(), -211.0);
EXPECT_DOUBLE_EQ(desc.getCapHeight(), 728.0);
EXPECT_DOUBLE_EQ(desc.getStemV(), 94.0);
EXPECT_FALSE(desc.isFixedPitch());
EXPECT_TRUE(desc.isNonsymbolic());
EXPECT_FALSE(desc.isItalic());
}
TEST(FontDescriptorTest, DescriptorParsingMalformed) {
pdfengine::fonts::pdf_fonts::FontDescriptor desc;
EXPECT_FALSE(desc.parseFromDictionaryString("/Flags 32 >>"));
EXPECT_FALSE(desc.parseFromDictionaryString("<< /Flags 32"));
EXPECT_FALSE(desc.parseFromDictionaryString("<< /FontBBox [-166 -225] >>"));
EXPECT_FALSE(desc.parseFromDictionaryString("<< /Ascent abc >>"));
EXPECT_FALSE(desc.parseFromDictionaryString("<< /Ascent >>"));
}
TEST(FontDescriptorTest, FontLoaderWithDescriptor) {
std::string fontPath = getSystemFontPath();
if (fontPath.empty()) {
GTEST_SKIP() << "No system font found to run PDF font loader test.";
}
std::ifstream file(fontPath, std::ios::binary | std::ios::ate);
ASSERT_TRUE(file.is_open());
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> buffer(size);
ASSERT_TRUE(file.read(reinterpret_cast<char*>(buffer.data()), size));
auto descriptor = std::make_unique<pdfengine::fonts::pdf_fonts::FontDescriptor>();
descriptor->setFontName("Arial-BoldMT");
descriptor->setFlags(96);
descriptor->setAscent(905.0);
descriptor->setDescent(-211.0);
auto pdfFont = pdfengine::fonts::pdf_fonts::FontLoader::loadTrueTypeFromMemory("Arial-Bold", buffer, std::move(descriptor));
ASSERT_NE(pdfFont, nullptr);
EXPECT_EQ(pdfFont->getBaseFont(), "Arial-Bold");
EXPECT_TRUE(pdfFont->isEmbedded());
const auto* retrievedDesc = pdfFont->getDescriptor();
ASSERT_NE(retrievedDesc, nullptr);
EXPECT_EQ(retrievedDesc->getFontName(), "Arial-BoldMT");
EXPECT_EQ(retrievedDesc->getFlags(), 96);
EXPECT_TRUE(retrievedDesc->isItalic());
EXPECT_TRUE(retrievedDesc->isNonsymbolic());
EXPECT_DOUBLE_EQ(retrievedDesc->getAscent(), 905.0);
EXPECT_DOUBLE_EQ(retrievedDesc->getDescent(), -211.0);
}
}