r15650 by pierremarc - made text shaping by ICU and started to fix issues in new text engine

scribus-commit scribus-commit at lists.scribus.net
Mon Oct 25 22:45:56 CEST 2010


Author: pierremarc
Date: Mon Oct 25 20:45:56 2010
New Revision: 15650

URL: http://scribus.info/websvn/listing.php?repname=Scribus&sc=1&rev=15650
Log:
made text shaping by ICU and started to fix issues in new text engine

Added:
    branches/ScribusOIF/scribus/fonts/scicufont.cpp
    branches/ScribusOIF/scribus/fonts/scicufont.h
Modified:
    branches/ScribusOIF/CMakeLists.txt
    branches/ScribusOIF/resources/loremipsum/fr.xml
    branches/ScribusOIF/scribus/CMakeLists.txt
    branches/ScribusOIF/scribus/fonts/CMakeLists.txt
    branches/ScribusOIF/scribus/fonts/fontfeatureset.h
    branches/ScribusOIF/scribus/fonts/scface.h
    branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
    branches/ScribusOIF/scribus/fonts/scface_ttf.h
    branches/ScribusOIF/scribus/langmgr.cpp
    branches/ScribusOIF/scribus/langmgr.h
    branches/ScribusOIF/scribus/styles/charstyle.attrdefs.cxx
    branches/ScribusOIF/scribus/text/boxes.cpp
    branches/ScribusOIF/scribus/text/glyphstore.cpp
    branches/ScribusOIF/scribus/text/legacylayout.cpp

Modified: branches/ScribusOIF/CMakeLists.txt
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/CMakeLists.txt
==============================================================================
--- branches/ScribusOIF/CMakeLists.txt (original)
+++ branches/ScribusOIF/CMakeLists.txt Mon Oct 25 20:45:56 2010
@@ -733,6 +733,15 @@
 ENDIF (WANT_GRAPHICSMAGICK)
 #>>GraphicksMagick++ for image import
 
+#<<ICU for text shaping (required)
+FIND_PACKAGE(ICU)
+IF(ICU_FOUND)
+  MESSAGE(STATUS "ICU Found OK")
+ELSE(ICU_FOUND)
+  MESSAGE(FATAL_ERROR "ICU NOT Found!")
+ENDIF(ICU_FOUND)
+#>>ICU for text shaping
+
 ##############################################################################################################
 ########## Include Setup                                                                            ##########
 

Modified: branches/ScribusOIF/resources/loremipsum/fr.xml
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/resources/loremipsum/fr.xml
==============================================================================
--- branches/ScribusOIF/resources/loremipsum/fr.xml (original)
+++ branches/ScribusOIF/resources/loremipsum/fr.xml Mon Oct 25 20:45:56 2010
@@ -5,16 +5,7 @@
 <author>Descartes</author>
 <url>http://fr.wikibooks.org/wiki/Perception</url>
 
-<p>Commençons par la considération des choses les plus communes, et que nous croyons comprendre le plus distinctement, à savoir les corps que nous touchons et que nous voyons. Je n'entends pas parler des corps en général, car ces notions générales sont d'ordinaire plus confuses, mais de quelqu'un en particulier. Prenons pour exemple ce morceau de cire qui vient d'être tiré de la ruche : il n'a pas encore perdu la douceur du miel qu'il contenait, il retient encore quelque chose de l'odeur des fleurs dont il a été recueilli; sa couleur, sa figure, sa grandeur, sont apparentes; il est dur, il est froid, on le touche, et si vous le frappez, il rendra quelque son.</p> 
-
+<p>ToYoTa affinites</p>
 <p>Enfin toutes les choses qui peuvent distinctement faire connaître un corps, se rencontrent en celui-ci. Mais voici que, cependant que je parle, on l'approche du feu : ce qui y restait de saveur s'exhale, l'odeur s'évanouit, sa couleur se change, sa figure se perd, sa grandeur augmente, il devient liquide, il s'échauffe, à peine le peut-on toucher, et quoiqu'on le frappe, il ne rendra plus aucun son. La même cire demeure-t-elle après ce changement ? Il faut avouer qu'elle demeure; et personne ne le peut nier. Qu'est-ce donc que l'on connaissait en ce morceau de cire avec tant de distinction ?</p>
 
-<p>Certes ce ne peut être rien de tout ce que j'y ai remarqué par l'entremise des sens, puisque toutes les choses qui tombaient sous le goût, ou l'odorat, ou la vue, ou l'attouchement, ou l'ouïe, se trouvent changées, et cependant la même cire demeure. Peut-être était-ce ce que je pense maintenant, à savoir que la cire n'était pas ni cette douceur du miel, ni cette agréable odeur des fleurs, ni cette blancheur, ni cette figure, ni ce son, mais seulement un corps qui un peu auparavant me paraissait sous ces formes, et qui maintenant se fait remarquer sous d'autres. Mais qu'est-ce, précisément parlant, que j'imagine, lorsque je la conçois en cette sorte ?</p>
-
-<p>Considérons-le attentivement, et éloignant toutes les choses qui n'appartiennent point à la cire, voyons ce qui reste. Certes il ne demeure rien que quelque chose d'étendu, de flexible et de muable. Or qu'est-ce que cela : flexible et muable ? N'est-ce pas que j'imagine que cette cire étant ronde est capable de devenir carrée, et de passer du carré en une figure triangulaire ? Non certes, ce n'est pas cela, puisque je la conçois capable de recevoir une infinité de semblables changements, et je ne saurais néanmoins parcourir cette infinité par mon imagination, et par conséquent cette conception que j'ai de la cire ne s'accomplit pas par la faculté d'imaginer.</p>
-
-<p>Qu'est-ce maintenant que cette extension ? N'est-elle pas aussi inconnue, puisque dans la cire qui se fond elle augmente, et se trouve encore plus grande quand elle est entièrement fondue, et beaucoup plus encore quand la chaleur augmente davantage ? Et je ne concevrais pas clairement et selon la vérité ce que c'est que la cire, si je ne pensais qu'elle est capable de recevoir plus de variétés selon l'extension, que je n'en ai jamais imaginé. Il faut donc que je tombe d'accord, que je ne saurais pas même concevoir par l'imagination ce que c'est que cette cire, et qu'il n'y a que mon entendement seul qui le conçoive; je dis ce morceau de cire en particulier, car pour la cire en général, il est encore plus évident.</p>
-
-<p>Or quelle est cette cire, qui ne peut être conçue que par l'entendement ou l'esprit ? Certes c'est la même que je vois, que je touche, que j'imagine, et la même que je connaissais dès le commencement. Mais ce qui est à remarquer, sa perception, ou bien l'action par laquelle on l'aperçoit, n'est point une vision, ni un attouchement, ni une imagination, et ne l'a jamais été, quoiqu'il le semblât ainsi auparavant, mais seulement une inspection de l'esprit, laquelle peut être imparfaite et confuse, comme elle était auparavant, ou bien claire et distincte, comme elle est à présent, selon que mon attention se porte plus ou moins aux choses qui sont en elle, et dont elle est composée.</p>
-
 </lorem>

Modified: branches/ScribusOIF/scribus/CMakeLists.txt
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/CMakeLists.txt
==============================================================================
--- branches/ScribusOIF/scribus/CMakeLists.txt (original)
+++ branches/ScribusOIF/scribus/CMakeLists.txt Mon Oct 25 20:45:56 2010
@@ -894,6 +894,7 @@
   ${CMAKE_SOURCE_DIR}
   ${CMAKE_CURRENT_SOURCE_DIR}
   ${FREETYPE_INCLUDE_DIRS}
+  ${ICU_INCLUDE_DIRS}
 )
 
 IF (GMAGICK_FOUND)
@@ -1020,6 +1021,7 @@
   ${ZLIB_LIBRARIES}
   ${WIN32_ONLY_LIBS}
   ${GMAGICK_LIBRARIES}
+  ${ICU_LIBRARIES}
 )
 
 # required to resolve symbols from libdl when ld is called with --no-add-needed

Modified: branches/ScribusOIF/scribus/fonts/CMakeLists.txt
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/fonts/CMakeLists.txt
==============================================================================
--- branches/ScribusOIF/scribus/fonts/CMakeLists.txt (original)
+++ branches/ScribusOIF/scribus/fonts/CMakeLists.txt Mon Oct 25 20:45:56 2010
@@ -2,6 +2,7 @@
 ${CMAKE_SOURCE_DIR}
 ${CMAKE_SOURCE_DIR}/scribus
 ${FREETYPE_INCLUDE_DIRS}
+${ICU_INCLUDE_DIRS}
 )
 
 
@@ -13,6 +14,7 @@
   scfontmetrics.cpp
   schbfunctions.cpp
   fontfeatureset.cpp
+  scicufont.cpp
 )
 SET(SCRIBUS_FONTS_LIB "scribus_fonts_lib")
 ADD_LIBRARY(${SCRIBUS_FONTS_LIB} STATIC ${SCRIBUS_FONTS_LIB_SOURCES})

