mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Font information
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include <QMutex>
|
||||
#include <QPainterPath>
|
||||
#include <QDataStream>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "Windows.h"
|
||||
@@ -350,6 +351,9 @@ public:
|
||||
|
||||
/// Returns true, if font has horizontal writing system
|
||||
virtual bool isHorizontalWritingSystem() const = 0;
|
||||
|
||||
/// Dumps information about the font
|
||||
virtual void dumpFontToTreeItem(QTreeWidgetItem* item) const { Q_UNUSED(item); }
|
||||
};
|
||||
|
||||
/// Implementation of the PDFRealizedFont class using PIMPL pattern for Type 3 fonts
|
||||
@@ -379,6 +383,7 @@ public:
|
||||
|
||||
virtual void fillTextSequence(const QByteArray& byteArray, TextSequence& textSequence, PDFRenderErrorReporter* reporter) override;
|
||||
virtual bool isHorizontalWritingSystem() const override { return !m_isVertical; }
|
||||
virtual void dumpFontToTreeItem(QTreeWidgetItem* item) const override;
|
||||
|
||||
static constexpr const PDFReal PIXEL_SIZE_MULTIPLIER = 100.0;
|
||||
|
||||
@@ -553,6 +558,107 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ
|
||||
}
|
||||
}
|
||||
|
||||
void PDFRealizedFontImpl::dumpFontToTreeItem(QTreeWidgetItem* item) const
|
||||
{
|
||||
QTreeWidgetItem* root = new QTreeWidgetItem(item, { PDFTranslationContext::tr("Details") });
|
||||
|
||||
if (m_face->family_name)
|
||||
{
|
||||
new QTreeWidgetItem(root, { PDFTranslationContext::tr("Font"), QString::fromLatin1(m_face->family_name) });
|
||||
}
|
||||
if (m_face->style_name)
|
||||
{
|
||||
new QTreeWidgetItem(root, { PDFTranslationContext::tr("Style"), QString::fromLatin1(m_face->style_name) });
|
||||
}
|
||||
|
||||
QString yesString = PDFTranslationContext::tr("Yes");
|
||||
QString noString = PDFTranslationContext::tr("No");
|
||||
|
||||
new QTreeWidgetItem(root, { PDFTranslationContext::tr("Glyph count"), QString::number(m_face->num_glyphs) });
|
||||
new QTreeWidgetItem(root, { PDFTranslationContext::tr("Is CID keyed"), (m_face->face_flags & FT_FACE_FLAG_CID_KEYED) ? yesString : noString });
|
||||
new QTreeWidgetItem(root, { PDFTranslationContext::tr("Is bold"), (m_face->style_flags & FT_STYLE_FLAG_BOLD) ? yesString : noString });
|
||||
new QTreeWidgetItem(root, { PDFTranslationContext::tr("Is italics"), (m_face->style_flags & FT_STYLE_FLAG_ITALIC) ? yesString : noString });
|
||||
new QTreeWidgetItem(root, { PDFTranslationContext::tr("Has vertical writing system"), (m_face->face_flags & FT_FACE_FLAG_VERTICAL) ? yesString : noString });
|
||||
new QTreeWidgetItem(root, { PDFTranslationContext::tr("Has SFNT storage scheme"), (m_face->face_flags & FT_FACE_FLAG_SFNT) ? yesString : noString });
|
||||
new QTreeWidgetItem(root, { PDFTranslationContext::tr("Has glyph names"), (m_face->face_flags & FT_FACE_FLAG_GLYPH_NAMES) ? yesString : noString });
|
||||
|
||||
if (m_face->num_charmaps > 0)
|
||||
{
|
||||
QTreeWidgetItem* encodingRoot = new QTreeWidgetItem(item, { PDFTranslationContext::tr("Encoding") });
|
||||
for (FT_Int i = 0; i < m_face->num_charmaps; ++i)
|
||||
{
|
||||
FT_CharMap charMap = m_face->charmaps[i];
|
||||
|
||||
const FT_Encoding encoding = charMap->encoding;
|
||||
QString encodingName;
|
||||
switch (encoding)
|
||||
{
|
||||
case FT_ENCODING_NONE:
|
||||
encodingName = PDFTranslationContext::tr("None");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_UNICODE:
|
||||
encodingName = PDFTranslationContext::tr("Unicode");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_MS_SYMBOL:
|
||||
encodingName = PDFTranslationContext::tr("MS Symbol");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_SJIS:
|
||||
encodingName = PDFTranslationContext::tr("Japanese Shift JIS");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_PRC:
|
||||
encodingName = PDFTranslationContext::tr("PRC - Simplified Chinese");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_BIG5:
|
||||
encodingName = PDFTranslationContext::tr("Traditional Chinese");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_WANSUNG:
|
||||
encodingName = PDFTranslationContext::tr("Korean Extended Wansung");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_JOHAB:
|
||||
encodingName = PDFTranslationContext::tr("Korean Standard");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_ADOBE_STANDARD:
|
||||
encodingName = PDFTranslationContext::tr("Adobe Standard");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_ADOBE_EXPERT:
|
||||
encodingName = PDFTranslationContext::tr("Adobe Expert");
|
||||
break;
|
||||
case FT_ENCODING_ADOBE_CUSTOM:
|
||||
encodingName = PDFTranslationContext::tr("Adobe Custom");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_ADOBE_LATIN_1:
|
||||
encodingName = PDFTranslationContext::tr("Adobe Latin 1");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_OLD_LATIN_2:
|
||||
encodingName = PDFTranslationContext::tr("Old Latin 1");
|
||||
break;
|
||||
|
||||
case FT_ENCODING_APPLE_ROMAN:
|
||||
encodingName = PDFTranslationContext::tr("Apple Roman");
|
||||
break;
|
||||
|
||||
default:
|
||||
encodingName = PDFTranslationContext::tr("Unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
QString encodingString = PDFTranslationContext::tr("Platform/Encoding = %1 %2").arg(charMap->platform_id).arg(charMap->encoding_id);
|
||||
new QTreeWidgetItem(encodingRoot, { encodingName, encodingString });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int PDFRealizedFontImpl::outlineMoveTo(const FT_Vector* to, void* user)
|
||||
{
|
||||
Glyph* glyph = reinterpret_cast<Glyph*>(user);
|
||||
@@ -647,6 +753,11 @@ bool PDFRealizedFont::isHorizontalWritingSystem() const
|
||||
return m_impl->isHorizontalWritingSystem();
|
||||
}
|
||||
|
||||
void PDFRealizedFont::dumpFontToTreeItem(QTreeWidgetItem* item) const
|
||||
{
|
||||
m_impl->dumpFontToTreeItem(item);
|
||||
}
|
||||
|
||||
PDFRealizedFontPointer PDFRealizedFont::createRealizedFont(PDFFontPointer font, PDFReal pixelSize, PDFRenderErrorReporter* reporter)
|
||||
{
|
||||
PDFRealizedFontPointer result;
|
||||
@@ -1347,6 +1458,59 @@ PDFInteger PDFSimpleFont::getGlyphAdvance(size_t index) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PDFSimpleFont::dumpFontToTreeItem(QTreeWidgetItem* item) const
|
||||
{
|
||||
BaseClass::dumpFontToTreeItem(item);
|
||||
|
||||
QString encodingTypeString;
|
||||
switch (m_encodingType)
|
||||
{
|
||||
case PDFEncoding::Encoding::Standard:
|
||||
encodingTypeString = PDFTranslationContext::tr("Standard");
|
||||
break;
|
||||
|
||||
case PDFEncoding::Encoding::MacRoman:
|
||||
encodingTypeString = PDFTranslationContext::tr("Mac Roman");
|
||||
break;
|
||||
|
||||
case PDFEncoding::Encoding::WinAnsi:
|
||||
encodingTypeString = PDFTranslationContext::tr("Win Ansi");
|
||||
break;
|
||||
|
||||
case PDFEncoding::Encoding::PDFDoc:
|
||||
encodingTypeString = PDFTranslationContext::tr("PDF Doc");
|
||||
break;
|
||||
|
||||
case PDFEncoding::Encoding::MacExpert:
|
||||
encodingTypeString = PDFTranslationContext::tr("Mac Expert");
|
||||
break;
|
||||
|
||||
case PDFEncoding::Encoding::Symbol:
|
||||
encodingTypeString = PDFTranslationContext::tr("Symbol");
|
||||
break;
|
||||
|
||||
case PDFEncoding::Encoding::ZapfDingbats:
|
||||
encodingTypeString = PDFTranslationContext::tr("Zapf Dingbats");
|
||||
break;
|
||||
|
||||
case PDFEncoding::Encoding::MacOsRoman:
|
||||
encodingTypeString = PDFTranslationContext::tr("Mac OS Roman");
|
||||
break;
|
||||
|
||||
case PDFEncoding::Encoding::Custom:
|
||||
encodingTypeString = PDFTranslationContext::tr("Custom");
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
new QTreeWidgetItem(item, { PDFTranslationContext::tr("Encoding"), encodingTypeString });
|
||||
}
|
||||
|
||||
PDFType1Font::PDFType1Font(FontDescriptor fontDescriptor,
|
||||
QByteArray name,
|
||||
QByteArray baseFont,
|
||||
@@ -1368,6 +1532,53 @@ FontType PDFType1Font::getFontType() const
|
||||
return FontType::Type1;
|
||||
}
|
||||
|
||||
void PDFType1Font::dumpFontToTreeItem(QTreeWidgetItem* item) const
|
||||
{
|
||||
BaseClass::dumpFontToTreeItem(item);
|
||||
|
||||
if (m_standardFontType != StandardFontType::Invalid)
|
||||
{
|
||||
QString standardFontTypeString;
|
||||
switch (m_standardFontType)
|
||||
{
|
||||
case StandardFontType::TimesRoman:
|
||||
case StandardFontType::TimesRomanBold:
|
||||
case StandardFontType::TimesRomanItalics:
|
||||
case StandardFontType::TimesRomanBoldItalics:
|
||||
standardFontTypeString = PDFTranslationContext::tr("Times Roman");
|
||||
break;
|
||||
|
||||
case StandardFontType::Helvetica:
|
||||
case StandardFontType::HelveticaBold:
|
||||
case StandardFontType::HelveticaOblique:
|
||||
case StandardFontType::HelveticaBoldOblique:
|
||||
standardFontTypeString = PDFTranslationContext::tr("Helvetica");
|
||||
break;
|
||||
|
||||
case StandardFontType::Courier:
|
||||
case StandardFontType::CourierBold:
|
||||
case StandardFontType::CourierOblique:
|
||||
case StandardFontType::CourierBoldOblique:
|
||||
standardFontTypeString = PDFTranslationContext::tr("Courier");
|
||||
break;
|
||||
|
||||
case StandardFontType::Symbol:
|
||||
standardFontTypeString = PDFTranslationContext::tr("Symbol");
|
||||
break;
|
||||
|
||||
case StandardFontType::ZapfDingbats:
|
||||
standardFontTypeString = PDFTranslationContext::tr("Zapf Dingbats");
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
new QTreeWidgetItem(item, { PDFTranslationContext::tr("Standard font"), standardFontTypeString });
|
||||
}
|
||||
}
|
||||
|
||||
FontType PDFTrueTypeFont::getFontType() const
|
||||
{
|
||||
return FontType::TrueType;
|
||||
@@ -1920,6 +2131,11 @@ FontType PDFType3Font::getFontType() const
|
||||
return FontType::Type3;
|
||||
}
|
||||
|
||||
void PDFType3Font::dumpFontToTreeItem(QTreeWidgetItem* item) const
|
||||
{
|
||||
new QTreeWidgetItem(item, { PDFTranslationContext::tr("Character count"), QString::number(m_characterContentStreams.size()) });
|
||||
}
|
||||
|
||||
double PDFType3Font::getWidth(int characterIndex) const
|
||||
{
|
||||
if (characterIndex >= m_firstCharacterIndex && characterIndex <= m_lastCharacterIndex)
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <QFont>
|
||||
#include <QMatrix>
|
||||
#include <QSharedPointer>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -166,7 +167,7 @@ static constexpr PDFEncoding::Encoding getEncodingForStandardFont(StandardFontTy
|
||||
}
|
||||
}
|
||||
|
||||
struct FontDescriptor
|
||||
struct PDFFORQTLIBSHARED_EXPORT FontDescriptor
|
||||
{
|
||||
bool isEmbedded() const { return !fontFile.isEmpty() || !fontFile2.isEmpty() || !fontFile3.isEmpty(); }
|
||||
|
||||
@@ -216,7 +217,7 @@ using PDFRealizedFontPointer = QSharedPointer<PDFRealizedFont>;
|
||||
|
||||
/// Font, which has fixed pixel size. It is programmed as PIMPL, because we need
|
||||
/// to remove FreeType types from the interface (so we do not include FreeType in the interface).
|
||||
class PDFRealizedFont
|
||||
class PDFFORQTLIBSHARED_EXPORT PDFRealizedFont
|
||||
{
|
||||
public:
|
||||
~PDFRealizedFont();
|
||||
@@ -231,6 +232,9 @@ public:
|
||||
/// Return true, if we have horizontal writing system
|
||||
bool isHorizontalWritingSystem() const;
|
||||
|
||||
/// Adds information about the font into tree item
|
||||
void dumpFontToTreeItem(QTreeWidgetItem* item) const;
|
||||
|
||||
/// Creates new realized font from the standard font. If font can't be created,
|
||||
/// then exception is thrown.
|
||||
static PDFRealizedFontPointer createRealizedFont(PDFFontPointer font, PDFReal pixelSize, PDFRenderErrorReporter* reporter);
|
||||
@@ -243,7 +247,7 @@ private:
|
||||
};
|
||||
|
||||
/// Base class representing font in the PDF file
|
||||
class PDFFont
|
||||
class PDFFORQTLIBSHARED_EXPORT PDFFont
|
||||
{
|
||||
public:
|
||||
explicit PDFFont(FontDescriptor fontDescriptor);
|
||||
@@ -255,6 +259,9 @@ public:
|
||||
/// Returns font descriptor
|
||||
const FontDescriptor* getFontDescriptor() const { return &m_fontDescriptor; }
|
||||
|
||||
/// Adds information about the font into tree item
|
||||
virtual void dumpFontToTreeItem(QTreeWidgetItem* item) const { Q_UNUSED(item); }
|
||||
|
||||
/// Creates font from the object. If font can't be created, exception is thrown.
|
||||
/// \param object Font dictionary
|
||||
/// \param document Document
|
||||
@@ -274,6 +281,8 @@ private:
|
||||
/// which maps single-byte character to the glyph in the font.
|
||||
class PDFSimpleFont : public PDFFont
|
||||
{
|
||||
using BaseClass = PDFFont;
|
||||
|
||||
public:
|
||||
explicit PDFSimpleFont(FontDescriptor fontDescriptor,
|
||||
QByteArray name,
|
||||
@@ -292,6 +301,8 @@ public:
|
||||
/// Returns the glyph advance (or zero, if glyph advance is invalid)
|
||||
PDFInteger getGlyphAdvance(size_t index) const;
|
||||
|
||||
virtual void dumpFontToTreeItem(QTreeWidgetItem* item) const override;
|
||||
|
||||
protected:
|
||||
QByteArray m_name;
|
||||
QByteArray m_baseFont;
|
||||
@@ -305,6 +316,8 @@ protected:
|
||||
|
||||
class PDFType1Font : public PDFSimpleFont
|
||||
{
|
||||
using BaseClass = PDFSimpleFont;
|
||||
|
||||
public:
|
||||
explicit PDFType1Font(FontDescriptor fontDescriptor,
|
||||
QByteArray name,
|
||||
@@ -319,6 +332,7 @@ public:
|
||||
virtual ~PDFType1Font() override = default;
|
||||
|
||||
virtual FontType getFontType() const override;
|
||||
virtual void dumpFontToTreeItem(QTreeWidgetItem*item) const override;
|
||||
|
||||
/// Returns the assigned standard font (or invalid, if font is not standard)
|
||||
StandardFontType getStandardFontType() const { return m_standardFontType; }
|
||||
@@ -347,6 +361,7 @@ public:
|
||||
const PDFObject& resources);
|
||||
|
||||
virtual FontType getFontType() const override;
|
||||
virtual void dumpFontToTreeItem(QTreeWidgetItem*item) const override;
|
||||
|
||||
/// Returns width of the character. If character doesn't exist, then zero is returned.
|
||||
double getWidth(int characterIndex) const;
|
||||
|
@@ -226,7 +226,7 @@ private:
|
||||
/// an array of pairs key-value, where key is name object and value is any
|
||||
/// PDF object. For this reason, we use QByteArray for key. We do not use
|
||||
/// map, because dictionaries are usually small.
|
||||
class PDFDictionary : public PDFObjectContent
|
||||
class PDFFORQTLIBSHARED_EXPORT PDFDictionary : public PDFObjectContent
|
||||
{
|
||||
public:
|
||||
using DictionaryEntry = std::pair<QByteArray, PDFObject>;
|
||||
|
Reference in New Issue
Block a user