r15578 by pierremarc - First ideas around a shaping-enabled ScFace

scribus-commit scribus-commit at lists.scribus.net
Tue Oct 19 18:15:51 CEST 2010


Author: pierremarc
Date: Tue Oct 19 16:15:51 2010
New Revision: 15578

URL: http://scribus.info/websvn/listing.php?repname=Scribus&sc=1&rev=15578
Log:
First ideas around a shaping-enabled ScFace

Added:
    branches/ScribusOIF/scribus/fonts/schbfunctions.cpp
    branches/ScribusOIF/scribus/fonts/schbfunctions.h
Modified:
    branches/ScribusOIF/scribus/fonts/CMakeLists.txt
    branches/ScribusOIF/scribus/fonts/scface.h
    branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
    branches/ScribusOIF/scribus/fonts/scface_ttf.h
    branches/ScribusOIF/scribus/pageitem.cpp
    branches/ScribusOIF/scribus/pageitem.h
    branches/ScribusOIF/scribus/pageitem_textframe.cpp
    branches/ScribusOIF/scribus/pslib.h
    branches/ScribusOIF/scribus/scribusdoc.h
    branches/ScribusOIF/scribus/text/legacylayout.cpp
    branches/ScribusOIF/scribus/text/legacylayout.h

Modified: branches/ScribusOIF/scribus/fonts/CMakeLists.txt
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/fonts/CMakeLists.txt
==============================================================================
--- branches/ScribusOIF/scribus/fonts/CMakeLists.txt (original)
+++ branches/ScribusOIF/scribus/fonts/CMakeLists.txt Tue Oct 19 16:15:51 2010
@@ -11,7 +11,8 @@
   scface_ps.cpp
   scface_ttf.cpp
   scfontmetrics.cpp
-fontfeatureset.cpp
+  schbfunctions.cpp
+  fontfeatureset.cpp
 )
 SET(SCRIBUS_FONTS_LIB "scribus_fonts_lib")
 ADD_LIBRARY(${SCRIBUS_FONTS_LIB} STATIC ${SCRIBUS_FONTS_LIB_SOURCES})

Modified: branches/ScribusOIF/scribus/fonts/scface.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/fonts/scface.h
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scface.h (original)
+++ branches/ScribusOIF/scribus/fonts/scface.h Tue Oct 19 16:15:51 2010
@@ -21,7 +21,6 @@
 */
 
 #include <QString>
-#include <QList>
 //#include <QVector>
 #include <QMap>
 //#include <QArray>
@@ -37,7 +36,7 @@
 	qreal descent;
 };
 
-class ScText;
+class GlyphStore;
 
 /*! \brief Base Class ScFace : This is a total rewrite of the old Foi class.
 
@@ -183,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(const QList<ScText*>& txt) const {return txt.count();}
+		virtual int shapeText(GlyphStore* /*gs*/) const {return 0;}
 
 		// these use the cache:
 		virtual qreal      glyphWidth(uint gl, qreal sz)   const;
@@ -380,8 +379,8 @@
 	/// Return a features Object provided by the font
 	FontFeatureSet * features() { return m->features();}
 
-	/// Process a styled string
-	int shapeText(const QList<ScText*>& txt) const{return m->shapeText(txt);}
+	/// Process a string
+	int shapeText(GlyphStore* gs) const{return m->shapeText(gs);}
 	
 private:
 		

Modified: branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scface_ttf.cpp (original)
+++ branches/ScribusOIF/scribus/fonts/scface_ttf.cpp Tue Oct 19 16:15:51 2010
@@ -17,6 +17,8 @@
 #include "fonts/scface_ttf.h"
 #include "fonts/scfontmetrics.h"
 #include "fonts/fontfeatureset.h"
+#include "fonts/schbfunctions.h"
+#include "text/glyphstore.h"
 #include "util.h"
 #include "scconfig.h"
 #include "sctextstruct.h"
