mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Better font handling
This commit is contained in:
@ -42,6 +42,7 @@ private:
|
|||||||
enum RenderErrorType
|
enum RenderErrorType
|
||||||
{
|
{
|
||||||
Error,
|
Error,
|
||||||
|
Warning,
|
||||||
NotImplemented
|
NotImplemented
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,6 +75,19 @@ private:
|
|||||||
PDFRenderError m_error;
|
PDFRenderError m_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Abstract class for reporting render errors
|
||||||
|
class PDFRenderErrorReporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PDFRenderErrorReporter() = default;
|
||||||
|
virtual ~PDFRenderErrorReporter() = default;
|
||||||
|
|
||||||
|
/// Reports render errors
|
||||||
|
/// \param type Error type
|
||||||
|
/// \param message Error message
|
||||||
|
virtual void reportRenderError(RenderErrorType type, QString message) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
|
||||||
#endif // PDFEXCEPTION_H
|
#endif // PDFEXCEPTION_H
|
||||||
|
@ -324,12 +324,16 @@ public:
|
|||||||
/// produces glyphs for the font.
|
/// produces glyphs for the font.
|
||||||
/// \param byteArray Array of bytes to be interpreted
|
/// \param byteArray Array of bytes to be interpreted
|
||||||
/// \param textSequence Text sequence to be filled
|
/// \param textSequence Text sequence to be filled
|
||||||
void fillTextSequence(const QByteArray& byteArray, TextSequence& textSequence);
|
void fillTextSequence(const QByteArray& byteArray, TextSequence& textSequence, PDFRenderErrorReporter* reporter);
|
||||||
|
|
||||||
|
static constexpr const PDFReal PIXEL_SIZE_MULTIPLIER = 100.0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class PDFRealizedFont;
|
friend class PDFRealizedFont;
|
||||||
|
|
||||||
|
static constexpr const PDFReal FONT_WIDTH_MULTIPLIER = 1.0 / 1000.0;
|
||||||
static constexpr const PDFReal FORMAT_26_6_MULTIPLIER = 1 / 64.0;
|
static constexpr const PDFReal FORMAT_26_6_MULTIPLIER = 1 / 64.0;
|
||||||
|
static constexpr const PDFReal FONT_MULTIPLIER = FORMAT_26_6_MULTIPLIER / PIXEL_SIZE_MULTIPLIER;
|
||||||
|
|
||||||
struct Glyph
|
struct Glyph
|
||||||
{
|
{
|
||||||
@ -405,7 +409,7 @@ PDFRealizedFontImpl::~PDFRealizedFontImpl()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequence& textSequence)
|
void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequence& textSequence, PDFRenderErrorReporter* reporter)
|
||||||
{
|
{
|
||||||
switch (m_parentFont->getFontType())
|
switch (m_parentFont->getFontType())
|
||||||
{
|
{
|
||||||
@ -432,14 +436,22 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!glyphIndex)
|
const PDFReal glyphWidth = font->getGlyphWidth(static_cast<uint8_t>(byteArray[i]));
|
||||||
{
|
|
||||||
throw PDFParserException(PDFTranslationContext::tr("Glyph for simple font character code '%1' not found.").arg(static_cast<uint8_t>(byteArray[i])));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (glyphIndex)
|
||||||
|
{
|
||||||
const Glyph& glyph = getGlyph(glyphIndex);
|
const Glyph& glyph = getGlyph(glyphIndex);
|
||||||
textSequence.items.emplace_back(&glyph.glyph, (*encoding)[static_cast<uint8_t>(byteArray[i])], glyph.advance);
|
textSequence.items.emplace_back(&glyph.glyph, (*encoding)[static_cast<uint8_t>(byteArray[i])], glyph.advance);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reporter->reportRenderError(RenderErrorType::Warning, PDFTranslationContext::tr("Glyph for simple font character code '%1' not found.").arg(static_cast<uint8_t>(byteArray[i])));
|
||||||
|
if (glyphWidth > 0)
|
||||||
|
{
|
||||||
|
textSequence.items.emplace_back(nullptr, QChar(), glyphWidth * m_pixelSize * FONT_WIDTH_MULTIPLIER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,28 +494,28 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ
|
|||||||
int PDFRealizedFontImpl::outlineMoveTo(const FT_Vector* to, void* user)
|
int PDFRealizedFontImpl::outlineMoveTo(const FT_Vector* to, void* user)
|
||||||
{
|
{
|
||||||
Glyph* glyph = reinterpret_cast<Glyph*>(user);
|
Glyph* glyph = reinterpret_cast<Glyph*>(user);
|
||||||
glyph->glyph.moveTo(to->x * FORMAT_26_6_MULTIPLIER, to->y * FORMAT_26_6_MULTIPLIER);
|
glyph->glyph.moveTo(to->x * FONT_MULTIPLIER, to->y * FONT_MULTIPLIER);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PDFRealizedFontImpl::outlineLineTo(const FT_Vector* to, void* user)
|
int PDFRealizedFontImpl::outlineLineTo(const FT_Vector* to, void* user)
|
||||||
{
|
{
|
||||||
Glyph* glyph = reinterpret_cast<Glyph*>(user);
|
Glyph* glyph = reinterpret_cast<Glyph*>(user);
|
||||||
glyph->glyph.lineTo(to->x * FORMAT_26_6_MULTIPLIER, to->y * FORMAT_26_6_MULTIPLIER);
|
glyph->glyph.lineTo(to->x * FONT_MULTIPLIER, to->y * FONT_MULTIPLIER);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PDFRealizedFontImpl::outlineConicTo(const FT_Vector* control, const FT_Vector* to, void* user)
|
int PDFRealizedFontImpl::outlineConicTo(const FT_Vector* control, const FT_Vector* to, void* user)
|
||||||
{
|
{
|
||||||
Glyph* glyph = reinterpret_cast<Glyph*>(user);
|
Glyph* glyph = reinterpret_cast<Glyph*>(user);
|
||||||
glyph->glyph.quadTo(control->x * FORMAT_26_6_MULTIPLIER, control->y * FORMAT_26_6_MULTIPLIER, to->x * FORMAT_26_6_MULTIPLIER, to->y * FORMAT_26_6_MULTIPLIER);
|
glyph->glyph.quadTo(control->x * FONT_MULTIPLIER, control->y * FONT_MULTIPLIER, to->x * FONT_MULTIPLIER, to->y * FONT_MULTIPLIER);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PDFRealizedFontImpl::outlineCubicTo(const FT_Vector* control1, const FT_Vector* control2, const FT_Vector* to, void* user)
|
int PDFRealizedFontImpl::outlineCubicTo(const FT_Vector* control1, const FT_Vector* control2, const FT_Vector* to, void* user)
|
||||||
{
|
{
|
||||||
Glyph* glyph = reinterpret_cast<Glyph*>(user);
|
Glyph* glyph = reinterpret_cast<Glyph*>(user);
|
||||||
glyph->glyph.cubicTo(control1->x * FORMAT_26_6_MULTIPLIER, control1->y * FORMAT_26_6_MULTIPLIER, control2->x * FORMAT_26_6_MULTIPLIER, control2->y * FORMAT_26_6_MULTIPLIER, to->x * FORMAT_26_6_MULTIPLIER, to->y * FORMAT_26_6_MULTIPLIER);
|
glyph->glyph.cubicTo(control1->x * FONT_MULTIPLIER, control1->y * FONT_MULTIPLIER, control2->x * FONT_MULTIPLIER, control2->y * FONT_MULTIPLIER, to->x * FONT_MULTIPLIER, to->y * FONT_MULTIPLIER);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +546,7 @@ const PDFRealizedFontImpl::Glyph& PDFRealizedFontImpl::getGlyph(unsigned int gly
|
|||||||
checkFreeTypeError(FT_Outline_Decompose(&m_face->glyph->outline, &glyphOutlineInterface, &glyph));
|
checkFreeTypeError(FT_Outline_Decompose(&m_face->glyph->outline, &glyphOutlineInterface, &glyph));
|
||||||
glyph.glyph.closeSubpath();
|
glyph.glyph.closeSubpath();
|
||||||
glyph.advance = !m_isVertical ? m_face->glyph->advance.x : m_face->glyph->advance.y;
|
glyph.advance = !m_isVertical ? m_face->glyph->advance.x : m_face->glyph->advance.y;
|
||||||
glyph.advance *= FORMAT_26_6_MULTIPLIER;
|
glyph.advance *= FONT_MULTIPLIER;
|
||||||
|
|
||||||
m_glyphCache[glyphIndex] = qMove(glyph);
|
m_glyphCache[glyphIndex] = qMove(glyph);
|
||||||
return m_glyphCache[glyphIndex];
|
return m_glyphCache[glyphIndex];
|
||||||
@ -563,9 +575,9 @@ PDFRealizedFont::~PDFRealizedFont()
|
|||||||
delete m_impl;
|
delete m_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFRealizedFont::fillTextSequence(const QByteArray& byteArray, TextSequence& textSequence)
|
void PDFRealizedFont::fillTextSequence(const QByteArray& byteArray, TextSequence& textSequence, PDFRenderErrorReporter* reporter)
|
||||||
{
|
{
|
||||||
m_impl->fillTextSequence(byteArray, textSequence);
|
m_impl->fillTextSequence(byteArray, textSequence, reporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PDFRealizedFont::isHorizontalWritingSystem() const
|
bool PDFRealizedFont::isHorizontalWritingSystem() const
|
||||||
@ -580,6 +592,7 @@ PDFRealizedFontPointer PDFRealizedFont::createRealizedFont(PDFFontPointer font,
|
|||||||
|
|
||||||
PDFRealizedFontImpl* impl = implPtr.get();
|
PDFRealizedFontImpl* impl = implPtr.get();
|
||||||
impl->m_parentFont = font;
|
impl->m_parentFont = font;
|
||||||
|
impl->m_pixelSize = pixelSize;
|
||||||
|
|
||||||
const FontDescriptor* descriptor = font->getFontDescriptor();
|
const FontDescriptor* descriptor = font->getFontDescriptor();
|
||||||
if (descriptor->isEmbedded())
|
if (descriptor->isEmbedded())
|
||||||
@ -594,7 +607,7 @@ PDFRealizedFontPointer PDFRealizedFont::createRealizedFont(PDFFontPointer font,
|
|||||||
|
|
||||||
PDFRealizedFontImpl::checkFreeTypeError(FT_New_Memory_Face(impl->m_library, reinterpret_cast<const FT_Byte*>(impl->m_embeddedFontData.constData()), impl->m_embeddedFontData.size(), 0, &impl->m_face));
|
PDFRealizedFontImpl::checkFreeTypeError(FT_New_Memory_Face(impl->m_library, reinterpret_cast<const FT_Byte*>(impl->m_embeddedFontData.constData()), impl->m_embeddedFontData.size(), 0, &impl->m_face));
|
||||||
FT_Select_Charmap(impl->m_face, FT_ENCODING_UNICODE); // We try to select unicode encoding, but if it fails, we don't do anything (use glyph indices instead)
|
FT_Select_Charmap(impl->m_face, FT_ENCODING_UNICODE); // We try to select unicode encoding, but if it fails, we don't do anything (use glyph indices instead)
|
||||||
PDFRealizedFontImpl::checkFreeTypeError(FT_Set_Pixel_Sizes(impl->m_face, 0, qRound(pixelSize)));
|
PDFRealizedFontImpl::checkFreeTypeError(FT_Set_Pixel_Sizes(impl->m_face, 0, qRound(pixelSize * PDFRealizedFontImpl::PIXEL_SIZE_MULTIPLIER)));
|
||||||
impl->m_isVertical = impl->m_face->face_flags & FT_FACE_FLAG_VERTICAL;
|
impl->m_isVertical = impl->m_face->face_flags & FT_FACE_FLAG_VERTICAL;
|
||||||
impl->m_isEmbedded = true;
|
impl->m_isEmbedded = true;
|
||||||
result.reset(new PDFRealizedFont(implPtr.release()));
|
result.reset(new PDFRealizedFont(implPtr.release()));
|
||||||
@ -620,7 +633,7 @@ PDFRealizedFontPointer PDFRealizedFont::createRealizedFont(PDFFontPointer font,
|
|||||||
PDFRealizedFontImpl::checkFreeTypeError(FT_Init_FreeType(&impl->m_library));
|
PDFRealizedFontImpl::checkFreeTypeError(FT_Init_FreeType(&impl->m_library));
|
||||||
PDFRealizedFontImpl::checkFreeTypeError(FT_New_Memory_Face(impl->m_library, reinterpret_cast<const FT_Byte*>(impl->m_systemFontData.constData()), impl->m_systemFontData.size(), 0, &impl->m_face));
|
PDFRealizedFontImpl::checkFreeTypeError(FT_New_Memory_Face(impl->m_library, reinterpret_cast<const FT_Byte*>(impl->m_systemFontData.constData()), impl->m_systemFontData.size(), 0, &impl->m_face));
|
||||||
FT_Select_Charmap(impl->m_face, FT_ENCODING_UNICODE); // We try to select unicode encoding, but if it fails, we don't do anything (use glyph indices instead)
|
FT_Select_Charmap(impl->m_face, FT_ENCODING_UNICODE); // We try to select unicode encoding, but if it fails, we don't do anything (use glyph indices instead)
|
||||||
PDFRealizedFontImpl::checkFreeTypeError(FT_Set_Pixel_Sizes(impl->m_face, 0, qRound(pixelSize)));
|
PDFRealizedFontImpl::checkFreeTypeError(FT_Set_Pixel_Sizes(impl->m_face, 0, qRound(pixelSize * PDFRealizedFontImpl::PIXEL_SIZE_MULTIPLIER)));
|
||||||
impl->m_isVertical = impl->m_face->face_flags & FT_FACE_FLAG_VERTICAL;
|
impl->m_isVertical = impl->m_face->face_flags & FT_FACE_FLAG_VERTICAL;
|
||||||
impl->m_isEmbedded = false;
|
impl->m_isEmbedded = false;
|
||||||
result.reset(new PDFRealizedFont(implPtr.release()));
|
result.reset(new PDFRealizedFont(implPtr.release()));
|
||||||
@ -815,13 +828,7 @@ PDFFontPointer PDFFont::createFont(const PDFObject& object, const PDFDocument* d
|
|||||||
throw PDFParserException(PDFTranslationContext::tr("Invalid differences in encoding entry of the font."));
|
throw PDFParserException(PDFTranslationContext::tr("Invalid differences in encoding entry of the font."));
|
||||||
}
|
}
|
||||||
|
|
||||||
QChar character = PDFNameToUnicode::getUnicodeForName(item.getString());
|
QChar character = PDFNameToUnicode::getUnicodeUsingResolvedName(item.getString());
|
||||||
|
|
||||||
// Try ZapfDingbats, if this fails
|
|
||||||
if (character.isNull())
|
|
||||||
{
|
|
||||||
character = PDFNameToUnicode::getUnicodeForNameZapfDingbats(item.getString());
|
|
||||||
}
|
|
||||||
differences[currentOffset] = character;
|
differences[currentOffset] = character;
|
||||||
|
|
||||||
++currentOffset;
|
++currentOffset;
|
||||||
@ -1106,6 +1113,23 @@ PDFSimpleFont::PDFSimpleFont(FontDescriptor fontDescriptor,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFInteger PDFSimpleFont::getGlyphWidth(size_t index) const
|
||||||
|
{
|
||||||
|
const size_t min = m_firstChar;
|
||||||
|
const size_t max = m_lastChar;
|
||||||
|
|
||||||
|
if (index >= min && index <= max)
|
||||||
|
{
|
||||||
|
const size_t adjustedIndex = index - min;
|
||||||
|
if (adjustedIndex < m_widths.size())
|
||||||
|
{
|
||||||
|
return m_widths[adjustedIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PDFType1Font::PDFType1Font(FontDescriptor fontDescriptor,
|
PDFType1Font::PDFType1Font(FontDescriptor fontDescriptor,
|
||||||
QByteArray name,
|
QByteArray name,
|
||||||
QByteArray baseFont,
|
QByteArray baseFont,
|
||||||
|
@ -30,6 +30,7 @@ class QPainterPath;
|
|||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
class PDFDocument;
|
class PDFDocument;
|
||||||
|
class PDFRenderErrorReporter;
|
||||||
|
|
||||||
using CID = unsigned int;
|
using CID = unsigned int;
|
||||||
using GID = unsigned int;
|
using GID = unsigned int;
|
||||||
@ -217,7 +218,8 @@ public:
|
|||||||
/// produces glyphs for the font.
|
/// produces glyphs for the font.
|
||||||
/// \param byteArray Array of bytes to be interpreted
|
/// \param byteArray Array of bytes to be interpreted
|
||||||
/// \param textSequence Text sequence to be filled
|
/// \param textSequence Text sequence to be filled
|
||||||
void fillTextSequence(const QByteArray& byteArray, TextSequence& textSequence);
|
/// \param reporter Error reporter
|
||||||
|
void fillTextSequence(const QByteArray& byteArray, TextSequence& textSequence, PDFRenderErrorReporter* reporter);
|
||||||
|
|
||||||
/// Return true, if we have horizontal writing system
|
/// Return true, if we have horizontal writing system
|
||||||
bool isHorizontalWritingSystem() const;
|
bool isHorizontalWritingSystem() const;
|
||||||
@ -280,6 +282,9 @@ public:
|
|||||||
const encoding::EncodingTable* getEncoding() const { return &m_encoding; }
|
const encoding::EncodingTable* getEncoding() const { return &m_encoding; }
|
||||||
const GlyphIndices* getGlyphIndices() const { return &m_glyphIndices; }
|
const GlyphIndices* getGlyphIndices() const { return &m_glyphIndices; }
|
||||||
|
|
||||||
|
/// Returns the glyph width (or zero, if glyph width is invalid)
|
||||||
|
PDFInteger getGlyphWidth(size_t index) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QByteArray m_name;
|
QByteArray m_name;
|
||||||
QByteArray m_baseFont;
|
QByteArray m_baseFont;
|
||||||
|
@ -4540,4 +4540,27 @@ QChar PDFNameToUnicode::getUnicodeForNameZapfDingbats(const QByteArray& name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QChar PDFNameToUnicode::getUnicodeUsingResolvedName(const QByteArray& name)
|
||||||
|
{
|
||||||
|
QChar character = getUnicodeForName(name);
|
||||||
|
|
||||||
|
// Try ZapfDingbats, if this fails
|
||||||
|
if (character.isNull())
|
||||||
|
{
|
||||||
|
character = getUnicodeForNameZapfDingbats(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (character.isNull() && name.startsWith("uni"))
|
||||||
|
{
|
||||||
|
QByteArray hexValue = QByteArray::fromHex(name.mid(3, -1));
|
||||||
|
if (hexValue.size() == 2)
|
||||||
|
{
|
||||||
|
unsigned short value = (static_cast<unsigned char>(hexValue[0]) << 8) + static_cast<unsigned char>(hexValue[1]);
|
||||||
|
character = QChar(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return character;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -38,6 +38,9 @@ public:
|
|||||||
/// Returns unicode character for name (for ZapfDingbats). If name is not found, then null character is returned.
|
/// Returns unicode character for name (for ZapfDingbats). If name is not found, then null character is returned.
|
||||||
static QChar getUnicodeForNameZapfDingbats(const QByteArray& name);
|
static QChar getUnicodeForNameZapfDingbats(const QByteArray& name);
|
||||||
|
|
||||||
|
/// Tries to resolve unicode name
|
||||||
|
static QChar getUnicodeUsingResolvedName(const QByteArray& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Comparator
|
struct Comparator
|
||||||
{
|
{
|
||||||
|
@ -257,6 +257,11 @@ QList<PDFRenderError> PDFPageContentProcessor::processContents()
|
|||||||
return m_errorList;
|
return m_errorList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::reportRenderError(RenderErrorType type, QString message)
|
||||||
|
{
|
||||||
|
m_errorList.append(PDFRenderError(type, qMove(message)));
|
||||||
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::performPathPainting(const QPainterPath& path, bool stroke, bool fill, Qt::FillRule fillRule)
|
void PDFPageContentProcessor::performPathPainting(const QPainterPath& path, bool stroke, bool fill, Qt::FillRule fillRule)
|
||||||
{
|
{
|
||||||
Q_UNUSED(path);
|
Q_UNUSED(path);
|
||||||
@ -1654,7 +1659,7 @@ void PDFPageContentProcessor::operatorTextShowTextString(PDFOperandString text)
|
|||||||
|
|
||||||
// We use simple heuristic to ensure reallocation doesn't occur too often
|
// We use simple heuristic to ensure reallocation doesn't occur too often
|
||||||
textSequence.items.reserve(m_operands.size());
|
textSequence.items.reserve(m_operands.size());
|
||||||
realizedFont->fillTextSequence(text.string, textSequence);
|
realizedFont->fillTextSequence(text.string, textSequence, this);
|
||||||
drawText(textSequence);
|
drawText(textSequence);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1711,7 +1716,7 @@ void PDFPageContentProcessor::operatorTextShowTextIndividualSpacing()
|
|||||||
|
|
||||||
case PDFLexicalAnalyzer::TokenType::String:
|
case PDFLexicalAnalyzer::TokenType::String:
|
||||||
{
|
{
|
||||||
realizedFont->fillTextSequence(m_operands[i].data.toByteArray(), textSequence);
|
realizedFont->fillTextSequence(m_operands[i].data.toByteArray(), textSequence, this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace pdf
|
|||||||
static constexpr const char* PDF_RESOURCE_EXTGSTATE = "ExtGState";
|
static constexpr const char* PDF_RESOURCE_EXTGSTATE = "ExtGState";
|
||||||
|
|
||||||
/// Process the contents of the page.
|
/// Process the contents of the page.
|
||||||
class PDFPageContentProcessor
|
class PDFPageContentProcessor : public PDFRenderErrorReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit PDFPageContentProcessor(const PDFPage* page, const PDFDocument* document, const PDFFontCache* fontCache);
|
explicit PDFPageContentProcessor(const PDFPage* page, const PDFDocument* document, const PDFFontCache* fontCache);
|
||||||
@ -155,6 +155,8 @@ public:
|
|||||||
/// Process the contents of the page
|
/// Process the contents of the page
|
||||||
QList<PDFRenderError> processContents();
|
QList<PDFRenderError> processContents();
|
||||||
|
|
||||||
|
virtual void reportRenderError(RenderErrorType type, QString message) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
class PDFLineDashPattern
|
class PDFLineDashPattern
|
||||||
|
@ -56,6 +56,12 @@ PDFRenderingErrorsWidget::PDFRenderingErrorsWidget(QWidget* parent, PDFWidget* p
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case RenderErrorType::Warning:
|
||||||
|
{
|
||||||
|
typeString = tr("Warning");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case RenderErrorType::NotImplemented:
|
case RenderErrorType::NotImplemented:
|
||||||
{
|
{
|
||||||
typeString = tr("Not implemented");
|
typeString = tr("Not implemented");
|
||||||
|
Reference in New Issue
Block a user