? scribus/fonts/OLD-myotf.cpp
? scribus/fonts/OLD-myotf.h
Index: scribus/pageitem.cpp
===================================================================
RCS file: /cvs/Scribus/scribus/pageitem.cpp,v
retrieving revision 1.121.2.419
diff -u -8 -p -r1.121.2.419 pageitem.cpp
--- scribus/pageitem.cpp	25 Mar 2007 22:34:31 -0000	1.121.2.419
+++ scribus/pageitem.cpp	7 Apr 2007 18:59:37 -0000
@@ -1747,16 +1747,179 @@ double PageItem::layoutGlyphs(const Char
 			layout.yadvance = layout.more->yadvance;
 	}
 	else {
 		layout.shrink();
 	}
 	return retval;
 }
 
+// the same, but character to render is retrieved from contextStringPointer
+double PageItem::layoutGlyphs(const CharStyle& style, int len, GlyphLayout& layout)
+{
+	QString chars;
+	bool otf = style.font().isOTF();
+	if(contextString[0] == 0) // We have a special char that can't be processed by libotf
+	{
+		chars = contextString[1].unicode();
+	}
+	else if(otf)
+	{
+		
+		if (contextStringPointer == 0) 
+		{
+			contextGlyphsString = style.font().otfied(contextString);
+		  //Now, we have 4 possibilities :
+		  // 1/ one glyph for one character ;
+		  // 2/ many glyphs for one character ;
+		  // 3/ one glyph for many characters ;
+		  // 4/ nothing if character was rendered in a previous case 3 call.
+		  // Too much complicated for me, I take the shorter way.
+			int ls = contextString.length();
+			int lg = contextGlyphsString.length();
+			contexLengthChange = lg - ls;
+		}
+		if (contexLengthChange < 0) // source string is longer then the rendered string
+		{
+			contexLengthChange += 1; // waiting
+			contextStringPointer = -1;
+			layout.glyph = ScFace::CONTROL_GLYPHS + SpecialChars::ZWSPACE.unicode();
+			return 0.0;
+		}
+		else if (contexLengthChange > 0) // in that case we just trust the GLyphLayout grow()
+		{
+			chars = contextGlyphsString.mid(contextStringPointer,contexLengthChange  + len);
+			contexLengthChange = 0;
+		}
+		else if(contexLengthChange == 0)
+		{
+			if(contextStringPointer == -1) contextStringPointer = 0;
+			chars = contextGlyphsString.mid(contextStringPointer,len);
+		}
+		//contextStringPointer += 1;
+	}
+	else 
+	{
+		chars = contextString.mid(contextStringPointer,len);
+	}
+	qDebug(QString("char is [%1], contextGlyphsString is [%2], contextStringPointer[%3], len [%4]").arg(chars[0].unicode()).arg(contextGlyphsString).arg(contextStringPointer).arg(len));
+	double retval = 0.0;
+	double asce = style.font().ascent(style.fontSize() / 10.0);
+	int chst = style.effects() & 1919;
+	if (chars[0] == SpecialChars::ZWSPACE ||
+		   chars[0] == SpecialChars::ZWNBSPACE ||
+		   chars[0] == SpecialChars::NBSPACE ||
+		   chars[0] == SpecialChars::NBHYPHEN ||
+		   chars[0] == SpecialChars::SHYPHEN ||
+		   chars[0] == SpecialChars::PARSEP ||
+		   chars[0] == SpecialChars::COLBREAK ||
+		   chars[0] == SpecialChars::LINEBREAK ||
+		   chars[0] == SpecialChars::FRAMEBREAK ||
+		   chars[0] == SpecialChars::TAB)
+	{
+		layout.glyph = ScFace::CONTROL_GLYPHS + chars[0].unicode();
+	}
+	else 
+	{
+		layout.glyph = style.font().char2CMap(chars[0].unicode()); //otf comment : here we assume that the proper pair is in the c_Map cache
+	}
+	
+	double tracking = 0.0;
+	if ( (style.effects() & ScStyle_StartOfLine) == 0)
+		tracking = style.fontSize() * style.tracking() / 10000.0;
+
+	layout.xoffset = tracking;
+	layout.yoffset = 0;
+	if (chst != ScStyle_Default)
+	{
+		if (chst & ScStyle_Superscript)
+		{
+			retval -= asce * m_Doc->typographicSettings.valueSuperScript / 100.0;
+			layout.yoffset -= asce * m_Doc->typographicSettings.valueSuperScript / 100.0;
+			layout.scaleV = layout.scaleH = QMAX(m_Doc->typographicSettings.scalingSuperScript / 100.0, 10.0 / style.fontSize());
+		}
+		else if (chst & ScStyle_Subscript)
+		{
+			retval += asce * m_Doc->typographicSettings.valueSubScript / 100.0;
+			layout.yoffset += asce * m_Doc->typographicSettings.valueSubScript / 100.0;
+			layout.scaleV = layout.scaleH = QMAX(m_Doc->typographicSettings.scalingSubScript / 100.0, 10.0 / style.fontSize());
+		}
+		else {
+			layout.scaleV = layout.scaleH = 1.0;
+		}
+		layout.scaleH *= style.scaleH() / 1000.0;
+		layout.scaleV *= style.scaleV() / 1000.0;
+		if (chst & ScStyle_AllCaps)
+		{
+			layout.glyph = style.font().char2CMap(chars[0].upper().unicode());
+		}
+		if (chst & ScStyle_SmallCaps)
+		{
+			
+			double smallcapsScale = m_Doc->typographicSettings.valueSmallCaps / 100.0;
+			QChar uc = chars[0].upper();
+			if (uc != chars[0])
+			{
+				layout.glyph = style.font().char2CMap(chars[0].upper().unicode());
+				layout.scaleV *= smallcapsScale;
+				layout.scaleH *= smallcapsScale;
+			}
+		}
+	}
+	else {
+		layout.scaleH = style.scaleH() / 1000.0;
+		layout.scaleV = style.scaleV() / 1000.0;
+	}	
+	
+	if (layout.glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode())) {
+		uint replGlyph = style.font().char2CMap(QChar(' '));
+		layout.xadvance = style.font().glyphWidth(replGlyph, style.fontSize() / 10) * layout.scaleH;
+		layout.yadvance = style.font().glyphBBox(replGlyph, style.fontSize() / 10).ascent * layout.scaleV;
+	}
+	else if (layout.glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode())) {
+		uint replGlyph = style.font().char2CMap(QChar('-'));
+		layout.xadvance = style.font().glyphWidth(replGlyph, style.fontSize() / 10) * layout.scaleH;
+		layout.yadvance = style.font().glyphBBox(replGlyph, style.fontSize() / 10).ascent * layout.scaleV;
+	}
+	else if (layout.glyph >= ScFace::CONTROL_GLYPHS) {
+		layout.xadvance = 0;
+		layout.yadvance = 0;
+	}
+	else {
+		layout.xadvance = style.font().glyphWidth(layout.glyph, style.fontSize() / 10) * layout.scaleH;
+		layout.yadvance = style.font().glyphBBox(layout.glyph, style.fontSize() / 10).ascent * layout.scaleV;
+	}
+	if(otf)//Don't wait for ::layout to adjust with pair kerning
+	{
+		posglyph pg = style.font().otf()->get_position(contextStringPointer);
+		qDebug(QString("Adjust[%1] pg.xadv=%2 , pg.yadv=%3").arg(layout.glyph).arg(pg.xadvance()).arg(pg.yadvance()));	
+		layout.xadvance = pg.xadvance() / style.font().unitsEM() * style.fontSize() / 10 *  layout.scaleH;
+		layout.yadvance = pg.yadvance() / style.font().unitsEM() * style.fontSize() / 10 *  layout.scaleV;
+
+			
+	}
+	if (layout.xadvance > 0)
+		layout.xadvance += tracking;
+
+	if (chars.length() > 1) {
+		layout.grow();
+		contextStringPointer += 1;
+		layoutGlyphs(style, chars.length()-1, *layout.more);
+		layout.xadvance += style.font().glyphKerning(layout.glyph, layout.more->glyph, style.fontSize() / 10) * layout.scaleH;
+		if (layout.more->yadvance > layout.yadvance)
+			layout.yadvance = layout.more->yadvance;
+	}
+	else {
+		contextStringPointer += 1;
+		layout.shrink();
+	}
+	
+	return retval;
+}
+
 void PageItem::drawGlyphs(ScPainter *p, const CharStyle& style, GlyphLayout& glyphs)
 {
 	uint glyph = glyphs.glyph;
 	if ((m_Doc->guidesSettings.showControls) && 
 		(glyph == style.font().char2CMap(QChar(' ')) || glyph >=  ScFace::CONTROL_GLYPHS))
 	{
 		bool stroke = false;
 		if (glyph >=  ScFace::CONTROL_GLYPHS)
Index: scribus/pageitem.h
===================================================================
RCS file: /cvs/Scribus/scribus/pageitem.h,v
retrieving revision 1.26.2.183
diff -u -8 -p -r1.26.2.183 pageitem.h
--- scribus/pageitem.h	4 Apr 2007 21:46:32 -0000	1.26.2.183
+++ scribus/pageitem.h	7 Apr 2007 18:59:40 -0000
@@ -289,16 +289,17 @@ public:
 	/// returns the style at the current charpos
 	const ParagraphStyle& currentStyle() const;
 	/// returns the style at the current charpos
 	ParagraphStyle& changeCurrentStyle();
 	/// returns the style at the current charpos
 	const CharStyle& currentCharStyle() const;
 	// deprecated:
 	double layoutGlyphs(const CharStyle& style, const QString chars, GlyphLayout& layout);
+	double layoutGlyphs(const CharStyle& style, int len, GlyphLayout& layout);
 	void SetFarbe(QColor *tmp, QString farbe, int shad);
 	void drawGlyphs(ScPainter *p, const CharStyle& style, GlyphLayout& glyphs );
 	void DrawPolyL(QPainter *p, QPointArray pts);
 	QString ExpandToken(uint base);
 	
 	bool AutoName;	
 	double gXpos;
 	double gYpos;
@@ -1208,16 +1209,22 @@ public:
 	
 	/** Darstellungsart Bild/Titel */
 	bool PicArt;
 	
 	 /** Line width */
 	double m_lineWidth;
 	double Oldm_lineWidth;
 	
+	/** Context String */
+	QString contextString;
+	QString contextGlyphsString;
+	int contextStringPointer;
+	int contexLengthChange;
+	
 signals:
 	//Frame signals
 	void myself(PageItem *);
 	void frameType(int);   // not related to Frametype but to m_itemIype :-/
 	void position(double, double); //X,Y
 	void widthAndHeight(double, double); //W,H
 	void rotation(double); //Degrees rotation	
 	void colors(QString, QString, int, int); //lineColor, fillColor, lineShade, fillShade
Index: scribus/pageitem_textframe.cpp
===================================================================
RCS file: /cvs/Scribus/scribus/Attic/pageitem_textframe.cpp,v
retrieving revision 1.1.2.159
diff -u -8 -p -r1.1.2.159 pageitem_textframe.cpp
--- scribus/pageitem_textframe.cpp	5 Apr 2007 16:27:20 -0000	1.1.2.159
+++ scribus/pageitem_textframe.cpp	7 Apr 2007 18:59:46 -0000
@@ -565,19 +565,16 @@ static double opticalRightMargin(const S
 			rightCorr -= itemText.charStyle(b).font().charWidth(chr, chs / 10.0, QChar('.'));
 		}
 		return rightCorr;
 	}
 	return 0.0;
 }
 
 