@@ -455,8 +457,11 @@
 	foreach(hb_tag_t table, tables)
 	{
 		unsigned int script_count = hb_ot_layout_table_get_script_count(face, table);
-		hb_tag_t     * script_tags = new hb_tag_t[script_count];
-		hb_ot_layout_table_get_script_tags (face, table, 0, &script_count, script_tags);
+		bool hastDFLTScript(hb_ot_layout_table_find_script(face,table,HB_OT_TAG_DEFAULT_SCRIPT, 0));
+		hb_tag_t     * script_tags = new hb_tag_t[(hastDFLTScript ? script_count + 1 : script_count)];
+		if(hastDFLTScript)
+			script_tags[0] = HB_OT_TAG_DEFAULT_SCRIPT;
+		hb_ot_layout_table_get_script_tags (face, table, 0, &script_count, (hastDFLTScript ? script_tags + 1 :  script_tags));
 		qDebug()<<"Table:"<<tagToString(table)<<"ScriptCount:"<<script_count;
 
 		for(unsigned int scIdx(0); scIdx < script_count; ++scIdx)
@@ -464,8 +469,11 @@
 			unsigned int script_index = 0;
 			hb_ot_layout_table_find_script (face, table, script_tags[scIdx], &script_index);
 			unsigned int language_count = hb_ot_layout_script_get_language_count(face, table, script_index);
-			hb_tag_t      * language_tags =  new hb_tag_t[language_count];
-			hb_ot_layout_script_get_language_tags(face, table, script_index, 0, &language_count , language_tags );
+			bool hasDFLTLang(hb_ot_layout_script_find_language(face, table,script_index, HB_OT_TAG_DEFAULT_LANGUAGE, 0));
+			hb_tag_t      * language_tags =  new hb_tag_t[(hasDFLTLang ? language_count + 1: language_count)];
+			if(hasDFLTLang)
+				language_tags[0] =  HB_OT_TAG_DEFAULT_LANGUAGE;
+			hb_ot_layout_script_get_language_tags(face, table, script_index, 0, &language_count , (hasDFLTLang ? language_tags + 1 : language_tags) );
 			qDebug()<<"\tScript:"<<tagToString(script_tags[scIdx])<<"LanguageCount:"<<language_count;
 
 			for(unsigned int laIdx(0); laIdx < language_count; ++laIdx)
@@ -516,6 +524,7 @@
 	formatCode = ScFace::SFNT;
 	kernFeature = 0;
 	featureSet = 0;
+	fillLangToTag();
 }
 
 ScFace_ttf::~ ScFace_ttf()
@@ -721,15 +730,63 @@
 		return FtFace::glyphKerning ( gl1, gl2, sz );
 }
 
-int ScFace_ttf::shapeText(const QList<ScText *> &txt) const
-{
-
-}
-
-unsigned int ScFace_ttf::getlookupIndex(const QString &table, const QString &language, const QString &feature)
+int ScFace_ttf::shapeText(GlyphStore* gs) const
+{
+	hb_face_t * face = hb_ft_face_create(ftFace(), releaseFaceForHB );
+	// we'll make a first try with required features liga & kern
+	unsigned int itemCount(gs->nrOfItems());
+	const TextStore * story(gs->story());
+	for(unsigned int it(0); it < itemCount; ++it)
+	{
+		hb_buffer_t * buf = hb_buffer_create(gs->itemCharCount(it));
+		ScHBFunctions::setBufferFunctions(buf);
+		unsigned int end(gs->itemTextPosition(it) + gs->itemCharCount(it));
+		for(unsigned int ci(gs->itemTextPosition(it)); ci < end; ++ci)
+		{
+			unsigned int gIndex(char2CMap(story->text(ci,1).at(0)));
+			hb_buffer_add_glyph(buf, gIndex, 0x1, ci);
+		}
+
+		QList<unsigned int> gli(getlookupIndex("GSUB", "English", "liga"));
+		foreach(unsigned int lookupIdx, gli)
+			hb_ot_layout_substitute_lookup(face, buf, lookupIdx, 0);
+
+//	We must wait to get something to build an hb_font, HB will drive me mad
+//		QList<unsigned int> pli(getlookupIndex("GPOS", "English", "kern"));
+//		foreach(unsigned int lookupIdx, pli)
+//			hb_ot_layout_position_lookup(face, buf, lookupIdx, 0);
+
+		hb_ot_layout_position_finish(0,0,buf);
+
+		unsigned int bLen(hb_buffer_get_length(buf));
+		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));
+		for(unsigned int bIdx(0); bIdx < bLen; ++bIdx)
+		{
+			hb_glyph_info_t  gi = gInfos[bIdx];
+			hb_glyph_position_t  gp = gPositions[bIdx];
+			curGlyph->xadvance = gp.x_advance;
+			curGlyph->xoffset = gp.x_offset;
+			curGlyph->yadvance = gp.y_advance;
+			curGlyph->yoffset = gp.y_offset;
+			curGlyph->glyph = gi.codepoint;
+
+			gs->markCluster(it, gi.cluster, curGlyph);
+			++curGlyph;
+		}
+
+		hb_buffer_destroy(buf);
+	}
+
+
+}
+
+QList<unsigned int> ScFace_ttf::getlookupIndex(const QString &table, const QString &language, const QString &feature) const
 {
 	hb_tag_t t = (table == QString("GSUB")) ? HB_OT_TAG_GSUB : HB_OT_TAG_GPOS;
-	fillLangToTag();
 	if(scLangToTags.contains(language))
 	{
 		hb_tag_t scriptTag = scLangToTags[language].first;
@@ -756,11 +813,17 @@
 			hb_ot_layout_table_find_script(face, t,scriptTag, &scriptIndex);
 			hb_ot_layout_script_find_language(face, t, scriptIndex, langTag, &languageIndex);
 			hb_ot_layout_language_find_feature(face, t,scriptIndex, languageIndex, featureTag, &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;
+		}
+	}
+	return QList<unsigned int>();
 }
 
 void ScFace_ttf::fillLangToTag()

