r24418 by jghali - Fix issue with handling of font resources in XPS export

scribus-commit scribus-commit at lists.scribus.net
Fri Jan 22 00:32:09 UTC 2021


Author: jghali
Date: Fri Jan 22 00:32:09 2021
New Revision: 24418

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=24418
Log:
Fix issue with handling of font resources in XPS export

Modified:
    trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp
    trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h

Modified: trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24418&path=/trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp	(original)
+++ trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp	Fri Jan 22 00:32:09 2021
@@ -304,6 +304,7 @@
 	for (int a = 0; a < m_Doc->Pages->count(); a++)
 	{
 		ScPage* Page = m_Doc->Pages->at(a);
+
 		p_docu.setContent(QString("<FixedPage></FixedPage>"));
 		QDomElement droot  = p_docu.documentElement();
 		droot.setAttribute("xmlns", "http://schemas.microsoft.com/xps/2005/06");
@@ -312,12 +313,17 @@
 		QString lang = QLocale::system().name();
 		lang.replace("_", "-");
 		droot.setAttribute("xml:lang", lang);
+
 		r_docu.setContent(QString("<Relationships></Relationships>"));
 		QDomElement rroot  = r_docu.documentElement();
 		rroot.setAttribute("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships");
+		xps_fontRel.clear();
+
 		writePage(droot, rroot, Page);
+
 		p_docu.appendChild(droot);
 		r_docu.appendChild(rroot);
+
 		QFile ft(baseDir + QString("/Documents/1/Pages/%1.fpage").arg(a+1));
 		if (ft.open(QIODevice::WriteOnly))
 		{
@@ -328,6 +334,7 @@
 			s.writeRawData(utf8wr.data(), utf8wr.length());
 			ft.close();
 		}
+
 		QFile ftr(baseDir + QString("/Documents/1/Pages/_rels/%1.fpage.rels").arg(a+1));
 		if (ftr.open(QIODevice::WriteOnly))
 		{
@@ -338,6 +345,7 @@
 			s.writeRawData(utf8wr.data(), utf8wr.length());
 			ftr.close();
 		}
+
 		QDomElement rel1 = f_docu.createElement("PageContent");
 		rel1.setAttribute("Source", QString("Pages/%1.fpage").arg(a+1));
 		root.appendChild(rel1);
@@ -803,7 +811,8 @@
 	//PageItem *m_item;
 	QDomElement m_group;
 	XPSExPlug *m_xps;
-	QMap<QString, QString> &m_fontMap;
+	QMap<QString, XPSResourceInfo> &m_fontMap;
+	QSet<QString> &m_fontRel;
 	QDomElement &m_relRoot;
 
 	bool    m_restart { true };
@@ -816,11 +825,12 @@
 	QDomElement m_glyphElem;
 
 public:
-	XPSPainter(PageItem *item, QDomElement &group, XPSExPlug *xps, QMap<QString, QString> &XPSfontMap, QDomElement &rel_root):
+	XPSPainter(PageItem *item, QDomElement &group, XPSExPlug *xps, QMap<QString, XPSResourceInfo> &xpsFontMap, QSet<QString> &xpsFontRel, QDomElement &rel_root):
 //		m_item(item),
 		m_group(group),
 		m_xps(xps),
-		m_fontMap(XPSfontMap),
+		m_fontMap(xpsFontMap),
+		m_fontRel(xpsFontRel),
 		m_relRoot(rel_root)
 	{ }
 
@@ -829,11 +839,21 @@
 		if (gc.isControlGlyphs() || gc.isEmpty())
 			return;
 
-		if (!m_fontMap.contains(font().replacementName()))
-			m_fontMap.insert(font().replacementName(), m_xps->embedFont(font(), m_relRoot));
+		XPSResourceInfo fontInfo;
+		QString replacementName = font().replacementName();
+		if (!m_fontMap.contains(replacementName))
+			m_fontMap.insert(replacementName, m_xps->embedFont(font(), m_relRoot));
+		fontInfo = m_fontMap.value(replacementName);
+
+		if (!m_fontRel.contains(replacementName))
+		{
+			m_xps->addFontRelationship(m_relRoot, fontInfo);
+			m_fontRel.insert(replacementName);
+		}
+
 		QTransform transform = matrix();
 		double size = fontSize() * qMax(gc.scaleV(), gc.scaleH()) * m_xps->conversionFactor;
-		QString fontUri = m_fontMap[font().replacementName()];
+		QString fontUri = fontInfo.uri;
 
 		if (m_restart || (size != m_fontSize) || (m_fillColor != fillColor()) || (m_fontUri != fontUri) ||
 			(qAbs(m_current_x - x()) > 1e-6) || (m_current_y != y()) || (m_transform != transform))
@@ -1122,7 +1142,7 @@
 			grp2.setAttribute("Name", grp.attribute("Name"));
 		if (grp.hasAttribute("Opacity"))
 			grp2.setAttribute("Opacity", grp.attribute("Opacity"));
-		XPSPainter p(Item, grp2, this, xps_fontMap, rel_root);
+		XPSPainter p(Item, grp2, this, xps_fontMap, xps_fontRel, rel_root);
 		Item->textLayout.renderBackground(&p);
 		Item->textLayout.render(&p);
 		parentElem.appendChild(grp2);
@@ -1809,7 +1829,16 @@
 	}
 }
 
