r22143 by jghali -

scribus-commit scribus-commit at lists.scribus.net
Fri Aug 25 10:03:33 UTC 2017


Author: jghali
Date: Fri Aug 25 10:03:33 2017
New Revision: 22143

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=22143
Log:
#14960 related: better handling of glyph ligatures when generating PDF ToUnicode map

Modified:
    trunk/Scribus/scribus/fonts/ftface.cpp
    trunk/Scribus/scribus/fonts/ftface.h
    trunk/Scribus/scribus/fonts/scface.h
    trunk/Scribus/scribus/fonts/scface_ttf.cpp
    trunk/Scribus/scribus/pdflib_core.cpp
    trunk/Scribus/scribus/ui/charselectenhanced.cpp

Modified: trunk/Scribus/scribus/fonts/ftface.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22143&path=/trunk/Scribus/scribus/fonts/ftface.cpp
==============================================================================
--- trunk/Scribus/scribus/fonts/ftface.cpp	(original)
+++ trunk/Scribus/scribus/fonts/ftface.cpp	Fri Aug 25 10:03:33 2017
@@ -340,10 +340,14 @@
 		// just in case FT gives empty string or ".notdef"
 		// no valid glyphname except ".notdef" starts with '.'		
 //		qDebug() << "\t" << gindex << " '" << charcode << "' --> '" << (notfound? "notfound" : buf) << "'";
+		ScFace::GlyphEncoding glEncoding;
+		glEncoding.charcode = charcode;
 		if (notfound || buf[0] == '\0' || buf[0] == '.')
-			GList.insert(gindex, std::make_pair(static_cast<ScFace::ucs4_type>(charcode), adobeGlyphName(charcode)));
+			glEncoding.glyphName = adobeGlyphName(charcode);
 		else
-			GList.insert(gindex, std::make_pair(static_cast<ScFace::ucs4_type>(charcode), QString(reinterpret_cast<char*>(buf))));
+			glEncoding.glyphName = QString(reinterpret_cast<char*>(buf));
+		glEncoding.toUnicode = QString().sprintf("%04X", charcode);
+		GList.insert(gindex, glEncoding);
 
 		charcode = FT_Get_Next_Char(face, charcode, &gindex );
 	}
@@ -365,19 +369,60 @@
 		ScFace::FaceEncoding::Iterator gli;
 		for (gli = GList.begin(); gli != GList.end(); ++gli)
 		{
-			if (glyphname == gli.value().second)
+			if (glyphname == gli.value().glyphName)
 			{
-				charcode = gli.value().first;
+				charcode = gli.value().charcode;
 				break;
 			}
 		}
 //		qDebug() << "\tmore: " << gindex << " '" << charcode << "' --> '" << buf << "'";
-		GList.insert(gindex, std::make_pair(static_cast<ScFace::ucs4_type>(charcode), glyphname));
+		ScFace::GlyphEncoding glEncoding;
+		glEncoding.charcode  = static_cast<ScFace::ucs4_type>(charcode);
+		glEncoding.glyphName = glyphname;
+		glEncoding.toUnicode = QString().sprintf("%04X", charcode);
+		if ((charcode == 0) && glyphname.startsWith("uni"))
+		{
+			QString uniHexStr = uniGlyphNameToUnicode(glyphname);
+			if (uniHexStr.length() > 0)
+				glEncoding.toUnicode = uniHexStr;
+		}
+		GList.insert(gindex, glEncoding);
 	}
 
 	return true;
 }
 
+QString FtFace::uniGlyphNameToUnicode(const QString& glyphName) const
+{
+	if (!glyphName.startsWith("uni"))
+		return QString();
+	if (glyphName.length() < 7)
+		return QString();
+
+	QString uniStr = glyphName.mid(3);
+	int firstDot = uniStr.indexOf('.');
+	if (firstDot >= 0)
+		uniStr = uniStr.left(firstDot);
+
+	bool isHexString = true;
+	if ((uniStr.length() <= 0) || (uniStr.length() % 4 != 0))
+		return QString();
+
+	int len = uniStr.length();
+	for (int i = 0; i < len; ++i)
+	{
+		int uni = uniStr[i].unicode();
+		isHexString &= (uni >= '0' && uni <= '9') ||
+			           (uni >= 'a' && uni <= 'f') ||
+			           (uni >= 'A' && uni <= 'F');
+		if (!isHexString)
+			break;
+	}
+
+	if (!isHexString)
+		return QString();
+	return uniStr.toUpper();
+}
 
 void FtFace::RawData(QByteArray & bb) const
 {

Modified: trunk/Scribus/scribus/fonts/ftface.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22143&path=/trunk/Scribus/scribus/fonts/ftface.h
==============================================================================
--- trunk/Scribus/scribus/fonts/ftface.h	(original)
+++ trunk/Scribus/scribus/fonts/ftface.h	Fri Aug 25 10:03:33 2017
@@ -122,6 +122,7 @@
 	mutable qreal m_strikeoutPos;
 	mutable qreal m_strokeWidth;
 
+	QString uniGlyphNameToUnicode(const QString& glyphName) const;
 };
 
 #endif

