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

175 lines
5.6 KiB
C++

#include "document_test_helpers.hpp"
namespace pdfengine {
TEST(PageRenderTest, RenderAtDifferentDPI) {
SKIP_IF_NO_PDFIUM();
auto path = getCorpusPath("basic", "hello_world.pdf");
if (!std::filesystem::exists(path)) {
GTEST_SKIP() << "hello_world.pdf not found in corpus.";
}
auto docRes = PdfDocument::loadFromFile(path.string());
ASSERT_TRUE(docRes.has_value());
auto pageRes = (*docRes)->getPage(0);
ASSERT_TRUE(pageRes.has_value());
auto page = *pageRes;
double ptWidth = page->width();
double ptHeight = page->height();
EXPECT_GT(ptWidth, 0.0);
EXPECT_GT(ptHeight, 0.0);
std::vector<int> dpis = {72, 144, 288};
for (int dpi : dpis) {
auto imgRes = page->render(dpi);
ASSERT_TRUE(imgRes.has_value()) << "Failed to render at DPI " << dpi;
double scale = dpi / 72.0;
int expectedW = static_cast<int>(ptWidth * scale);
int expectedH = static_cast<int>(ptHeight * scale);
EXPECT_EQ(imgRes->width, expectedW);
EXPECT_EQ(imgRes->height, expectedH);
ASSERT_GE(imgRes->data.size(), 8U);
EXPECT_EQ(imgRes->data[0], 0x89);
EXPECT_EQ(imgRes->data[1], 'P');
EXPECT_EQ(imgRes->data[2], 'N');
EXPECT_EQ(imgRes->data[3], 'G');
EXPECT_EQ(imgRes->data[4], 0x0D);
EXPECT_EQ(imgRes->data[5], 0x0A);
EXPECT_EQ(imgRes->data[6], 0x1A);
EXPECT_EQ(imgRes->data[7], 0x0A);
}
}
TEST(PageRenderTest, InvalidPageIndexReturnsPageOutOfBounds) {
SKIP_IF_NO_PDFIUM();
auto path = getCorpusPath("basic", "hello_world.pdf");
if (!std::filesystem::exists(path)) {
GTEST_SKIP() << "hello_world.pdf not found in corpus.";
}
auto docRes = PdfDocument::loadFromFile(path.string());
ASSERT_TRUE(docRes.has_value());
auto pageRes = (*docRes)->getPage(1);
ASSERT_FALSE(pageRes.has_value());
EXPECT_EQ(pageRes.error(), EngineError::PageOutOfBounds);
auto pageResNeg = (*docRes)->getPage(-1);
ASSERT_FALSE(pageResNeg.has_value());
EXPECT_EQ(pageResNeg.error(), EngineError::PageOutOfBounds);
}
TEST(CoordinateTransformTest, PageToDeviceAndBackRoundtrip) {
SKIP_IF_NO_PDFIUM();
auto path = getCorpusPath("basic", "hello_world.pdf");
if (!std::filesystem::exists(path)) {
GTEST_SKIP() << "hello_world.pdf not found in corpus.";
}
auto docRes = PdfDocument::loadFromFile(path.string());
ASSERT_TRUE(docRes.has_value());
auto pageRes = (*docRes)->getPage(0);
ASSERT_TRUE(pageRes.has_value());
auto page = *pageRes;
int deviceW = 1024;
int deviceH = 768;
std::vector<int> rotations = {0, 90, 180, 270};
std::vector<Point2D> testPoints = {
{0.0, 0.0},
{50.0, 50.0},
{100.0, 200.0},
{page->width() / 2.0, page->height() / 2.0},
{page->width() - 10.0, page->height() - 10.0}
};
for (int rotation : rotations) {
for (const auto& pt : testPoints) {
auto devPt = page->pageToDevice(pt, deviceW, deviceH, rotation);
auto pagePt = page->deviceToPage(devPt, deviceW, deviceH, rotation);
EXPECT_NEAR(pt.x, pagePt.x, 2.0) << "Failed roundtrip for x at rotation " << rotation;
EXPECT_NEAR(pt.y, pagePt.y, 2.0) << "Failed roundtrip for y at rotation " << rotation;
}
}
}
TEST(TextExtractionTest, ExtractSimpleText) {
SKIP_IF_NO_PDFIUM();
auto path = getCorpusPath("basic", "hello_world.pdf");
if (!std::filesystem::exists(path)) {
GTEST_SKIP() << "hello_world.pdf not found in corpus.";
}
auto docRes = PdfDocument::loadFromFile(path.string());
ASSERT_TRUE(docRes.has_value());
auto pageRes = (*docRes)->getPage(0);
ASSERT_TRUE(pageRes.has_value());
auto textRes = (*pageRes)->extractText();
ASSERT_TRUE(textRes.has_value());
std::string text = *textRes;
EXPECT_NE(text.find("Hello"), std::string::npos);
EXPECT_NE(text.find("world"), std::string::npos);
}
TEST(TextExtractionTest, ExtractUtf8ExtendedText) {
SKIP_IF_NO_PDFIUM();
auto path = getCorpusPath("fonts", "latin_extended.pdf");
if (!std::filesystem::exists(path)) {
GTEST_SKIP() << "latin_extended.pdf not found in corpus.";
}
auto docRes = PdfDocument::loadFromFile(path.string());
ASSERT_TRUE(docRes.has_value());
auto pageRes = (*docRes)->getPage(0);
ASSERT_TRUE(pageRes.has_value());
auto textRes = (*pageRes)->extractText();
ASSERT_TRUE(textRes.has_value());
std::string text = *textRes;
EXPECT_FALSE(text.empty());
}
TEST(TextExtractionTest, ExtractTextWithBounds) {
SKIP_IF_NO_PDFIUM();
auto path = getCorpusPath("basic", "hello_world.pdf");
if (!std::filesystem::exists(path)) {
GTEST_SKIP() << "hello_world.pdf not found in corpus.";
}
auto docRes = PdfDocument::loadFromFile(path.string());
ASSERT_TRUE(docRes.has_value());
auto pageRes = (*docRes)->getPage(0);
ASSERT_TRUE(pageRes.has_value());
auto boundsRes = (*pageRes)->extractTextWithBounds();
ASSERT_TRUE(boundsRes.has_value());
const auto& glyphs = *boundsRes;
ASSERT_FALSE(glyphs.empty());
bool found_hello = false;
for (const auto& glyph : glyphs) {
EXPECT_FALSE(glyph.text.empty());
if (glyph.text != " " && glyph.text != "\r" && glyph.text != "\n" && glyph.text != "\t") {
EXPECT_GT(glyph.w, 0.0);
EXPECT_GT(glyph.h, 0.0);
}
EXPECT_GT(glyph.fontSize, 0.0);
if (glyph.text == "H" || glyph.text == "e" || glyph.text == "l" || glyph.text == "o") {
found_hello = true;
}
}
EXPECT_TRUE(found_hello);
}
}