r18433 by jghali - #5618 + #10766 : incorrect characters displayed after PDF export with some TrueType fonts
scribus-commit
scribus-commit at lists.scribus.net
Sun Aug 25 11:23:09 UTC 2013
Author: jghali
Date: Sun Aug 25 11:23:09 2013
New Revision: 18433
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=18433
Log:
#5618 + #10766 : incorrect characters displayed after PDF export with some TrueType fonts
The PostScript glyph names table embedded in TrueType fonts basically cannot be relied on. So whenever possible use Adobe glyph names instead of embedded glyph names.
Modified:
trunk/Scribus/scribus/fonts/ftface.cpp
trunk/Scribus/scribus/fonts/scfontmetrics.cpp
trunk/Scribus/scribus/fonts/scfontmetrics.h
Modified: trunk/Scribus/scribus/fonts/ftface.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=18433&path=/trunk/Scribus/scribus/fonts/ftface.cpp
==============================================================================
--- trunk/Scribus/scribus/fonts/ftface.cpp (original)
+++ trunk/Scribus/scribus/fonts/ftface.cpp Sun Aug 25 11:23:09 2013
@@ -308,7 +308,7 @@
bool FtFace::glyphNames(QMap<uint, std::pair<QChar, QString> >& GList) const
{
- return GlyNames(ftFace(), GList);
+ return GlyphNames(*this, GList);
}
Modified: trunk/Scribus/scribus/fonts/scfontmetrics.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=18433&path=/trunk/Scribus/scribus/fonts/scfontmetrics.cpp
==============================================================================
--- trunk/Scribus/scribus/fonts/scfontmetrics.cpp (original)
+++ trunk/Scribus/scribus/fonts/scfontmetrics.cpp Sun Aug 25 11:23:09 2013
@@ -15,6 +15,7 @@
#include "fpoint.h"
#include "fpointarray.h"
+#include "ftface.h"
#include "scfontmetrics.h"
#include "scfonts.h"
#include "scpage.h"
@@ -22,7 +23,6 @@
#include "scribusdoc.h"
#include "style.h"
#include "util_math.h"
-
// this code contains a set of font related functions
// that don't really fit within ScFonts.
@@ -321,93 +321,72 @@
return pmr;
}
-/** Same as FontSample() with \n strings support added.
-09/26/2004 petr vanek
-
-QPixmap fontSamples(ScFace * fnt, int s, QString ts, QColor back)
-{
- QStringList lines = QStringList::split("\n", ts);
- QPixmap ret(640, 480);
- QPixmap sample;
- QPainter *painter = new QPainter(&ret);
- int y = 0;
- int x = 0;
- ret.fill(back);
- for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
- {
- sample = FontSample(fnt, s, *it, back);
- if (!sample.isNull())
- painter->drawPixmap(0, y, sample, 0, 0);
- y = y + sample.height();
- if (x < sample.width())
- x = sample.width();
- } // for
- delete(painter);
- QPixmap final(x, y);
- if ((x != 0) && (y != 0))
- {
- QPainter *fpainter = new QPainter(&final);
- fpainter->drawPixmap(0, 0, ret, 0, 0, x, y);
- delete(fpainter);
- }
- return final;
-}
-*/
-
-bool GlyNames(FT_Face face, QMap<uint, std::pair<QChar, QString> >& GList)
+bool GlyphNames(const FtFace& fnt, QMap<uint, std::pair<QChar, QString> >& GList)
{
char buf[50];
FT_ULong charcode;
- FT_UInt gindex;
- setBestEncoding(face);
- gindex = 0;
- charcode = FT_Get_First_Char(face, &gindex );
- const bool hasPSNames = FT_HAS_GLYPH_NAMES(face);
+ FT_UInt gindex = 0;
+
+ FT_Face face = fnt.ftFace();
+ if (!face)
+ return false;
+
if (adobeGlyphNames.empty())
readAdobeGlyphNames();
+
+ // The glyph name table embedded in Truetype fonts is not reliable.
+ // For those fonts we consequently use Adobe Glyph names whenever possible.
+ const bool avoidFntNames = (fnt.formatCode != ScFace::TYPE42 && fnt.typeCode == ScFace::TTF) &&
+ (face->charmap && face->charmap->encoding == FT_ENCODING_UNICODE);
+ const bool hasPSNames = FT_HAS_GLYPH_NAMES(face);
+
// qDebug() << "reading metrics for" << face->family_name << face->style_name;
+ charcode = FT_Get_First_Char(face, &gindex );
while (gindex != 0)
{
bool notfound = true;
- if (hasPSNames)
+ if (hasPSNames && !avoidFntNames)
notfound = FT_Get_Glyph_Name(face, gindex, &buf, 50);
// just in case FT gives empty string or ".notdef"
// no valid glyphname except ".notdef" starts with '.'
// qDebug() << "\t" << gindex << " '" << charcode << "' --> '" << (notfound? "notfound" : buf) << "'";
if (notfound || buf[0] == '\0' || buf[0] == '.')
- GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)),adobeGlyphName(charcode)));
+ GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)), adobeGlyphName(charcode)));
else
- GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)),QString(reinterpret_cast<char*>(buf))));
+ GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)), QString(reinterpret_cast<char*>(buf))));
charcode = FT_Get_Next_Char(face, charcode, &gindex );
}
+
+ if (!hasPSNames)
+ return true;
+
// Let's see if we can find some more...
int maxSlot1 = face->num_glyphs;
- if (hasPSNames)
- for (int gindex = 1; gindex < maxSlot1; ++gindex)
- {
- if (!GList.contains(gindex))
+ for (int gindex = 1; gindex < maxSlot1; ++gindex)
+ {
+ if (GList.contains(gindex))
+ continue;
+ if (FT_Get_Glyph_Name(face, gindex, &buf, 50))
+ continue;
+ QString glyphname(reinterpret_cast<char*>(buf));
+ if (avoidFntNames && buf[0] != '.' && buf[0] != '\0')
+ glyphname = adobeGlyphName(charcode);
+
+ charcode = 0;
+ QMap<uint,std::pair<QChar,QString> >::Iterator gli;
+ for (gli = GList.begin(); gli != GList.end(); ++gli)
+ {
+ if (glyphname == gli.value().second)
{
- bool found = ! FT_Get_Glyph_Name(face, gindex, &buf, 50);
- if (found)
- {
- QString glyphname(reinterpret_cast<char*>(buf));
- charcode = 0;
- QMap<uint,std::pair<QChar,QString> >::Iterator gli;
- for (gli = GList.begin(); gli != GList.end(); ++gli)
- {
- if (glyphname == gli.value().second)
- {
- charcode = gli.value().first.unicode();
- break;
- }
- }
-// qDebug() << "\tmore: " << gindex << " '" << charcode << "' --> '" << buf << "'";
- GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)), glyphname));
- }
+ charcode = gli.value().first.unicode();
+ break;
}
}
+// qDebug() << "\tmore: " << gindex << " '" << charcode << "' --> '" << buf << "'";
+ GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)), glyphname));
+ }
return true;
}
Modified: trunk/Scribus/scribus/fonts/scfontmetrics.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=18433&path=/trunk/Scribus/scribus/fonts/scfontmetrics.h
==============================================================================
--- trunk/Scribus/scribus/fonts/scfontmetrics.h (original)
+++ trunk/Scribus/scribus/fonts/scfontmetrics.h Sun Aug 25 11:23:09 2013
@@ -26,13 +26,12 @@
class ScFace;
class Scribusdoc;
+struct FtFace;
-int SCRIBUS_API setBestEncoding(FT_Face face);
+int SCRIBUS_API setBestEncoding(FT_Face face);
FPointArray SCRIBUS_API traceChar(FT_Face face, uint chr, int chs, qreal *x, qreal *y, bool *err);
FPointArray SCRIBUS_API traceGlyph(FT_Face face, uint chr, int chs, qreal *x, qreal *y, bool *err);
-QPixmap SCRIBUS_API FontSample(const ScFace& fnt, int s, QString ts, QColor back, bool force = false);
-//QPixmap SCRIBUS_API fontSamples(const ScFace& fnt, int s, QString ts, QColor back);
-bool SCRIBUS_API GlyNames(FT_Face face, QMap<uint, std::pair<QChar, QString> >& GList);
-
+QPixmap SCRIBUS_API FontSample(const ScFace& fnt, int s, QString ts, QColor back, bool force = false);
+bool SCRIBUS_API GlyphNames(const FtFace& fnt, QMap<uint, std::pair<QChar, QString> >& GList);
#endif
More information about the scribus-commit
mailing list