r24429 by jghali - #16447: improve extraction of PDF text, noticeably ligatures

scribus-commit scribus-commit at lists.scribus.net
Tue Jan 26 22:36:49 UTC 2021


Author: jghali
Date: Tue Jan 26 22:36:49 2021
New Revision: 24429

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=24429
Log:
#16447: improve extraction of PDF text, noticeably ligatures

Modified:
    trunk/Scribus/scribus/pdflib_core.cpp
    trunk/Scribus/scribus/pdflib_core.h
    trunk/Scribus/scribus/pslib.cpp
    trunk/Scribus/scribus/scribusdoc.cpp
    trunk/Scribus/scribus/scribusdoc.h

Modified: trunk/Scribus/scribus/pdflib_core.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24429&path=/trunk/Scribus/scribus/pdflib_core.cpp
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.cpp	(original)
+++ trunk/Scribus/scribus/pdflib_core.cpp	Tue Jan 26 22:36:49 2021
@@ -618,7 +618,7 @@
 		return false;
 	}
 
-	QMap<QString, QMap<uint, FPointArray> > usedFonts;
+	QMap<QString, QMap<uint, QString> > usedFonts;
 	doc.getUsedFonts(usedFonts);
 
 	if (PDF_Begin_Doc(fn, PrefsManager::instance().appPrefs.fontPrefs.AvailFonts, usedFonts, doc.scMW()->bookmarkPalette->BView))
@@ -1001,7 +1001,7 @@
 	return (succeed ? bytesWritten : 0);
 }
 
-bool PDFLibCore::PDF_Begin_Doc(const QString& fn, SCFonts &AllFonts, const QMap<QString, QMap<uint, FPointArray> >& DocFonts, BookmarkView* vi)
+bool PDFLibCore::PDF_Begin_Doc(const QString& fn, SCFonts &AllFonts, const QMap<QString, QMap<uint, QString> >& DocFonts, BookmarkView* vi)
 {
 	if (!writer.open(fn))
 		return false;
@@ -1201,11 +1201,10 @@
 	writer.endObj(writer.InfoObj);
 }
 
-QMap<QString, QMap<uint, FPointArray> >
-PDFLibCore::PDF_Begin_FindUsedFonts(SCFonts &AllFonts, const QMap<QString, QMap<uint, FPointArray> >& DocFonts)
-{
-	QMap<QString, QMap<uint, FPointArray> > ReallyUsed;
-	ReallyUsed.clear();
+QMap<QString, QMap<uint, QString> >
+PDFLibCore::PDF_Begin_FindUsedFonts(SCFonts &AllFonts, const QMap<QString, QMap<uint, QString> >& DocFonts)
+{
+	QMap<QString, QMap<uint, QString> > usedFonts;
 	PageItem* pgit;
 	QMap<int, QByteArray> ind2PDFabr;
 	const QByteArray tmpf[] = {"/Courier", "/Courier-Bold", "/Courier-Oblique", "/Courier-BoldOblique",
@@ -1238,7 +1237,7 @@
 					if (Options.Version < PDFVersion::PDF_14)
 						StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
 					QString replacementName = pgit->itemText.defaultStyle().charStyle().font().replacementName();
-					ReallyUsed.insert(replacementName, DocFonts[replacementName]);
+					usedFonts.insert(replacementName, DocFonts[replacementName]);
 				}
 			}
 			uint start = pgit->isTextFrame() ? (uint) pgit->firstInFrame() : 0;
@@ -1246,7 +1245,7 @@
 			for (uint e = start; e < stop; ++e)
 			{
 				QString replacementName = pgit->itemText.charStyle(e).font().replacementName();
-				ReallyUsed.insert(replacementName, DocFonts[replacementName]);
+				usedFonts.insert(replacementName, DocFonts[replacementName]);
 			}
 		}
 	}
@@ -1273,7 +1272,7 @@
 					if (Options.Version < PDFVersion::PDF_14)
 						StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
 					QString replacementName = pgit->itemText.defaultStyle().charStyle().font().replacementName();
-					ReallyUsed.insert(replacementName, DocFonts[replacementName]);
+					usedFonts.insert(replacementName, DocFonts[replacementName]);
 				}
 			}
 			uint start = pgit->isTextFrame() ? (uint) pgit->firstInFrame() : 0;
@@ -1281,7 +1280,7 @@
 			for (uint e = start; e < stop; ++e)
 			{
 				QString replacementName = pgit->itemText.charStyle(e).font().replacementName();
-				ReallyUsed.insert(replacementName, DocFonts[replacementName]);
+				usedFonts.insert(replacementName, DocFonts[replacementName]);
 			}
 		}
 	}