-
-
-
 void PageItem_TextFrame::layout() 
 {
 	
 	if (BackBox != NULL && BackBox->invalid) {
 //		qDebug("textframe: len=%d, going back", itemText.length());
 		invalid = false;
 		PageItem_TextFrame* prevInChain = dynamic_cast<PageItem_TextFrame*>(BackBox);
 		if (!prevInChain)
@@ -699,19 +696,71 @@ void PageItem_TextFrame::layout() 
 		else // empty itemText:
 		{
 			desc2 = -itemText.defaultStyle().charStyle().font().descent(itemText.defaultStyle().charStyle().fontSize() / 10.0);
 			current.yPos = itemText.defaultStyle().lineSpacing() + extra.Top+lineCorr-desc2;
 		}
 		current.startLine(firstInFrame());
 		outs = false;
 		OFs = 0;
-		MaxChars = 0;
+		MaxChars = 0;	
+		// BIGLOOP
+		int contextrest = 0;
+		int sccontrol;
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
+			// here we set the context string
+			if(contextrest == 0)
+			{
+				contextString = "";
+				sccontrol = 0;
+				for(int ctsg = a; ctsg < itemText.length(); ++ctsg)
+				{
+					
+					QString contmp = ExpandToken(ctsg);
+					if(current.breakIndex == a)
+					{
+						break;
+					}
+					else if(contmp[0] == SpecialChars::ZWSPACE ||
+								contmp[0] == SpecialChars::ZWNBSPACE ||
+								contmp[0] == SpecialChars::NBSPACE ||
+								contmp[0] == SpecialChars::NBHYPHEN ||
+								contmp[0] == SpecialChars::SHYPHEN ||
+								contmp[0] == SpecialChars::PARSEP ||
+								contmp[0] == SpecialChars::COLBREAK ||
+								contmp[0] == SpecialChars::LINEBREAK ||
+								contmp[0] == SpecialChars::FRAMEBREAK ||
+								contmp[0] == SpecialChars::TAB || 
+								contmp[0] == SpecialChars::BLANK)
+					{
+						if(sccontrol > 0)
+						{
+							break;
+						}
+						else
+						{
+						contextString += QChar(0) ;
+						contextString += contmp[0].unicode();
+						break;
+						}
+					}
+					else
+					{
+						sccontrol += 1;
+						contextString += contmp;
+					}
+				}
+				contextrest = (sccontrol == 0 ? 1 : contextString.length());// we send special char one by one
+				contextStringPointer = 0;
+				qDebug(QString("contextrest = %1 and context string is \"%2\"").arg(contextrest).arg(contextString));
+			}
+			--contextrest;
+
+			
 			hl = itemText.item(a);
 			if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
 				style = itemText.paragraphStyle(a);
 			if (current.itemsInLine == 0)
 				opticalMargins = style.opticalMargins();
 			
 //			qDebug(QString("style pos %1: %2 (%3)").arg(a).arg(style.alignment()).arg(style.parent()));
 			const CharStyle& charStyle = itemText.charStyle(a);
@@ -862,30 +911,35 @@ void PageItem_TextFrame::layout() 
 				kernVal = 0;
 			}
 			else
 			{
 				kernVal = 0; // chs * charStyle.tracking() / 10000.0;
 				itemText.item(a)->setEffects(itemText.item(a)->effects() & ~ScStyle_StartOfLine);
 			}
 			hl->glyph.yadvance = 0;
-			oldCurY = layoutGlyphs(*hl, chstr, hl->glyph);
+			//qDebug(QString("sending [%1] to layoutGlyphs()").arg(chstr));
+			oldCurY = layoutGlyphs(*hl, chstr.length(), hl->glyph);
+			//oldCurY = layoutGlyphs(*hl, chstr, hl->glyph);
 			// find out width of char
 			if ((hl->ch[0] == SpecialChars::OBJECT) && (hl->embedded.hasItem()))
 				wide = hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth();
 			else
 			{
 				wide = hl->glyph.wide();
 				// apply kerning
 				if (a+1 < itemText.length())
 				{
-					uint glyph2 = charStyle.font().char2CMap(itemText.text(a+1));
-					double kern= charStyle.font().glyphKerning(hl->glyph.glyph, glyph2, chs / 10.0) * hl->glyph.scaleH;
-					wide += kern;
-					hl->glyph.xadvance += kern;
+					if( !charStyle.font().isOTF() )
+					{
+						uint glyph2 = charStyle.font().char2CMap(itemText.text(a+1));
+						double kern= charStyle.font().glyphKerning(hl->glyph.glyph, glyph2, chs / 10.0) * hl->glyph.scaleH;
+						wide += kern;
+						hl->glyph.xadvance += kern;
+					}	
 				}
 			}
 			if (DropCmode)
 			{
 				// drop caps are wider...
 				if ((hl->ch[0] == SpecialChars::OBJECT) && (hl->embedded.hasItem()))
 				{
 					wide = hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth();
@@ -1352,16 +1406,17 @@ void PageItem_TextFrame::layout() 
 				tcli.setPoint(3, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY)));
 				cm = QRegion(pf2.xForm(tcli));
 				cl = cl.subtract(cm);
 //				current.yPos = maxDY;
 			}
 			// end of line
 			if ( SpecialChars::isBreak(hl->ch[0], Cols > 1) || (outs))
 			{
+				contextrest = 0;
 				tabs.active = false;
 				tabs.status = TabNONE;
 				if (SpecialChars::isBreak(hl->ch[0], Cols > 1))
 				{
 					// find end of line
 					current.breakLine(itemText, a);
 					EndX = current.endOfLine(cl, pf2, asce, desc, style.rightMargin());
 					current.finishLine(EndX);
Index: scribus/scribusdoc.cpp
===================================================================
RCS file: /cvs/Scribus/scribus/scribusdoc.cpp,v
retrieving revision 1.25.2.448
diff -u -8 -p -r1.25.2.448 scribusdoc.cpp
--- scribus/scribusdoc.cpp	4 Apr 2007 21:08:56 -0000	1.25.2.448
+++ scribus/scribusdoc.cpp	7 Apr 2007 19:00:01 -0000
@@ -2765,22 +2765,28 @@ void ScribusDoc::checkItemForFonts(PageI
 							newText=getSectionPageNumberForPageIndex(a);
 							for (uint nti=0;nti<newText.length();++nti)
 								if (pageNumberText.find(newText[nti])==-1)
 									pageNumberText+=newText[nti];
 						}
 					}
 				}
 				//Now scan and add any glyphs used in page numbers
