Spaces:
Running
Running
//======================================================================== | |
// | |
// GfxFont.h | |
// | |
// Copyright 1996-2003 Glyph & Cog, LLC | |
// | |
//======================================================================== | |
//======================================================================== | |
// | |
// Modified under the Poppler project - http://poppler.freedesktop.org | |
// | |
// All changes made under the Poppler project to this file are licensed | |
// under GPL version 2 or later | |
// | |
// Copyright (C) 2005, 2008, 2015, 2017-2022 Albert Astals Cid <[email protected]> | |
// Copyright (C) 2006 Takashi Iwai <[email protected]> | |
// Copyright (C) 2006 Kristian Høgsberg <[email protected]> | |
// Copyright (C) 2007 Julien Rebetez <[email protected]> | |
// Copyright (C) 2007 Jeff Muizelaar <[email protected]> | |
// Copyright (C) 2007 Koji Otani <[email protected]> | |
// Copyright (C) 2011 Axel Strübing <[email protected]> | |
// Copyright (C) 2011, 2012, 2014 Adrian Johnson <[email protected]> | |
// Copyright (C) 2015, 2018 Jason Crain <[email protected]> | |
// Copyright (C) 2015 Thomas Freitag <[email protected]> | |
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <[email protected]>. Work sponsored by the LiMux project of the city of Munich | |
// Copyright (C) 2021, 2022 Oliver Sander <[email protected]> | |
// | |
// To see a description of the changes please see the Changelog file that | |
// came with your tarball or type make ChangeLog if you are building from git | |
// | |
//======================================================================== | |
class Dict; | |
class CMap; | |
class CharCodeToUnicode; | |
class FoFiTrueType; | |
class PSOutputDev; | |
struct GfxFontCIDWidths; | |
struct Base14FontMapEntry; | |
class FNVHash; | |
//------------------------------------------------------------------------ | |
// GfxFontType | |
//------------------------------------------------------------------------ | |
enum GfxFontType | |
{ | |
//----- Gfx8BitFont | |
fontUnknownType, | |
fontType1, | |
fontType1C, | |
fontType1COT, | |
fontType3, | |
fontTrueType, | |
fontTrueTypeOT, | |
//----- GfxCIDFont | |
fontCIDType0, | |
fontCIDType0C, | |
fontCIDType0COT, | |
fontCIDType2, | |
fontCIDType2OT | |
}; | |
//------------------------------------------------------------------------ | |
// GfxFontCIDWidths | |
//------------------------------------------------------------------------ | |
struct GfxFontCIDWidthExcep | |
{ | |
CID first; // this record applies to | |
CID last; // CIDs <first>..<last> | |
double width; // char width | |
}; | |
struct GfxFontCIDWidthExcepV | |
{ | |
CID first; // this record applies to | |
CID last; // CIDs <first>..<last> | |
double height; // char height | |
double vx, vy; // origin position | |
}; | |
struct GfxFontCIDWidths | |
{ | |
double defWidth; // default char width | |
double defHeight; // default char height | |
double defVY; // default origin position | |
GfxFontCIDWidthExcep *exceps; // exceptions | |
int nExceps; // number of valid entries in exceps | |
GfxFontCIDWidthExcepV * // exceptions for vertical font | |
excepsV; | |
int nExcepsV; // number of valid entries in excepsV | |
}; | |
//------------------------------------------------------------------------ | |
// GfxFontLoc | |
//------------------------------------------------------------------------ | |
enum GfxFontLocType | |
{ | |
gfxFontLocEmbedded, // font embedded in PDF file | |
gfxFontLocExternal, // external font file | |
gfxFontLocResident // font resident in PS printer | |
}; | |
class POPPLER_PRIVATE_EXPORT GfxFontLoc | |
{ | |
public: | |
GfxFontLoc(); | |
~GfxFontLoc(); | |
GfxFontLoc(const GfxFontLoc &) = delete; | |
GfxFontLoc(GfxFontLoc &&) noexcept; | |
GfxFontLoc &operator=(const GfxFontLoc &) = delete; | |
GfxFontLoc &operator=(GfxFontLoc &&other) noexcept; | |
// Set the 'path' string from a GooString on the heap. | |
// Ownership of the object is taken. | |
void setPath(GooString *pathA); | |
const GooString *pathAsGooString() const; | |
GfxFontLocType locType; | |
GfxFontType fontType; | |
Ref embFontID; // embedded stream obj ID | |
// (if locType == gfxFontLocEmbedded) | |
std::string path; // font file path | |
// (if locType == gfxFontLocExternal) | |
// PS font name | |
// (if locType == gfxFontLocResident) | |
int fontNum; // for TrueType collections | |
// (if locType == gfxFontLocExternal) | |
int substIdx; // substitute font index | |
// (if locType == gfxFontLocExternal, | |
// and a Base-14 substitution was made) | |
}; | |
//------------------------------------------------------------------------ | |
// GfxFont | |
//------------------------------------------------------------------------ | |
class POPPLER_PRIVATE_EXPORT GfxFont | |
{ | |
public: | |
enum Stretch | |
{ | |
StretchNotDefined, | |
UltraCondensed, | |
ExtraCondensed, | |
Condensed, | |
SemiCondensed, | |
Normal, | |
SemiExpanded, | |
Expanded, | |
ExtraExpanded, | |
UltraExpanded | |
}; | |
enum Weight | |
{ | |
WeightNotDefined, | |
W100, | |
W200, | |
W300, | |
W400, // Normal | |
W500, | |
W600, | |
W700, // Bold | |
W800, | |
W900 | |
}; | |
// Build a GfxFont object. | |
static std::unique_ptr<GfxFont> makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict); | |
GfxFont(const GfxFont &) = delete; | |
GfxFont &operator=(const GfxFont &other) = delete; | |
virtual ~GfxFont(); | |
bool isOk() const { return ok; } | |
// Get font tag. | |
const std::string &getTag() const { return tag; } | |
// Get font dictionary ID. | |
const Ref *getID() const { return &id; } | |
// Does this font match the tag? | |
bool matches(const char *tagA) const { return tag == tagA; } | |
// Get font family name. | |
GooString *getFamily() const { return family; } | |
// Get font stretch. | |
Stretch getStretch() const { return stretch; } | |
// Get font weight. | |
Weight getWeight() const { return weight; } | |
// Get the original font name (ignornig any munging that might have | |
// been done to map to a canonical Base-14 font name). | |
const std::optional<std::string> &getName() const { return name; } | |
bool isSubset() const; | |
// Returns the original font name without the subset tag (if it has one) | |
std::string getNameWithoutSubsetTag() const; | |
// Get font type. | |
GfxFontType getType() const { return type; } | |
virtual bool isCIDFont() const { return false; } | |
// Get embedded font ID, i.e., a ref for the font file stream. | |
// Returns false if there is no embedded font. | |
bool getEmbeddedFontID(Ref *embID) const | |
{ | |
*embID = embFontID; | |
return embFontID != Ref::INVALID(); | |
} | |
// Invalidate an embedded font | |
// Returns false if there is no embedded font. | |
bool invalidateEmbeddedFont() | |
{ | |
if (embFontID != Ref::INVALID()) { | |
embFontID = Ref::INVALID(); | |
return true; | |
} | |
return false; | |
} | |
// Get the PostScript font name for the embedded font. Returns | |
// NULL if there is no embedded font. | |
const GooString *getEmbeddedFontName() const { return embFontName; } | |
// Get font descriptor flags. | |
int getFlags() const { return flags; } | |
bool isFixedWidth() const { return flags & fontFixedWidth; } | |
bool isSerif() const { return flags & fontSerif; } | |
bool isSymbolic() const { return flags & fontSymbolic; } | |
bool isItalic() const { return flags & fontItalic; } | |
bool isBold() const { return flags & fontBold; } | |
// Return the Unicode map. | |
virtual const CharCodeToUnicode *getToUnicode() const = 0; | |
// Return the font matrix. | |
const double *getFontMatrix() const { return fontMat; } | |
// Return the font bounding box. | |
const double *getFontBBox() const { return fontBBox; } | |
// Return the ascent and descent values. | |
double getAscent() const { return ascent; } | |
double getDescent() const { return descent; } | |
// Return the writing mode (0=horizontal, 1=vertical). | |
virtual int getWMode() const { return 0; } | |
// Locate the font file for this font. If <ps> is not null, includes PS | |
// printer-resident fonts. Returns std::optional without a value on failure. | |
std::optional<GfxFontLoc> locateFont(XRef *xref, PSOutputDev *ps); | |
// Read an external or embedded font file into a buffer. | |
std::optional<std::vector<unsigned char>> readEmbFontFile(XRef *xref); | |
// Get the next char from a string <s> of <len> bytes, returning the | |
// char <code>, its Unicode mapping <u>, its displacement vector | |
// (<dx>, <dy>), and its origin offset vector (<ox>, <oy>). <uSize> | |
// is the number of entries available in <u>, and <uLen> is set to | |
// the number actually used. Returns the number of bytes used by | |
// the char code. | |
virtual int getNextChar(const char *s, int len, CharCode *code, Unicode const **u, int *uLen, double *dx, double *dy, double *ox, double *oy) const = 0; | |
// Does this font have a toUnicode map? | |
bool hasToUnicodeCMap() const { return hasToUnicode; } | |
// Return the name of the encoding | |
const std::string &getEncodingName() const { return encodingName; } | |
// Return AGLFN names of ligatures in the Standard and Expert encodings | |
// for use with fonts that are not compatible with the Standard 14 fonts. | |
// http://sourceforge.net/adobe/aglfn/wiki/AGL%20Specification/ | |
static const char *getAlternateName(const char *name); | |
protected: | |
GfxFont(const char *tagA, Ref idA, std::optional<std::string> &&nameA, GfxFontType typeA, Ref embFontIDA); | |
static GfxFontType getFontType(XRef *xref, Dict *fontDict, Ref *embID); | |
void readFontDescriptor(XRef *xref, Dict *fontDict); | |
CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits, CharCodeToUnicode *ctu); | |
static std::optional<GfxFontLoc> getExternalFont(GooString *path, bool cid); | |
const std::string tag; // PDF font tag | |
const Ref id; // reference (used as unique ID) | |
std::optional<std::string> name; // font name | |
GooString *family; // font family | |
Stretch stretch; // font stretch | |
Weight weight; // font weight | |
const GfxFontType type; // type of font | |
int flags; // font descriptor flags | |
GooString *embFontName; // name of embedded font | |
Ref embFontID; // ref to embedded font file stream | |
double fontMat[6]; // font matrix (Type 3 only) | |
double fontBBox[4]; // font bounding box (Type 3 only) | |
double missingWidth; // "default" width | |
double ascent; // max height above baseline | |
double descent; // max depth below baseline | |
bool ok; | |
bool hasToUnicode; | |
std::string encodingName; | |
}; | |
//------------------------------------------------------------------------ | |
// Gfx8BitFont | |
//------------------------------------------------------------------------ | |
class POPPLER_PRIVATE_EXPORT Gfx8BitFont : public GfxFont | |
{ | |
public: | |
Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, std::optional<std::string> &&nameA, GfxFontType typeA, Ref embFontIDA, Dict *fontDict); | |
int getNextChar(const char *s, int len, CharCode *code, Unicode const **u, int *uLen, double *dx, double *dy, double *ox, double *oy) const override; | |
// Return the encoding. | |
char **getEncoding() { return enc; } | |
// Return the Unicode map. | |
const CharCodeToUnicode *getToUnicode() const override; | |
// Return the character name associated with <code>. | |
const char *getCharName(int code) const { return enc[code]; } | |
// Returns true if the PDF font specified an encoding. | |
bool getHasEncoding() const { return hasEncoding; } | |
// Returns true if the PDF font specified MacRomanEncoding. | |
bool getUsesMacRomanEnc() const { return usesMacRomanEnc; } | |
// Get width of a character. | |
double getWidth(unsigned char c) const { return widths[c]; } | |
// Return a char code-to-GID mapping for the provided font file. | |
// (This is only useful for TrueType fonts.) | |
int *getCodeToGIDMap(FoFiTrueType *ff); | |
// Return the Type 3 CharProc dictionary, or NULL if none. | |
Dict *getCharProcs(); | |
// Return the Type 3 CharProc for the character associated with <code>. | |
Object getCharProc(int code); | |
Object getCharProcNF(int code); | |
// Return the Type 3 Resources dictionary, or NULL if none. | |
Dict *getResources(); | |
private: | |
~Gfx8BitFont() override; | |
const Base14FontMapEntry *base14; // for Base-14 fonts only; NULL otherwise | |
char *enc[256]; // char code --> char name | |
char encFree[256]; // boolean for each char name: if set, | |
// the string is malloc'ed | |
CharCodeToUnicode *ctu; // char code --> Unicode | |
bool hasEncoding; | |
bool usesMacRomanEnc; | |
double widths[256]; // character widths | |
Object charProcs; // Type 3 CharProcs dictionary | |
Object resources; // Type 3 Resources dictionary | |
friend class GfxFont; | |
}; | |
//------------------------------------------------------------------------ | |
// GfxCIDFont | |
//------------------------------------------------------------------------ | |
class POPPLER_PRIVATE_EXPORT GfxCIDFont : public GfxFont | |
{ | |
public: | |
GfxCIDFont(XRef *xref, const char *tagA, Ref idA, std::optional<std::string> &&nameA, GfxFontType typeA, Ref embFontIDA, Dict *fontDict); | |
bool isCIDFont() const override { return true; } | |
int getNextChar(const char *s, int len, CharCode *code, Unicode const **u, int *uLen, double *dx, double *dy, double *ox, double *oy) const override; | |
// Return the writing mode (0=horizontal, 1=vertical). | |
int getWMode() const override; | |
// Return the Unicode map. | |
const CharCodeToUnicode *getToUnicode() const override; | |
// Get the collection name (<registry>-<ordering>). | |
const GooString *getCollection() const; | |
// Return the CID-to-GID mapping table. These should only be called | |
// if type is fontCIDType2. | |
int *getCIDToGID() const { return cidToGID; } | |
unsigned int getCIDToGIDLen() const { return cidToGIDLen; } | |
int *getCodeToGIDMap(FoFiTrueType *ff, int *codeToGIDLen); | |
double getWidth(char *s, int len) const; | |
private: | |
~GfxCIDFont() override; | |
int mapCodeToGID(FoFiTrueType *ff, int cmapi, Unicode unicode, bool wmode); | |
double getWidth(CID cid) const; // Get width of a character. | |
GooString *collection; // collection name | |
std::shared_ptr<CMap> cMap; // char code --> CID | |
CharCodeToUnicode *ctu; // CID --> Unicode | |
bool ctuUsesCharCode; // true: ctu maps char code to Unicode; | |
// false: ctu maps CID to Unicode | |
GfxFontCIDWidths widths; // character widths | |
int *cidToGID; // CID --> GID mapping (for embedded | |
// TrueType fonts) | |
unsigned int cidToGIDLen; | |
}; | |
//------------------------------------------------------------------------ | |
// GfxFontDict | |
//------------------------------------------------------------------------ | |
class GfxFontDict | |
{ | |
public: | |
// Build the font dictionary, given the PDF font dictionary. | |
GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict); | |
GfxFontDict(const GfxFontDict &) = delete; | |
GfxFontDict &operator=(const GfxFontDict &) = delete; | |
// Get the specified font. | |
std::shared_ptr<GfxFont> lookup(const char *tag) const; | |
// Iterative access. | |
int getNumFonts() const { return fonts.size(); } | |
const std::shared_ptr<GfxFont> &getFont(int i) const { return fonts[i]; } | |
private: | |
int hashFontObject(Object *obj); | |
void hashFontObject1(const Object *obj, FNVHash *h); | |
std::vector<std::shared_ptr<GfxFont>> fonts; | |
}; | |