@@ -1308,7 +1307,7 @@
 					if (Options.Version < PDFVersion::PDF_14)
 						StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
 					QString replacementName = pgit->itemText.defaultStyle().charStyle().font().replacementName();
-					ReallyUsed.insert(replacementName, DocFonts[replacementName]);
+					usedFonts.insert(replacementName, DocFonts[replacementName]);
 				}
 			}
 			uint start = pgit->isTextFrame() ? (uint) pgit->firstInFrame() : 0;
@@ -1316,7 +1315,7 @@
 			for (uint e = start; e < stop; ++e)
 			{
 				QString replacementName = pgit->itemText.charStyle(e).font().replacementName();
-				ReallyUsed.insert(replacementName, DocFonts[replacementName]);
+				usedFonts.insert(replacementName, DocFonts[replacementName]);
 			}
 		}
 	}
@@ -1348,7 +1347,7 @@
 						if (Options.Version < PDFVersion::PDF_14)
 							StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
 						QString replacementName = pgit->itemText.defaultStyle().charStyle().font().replacementName();
-						ReallyUsed.insert(replacementName, DocFonts[replacementName]);
+						usedFonts.insert(replacementName, DocFonts[replacementName]);
 					}
 				}
 				uint start = pgit->isTextFrame() ? (uint) pgit->firstInFrame() : 0;
@@ -1356,12 +1355,12 @@
 				for (uint e = start; e < stop; ++e)
 				{
 					QString replacementName = pgit->itemText.charStyle(e).font().replacementName();
-					ReallyUsed.insert(replacementName, DocFonts[replacementName]);
+					usedFonts.insert(replacementName, DocFonts[replacementName]);
 				}
 			}
 		}
 	}
-	return ReallyUsed;
+	return usedFonts;
 }
 
 static QByteArray sanitizeFontName(QString fn)
@@ -1421,7 +1420,7 @@
 }
 
 