Modified: branches/ScribusOIF/scribus/fonts/fontfeatureset.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/fonts/fontfeatureset.h
==============================================================================
--- branches/ScribusOIF/scribus/fonts/fontfeatureset.h (original)
+++ branches/ScribusOIF/scribus/fonts/fontfeatureset.h Mon Oct 25 20:45:56 2010
@@ -52,8 +52,8 @@
 	{
 		QString name;
 		FeatureType type;
-		QStringList script;
-		QStringList lang;
+		QString script;
+		QString lang;
 		Feature(){}
 		Feature& operator=(const Feature& other)
 		{

Modified: branches/ScribusOIF/scribus/fonts/scface.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/fonts/scface.h
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scface.h (original)
+++ branches/ScribusOIF/scribus/fonts/scface.h Mon Oct 25 20:45:56 2010
@@ -182,7 +182,7 @@
 		virtual void RawData(QByteArray & /*bb*/)      const {}
 		virtual bool glyphNames(QMap<uint, std::pair<QChar, QString> >& gList) const;
 		virtual FontFeatureSet * features() const { return 0; }
-		virtual int shapeText(GlyphStore* /*gs*/) const {return 0;}
+		virtual int shapeText(GlyphStore* /*gs*/, unsigned int /*item*/) const {return 0;}
 
 		// these use the cache:
 		virtual qreal      glyphWidth(uint gl, qreal sz)   const;
@@ -380,7 +380,7 @@
 	FontFeatureSet * features() { return m->features();}
 
 	/// Process a string
-	int shapeText(GlyphStore* gs) const{return m->shapeText(gs);}
+	int shapeText(GlyphStore* gs, unsigned int item) const{return m->shapeText(gs, item);}
 	
 private:
 		

Modified: branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scface_ttf.cpp (original)
+++ branches/ScribusOIF/scribus/fonts/scface_ttf.cpp Mon Oct 25 20:45:56 2010
@@ -23,6 +23,12 @@
 #include "scconfig.h"
 #include "sctextstruct.h"
 #include "langmgr.h"
+#include "fonts/scicufont.h"
+
+#include <layout/LETypes.h>
+#include <layout/LayoutEngine.h>
+#include <layout/LEFontInstance.h>
+#include <layout/LEScripts.h>
 
 
 #include "third_party/harfbuzz/src/hb-ot.h"
@@ -46,363 +52,363 @@
 }
 
 
-KernFeature::KernFeature ( FT_Face face )
-	:m_valid ( true )
-{
-	FontName = QString ( face->family_name ) + " " + QString ( face->style_name )   ;
-	// 	qDebug() <<"KF"<<FontName;
-	// 	QTime t;
-	// 	t.start();
-	FT_ULong length = 0;
-	if ( !FT_Load_Sfnt_Table ( face, TTAG_GPOS , 0, NULL, &length ) )
-	{
-		// 		qDebug() <<"\t"<<"GPOS table len"<<length;
-		if ( length > 32 )
-		{
-			GPOSTableRaw.resize ( length );
-			FT_Load_Sfnt_Table ( face, TTAG_GPOS, 0, reinterpret_cast<FT_Byte*> ( GPOSTableRaw.data() ), &length );
-
-			makeCoverage();
-		}
-		else
-			m_valid = false;
-
-		GPOSTableRaw.clear();
-		coverages.clear();
-	}
-	else
-		m_valid = false;
-
-	if ( !m_valid )
-		pairs.clear();
-	// 	qDebug() <<"\t"<<m_valid;
-	// 	qDebug() <<"\t"<<t.elapsed();
-}
-
-KernFeature::KernFeature ( const KernFeature & kf )
-{
-	m_valid = kf.m_valid;
-	if ( m_valid )
-		pairs = kf.pairs;
-
-}
-
-
-KernFeature::~ KernFeature()
-{
-}
-
-double KernFeature::getPairValue ( unsigned int glyph1, unsigned int glyph2 ) const
-{
-	if ( m_valid )
-	{
-		if ( pairs.contains ( glyph1 ) )
-		{
-			if ( pairs[glyph1].contains ( glyph2 ) )
-			{
-				return pairs[glyph1][glyph2];
-			}
-		}
-	}
-	return 0.0;
-}
-
-void KernFeature::makeCoverage()
-{
-	if ( GPOSTableRaw.isEmpty() )
-		return;
-
-	quint16 FeatureList_Offset= toUint16 ( 6 );
-	quint16 LookupList_Offset = toUint16 ( 8 );
-
-	// Find the offsets of the kern feature tables
-	quint16 FeatureCount = toUint16 ( FeatureList_Offset );;
-	QList<quint16> FeatureKern_Offset;
-	for ( quint16 FeatureRecord ( 0 ); FeatureRecord < FeatureCount; ++ FeatureRecord )
-	{
-		int rawIdx ( FeatureList_Offset + 2 + ( 6 * FeatureRecord ) );
-		quint32 tag ( FT_MAKE_TAG ( GPOSTableRaw.at ( rawIdx ),
-		                            GPOSTableRaw.at ( rawIdx + 1 ),
-		                            GPOSTableRaw.at ( rawIdx + 2 ),
-		                            GPOSTableRaw.at ( rawIdx + 3 ) ) );
-		if ( tag == TTAG_kern )
-		{
-			FeatureKern_Offset << ( toUint16 ( rawIdx + 4 ) + FeatureList_Offset );
-
-		}
-	}
-
-	// Extract indices of lookups for feture kern
-	QList<quint16> LookupListIndex;
-	foreach ( quint16 kern, FeatureKern_Offset )
-	{
-		quint16 LookupCount ( toUint16 ( kern + 2 ) );
-		for ( int llio ( 0 ) ; llio < LookupCount; ++llio )
-		{
-			quint16 Idx ( toUint16 ( kern + 4 + ( llio * 2 ) ) );
-			if ( !LookupListIndex.contains ( Idx ) )
-			{
-				LookupListIndex <<Idx ;
-			}
-		}
-	}
-
-
-	// Extract offsets of lookup tables for feature kern
-	QList<quint16> LookupTables;
-	QList<quint16> PairAdjustmentSubTables;
-	for ( int i ( 0 ); i < LookupListIndex.count(); ++i )
-	{
-		int rawIdx ( LookupList_Offset + 2 + ( LookupListIndex[i] * 2 ) );
-		quint16 Lookup ( toUint16 ( rawIdx )  + LookupList_Offset );
-		quint16 SubTableCount ( toUint16 ( Lookup + 4 ) );
-		for ( int stIdx ( 0 ); stIdx < SubTableCount; ++ stIdx )
-		{
-			quint16 SubTable ( toUint16 ( Lookup + 6 + ( 2 * stIdx ) ) + Lookup );
-
-			// 			quint16 PosFormat ( toUint16 ( SubTable ) );
-			quint16 Coverage_Offset ( toUint16 ( SubTable + 2 ) + SubTable );
-			quint16 CoverageFormat ( toUint16 ( Coverage_Offset ) );
-
-			if ( 1 == CoverageFormat ) // glyph indices based
-			{
-				quint16 GlyphCount ( toUint16 ( Coverage_Offset + 2 ) );
-				quint16 GlyphID ( Coverage_Offset + 4 );
-
-				for ( unsigned int gl ( 0 ); gl < GlyphCount; ++gl )
-				{
-					coverages[SubTable] << toUint16 ( GlyphID + ( gl * 2 ) );
-				}
-			}
-			else if ( 2 == CoverageFormat ) // Coverage Format2 => ranges based
-			{
-				quint16 RangeCount ( toUint16 ( Coverage_Offset + 2 ) );
-
-				// 				int gl_base ( 0 );
-				for ( int r ( 0 ); r < RangeCount; ++r )
-				{
-					quint16 rBase ( Coverage_Offset + 4 + ( r * 6 ) );
-					quint16 Start ( toUint16 ( rBase ) );
-					quint16 End ( toUint16 ( rBase + 2 ) );
-					// 					quint16 StartCoverageIndex ( toUint16 ( rBase + 4 ) );
-					for ( unsigned int gl ( Start ); gl <= End; ++gl )
-						coverages[SubTable]  << gl;
-				}
-			}
-			else
-			{
-				qDebug() <<"Unknow Coverage Format:"<<CoverageFormat;
-				continue;
-			}
-
-			makePairs ( SubTable );
-		}
-
-	}
-
-
-}
-
-
-void KernFeature::makePairs ( quint16 subtableOffset )
-{
-	/*
-	Lookup Type 2:
-	Pair Adjustment Positioning Subtable
-	*/
-
-	quint16 PosFormat ( toUint16 ( subtableOffset ) );
-
-	if ( PosFormat == 1 )
-	{
-		quint16 ValueFormat1 ( toUint16 ( subtableOffset +4 ) );
-		quint16 ValueFormat2 ( toUint16 ( subtableOffset +6 ) );
-		quint16 PairSetCount ( toUint16 ( subtableOffset +8 ) );
-		if ( ValueFormat1 && ValueFormat2 )
-		{
-			for ( int psIdx ( 0 ); psIdx < PairSetCount; ++ psIdx )
-			{
-				unsigned int FirstGlyph ( coverages[subtableOffset][psIdx] );
-				quint16 PairSetOffset ( toUint16 ( subtableOffset +10 + ( 2 * psIdx ) ) +  subtableOffset );
-				quint16 PairValueCount ( toUint16 ( PairSetOffset ) );
-				quint16 PairValueRecord ( PairSetOffset + 2 );
-				for ( int pvIdx ( 0 );pvIdx < PairValueCount; ++pvIdx )
-				{
-					quint16 recordBase ( PairValueRecord + ( ( 2 + 2 + 2 ) * pvIdx ) );
-					quint16 SecondGlyph ( toUint16 ( recordBase ) );
-					qint16 Value1 ( toInt16 ( recordBase + 2 ) );
-					pairs[FirstGlyph][SecondGlyph] = double ( Value1 );
-
-				}
-
-			}
-		}
-		else if ( ValueFormat1 && ( !ValueFormat2 ) )
-		{
-			for ( int psIdx ( 0 ); psIdx < PairSetCount; ++ psIdx )
-			{
-				unsigned int FirstGlyph ( coverages[subtableOffset][psIdx] );
-				quint16 PairSetOffset ( toUint16 ( subtableOffset +10 + ( 2 * psIdx ) ) +  subtableOffset );
-				quint16 PairValueCount ( toUint16 ( PairSetOffset ) );
-				quint16 PairValueRecord ( PairSetOffset + 2 );
-				for ( int pvIdx ( 0 );pvIdx < PairValueCount; ++pvIdx )
-				{
-					quint16 recordBase ( PairValueRecord + ( ( 2 + 2 ) * pvIdx ) );
-					quint16 SecondGlyph ( toUint16 ( recordBase ) );
-					qint16 Value1 ( toInt16 ( recordBase + 2 ) );
-					pairs[FirstGlyph][SecondGlyph] = double ( Value1 );
-
-				}
-
-			}
-		}
-		else
-		{
-			qDebug() <<"ValueFormat1 is null or both ValueFormat1 and ValueFormat2 are null";
-		}
-
-	}
-	else if ( PosFormat == 2 )
-	{
-		quint16 ValueFormat1 ( toUint16 ( subtableOffset +4 ) );
-		quint16 ValueFormat2 ( toUint16 ( subtableOffset +6 ) );
-		quint16 ClassDef1 ( toUint16 ( subtableOffset +8 )  + subtableOffset );
-		quint16 ClassDef2 ( toUint16 ( subtableOffset +10 ) + subtableOffset );
-		quint16 Class1Count ( toUint16 ( subtableOffset +12 ) );
-		quint16 Class2Count ( toUint16 ( subtableOffset +14 ) );
-		quint16 Class1Record ( subtableOffset +16 );
-
-		// first extract classses
-		ClassDefTable Class1Data ( getClass ( ClassDef1 , subtableOffset ) );
-		ClassDefTable Class2Data ( getClass ( ClassDef2 , subtableOffset ) );
-
-		if ( ValueFormat1 && ValueFormat2 )
-		{
-			for ( quint16 C1 ( 0 );C1 < Class1Count; ++C1 )
-			{
-				QList<quint16> Class1 ( Class1Data[C1] );
-				quint16 Class2Record ( Class1Record + ( C1 * ( 2 * 2 * Class2Count ) ) );
-				for ( quint16 C2 ( 0 );C2 < Class2Count; ++C2 )
-				{
-					qint16 Value1 ( toInt16 ( Class2Record + ( C2 * ( 2 * 2 ) ) ) );
-					QList<quint16> Class2 ( Class2Data[C2] );
-					// keep it barbarian :D
-					foreach ( quint16 FirstGlyph, Class1 )
-					{
-						foreach ( quint16 SecondGlyph, Class2 )
-						{
-							if ( Value1 )
-								pairs[FirstGlyph][SecondGlyph] = double ( Value1 );
-						}
-					}
-				}
-			}
-		}
-		else if ( ValueFormat1 && ( !ValueFormat2 ) )
-		{
-			for ( quint16 C1 ( 0 );C1 < Class1Count; ++C1 )
-			{
-				QString cdbg ( QString::number ( C1 ).rightJustified ( 5,QChar ( 32 ) ) );
-				QList<quint16> Class1 ( Class1Data[C1] );
-				quint16 Class2Record ( Class1Record + ( C1 * ( 2 * Class2Count ) ) );
-				for ( quint16 C2 ( 0 );C2 < Class2Count; ++C2 )
-				{
-					qint16 Value1 ( toInt16 ( Class2Record + ( C2 * 2 ) ) );
-					QList<quint16> Class2 ( Class2Data[C2] );
-
-					foreach ( quint16 FirstGlyph, Class1 )
-					{
-						foreach ( quint16 SecondGlyph, Class2 )
-						{
-							if ( Value1 )
-								pairs[FirstGlyph][SecondGlyph] = double ( Value1 );
-						}
-					}
-				}
-			}
-		}
-		else
-		{
-			qDebug() <<"ValueFormat1 is null or both ValueFormat1 and ValueFormat2 are null";
-		}
-
-	}
-	else
-		qDebug() <<"unknown PosFormat"<<PosFormat;
-}
-
-KernFeature::ClassDefTable KernFeature::getClass ( quint16 classDefOffset, quint16 coverageId )
-{
-	ClassDefTable ret;
-	ret[0] = coverages[coverageId];
-	quint16 ClassFormat ( toUint16 ( classDefOffset ) );
-	if ( ClassFormat == 1 )
-	{
-		quint16 StartGlyph ( toUint16 ( classDefOffset +2 ) );
-		quint16 GlyphCount ( toUint16 ( classDefOffset +4 ) );
-		quint16 ClassValueArray ( classDefOffset + 6 );
-
-		for ( quint16 CV ( 0 );CV < GlyphCount; ++CV )
-		{
-			ret[0].removeAll ( StartGlyph + CV );
-			ret[ toUint16 ( ClassValueArray + ( CV * 2 ) ) ] << StartGlyph + CV;
-		}
-	}
-	else if ( ClassFormat == 2 )
-	{
-		quint16 ClassRangeCount ( toUint16 ( classDefOffset + 2 ) );
-		quint16 ClassRangeRecord ( classDefOffset + 4 );
-		for ( int CRR ( 0 ); CRR < ClassRangeCount; ++CRR )
-		{
-			quint16 Start ( toUint16 ( ClassRangeRecord + ( CRR * 6 ) ) );
-			quint16 End ( toUint16 ( ClassRangeRecord + ( CRR * 6 ) + 2 ) );
-			quint16 Class ( toUint16 ( ClassRangeRecord + ( CRR * 6 ) + 4 ) );
-
-			for ( quint16 gl ( Start ); gl <= End; ++gl )
-			{
-				ret[0].removeAll ( gl );
-				ret[Class] << gl;
-			}
-		}
-	}
-	else
-		qDebug() <<"Unknown Class Table type";
-
-	return ret;
-}
-
-quint16 KernFeature::toUint16 ( quint16 index )
-{
-	if ( ( index + 2 ) > GPOSTableRaw.count() )
-	{
-		qDebug() << "HORROR!" << index << GPOSTableRaw.count() << FontName ;
-		// Rather no kerning at all than random kerning
-		// 		m_valid = false;
-		return 0;
-	}
-	// FIXME I just do not know how it has to be done *properly*
-	quint16 c1 ( GPOSTableRaw.at ( index ) );
-	quint16 c2 ( GPOSTableRaw.at ( index + 1 ) );
-	c1 &= 0xFF;
-	c2 &= 0xFF;
-	quint16 ret ( ( c1 << 8 ) | c2 );
-	return ret;
-}
-
-qint16 KernFeature::toInt16 ( quint16 index )
-{
-	if ( ( index + 2 ) > GPOSTableRaw.count() )
-	{
-		return 0;
-	}
-	// FIXME I just do not know how it has to be done *properly*
-	quint16 c1 ( GPOSTableRaw.at ( index ) );
-	quint16 c2 ( GPOSTableRaw.at ( index + 1 ) );
-	c1 &= 0xFF;
-	c2 &= 0xFF;
-	qint16 ret ( ( c1 << 8 ) | c2 );
-	return ret;
-}
+//KernFeature::KernFeature ( FT_Face face )
+//	:m_valid ( true )
+//{
+//	FontName = QString ( face->family_name ) + " " + QString ( face->style_name )   ;
+//	// 	qDebug() <<"KF"<<FontName;
+//	// 	QTime t;
+//	// 	t.start();
+//	FT_ULong length = 0;
+//	if ( !FT_Load_Sfnt_Table ( face, TTAG_GPOS , 0, NULL, &length ) )
+//	{
+//		// 		qDebug() <<"\t"<<"GPOS table len"<<length;
+//		if ( length > 32 )
+//		{
+//			GPOSTableRaw.resize ( length );
+//			FT_Load_Sfnt_Table ( face, TTAG_GPOS, 0, reinterpret_cast<FT_Byte*> ( GPOSTableRaw.data() ), &length );
+
+//			makeCoverage();
+//		}
+//		else
+//			m_valid = false;
+
+//		GPOSTableRaw.clear();
+//		coverages.clear();
+//	}
+//	else
+//		m_valid = false;
+
+//	if ( !m_valid )
+//		pairs.clear();
+//	// 	qDebug() <<"\t"<<m_valid;
+//	// 	qDebug() <<"\t"<<t.elapsed();
+//}
+
+//KernFeature::KernFeature ( const KernFeature & kf )
+//{
+//	m_valid = kf.m_valid;
+//	if ( m_valid )
+//		pairs = kf.pairs;
+
+//}
+
+
+//KernFeature::~ KernFeature()
+//{
+//}
+
+//double KernFeature::getPairValue ( unsigned int glyph1, unsigned int glyph2 ) const
+//{
+//	if ( m_valid )
+//	{
+//		if ( pairs.contains ( glyph1 ) )
+//		{
+//			if ( pairs[glyph1].contains ( glyph2 ) )
+//			{
+//				return pairs[glyph1][glyph2];
+//			}
+//		}
+//	}
+//	return 0.0;
+//}
+
+//void KernFeature::makeCoverage()
+//{
+//	if ( GPOSTableRaw.isEmpty() )
+//		return;
+
+//	quint16 FeatureList_Offset= toUint16 ( 6 );
+//	quint16 LookupList_Offset = toUint16 ( 8 );
+
+//	// Find the offsets of the kern feature tables
+//	quint16 FeatureCount = toUint16 ( FeatureList_Offset );;
+//	QList<quint16> FeatureKern_Offset;
+//	for ( quint16 FeatureRecord ( 0 ); FeatureRecord < FeatureCount; ++ FeatureRecord )
+//	{
+//		int rawIdx ( FeatureList_Offset + 2 + ( 6 * FeatureRecord ) );
+//		quint32 tag ( FT_MAKE_TAG ( GPOSTableRaw.at ( rawIdx ),
+//		                            GPOSTableRaw.at ( rawIdx + 1 ),
+//		                            GPOSTableRaw.at ( rawIdx + 2 ),
+//		                            GPOSTableRaw.at ( rawIdx + 3 ) ) );
+//		if ( tag == TTAG_kern )
+//		{
+//			FeatureKern_Offset << ( toUint16 ( rawIdx + 4 ) + FeatureList_Offset );
+
+//		}
+//	}
+
+//	// Extract indices of lookups for feture kern
+//	QList<quint16> LookupListIndex;
+//	foreach ( quint16 kern, FeatureKern_Offset )
+//	{
+//		quint16 LookupCount ( toUint16 ( kern + 2 ) );
+//		for ( int llio ( 0 ) ; llio < LookupCount; ++llio )
+//		{
+//			quint16 Idx ( toUint16 ( kern + 4 + ( llio * 2 ) ) );
+//			if ( !LookupListIndex.contains ( Idx ) )
+//			{
+//				LookupListIndex <<Idx ;
+//			}
+//		}
+//	}
+
+
+//	// Extract offsets of lookup tables for feature kern
+//	QList<quint16> LookupTables;
+//	QList<quint16> PairAdjustmentSubTables;
+//	for ( int i ( 0 ); i < LookupListIndex.count(); ++i )
+//	{
+//		int rawIdx ( LookupList_Offset + 2 + ( LookupListIndex[i] * 2 ) );
+//		quint16 Lookup ( toUint16 ( rawIdx )  + LookupList_Offset );
+//		quint16 SubTableCount ( toUint16 ( Lookup + 4 ) );
+//		for ( int stIdx ( 0 ); stIdx < SubTableCount; ++ stIdx )
+//		{
+//			quint16 SubTable ( toUint16 ( Lookup + 6 + ( 2 * stIdx ) ) + Lookup );
+
+//			// 			quint16 PosFormat ( toUint16 ( SubTable ) );
+//			quint16 Coverage_Offset ( toUint16 ( SubTable + 2 ) + SubTable );
+//			quint16 CoverageFormat ( toUint16 ( Coverage_Offset ) );
+
+//			if ( 1 == CoverageFormat ) // glyph indices based
+//			{
+//				quint16 GlyphCount ( toUint16 ( Coverage_Offset + 2 ) );
+//				quint16 GlyphID ( Coverage_Offset + 4 );
+
+//				for ( unsigned int gl ( 0 ); gl < GlyphCount; ++gl )
+//				{
+//					coverages[SubTable] << toUint16 ( GlyphID + ( gl * 2 ) );
+//				}
+//			}
+//			else if ( 2 == CoverageFormat ) // Coverage Format2 => ranges based
+//			{
+//				quint16 RangeCount ( toUint16 ( Coverage_Offset + 2 ) );
+
+//				// 				int gl_base ( 0 );
+//				for ( int r ( 0 ); r < RangeCount; ++r )
+//				{
+//					quint16 rBase ( Coverage_Offset + 4 + ( r * 6 ) );
+//					quint16 Start ( toUint16 ( rBase ) );
+//					quint16 End ( toUint16 ( rBase + 2 ) );
+//					// 					quint16 StartCoverageIndex ( toUint16 ( rBase + 4 ) );
+//					for ( unsigned int gl ( Start ); gl <= End; ++gl )
+//						coverages[SubTable]  << gl;
+//				}
+//			}
+//			else
+//			{
+//				qDebug() <<"Unknow Coverage Format:"<<CoverageFormat;
+//				continue;
+//			}
+
+//			makePairs ( SubTable );
+//		}
+
+//	}
+
+
+//}
+
+
+//void KernFeature::makePairs ( quint16 subtableOffset )
+//{
+//	/*
+//	Lookup Type 2:
+//	Pair Adjustment Positioning Subtable
+//	*/
+
+//	quint16 PosFormat ( toUint16 ( subtableOffset ) );
+
+//	if ( PosFormat == 1 )
+//	{
+//		quint16 ValueFormat1 ( toUint16 ( subtableOffset +4 ) );
+//		quint16 ValueFormat2 ( toUint16 ( subtableOffset +6 ) );
+//		quint16 PairSetCount ( toUint16 ( subtableOffset +8 ) );
+//		if ( ValueFormat1 && ValueFormat2 )
+//		{
+//			for ( int psIdx ( 0 ); psIdx < PairSetCount; ++ psIdx )
+//			{
+//				unsigned int FirstGlyph ( coverages[subtableOffset][psIdx] );
+//				quint16 PairSetOffset ( toUint16 ( subtableOffset +10 + ( 2 * psIdx ) ) +  subtableOffset );
+//				quint16 PairValueCount ( toUint16 ( PairSetOffset ) );
+//				quint16 PairValueRecord ( PairSetOffset + 2 );
+//				for ( int pvIdx ( 0 );pvIdx < PairValueCount; ++pvIdx )
+//				{
+//					quint16 recordBase ( PairValueRecord + ( ( 2 + 2 + 2 ) * pvIdx ) );
+//					quint16 SecondGlyph ( toUint16 ( recordBase ) );
+//					qint16 Value1 ( toInt16 ( recordBase + 2 ) );
+//					pairs[FirstGlyph][SecondGlyph] = double ( Value1 );
+
+//				}
+
+//			}
+//		}
+//		else if ( ValueFormat1 && ( !ValueFormat2 ) )
+//		{
+//			for ( int psIdx ( 0 ); psIdx < PairSetCount; ++ psIdx )
+//			{
+//				unsigned int FirstGlyph ( coverages[subtableOffset][psIdx] );
+//				quint16 PairSetOffset ( toUint16 ( subtableOffset +10 + ( 2 * psIdx ) ) +  subtableOffset );
+//				quint16 PairValueCount ( toUint16 ( PairSetOffset ) );
+//				quint16 PairValueRecord ( PairSetOffset + 2 );
+//				for ( int pvIdx ( 0 );pvIdx < PairValueCount; ++pvIdx )
+//				{
+//					quint16 recordBase ( PairValueRecord + ( ( 2 + 2 ) * pvIdx ) );
+//					quint16 SecondGlyph ( toUint16 ( recordBase ) );
+//					qint16 Value1 ( toInt16 ( recordBase + 2 ) );
+//					pairs[FirstGlyph][SecondGlyph] = double ( Value1 );
+
+//				}
+
+//			}
+//		}
+//		else
+//		{
+//			qDebug() <<"ValueFormat1 is null or both ValueFormat1 and ValueFormat2 are null";
+//		}
+
+//	}
+//	else if ( PosFormat == 2 )
+//	{
+//		quint16 ValueFormat1 ( toUint16 ( subtableOffset +4 ) );
+//		quint16 ValueFormat2 ( toUint16 ( subtableOffset +6 ) );
+//		quint16 ClassDef1 ( toUint16 ( subtableOffset +8 )  + subtableOffset );
+//		quint16 ClassDef2 ( toUint16 ( subtableOffset +10 ) + subtableOffset );
+//		quint16 Class1Count ( toUint16 ( subtableOffset +12 ) );
+//		quint16 Class2Count ( toUint16 ( subtableOffset +14 ) );
+//		quint16 Class1Record ( subtableOffset +16 );
+
+//		// first extract classses
+//		ClassDefTable Class1Data ( getClass ( ClassDef1 , subtableOffset ) );
+//		ClassDefTable Class2Data ( getClass ( ClassDef2 , subtableOffset ) );
+
+//		if ( ValueFormat1 && ValueFormat2 )
+//		{
+//			for ( quint16 C1 ( 0 );C1 < Class1Count; ++C1 )
+//			{
+//				QList<quint16> Class1 ( Class1Data[C1] );
+//				quint16 Class2Record ( Class1Record + ( C1 * ( 2 * 2 * Class2Count ) ) );
+//				for ( quint16 C2 ( 0 );C2 < Class2Count; ++C2 )
+//				{
+//					qint16 Value1 ( toInt16 ( Class2Record + ( C2 * ( 2 * 2 ) ) ) );
+//					QList<quint16> Class2 ( Class2Data[C2] );
+//					// keep it barbarian :D
+//					foreach ( quint16 FirstGlyph, Class1 )
+//					{
+//						foreach ( quint16 SecondGlyph, Class2 )
+//						{
+//							if ( Value1 )
+//								pairs[FirstGlyph][SecondGlyph] = double ( Value1 );
+//						}
+//					}
+//				}
+//			}
+//		}
+//		else if ( ValueFormat1 && ( !ValueFormat2 ) )
+//		{
+//			for ( quint16 C1 ( 0 );C1 < Class1Count; ++C1 )
+//			{
+//				QString cdbg ( QString::number ( C1 ).rightJustified ( 5,QChar ( 32 ) ) );
+//				QList<quint16> Class1 ( Class1Data[C1] );
+//				quint16 Class2Record ( Class1Record + ( C1 * ( 2 * Class2Count ) ) );
+//				for ( quint16 C2 ( 0 );C2 < Class2Count; ++C2 )
+//				{
+//					qint16 Value1 ( toInt16 ( Class2Record + ( C2 * 2 ) ) );
+//					QList<quint16> Class2 ( Class2Data[C2] );
+
+//					foreach ( quint16 FirstGlyph, Class1 )
+//					{
+//						foreach ( quint16 SecondGlyph, Class2 )
+//						{
+//							if ( Value1 )
+//								pairs[FirstGlyph][SecondGlyph] = double ( Value1 );
+//						}
+//					}
+//				}
+//			}
+//		}
+//		else
+//		{
+//			qDebug() <<"ValueFormat1 is null or both ValueFormat1 and ValueFormat2 are null";
+//		}
+
+//	}
+//	else
+//		qDebug() <<"unknown PosFormat"<<PosFormat;
+//}
+
+//KernFeature::ClassDefTable KernFeature::getClass ( quint16 classDefOffset, quint16 coverageId )
+//{
+//	ClassDefTable ret;
+//	ret[0] = coverages[coverageId];
+//	quint16 ClassFormat ( toUint16 ( classDefOffset ) );
+//	if ( ClassFormat == 1 )
+//	{
+//		quint16 StartGlyph ( toUint16 ( classDefOffset +2 ) );
+//		quint16 GlyphCount ( toUint16 ( classDefOffset +4 ) );
+//		quint16 ClassValueArray ( classDefOffset + 6 );
+
+//		for ( quint16 CV ( 0 );CV < GlyphCount; ++CV )
+//		{
+//			ret[0].removeAll ( StartGlyph + CV );
+//			ret[ toUint16 ( ClassValueArray + ( CV * 2 ) ) ] << StartGlyph + CV;
+//		}
+//	}
+//	else if ( ClassFormat == 2 )
+//	{
+//		quint16 ClassRangeCount ( toUint16 ( classDefOffset + 2 ) );
+//		quint16 ClassRangeRecord ( classDefOffset + 4 );
+//		for ( int CRR ( 0 ); CRR < ClassRangeCount; ++CRR )
+//		{
+//			quint16 Start ( toUint16 ( ClassRangeRecord + ( CRR * 6 ) ) );
+//			quint16 End ( toUint16 ( ClassRangeRecord + ( CRR * 6 ) + 2 ) );
+//			quint16 Class ( toUint16 ( ClassRangeRecord + ( CRR * 6 ) + 4 ) );
+
+//			for ( quint16 gl ( Start ); gl <= End; ++gl )
+//			{
+//				ret[0].removeAll ( gl );
+//				ret[Class] << gl;
+//			}
+//		}
+//	}
+//	else
+//		qDebug() <<"Unknown Class Table type";
+
+//	return ret;
+//}
+
+//quint16 KernFeature::toUint16 ( quint16 index )
+//{
+//	if ( ( index + 2 ) > GPOSTableRaw.count() )
+//	{
+//		qDebug() << "HORROR!" << index << GPOSTableRaw.count() << FontName ;
+//		// Rather no kerning at all than random kerning
+//		// 		m_valid = false;
+//		return 0;
+//	}
+//	// FIXME I just do not know how it has to be done *properly*
+//	quint16 c1 ( GPOSTableRaw.at ( index ) );
+//	quint16 c2 ( GPOSTableRaw.at ( index + 1 ) );
+//	c1 &= 0xFF;
+//	c2 &= 0xFF;
+//	quint16 ret ( ( c1 << 8 ) | c2 );
+//	return ret;
+//}
+
+//qint16 KernFeature::toInt16 ( quint16 index )
+//{
+//	if ( ( index + 2 ) > GPOSTableRaw.count() )
+//	{
+//		return 0;
+//	}
+//	// FIXME I just do not know how it has to be done *properly*
+//	quint16 c1 ( GPOSTableRaw.at ( index ) );
+//	quint16 c2 ( GPOSTableRaw.at ( index + 1 ) );
+//	c1 &= 0xFF;
+//	c2 &= 0xFF;
+//	qint16 ret ( ( c1 << 8 ) | c2 );
+//	return ret;
+//}
 
 
 namespace
@@ -493,14 +499,13 @@
 				{
 					QString feName(tagToString(feature_tags[feIdx]));
 					qDebug()<<"\t\t\tFeature:"<<feName;
-					FontFeatureSet::Feature& f = featuresList[feName];
+					FontFeatureSet::Feature f;
 
 					f.name = feName;
 					f.type = (table == HB_TAG('G','P','O','S')) ? FontFeatureSet::Pos :  FontFeatureSet::Sub;
-					f.lang.append(tagToString(language_tags[laIdx]));
-					f.script.append(tagToString(script_tags[scIdx]));
-
-					qDebug()<<ftface->family_name<<ftface->style_name <<feName<< tagToString(script_tags[scIdx])<<tagToString(language_tags[laIdx])  ;
+					f.lang = tagToString(language_tags[laIdx]);
+					f.script = tagToString(script_tags[scIdx]);
+					featuresList << f;
 				}
 				delete[] feature_tags;
 			}