+				if(it->itemText.charStyle(e).font().isOTF())
+					pageNumberText = it->itemText.charStyle(e).font().otfied(pageNumberText);
 				for (uint pnti=0;pnti<pageNumberText.length(); ++pnti)
 				{
 					uint chr = pageNumberText[pnti].unicode();
 					if (it->itemText.charStyle(e).font().canRender(chr))
 					{
-						uint gl = it->itemText.charStyle(e).font().char2CMap(pageNumberText[pnti]);
+						uint gl;
+						if(it->itemText.charStyle(e).font().isOTF())
+							gl = pageNumberText[pnti].unicode() ;
+						else
+							gl = it->itemText.charStyle(e).font().char2CMap(pageNumberText[pnti]);
 						FPointArray gly(it->itemText.charStyle(e).font().glyphOutline(gl));
 						Really[it->itemText.charStyle(e).font().replacementName()].insert(gl, gly);
 					}
 				}
 				continue;
 			}
 			if (it->itemText.charStyle(e).effects() & ScStyle_SmartHyphenVisible)
 			{
@@ -2792,17 +2798,18 @@ void ScribusDoc::checkItemForFonts(PageI
 			{
 				chstr = it->itemText.text(e, 1);
 				if (chstr.upper() != it->itemText.text(e, 1))
 					chstr = chstr.upper();
 				chr = chstr[0].unicode();
 			}
 			if (it->itemText.charStyle(e).font().canRender(chr))
 			{
-				uint gl = it->itemText.charStyle(e).font().char2CMap(chr);
+				//uint gl = it->itemText.charStyle(e).font().char2CMap(chr);
+				uint gl = it->itemText.item(e)->glyph.glyph;
 				gly = it->itemText.charStyle(e).font().glyphOutline(gl);
 				Really[it->itemText.charStyle(e).font().replacementName()].insert(gl, gly);
 			}
 		}
 	}
 }
 
 void ScribusDoc::getUsedProfiles(ProfilesL& usedProfiles)