-PdfFont PDFLibCore::PDF_WriteType3Font(const QByteArray& name, ScFace& face, const QMap<uint,FPointArray>& RealGlyphs)
+PdfFont PDFLibCore::PDF_WriteType3Font(const QByteArray& name, ScFace& face, const QMap<uint, QString>& usedGlyphs)
 {
 	PdfFont result;
 	result.name = Pdf::toName(name);
@@ -1456,15 +1455,17 @@
 	ScFace::FaceEncoding gl;
 	face.glyphNames(gl);
 
-	QMap<uint,FPointArray>::ConstIterator ig;
-	for (ig = RealGlyphs.cbegin(); ig != RealGlyphs.cend(); ++ig)
+	for (auto ig = usedGlyphs.cbegin(); ig != usedGlyphs.cend(); ++ig)
 	{
 		FPoint np, np1, np2;
 		bool nPath = true;
 		fon.resize(0);
-		if (ig.value().size() > 3)
-		{
-			FPointArray gly = ig.value();
+
+		uint gid = ig.key();
+		FPointArray glyphOutline = face.glyphOutline(gid);
+		if (glyphOutline.size() > 3)
+		{
+			FPointArray gly = glyphOutline;
 			QTransform mat;
 			mat.scale(100.0, -100.0);
 			gly.map(mat);
@@ -1483,9 +1484,9 @@
 					fon += FToStr(np.x()) + " " + FToStr(np.y()) + " m\n";
 					nPath = false;
 				}
-				np = gly.point(poi+1);
-				np1 = gly.point(poi+3);
-				np2 = gly.point(poi+2);
+				np = gly.point(poi + 1);
+				np1 = gly.point(poi + 3);
+				np2 = gly.point(poi + 2);
 				fon += FToStr(np.x()) + " " + FToStr(np.y()) + " " + FToStr(np1.x()) + " " + FToStr(np1.y()) + " " + FToStr(np2.x()) + " " + FToStr(np2.y()) + " c\n";
 			}
 			fon += useNonZeroRule? "h f\n" : "h f*\n";
@@ -1522,16 +1523,22 @@
 		// using ScFace's glyphNames(), so generate custom glyph names using glyph index.
 		// With Type 3 fonts we have more flexibility than with other fonts.
 		QString glGlyphName, glToUnicode;
-		auto  glyphIt = gl.constFind(ig.key());
+		auto  glyphIt = gl.constFind(gid);
 		if ((glyphIt != gl.constEnd()) && (glyphIt->charcode > 0))
 			glToUnicode = QString::asprintf("%04X", glyphIt->charcode);
-		else
+		if (glToUnicode.isEmpty() && usedGlyphs.contains(gid))
+		{
+			QString uniStr = usedGlyphs.value(gid);
+			for (int i = 0; i < uniStr.length(); ++i)
+				glToUnicode += QString::asprintf("%04X", uniStr.at(i).unicode());
+		}
+		if (glToUnicode.isEmpty())
 			glToUnicode = QString("0000");
-		glGlyphName = "gly" + QString::asprintf("%04X", ig.key());
+		glGlyphName = "gly" + QString::asprintf("%04X", gid);
 
 		charProcs.append(Pdf::toName(glGlyphName) + " " + Pdf::toPdf(charProcObject) + " 0 R\n");
 		encoding += Pdf::toName(glGlyphName) + " ";
-		glyphMapping.insert(ig.key(), glyphCount + SubFonts * 256);
+		glyphMapping.insert(gid, glyphCount + SubFonts * 256);
 
 		QString tmp = QString::asprintf("%02X", glyphCount);
 		toUnicodeMap += "<" + Pdf::toAscii(tmp) + "> <" + Pdf::toAscii(glToUnicode) + ">\n";
@@ -1545,7 +1552,7 @@
 		}
 
 		glyphCount++;
-		int glyphsLeft = RealGlyphs.count() - SubFonts * 256;
+		int glyphsLeft = usedGlyphs.count() - SubFonts * 256;
 		if ((glyphCount > 255) || (glyphCount == glyphsLeft))
 		{
 			PdfId fontWidths = writer.newObject();
@@ -1641,7 +1648,7 @@
 }
 
 
-PdfFont PDFLibCore::PDF_WriteGlyphsAsXForms(const QByteArray& fontName, ScFace& face, const QMap<uint,FPointArray>& RealGlyphs)
+PdfFont PDFLibCore::PDF_WriteGlyphsAsXForms(const QByteArray& fontName, ScFace& face, const QMap<uint, QString>& usedGlyphs)
 {
 	PdfFont result;
 	result.name = Pdf::toName(fontName);
@@ -1657,15 +1664,17 @@
 	bool useNonZeroRule = (face.type() == ScFace::TTF);
 
 	QByteArray fon;
-	QMap<uint,FPointArray>::ConstIterator ig;
-	for (ig = RealGlyphs.cbegin(); ig != RealGlyphs.cend(); ++ig)
+	for (auto ig = usedGlyphs.cbegin(); ig != usedGlyphs.cend(); ++ig)
 	{
 		FPoint np, np1, np2;
 		bool nPath = true;
 		fon.resize(0);
-		if (ig.value().size() > 3)
-		{
-			FPointArray gly = ig.value();
+
+		uint gid = ig.key();
+		FPointArray glyphOutline = face.glyphOutline(gid);
+		if (glyphOutline.size() > 3)
+		{
+			FPointArray gly = glyphOutline;
 			QTransform mat;
 			mat.scale(0.1, 0.1);
 			gly.map(mat);
@@ -1683,9 +1692,9 @@
 					fon += FToStr(np.x()) + " " + FToStr(-np.y()) + " m\n";
 					nPath = false;
 				}
-				np = gly.point(poi+1);
-				np1 = gly.point(poi+3);
-				np2 = gly.point(poi+2);
+				np = gly.point(poi + 1);
+				np1 = gly.point(poi + 3);
+				np2 = gly.point(poi + 2);
 				fon += FToStr(np.x()) + " " + FToStr(-np.y()) + " " +
 				FToStr(np1.x()) + " " + FToStr(-np1.y()) + " " +
 				FToStr(np2.x()) + " " + FToStr(-np2.y()) + " c\n";
@@ -1716,7 +1725,7 @@
 			PutDoc("\n/Filter /FlateDecode");
 		PutDoc(" >>\nstream\n" + EncStream(fon, fontGlyphXForm) + "\nendstream");
 		writer.endObj(fontGlyphXForm);
-		pageData.XObjects[fontName + "_gl" + Pdf::toPdf(ig.key())] = fontGlyphXForm;
+		pageData.XObjects[fontName + "_gl" + Pdf::toPdf(gid)] = fontGlyphXForm;
 	}
 	return result;
 }
@@ -1808,7 +1817,7 @@
 	return fontDescriptor;
 }
 
-PdfFont PDFLibCore::PDF_EncodeCidFont(const QByteArray& fontName, ScFace& face, const QByteArray& baseFont, PdfId fontDes, const ScFace::FaceEncoding& gl, const QMap<uint,uint>& glyphmap)
+PdfFont PDFLibCore::PDF_EncodeCidFont(const QByteArray& fontName, ScFace& face, const QByteArray& baseFont, PdfId fontDes, const QMap<uint, QString>& usedGlyphs, const QMap<uint,uint>& glyphmap)
 {
 	PdfFont result;
 	result.name = Pdf::toName(fontName);
@@ -1824,7 +1833,9 @@
 	QByteArray toUnicodeMap;
 	int toUnicodeMapCounter = 0;
 
-	QList<uint> keys = gl.uniqueKeys();
+	ScFace::FaceEncoding encoding;
+	face.glyphNames(encoding);
+	QList<uint> keys = encoding.uniqueKeys();
 	bool seenNotDef = false;
 	
 	PutDoc("[ ");
@@ -1837,7 +1848,18 @@
 
 		PutDoc(Pdf::toPdf(gid) + " [" + Pdf::toPdf(static_cast<int>(face.glyphWidth(*git) * 1000)) + "] ");
 		QString tmp = QString::asprintf("%04X", gid);
-		QString tmp2 = gl.value(*git).toUnicode;
+		QString tmp2;
+		auto  glyphIt = encoding.constFind(*git);
+		if ((glyphIt != encoding.constEnd()) && (glyphIt->charcode > 0))
+			tmp2 = glyphIt->toUnicode;
+		if (tmp2.isEmpty() && usedGlyphs.contains(*git))
+		{
+			QString uniStr = usedGlyphs.value(*git);
+			for (int i = 0; i < uniStr.length(); ++i)
+				tmp2 += QString::asprintf("%04X", uniStr.at(i).unicode());
+		}
+		if (tmp2.isEmpty())
+			tmp2 = "0000";
 		toUnicodeMap += "<" + Pdf::toAscii(tmp) + "> <" + Pdf::toAscii(tmp2) + ">\n";
 		toUnicodeMapCounter++;
 		if (toUnicodeMapCounter == 100)
@@ -1909,13 +1931,16 @@
 }
 
 
-PdfFont PDFLibCore::PDF_EncodeSimpleFont(const QByteArray& fontName, ScFace& face, const QByteArray& baseFont, const QByteArray& subtype, bool isEmbedded, PdfId fontDes, const ScFace::FaceEncoding& gl)
+PdfFont PDFLibCore::PDF_EncodeSimpleFont(const QByteArray& fontName, ScFace& face, const QByteArray& baseFont, const QByteArray& subtype, bool isEmbedded, PdfId fontDes, const QMap<uint, QString>& usedGlyphs)
 {
 	PdfFont result;
 	result.name = Pdf::toName(fontName);
 	result.usage = Used_in_Content;
 	result.method = isEmbedded? Use_Embedded : Use_System;
 	result.encoding = Encode_224;
+
+	ScFace::FaceEncoding gl;
+	face.glyphNames(gl);
 	
 	int nglyphs = 0;
 	for (auto gli = gl.cbegin(); gli != gl.cend(); ++gli)
@@ -1974,9 +1999,16 @@
 				}
 				PutDoc(Pdf::toName(glEncoding.glyphName) + " ");
 				QString tmp = QString::asprintf("%02X", ww2);
-				QString tmp2 = glEncoding.toUnicode;
+				QString tmp2 = (glEncoding.charcode > 0) ? glEncoding.toUnicode : QString();
+				if (tmp2.isEmpty() && usedGlyphs.contains(glyph))
+				{
+					QString uniStr = usedGlyphs.value(glyph);
+					for (int i = 0; i < uniStr.length(); ++i)
+						tmp2 += QString::asprintf("%04X", uniStr.at(i).unicode());
+				}
+				if (tmp2.isEmpty())
+					tmp2 = "0000";
 				toUnicodeMap += "<" + Pdf::toAscii(tmp) + "> <" + Pdf::toAscii(tmp2) + ">\n";
-				//QString("<%1> <%2>\n").arg(tmp).arg((tmp2));
 				toUnicodeMapCounter++;
 				if (toUnicodeMapCounter == 100)
 				{
@@ -2131,12 +2163,12 @@
 */
 
 
-PdfFont PDFLibCore::PDF_WriteTtfSubsetFont(const QByteArray& fontName, ScFace& face, const QMap<uint,FPointArray>& RealGlyphs)
+PdfFont PDFLibCore::PDF_WriteTtfSubsetFont(const QByteArray& fontName, ScFace& face, const QMap<uint, QString>& usedGlyphs)
 {
 	QByteArray font;
 	face.rawData(font);
 	/*dumpFont(face.psName() + ".ttf", font);*/
-	QList<ScFace::gid_type> glyphs = RealGlyphs.uniqueKeys();
+	QList<ScFace::gid_type> glyphs = usedGlyphs.uniqueKeys();
 	glyphs.removeAll(0);
 	glyphs.prepend(0);
 	QByteArray subset = sfnt::subsetFace(font, glyphs);
@@ -2147,21 +2179,19 @@
 	PdfId embeddedFontObj = PDF_EmbedFontObject(subset, QByteArray());
 	PdfId fontDes = PDF_WriteFontDescriptor(subsetName, face, face.format(), embeddedFontObj);
 	
-	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]].charcode);
 	}
 	
