Bugfix: inexact font loading using font name, warning about font substitution

This commit is contained in:
Jakub Melka
2019-10-02 19:37:19 +02:00
parent 2dfb653233
commit efef799c09
5 changed files with 51 additions and 12 deletions

View File

@ -52,7 +52,7 @@ public:
/// Loads font from descriptor /// Loads font from descriptor
/// \param descriptor Descriptor describing the font /// \param descriptor Descriptor describing the font
QByteArray loadFont(const FontDescriptor* descriptor, StandardFontType standardFontType) const; QByteArray loadFont(const FontDescriptor* descriptor, StandardFontType standardFontType, PDFRenderErrorReporter* reporter) const;
private: private:
explicit PDFSystemFontInfoStorage(); explicit PDFSystemFontInfoStorage();
@ -91,7 +91,7 @@ const PDFSystemFontInfoStorage* PDFSystemFontInfoStorage::getInstance()
return &instance; return &instance;
} }
QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor, StandardFontType standardFontType) const QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor, StandardFontType standardFontType, PDFRenderErrorReporter* reporter) const
{ {
QByteArray result; QByteArray result;
@ -187,7 +187,7 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor,
// and try to set weight // and try to set weight
QString fontFamily = QString::fromLatin1(descriptor->fontFamily); QString fontFamily = QString::fromLatin1(descriptor->fontFamily);
if (!fontFamily.isEmpty()) if (!fontFamily.isEmpty() && result.isEmpty())
{ {
for (const FontInfo& fontInfo : m_fontInfos) for (const FontInfo& fontInfo : m_fontInfos)
{ {
@ -199,6 +199,7 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor,
if (!result.isEmpty()) if (!result.isEmpty())
{ {
reporter->reportRenderError(RenderErrorType::Warning, PDFTranslationContext::tr("Inexact font substitution: font %1 replaced by %2 using font family %3.").arg(fontName, fontInfo.faceNameAdjusted, fontFamily));
break; break;
} }
} }
@ -218,6 +219,7 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor,
if (!result.isEmpty()) if (!result.isEmpty())
{ {
reporter->reportRenderError(RenderErrorType::Warning, PDFTranslationContext::tr("Inexact font substitution: font %1 replaced by %2 using font family %3.").arg(fontName, fontInfo.faceNameAdjusted, fontFamily));
break; break;
} }
} }
@ -225,6 +227,27 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor,
} }
} }
// Try to inexact match for font name - find similar font
if (!fontName.isEmpty() && result.isEmpty())
{
for (const FontInfo& fontInfo : m_fontInfos)
{
if (fontInfo.faceNameAdjusted.contains(fontName))
{
LOGFONT logFont = fontInfo.logFont;
logFont.lfWeight = descriptor->fontWeight;
logFont.lfItalic = lfItalic;
result = getFontData(&logFont, hdc);
if (!result.isEmpty())
{
reporter->reportRenderError(RenderErrorType::Warning, PDFTranslationContext::tr("Inexact font substitution: font %1 replaced by %2.").arg(fontName, fontInfo.faceNameAdjusted));
break;
}
}
}
}
ReleaseDC(NULL, hdc); ReleaseDC(NULL, hdc);
#endif #endif
@ -624,7 +647,7 @@ bool PDFRealizedFont::isHorizontalWritingSystem() const
return m_impl->isHorizontalWritingSystem(); return m_impl->isHorizontalWritingSystem();
} }
PDFRealizedFontPointer PDFRealizedFont::createRealizedFont(PDFFontPointer font, PDFReal pixelSize) PDFRealizedFontPointer PDFRealizedFont::createRealizedFont(PDFFontPointer font, PDFReal pixelSize, PDFRenderErrorReporter* reporter)
{ {
PDFRealizedFontPointer result; PDFRealizedFontPointer result;
@ -669,7 +692,7 @@ PDFRealizedFontPointer PDFRealizedFont::createRealizedFont(PDFFontPointer font,
} }
const PDFSystemFontInfoStorage* fontStorage = PDFSystemFontInfoStorage::getInstance(); const PDFSystemFontInfoStorage* fontStorage = PDFSystemFontInfoStorage::getInstance();
impl->m_systemFontData = fontStorage->loadFont(descriptor, standardFontType); impl->m_systemFontData = fontStorage->loadFont(descriptor, standardFontType, reporter);
if (impl->m_systemFontData.isEmpty()) if (impl->m_systemFontData.isEmpty())
{ {
@ -1393,7 +1416,7 @@ PDFFontPointer PDFFontCache::getFont(const PDFObject& fontObject) const
} }
} }
PDFRealizedFontPointer PDFFontCache::getRealizedFont(const PDFFontPointer& font, PDFReal size) const PDFRealizedFontPointer PDFFontCache::getRealizedFont(const PDFFontPointer& font, PDFReal size, PDFRenderErrorReporter* reporter) const
{ {
Q_ASSERT(font); Q_ASSERT(font);
@ -1402,7 +1425,7 @@ PDFRealizedFontPointer PDFFontCache::getRealizedFont(const PDFFontPointer& font,
if (it == m_realizedFontCache.cend()) if (it == m_realizedFontCache.cend())
{ {
// We must create the realized font // We must create the realized font
PDFRealizedFontPointer realizedFont = PDFRealizedFont::createRealizedFont(font, size); PDFRealizedFontPointer realizedFont = PDFRealizedFont::createRealizedFont(font, size, reporter);
if (m_realizedFontCache.size() >= m_realizedFontCacheLimit) if (m_realizedFontCache.size() >= m_realizedFontCacheLimit)
{ {

View File

@ -233,7 +233,7 @@ public:
/// Creates new realized font from the standard font. If font can't be created, /// Creates new realized font from the standard font. If font can't be created,
/// then exception is thrown. /// then exception is thrown.
static PDFRealizedFontPointer createRealizedFont(PDFFontPointer font, PDFReal pixelSize); static PDFRealizedFontPointer createRealizedFont(PDFFontPointer font, PDFReal pixelSize, PDFRenderErrorReporter* reporter);
private: private:
/// Constructs new realized font /// Constructs new realized font
@ -393,7 +393,8 @@ public:
/// then exception is thrown. /// then exception is thrown.
/// \param font Font, which should be realized /// \param font Font, which should be realized
/// \param size Size of the font (in pixels) /// \param size Size of the font (in pixels)
PDFRealizedFontPointer getRealizedFont(const PDFFontPointer& font, PDFReal size) const; /// \param reporter Error reporter
PDFRealizedFontPointer getRealizedFont(const PDFFontPointer& font, PDFReal size, PDFRenderErrorReporter* reporter) const;
private: private:
const size_t m_fontCacheLimit; const size_t m_fontCacheLimit;

View File

@ -2917,11 +2917,11 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
} }
} }
PDFRealizedFontPointer PDFPageContentProcessor::getRealizedFontImpl() const PDFRealizedFontPointer PDFPageContentProcessor::getRealizedFontImpl()
{ {
if (m_graphicState.getTextFont()) if (m_graphicState.getTextFont())
{ {
return m_fontCache->getRealizedFont(m_graphicState.getTextFont(), m_graphicState.getTextFontSize()); return m_fontCache->getRealizedFont(m_graphicState.getTextFont(), m_graphicState.getTextFontSize(), this);
} }
return PDFRealizedFontPointer(); return PDFRealizedFontPointer();

View File

@ -785,7 +785,7 @@ private:
const PDFRealizedFontPointer& getRealizedFont() { return m_realizedFont.get(this, &PDFPageContentProcessor::getRealizedFontImpl); } const PDFRealizedFontPointer& getRealizedFont() { return m_realizedFont.get(this, &PDFPageContentProcessor::getRealizedFontImpl); }
/// Returns realized font (or empty font, if font can't be realized) /// Returns realized font (or empty font, if font can't be realized)
PDFRealizedFontPointer getRealizedFontImpl() const; PDFRealizedFontPointer getRealizedFontImpl();
/// Checks, if stroking color is valid /// Checks, if stroking color is valid
void checkStrokingColor(); void checkStrokingColor();

View File

@ -59,6 +59,21 @@ public:
return m_object; return m_object;
} }
/// Returns the cached object. If object is dirty, then cached object is refreshed.
/// \param holder Holder object, which owns the cached item
/// \param function Refresh function
template<typename H>
inline const T& get(H* holder, T(H::* function)(void))
{
if (m_dirty)
{
m_object = (holder->*function)();
m_dirty = false;
}
return m_object;
}
/// Invalidates the cached item, so it must be refreshed from the cache next time, /// Invalidates the cached item, so it must be refreshed from the cache next time,
/// if it is accessed. /// if it is accessed.
inline void dirty() inline void dirty()