r24370 by jghali - #15682: Scribus crashes when checking fonts on startup
scribus-commit
scribus-commit at lists.scribus.net
Mon Jan 4 17:02:06 UTC 2021
Author: jghali
Date: Mon Jan 4 17:02:06 2021
New Revision: 24370
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=24370
Log:
#15682: Scribus crashes when checking fonts on startup
Modified:
trunk/Scribus/scribus/scfonts.cpp
Modified: trunk/Scribus/scribus/scfonts.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24370&path=/trunk/Scribus/scribus/scfonts.cpp
==============================================================================
--- trunk/Scribus/scribus/scfonts.cpp (original)
+++ trunk/Scribus/scribus/scfonts.cpp Mon Jan 4 17:02:06 2021
@@ -247,20 +247,20 @@
type = ScFace::UNKNOWN_TYPE;
if (ftIOFunc(fts, 0L, reinterpret_cast<FT_Byte *>(buf), 128) == FONT_NO_ERROR)
{
- if (strncmp(buf,T42_HEAD,strlen(T42_HEAD)) == 0)
+ if (strncmp(buf, T42_HEAD, strlen(T42_HEAD)) == 0)
{
fmt = ScFace::TYPE42;
type = ScFace::TTF;
}
- else if (strncmp(buf,T1_HEAD,strlen(T1_HEAD)) == 0 ||
- strncmp(buf,T1_ADOBE_HEAD,strlen(T1_ADOBE_HEAD)) == 0)
+ else if (strncmp(buf, T1_HEAD, strlen(T1_HEAD)) == 0 ||
+ strncmp(buf, T1_ADOBE_HEAD, strlen(T1_ADOBE_HEAD)) == 0)
{
fmt = ScFace::PFA;
type = ScFace::TYPE1;
}
- else if (strncmp(buf,PSFONT_ADOBE2_HEAD,strlen(PSFONT_ADOBE2_HEAD)) == 0 ||
- strncmp(buf,PSFONT_ADOBE21_HEAD,strlen(PSFONT_ADOBE21_HEAD)) == 0 ||
- strncmp(buf,PSFONT_ADOBE3_HEAD,strlen(PSFONT_ADOBE3_HEAD)) ==0)
+ else if (strncmp(buf, PSFONT_ADOBE2_HEAD, strlen(PSFONT_ADOBE2_HEAD)) == 0 ||
+ strncmp(buf, PSFONT_ADOBE21_HEAD, strlen(PSFONT_ADOBE21_HEAD)) == 0 ||
+ strncmp(buf, PSFONT_ADOBE3_HEAD, strlen(PSFONT_ADOBE3_HEAD)) == 0)
{
// Type2(CFF), Type0(Composite/CID), Type 3, Type 14 etc would end here
fmt = ScFace::PFA;
@@ -277,17 +277,17 @@
fmt = ScFace::SFNT;
type = ScFace::TTF;
}
- else if (strncmp(buf,"true",4) == 0)
+ else if (strncmp(buf, "true", 4) == 0)
{
fmt = ScFace::SFNT;
type = ScFace::TTF;
}
- else if (strncmp(buf,"ttcf",4) == 0)
+ else if (strncmp(buf, "ttcf", 4) == 0)
{
fmt = ScFace::TTCF;
type = ScFace::OTF;
}
- else if (strncmp(buf,"OTTO",4) == 0)
+ else if (strncmp(buf, "OTTO", 4) == 0)
{
fmt = ScFace::SFNT;
type = ScFace::OTF;
@@ -378,7 +378,9 @@
static QString decodeNameRecord(FT_SfntName name)
{
- QString string;
+ if (!name.string || name.string_len == 0)
+ return QString();
+
QByteArray encoding;
if (name.platform_id == TT_PLATFORM_APPLE_UNICODE)
{
@@ -396,7 +398,7 @@
encoding = "Shift-JIS";
break;
case TT_MS_ID_GB2312:
- encoding = "GB18030-0";
+ encoding = "GB18030";
break;
case TT_MS_ID_BIG_5:
encoding = "Big5";
@@ -406,13 +408,24 @@
}
}
- if (!encoding.isEmpty())
- {
- QTextCodec* codec = QTextCodec::codecForName(encoding);
- QByteArray bytes((const char*) name.string, name.string_len);
- string = codec->toUnicode(bytes);
- }
-
+ if (encoding.isEmpty())
+ return QString();
+
+ QTextCodec* codec = QTextCodec::codecForName(encoding);
+ if (!codec)
+ return QString();
+
+ QByteArray bytes((const char*) name.string, name.string_len);
+ if (name.encoding_id == TT_MS_ID_GB2312 && bytes.startsWith('\0'))
+ {
+ // 16 bytes chars appears to be used as transport type for 8 bytes values.
+ // We have to fix this so that Qt GB18030 codec process strings correctly
+ for (int i = 0; i < (int) name.string_len / 2; ++i)
+ bytes[i] = bytes[2 * i + 1];
+ bytes.resize(name.string_len / 2);
+ }
+
+ QString string = codec->toUnicode(bytes);
return string;
}
@@ -442,7 +455,7 @@
if (!names.isEmpty())
{
std::sort(names.begin(), names.end(), nameComp);
- foreach (const FT_SfntName& name, names)
+ for (const FT_SfntName& name : qAsConst(names))
{
QString string(decodeNameRecord(name));
if (!string.isEmpty())
@@ -665,6 +678,15 @@
addRejectedFont(filename, QObject::tr("Font is broken: \"%1\"").arg(getFtError(error)));
if (m_showFontInfo)
sDebug(QObject::tr("Font %1 is broken, discarding it. Error message: \"%2\"").arg(filename, getFtError(error)));
+ return true;
+ }
+ if (face->family_name == nullptr)
+ {
+ addRejectedFont(filename, QObject::tr("Failed to load font: font family unspecified"));
+ if (m_showFontInfo)
+ sDebug(QObject::tr("Failed to load font %1 - font family unspecified").arg(filename));
+ FT_Done_Face(face);
+ m_checkedFonts.insert(filename, foCache);
return true;
}
getFontFormat(face, format, type);
@@ -783,11 +805,12 @@
QString fam(getFamilyName(face));
QStringList features(getFontFeatures(face));
QString sty(face->style_name);
- if (sty == "Regular")
+ if ((sty == "Regular" && face->style_flags != 0) || sty.isEmpty())
{
switch (face->style_flags)
{
case 0:
+ sty = "Regular";
break;
case 1:
sty = "Italic";
@@ -802,52 +825,53 @@
break;
}
}
- QString ts(fam + " " + sty);
- QString alt("");
+ QString fullName(fam);
+ if (!sty.isEmpty())
+ fullName += " " + sty;
const char* psName = FT_Get_Postscript_Name(face);
QString qpsName;
if (psName)
qpsName = QString(psName);
else
- qpsName = ts;
+ qpsName = fullName;
ScFace t;
- if (contains(ts))
- {
- t = (*this)[ts];
+ if (contains(fullName))
+ {
+ t = (*this)[fullName];
if (t.psName() != qpsName)
{
- alt = " ("+qpsName+")";
- ts += alt;
+ QString alt = " (" + qpsName + ")";
+ fullName += alt;
sty += alt;
}
}
- t = (*this)[ts];
+ t = (*this)[fullName];
if (t.isNone())
{
switch (format)
{
case ScFace::PFA:
- t = ScFace(new ScFace_PFA(fam, sty, "", ts, qpsName, filename, faceIndex, features));
+ t = ScFace(new ScFace_PFA(fam, sty, "", fullName, qpsName, filename, faceIndex, features));
t.subset(Subset);
break;
case ScFace::PFB:
- t = ScFace(new ScFace_PFB(fam, sty, "", ts, qpsName, filename, faceIndex, features));
+ t = ScFace(new ScFace_PFB(fam, sty, "", fullName, qpsName, filename, faceIndex, features));
t.subset(Subset);
break;
case ScFace::SFNT:
- t = ScFace(new ScFace_ttf(fam, sty, "", ts, qpsName, filename, faceIndex, features));
+ t = ScFace(new ScFace_ttf(fam, sty, "", fullName, qpsName, filename, faceIndex, features));
getSFontType(face, t.m_m->typeCode);
t.subset(Subset);
break;
case ScFace::TTCF:
- t = ScFace(new ScFace_ttf(fam, sty, "", ts, qpsName, filename, faceIndex, features));
+ t = ScFace(new ScFace_ttf(fam, sty, "", fullName, qpsName, filename, faceIndex, features));
t.m_m->formatCode = ScFace::TTCF;
t.m_m->typeCode = ScFace::TTF;
getSFontType(face, t.m_m->typeCode);
t.subset(Subset);
break;
case ScFace::TYPE42:
- t = ScFace(new ScFace_ttf(fam, sty, "", ts, qpsName, filename, faceIndex, features));
+ t = ScFace(new ScFace_ttf(fam, sty, "", fullName, qpsName, filename, faceIndex, features));
getSFontType(face, t.m_m->typeCode);
t.subset(Subset);
break;
@@ -855,7 +879,7 @@
/* catching any types not handled above to silence compiler */
break;
}
- insert(ts,t);
+ insert(fullName, t);
t.m_m->hasGlyphNames = HasNames;
t.embedPs(true);
t.usable(true);
@@ -871,7 +895,7 @@
//debug
QByteArray bb;
t->rawData(bb);
- QFile dump(QString("/tmp/fonts/%1-%2").arg(ts, psName));
+ QFile dump(QString("/tmp/fonts/%1-%2").arg(fullName, psName));
dump.open(IO_WriteOnly);
QDataStream os(&dump);
os.writeRawBytes(bb.data(), bb.size());
@@ -881,7 +905,7 @@
else
{
if (m_showFontInfo)
- sDebug(QObject::tr("Font %1(%2) is duplicate of %3").arg(filename).arg(faceIndex+1).arg(t.fontPath()));
+ sDebug(QObject::tr("Font %1(%2) is duplicate of %3").arg(filename).arg(faceIndex + 1).arg(t.fontPath()));
// this is needed since eg. AppleSymbols will happily return a face for *any* face_index
if (faceIndex > 0) {
break;
More information about the scribus-commit
mailing list