mirror of https://github.com/JakubMelka/PDF4QT.git
XFA: Use fonts from font dictionary
This commit is contained in:
parent
354b4cc69b
commit
4035b26615
|
@ -287,14 +287,13 @@ public:
|
||||||
/// \param document Document
|
/// \param document Document
|
||||||
static PDFFontPointer createFont(const PDFObject& object, const PDFDocument* document);
|
static PDFFontPointer createFont(const PDFObject& object, const PDFDocument* document);
|
||||||
|
|
||||||
protected:
|
|
||||||
FontDescriptor m_fontDescriptor;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Tries to read font descriptor from the object
|
/// Tries to read font descriptor from the object
|
||||||
/// \param fontDescriptorObject Font descriptor dictionary
|
/// \param fontDescriptorObject Font descriptor dictionary
|
||||||
/// \param document Document
|
/// \param document Document
|
||||||
static FontDescriptor readFontDescriptor(const PDFObject& fontDescriptorObject, const PDFDocument* document);
|
static FontDescriptor readFontDescriptor(const PDFObject& fontDescriptorObject, const PDFDocument* document);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FontDescriptor m_fontDescriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Simple font, see PDF reference 1.7, chapter 5.5. Simple fonts have encoding table,
|
/// Simple font, see PDF reference 1.7, chapter 5.5. Simple fonts have encoding table,
|
||||||
|
|
|
@ -818,13 +818,9 @@ void PDFPrecompiledPage::finalize(qint64 compilingTimeNS, QList<PDFRenderError>
|
||||||
return sizeof(QPainterPath::Element) * path.capacity();
|
return sizeof(QPainterPath::Element) * path.capacity();
|
||||||
};
|
};
|
||||||
for (const PathPaintData& data : m_paths)
|
for (const PathPaintData& data : m_paths)
|
||||||
{
|
|
||||||
// Texts are shared from the font
|
|
||||||
if (!data.isText)
|
|
||||||
{
|
{
|
||||||
m_memoryConsumptionEstimate += calculateQPathMemoryConsumption(data.path);
|
m_memoryConsumptionEstimate += calculateQPathMemoryConsumption(data.path);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (const ClipData& data : m_clips)
|
for (const ClipData& data : m_clips)
|
||||||
{
|
{
|
||||||
m_memoryConsumptionEstimate += calculateQPathMemoryConsumption(data.clipPath);
|
m_memoryConsumptionEstimate += calculateQPathMemoryConsumption(data.clipPath);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "pdfxfaengine.h"
|
#include "pdfxfaengine.h"
|
||||||
#include "pdfform.h"
|
#include "pdfform.h"
|
||||||
#include "pdfpainterutils.h"
|
#include "pdfpainterutils.h"
|
||||||
|
#include "pdffont.h"
|
||||||
|
|
||||||
#include <QDomElement>
|
#include <QDomElement>
|
||||||
#include <QDomDocument>
|
#include <QDomDocument>
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
|
#include <QFontDatabase>
|
||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
@ -9699,6 +9701,7 @@ private:
|
||||||
std::vector<xfa::XFA_ParagraphSettings> paragraphSettings;
|
std::vector<xfa::XFA_ParagraphSettings> paragraphSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void updateResources(const PDFObject& resources);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
QMarginsF createMargin(const xfa::XFA_margin* margin);
|
QMarginsF createMargin(const xfa::XFA_margin* margin);
|
||||||
|
@ -9850,6 +9853,7 @@ private:
|
||||||
const PDFDocument* m_document;
|
const PDFDocument* m_document;
|
||||||
PDFForm* m_form;
|
PDFForm* m_form;
|
||||||
Layout m_layout;
|
Layout m_layout;
|
||||||
|
std::map<int, QByteArray> m_fonts;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PDFXFALayoutEngine : public xfa::XFA_AbstractVisitor
|
class PDFXFALayoutEngine : public xfa::XFA_AbstractVisitor
|
||||||
|
@ -11641,6 +11645,7 @@ void PDFXFAEngineImpl::setDocument(const PDFModifiedDocument& document, PDFForm*
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const PDFObject& xfaObject = m_document->getObject(form->getXFA());
|
const PDFObject& xfaObject = m_document->getObject(form->getXFA());
|
||||||
|
updateResources(m_document->getObject(form->getResources()));
|
||||||
|
|
||||||
std::map<QByteArray, QByteArray> xfaData;
|
std::map<QByteArray, QByteArray> xfaData;
|
||||||
if (xfaObject.isArray())
|
if (xfaObject.isArray())
|
||||||
|
@ -11725,6 +11730,79 @@ void PDFXFAEngineImpl::draw(const QMatrix& pagePointToDevicePointMatrix,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFXFAEngineImpl::updateResources(const PDFObject& resources)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::set<int> usedFonts;
|
||||||
|
|
||||||
|
if (m_document)
|
||||||
|
{
|
||||||
|
if (const PDFDictionary* resourcesDictionary = m_document->getDictionaryFromObject(resources))
|
||||||
|
{
|
||||||
|
if (const PDFDictionary* fontsDictionary = m_document->getDictionaryFromObject(resourcesDictionary->get("Font")))
|
||||||
|
{
|
||||||
|
const size_t size = fontsDictionary->getCount();
|
||||||
|
for (size_t i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
const PDFDictionary* fontDictionary = m_document->getDictionaryFromObject(fontsDictionary->getValue(i));
|
||||||
|
FontDescriptor descriptor = PDFFont::readFontDescriptor(m_document->getObject(fontDictionary->get("FontDescriptor")), m_document);
|
||||||
|
|
||||||
|
if (const QByteArray* data = descriptor.getEmbeddedFontData())
|
||||||
|
{
|
||||||
|
int fontId = -1;
|
||||||
|
|
||||||
|
for (const auto& font : m_fonts)
|
||||||
|
{
|
||||||
|
if (font.second == *data)
|
||||||
|
{
|
||||||
|
fontId = font.first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fontId == -1)
|
||||||
|
{
|
||||||
|
// Try to create application font from data
|
||||||
|
fontId = QFontDatabase::addApplicationFontFromData(*data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fontId != -1)
|
||||||
|
{
|
||||||
|
if (!m_fonts.count(fontId))
|
||||||
|
{
|
||||||
|
m_fonts[fontId] = *data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark font as used
|
||||||
|
usedFonts.insert(fontId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unused fonts
|
||||||
|
for (auto it = m_fonts.begin(); it != m_fonts.end();)
|
||||||
|
{
|
||||||
|
if (usedFonts.count(it->first))
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QFontDatabase::removeApplicationFont(it->first);
|
||||||
|
it = m_fonts.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const PDFException&)
|
||||||
|
{
|
||||||
|
// Just clear the fonts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PDFXFAEngineImpl::drawItemValue(const xfa::XFA_value* value,
|
void PDFXFAEngineImpl::drawItemValue(const xfa::XFA_value* value,
|
||||||
const xfa::XFA_ui* ui,
|
const xfa::XFA_ui* ui,
|
||||||
QList<PDFRenderError>& errors,
|
QList<PDFRenderError>& errors,
|
||||||
|
@ -13041,6 +13119,12 @@ void PDFXFAEngineImpl::clear()
|
||||||
// Clear the template
|
// Clear the template
|
||||||
m_template = xfa::XFA_Node<xfa::XFA_template>();
|
m_template = xfa::XFA_Node<xfa::XFA_template>();
|
||||||
m_layout = Layout();
|
m_layout = Layout();
|
||||||
|
|
||||||
|
for (const auto& font : m_fonts)
|
||||||
|
{
|
||||||
|
QFontDatabase::removeApplicationFont(font.first);
|
||||||
|
}
|
||||||
|
m_fonts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMarginsF PDFXFAEngineImpl::createMargin(const xfa::XFA_margin* margin)
|
QMarginsF PDFXFAEngineImpl::createMargin(const xfa::XFA_margin* margin)
|
||||||
|
|
Loading…
Reference in New Issue