Index: scribus/fonts/ftface.cpp =================================================================== RCS file: /cvs/Scribus/scribus/fonts/Attic/ftface.cpp,v retrieving revision 1.1.2.8 diff -u -r1.1.2.8 ftface.cpp --- scribus/fonts/ftface.cpp 12 Sep 2006 16:00:18 -0000 1.1.2.8 +++ scribus/fonts/ftface.cpp 29 Nov 2006 23:29:34 -0000 @@ -6,6 +6,7 @@ #include #include +#include #include "scfonts.h" #include "fonts/scfontmetrics.h" @@ -51,6 +52,7 @@ FtFace::~FtFace() { unload(); + } @@ -133,6 +135,7 @@ if (invalidGlyph > 0) { status = ScFace::BROKENGLYPHS; } + loadUserFontRessource(); } @@ -142,8 +145,11 @@ FT_Done_Face( m_face ); m_face = NULL; } + qDebug(QString("FtFace[%1] is in unload process").arg(scName)); + saveKerningCache(); // clear caches ScFaceData::unload(); + } @@ -196,6 +202,16 @@ double FtFace::glyphKerning(uint gl, uint gl2, double size) const { + const std::pair pairkern(gl,gl2); + if (kerningCache.contains(pairkern)) + { + qDebug(QString("the [%1,%2] kerning pair comes from cache and is : %3").arg(gl).arg(gl2).arg(kerningCache[pairkern])); + return kerningCache[pairkern] / m_uniEM * size ; + } + else + { + qDebug(QString("the [%1,%2] kerning pair is not cached").arg(gl).arg(gl2)); + } FT_Vector delta; FT_Face face = ftFace(); double result = 0; @@ -206,11 +222,13 @@ if (true || FT_HAS_KERNING(face) ) { FT_Error error = FT_Get_Kerning(face, gl, gl2, FT_KERNING_UNSCALED, &delta); - if (error) { + if (error) + { qDebug(QString("Error %2 when accessing kerning pair for font %1").arg(scName).arg(error)); } else { result = delta.x / m_uniEM * size; + updateKerningCache(gl,gl2 , delta.x); } } else { @@ -304,4 +322,122 @@ */ } +void FtFace::loadUserFontRessource() const +{ + QString ufrPath(QDir::homeDirPath () + "/.scribus/fonts/"+psName+".ufr"); + + QFile ufr(QFile::encodeName( ufrPath )); + if(!ufr.exists()) + { + qDebug(QString("load -> ufrFile[%1] doesn't exist").arg(QFile::encodeName( ufrPath ))); + return; + } + + if(!ufr.open( IO_ReadOnly ) ) + { + qDebug(QString("load -> Can't open ufrFile[%1]").arg(QFile::encodeName( ufrPath ))); + return; + } + + QDomDocument ufrdom( "ufr" ); + if ( !ufrdom.setContent( &ufr ) ) { + ufr.close(); + return; + } + ufr.close(); + + QDomNodeList kernpair(ufrdom.elementsByTagName ( "kernpair")); + QString left; + QString right; + QString value; + if(!kerningCache.isEmpty()) + kerningCache.clear(); + if(kernpair.count()) + { + for(uint i=0;i(nameGlyph(left),nameGlyph(right)), value.toDouble()); + qDebug(QString("load -> pair[%1,%2] inserted with value '%3'").arg(left).arg(right).arg(value)); + } + } +} + +void FtFace::updateKerningCache(uint gl,uint gl2, double adj) const +{ + + const std::pair pairkern(gl,gl2); + kerningCache.insert(pairkern,adj); +} +void FtFace::saveKerningCache() const +{ + if(kerningCache.isEmpty()) + { + qDebug(QString("kerningCache is Empty")); + return; + } + QString ufrPath(QDir::homeDirPath () + "/.scribus/fonts/"+psName+".ufr"); + QFile ufr(QFile::encodeName( ufrPath)); + if(!psName.isEmpty()) + { + + if(!ufr.open( IO_WriteOnly ) ) + { + qDebug(QString("save -> Can't open ufrFile[%1]").arg(QFile::encodeName( ufrPath ))); + return; + } + qDebug(QString("save-> ufrFile[%1] is opened").arg(QFile::encodeName( ufrPath ))); + } + else + { + return; + } + + QDomDocument kerningCache_dom( "MyML" ); + QDomElement root = kerningCache_dom.createElement( "ufr" ); + kerningCache_dom.appendChild( root ); + + QDomElement kern = kerningCache_dom.createElement( "kern" ); + root.appendChild( kern ); + QDomElement kernpair; + for(QMap,double>::iterator it=kerningCache.begin();it != kerningCache.end(); ++it) + { + kernpair = kerningCache_dom.createElement("kernpair"); + kernpair.setAttribute("left",glyphName(it.key().first)); + kernpair.setAttribute("right",glyphName(it.key().second)); + kernpair.setAttribute("value",it.data()); + kern.appendChild(kernpair); + + } + + QTextStream ufrstream( &ufr ); + + kerningCache_dom.save(ufrstream , 1); + ufr.flush(); + ufr.close(); +} + +QString FtFace::glyphName(uint g) const +{ + if(glyphList.isEmpty()) + glyphNames(glyphList); + + return glyphList[g].second; +} + +uint FtFace::nameGlyph(QString n) const +{ + if(nameList.isEmpty()) + { + glyphNames(glyphList); + for(QMap >::iterator it=glyphList.begin(); it != glyphList.end(); ++it) + { + nameList.insert(it.data().second, it.key()); + } + } + return nameList[n]; +} + Index: scribus/fonts/ftface.h =================================================================== RCS file: /cvs/Scribus/scribus/fonts/Attic/ftface.h,v retrieving revision 1.1.2.5 diff -u -r1.1.2.5 ftface.h --- scribus/fonts/ftface.h 1 Sep 2006 23:55:18 -0000 1.1.2.5 +++ scribus/fonts/ftface.h 29 Nov 2006 23:29:37 -0000 @@ -5,6 +5,7 @@ #include //#include #include +#include //#include #include "scribusapi.h" @@ -85,6 +86,12 @@ void load () const; void unload () const; void loadGlyph (uint ch) const; + void loadUserFontRessource() const; + void updateKerningCache(uint,uint,double) const; + void saveKerningCache() const; + QString glyphName(uint) const; + uint nameGlyph(QString) const; + protected: mutable FT_Face m_face; @@ -111,6 +118,10 @@ mutable double m_underlinePos; mutable double m_strikeoutPos; mutable double m_strokeWidth; + mutable QMap,double> kerningCache; + mutable QMap > glyphList; + mutable QMap nameList; + };