-	PdfFont result = PDF_EncodeCidFont(fontName, face, subsetName, fontDes, fullEncoding, glyphmap);
+	PdfFont result = PDF_EncodeCidFont(fontName, face, subsetName, fontDes, usedGlyphs, glyphmap);
 	return result;
 }
 
 
-PdfFont PDFLibCore::PDF_WriteCffSubsetFont(const QByteArray& fontName, ScFace& face, const QMap<uint,FPointArray>& RealGlyphs)
+PdfFont PDFLibCore::PDF_WriteCffSubsetFont(const QByteArray& fontName, ScFace& face, const QMap<uint, QString>& usedGlyphs)
 {
 //	QByteArray sfnt; //TEST
 //	face.rawData(sfnt);
@@ -2180,7 +2210,7 @@
 	face.rawData(data);
 	font = sfnt::getTable(data, "CFF ");
 	/*dumpFont(face.psName() + ".cff", font);*/
-	QList<ScFace::gid_type> glyphs = RealGlyphs.uniqueKeys();
+	QList<ScFace::gid_type> glyphs = usedGlyphs.uniqueKeys();
 	glyphs.removeAll(0);
 	glyphs.prepend(0);
 	QByteArray subset = cff::subsetFace(font, glyphs);
@@ -2191,16 +2221,14 @@
 	PdfId embeddedFontObj = PDF_EmbedFontObject(subset, "/CIDFontType0C");
 	PdfId fontDes = PDF_WriteFontDescriptor(subsetName, face, face.format(), embeddedFontObj);
 
-	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]].charcode);
 	}
 	