Index: scribus/fonts/CMakeLists.txt
===================================================================
RCS file: /cvs/Scribus/scribus/fonts/Attic/CMakeLists.txt,v
retrieving revision 1.1.2.1
diff -u -8 -p -r1.1.2.1 CMakeLists.txt
--- scribus/fonts/CMakeLists.txt	23 Jul 2006 12:07:47 -0000	1.1.2.1
+++ scribus/fonts/CMakeLists.txt	7 Apr 2007 19:00:04 -0000
@@ -5,12 +5,15 @@ ${CMAKE_SOURCE_DIR}/scribus
 
 
 SET(SCRIBUS_FONTS_LIB_SOURCES
 scface.cpp
 ftface.cpp
 scface_ps.cpp
 scface_ttf.cpp
 scfontmetrics.cpp
+myotf.cpp
 )
 
+
+
 SET(SCRIBUS_FONTS_LIB "scribus_fonts_lib")
 ADD_LIBRARY(${SCRIBUS_FONTS_LIB} STATIC ${SCRIBUS_FONTS_LIB_SOURCES})
Index: scribus/fonts/ftface.cpp
===================================================================
RCS file: /cvs/Scribus/scribus/fonts/Attic/ftface.cpp,v
retrieving revision 1.1.2.9
diff -u -8 -p -r1.1.2.9 ftface.cpp
--- scribus/fonts/ftface.cpp	11 Jan 2007 15:29:46 -0000	1.1.2.9
+++ scribus/fonts/ftface.cpp	7 Apr 2007 19:00:05 -0000
@@ -2,16 +2,19 @@
 #include "fonts/ftface.h"
 
 #include FT_OUTLINE_H
 #include FT_GLYPH_H
 
 #include <qobject.h>
 #include <qfile.h>
 
+#include <qmessagebox.h>
+#include <qinputdialog.h>
+
 #include "scfonts.h"
 #include "fonts/scfontmetrics.h"
 
 // static:
 FT_Library FtFace::library = NULL;
 
 /*****
    ScFace lifecycle:  unchecked -> loaded -> glyphs checked
@@ -136,36 +139,116 @@ void FtFace::load() const
 		++goodGlyph;
 		if (m_face->glyph->format == FT_GLYPH_FORMAT_PLOTTER)
 			const_cast<FtFace*>(this)->isStroked = true;
 		charcode = FT_Get_Next_Char( m_face, charcode, &gindex );
 	}
 	if (invalidGlyph > 0) {
 		status = ScFace::BROKENGLYPHS;
 	}
+	//TEST libotf
+	if(typeCode == ScFace::OTF)
+	{
+		_otf = new myotf(QFile::encodeName(fontFile));
+		bool ok;
+		QMessageBox::information( 0, "Scribus",
+					  QString("You choose to use an OpenType Font file \"%1\".\n You have to set parameters for this font.").arg(scName) );
+		
+		_otf->get_tables().contains("GSUB") ? _otf->set_table("GSUB") : _otf->set_table("GPOS");
+		QStringList choice = _otf->get_scripts();
+		if(choice.count() > 1)
+		{
+			otfScript = QInputDialog::getItem("Scribus :: otf", "Select the script ", choice, 0, FALSE, &ok );
+			_otf->set_script(otfScript);
+		}
+		else
+		{
+			otfScript = choice[0];
+			_otf->set_script(otfScript);
+		}
+		choice = _otf->get_langs();
+		choice.append("dflt");
+		if(choice.count() > 1)
+		{
+			otfLang = QInputDialog::getItem("Scribus :: otf", QString("Select the language for script %1").arg(otfScript), choice, 0, FALSE, &ok );
+			_otf->set_lang(otfLang);
+		}
+		else
+		{
+			otfLang = choice[0];
+			_otf->set_lang(otfLang);
+		}
+		if(_otf->get_tables().contains("GSUB"))
+		{
+			_otf->set_table("GSUB");
+			_otf->set_script(otfScript);
+			_otf->set_lang(otfLang);
+			choice =_otf->get_features();
+			QString ft;
+			ok = TRUE;
+	// 		while(QMessageBox::question(0,"Scribus","Want to choose features for GSUB ?",QMessageBox::Ok,QMessageBox::No,QMessageBox::NoButton) == QMessageBox::Ok)
+			while(ok && !choice.isEmpty())
+			{
+				ft = QInputDialog::getItem("Scribus :: otf", QString("Select GSUB feature for lang  %1").arg(otfLang), choice, 0, FALSE, &ok );
+				if(ok)
+				{
+				otfSubFeatures.append(ft);
+				choice.remove(ft);
+				}
+			}
+		}
+		if(_otf->get_tables().contains("GPOS"))
+		{
+			_otf->set_table("GPOS");
+			_otf->set_script(otfScript);
+			_otf->set_lang(otfLang);
+			choice =_otf->get_features();
+			QString ft;
+			ok = TRUE;
+	// 		while(QMessageBox::question(0,"Scribus","Want to choose features for GPOS ?",QMessageBox::Ok,QMessageBox::No,QMessageBox::NoButton) == QMessageBox::Ok)
+			while(ok && !choice.isEmpty())
+			{
+				ft = QInputDialog::getItem("Scribus :: otf", QString("Select GPOS feature for lang %1").arg(otfLang), choice, 0, FALSE, &ok );
+				if(ok)
+				{
+				otfPosFeatures.append(ft);
+				choice.remove(ft);
+				}
+			}
+		}
+		qDebug("otf filled");
+	}
 }
 
 
 void FtFace::unload() const
 {
 	if (m_face) {
 		FT_Done_Face( m_face );
 		m_face = NULL;
 	}
 	// clear caches
+	if(_otf) delete _otf;
 	ScFaceData::unload();
 }
 
 
 uint FtFace::char2CMap(QChar ch) const
 {
-	// FIXME use cMap cache
-	FT_Face face = ftFace();
-	uint gl = FT_Get_Char_Index(face, ch.unicode());
-	return gl;
+	if(m_cMap.contains(ch.unicode()))
+	{
+		return m_cMap[ch.unicode()];
+	}
+	else
+	{
+		FT_Face face = ftFace();
+		uint gl = FT_Get_Char_Index(face, ch.unicode());
+		m_cMap.insert(ch.unicode(), gl);
+		return gl;
+	}
 }
 
 
 void FtFace::loadGlyph(uint gl) const
 {
 	if (m_glyphWidth.contains(gl))
 		return;
 	
@@ -307,9 +390,34 @@ void FtFace::RawData(QByteArray & bb) co
 //	 if (showFontInformation)
 	 {
 		 QFile f(fontFile);
 		 qDebug(QObject::tr("RawData for Font %1(%2): size=%3 filesize=%4").arg(fontFile).arg(faceIndex).arg(bb.size()).arg(f.size()));
 	 }
 */	 
 }
 