Modified: branches/ScribusOIF/scribus/fonts/scface_ttf.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/fonts/scface_ttf.h
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scface_ttf.h (original)
+++ branches/ScribusOIF/scribus/fonts/scface_ttf.h Tue Oct 19 16:15:51 2010
@@ -81,7 +81,8 @@
 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);}
 };
 
 /*
@@ -107,11 +108,11 @@
 		qreal glyphKerning ( uint gl1, uint gl2, qreal sz ) const;
 
 		TTFFeatureSet * features(FontFeatureSet::FeatureType type) const {return featureSet;}
-		int shapeText(const QList<ScText *> &txt) const;
+		int shapeText( GlyphStore* gs) const;
 
 	private:
 		void fillLangToTag();
-		unsigned int getlookupIndex(const QString& table, const QString& language, const QString& feature);
+		QList<unsigned int> getlookupIndex(const QString& table, const QString& language, const QString& feature) const;
 		mutable KernFeature * kernFeature;
 		mutable TTFFeatureSet * featureSet;
 };

Modified: branches/ScribusOIF/scribus/pageitem.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/pageitem.cpp
==============================================================================
--- branches/ScribusOIF/scribus/pageitem.cpp (original)
+++ branches/ScribusOIF/scribus/pageitem.cpp Tue Oct 19 16:15:51 2010
@@ -350,6 +350,8 @@
 		tempImageFile = NULL;
 		isInlineImage = false;
 	}
+
+	textLayout = new TextLayout(&itemText, this);
 }
 
 
@@ -827,6 +829,15 @@
 	}
 	tempImageFile = NULL;
 	isInlineImage = false;
+	textLayout = 0;
+}
+
+PageItem::~PageItem()
+{
+	if (tempImageFile != NULL)
+		delete tempImageFile;
+	if(textLayout)
+		delete textLayout;
 }
 
 void PageItem::setXPos(const double newXPos, bool drawingOnly)

Modified: branches/ScribusOIF/scribus/pageitem.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/pageitem.h
==============================================================================
--- branches/ScribusOIF/scribus/pageitem.h (original)
+++ branches/ScribusOIF/scribus/pageitem.h Tue Oct 19 16:15:51 2010
@@ -223,11 +223,7 @@
 	
 public:
 	PageItem(ScribusDoc *pa, ItemType newType, double x, double y, double w, double h, double w2, QString fill, QString outline);
-	~PageItem()
-	{
-		if (tempImageFile != NULL)
-			delete tempImageFile;
-	}
+	~PageItem();
 
 	static const Xml_string saxxDefaultElem;
 	static void  desaxeRules(const Xml_string& prefixPattern, desaxe::Digester& ruleset, Xml_string elemtag = saxxDefaultElem);

Modified: branches/ScribusOIF/scribus/pageitem_textframe.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/pageitem_textframe.cpp
==============================================================================
--- branches/ScribusOIF/scribus/pageitem_textframe.cpp (original)
+++ branches/ScribusOIF/scribus/pageitem_textframe.cpp Tue Oct 19 16:15:51 2010
@@ -70,7 +70,7 @@
 	unicodeTextEditMode = false;
 	unicodeInputCount = 0;
 	unicodeInputString = "";
-	
+	textLayout = new TextLayout(&itemText, this);
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
 

Modified: branches/ScribusOIF/scribus/pslib.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/pslib.h
==============================================================================
--- branches/ScribusOIF/scribus/pslib.h (original)
+++ branches/ScribusOIF/scribus/pslib.h Tue Oct 19 16:15:51 2010
@@ -47,6 +47,7 @@
 class MultiProgressDialog;
 class ScImage;
 class ScLayer;
+class ScText;
 
 /**
   *@author Franz Schmid

Modified: branches/ScribusOIF/scribus/scribusdoc.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/scribusdoc.h
==============================================================================
--- branches/ScribusOIF/scribus/scribusdoc.h (original)
+++ branches/ScribusOIF/scribus/scribusdoc.h Tue Oct 19 16:15:51 2010
@@ -68,6 +68,7 @@
 class ScPattern;
 class UndoTransaction;
 class Serializer;
+class ScText;
 
 class QProgressBar;
 

Modified: branches/ScribusOIF/scribus/text/legacylayout.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/text/legacylayout.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/legacylayout.cpp (original)
+++ branches/ScribusOIF/scribus/text/legacylayout.cpp Tue Oct 19 16:15:51 2010
@@ -108,6 +108,23 @@
 	return 0.0;
 }
 
+/**
+  An attempt to provide full featured shaping
+  */
+void shapeShape(const TypoPrefs& typographicSettings,
+		const CharStyle& style,
+		const QString& chars,
+		const TextFlags* textFlags,
+		int start,
+		int end,
+		GlyphStore& glyphs)
+{
+	double asce = style.font().ascent(style.fontSize() / 10.0);
+	int chst = style.effects() & 1919;
+	uint item = glyphs.addItem(start, end - start);
+
+	style.font().shapeText(&glyphs);
+}
 
 /**
  This used to be layoutGlyphs(). It translates the chars into a number of glyphs, applying the Charstyle
@@ -118,6 +135,10 @@
  */
 void legacyShape(const TypoPrefs& typographicSettings, const CharStyle& style, const QString& chars, const TextFlags* textFlags, int start, int end, GlyphStore& glyphs)
 {
+	if(style.font().type() == ScFace::OTF)
+	{
+		shapeShape(typographicSettings, style, chars, textFlags, start, end, glyphs);
+	}
 	double asce = style.font().ascent(style.fontSize() / 10.0);
 	int chst = style.effects() & 1919;
 	
@@ -786,7 +807,14 @@
 	qreal ColGap;
 	int   Cols;
 	
-	FrameControl(PageItem_TextFrame* item) : frame(item), story(item->itemText), BackBox(item->BackBox), NextBox(item->NextBox), invalid(item->invalid), MaxChars(item->MaxChars), OwnPage(item->OwnPage), OnMasterPage(item->OnMasterPage)
+	FrameControl(PageItem_TextFrame* item) :
+			frame(item), story(item->itemText),
+			BackBox(item->BackBox),
+			NextBox(item->NextBox),
+			invalid(item->invalid),
+			MaxChars(item->MaxChars),
+			OwnPage(item->OwnPage),
+			OnMasterPage(item->OnMasterPage)
 	{
 		m_Doc = frame->m_Doc;
 		extra.Top = frame->TExtra;

Modified: branches/ScribusOIF/scribus/text/legacylayout.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15578&path=/branches/ScribusOIF/scribus/text/legacylayout.h
==============================================================================
--- branches/ScribusOIF/scribus/text/legacylayout.h (original)
+++ branches/ScribusOIF/scribus/text/legacylayout.h Tue Oct 19 16:15:51 2010
@@ -20,6 +20,7 @@
 class PageItem_TextFrame;
 class TypoPrefs;
 
+void shapeShape(const TypoPrefs& typographicSetings, const CharStyle& charStyle, const QString& text, const TextFlags* textFlags, int start, int end, GlyphStore& glyphs);
 void legacyShape(const TypoPrefs& typographicSetings, const CharStyle& charStyle, const QString& text, const TextFlags* textFlags, int start, int end, GlyphStore& glyphs);
 void legacyLayout(PageItem_TextFrame* item);
 




More information about the scribus-commit mailing list