Issue #50: Fix of fonts, be more patient when PDF has error items

This commit is contained in:
Jakub Melka 2023-04-30 17:52:01 +02:00
parent 0b47464241
commit 349efcbf88
3 changed files with 23 additions and 94 deletions

View File

@ -351,10 +351,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
{ {
result.m_optionFlags.setFlag(flag, flagObject.getBool()); result.m_optionFlags.setFlag(flag, flagObject.getBool());
} }
else
{
throw PDFException(PDFTranslationContext::tr("Expected boolean value."));
}
} }
}; };
addFlag(PDF_VIEWER_PREFERENCES_HIDE_TOOLBAR, HideToolbar); addFlag(PDF_VIEWER_PREFERENCES_HIDE_TOOLBAR, HideToolbar);
@ -367,13 +363,8 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
// Non-fullscreen page mode // Non-fullscreen page mode
const PDFObject& nonFullscreenPageMode = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_NON_FULLSCREEN_PAGE_MODE)); const PDFObject& nonFullscreenPageMode = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_NON_FULLSCREEN_PAGE_MODE));
if (!nonFullscreenPageMode.isNull()) if (nonFullscreenPageMode.isName())
{ {
if (!nonFullscreenPageMode.isName())
{
throw PDFException(PDFTranslationContext::tr("Expected name."));
}
QByteArray enumName = nonFullscreenPageMode.getString(); QByteArray enumName = nonFullscreenPageMode.getString();
if (enumName == "UseNone") if (enumName == "UseNone")
{ {
@ -391,21 +382,12 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
{ {
result.m_nonFullScreenPageMode = NonFullScreenPageMode::UseOptionalContent; result.m_nonFullScreenPageMode = NonFullScreenPageMode::UseOptionalContent;
} }
else
{
throw PDFException(PDFTranslationContext::tr("Unknown viewer preferences settings."));
}
} }
// Direction // Direction
const PDFObject& direction = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_DIRECTION)); const PDFObject& direction = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_DIRECTION));
if (!direction.isNull()) if (direction.isName())
{ {
if (!direction.isName())
{
throw PDFException(PDFTranslationContext::tr("Expected name."));
}
QByteArray enumName = direction.getString(); QByteArray enumName = direction.getString();
if (enumName == "L2R") if (enumName == "L2R")
{ {
@ -415,10 +397,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
{ {
result.m_direction = Direction::RightToLeft; result.m_direction = Direction::RightToLeft;
} }
else
{
throw PDFException(PDFTranslationContext::tr("Unknown viewer preferences settings."));
}
} }
auto addProperty = [&result, viewerPreferencesDictionary, document] (const char* name, Properties property) auto addProperty = [&result, viewerPreferencesDictionary, document] (const char* name, Properties property)
@ -430,10 +408,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
{ {
result.m_properties[property] = propertyObject.getString(); result.m_properties[property] = propertyObject.getString();
} }
else
{
throw PDFException(PDFTranslationContext::tr("Expected name."));
}
} }
}; };
addProperty(PDF_VIEWER_PREFERENCES_VIEW_AREA, ViewArea); addProperty(PDF_VIEWER_PREFERENCES_VIEW_AREA, ViewArea);
@ -443,13 +417,8 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
// Print scaling // Print scaling
const PDFObject& printScaling = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_PRINT_SCALING)); const PDFObject& printScaling = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_PRINT_SCALING));
if (!printScaling.isNull()) if (printScaling.isName())
{ {
if (!printScaling.isName())
{
throw PDFException(PDFTranslationContext::tr("Expected name."));
}
QByteArray enumName = printScaling.getString(); QByteArray enumName = printScaling.getString();
if (enumName == "None") if (enumName == "None")
{ {
@ -459,21 +428,12 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
{ {
result.m_printScaling = PrintScaling::AppDefault; result.m_printScaling = PrintScaling::AppDefault;
} }
else
{
throw PDFException(PDFTranslationContext::tr("Unknown viewer preferences settings."));
}
} }
// Duplex // Duplex
const PDFObject& duplex = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_DUPLEX)); const PDFObject& duplex = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_DUPLEX));
if (!duplex.isNull()) if (duplex.isName())
{ {
if (!duplex.isName())
{
throw PDFException(PDFTranslationContext::tr("Expected name."));
}
QByteArray enumName = duplex.getString(); QByteArray enumName = duplex.getString();
if (enumName == "Simplex") if (enumName == "Simplex")
{ {
@ -487,21 +447,12 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
{ {
result.m_duplex = Duplex::DuplexFlipLongEdge; result.m_duplex = Duplex::DuplexFlipLongEdge;
} }
else
{
throw PDFException(PDFTranslationContext::tr("Unknown viewer preferences settings."));
}
} }
// Print page range // Print page range
const PDFObject& printPageRange = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_PRINT_PAGE_RANGE)); const PDFObject& printPageRange = document->getObject(viewerPreferencesDictionary->get(PDF_VIEWER_PREFERENCES_PRINT_PAGE_RANGE));
if (!printPageRange.isNull()) if (printPageRange.isArray())
{ {
if (!duplex.isArray())
{
throw PDFException(PDFTranslationContext::tr("Expected array of integers."));
}
// According to PDF Reference 1.7, this entry is ignored in following cases: // According to PDF Reference 1.7, this entry is ignored in following cases:
// 1) Array size is odd // 1) Array size is odd
// 2) Array contains negative numbers // 2) Array contains negative numbers
@ -549,10 +500,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
Q_ASSERT(false); Q_ASSERT(false);
} }
} }
else
{
throw PDFException(PDFTranslationContext::tr("Expected integer."));
}
} }
// Did we get negative or zero value? If yes, clear the range. // Did we get negative or zero value? If yes, clear the range.
@ -571,10 +518,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
{ {
result.m_numberOfCopies = numberOfCopies.getInteger(); result.m_numberOfCopies = numberOfCopies.getInteger();
} }
else
{
throw PDFException(PDFTranslationContext::tr("Expected integer."));
}
} }
// Enforce // Enforce
@ -582,10 +525,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
std::vector<QByteArray> enforce = loader.readNameArrayFromDictionary(viewerPreferencesDictionary, "Enforce"); std::vector<QByteArray> enforce = loader.readNameArrayFromDictionary(viewerPreferencesDictionary, "Enforce");
result.m_optionFlags.setFlag(EnforcePrintScaling, std::find(enforce.cbegin(), enforce.cend(), "PrintScaling") != enforce.cend()); result.m_optionFlags.setFlag(EnforcePrintScaling, std::find(enforce.cbegin(), enforce.cend(), "PrintScaling") != enforce.cend());
} }
else if (!viewerPreferencesObject.isNull())
{
throw PDFException(PDFTranslationContext::tr("Viewer preferences must be a dictionary."));
}
} }
return result; return result;
@ -609,10 +548,8 @@ PDFPageLabel PDFPageLabel::parse(PDFInteger pageIndex, const PDFObjectStorage* s
const PDFInteger startNumber = loader.readInteger(dictionary->get("St"), 1); const PDFInteger startNumber = loader.readInteger(dictionary->get("St"), 1);
return PDFPageLabel(numberingStyle, prefix, pageIndex, startNumber); return PDFPageLabel(numberingStyle, prefix, pageIndex, startNumber);
} }
else
{ return PDFPageLabel();
throw PDFException(PDFTranslationContext::tr("Expected page label dictionary."));
}
} }
const PDFDocumentSecurityStore::SecurityStoreItem* PDFDocumentSecurityStore::getItem(const QByteArray& hash) const const PDFDocumentSecurityStore::SecurityStoreItem* PDFDocumentSecurityStore::getItem(const QByteArray& hash) const
@ -740,10 +677,6 @@ PDFDocumentInfo PDFDocumentInfo::parse(const PDFObject& object, const PDFObjectS
// We have succesfully read the string, convert it according to encoding // We have succesfully read the string, convert it according to encoding
fillEntry = PDFEncoding::convertTextString(stringObject.getString()); fillEntry = PDFEncoding::convertTextString(stringObject.getString());
} }
else if (!stringObject.isNull())
{
throw PDFException(PDFTranslationContext::tr("Bad format of document info entry in trailer dictionary. String expected."));
}
} }
}; };
readTextString(PDF_DOCUMENT_INFO_ENTRY_TITLE, info.title); readTextString(PDF_DOCUMENT_INFO_ENTRY_TITLE, info.title);
@ -762,15 +695,6 @@ PDFDocumentInfo PDFDocumentInfo::parse(const PDFObject& object, const PDFObjectS
{ {
// We have succesfully read the string, convert it to date time // We have succesfully read the string, convert it to date time
fillEntry = PDFEncoding::convertToDateTime(stringObject.getString()); fillEntry = PDFEncoding::convertToDateTime(stringObject.getString());
if (!fillEntry.isValid())
{
throw PDFException(PDFTranslationContext::tr("Bad format of document info entry in trailer dictionary. String with date time format expected."));
}
}
else if (!stringObject.isNull())
{
throw PDFException(PDFTranslationContext::tr("Bad format of document info entry in trailer dictionary. String with date time format expected."));
} }
} }
}; };
@ -795,19 +719,11 @@ PDFDocumentInfo PDFDocumentInfo::parse(const PDFObject& object, const PDFObjectS
{ {
info.trapped = Trapped::Unknown; info.trapped = Trapped::Unknown;
} }
else
{
throw PDFException(PDFTranslationContext::tr("Bad format of document info entry in trailer dictionary. Trapping information expected"));
}
} }
else if (nameObject.isBool()) else if (nameObject.isBool())
{ {
info.trapped = nameObject.getBool() ? Trapped::True : Trapped::False; info.trapped = nameObject.getBool() ? Trapped::True : Trapped::False;
} }
else
{
throw PDFException(PDFTranslationContext::tr("Bad format of document info entry in trailer dictionary. Trapping information expected"));
}
} }
// Scan for extra items // Scan for extra items

