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`.
*/
/* #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
static QByteArray getFontData(const LOGFONT* font, HDC hdc);
/// Create a postscript name for comparation purposes
static QString getFontPostscriptName(QString fontName);
struct FontInfo
{
QString faceName;
QString faceNameAdjusted;
LOGFONT logFont;
TEXTMETRIC textMetric;
};
@ -93,35 +97,19 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor)
#ifdef Q_OS_WIN
HDC hdc = GetDC(NULL);
// Exact match for font, if font can't be exact matched, then match font family
// and try to set weight
QString fontFamily = QString::fromLatin1(descriptor->fontFamily);
for (const FontInfo& fontInfo : m_fontInfos)
{
if (fontInfo.faceName.contains(fontFamily) &&
fontInfo.logFont.lfWeight == descriptor->fontWeight &&
fontInfo.logFont.lfItalic == (descriptor->italicAngle != 0.0 ? TRUE : FALSE))
{
result = getFontData(&fontInfo.logFont, hdc);
const BYTE lfItalic = (descriptor->italicAngle != 0.0 ? TRUE : FALSE);
if (!result.isEmpty())
{
break;
}
}
}
// Match for font family
if (result.isEmpty())
// Exact match font face name
QString fontName = getFontPostscriptName(descriptor->fontName);
if (!fontName.isEmpty())
{
for (const FontInfo& fontInfo : m_fontInfos)
{
if (fontInfo.faceName.contains(fontFamily))
if (fontInfo.faceNameAdjusted == fontName &&
fontInfo.logFont.lfWeight == descriptor->fontWeight &&
fontInfo.logFont.lfItalic == lfItalic)
{
LOGFONT logFont = fontInfo.logFont;
logFont.lfWeight = descriptor->fontWeight;
logFont.lfItalic = (descriptor->italicAngle != 0.0 ? TRUE : FALSE);
result = getFontData(&logFont, hdc);
result = getFontData(&fontInfo.logFont, hdc);
if (!result.isEmpty())
{
@ -129,6 +117,68 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor)
}
}
}
// 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
// and try to set weight
QString fontFamily = QString::fromLatin1(descriptor->fontFamily);
if (!fontFamily.isEmpty())
{
for (const FontInfo& fontInfo : m_fontInfos)
{
if (fontInfo.faceName.contains(fontFamily) &&
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.faceName.contains(fontFamily))
{
LOGFONT logFont = fontInfo.logFont;
logFont.lfWeight = descriptor->fontWeight;
logFont.lfItalic = lfItalic;
result = getFontData(&logFont, hdc);
if (!result.isEmpty())
{
break;
}
}
}
}
}
ReleaseDC(NULL, hdc);
@ -166,6 +216,7 @@ int PDFSystemFontInfoStorage::enumerateFontProc(const LOGFONT* font, const TEXTM
fontInfo.logFont = *font;
fontInfo.textMetric = *textMetrics;
fontInfo.faceName = QString::fromWCharArray(font->lfFaceName);
fontInfo.faceNameAdjusted = getFontPostscriptName(fontInfo.faceName);
callbackInfo->storage->m_fontInfos.push_back(qMove(fontInfo));
// For debug purposes only!
@ -199,6 +250,17 @@ QByteArray PDFSystemFontInfoStorage::getFontData(const LOGFONT* font, HDC hdc)
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
PDFFont::PDFFont(FontDescriptor fontDescriptor) :

View File

@ -1661,8 +1661,12 @@ PDFPostScriptFunction::~PDFPostScriptFunction()
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;
PDFLexicalAnalyzer parser(byteArray.constBegin(), byteArray.constEnd());
PDFLexicalAnalyzer parser(adjustedArray.constBegin(), adjustedArray.constEnd());
std::stack<InstructionPointer> blockCallStack;
while (true)