stuff-from-scratch/src/publishing/pdf/PdfPage.h

122 lines
3.4 KiB
C
Raw Normal View History

2022-01-01 18:46:31 +00:00
#pragma once
#include "PdfObject.h"
#include "PdfStream.h"
#include "PdfXRefTable.h"
class PdfPageTree;
class PdfProcSet : public PdfObject
{
public:
std::string ToString(PdfXRefTable* xRefTable) override
{
UpdateDictionary();
auto content = GetStringPrefix();
content += mDictionary.ToString();
content += "[/PDF]\n";
content += GetStringSuffix();
xRefTable->AddRecord(content.size(), mGenerationNumber, mIsFree);
return content;
}
};
class PdfFont : public PdfObject
{
public:
std::string ToString(PdfXRefTable* xRefTable) override
{
UpdateDictionary();
auto content = GetStringPrefix();
content += mDictionary.ToString();
content += GetStringSuffix();
xRefTable->AddRecord(content.size(), mGenerationNumber, mIsFree);
return content;
}
void UpdateDictionary()
{
mDictionary.AddStringItem("Type", "/Font");
mDictionary.AddStringItem("Subtype", "/Type1");
mDictionary.AddStringItem("Name", "/F1");
mDictionary.AddStringItem("BaseFont", "/Helvetica");
mDictionary.AddStringItem("Encoding", "/MacRomanEncoding");
}
};
class PdfPage : public PdfObject
{
public:
PdfPage(PdfPageTree* parent)
: mParent(parent)
{
mContent = std::make_unique<PdfStream>();
std::string pageContent = "BT\n";
pageContent += "/F1 24 Tf\n";
pageContent += "100 100 Td\n";
pageContent += "(Hello World) Tj\n";
pageContent += "ET";
mContent->SetContent(pageContent);
mProcSet = std::make_unique<PdfProcSet>();
mDefaultFont = std::make_unique<PdfFont>();
}
unsigned IndexObjects(unsigned count)
{
auto newCount = count + 1;
mObjectNumber = newCount;
newCount = mContent->IndexObjects(newCount);
newCount = mProcSet->IndexObjects(newCount);
newCount = mDefaultFont->IndexObjects(newCount);
return newCount;
}
std::string ToString(PdfXRefTable* xRefTable) override
{
UpdateDictionary();
auto content = GetStringPrefix();
content += mDictionary.ToString();
content += GetStringSuffix();
xRefTable->AddRecord(content.size(), mGenerationNumber, mIsFree);
content += mContent->ToString(xRefTable);
content += mProcSet->ToString(xRefTable);
content += mDefaultFont->ToString(xRefTable);
return content;
}
void UpdateDictionary()
{
std::string mediaBox = "[0 0 " + std::to_string(mWidth) + " " + std::to_string(mHeight) + "]";
mDictionary.AddStringItem("Type", "/Page");
mDictionary.AddStringItem("MediaBox", mediaBox);
mDictionary.AddStringItem("Parent", mParent->GetRefString());
mDictionary.AddStringItem("Contents", mContent->GetRefString());
auto resourcesDict = std::make_unique<PdfDictionary>();
resourcesDict->AddStringItem("ProcSet", mProcSet->GetRefString());
auto fontDict = std::make_unique<PdfDictionary>();
fontDict->AddStringItem("F1", mDefaultFont->GetRefString());
resourcesDict->AddDictItem("Font", std::move(fontDict));
mDictionary.AddDictItem("Resources", std::move(resourcesDict));
}
private:
unsigned mWidth{612};
unsigned mHeight{792};
std::unique_ptr<PdfStream> mContent;
std::unique_ptr<PdfFont> mDefaultFont;
PdfObjectPtr mProcSet;
PdfPageTree* mParent;
};