-QString XPSExPlug::embedFont(const ScFace& font, QDomElement &rel_root)
+void XPSExPlug::addFontRelationship(QDomElement &rel_root, const XPSResourceInfo& fontInfo)
+{
+	QDomElement rel = r_docu.createElement("Relationship");
+	rel.setAttribute("Id", fontInfo.id);
+	rel.setAttribute("Type", "http://schemas.microsoft.com/xps/2005/06/required-resource");
+	rel.setAttribute("Target", fontInfo.uri);
+	rel_root.appendChild(rel);
+}
+
+XPSResourceInfo XPSExPlug::embedFont(const ScFace& font, QDomElement &rel_root)
 {
 	QByteArray fontData;
 	loadRawText(font.fontFilePath(), fontData);
@@ -1839,13 +1868,13 @@
 		ft.write(fontData);
 		ft.close();
 	}
-	QDomElement rel = r_docu.createElement("Relationship");
-	rel.setAttribute("Id", QString("rIDf%1").arg(fontCounter));
-	rel.setAttribute("Type", "http://schemas.microsoft.com/xps/2005/06/required-resource");
-	rel.setAttribute("Target", "/Resources/Fonts/" + guidString + ".odttf");
-	rel_root.appendChild(rel);
+
+	XPSResourceInfo rsrcInfo;
+	rsrcInfo.id =  QString("rIDf%1").arg(fontCounter);
+	rsrcInfo.uri = "/Resources/Fonts/" + guidString + ".odttf";
 	fontCounter++;
-	return "/Resources/Fonts/" + guidString + ".odttf";
+
+	return rsrcInfo;
 }
 
 void XPSExPlug::GetMultiStroke(struct SingleLine *sl, QDomElement &parentElem)

Modified: trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24418&path=/trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h
==============================================================================
--- trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h	(original)
+++ trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h	Fri Jan 22 00:32:09 2021
@@ -16,6 +16,9 @@
 
 #include <QObject>
 #include <QDomElement>
+#include <QMap>
+#include <QSet>
+
 #include "pluginapi.h"
 #include "loadsaveplugin.h"
 #include "tableborder.h"
@@ -29,6 +32,12 @@
 class ScPage;
 class ScText;
 class ScZipHandler;
+
+struct XPSResourceInfo
+{
+	QString id;
+	QString uri;
+};
 
 class PLUGIN_API XPSExportPlugin : public ScActionPlugin
 {
@@ -89,7 +98,8 @@
 	void processSymbolStroke(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
 	void processArrows(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
 	void drawArrow(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root, FPointArray &arrow);
-	QString embedFont(const ScFace& font, QDomElement &rel_root);
+	void addFontRelationship(QDomElement &rel_root, const XPSResourceInfo& fontInfo);
+	XPSResourceInfo embedFont(const ScFace& font, QDomElement &rel_root);
 	void GetMultiStroke(struct SingleLine *sl, QDomElement &parentElem);
 	void getStrokeStyle(PageItem *Item, QDomElement &parentElem, QDomElement &rel_root, double xOffset, double yOffset, bool forArrow = false);
 	void getFillStyle(PageItem *Item, QDomElement &parentElem, QDomElement &rel_root, double xOffset, double yOffset, bool withTransparency = true);
@@ -107,15 +117,17 @@
 	QString MatrixToStr(QTransform &mat, double factor);
 	int hex2int(char hex);
 	bool checkForFallback(PageItem *Item);
+
 	ScribusDoc* m_Doc {nullptr};
 	QString baseDir;
 	QDomDocument f_docu;
 	QDomDocument p_docu;
 	QDomDocument r_docu;
-	double conversionFactor;
-	int imageCounter;
-	int fontCounter;
-	QMap<QString, QString> xps_fontMap;
+	double conversionFactor { 96.0 / 72.0 };
+	int imageCounter { 0 };
+	int fontCounter { 0 };
+	QMap<QString, XPSResourceInfo> xps_fontMap;
+	QSet<QString> xps_fontRel;
 	struct txtRunItem
 	{
 		QChar chr;




More information about the scribus-commit mailing list