+QString FtFace::otfied(QString s) const
+{
+	qDebug("otfied");
+	if(status != ScFace::LOADED)
+	{
+		qDebug("Face is not loaded");
+	}
+	else if(typeCode == ScFace::OTF)
+	{
+		int nbg = _otf->procstring(s,otfScript,otfLang,otfSubFeatures,otfPosFeatures);
+		// Actually, newstring should be a QValueList<uint> as it's a glyphstring
+		QString newstring;
+		for (int i = 0; i < nbg ; ++i)
+		{
+			int gi= _otf->get_glyph(i);
+			newstring += QChar(gi);
+			m_cMap.insert(gi,gi);
+		}
+		
+		
+		qDebug(QString("oldstring is \"%1\" and new string is \"%2\"").arg(s).arg(newstring));
+		return newstring;
 
+	}
+	return s;
+}
Index: scribus/fonts/ftface.h
===================================================================
RCS file: /cvs/Scribus/scribus/fonts/Attic/ftface.h,v
retrieving revision 1.1.2.5
diff -u -8 -p -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	7 Apr 2007 19:00:05 -0000
@@ -96,22 +96,31 @@ protected:
 	mutable QString Descender;
 	mutable QString ItalicAngle;
 	mutable QString StdVW;
 	QString FontEnc;
 	mutable QString FontBBox;
 
 	mutable int m_encoding;
 	
-	mutable double m_uniEM;
+//	mutable double m_uniEM;
 	mutable double m_ascent;
 	mutable double m_descent;
 	mutable double m_height;
 	mutable double m_xHeight;
 	mutable double m_capHeight;
 	mutable double m_maxAdvanceWidth;
 	mutable double m_underlinePos;
 	mutable double m_strikeoutPos;
 	mutable double m_strokeWidth;
 	
+	//TEST libotf
+	public:
+		mutable QStringList otfSubFeatures;
+		mutable QStringList otfPosFeatures;
+		mutable QString otfScript;
+		mutable QString otfLang;
+		QString otfied(QString s) const ;
+		
+	
 };
 
 #endif
