Better finding of fonts

This commit is contained in:
Jakub Melka
2019-04-27 17:09:37 +02:00
parent 8b235acc75
commit a407dbd3f3
4 changed files with 92 additions and 26 deletions

Binary file not shown.

View File

@ -503,7 +503,7 @@ FT_BEGIN_HEADER
* *
* More details can be found in the file `fterrors.h`. * More details can be found in the file `fterrors.h`.
*/ */
/* #define FT_CONFIG_OPTION_ERROR_STRINGS */ #define FT_CONFIG_OPTION_ERROR_STRINGS
/*************************************************************************/ /*************************************************************************/

View File

@ -63,9 +63,13 @@ private:
/// Retrieves font data for desired font /// Retrieves font data for desired font
static QByteArray getFontData(const LOGFONT* font, HDC hdc); static QByteArray getFontData(const LOGFONT* font, HDC hdc);
/// Create a postscript name for comparation purposes
static QString getFontPostscriptName(QString fontName);
struct FontInfo struct FontInfo
{ {
QString faceName; QString faceName;
QString faceNameAdjusted;
LOGFONT logFont; LOGFONT logFont;
TEXTMETRIC textMetric; TEXTMETRIC textMetric;
}; };
@ -93,14 +97,59 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor)
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
HDC hdc = GetDC(NULL); HDC hdc = GetDC(NULL);
const BYTE lfItalic = (descriptor->italicAngle != 0.0 ? TRUE : FALSE);
// Exact match font face name
QString fontName = getFontPostscriptName(descriptor->fontName);
if (!fontName.isEmpty())
{
for (const FontInfo& fontInfo : m_fontInfos)
{
if (fontInfo.faceNameAdjusted == fontName &&
fontInfo.logFont.lfWeight == descriptor->fontWeight &&
fontInfo.logFont.lfItalic == lfItalic)
{
result = getFontData(&fontInfo.logFont, hdc);
if (!result.isEmpty())
{
break;
}
}
}
// Match for font family
if (result.isEmpty())
{
for (const FontInfo& fontInfo : m_fontInfos)
{
if (fontInfo.faceNameAdjusted == fontName)
{
LOGFONT logFont = fontInfo.logFont;
logFont.lfWeight = descriptor->fontWeight;
logFont.lfItalic = lfItalic;
result = getFontData(&logFont, hdc);
if (!result.isEmpty())
{
break;
}
}
}
}
}
// Exact match for font, if font can't be exact matched, then match font family // Exact match for font, if font can't be exact matched, then match font family
// 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())
{
for (const FontInfo& fontInfo : m_fontInfos) for (const FontInfo& fontInfo : m_fontInfos)
{ {
if (fontInfo.faceName.contains(fontFamily) && if (fontInfo.faceName.contains(fontFamily) &&
fontInfo.logFont.lfWeight == descriptor->fontWeight && fontInfo.logFont.lfWeight == descriptor->fontWeight &&
fontInfo.logFont.lfItalic == (descriptor->italicAngle != 0.0 ? TRUE : FALSE)) fontInfo.logFont.lfItalic == lfItalic)
{ {
result = getFontData(&fontInfo.logFont, hdc); result = getFontData(&fontInfo.logFont, hdc);
@ -120,7 +169,7 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor)
{ {
LOGFONT logFont = fontInfo.logFont; LOGFONT logFont = fontInfo.logFont;
logFont.lfWeight = descriptor->fontWeight; logFont.lfWeight = descriptor->fontWeight;
logFont.lfItalic = (descriptor->italicAngle != 0.0 ? TRUE : FALSE); logFont.lfItalic = lfItalic;
result = getFontData(&logFont, hdc); result = getFontData(&logFont, hdc);
if (!result.isEmpty()) if (!result.isEmpty())
@ -130,6 +179,7 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor)
} }
} }
} }
}
ReleaseDC(NULL, hdc); ReleaseDC(NULL, hdc);
#endif #endif
@ -166,6 +216,7 @@ int PDFSystemFontInfoStorage::enumerateFontProc(const LOGFONT* font, const TEXTM
fontInfo.logFont = *font; fontInfo.logFont = *font;
fontInfo.textMetric = *textMetrics; fontInfo.textMetric = *textMetrics;
fontInfo.faceName = QString::fromWCharArray(font->lfFaceName); fontInfo.faceName = QString::fromWCharArray(font->lfFaceName);
fontInfo.faceNameAdjusted = getFontPostscriptName(fontInfo.faceName);
callbackInfo->storage->m_fontInfos.push_back(qMove(fontInfo)); callbackInfo->storage->m_fontInfos.push_back(qMove(fontInfo));
// For debug purposes only! // For debug purposes only!
@ -199,6 +250,17 @@ QByteArray PDFSystemFontInfoStorage::getFontData(const LOGFONT* font, HDC hdc)
return byteArray; return byteArray;
} }
QString PDFSystemFontInfoStorage::getFontPostscriptName(QString fontName)
{
for (const char* string : { "PS", "MT", "Regular", "Bold", "Italic", "Oblique" })
{
fontName.remove(QLatin1String(string), Qt::CaseInsensitive);
}
return fontName.remove(QChar(' ')).remove(QChar('-')).trimmed();
}
#endif #endif
PDFFont::PDFFont(FontDescriptor fontDescriptor) : PDFFont::PDFFont(FontDescriptor fontDescriptor) :

View File

@ -1661,8 +1661,12 @@ PDFPostScriptFunction::~PDFPostScriptFunction()
PDFPostScriptFunction::Program PDFPostScriptFunction::parseProgram(const QByteArray& byteArray) PDFPostScriptFunction::Program PDFPostScriptFunction::parseProgram(const QByteArray& byteArray)
{ {
// Lexical analyzer can't handle when '{' or '}' is near next token (for example '{0' etc.)
QByteArray adjustedArray = byteArray;
adjustedArray.replace('{', " { ").replace('}', " } ");
Program result; Program result;
PDFLexicalAnalyzer parser(byteArray.constBegin(), byteArray.constEnd()); PDFLexicalAnalyzer parser(adjustedArray.constBegin(), adjustedArray.constEnd());
std::stack<InstructionPointer> blockCallStack; std::stack<InstructionPointer> blockCallStack;
while (true) while (true)