@@ -514,7 +519,7 @@
 QList<FontFeatureSet::Feature> TTFFeatureSet::features(FeatureType type) const
 {
 	QList<FontFeatureSet::Feature> ret;
-	foreach(FontFeatureSet::Feature f, featuresList.values())
+	foreach(FontFeatureSet::Feature f, featuresList)
 	{
 		if(f.type == type)
 			ret << f;
@@ -524,40 +529,40 @@
 
 // TODO move it to a better place
 QMap<QString, QPair<hb_tag_t, hb_tag_t> > ScFace_ttf::scLangToTags;
+QMap<QString, LanguageCodes> ScFace_ttf::icuLangList;
+QMap<QString, ScriptCodes> ScFace_ttf::scriptTagToICUCode;
 
 ScFace_ttf::ScFace_ttf ( QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face )
 	: FtFace ( fam, sty, alt, scname, psname, path, face )
 {
 	formatCode = ScFace::SFNT;
-	kernFeature = 0;
 	featureSet = 0;
+	icuFont = 0;
 	fillLangToTag();
 }
 
 ScFace_ttf::~ ScFace_ttf()
 {
-	if ( kernFeature )
-		delete kernFeature;
 }
 
 
 void ScFace_ttf::load() const
 {
 	FtFace::load();
-	if ( !kernFeature )
-		kernFeature = new KernFeature ( ftFace() );
 	if(!featureSet)
 		featureSet = new TTFFeatureSet( ftFace() );
+	if(!icuFont)
+		icuFont = new ScICUFont(ftFace());
 }
 
 void ScFace_ttf::unload() const
 {
-	if ( kernFeature )
-		delete kernFeature;
 	if(featureSet)
 		delete featureSet;
+	if(icuFont)
+		delete icuFont;
+	icuFont = 0;
 	featureSet = 0;
-	kernFeature = 0;
 	FtFace::unload();
 }
 
@@ -728,35 +733,102 @@
 
 qreal ScFace_ttf::glyphKerning ( uint gl1, uint gl2, qreal sz ) const
 {
-	if ( kernFeature->isValid() )
-	{
-		return kernFeature->getPairValue ( gl1,gl2 ) / m_uniEM * sz;
-
-	}
-	else
-		return FtFace::glyphKerning ( gl1, gl2, sz );
-}
-
-int ScFace_ttf::shapeText(GlyphStore* gs) const
-{
-	hb_face_t * face = hb_ft_face_create(ftFace(), releaseFaceForHB );
-	hb_font_t * font = hb_ft_font_create (ftFace(), releaseFaceForHB);
-	// we'll make a first try with required features liga & kern
+	return FtFace::glyphKerning ( gl1, gl2, sz );
+}
+
+int ScFace_ttf::shapeText(GlyphStore* gs, unsigned int item) const
+{
 	unsigned int itemCount(gs->nrOfItems());
+	if(item >= itemCount)
+		return -1;
 	const TextStore * story(gs->story());
-	for(unsigned int it(0); it < itemCount; ++it)
-	{
-		hb_buffer_t * buf = hb_buffer_create(gs->itemCharCount(it));
+	QString language(story->charStyle(gs->itemTextPosition(item)).language());
+	bool isAuto(story->charStyle(gs->itemTextPosition(item)).autoShape());
+	double fSize(story->charStyle(gs->itemTextPosition(item)).fontSize() /10.0);
+	if(isAuto)
+	{
+		LanguageManager *lm(LanguageManager::instance());
+		hb_tag_t scriptTag = scLangToTags[language].first;
+		LEErrorCode err(LE_NO_ERROR);
+		LayoutEngine * icuLE = LayoutEngine::layoutEngineFactory( icuFont,
+									  scriptTagToICUCode.value( tagToString(scriptTag) ),
+									  icuLangList.value(lm->getIsoLangFromAbbr(lm->getAbbrevFromLang(language))),
+									  err);
+		err = LE_NO_ERROR;
+		int sCount (gs->itemCharCount(item));
+		LEUnicode16 *ts = new LEUnicode[sCount];
+		unsigned int end(gs->itemTextPosition(item) + gs->itemCharCount(item));
+		for(unsigned int ci(gs->itemTextPosition(item)); ci < end; ++ci)
+		{
+			ts[ci] = story->text(ci,1).at(0).unicode() ;
+		}
+		icuLE->reset();
+		int glAllocated = icuLE->layoutChars( ts, 0, sCount , sCount, false, 0, 0, err );
+
+		LEGlyphID *glyphs    = new LEGlyphID[glAllocated];
+		le_int32 *indices   = new le_int32[glAllocated];
+		float     *positions = new float[ ( glAllocated * 2 ) + 2];
+		icuLE->getGlyphs ( glyphs, err );
+		icuLE->getCharIndices ( indices, err );
+		icuLE->getGlyphPositions ( positions, err );
+		float stackX ( 0.0 );
+		float stackY ( 0.0 );
+		QList<GlyphLayout> glList;
+		QList<le_int32> charList;
+		double sHeight((m_ascent - m_descent) * fSize);
+
+		for ( int gIdx ( 0 ); gIdx < glAllocated ; ++gIdx )
+		{
+			if(glyphs[gIdx] != 0xFFFF)
+			{
+				GlyphLayout curGlyph;
+				curGlyph.glyph = glyphs[gIdx];
+				curGlyph.xadvance = (positions[ ( gIdx + 1 ) * 2] * fSize / m_uniEM) - stackX;
+				curGlyph.yoffset = ((stackY - positions[ ( ( gIdx + 1 ) * 2 ) + 1]) * fSize / m_uniEM) + sHeight;
+				curGlyph.xoffset = curGlyph.yadvance = 0;
+				stackX +=  curGlyph.xadvance;
+				stackY = positions[ ( ( gIdx + 1 ) * 2 ) + 1];
+				glList << curGlyph;
+				charList << indices[gIdx];
+				qDebug()<<"icu"<<story->text(indices[gIdx],1)<< curGlyph.glyph <<curGlyph.xadvance <<curGlyph.yoffset ;
+			}
+		}
+		icuLE->reset();
+
+		delete  ts;
+		delete  glyphs;
+		delete  indices;
+		delete  positions;
+		gs->itemSetGlyphCount(item, glList.count());
+		GlyphLayout* curGlyph(gs->itemGlyphStart(item));
+		for(unsigned int i(0); i < glList.count(); ++i)
+		{
+			const GlyphLayout& g(glList.at(i));
+			const le_int32& c(charList.at(i));
+			curGlyph->glyph = g.glyph;
+			curGlyph->xadvance = g.xadvance;
+			curGlyph->xoffset = g.xoffset;
+			curGlyph->yadvance = g.yadvance;
+			curGlyph->yoffset = g.yoffset;
+			gs->markCluster(item, c , curGlyph);
+			++curGlyph;
+		}
+
+
+	}
+	else // FIXME_OIF should be able to mix auto and "manual"
+	{
+		hb_face_t * face = hb_ft_face_create(ftFace(), releaseFaceForHB );
+		hb_font_t * font = hb_ft_font_create (ftFace(), releaseFaceForHB);
+		hb_buffer_t * buf = hb_buffer_create(gs->itemCharCount(item));
 		hb_buffer_clear(buf);
 		hb_buffer_clear_positions(buf);
 		ScHBFunctions::setBufferFunctions(buf);
 		hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
-		unsigned int end(gs->itemTextPosition(it) + gs->itemCharCount(it));
-		QString language(story->charStyle(gs->itemTextPosition(it)).language());
-		double fSize(story->charStyle(gs->itemTextPosition(it)).fontSize() /10.0);
+		unsigned int end(gs->itemTextPosition(item) + gs->itemCharCount(item));
 		hb_font_set_scale(font, fSize * 1000, fSize * 1000);
 		unsigned int counterP(0);
-		for(unsigned int ci(gs->itemTextPosition(it)); ci < end; ++ci)
+		for(unsigned int ci(gs->itemTextPosition(item)); ci < end; ++ci)
 		{
 			unsigned int gIndex(char2CMap(story->text(ci,1).at(0)));
 			hb_buffer_add_glyph(buf, gIndex, 0x1, ci);
@@ -769,22 +841,22 @@
 		}
 
 		// DEBUGGING
-		hb_position_t  Txadv = (hb_buffer_get_glyph_positions(buf)->x_offset);
-		hb_position_t  oxadv = ((hb_buffer_get_glyph_positions(buf) + 1)->x_offset);
+//		hb_position_t  Txadv = (hb_buffer_get_glyph_positions(buf)->x_offset);
+//		hb_position_t  oxadv = ((hb_buffer_get_glyph_positions(buf) + 1)->x_offset);
 		// EOD
 
-		QList<unsigned int> gli(getlookupIndex("GSUB", language , "liga"));
+		QList<unsigned int> gli(getlookupIndex("GSUB", language ));
 		foreach(unsigned int lookupIdx, gli)
 		{
 			if(!hb_ot_layout_substitute_lookup(face, buf, lookupIdx, 0x1))
-				qDebug()<<"Failed to apply lookup"<< lookupIdx<< "[liga] to"<<family<<style;
-		}
-
-		QList<unsigned int> pli(getlookupIndex("GPOS", language, "kern"));
+				qDebug()<<"Failed to apply lookup"<< lookupIdx<< "to"<<family<<style;
+		}
+
+		QList<unsigned int> pli(getlookupIndex("GPOS", language));
 		foreach(unsigned int lookupIdx, pli)
 		{
 			if(!hb_ot_layout_position_lookup(font, face, buf, lookupIdx, 0x1))
-				qDebug()<<"Failed to apply lookup"<< lookupIdx<< "[kern] to"<<family<<style;
+				qDebug()<<"Failed to apply lookup"<< lookupIdx<< "to"<<family<<style;
 		}
 
 //		hb_ot_layout_position_finish(font,face,buf);
@@ -793,8 +865,8 @@
 		hb_glyph_info_t * gInfos = hb_buffer_get_glyph_infos (buf);
 		hb_glyph_position_t * gPositions = hb_buffer_get_glyph_positions (buf);
 
-		gs->itemSetGlyphCount(it, bLen);
-		GlyphLayout* curGlyph(gs->itemGlyphStart(it));
+		gs->itemSetGlyphCount(item, bLen);
+		GlyphLayout* curGlyph(gs->itemGlyphStart(item));
 		for(unsigned int bIdx(0); bIdx < bLen; ++bIdx)
 		{
 			hb_glyph_info_t  gi = gInfos[bIdx];
@@ -805,7 +877,7 @@
 			curGlyph->yoffset = gp.y_offset;
 			curGlyph->glyph = gi.codepoint;
 
-			gs->markCluster(it, gi.cluster, curGlyph);
+			gs->markCluster(item, gi.cluster, curGlyph);
 
 			qDebug()<<"ScFace_ttf::shapeText:" <<curGlyph->glyph <<glyphWidth(gi.codepoint, fSize) <<curGlyph->xadvance <<curGlyph->xoffset;
 
@@ -828,7 +900,24 @@
 		hb_tag_t langTag = scLangToTags[language].second;
 		if(feature.isEmpty())
 		{
-
+			// If no specific feature has been asked for, we return required feature for this language.
+			hb_face_t * face = hb_ft_face_create(ftFace(), releaseFaceForHB );
+			unsigned int scriptIndex(0);
+			unsigned int languageIndex(0);
+			unsigned int featureIndex(0);
+			hb_ot_layout_table_find_script(face, t,scriptTag, &scriptIndex);
+			if(!hb_ot_layout_script_find_language(face, t, scriptIndex, langTag, &languageIndex))
+				hb_ot_layout_script_find_language(face, t, scriptIndex, HB_OT_TAG_DEFAULT_LANGUAGE, &languageIndex);
+			hb_ot_layout_language_get_required_feature_index(face, t, scriptIndex, languageIndex, &featureIndex);
+			unsigned int lookupCount(hb_ot_layout_feature_get_lookup_indexes (face,t,  featureIndex,0, 0 ,0));
+			unsigned int * lookup_indexes = new unsigned int[lookupCount];
+			hb_ot_layout_feature_get_lookup_indexes (face,t,  featureIndex,0, &lookupCount, lookup_indexes);
+
+			QList<unsigned int> ret;
+			for(unsigned int ui(0); ui < lookupCount; ++ui)
+				ret << lookup_indexes[ui];
+			delete lookup_indexes;
+			return ret;
 		}
 		else
 		{
@@ -850,7 +939,6 @@
 				unsigned int scriptIndex(0);
 				unsigned int languageIndex(0);
 				unsigned int featureIndex(0);
-				unsigned int lookupIndex(0);
 				hb_ot_layout_table_find_script(face, t,scriptTag, &scriptIndex);
 				if(!hb_ot_layout_script_find_language(face, t, scriptIndex, langTag, &languageIndex))
 					hb_ot_layout_script_find_language(face, t, scriptIndex, HB_OT_TAG_DEFAULT_LANGUAGE, &languageIndex);
@@ -884,4 +972,181 @@
 		scLangToTags[lm->getLangFromTransLang(lang)] = qMakePair(HB_TAG('l','a','t','n'),
 									 hb_ot_tag_from_language(hb_language_from_string(abbr.toAscii().data())));
 	}
-}
+
+	icuLangList.insert(QString("afk"), afkLanguageCode);
+	icuLangList.insert(QString("ara"), araLanguageCode);
+	icuLangList.insert(QString("asm"), asmLanguageCode);
+	icuLangList.insert(QString("bel"), belLanguageCode);
+	icuLangList.insert(QString("ben"), benLanguageCode);
+	icuLangList.insert(QString("bgr"), bgrLanguageCode);
+	icuLangList.insert(QString("cat"), catLanguageCode);
+	icuLangList.insert(QString("che"), cheLanguageCode);
+	icuLangList.insert(QString("cop"), copLanguageCode);
+	icuLangList.insert(QString("csy"), csyLanguageCode);
+	icuLangList.insert(QString("dan"), danLanguageCode);
+	icuLangList.insert(QString("deu"), deuLanguageCode);
+	icuLangList.insert(QString("dzn"), dznLanguageCode);
+	icuLangList.insert(QString("ell"), ellLanguageCode);
+	icuLangList.insert(QString("eng"), engLanguageCode);
+	icuLangList.insert(QString("esp"), espLanguageCode);
+	icuLangList.insert(QString("eti"), etiLanguageCode);
+	icuLangList.insert(QString("euq"), euqLanguageCode);
+	icuLangList.insert(QString("far"), farLanguageCode);
+	icuLangList.insert(QString("fin"), finLanguageCode);
+	icuLangList.insert(QString("fra"), fraLanguageCode);
+	icuLangList.insert(QString("gae"), gaeLanguageCode);
+	icuLangList.insert(QString("guj"), gujLanguageCode);
+	icuLangList.insert(QString("hau"), hauLanguageCode);
+	icuLangList.insert(QString("hin"), hinLanguageCode);
+	icuLangList.insert(QString("hrv"), hrvLanguageCode);
+	icuLangList.insert(QString("hun"), hunLanguageCode);
+	icuLangList.insert(QString("hye"), hyeLanguageCode);
+	icuLangList.insert(QString("ind"), indLanguageCode);
+	icuLangList.insert(QString("ita"), itaLanguageCode);
+	icuLangList.insert(QString("iwr"), iwrLanguageCode);
+	icuLangList.insert(QString("jan"), janLanguageCode);
+	icuLangList.insert(QString("jii"), jiiLanguageCode);
+	icuLangList.insert(QString("kan"), kanLanguageCode);
+	icuLangList.insert(QString("khm"), khmLanguageCode);
+	icuLangList.insert(QString("kok"), kokLanguageCode);
+	icuLangList.insert(QString("kor"), korLanguageCode);
+	icuLangList.insert(QString("ksh"), kshLanguageCode);
+	icuLangList.insert(QString("mal"), malLanguageCode);
+	icuLangList.insert(QString("mar"), marLanguageCode);
+	icuLangList.insert(QString("mlr"), mlrLanguageCode);
+	icuLangList.insert(QString("mng"), mngLanguageCode);
+	icuLangList.insert(QString("mni"), mniLanguageCode);
+	icuLangList.insert(QString("mts"), mtsLanguageCode);
+	icuLangList.insert(QString("nep"), nepLanguageCode);
+	icuLangList.insert(QString("nld"), nldLanguageCode);
+	icuLangList.insert(QString("ori"), oriLanguageCode);
+	icuLangList.insert(QString("pas"), pasLanguageCode);
+	icuLangList.insert(QString("plk"), plkLanguageCode);
+	icuLangList.insert(QString("ptg"), ptgLanguageCode);
+	icuLangList.insert(QString("rom"), romLanguageCode);
+	icuLangList.insert(QString("rus"), rusLanguageCode);
+	icuLangList.insert(QString("san"), sanLanguageCode);
+	icuLangList.insert(QString("sky"), skyLanguageCode);
+	icuLangList.insert(QString("slv"), slvLanguageCode);
+	icuLangList.insert(QString("snd"), sndLanguageCode);
+	icuLangList.insert(QString("snh"), snhLanguageCode);
+	icuLangList.insert(QString("sqi"), sqiLanguageCode);
+	icuLangList.insert(QString("srb"), srbLanguageCode);
+	icuLangList.insert(QString("sve"), sveLanguageCode);
+	icuLangList.insert(QString("syr"), syrLanguageCode);
+	icuLangList.insert(QString("tam"), tamLanguageCode);
+	icuLangList.insert(QString("tel"), telLanguageCode);
+	icuLangList.insert(QString("tha"), thaLanguageCode);
+	icuLangList.insert(QString("tib"), tibLanguageCode);
+	icuLangList.insert(QString("trk"), trkLanguageCode);
+	icuLangList.insert(QString("urd"), urdLanguageCode);
+	icuLangList.insert(QString("wel"), welLanguageCode);
+	icuLangList.insert(QString("zhp"), zhpLanguageCode);
+	icuLangList.insert(QString("zhs"), zhsLanguageCode);
+	icuLangList.insert(QString("zht"), zhtLanguageCode);
+
+	scriptTagToICUCode["zyyy"] = zyyyScriptCode  ;
+	scriptTagToICUCode["qaai"] = qaaiScriptCode  ;
+	scriptTagToICUCode["arab"] = arabScriptCode  ;
+	scriptTagToICUCode["armn"] = armnScriptCode  ;
+	scriptTagToICUCode["beng"] = bengScriptCode  ;
+	scriptTagToICUCode["bopo"] = bopoScriptCode  ;
+	scriptTagToICUCode["cher"] = cherScriptCode  ;
+	scriptTagToICUCode["copt"] = coptScriptCode  ;
+	scriptTagToICUCode["cyrl"] = cyrlScriptCode  ;
+	scriptTagToICUCode["dsrt"] = dsrtScriptCode  ;
+	scriptTagToICUCode["deva"] = devaScriptCode  ;
+	scriptTagToICUCode["ethi"] = ethiScriptCode  ;
+	scriptTagToICUCode["geor"] = georScriptCode  ;
+	scriptTagToICUCode["goth"] = gothScriptCode  ;
+	scriptTagToICUCode["grek"] = grekScriptCode  ;
+	scriptTagToICUCode["gujr"] = gujrScriptCode  ;
+	scriptTagToICUCode["guru"] = guruScriptCode  ;
+	scriptTagToICUCode["hani"] = haniScriptCode  ;
+	scriptTagToICUCode["hang"] = hangScriptCode  ;
+	scriptTagToICUCode["hebr"] = hebrScriptCode  ;
+	scriptTagToICUCode["hira"] = hiraScriptCode  ;
+	scriptTagToICUCode["knda"] = kndaScriptCode  ;
+	scriptTagToICUCode["kana"] = kanaScriptCode  ;
+	scriptTagToICUCode["khmr"] = khmrScriptCode  ;
+	scriptTagToICUCode["lao "] = laooScriptCode  ;
+	scriptTagToICUCode["latn"] = latnScriptCode  ;
+	scriptTagToICUCode["mlym"] = mlymScriptCode  ;
+	scriptTagToICUCode["mong"] = mongScriptCode  ;
+	scriptTagToICUCode["mymr"] = mymrScriptCode  ;
+	scriptTagToICUCode["ogam"] = ogamScriptCode  ;
+	scriptTagToICUCode["ital"] = italScriptCode  ;
+	scriptTagToICUCode["orya"] = oryaScriptCode  ;
+	scriptTagToICUCode["runr"] = runrScriptCode  ;
+	scriptTagToICUCode["sinh"] = sinhScriptCode  ;
+	scriptTagToICUCode["syrc"] = syrcScriptCode  ;
+	scriptTagToICUCode["taml"] = tamlScriptCode  ;
+	scriptTagToICUCode["telu"] = teluScriptCode  ;
+	scriptTagToICUCode["thaa"] = thaaScriptCode  ;
+	scriptTagToICUCode["thai"] = thaiScriptCode  ;
+	scriptTagToICUCode["tibt"] = tibtScriptCode  ;
+	scriptTagToICUCode["cans"] = cansScriptCode  ;
+	scriptTagToICUCode["yi  "] = yiiiScriptCode  ;
+	scriptTagToICUCode["tglg"] = tglgScriptCode  ;
+	scriptTagToICUCode["hano"] = hanoScriptCode  ;
+	scriptTagToICUCode["buhd"] = buhdScriptCode  ;
+	scriptTagToICUCode["tagb"] = tagbScriptCode  ;
+	scriptTagToICUCode["brai"] = braiScriptCode  ;
+	scriptTagToICUCode["cprt"] = cprtScriptCode  ;
+	scriptTagToICUCode["limb"] = limbScriptCode  ;
+	scriptTagToICUCode["linb"] = linbScriptCode  ;
+	scriptTagToICUCode["osma"] = osmaScriptCode  ;
+	scriptTagToICUCode["shaw"] = shawScriptCode  ;
+	scriptTagToICUCode["tale"] = taleScriptCode  ;
+	scriptTagToICUCode["ugar"] = ugarScriptCode  ;
+	scriptTagToICUCode["hrkt"] = hrktScriptCode  ;
+	scriptTagToICUCode["bugi"] = bugiScriptCode  ;
+	scriptTagToICUCode["glag"] = glagScriptCode  ;
+	scriptTagToICUCode["khar"] = kharScriptCode  ;
+	scriptTagToICUCode["sylo"] = syloScriptCode  ;
+	scriptTagToICUCode["talu"] = taluScriptCode  ;
+	scriptTagToICUCode["tfng"] = tfngScriptCode  ;
+	scriptTagToICUCode["xpeo"] = xpeoScriptCode  ;
+	scriptTagToICUCode["bali"] = baliScriptCode  ;
+	scriptTagToICUCode["batk"] = batkScriptCode  ;
+	scriptTagToICUCode["blis"] = blisScriptCode  ;
+	scriptTagToICUCode["brah"] = brahScriptCode  ;
+	scriptTagToICUCode["cham"] = chamScriptCode  ;
+	scriptTagToICUCode["cirt"] = cirtScriptCode  ;
+	scriptTagToICUCode["cyrs"] = cyrsScriptCode  ;
+	scriptTagToICUCode["egyd"] = egydScriptCode  ;
+	scriptTagToICUCode["egyh"] = egyhScriptCode  ;
+	scriptTagToICUCode["egyp"] = egypScriptCode  ;
+	scriptTagToICUCode["geok"] = geokScriptCode  ;
+	scriptTagToICUCode["hans"] = hansScriptCode  ;
+	scriptTagToICUCode["hant"] = hantScriptCode  ;
+	scriptTagToICUCode["hmng"] = hmngScriptCode  ;
+	scriptTagToICUCode["hung"] = hungScriptCode  ;
+	scriptTagToICUCode["inds"] = indsScriptCode  ;
+	scriptTagToICUCode["java"] = javaScriptCode  ;
+	scriptTagToICUCode["kali"] = kaliScriptCode  ;
+	scriptTagToICUCode["latf"] = latfScriptCode  ;
+	scriptTagToICUCode["latg"] = latgScriptCode  ;
+	scriptTagToICUCode["lepc"] = lepcScriptCode  ;
+	scriptTagToICUCode["lina"] = linaScriptCode  ;
+	scriptTagToICUCode["mand"] = mandScriptCode  ;
+	scriptTagToICUCode["maya"] = mayaScriptCode  ;
+	scriptTagToICUCode["mero"] = meroScriptCode  ;
+	scriptTagToICUCode["nko "] = nkooScriptCode  ;
+	scriptTagToICUCode["orkh"] = orkhScriptCode  ;
+	scriptTagToICUCode["perm"] = permScriptCode  ;
+	scriptTagToICUCode["phag"] = phagScriptCode  ;
+	scriptTagToICUCode["phnx"] = phnxScriptCode  ;
+	scriptTagToICUCode["plrd"] = plrdScriptCode  ;
+	scriptTagToICUCode["roro"] = roroScriptCode  ;
+	scriptTagToICUCode["sara"] = saraScriptCode  ;
+	scriptTagToICUCode["syre"] = syreScriptCode  ;
+	scriptTagToICUCode["syrj"] = syrjScriptCode  ;
+	scriptTagToICUCode["syrn"] = syrnScriptCode  ;
+	scriptTagToICUCode["teng"] = tengScriptCode  ;
+	scriptTagToICUCode["vai "] = vaiiScriptCode  ;
+	scriptTagToICUCode["visp"] = vispScriptCode  ;
+	scriptTagToICUCode["xsux"] = xsuxScriptCode  ;
+	scriptTagToICUCode["zxxx"] = zxxxScriptCode  ;
+	scriptTagToICUCode["zzzz"] = zzzzScriptCode  ;
+}

Modified: branches/ScribusOIF/scribus/fonts/scface_ttf.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/fonts/scface_ttf.h
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scface_ttf.h (original)
+++ branches/ScribusOIF/scribus/fonts/scface_ttf.h Mon Oct 25 20:45:56 2010
@@ -12,80 +12,84 @@
 #include "fonts/fontfeatureset.h"
 
 #include "third_party/harfbuzz/src/hb.h"
+#include "layout/LELanguages.h"
+#include "layout/LEScripts.h"
 
 #include <QMap>
 #include <QPair>
 
-#include FT_TRUETYPE_TABLES_H
-#include FT_TRUETYPE_TAGS_H
+class ScICUFont;
+
+//#include FT_TRUETYPE_TABLES_H
+//#include FT_TRUETYPE_TAGS_H
 
 
-/**
-	An object holding a table of kerning pairs extracted from
-	a kern feature such as found in a GPOS table
- */
-class SCRIBUS_API KernFeature
-{
-	public:
-		/**
-		* Build a ready-to-use kerning pairs table
-		* @param face a valid FT_Face, It won’t be store by KernFeature
-		 */
-		KernFeature ( FT_Face face );
-		KernFeature ( const KernFeature& kf );
-		~KernFeature();
+///** Deprecated, will do regular OpenType processing
+//	An object holding a table of kerning pairs extracted from
+//	a kern feature such as found in a GPOS table
+// */
+//class SCRIBUS_API KernFeature
+//{
+//	public:
+//		/**
+//		* Build a ready-to-use kerning pairs table
+//		* @param face a valid FT_Face, It won’t be store by KernFeature
+//		 */
+//		KernFeature ( FT_Face face );
+//		KernFeature ( const KernFeature& kf );
+//		~KernFeature();
 
-		/**
-		 * Get the kerning value for a pair of glyph indexes.
-		 * @param glyph1 Index of the left glyph in logical order
-		 * @param glyph2 Index of the right glyph in logical order
-		 * @return the unscaled delta to apply to xadvance of the first glyph
-		 */
-		double getPairValue ( unsigned int glyph1, unsigned int glyph2 ) const;
+//		/**
+//		 * Get the kerning value for a pair of glyph indexes.
+//		 * @param glyph1 Index of the left glyph in logical order
+//		 * @param glyph2 Index of the right glyph in logical order
+//		 * @return the unscaled delta to apply to xadvance of the first glyph
+//		 */
+//		double getPairValue ( unsigned int glyph1, unsigned int glyph2 ) const;
 
-		/**
-		 * The table can have been invalidated if something went wrong at any moment.
-		 * @return True if valid, False otherwise.
-		 */
-		bool isValid() const {return m_valid;}
+//		/**
+//		 * The table can have been invalidated if something went wrong at any moment.
+//		 * @return True if valid, False otherwise.
+//		 */
+//		bool isValid() const {return m_valid;}
 
-	private:
-		bool m_valid;
-		QByteArray GPOSTableRaw;
-		QMap<quint16,QList<quint16> > coverages;
-		QMap<quint16, QMap<quint16, double> > pairs;
+//	private:
+//		bool m_valid;
+//		QByteArray GPOSTableRaw;
+//		QMap<quint16,QList<quint16> > coverages;
+//		QMap<quint16, QMap<quint16, double> > pairs;
 
-		void makeCoverage();
-		void makePairs ( quint16 subtableOffset );
+//		void makeCoverage();
+//		void makePairs ( quint16 subtableOffset );
 
-		typedef QMap<quint16, QList<quint16> > ClassDefTable; // <Class , list<GLyph> >
-		ClassDefTable getClass ( quint16 classDefOffset, quint16 coverageId );
-		inline quint16 toUint16 ( quint16 index );
-		inline qint16 toInt16 ( quint16 index );
+//		typedef QMap<quint16, QList<quint16> > ClassDefTable; // <Class , list<GLyph> >
+//		ClassDefTable getClass ( quint16 classDefOffset, quint16 coverageId );
+//		inline quint16 toUint16 ( quint16 index );
+//		inline qint16 toInt16 ( quint16 index );
 
-		enum ValueFormat
-		{
-			XPlacement = 0x0001,
-			YPlacement = 0x0002,
-			XAdvance = 0x0004,
-			YAdvance = 0x0008,
-			XPlaDevice =0x0010,
-			YPlaDevice =0x0020,
-			XAdvDevice =0x0040,
-			YAdvDevice =0x0080
-		};
-		QString FontName;// for debugging purpose
-};
+//		enum ValueFormat
+//		{
+//			XPlacement = 0x0001,
+//			YPlacement = 0x0002,
+//			XAdvance = 0x0004,
+//			YAdvance = 0x0008,
+//			XPlaDevice =0x0010,
+//			YPlaDevice =0x0020,
+//			XAdvDevice =0x0040,
+//			YAdvDevice =0x0080
+//		};
+//		QString FontName;// for debugging purpose
+//};
 
 class SCRIBUS_API TTFFeatureSet : public FontFeatureSet
 {
-	QMap<QString, Feature> featuresList;
+	QList<Feature> featuresList;
 
 public:
 	TTFFeatureSet( FT_Face ftface );
 	QList<Feature> features(FeatureType type) const;
-	bool hasFeature(const QString& f){return featuresList.contains(f);}
-	Feature getFeature(const QString& f){return featuresList.value(f);}
+	bool hasFeature(const QString& f);
+	Feature getFeature(const QString& f);
 };
 
 /*
@@ -111,14 +115,16 @@
 		qreal glyphKerning ( uint gl1, uint gl2, qreal sz ) const;
 
 		TTFFeatureSet * features(FontFeatureSet::FeatureType type) const {return featureSet;}
-		int shapeText( GlyphStore* gs) const;
+		int shapeText( GlyphStore* gs, unsigned int item) const;
 
 	private:
 		static QMap<QString, QPair<hb_tag_t, hb_tag_t> > scLangToTags;
+		static QMap<QString, LanguageCodes> icuLangList;
+		static QMap<QString, ScriptCodes> scriptTagToICUCode;
 		void fillLangToTag();
-		QList<unsigned int> getlookupIndex(const QString& table, const QString& language, const QString& feature) const;
-		mutable KernFeature * kernFeature;
+		QList<unsigned int> getlookupIndex(const QString& table, const QString& language, const QString& feature = QString()) const;
 		mutable TTFFeatureSet * featureSet;
+		mutable ScICUFont * icuFont;
 };
 
 #endif

Modified: branches/ScribusOIF/scribus/langmgr.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/langmgr.cpp
==============================================================================
--- branches/ScribusOIF/scribus/langmgr.cpp (original)
+++ branches/ScribusOIF/scribus/langmgr.cpp Mon Oct 25 20:45:56 2010
@@ -129,6 +129,193 @@
 	langList.insert("uk",       langPair("Ukranian",            QObject::tr( "Ukranian" )) );
 	langList.insert("vi",       langPair("Vietnamese",          QObject::tr( "Vietnamese" )) );
 	langList.insert("cy",       langPair("Welsh",               QObject::tr( "Welsh" )) );
+
+
+	isoLang.insert(QString("aa"), QString("aar"));
+	isoLang.insert(QString("ab"), QString("abk"));
+	isoLang.insert(QString("af"), QString("afr"));
+	isoLang.insert(QString("ak"), QString("aka"));
+	isoLang.insert(QString("sq"), QString("alb"));
+	isoLang.insert(QString("am"), QString("amh"));
+	isoLang.insert(QString("ar"), QString("ara"));
+	isoLang.insert(QString("an"), QString("arg"));
+	isoLang.insert(QString("hy"), QString("arm"));
+	isoLang.insert(QString("as"), QString("asm"));
+	isoLang.insert(QString("av"), QString("ava"));
+	isoLang.insert(QString("ae"), QString("ave"));
+	isoLang.insert(QString("ay"), QString("aym"));
+	isoLang.insert(QString("az"), QString("aze"));
+	isoLang.insert(QString("ba"), QString("bak"));
+	isoLang.insert(QString("bm"), QString("bam"));
+	isoLang.insert(QString("eu"), QString("baq"));
+	isoLang.insert(QString("be"), QString("bel"));
+	isoLang.insert(QString("bn"), QString("ben"));
+	isoLang.insert(QString("bh"), QString("bih"));
+	isoLang.insert(QString("bi"), QString("bis"));
+	isoLang.insert(QString("bs"), QString("bos"));
+	isoLang.insert(QString("br"), QString("bre"));
+	isoLang.insert(QString("bg"), QString("bul"));
+	isoLang.insert(QString("my"), QString("bur"));
+	isoLang.insert(QString("ca"), QString("cat"));
+	isoLang.insert(QString("ch"), QString("cha"));
+	isoLang.insert(QString("ce"), QString("che"));
+	isoLang.insert(QString("zh"), QString("chi"));
+	isoLang.insert(QString("cu"), QString("chu"));
+	isoLang.insert(QString("cv"), QString("chv"));
+	isoLang.insert(QString("kw"), QString("cor"));
+	isoLang.insert(QString("co"), QString("cos"));
+	isoLang.insert(QString("cr"), QString("cre"));
+	isoLang.insert(QString("cs"), QString("cze"));
+	isoLang.insert(QString("da"), QString("dan"));
+	isoLang.insert(QString("dv"), QString("div"));
+	isoLang.insert(QString("nl"), QString("dut"));
+	isoLang.insert(QString("dz"), QString("dzo"));
+	isoLang.insert(QString("en"), QString("eng"));
+	isoLang.insert(QString("eo"), QString("epo"));
+	isoLang.insert(QString("et"), QString("est"));
+	isoLang.insert(QString("ee"), QString("ewe"));
+	isoLang.insert(QString("fo"), QString("fao"));
+	isoLang.insert(QString("fj"), QString("fij"));
+	isoLang.insert(QString("fi"), QString("fin"));
+	isoLang.insert(QString("fr"), QString("fre"));
+	isoLang.insert(QString("fy"), QString("fry"));
+	isoLang.insert(QString("ff"), QString("ful"));
+	isoLang.insert(QString("ka"), QString("geo"));
+	isoLang.insert(QString("de"), QString("ger"));
+	isoLang.insert(QString("gd"), QString("gla"));
+	isoLang.insert(QString("ga"), QString("gle"));
+	isoLang.insert(QString("gl"), QString("glg"));
+	isoLang.insert(QString("gv"), QString("glv"));
+	isoLang.insert(QString("el"), QString("gre"));
+	isoLang.insert(QString("gn"), QString("grn"));
+	isoLang.insert(QString("gu"), QString("guj"));
+	isoLang.insert(QString("ht"), QString("hat"));
+	isoLang.insert(QString("ha"), QString("hau"));
+	isoLang.insert(QString("he"), QString("heb"));
+	isoLang.insert(QString("hz"), QString("her"));
+	isoLang.insert(QString("hi"), QString("hin"));
+	isoLang.insert(QString("ho"), QString("hmo"));
+	isoLang.insert(QString("hr"), QString("hrv"));
+	isoLang.insert(QString("hu"), QString("hun"));
+	isoLang.insert(QString("ig"), QString("ibo"));
+	isoLang.insert(QString("is"), QString("ice"));
+	isoLang.insert(QString("io"), QString("ido"));
+	isoLang.insert(QString("ii"), QString("iii"));
+	isoLang.insert(QString("iu"), QString("iku"));
+	isoLang.insert(QString("ie"), QString("ile"));
+	isoLang.insert(QString("ia"), QString("ina"));
+	isoLang.insert(QString("id"), QString("ind"));
+	isoLang.insert(QString("ik"), QString("ipk"));
+	isoLang.insert(QString("it"), QString("ita"));
+	isoLang.insert(QString("jv"), QString("jav"));
+	isoLang.insert(QString("ja"), QString("jpn"));
+	isoLang.insert(QString("kl"), QString("kal"));
+	isoLang.insert(QString("kn"), QString("kan"));
+	isoLang.insert(QString("ks"), QString("kas"));
+	isoLang.insert(QString("kr"), QString("kau"));
+	isoLang.insert(QString("kk"), QString("kaz"));
+	isoLang.insert(QString("km"), QString("khm"));
+	isoLang.insert(QString("ki"), QString("kik"));
+	isoLang.insert(QString("rw"), QString("kin"));
+	isoLang.insert(QString("ky"), QString("kir"));
+	isoLang.insert(QString("kv"), QString("kom"));
+	isoLang.insert(QString("kg"), QString("kon"));
+	isoLang.insert(QString("ko"), QString("kor"));
+	isoLang.insert(QString("kj"), QString("kua"));
+	isoLang.insert(QString("ku"), QString("kur"));
+	isoLang.insert(QString("lo"), QString("lao"));
+	isoLang.insert(QString("la"), QString("lat"));
+	isoLang.insert(QString("lv"), QString("lav"));
+	isoLang.insert(QString("li"), QString("lim"));
+	isoLang.insert(QString("ln"), QString("lin"));
+	isoLang.insert(QString("lt"), QString("lit"));
+	isoLang.insert(QString("lb"), QString("ltz"));
+	isoLang.insert(QString("lu"), QString("lub"));
+	isoLang.insert(QString("lg"), QString("lug"));
+	isoLang.insert(QString("mk"), QString("mac"));
+	isoLang.insert(QString("mh"), QString("mah"));
+	isoLang.insert(QString("ml"), QString("mal"));
+	isoLang.insert(QString("mi"), QString("mao"));
+	isoLang.insert(QString("mr"), QString("mar"));
+	isoLang.insert(QString("ms"), QString("may"));
+	isoLang.insert(QString("mg"), QString("mlg"));
+	isoLang.insert(QString("mt"), QString("mlt"));
+	isoLang.insert(QString("mn"), QString("mon"));
+	isoLang.insert(QString("na"), QString("nau"));
+	isoLang.insert(QString("nv"), QString("nav"));
+	isoLang.insert(QString("nr"), QString("nbl"));
+	isoLang.insert(QString("nd"), QString("nde"));
+	isoLang.insert(QString("ng"), QString("ndo"));
+	isoLang.insert(QString("ne"), QString("nep"));
+	isoLang.insert(QString("nn"), QString("nno"));
+	isoLang.insert(QString("nb"), QString("nob"));
+	isoLang.insert(QString("no"), QString("nor"));
+	isoLang.insert(QString("ny"), QString("nya"));
+	isoLang.insert(QString("oc"), QString("oci"));
+	isoLang.insert(QString("oj"), QString("oji"));
+	isoLang.insert(QString("or"), QString("ori"));
+	isoLang.insert(QString("om"), QString("orm"));
+	isoLang.insert(QString("os"), QString("oss"));
+	isoLang.insert(QString("pa"), QString("pan"));
+	isoLang.insert(QString("fa"), QString("per"));
+	isoLang.insert(QString("pi"), QString("pli"));
+	isoLang.insert(QString("pl"), QString("pol"));
+	isoLang.insert(QString("pt"), QString("por"));
+	isoLang.insert(QString("ps"), QString("pus"));
+	isoLang.insert(QString("qu"), QString("que"));
+	isoLang.insert(QString("rm"), QString("roh"));
+	isoLang.insert(QString("ro"), QString("rum"));
+	isoLang.insert(QString("rn"), QString("run"));
+	isoLang.insert(QString("ru"), QString("rus"));
+	isoLang.insert(QString("sg"), QString("sag"));
+	isoLang.insert(QString("sa"), QString("san"));
+	isoLang.insert(QString("si"), QString("sin"));
+	isoLang.insert(QString("sk"), QString("slo"));
+	isoLang.insert(QString("sl"), QString("slv"));
+	isoLang.insert(QString("se"), QString("sme"));
+	isoLang.insert(QString("sm"), QString("smo"));
+	isoLang.insert(QString("sn"), QString("sna"));
+	isoLang.insert(QString("sd"), QString("snd"));
+	isoLang.insert(QString("so"), QString("som"));
+	isoLang.insert(QString("st"), QString("sot"));
+	isoLang.insert(QString("es"), QString("spa"));
+	isoLang.insert(QString("sc"), QString("srd"));
+	isoLang.insert(QString("sr"), QString("srp"));
+	isoLang.insert(QString("ss"), QString("ssw"));
+	isoLang.insert(QString("su"), QString("sun"));
+	isoLang.insert(QString("sw"), QString("swa"));
+	isoLang.insert(QString("sv"), QString("swe"));
+	isoLang.insert(QString("ty"), QString("tah"));
+	isoLang.insert(QString("ta"), QString("tam"));
+	isoLang.insert(QString("tt"), QString("tat"));
+	isoLang.insert(QString("te"), QString("tel"));
+	isoLang.insert(QString("tg"), QString("tgk"));
+	isoLang.insert(QString("tl"), QString("tgl"));
+	isoLang.insert(QString("th"), QString("tha"));
+	isoLang.insert(QString("bo"), QString("tib"));
+	isoLang.insert(QString("ti"), QString("tir"));
+	isoLang.insert(QString("to"), QString("ton"));
+	isoLang.insert(QString("tn"), QString("tsn"));
+	isoLang.insert(QString("ts"), QString("tso"));
+	isoLang.insert(QString("tk"), QString("tuk"));
+	isoLang.insert(QString("tr"), QString("tur"));
+	isoLang.insert(QString("tw"), QString("twi"));
+	isoLang.insert(QString("ug"), QString("uig"));
+	isoLang.insert(QString("uk"), QString("ukr"));
+	isoLang.insert(QString("ur"), QString("urd"));
+	isoLang.insert(QString("uz"), QString("uzb"));
+	isoLang.insert(QString("ve"), QString("ven"));
+	isoLang.insert(QString("vi"), QString("vie"));
+	isoLang.insert(QString("vo"), QString("vol"));
+	isoLang.insert(QString("cy"), QString("wel"));
+	isoLang.insert(QString("wa"), QString("wln"));
+	isoLang.insert(QString("wo"), QString("wol"));
+	isoLang.insert(QString("xh"), QString("xho"));
+	isoLang.insert(QString("yi"), QString("yid"));
+	isoLang.insert(QString("yo"), QString("yor"));
+	isoLang.insert(QString("za"), QString("zha"));
+	isoLang.insert(QString("zu"), QString("zul"));
+
 }
 
 void LanguageManager::generateInstalledLangList()
@@ -227,6 +414,13 @@
 	return "";
 }
 
+const QString LanguageManager::getIsoLangFromAbbr(QString abbr)
+{
+	if(isoLang.contains(abbr))
+		return isoLang.value(abbr);
+	return QString();
+}
+
 void LanguageManager::fillInstalledStringList(QStringList *stringListToFill, bool addDefaults) 
 {
 	if (stringListToFill)

Modified: branches/ScribusOIF/scribus/langmgr.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/langmgr.h
==============================================================================
--- branches/ScribusOIF/scribus/langmgr.h (original)
+++ branches/ScribusOIF/scribus/langmgr.h Mon Oct 25 20:45:56 2010
@@ -47,6 +47,7 @@
 	const QString getAbbrevFromLang(QString, bool getFromTranslated=true, bool useInstalled=true);
 	const QString getLangFromTransLang(QString lang);
 	const QString getTransLangFromLang(QString lang);
+	const QString getIsoLangFromAbbr(QString abbr);
 	void fillInstalledStringList(QStringList *stringListToFill, bool addDefaults);
 	void printInstalledList();
 	QString numericSequence(QString seq);
@@ -59,6 +60,7 @@
 	QMap<QString, langPair > langList;
 	QMap<QString, QString> installedLangList;
 	QMap<QString, QString> hyphLangList; // <lang abbreviated, dict filename>
+	QMap<QString, QString> isoLang; // <lang abbreviated, iso639-2 abbreviation>
 
 	void generateLangList();
 	void generateInstalledLangList();

Modified: branches/ScribusOIF/scribus/styles/charstyle.attrdefs.cxx
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/styles/charstyle.attrdefs.cxx
==============================================================================
--- branches/ScribusOIF/scribus/styles/charstyle.attrdefs.cxx (original)
+++ branches/ScribusOIF/scribus/styles/charstyle.attrdefs.cxx Mon Oct 25 20:45:56 2010
@@ -37,3 +37,4 @@
 ATTRDEF(QString, fontVariant, FontVariant, "")
 ATTRDEF(ScFace, font, Font, ScFace::none())
 ATTRDEF(QStringList, features, Features, QStringList(CharStyle::INHERIT))
+ATTRDEF(bool, autoShape, AutoShape, true)

Modified: branches/ScribusOIF/scribus/text/boxes.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/text/boxes.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/boxes.cpp (original)
+++ branches/ScribusOIF/scribus/text/boxes.cpp Mon Oct 25 20:45:56 2010
@@ -32,9 +32,10 @@
 
 void BoxGroup::render(ScPainter* p, const RenderOptions& renderOptions) const
 {
+	p->save();
 	p->setPen(Qt::green);
 	p->drawLine(FPoint(x(), y() - m_ascent), FPoint(x()+width(), y() + m_descent));
-	
+	p->restore();
 	for (int i=0; i < m_boxes.count(); ++i)
 	{
 		m_boxes[i]->render(p, renderOptions);
@@ -399,14 +400,45 @@
 void GlyphBox::render(ScPainter* p, const RenderOptions& renderOptions) const
 {
 	int first = m_charStart - m_glyphs->itemTextPosition(m_item);
-	int end = m_charEnd - m_glyphs->itemTextPosition(m_item);
-	GlyphLayout* glyphStart = m_glyphs->itemGlyphStart(m_item);
+	int end = m_charEnd - m_glyphs->itemTextPosition(m_item); // wrong, it asserts that there are as many glyphs as characters
+	// the item to be rendered
+	unsigned int rItem(m_item);
+	unsigned int join(0);
+	// First see if first and end matches begining and end of m_item;
+	if((first == 0) && (end == m_glyphs->itemCharCount(m_item)))
+	{
+		rItem = m_item;
+		join = 0;
+	}
+	// test if the run starts with the item but finishes elsewhere
+	else if((first == 0) && (end != m_glyphs->itemCharCount(m_item)))
+	{
+		rItem = m_item;
+		m_glyphs->splitItem(m_item, end - first);
+		join = 1;
+	}
+	// test if the run does not start with the item but finishes with it
+	else if((first != 0) && (end == m_glyphs->itemCharCount(m_item)))
+	{
+		rItem = m_item + 1;
+		m_glyphs->splitItem(m_item, first);
+		join = 1;
+	}
+	// test if the run does not match the item at all
+	else if((first != 0) && (end != m_glyphs->itemCharCount(m_item)))
+	{
+		rItem = m_item + 1;
+		m_glyphs->splitItem(m_item, first);
+		m_glyphs->splitItem(m_item, end - first);
+		join = 2;
+
+	}
 	const CharStyle& style(m_glyphs->story()->charStyle(m_charStart));
-		
-;
+p->save();
+p->setPen(Qt::lightGray);
 	p->setFillMode(ScPainter::None);
 	p->drawRect(x(), y()-m_ascent, width(), height());
-	
+	p->restore();
 	p->save();
 	p->translate(x(), y());
 	
@@ -433,10 +465,9 @@
 		strokeColor.setAlphaF(shade / 100.0);
 		p->setPen(strokeColor, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
 	}
-	
-	for (int i=first; i < end; ++i)
-	{
-		GlyphLayout* layout = glyphStart + i;
+	GlyphLayout* layout = m_glyphs->itemGlyphStart(rItem);
+	for (unsigned int i(0); i < m_glyphs->itemGlyphCount(rItem); ++i)
+	{
 		uint glyph = layout->glyph;
 		//qDebug() << "render glyph" << glyph << "width" << layout->xadvance  << "font" << style.font().scName();
 		if ((renderOptions.showControls) && 
@@ -483,8 +514,12 @@
 		 }
 		 */	
 		p->translate(layout->xadvance, 0);
+		layout++;
 	}
 	p->restore();
+
+	for(unsigned int j(0); j < join; ++j)
+		m_glyphs->joinItem(m_item);
 }
 
 

Modified: branches/ScribusOIF/scribus/text/glyphstore.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/text/glyphstore.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/glyphstore.cpp (original)
+++ branches/ScribusOIF/scribus/text/glyphstore.cpp Mon Oct 25 20:45:56 2010
@@ -125,8 +125,11 @@
 {
 	ItemData& item(m_items[i]);
 	int nglyphs = item.glyphCount;
-	m_items.insert(i+1, ItemData(item.textPosition + n, item.charCount - n, item.glyphIndex + nglyphs, 	item.glyphCount - nglyphs));
-	item.charCount -= n;
+	int gStart = glyphIndexForCharacter(i, item.textPosition);
+	int gEnd = glyphIndexForCharacter(i, item.textPosition + n);
+	item.glyphCount = gEnd - gStart;
+	m_items.insert(i+1, ItemData(item.textPosition + n, item.charCount - n, item.glyphIndex + nglyphs, nglyphs - item.glyphCount));
+	item.charCount = n;
 }
 							   
 void GlyphStore::splitItem(uint i, const Cluster& c)

Modified: branches/ScribusOIF/scribus/text/legacylayout.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15650&path=/branches/ScribusOIF/scribus/text/legacylayout.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/legacylayout.cpp (original)
+++ branches/ScribusOIF/scribus/text/legacylayout.cpp Mon Oct 25 20:45:56 2010
@@ -123,7 +123,7 @@
 	int chst = style.effects() & 1919;
 	uint item = glyphs.addItem(start, end - start);
 
-	style.font().shapeText(&glyphs);
+	style.font().shapeText(&glyphs, item);
 }
 
 /**




More information about the scribus-commit mailing list