Index: scribus/fonts/myotf.cpp
===================================================================
RCS file: scribus/fonts/myotf.cpp
diff -N scribus/fonts/myotf.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ scribus/fonts/myotf.cpp	7 Apr 2007 19:00:06 -0000
@@ -0,0 +1,515 @@
+/* un test de libotf mer18jan qui se transforme en test de harfbuzz mer4avr*/
+
+
+#include "myotf.h"
+
+///Required by this great lib that do not provide all symbols
+#include <harfbuzz-external.h>
+//#include <Qt/private/qunicodetables_p.h>
+
+HB_LineBreakClass HB_GetLineBreakClass(HB_UChar32 ch)
+{
+// #if QT_VERSION >= 0x040300
+//     return (HB_LineBreakClass)QUnicodeTables::lineBreakClass(ch);
+// #else
+// #error "This test currently requires Qt >= 4.3"
+// #endif
+	return (HB_LineBreakClass) 0;
+}
+
+void HB_GetUnicodeCharProperties(HB_UChar32 ch, HB_CharCategory *category, int *combiningClass)
+{
+	*category = (HB_CharCategory)QChar::Category(ch);
+	*combiningClass = QChar::CombiningClass(ch);
+}
+
+HB_CharCategory HB_GetUnicodeCharCategory(HB_UChar32 ch)
+{
+	return (HB_CharCategory)QChar::Category(ch);
+}
+
+int HB_GetUnicodeCharCombiningClass(HB_UChar32 ch)
+{
+	return QChar::CombiningClass(ch);
+}
+
+HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch)
+{
+	return QChar(ch).mirroredChar();
+}
+///
+
+QString
+OTF_tag_name (HB_UInt tag)
+{
+  QString name;
+  name[0] = (char) (tag >> 24);
+  name[1] = (char) ((tag >> 16) & 0xFF);
+  name[2] = (char) ((tag >> 8) & 0xFF);
+  name[3] = (char) (tag & 0xFF);
+//   qDebug(QString("OTF_tag_name (%1) -> %2").arg(tag).arg(name));
+  return name;
+}
+
+HB_UInt
+OTF_name_tag (QString s)
+{
+  QChar sometimestagnameisthreecharslong =
+    s.length () > 3 ? s[3].unicode () : ' ';
+  HB_UInt ret = FT_MAKE_TAG (s[0].unicode (), s[1].unicode (), s[2].unicode (),
+		      sometimestagnameisthreecharslong.unicode ());
+//   qDebug(QString("OTF_name_tag (%1) -> %2").arg(s).arg(ret));
+  return ret;
+}
+
+//#define DFLT 0xFFFF
+
+void
+myotf::set_subalt (bool b)
+{
+  subAlt = b;
+}
+
+int myotf::get_glyph( int index)
+{
+	return _buffer->in_string[index].gindex;
+}
+int
+myotf::get_glyph_used ()
+{
+  //    return mys.used;
+  return _buffer->in_length;
+}
+
+myotf::myotf (QString n)
+{
+  nom = n;
+  if (FT_Init_FreeType (&_ftlib))
+    qDebug ("oh merde");
+  if (FT_New_Face (_ftlib, nom, 0, &_face))
+    qDebug ("oh putaing");
+
+  hbFont.klass = NULL;		/* Hope it will work without more code */
+  hbFont.userData = 0;
+  hbFont.faceData = _face;
+  hbFont.x_ppem = _face->size->metrics.x_ppem;
+  hbFont.y_ppem = _face->size->metrics.y_ppem;
+  hbFont.x_scale = 0x10000;//_face->size->metrics.x_scale;
+  hbFont.y_scale = 0x10000;//_face->size->metrics.y_scale;
+
+  subAlt = false;
+  glyphAlloc = false;
+  FT_ULong length = 0;
+
+  if (!FT_Load_Sfnt_Table (_face, OTF_name_tag ("GDEF"), 0, NULL, &length))
+    {
+	    qDebug(QString("length of GDEF table is %1").arg(length));
+	    if(length > 0)
+	    {
+      _memgdef.resize (length);
+      FT_Load_Sfnt_Table (_face, OTF_name_tag ("GDEF"), 0,
+			  (FT_Byte *) _memgdef.data (), &length);
+      gdefstream = new (HB_StreamRec);
+      gdefstream->base = (HB_Byte *) _memgdef.data ();
+      gdefstream->size = _memgdef.size ();
+      gdefstream->pos = 0;
+
+
+      HB_New_GDEF_Table (&_gdef);
+      if (!HB_Load_GDEF_Table (gdefstream, &_gdef))
+	GDEF = 1;
+      else
+	      GDEF = 0;
+	    }
+	    
+	    else
+		    GDEF = 0; 
+    }
+    else
+	    GDEF = 0; 
+  length = 0;
+  if (!FT_Load_Sfnt_Table (_face, OTF_name_tag ("GSUB"), 0, NULL, &length))
+    {
+	    qDebug(QString("length of GSUB table is %1").arg(length));
+	    if(length > 32)//Some font files seem to have a fake table that is just 32 words long and make harbuzz confused
+	    {
+      _memgsub.resize (length);
+      FT_Load_Sfnt_Table (_face, OTF_name_tag ("GSUB"), 0,
+			  (FT_Byte *) _memgsub.data (), &length);
+      gsubstream = new (HB_StreamRec);
+      gsubstream->base = (HB_Byte *) _memgsub.data ();
+      gsubstream->size = _memgsub.size ();
+      gsubstream->pos = 0;
+
+      if (GDEF ? !HB_Load_GSUB_Table (gsubstream, &_gsub, _gdef, gdefstream) :
+	  !HB_Load_GSUB_Table (gsubstream, &_gsub, NULL, NULL))
+	GSUB = 1;
+      else
+	GSUB = 0;
+	    }
+	    else
+		    GSUB = 0;
+    }
+    else
+	    GSUB = 0;
+    // What are thes f... properties ?
+//     if(GSUB)
+//     {
+// 	    for(int i = 0; i < _gsub->LookupList.LookupCount ; i++)
+// 		    qDebug(QString("property[%1] = %2").arg(i).arg(_gsub->LookupList.Properties[i]));
+//     }
+  length = 0;
+  if (!FT_Load_Sfnt_Table (_face, OTF_name_tag ("GPOS"), 0, NULL, &length))
+    {
+	    qDebug(QString("length of GPOS table is %1").arg(length));
+	    if(length > 32)
+	    {
+      _memgpos.resize (length);
+      FT_Load_Sfnt_Table (_face, OTF_name_tag ("GPOS"), 0,
+			  (FT_Byte *) _memgpos.data (), &length);
+      gposstream = new (HB_StreamRec);
+      gposstream->base = (HB_Byte *) _memgpos.data ();
+      gposstream->size = _memgpos.size ();
+      gposstream->pos = 0;
+
+      if (GDEF ? !HB_Load_GPOS_Table (gposstream, &_gpos, _gdef, gdefstream) :
+	  !HB_Load_GPOS_Table (gposstream, &_gpos, NULL, NULL))
+	GPOS = 1;
+      else
+	GPOS = 0;
+	    }
+	    else
+		    GPOS = 0;
+    }
+    else
+	    GPOS = 0;
+  if (hb_buffer_new (&_buffer))
+    qDebug ("unable to get _buffer");
+}
+
+myotf::~myotf ()
+{
+
+  if (_buffer)
+    hb_buffer_free (_buffer);
+  if (GDEF)
+    HB_Done_GDEF_Table (_gdef);
+  if (GSUB)
+    HB_Done_GSUB_Table (_gsub);
+  if (GPOS)
+    HB_Done_GPOS_Table (_gpos);
+  if (_face)
+    FT_Done_Face (_face);
+  if (_ftlib)
+    FT_Done_FreeType (_ftlib);
+}
+
+
+/// the actual function
+int
+myotf::procstring (QString s, QString script, QString lang, QStringList gsub,
+		   QStringList gpos)
+{
+	qDebug (QString("procstring(%1, %2, %3, ...)").arg(s).arg(script).arg(lang));
+	hb_buffer_clear( _buffer );
+  int n = s.length ();
+  HB_Error           error;
+  for (int i = 0; i < n; i++)
+    {
+
+      error = hb_buffer_add_glyph (_buffer,
+			   FT_Get_Char_Index (_face, s[i].unicode()),
+			   0,
+			  0);
+      qDebug(QString("adding glyph [%1] gives glyph [%2]  properties [%3] cluster [%4]").arg(FT_Get_Char_Index (_face, s[i].unicode())).arg(_buffer->in_string[i].gindex).arg(_buffer->in_string[i].properties).arg(_buffer->in_string[i].cluster));
+
+    }
+
+    qDebug(QString("in_string is %1 long").arg(_buffer->in_length));
+
+  if (gsub.count ())
+    {
+      HB_GSUB_Clear_Features (_gsub);
+      set_table ("GSUB");
+      set_script (script);
+      set_lang (lang);
+
+      for (QStringList::iterator ife = gsub.begin (); ife != gsub.end ();
+	   ife++)
+	{
+	  HB_UShort fidx;
+	  error = HB_GSUB_Select_Feature (_gsub,
+				       OTF_name_tag (*ife),
+				       curScript, curLang, &fidx);
+	  if(!error)
+	  {
+	    HB_GSUB_Add_Feature (_gsub, fidx, 1);
+	    qDebug(QString("GSUB [%2] feature.lookupcount = %1").arg(_gsub->FeatureList.FeatureRecord[fidx].Feature.LookupListCount).arg(*ife));
+	  }
+	  else
+		  qDebug(QString("adding gsub feature [%1] failed : %2").arg(*ife).arg(error));
+	}  
+  
+      error = HB_GSUB_Apply_String (_gsub, _buffer);
+      if(error)qDebug(QString("applying gsub features to string \"%1\" returned %2").arg(s).arg(error));
+
+    }
+  if (gpos.count ())
+    {
+      HB_GPOS_Clear_Features (_gpos);
+      set_table ("GPOS");
+      set_script (script);
+      set_lang (lang);
+
+      for (QStringList::iterator ife = gpos.begin (); ife != gpos.end ();
+	   ife++)
+	{
+	  HB_UShort fidx;
+	  error = HB_GPOS_Select_Feature (_gpos,
+				       OTF_name_tag (*ife),
+				       curScript, curLang, &fidx);
+	  if(!error)
+	  {
+	    HB_GPOS_Add_Feature (_gpos, fidx, 1);
+	    qDebug(QString("GPOS [%2] feature.lookupcount = %1").arg(_gpos->FeatureList.FeatureRecord[fidx].Feature.LookupListCount).arg(*ife));
+	  }
+	  else
+		  qDebug(QString("adding gsub feature [%1] failed : %2").arg(*ife).arg(error));
+	}
+	if(_buffer->in_length > 0) memset(_buffer->positions, 0, _buffer->in_length*sizeof(HB_PositionRec));
+      error = HB_GPOS_Apply_String (&hbFont, _gpos, FT_LOAD_NO_SCALE, _buffer,
+			    /*while dvi is true font klass is not used */ true,
+			    /*r2l */ true);
+      if(error)qDebug(QString("applying gpos features to string \"%1\" returned %2").arg(s).arg(error));
+
+    }
+
+
+  return _buffer->in_length;
+}
+
+
+
+
+
+
+QStringList
+myotf::get_tables ()
+{
+  QStringList ret;
+
+  //   if (GDEF)
+  //     ret.insert (ret.end (), "GDEF");
+  if (GPOS)
+    ret.insert (ret.end (), "GPOS");
+  if (GSUB)
+    ret.insert (ret.end (), "GSUB");
+
+  return ret;
+}
+
+void
+myotf::set_table (QString s)
+{
+  curTable = s;
+}
+
+QStringList
+myotf::get_scripts ()
+{
+	qDebug("myotf::get_scripts ()");
+  QStringList ret;
+
+  if (curTable == "GSUB")
+    {
+      HB_UInt *taglist;
+      if (HB_GSUB_Query_Scripts (_gsub, &taglist))
+	qDebug ("error HB_GSUB_Query_Scripts");
+      while (*taglist)
+	{
+		qDebug(QString("script [%1]").arg(OTF_tag_name (*taglist)));
+	  ret.append (OTF_tag_name (*taglist));
+	  ++taglist;
+	}
+
+    }
+  if (curTable == "GPOS")
+    {
+
+      HB_UInt *taglist;
+      if (HB_GPOS_Query_Scripts (_gpos, &taglist))
+	qDebug ("error HB_GPOS_Query_Scripts");
+      while (*taglist)
+	{
+	  ret.append (OTF_tag_name (*taglist));
+	  ++taglist;
+	}
+    }
+  return ret;
+
+}
+
+void
+myotf::set_script (QString s)
+{
+
+  curScriptName = s;
+  if (curTable == "GSUB")
+    {
+      if (HB_GSUB_Select_Script
+	  (_gsub, OTF_name_tag (curScriptName), &curScript))
+	      qDebug (QString("Unable to set script index for %1").arg( curScriptName));
+    }
+  if (curTable == "GPOS")
+    {
+      if (HB_GPOS_Select_Script
+	  (_gpos, OTF_name_tag (curScriptName), &curScript))
+	qDebug ("Unable to set script index");
+    }
+}
+
+
+QStringList
+myotf::get_langs ()
+{
+  QStringList ret;
+ 
+  if (curTable == "GSUB")
+    {
+
+      HB_UInt *taglist;
+      if (HB_GSUB_Query_Languages (_gsub, curScript, &taglist))
+	qDebug ("error HB_GSUB_Query_Langs");
+      while (*taglist)
+	{
+	  ret.append (OTF_tag_name (*taglist));
+	  ++taglist;
+	}
+
+    }
+  if (curTable == "GPOS")
+    {
+
+      HB_UInt *taglist;
+      if (HB_GPOS_Query_Languages (_gpos, curScript, &taglist))
+	qDebug ("error HB_GPOS_Query_Langs");
+      while (*taglist)
+	{
+	  ret.append (OTF_tag_name (*taglist));
+	  ++taglist;
+	}
+
+    }
+
+  return ret;
+}
+
+void
+myotf::set_lang (QString s)
+{
+  if (s == "default" || s == "dflt" || s.isEmpty ())
+    {
+      curLangName = "dflt";
+      curLang = HB_DEFAULT_LANGUAGE;
+      return;
+    }
+
+  curLangName = s;
+  if (curTable == "GSUB")
+    {
+      if (!HB_GSUB_Select_Language (_gsub,
+				    OTF_name_tag (curLangName),
+				    curScript,
+				    &curLang, 
+				    &curLangReq))
+	qDebug ("Unable to set lang index");
+    }
+  if (curTable == "GPOS")
+    {
+      if (!HB_GPOS_Select_Language
+	  (_gpos, OTF_name_tag (curLangName),curScript, &curLang, &curLangReq))
+	qDebug ("Unable to set lang index");
+    }
+
+}
+
+
+QStringList
+myotf::get_features (bool required )
+{
+  QStringList ret;
+
+  if (curTable == "GSUB")
+    {
+
+      HB_UInt *taglist;
+      required ? HB_GSUB_Query_Features (_gsub, curScript, curLangReq,
+					 &taglist) :
+	HB_GSUB_Query_Features (_gsub, curScript, curLang, &taglist);
+      while (*taglist)
+	{
+	  ret.append (OTF_tag_name (*taglist));
+	  ++taglist;
+	}
+
+
+    }
+  if (curTable == "GPOS")
+    {
+
+      HB_UInt *taglist;
+      required ? HB_GPOS_Query_Features (_gpos, curScript, curLangReq,
+					 &taglist) :
+	HB_GPOS_Query_Features (_gpos, curScript, curLang, &taglist);
+      while (*taglist)
+	{
+	  ret.append (OTF_tag_name (*taglist));
+	  ++taglist;
+	}
+
+    }
+  return ret;
+}
+
+void
+myotf::set_features (QStringList ls)
+{
+  curFeatures = ls;
+}
+
+void dump_pos(HB_PositionRec p)
+{
+	qDebug(QString("xpos = %1 | ypos = %2 | xadv = %3 | yadv = %4 | %5 | back = %6 ").arg(p.x_pos).arg(p.y_pos).arg(p.x_advance).arg(p.y_advance).arg(p.new_advance ? "NEW" : "NOT_NEW").arg(p.back));
+}
+
+posglyph myotf::get_position (int g)
+{
+  posglyph
+    ret;
+  if (g > _buffer->in_length)
+    return ret;
+
+  dump_pos(_buffer->positions[g]);
+  if (_buffer->positions[g].new_advance)
+    {
+      ret.Xadvance = (double) _buffer->positions[g].x_advance;
+      ret.Yadvance = (double) _buffer->positions[g].y_advance;
+    }
+  else
+    {
+      FT_GlyphSlot
+	slot = _face->glyph;
+      if (!FT_Load_Glyph
+	  (_face, _buffer->in_string[g].gindex, FT_LOAD_NO_SCALE))
+	{
+	  ret.Xadvance =
+	    (double) (_buffer->positions[g].x_advance + slot->advance.x);
+	  ret.Yadvance =
+	    (double) (_buffer->positions[g].y_advance + slot->advance.y);
+	}
+
+    }
+
+
+  return ret;
+}
Index: scribus/fonts/myotf.h
===================================================================
RCS file: scribus/fonts/myotf.h
diff -N scribus/fonts/myotf.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ scribus/fonts/myotf.h	7 Apr 2007 19:00:06 -0000
@@ -0,0 +1,110 @@
+// myotf.h
+
+#ifndef WRAPLIBOTF
+#define WRAPLIBOTF
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_TABLES_H
+
+extern "C"
+{
+// #include <otf.h>
+// #include <stdlib.h>
+#include "harfbuzz.h"
+}
+
+#include <iostream>
+#include <iomanip>
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+using namespace std;
+
+struct posglyph
+{
+	double Xposition;
+	double Yposition;
+	double Xadvance;
+	double Yadvance;
+	double xadvance(){return Xadvance;}
+	double yadvance(){return Yadvance;}
+	double xposition(){return Xposition;}
+	double yposition(){return Yposition;}
+};
+
+class myotf
+{
+  QString nom;
+  
+  //OTF *my;
+ FT_Library _ftlib;
+ FT_Face _face;
+ HB_FontRec hbFont;
+  QByteArray _memgdef,_memgsub,_memgpos;
+  HB_StreamRec* gdefstream;
+  HB_StreamRec* gsubstream;
+  HB_StreamRec* gposstream;
+  HB_GDEF _gdef;
+  HB_GSUB _gsub;
+  HB_GPOS _gpos;
+  
+  //OTF_GlyphString mys;
+  HB_Buffer _buffer;
+
+  
+  bool subAlt;
+  bool glyphAlloc;
+  
+  int head, name, cmap, GDEF, GSUB, GPOS;
+  
+public: 
+// 	OTF_GlyphString * otfString() {return &mys;}
+// 	int unicode(int gid){ return OTF_get_unicode(my, gid);}
+	int get_glyph( int index);//{return _buffer->out_string[index].gindex;}
+	QString curTable;
+	HB_UShort curScript, curLang, curLangReq;
+  	QString curScriptName, curLangName;
+    	QStringList curFeatures;
+    	myotf (QString n);
+   	~myotf ();
+/*
+ * These members functions apply features currently set 
+ */
+  int procstring (QString );
+  int procstring ();
+  int procstring (QString s, QString script, QString lang, QStringList gsub, QStringList gpos); 
+/*
+  * These functions give access to informations contained in the fontfile
+ */
+  QStringList get_tables ();
+  QStringList   get_scripts ();
+  QStringList   get_langs ();
+  QStringList   get_features (bool required=false);
+/*
+ * These allow to set up the features ( Tab -> Scr -> Lan -> Fea )
+ */
+  void set_table (QString);
+  void set_script (QString);
+  void set_lang (QString);
+  void set_features (QStringList);
+  void set_subalt (bool);
+/*
+ * I can't remember what this so important method is expected to achieve !
+ */
+  int get_position_type (int);
+  /*
+   * for the moment, it just does nothing. Because I have no idea
+   * of which sruct can be the target of this function.Nevertheless
+   * I'm clearly aware that's the key function, it's the reason why
+   * i put this apart from procstring().
+   * The argument is the number of the glyph 
+   */
+ 
+  posglyph get_position(int);
+  int get_glyph_used();
+
+};
+
+#endif
Index: scribus/fonts/scface.h
===================================================================
RCS file: /cvs/Scribus/scribus/fonts/Attic/scface.h,v
retrieving revision 1.1.2.11
diff -u -8 -p -r1.1.2.11 scface.h
--- scribus/fonts/scface.h	25 Mar 2007 22:34:32 -0000	1.1.2.11
+++ scribus/fonts/scface.h	7 Apr 2007 19:00:07 -0000
@@ -16,16 +16,19 @@ virtual:      dispatch to constituents, 
 #include <qstring.h>
 //#include <qvector.h>
 #include <qmap.h>
 //#include <qarray.h>
 #include <utility>
 
 #include "fpointarray.h"
 