Modified: trunk/Scribus/scribus/fonts/scface.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22143&path=/trunk/Scribus/scribus/fonts/scface.h
==============================================================================
--- trunk/Scribus/scribus/fonts/scface.h	(original)
+++ trunk/Scribus/scribus/fonts/scface.h	Fri Aug 25 10:03:33 2017
@@ -83,9 +83,16 @@
 		// handled by freetype:	PFB_MAC, DFONT, HQX, MACBIN,
 		SFNT, TTCF, UNKNOWN_FORMAT };
 
-    typedef uint gid_type;
-    typedef uint ucs4_type;
-    typedef QMap<gid_type, std::pair<ucs4_type, QString> > FaceEncoding;
+	typedef uint gid_type;
+	typedef uint ucs4_type;
+	struct GlyphEncoding
+	{
+		GlyphEncoding() { charcode = 0; toUnicode = "0000"; }
+		ucs4_type charcode;
+		QString   glyphName;
+		QString   toUnicode;
+	};
+	typedef QMap<gid_type, GlyphEncoding> FaceEncoding;
 
 	static const gid_type CONTROL_GLYPHS = 2000000000; // 2 billion
 
@@ -198,7 +205,7 @@
 
 		virtual bool isCIDKeyed() const { return isCIDFont; }
 		virtual bool hasNames() const { return hasGlyphNames; }
-		virtual bool glyphNames(QMap<gid_type, std::pair<ucs4_type, QString> >& gList) const;
+		virtual bool glyphNames(ScFace::FaceEncoding& gList) const;
 
 		// these use the cache:
 		virtual qreal       glyphWidth(gid_type gl, qreal sz)   const;
@@ -233,7 +240,7 @@
 
 	bool EmbedFont(QByteArray &str);
 	void RawData(QByteArray & bb);
-	bool glyphNames(QMap<gid_type, std::pair<ucs4_type, QString> >& gList);
+	bool glyphNames(FaceEncoding& gList);
 
 	/// prevent unloading of face data
 	void increaseUsage() const;

Modified: trunk/Scribus/scribus/fonts/scface_ttf.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22143&path=/trunk/Scribus/scribus/fonts/scface_ttf.cpp
==============================================================================
--- trunk/Scribus/scribus/fonts/scface_ttf.cpp	(original)
+++ trunk/Scribus/scribus/fonts/scface_ttf.cpp	Fri Aug 25 10:03:33 2017
@@ -91,7 +91,11 @@
 	charcode = FT_Get_First_Char(face, &gindex);
 	while (gindex != 0)
 	{
-		GList.insert(gindex, std::make_pair(static_cast<ScFace::ucs4_type>(charcode), adobeGlyphName(charcode)));
+		ScFace::GlyphEncoding glEncoding;
+		glEncoding.charcode  = charcode;
+		glEncoding.glyphName = adobeGlyphName(charcode);
+		glEncoding.toUnicode = QString().sprintf("%04X", charcode);
+		GList.insert(gindex, glEncoding);
 		charcode = FT_Get_Next_Char(face, charcode, &gindex );
 	}
 

Modified: trunk/Scribus/scribus/pdflib_core.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22143&path=/trunk/Scribus/scribus/pdflib_core.cpp
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.cpp	(original)
+++ trunk/Scribus/scribus/pdflib_core.cpp	Fri Aug 25 10:03:33 2017
@@ -1526,8 +1526,9 @@
 		glyphWidths.append(qRound(np1.x()));
 
 		PdfId charProcObject = writer.newObject();
-		charProcs.append(Pdf::toName(gl[ig.key()].second)+" "+Pdf::toPdf(charProcObject)+" 0 R\n");
-		encoding += Pdf::toName(gl[ig.key()].second)+" ";
+		const ScFace::GlyphEncoding& glEncoding = gl[ig.key()];
+		charProcs.append(Pdf::toName(glEncoding.glyphName)+" "+Pdf::toPdf(charProcObject)+" 0 R\n");
+		encoding += Pdf::toName(glEncoding.glyphName)+" ";
 		glyphMapping.insert(ig.key(), glyphCount + SubFonts * 256);
 		writer.startObj(charProcObject);
 		if (Options.Compress)
@@ -1538,10 +1539,9 @@
 		PutDoc("\n>>\nstream\n"+EncStream(fon, charProcObject)+"\nendstream");
 		writer.endObj(charProcObject);
 
-		QString tmp, tmp2;
+		QString tmp;
 		tmp.sprintf("%02X", glyphCount);