-	PdfFont result = PDF_EncodeCidFont(fontName, face, subsetName, fontDes, fullEncoding, glyphmap);
+	PdfFont result = PDF_EncodeCidFont(fontName, face, subsetName, fontDes, usedGlyphs, glyphmap);
 	return result;
 }
 
@@ -2335,21 +2363,21 @@
 }
 
 
-void PDFLibCore::PDF_Begin_WriteUsedFonts(SCFonts &AllFonts, const QMap<QString, QMap<uint, FPointArray> >& ReallyUsed)
+void PDFLibCore::PDF_Begin_WriteUsedFonts(SCFonts &AllFonts, const QMap<QString, QMap<uint, QString> >& usedFonts)
 {
 	qDebug() << "embed list:" << QStringList(Options.EmbedList).join(", ");
 	qDebug() << "subset list:" << QStringList(Options.SubsetList).join(", ");
 	qDebug() << "outline list:" << QStringList(Options.OutlineList).join(", ");
-	QMap<QString,QMap<uint, FPointArray> >::ConstIterator it;
+
 	int a = 0;
-	for (it = ReallyUsed.cbegin(); it != ReallyUsed.cend(); ++it)
+	for (auto it = usedFonts.cbegin(); it != usedFonts.cend(); ++it)
 	{
 		ScFace& face(AllFonts[it.key()]);
 		ScFace::FontFormat fformat = face.format();
 		PdfFont pdfFont;
 		QByteArray fontName = QByteArray("Fo") + Pdf::toPdf(a);
 		
-		QMap<uint, FPointArray> usedGlyphs = it.value();
+		QMap<uint, QString> usedGlyphs = it.value();
 		if (usedGlyphs.count() <= 0)
 			continue;
 		
@@ -2400,8 +2428,7 @@
 				bool hasNeededGlyphNames = face.hasNames() && (gl.count() >= usedGlyphs.count());
 				if ((fformat == ScFace::SFNT || fformat == ScFace::TTCF))
 				{
-					QMap<uint, FPointArray>::const_iterator it;
-					for (it = usedGlyphs.constBegin(); it != usedGlyphs.constEnd(); ++it)
+					for (auto it = usedGlyphs.constBegin(); it != usedGlyphs.constEnd(); ++it)
 					{
 						int glyphIndex = it.key();
 						hasNeededGlyphNames &= gl.contains(glyphIndex);
@@ -2415,11 +2442,11 @@
 				if ((face.isSymbolic() || !hasNeededGlyphNames || Options.Version == PDFVersion::PDF_X4 || face.type() == ScFace::OTF) &&
 					(fformat == ScFace::SFNT || fformat == ScFace::TTCF))
 				{
-					pdfFont = PDF_EncodeCidFont(fontName, face, baseFont, fontDescriptor, gl, QMap<uint,uint>());
+					pdfFont = PDF_EncodeCidFont(fontName, face, baseFont, fontDescriptor, usedGlyphs, QMap<uint,uint>());
 				}
 				else
 				{
-					pdfFont = PDF_EncodeSimpleFont(fontName, face, baseFont, subtype, embeddedFontObject != 0, fontDescriptor, gl);
+					pdfFont = PDF_EncodeSimpleFont(fontName, face, baseFont, subtype, embeddedFontObject != 0, fontDescriptor, usedGlyphs);
 				}
 
 				if ((Options.Version != PDFVersion::PDF_X4) && (face.type() != ScFace::OTF))

Modified: trunk/Scribus/scribus/pdflib_core.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24429&path=/trunk/Scribus/scribus/pdflib_core.h
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.h	(original)
+++ trunk/Scribus/scribus/pdflib_core.h	Tue Jan 26 22:36:49 2021
@@ -95,22 +95,22 @@
 	bool PDF_IsPDFX();
 	bool PDF_IsPDFX(const PDFVersion& ver);
 
-	bool PDF_Begin_Doc(const QString& fn, SCFonts &AllFonts, const QMap<QString, QMap<uint, FPointArray> >& DocFonts, BookmarkView* vi);
+	bool PDF_Begin_Doc(const QString& fn, SCFonts &AllFonts, const QMap<QString, QMap<uint, QString> >& DocFonts, BookmarkView* vi);
 	void PDF_Begin_Catalog();
 	void PDF_Begin_MetadataAndEncrypt();
-	QMap<QString, QMap<uint, FPointArray> >
-	     PDF_Begin_FindUsedFonts(SCFonts &AllFonts, const QMap<QString, QMap<uint, FPointArray> >& DocFonts);
-	void PDF_Begin_WriteUsedFonts(SCFonts &AllFonts, const QMap<QString, QMap<uint, FPointArray> >& ReallyUsed);
+	QMap<QString, QMap<uint, QString> >
+	     PDF_Begin_FindUsedFonts(SCFonts &AllFonts, const QMap<QString, QMap<uint, QString> >& DocFonts);
+	void PDF_Begin_WriteUsedFonts(SCFonts &AllFonts, const QMap<QString, QMap<uint, QString> >& usedFonts);
 	void PDF_WriteStandardFonts();
-	PdfFont PDF_WriteType3Font(const QByteArray& name, ScFace& face, const QMap<uint,FPointArray>& RealGlyphs);
-	PdfFont PDF_WriteGlyphsAsXForms(const QByteArray& fontName, ScFace& face, const QMap<uint,FPointArray>& RealGlyphs);
+	PdfFont PDF_WriteType3Font(const QByteArray& name, ScFace& face, const QMap<uint, QString>& usedGlyphs);
+	PdfFont PDF_WriteGlyphsAsXForms(const QByteArray& fontName, ScFace& face, const QMap<uint, QString>& usedGlyphs);
 	
 	QByteArray PDF_GenerateSubsetTag(const QByteArray& fontName, const QList<uint>& usedGlyphs);
 	PdfId PDF_WriteFontDescriptor(const QByteArray& fontName, ScFace& face, ScFace::FontFormat fformat, PdfId embeddedFontObject);
-	PdfFont PDF_WriteTtfSubsetFont(const QByteArray& fontName, ScFace& face, const QMap<uint,FPointArray>& RealGlyphs);
-	PdfFont PDF_WriteCffSubsetFont(const QByteArray& fontName, ScFace& face, const QMap<uint,FPointArray>& RealGlyphs);
-	PdfFont PDF_EncodeSimpleFont(const QByteArray& fontname, ScFace& face,  const QByteArray& baseFont, const QByteArray& subtype, bool isEmbedded, PdfId fontDes, const ScFace::FaceEncoding& gl);
-	PdfFont PDF_EncodeCidFont(const QByteArray& fontname, ScFace& face, const QByteArray& baseFont, PdfId fontDes, const ScFace::FaceEncoding& gl, const QMap<uint,uint>& glyphmap);
+	PdfFont PDF_WriteTtfSubsetFont(const QByteArray& fontName, ScFace& face, const QMap<uint, QString>& usedGlyphs);
+	PdfFont PDF_WriteCffSubsetFont(const QByteArray& fontName, ScFace& face, const QMap<uint, QString>& usedGlyphs);
+	PdfFont PDF_EncodeSimpleFont(const QByteArray& fontname, ScFace& face,  const QByteArray& baseFont, const QByteArray& subtype, bool isEmbedded, PdfId fontDes, const QMap<uint, QString>& usedGlyphs);
+	PdfFont PDF_EncodeCidFont(const QByteArray& fontname, ScFace& face, const QByteArray& baseFont, PdfId fontDes, const QMap<uint, QString>& usedGlyphs, const QMap<uint, uint>& glyphmap);
 	PdfFont PDF_EncodeFormFont(const QByteArray& fontname, ScFace& face,  const QByteArray& baseFont, const QByteArray& subtype, PdfId fontDes);
 	PdfId PDF_EmbedFontObject(const QString& fontName, ScFace &face);
 	PdfId PDF_EmbedFontObject(const QByteArray& font, const QByteArray& subtype);

Modified: trunk/Scribus/scribus/pslib.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24429&path=/trunk/Scribus/scribus/pslib.cpp
==============================================================================
--- trunk/Scribus/scribus/pslib.cpp	(original)
+++ trunk/Scribus/scribus/pslib.cpp	Tue Jan 26 22:36:49 2021
@@ -303,7 +303,7 @@
 
 	QMap<QString, QString> psNameMap;
 	SCFonts& allFonts = PrefsManager::instance().appPrefs.fontPrefs.AvailFonts;
-	QMap<QString, QMap<uint, FPointArray> > docFonts;
+	QMap<QString, QMap<uint, QString> > docFonts;
 	doc->getUsedFonts(docFonts);
 
 	for (auto it = docFonts.begin(); it != docFonts.end(); ++it)
@@ -312,7 +312,7 @@
 		// Subset also font whose postscript name conflicts with an already used font
 		// Subset always now with new boxes code.
 		ScFace &face (allFonts[it.key()]);
-		QMap<uint, FPointArray>& RealGlyphs(it.value());
+		QMap<uint, QString>& usedGlyphs(it.value());
 		QString encodedName = face.psName().simplified().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" );
 
 		// Handle possible PostScript name conflict in oft/ttf fonts
@@ -323,19 +323,22 @@
 			encodedName = QString("%1-%2").arg(initialName).arg(psNameIndex);
 			++psNameIndex;
 		}
-		FontDesc += "/" + encodedName + " " + IToStr(RealGlyphs.count()+1) + " dict def\n";
+		FontDesc += "/" + encodedName + " " + IToStr(usedGlyphs.count() + 1) + " dict def\n";
 		FontDesc += encodedName + " begin\n";
-		QMap<uint,FPointArray>::Iterator ig;
-		for (ig = RealGlyphs.begin(); ig != RealGlyphs.end(); ++ig)
-		{
-			FontDesc += "/G" + IToStr(ig.key()) + " { newpath\n";
+
+		for (auto ig = usedGlyphs.begin(); ig != usedGlyphs.end(); ++ig)
+		{
+			uint gid = ig.key();
+			FPointArray glyphOutline = face.glyphOutline(gid);
+
+			FontDesc += "/G" + IToStr(gid) + " { newpath\n";
 			FPoint np, np1, np2;
 			bool nPath = true;
-			if (ig.value().size() > 3)
-			{
-				for (int poi = 0; poi < ig.value().size() - 3; poi += 4)
-				{
-					if (ig.value().isMarker(poi))
+			if (glyphOutline.size() > 3)
+			{
+				for (int poi = 0; poi < glyphOutline.size() - 3; poi += 4)
+				{
+					if (glyphOutline.isMarker(poi))
 					{
 						FontDesc += "cl\n";
 						nPath = true;
@@ -343,13 +346,13 @@
 					}
 					if (nPath)
 					{
-						np = ig.value().point(poi);
+						np = glyphOutline.point(poi);
 						FontDesc += ToStr(np.x()) + " " + ToStr(-np.y()) + " m\n";
 						nPath = false;
 					}
-					np = ig.value().point(poi + 1);
-					np1 = ig.value().point(poi + 3);
-					np2 = ig.value().point(poi + 2);
+					np = glyphOutline.point(poi + 1);
+					np1 = glyphOutline.point(poi + 3);
+					np2 = glyphOutline.point(poi + 2);
 					FontDesc += ToStr(np.x()) + " " + ToStr(-np.y()) + " " +
 							ToStr(np1.x()) + " " + ToStr(-np1.y()) + " " +
 							ToStr(np2.x()) + " " + ToStr(-np2.y()) + " cu\n";

Modified: trunk/Scribus/scribus/scribusdoc.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24429&path=/trunk/Scribus/scribus/scribusdoc.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.cpp	(original)
+++ trunk/Scribus/scribus/scribusdoc.cpp	Tue Jan 26 22:36:49 2021
@@ -4105,7 +4105,7 @@
 	return Really;
 }
 
-void ScribusDoc::getUsedFonts(QMap<QString, QMap<uint, FPointArray> > & Really)
+void ScribusDoc::getUsedFonts(QMap<QString, QMap<uint, QString> > & Really)
 {
 	QList<PageItem*>  allItems;
 	QList<PageItem*>* itemLists[] = { &MasterItems, &DocItems };
@@ -4161,14 +4161,18 @@
 class UsedGlyphsPainter: public TextLayoutPainter
 {
 public:
-	UsedGlyphsPainter(QMap<QString, QMap<uint, FPointArray> > & Really)
-		: m_really(Really)
+	UsedGlyphsPainter(QMap<QString, QMap<uint, QString> > & usedFonts)
+		: m_fonts(usedFonts)
 	{}
 
 	void drawGlyph(const GlyphCluster& gc) override
 	{
 		if (gc.isControlGlyphs())
 			return;
+
+		const QList<GlyphLayout>& glyphs = gc.glyphs();
+		int glyphCount = glyphs.count();
+
 		for (const GlyphLayout& gl : gc.glyphs())
 		{
 			uint gid = gl.glyph;
@@ -4178,8 +4182,10 @@
 			QString replacementName = font().replacementName();
 			if (!replacementName.isEmpty())
 			{
-				FPointArray outline = font().glyphOutline(gid);
-				m_really[replacementName].insert(gid, outline);
+				QString unicode;
+				if (glyphCount == 1)
+					unicode = gc.getText();
+				m_fonts[replacementName].insert(gid, unicode);
 			}
 		}
 	}
@@ -4195,10 +4201,10 @@
 	void drawObject(PageItem*) override {}
 
 private:
-	QMap<QString, QMap<uint, FPointArray> > & m_really;
+	QMap<QString, QMap<uint, QString> > & m_fonts;
 };
 
-void ScribusDoc::checkItemForFonts(PageItem *it, QMap<QString, QMap<uint, FPointArray> > & Really, uint lc)
+void ScribusDoc::checkItemForFonts(PageItem *it, QMap<QString, QMap<uint, QString> > & usedFonts, uint lc)
 {
 	if (!it->isTextFrame() && !it->isPathText())
 		return;
@@ -4213,7 +4219,7 @@
 
 	// This works pretty well except for the case of page numbers and al. placed on masterpages
 	// where layout may depend on the page where the masterpage item is placed
-	UsedGlyphsPainter p(Really);
+	UsedGlyphsPainter p(usedFonts);
 	it->textLayout.render(&p);
 
 	// Process page numbers and page count special characters on master pages
@@ -4259,8 +4265,8 @@
 			const ScFace& font = it->itemText.defaultStyle().charStyle().font();
 			QString fontName = font.replacementName();
 
-			if (!Really.contains(fontName) && !fontName.isEmpty())
-				Really.insert(fontName, QMap<uint, FPointArray>());
+			if (!usedFonts.contains(fontName) && !fontName.isEmpty())
+				usedFonts.insert(fontName, QMap<uint, QString>());
 
 			for (uint ww = 32; ww < 256; ++ww)
 			{
@@ -4268,9 +4274,9 @@
 				uint glyph  = font.char2CMap(unicode);
 				if (glyph > 0)
 				{
-					FPointArray outline(font.glyphOutline(glyph));
+					QString uniStr = QChar(unicode);
 					if (!fontName.isEmpty())
-						Really[fontName].insert(glyph, outline);
+						usedFonts[fontName].insert(glyph, uniStr);
 				}
 			}
 		}
@@ -16604,7 +16610,7 @@
 		else if (pos > 0)
 		{
 			ParagraphStyle prevStyle;
-			prevStyle = itemText.paragraphStyle(pos -1);
+			prevStyle = itemText.paragraphStyle(pos - 1);
 			reset = !prevStyle.hasNum()
 					|| prevStyle.numName() != "<local block>"
 					|| prevStyle.numLevel() < level

Modified: trunk/Scribus/scribus/scribusdoc.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24429&path=/trunk/Scribus/scribus/scribusdoc.h
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.h	(original)
+++ trunk/Scribus/scribus/scribusdoc.h	Tue Jan 26 22:36:49 2021
@@ -686,8 +686,8 @@
 	/*!
 	 * @brief Returns a qmap of the fonts and  their glyphs used within the document
 	 */
-	void getUsedFonts(QMap<QString,QMap<uint, FPointArray> > &Really);
-	void checkItemForFonts(PageItem *it, QMap<QString, QMap<uint, FPointArray> > & Really, uint lc);
+	void getUsedFonts(QMap<QString,QMap<uint, QString> > &Really);
+	void checkItemForFonts(PageItem *it, QMap<QString, QMap<uint, QString> > & Really, uint lc);
 
 	/*!
 	 * @brief Replace line style colors




More information about the scribus-commit mailing list