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 <qobject.h>
 #include <qfile.h>
+#include <qdir.h>
 
 #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<uint,uint> 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<kernpair.count();++i)
+		{
+			left= kernpair.item(i).attributes().namedItem("left").nodeValue();
+			right=kernpair.item(i).attributes().namedItem("right").nodeValue();
+			value=kernpair.item(i).attributes().namedItem("value").nodeValue();
+			kerningCache.insert(std::pair<uint,uint>(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<uint,uint> 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<std::pair<uint,uint>,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<uint, std::pair<QChar, QString> >::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 <qstring.h>
 //#include <qvector.h>
 #include <qmap.h>
+#include <qdom.h>
 //#include <qarray.h>
 
 #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<std::pair<uint,uint>,double> kerningCache;
+	mutable QMap<uint, std::pair<QChar, QString> > glyphList;
+	mutable QMap<QString,uint> nameList;
+
 	
 };
 