+//TEST libotf
+
+#include "myotf.h"
 
 
 struct GlyphMetrics {
 	double width;
 	double ascent;
 	double descent;
 };
 
@@ -109,16 +112,21 @@ public:
 		bool usable;
 		bool embedPs;
 		bool subset;
 		
 		bool isStroked;
 		bool isFixedPitch;
 		bool hasNames;
 		uint maxGlyph;
+		mutable double m_uniEM;
+		protected :
+		mutable myotf * _otf;
+		public:
+		myotf * otf() const { return _otf;}
 
 		ScFaceData();
 		virtual ~ScFaceData() { };
 	protected:
 			
 		friend class ScFace;
 		Status cachedStatus;
 		
@@ -145,16 +153,17 @@ public:
 			m_cMap.clear();
 
 			status = ScFace::UNKNOWN;
 		}
 		
 		virtual void loadGlyph(uint /*gl*/) const {}
 
 		// dummy implementations
+		virtual double uniEM() const {return m_uniEM;}
 		virtual double ascent(double sz)           const { return sz; }
 		virtual QString ascentAsString()    const { return "0" ; }
 		virtual QString descentAsString()    const { return "0"; }
 		virtual QString capHeightAsString()    const { return "0"; }
 		virtual QString FontBBoxAsString()    const { return "0 0 0 0"; }
 		virtual QString ItalicAngleAsString()    const { return "0"; }
 		virtual double descent(double /*sz*/)          const { return 0.0; }
 		virtual double xHeight(double sz)          const { return sz; }
