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);


_______________________________________________
scribus-commit mailing list
[email protected]
http://lists.scribus.net/mailman/listinfo/scribus-commit

Reply via email to