-		tmp2.sprintf("%04X", gl[ig.key()].first);
-		toUnicodeMap += "<" + Pdf::toAscii(tmp) + "> <" + Pdf::toAscii(tmp2) + ">\n";
+		toUnicodeMap += "<" + Pdf::toAscii(tmp) + "> <" + Pdf::toAscii(glEncoding.toUnicode) + ">\n";
 		toUnicodeMapCounter++;
 		if (toUnicodeMapCounter == 100)
 		{
@@ -1843,7 +1843,7 @@
 			PutDoc(Pdf::toPdf(gid)+" ["+Pdf::toPdf(static_cast<int>(face.glyphWidth(*git)* 1000))+"] " );
 			QString tmp, tmp2;
 			tmp.sprintf("%04X", gid);
-			tmp2.sprintf("%04X", gl.value(*git).first);
+			tmp2 = gl.value(*git).toUnicode;
 			toUnicodeMap += "<" + Pdf::toAscii(tmp)+ "> <" + Pdf::toAscii(tmp2) + ">\n";
 			toUnicodeMapCounter++;
 			if (toUnicodeMapCounter == 100)
@@ -1969,17 +1969,18 @@
 		{
 			uint glyph = 224 * Fc + ww2 - 32;
 			ScFace::FaceEncoding::ConstIterator glIt = gl.find(glyph);
-			if (glIt != gl.cend() && !glIt.value().second.isEmpty())
-			{
+			if (glIt != gl.cend() && !glIt.value().glyphName.isEmpty())
+			{
+				const ScFace::GlyphEncoding& glEncoding = glIt.value();
 				if (startOfSeq)
 				{
 					PutDoc(Pdf::toPdf(ww2)+" ");
 					startOfSeq = false;
 				}
-				PutDoc(Pdf::toName(glIt.value().second)+" ");
+				PutDoc(Pdf::toName(glEncoding.glyphName)+" ");
 				QString tmp, tmp2;
 				tmp.sprintf("%02X", ww2);
-				tmp2.sprintf("%04X", glIt.value().first);
+				tmp2 = glEncoding.toUnicode;
 				toUnicodeMap += "<" + Pdf::toAscii(tmp) + "> <" + Pdf::toAscii(tmp2) + ">\n";
 				//QString("<%1> <%2>\n").arg(tmp).arg((tmp2));
 				toUnicodeMapCounter++;
@@ -2152,13 +2153,13 @@
 	PdfId embeddedFontObj = PDF_EmbedFontObject(subset, QByteArray());
 	PdfId fontDes = PDF_WriteFontDescriptor(subsetName, face, face.format(), embeddedFontObj);
 	
-	ScFace::FaceEncoding fullEncoding, subEncoding;
+	ScFace::FaceEncoding fullEncoding;
 	QMap<uint,uint> glyphmap;
 	face.glyphNames(fullEncoding);
 	for (int i = 0; i < glyphs.length(); ++i)
 	{
 		glyphmap[glyphs[i]] = i;
-		qDebug() << glyphs[i] << " --> " << i << QChar(fullEncoding[glyphs[i]].first);
+		qDebug() << glyphs[i] << " --> " << i << QChar(fullEncoding[glyphs[i]].charcode);
 	}
 	
 	PdfFont result = PDF_EncodeCidFont(fontName, face, subsetName, fontDes, fullEncoding, glyphmap);
@@ -2196,13 +2197,13 @@
 	PdfId embeddedFontObj = PDF_EmbedFontObject(subset, "/CIDFontType0C");
 	PdfId fontDes = PDF_WriteFontDescriptor(subsetName, face, face.format(), embeddedFontObj);
 
-	ScFace::FaceEncoding fullEncoding, subEncoding;
+	ScFace::FaceEncoding fullEncoding;
 	QMap<uint,uint> glyphmap;
 	face.glyphNames(fullEncoding);
 	for (int i = 0; i < glyphs.length(); ++i)
 	{
 		glyphmap[glyphs[i]] = i;
-		qDebug() << glyphs[i] << " --> " << i << QChar(fullEncoding[glyphs[i]].first);
+		qDebug() << glyphs[i] << " --> " << i << QChar(fullEncoding[glyphs[i]].charcode);
 	}
 	
 	PdfFont result = PDF_EncodeCidFont(fontName, face, subsetName, fontDes, fullEncoding, glyphmap);

Modified: trunk/Scribus/scribus/ui/charselectenhanced.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22143&path=/trunk/Scribus/scribus/ui/charselectenhanced.cpp
==============================================================================
--- trunk/Scribus/scribus/ui/charselectenhanced.cpp	(original)
+++ trunk/Scribus/scribus/ui/charselectenhanced.cpp	Fri Aug 25 10:03:33 2017
@@ -110,8 +110,8 @@
 	for (ScFace::FaceEncoding::iterator it=glyphs.begin();
 	        it != glyphs.end(); ++it)
 	{
-		charcode = it.value().first;
-		gname = it.value().second;
+		charcode = it.value().charcode;
+		gname = it.value().glyphName;
 		charactersFull.append(charcode);
 		if ((charcode >= 0x0020) && (charcode <= 0x007F))
 			charactersLatin1.append(charcode);




More information about the scribus-commit mailing list