View File

@ -983,6 +983,11 @@ PDFRealizedFontPointer PDFRealizedFont::createRealizedFont(PDFFontPointer font,
{ {
PDFRealizedFontPointer result; PDFRealizedFontPointer result;
if (pixelSize < 0.0)
{
pixelSize = qAbs(pixelSize);
}
if (font->getFontType() == FontType::Type3) if (font->getFontType() == FontType::Type3)
{ {
result.reset(new PDFRealizedFont(new PDFRealizedType3FontImpl(font, pixelSize))); result.reset(new PDFRealizedFont(new PDFRealizedType3FontImpl(font, pixelSize)));

View File

@ -2691,7 +2691,14 @@ void PDFPageContentProcessor::operatorTextSetWordSpacing(PDFReal wordSpacing)
void PDFPageContentProcessor::operatorTextSetHorizontalScale(PDFReal horizontalScaling) void PDFPageContentProcessor::operatorTextSetHorizontalScale(PDFReal horizontalScaling)
{ {
// We disable horizontal scaling to less than 1% // We disable horizontal scaling to less than 1%
horizontalScaling = qMax(horizontalScaling, 1.0); if (horizontalScaling >= 0.0 && horizontalScaling < 1.0)
{
horizontalScaling = 1.0;
}
if (horizontalScaling < 0.0 && horizontalScaling > -1.0)
{
horizontalScaling = -1.0;
}
m_graphicState.setTextHorizontalScaling(horizontalScaling); m_graphicState.setTextHorizontalScaling(horizontalScaling);
updateGraphicState(); updateGraphicState();
@ -3176,7 +3183,8 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
const bool isHorizontalWritingSystem = font->isHorizontalWritingSystem(); const bool isHorizontalWritingSystem = font->isHorizontalWritingSystem();
// Calculate text rendering matrix // Calculate text rendering matrix
QTransform adjustMatrix(horizontalScaling, 0.0, 0.0, 1.0, 0.0, textRise); const PDFReal fontFactor = (fontSize < 0.0) ? -1.0 : 1.0;
QTransform adjustMatrix(horizontalScaling * fontFactor, 0.0, 0.0, fontFactor, 0.0, textRise);
QTransform textMatrix = m_graphicState.getTextMatrix(); QTransform textMatrix = m_graphicState.getTextMatrix();
if (!isType3Font) if (!isType3Font)
@ -3201,7 +3209,7 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
{ {
advance.ry() += additionalAdvance; advance.ry() += additionalAdvance;
} }
advance.rx() *= horizontalScaling; advance.rx() *= horizontalScaling * fontFactor;
// Then get the glyph path and paint it // Then get the glyph path and paint it
if (item.glyph) if (item.glyph)