2019-03-25 18:44:45 +01:00
|
|
|
// Copyright (C) 2019 Jakub Melka
|
|
|
|
//
|
|
|
|
// This file is part of PdfForQt.
|
|
|
|
//
|
|
|
|
// PdfForQt is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// PdfForQt is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#ifndef PDFFONT_H
|
|
|
|
#define PDFFONT_H
|
|
|
|
|
|
|
|
#include "pdfglobal.h"
|
2019-03-30 18:45:30 +01:00
|
|
|
#include "pdfencoding.h"
|
|
|
|
#include "pdfobject.h"
|
2019-03-25 18:44:45 +01:00
|
|
|
|
2019-03-30 18:45:30 +01:00
|
|
|
#include <QRawFont>
|
2019-03-25 18:44:45 +01:00
|
|
|
#include <QSharedPointer>
|
|
|
|
|
|
|
|
namespace pdf
|
|
|
|
{
|
2019-03-30 18:45:30 +01:00
|
|
|
class PDFDocument;
|
2019-03-25 18:44:45 +01:00
|
|
|
|
|
|
|
enum class TextRenderingMode
|
|
|
|
{
|
|
|
|
Fill = 0,
|
|
|
|
Stroke = 1,
|
|
|
|
FillStroke = 2,
|
|
|
|
Invisible = 3,
|
|
|
|
FillClip = 4,
|
|
|
|
StrokeClip = 5,
|
|
|
|
FillStrokeClip = 6,
|
|
|
|
Clip = 7
|
|
|
|
};
|
|
|
|
|
|
|
|
constexpr bool isTextRenderingModeFilled(TextRenderingMode mode)
|
|
|
|
{
|
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case TextRenderingMode::Fill:
|
|
|
|
case TextRenderingMode::FillClip:
|
|
|
|
case TextRenderingMode::FillStroke:
|
|
|
|
case TextRenderingMode::FillStrokeClip:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr bool isTextRenderingModeStroked(TextRenderingMode mode)
|
|
|
|
{
|
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case TextRenderingMode::Stroke:
|
|
|
|
case TextRenderingMode::FillStroke:
|
|
|
|
case TextRenderingMode::StrokeClip:
|
|
|
|
case TextRenderingMode::FillStrokeClip:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr bool isTextRenderingModeClipped(TextRenderingMode mode)
|
|
|
|
{
|
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case TextRenderingMode::Clip:
|
|
|
|
case TextRenderingMode::FillClip:
|
|
|
|
case TextRenderingMode::StrokeClip:
|
|
|
|
case TextRenderingMode::FillStrokeClip:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-30 18:45:30 +01:00
|
|
|
enum class FontType
|
|
|
|
{
|
|
|
|
Invalid,
|
|
|
|
Type1,
|
|
|
|
TrueType
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Standard Type1 fonts
|
|
|
|
enum class StandardFontType
|
|
|
|
{
|
|
|
|
Invalid,
|
|
|
|
TimesRoman,
|
|
|
|
TimesRomanBold,
|
|
|
|
TimesRomanItalics,
|
|
|
|
TimesRomanBoldItalics,
|
|
|
|
Helvetica,
|
|
|
|
HelveticaBold,
|
|
|
|
HelveticaOblique,
|
|
|
|
HelveticaBoldOblique,
|
|
|
|
Courier,
|
|
|
|
CourierBold,
|
|
|
|
CourierOblique,
|
|
|
|
CourierBoldOblique,
|
|
|
|
Symbol,
|
|
|
|
ZapfDingbats
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Returns builtin encoding for the standard font
|
|
|
|
static constexpr PDFEncoding::Encoding getEncodingForStandardFont(StandardFontType standardFont)
|
|
|
|
{
|
|
|
|
switch (standardFont)
|
|
|
|
{
|
|
|
|
case StandardFontType::Symbol:
|
|
|
|
return PDFEncoding::Encoding::Symbol;
|
|
|
|
|
|
|
|
case StandardFontType::ZapfDingbats:
|
|
|
|
return PDFEncoding::Encoding::ZapfDingbats;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return PDFEncoding::Encoding::Standard;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-31 18:08:36 +02:00
|
|
|
struct FontDescriptor
|
|
|
|
{
|
|
|
|
bool isEmbedded() const { return !fontFile.isEmpty() || !fontFile2.isEmpty() || !fontFile3.isEmpty(); }
|
|
|
|
|
|
|
|
QByteArray fontName;
|
|
|
|
QByteArray fontFamily;
|
|
|
|
QFont::Stretch fontStretch = QFont::AnyStretch;
|
|
|
|
PDFReal fontWeight = 400.0;
|
|
|
|
PDFInteger flags;
|
|
|
|
QRectF boundingBox;
|
|
|
|
PDFReal italicAngle = 0.0;
|
|
|
|
PDFReal ascent = 0.0;
|
|
|
|
PDFReal descent = 0.0;
|
|
|
|
PDFReal leading = 0.0;
|
|
|
|
PDFReal capHeight = 0.0;
|
|
|
|
PDFReal xHeight = 0.0;
|
|
|
|
PDFReal stemV = 0.0;
|
|
|
|
PDFReal stemH = 0.0;
|
|
|
|
PDFReal avgWidth = 0.0;
|
|
|
|
PDFReal maxWidth = 0.0;
|
|
|
|
PDFReal missingWidth = 0.0;
|
|
|
|
|
|
|
|
/// Byte array with Type 1 font program (embedded font)
|
|
|
|
QByteArray fontFile;
|
|
|
|
|
|
|
|
/// Byte array with TrueType font program (embedded font)
|
|
|
|
QByteArray fontFile2;
|
|
|
|
|
|
|
|
/// Byte array with font program, whose format is defined by the Subtype array
|
|
|
|
/// in the font dictionary.
|
|
|
|
QByteArray fontFile3;
|
|
|
|
|
|
|
|
/// Character set
|
|
|
|
QByteArray charset;
|
|
|
|
};
|
|
|
|
|
2019-03-30 18:45:30 +01:00
|
|
|
class PDFFont;
|
|
|
|
|
|
|
|
using PDFFontPointer = QSharedPointer<PDFFont>;
|
|
|
|
|
|
|
|
/// Base class representing font in the PDF file
|
2019-03-25 18:44:45 +01:00
|
|
|
class PDFFont
|
|
|
|
{
|
|
|
|
public:
|
2019-03-31 18:08:36 +02:00
|
|
|
explicit PDFFont(FontDescriptor fontDescriptor);
|
2019-03-30 18:45:30 +01:00
|
|
|
virtual ~PDFFont() = default;
|
|
|
|
|
|
|
|
/// Returns the font type
|
|
|
|
virtual FontType getFontType() const = 0;
|
|
|
|
|
|
|
|
/// Realizes the font (physical materialization of the font using pixel size,
|
|
|
|
/// if font can't be realized, then empty QRawFont is returned).
|
|
|
|
/// \param fontSize Size of the font
|
|
|
|
virtual QRawFont getRealizedFont(PDFReal fontSize) const = 0;
|
|
|
|
|
|
|
|
/// Returns text using the font encoding
|
|
|
|
/// \param byteArray Byte array with encoded string
|
|
|
|
virtual QString getTextUsingEncoding(const QByteArray& byteArray) const = 0;
|
|
|
|
|
2019-03-31 18:08:36 +02:00
|
|
|
/// Returns font descriptor
|
|
|
|
const FontDescriptor* getFontDescriptor() const { return &m_fontDescriptor; }
|
|
|
|
|
|
|
|
/// Creates font from the object. If font can't be created, exception is thrown.
|
|
|
|
/// \param object Font dictionary
|
|
|
|
/// \param document Document
|
2019-03-30 18:45:30 +01:00
|
|
|
static PDFFontPointer createFont(const PDFObject& object, const PDFDocument* document);
|
2019-03-31 18:08:36 +02:00
|
|
|
|
|
|
|
protected:
|
|
|
|
FontDescriptor m_fontDescriptor;
|
2019-03-25 18:44:45 +01:00
|
|
|
};
|
|
|
|
|
2019-03-30 18:45:30 +01:00
|
|
|
/// Simple font, see PDF reference 1.7, chapter 5.5. Simple fonts have encoding table,
|
|
|
|
/// which maps single-byte character to the glyph in the font.
|
|
|
|
class PDFSimpleFont : public PDFFont
|
|
|
|
{
|
|
|
|
public:
|
2019-03-31 18:08:36 +02:00
|
|
|
explicit PDFSimpleFont(FontDescriptor fontDescriptor,
|
|
|
|
QByteArray name,
|
2019-03-30 18:45:30 +01:00
|
|
|
QByteArray baseFont,
|
|
|
|
PDFInteger firstChar,
|
|
|
|
PDFInteger lastChar,
|
|
|
|
std::vector<PDFInteger> widths,
|
|
|
|
PDFEncoding::Encoding encodingType,
|
|
|
|
encoding::EncodingTable encoding);
|
|
|
|
virtual ~PDFSimpleFont() override = default;
|
|
|
|
|
|
|
|
virtual QRawFont getRealizedFont(PDFReal fontSize) const override;
|
|
|
|
virtual QString getTextUsingEncoding(const QByteArray& byteArray) const override;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
QByteArray m_name;
|
|
|
|
QByteArray m_baseFont;
|
|
|
|
PDFInteger m_firstChar;
|
|
|
|
PDFInteger m_lastChar;
|
|
|
|
std::vector<PDFInteger> m_widths;
|
|
|
|
PDFEncoding::Encoding m_encodingType;
|
|
|
|
encoding::EncodingTable m_encoding;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PDFType1Font : public PDFSimpleFont
|
|
|
|
{
|
|
|
|
public:
|
2019-03-31 18:08:36 +02:00
|
|
|
explicit PDFType1Font(FontDescriptor fontDescriptor,
|
|
|
|
QByteArray name,
|
2019-03-30 18:45:30 +01:00
|
|
|
QByteArray baseFont,
|
|
|
|
PDFInteger firstChar,
|
|
|
|
PDFInteger lastChar,
|
|
|
|
std::vector<PDFInteger> widths,
|
|
|
|
PDFEncoding::Encoding encodingType,
|
|
|
|
encoding::EncodingTable encoding,
|
|
|
|
StandardFontType standardFontType);
|
|
|
|
virtual ~PDFType1Font() override = default;
|
|
|
|
|
|
|
|
virtual FontType getFontType() const override;
|
|
|
|
|
|
|
|
/// Returns the assigned standard font (or invalid, if font is not standard)
|
|
|
|
StandardFontType getStandardFontType() const { return m_standardFontType; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
StandardFontType m_standardFontType; ///< Type of the standard font (or invalid, if it is not a standard font)
|
|
|
|
};
|
|
|
|
|
|
|
|
class PDFTrueTypeFont : public PDFSimpleFont
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using PDFSimpleFont::PDFSimpleFont;
|
|
|
|
|
|
|
|
virtual FontType getFontType() const override;
|
|
|
|
};
|
2019-03-25 18:44:45 +01:00
|
|
|
|
|
|
|
} // namespace pdf
|
|
|
|
|
|
|
|
#endif // PDFFONT_H
|