mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Issue #50: Fix of fonts, be more patient when PDF has error items
This commit is contained in:
		@@ -351,10 +351,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
 | 
			
		||||
                    {
 | 
			
		||||
                        result.m_optionFlags.setFlag(flag, flagObject.getBool());
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        throw PDFException(PDFTranslationContext::tr("Expected boolean value."));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            addFlag(PDF_VIEWER_PREFERENCES_HIDE_TOOLBAR, HideToolbar);
 | 
			
		||||
@@ -367,13 +363,8 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
 | 
			
		||||
 | 
			
		||||
            // 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();
 | 
			
		||||
                if (enumName == "UseNone")
 | 
			
		||||
                {
 | 
			
		||||
@@ -391,21 +382,12 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
 | 
			
		||||
                {
 | 
			
		||||
                    result.m_nonFullScreenPageMode = NonFullScreenPageMode::UseOptionalContent;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    throw PDFException(PDFTranslationContext::tr("Unknown viewer preferences settings."));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 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();
 | 
			
		||||
                if (enumName == "L2R")
 | 
			
		||||
                {
 | 
			
		||||
@@ -415,10 +397,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
 | 
			
		||||
                {
 | 
			
		||||
                    result.m_direction = Direction::RightToLeft;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    throw PDFException(PDFTranslationContext::tr("Unknown viewer preferences settings."));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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();
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        throw PDFException(PDFTranslationContext::tr("Expected name."));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            addProperty(PDF_VIEWER_PREFERENCES_VIEW_AREA, ViewArea);
 | 
			
		||||
@@ -443,13 +417,8 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
 | 
			
		||||
 | 
			
		||||
            // 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();
 | 
			
		||||
                if (enumName == "None")
 | 
			
		||||
                {
 | 
			
		||||
@@ -459,21 +428,12 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
 | 
			
		||||
                {
 | 
			
		||||
                    result.m_printScaling = PrintScaling::AppDefault;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    throw PDFException(PDFTranslationContext::tr("Unknown viewer preferences settings."));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 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();
 | 
			
		||||
                if (enumName == "Simplex")
 | 
			
		||||
                {
 | 
			
		||||
@@ -487,21 +447,12 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
 | 
			
		||||
                {
 | 
			
		||||
                    result.m_duplex = Duplex::DuplexFlipLongEdge;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    throw PDFException(PDFTranslationContext::tr("Unknown viewer preferences settings."));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 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:
 | 
			
		||||
                //  1) Array size is odd
 | 
			
		||||
                //  2) Array contains negative numbers
 | 
			
		||||
@@ -549,10 +500,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
 | 
			
		||||
                                    Q_ASSERT(false);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            throw PDFException(PDFTranslationContext::tr("Expected integer."));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // 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();
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    throw PDFException(PDFTranslationContext::tr("Expected integer."));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Enforce
 | 
			
		||||
@@ -582,10 +525,6 @@ PDFViewerPreferences PDFViewerPreferences::parse(const PDFObject& catalogDiction
 | 
			
		||||
            std::vector<QByteArray> enforce = loader.readNameArrayFromDictionary(viewerPreferencesDictionary, "Enforce");
 | 
			
		||||
            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;
 | 
			
		||||
@@ -609,10 +548,8 @@ PDFPageLabel PDFPageLabel::parse(PDFInteger pageIndex, const PDFObjectStorage* s
 | 
			
		||||
        const PDFInteger startNumber = loader.readInteger(dictionary->get("St"), 1);
 | 
			
		||||
        return PDFPageLabel(numberingStyle, prefix, pageIndex, startNumber);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        throw PDFException(PDFTranslationContext::tr("Expected page label dictionary."));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return PDFPageLabel();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
                    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);
 | 
			
		||||
@@ -762,15 +695,6 @@ PDFDocumentInfo PDFDocumentInfo::parse(const PDFObject& object, const PDFObjectS
 | 
			
		||||
                {
 | 
			
		||||
                    // We have succesfully read the string, convert it to date time
 | 
			
		||||
                    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;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    throw PDFException(PDFTranslationContext::tr("Bad format of document info entry in trailer dictionary. Trapping information expected"));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (nameObject.isBool())
 | 
			
		||||
            {
 | 
			
		||||
                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
 | 
			
		||||
 
 | 
			
		||||
@@ -983,6 +983,11 @@ PDFRealizedFontPointer PDFRealizedFont::createRealizedFont(PDFFontPointer font,
 | 
			
		||||
{
 | 
			
		||||
    PDFRealizedFontPointer result;
 | 
			
		||||
 | 
			
		||||
    if (pixelSize < 0.0)
 | 
			
		||||
    {
 | 
			
		||||
        pixelSize = qAbs(pixelSize);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (font->getFontType() == FontType::Type3)
 | 
			
		||||
    {
 | 
			
		||||
        result.reset(new PDFRealizedFont(new PDFRealizedType3FontImpl(font, pixelSize)));
 | 
			
		||||
 
 | 
			
		||||
@@ -2691,7 +2691,14 @@ void PDFPageContentProcessor::operatorTextSetWordSpacing(PDFReal wordSpacing)
 | 
			
		||||
void PDFPageContentProcessor::operatorTextSetHorizontalScale(PDFReal horizontalScaling)
 | 
			
		||||
{
 | 
			
		||||
    // 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);
 | 
			
		||||
    updateGraphicState();
 | 
			
		||||
@@ -3176,7 +3183,8 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
 | 
			
		||||
        const bool isHorizontalWritingSystem = font->isHorizontalWritingSystem();
 | 
			
		||||
 | 
			
		||||
        // 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();
 | 
			
		||||
 | 
			
		||||
        if (!isType3Font)
 | 
			
		||||
@@ -3201,7 +3209,7 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
 | 
			
		||||
                    {
 | 
			
		||||
                        advance.ry() += additionalAdvance;
 | 
			
		||||
                    }
 | 
			
		||||
                    advance.rx() *= horizontalScaling;
 | 
			
		||||
                    advance.rx() *= horizontalScaling * fontFactor;
 | 
			
		||||
 | 
			
		||||
                    // Then get the glyph path and paint it
 | 
			
		||||
                    if (item.glyph)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user