@@ -166,16 +175,19 @@ public:
 		virtual double maxAdvanceWidth(double sz)  const { return sz; }
 		virtual uint   char2CMap(QChar /*ch*/)         const { return 0; }
 		virtual double glyphKerning(uint gl1, uint gl2, double sz) const;
 		virtual QMap<QString,QString> fontDictionary(double sz=1.0) const;
 		virtual GlyphMetrics glyphBBox(uint gl, double sz) const;
 		virtual bool EmbedFont(QString &/*str*/)       const { return false; }
 		virtual void RawData(QByteArray & /*bb*/)      const {}
 		virtual bool glyphNames(QMap<uint, std::pair<QChar, QString> >& gList) const;
+		
+		virtual QString otfied(QString s) const {return s;}
+		
 
 		// these use the cache:
 		virtual double      glyphWidth(uint gl, double sz)   const;
 		virtual FPointArray glyphOutline(uint gl, double sz) const; 
 		virtual FPoint      glyphOrigin (uint gl, double sz) const;
 		
 	};
 		
@@ -293,16 +305,17 @@ public:
 	
 	/// returns the font style as seen by Scribus (eg. bold, Italic)
 	QString style()    const { return m->style; }
 	
 	/// returns an additional discriminating String for this face
 	QString variant()  const { return m->variant; }
 	
 	// font metrics
+	double unitsEM () const {return m->uniEM();}
 	double ascent(double sz=1.0)          const { return m->ascent(sz); }
 	QString ascentAsString()    const { return m->ascentAsString() ; }
 	QString descentAsString()    const { return m->descentAsString() ; }
 	QString capHeightAsString()    const { return m->capHeightAsString() ; }
 	QString FontBBoxAsString()    const { return m->FontBBoxAsString() ; }
 	QString ItalicAngleAsString()    const { return m->ItalicAngleAsString() ; }
 	double descent(double sz=1.0)         const { return m->descent(sz); }
 	double xHeight(double sz=1.0)         const { return m->xHeight(sz); }
@@ -359,16 +372,19 @@ public:
 	double realCharHeight(QChar ch, double sz=1.0) const { GlyphMetrics gm=glyphBBox(char2CMap(ch),sz); return gm.ascent + gm.descent; }
 	
 	/// deprecated, see glyphBBox()
 	double realCharAscent(QChar ch, double sz=1.0) const { return glyphBBox(char2CMap(ch),sz).ascent; }
 	
 	/// deprecated, see glyphBBox()
 	double realCharDescent(QChar ch, double sz=1.0) const { return glyphBBox(char2CMap(ch),sz).descent; }
 	
+	//TEST libotf
+	QString otfied (QString s) const {  return m->otfied(s); }
+	myotf * otf() const { return m->otf();}
 private:
 		
 	friend class SCFonts;
 	
 	ScFace(ScFaceData* md);
 	ScFaceData* m;
 	QString replacedName;
 	QString replacedInDoc;
