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
|
||||
static PDFFontPointer createFont(const PDFObject& object, const PDFDocument* document);
|
||||
|
||||
protected:
|
||||
FontDescriptor m_fontDescriptor;
|
||||
|
||||
private:
|
||||
/// Tries to read font descriptor from the object
|
||||
/// \param fontDescriptorObject Font descriptor dictionary
|
||||
/// \param document 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,
|
||||
|
|
|
@ -818,13 +818,9 @@ void PDFPrecompiledPage::finalize(qint64 compilingTimeNS, QList<PDFRenderError>
|
|||
return sizeof(QPainterPath::Element) * path.capacity();
|
||||
};
|
||||
for (const PathPaintData& data : m_paths)
|
||||
{
|
||||
// Texts are shared from the font
|
||||
if (!data.isText)
|
||||
{
|
||||
m_memoryConsumptionEstimate += calculateQPathMemoryConsumption(data.path);
|
||||
}
|
||||
}
|
||||
for (const ClipData& data : m_clips)
|
||||
{
|
||||
m_memoryConsumptionEstimate += calculateQPathMemoryConsumption(data.clipPath);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "pdfxfaengine.h"
|
||||
#include "pdfform.h"
|
||||
#include "pdfpainterutils.h"
|
||||
#include "pdffont.h"
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QDomDocument>
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include <QImageReader>
|
||||
#include <QTextDocument>
|
||||
#include <QTextBlock>
|
||||
#include <QFontDatabase>
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
|
||||
#include <stack>
|
||||
|
@ -9699,6 +9701,7 @@ private:
|
|||
std::vector<xfa::XFA_ParagraphSettings> paragraphSettings;
|
||||
};
|
||||
|
||||
void updateResources(const PDFObject& resources);
|
||||
void clear();
|
||||
|
||||
QMarginsF createMargin(const xfa::XFA_margin* margin);
|
||||
|
@ -9850,6 +9853,7 @@ private:
|
|||
const PDFDocument* m_document;
|
||||
PDFForm* m_form;
|
||||
Layout m_layout;
|
||||
std::map<int, QByteArray> m_fonts;
|
||||
};
|
||||
|
||||
class PDFXFALayoutEngine : public xfa::XFA_AbstractVisitor
|
||||
|
@ -11641,6 +11645,7 @@ void PDFXFAEngineImpl::setDocument(const PDFModifiedDocument& document, PDFForm*
|
|||
try
|
||||
{
|
||||
const PDFObject& xfaObject = m_document->getObject(form->getXFA());
|
||||
updateResources(m_document->getObject(form->getResources()));
|
||||
|
||||
std::map<QByteArray, QByteArray> xfaData;
|
||||
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,
|
||||
const xfa::XFA_ui* ui,
|
||||
QList<PDFRenderError>& errors,
|
||||
|
@ -13041,6 +13119,12 @@ void PDFXFAEngineImpl::clear()
|
|||
// Clear the template
|
||||
m_template = xfa::XFA_Node<xfa::XFA_template>();
|
||||
m_layout = Layout();
|
||||
|
||||
for (const auto& font : m_fonts)
|
||||
{
|
||||
QFontDatabase::removeApplicationFont(font.first);
|
||||
}
|
||||
m_fonts.clear();
|
||||
}
|
||||
|
||||
QMarginsF PDFXFAEngineImpl::createMargin(const xfa::XFA_margin* margin)
|
||||
|
|
Loading…
Reference in New Issue