1 //
2 // C++ Interface: fmaltcontext
3 //
4 // Description: Maintains state of user defined alternate glyphs in specific context
5 //
6 //
7 // Author: Pierre Marchand <pierremarc@oep-h.com>, (C) 2009
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12 
13 #ifndef FMALTCONTEXT_H
14 #define FMALTCONTEXT_H
15 
16 #include <QObject>
17 #include <QMap>
18 #include <QString>
19 #include <QList>
20 
21 class FMAltContext
22 {
23 	int runPar;
24 	int runWord;
25 	int runChunk;
26 	/**
27 	  We store lists of alternates at the glyph level in the intermediate form of the text
28 	  Text
29 	  ----> Paragraph
30 		----> Word
31 		      ----> Chunk (as returned by hyphenator, and actually sent to OT processor)
32 			    ----> Glyph
33 				  ----> List<Alternates>
34 	*/
35 	// alternate lists
36 	QMap<int , QMap< int , QMap<int , QMap< int, QList<int> > > > > m_alt;
37 	// base glyph
38 	QMap<int , QMap< int , QMap<int , QMap< int, int> > > > m_control;
39 	// selected glyph (indexOf, 0 by default)
40 	QMap<int , QMap< int , QMap<int , QMap< int, int> > > > m_select;
41 
42 	// actual words
43 	QMap<int , QMap< int , QString> > m_words;
44 	// actual chunks
45 	QMap<int , QMap< int , QMap<int , QString> > > m_chunks;
46 
47 	struct run
48 	{
49 		int par;
50 		int word;
51 		int chunk;
52 	};
53 
54 	QList<run> runStore;
55 
56 public:
57 	QString fontID;
58 	QString textID;
FMAltContext()59 	FMAltContext():runPar(0),runWord(0),runChunk(0){}
60 
61 //	void reset()
62 //	{
63 //		m_alt.clear();
64 //		m_control.clear();
65 //		m_select.clear();
66 //
67 //		runChunk = 0;
68 //		runPar = 0;
69 //		runWord = 0;
70 //	}
71 
saveRun()72 	void saveRun(){run r;r.chunk = runChunk;r.par = runPar; r.word = runWord; runStore << r;}
restoreRun()73 	void restoreRun(){run r = runStore.takeLast(); runPar = r.par;runWord = r.word; runChunk = r.chunk;}
74 
maxPar()75 	int maxPar(){return m_alt.count();}
maxWord()76 	int maxWord(){return m_alt[runPar].count();}
maxChunk()77 	int maxChunk(){return m_alt[runPar][runWord].count();}
maxGlyph()78 	int maxGlyph(){return m_alt[runPar][runWord][runChunk].count();}
maxAlt(const int & gIdx)79 	int maxAlt(const int& gIdx){return m_alt[runPar][runWord][runChunk][gIdx].count();}
80 
81 	void setPar(const int& p = 0){runPar = p;}
par()82 	int par() const {return runPar;}
83 
84 	void setWord(const int& w = 0){runWord = w;}
word()85 	int word() const{return runWord;}
86 
87 	void setChunk(const int& c = 0){runChunk = c;}
chunk()88 	int chunk() const{return runChunk;}
89 
addAlt(const int & gIndex,const int & gAlt)90 	void addAlt(const int& gIndex, const int& gAlt)
91 	{
92 		if(!m_alt[runPar][runWord][runChunk][gIndex].contains(gAlt))
93 			m_alt[runPar][runWord][runChunk][gIndex].append(gAlt);
94 	}
alts(const int & gIndex)95 	QList<int> alts(const int& gIndex) const { return m_alt[runPar][runWord][runChunk][gIndex]; }
96 
setControl(const int & gIndex,const int & c)97 	void setControl(const int& gIndex, const int& c){ m_control[runPar][runWord][runChunk][gIndex] = c; }
control(const int & gIndex)98 	int control(const int& gIndex) const {return m_control[runPar][runWord][runChunk][gIndex];}
99 
setSelect(const int & gIndex,const int & s)100 	void setSelect(const int& gIndex, const int& s){ m_select[runPar][runWord][runChunk][gIndex] = s; }
select(const int & gIndex)101 	int select(const int& gIndex) const { return m_select[runPar][runWord][runChunk][gIndex]; }
102 
fileWord(const QString & s)103 	void fileWord(const QString& s){m_words[runPar][runWord] = s;}
wordString()104 	QString wordString()const{return m_words[runPar][runWord];}
105 
fileChunk(const QString & s)106 	void fileChunk(const QString& s){m_chunks[runPar][runWord][runChunk] = s;}
chunkString()107 	QString chunkString()const{return m_chunks[runPar][runWord][runChunk];}
108 
cleanup()109 	void cleanup()
110 	{
111 		QMap<int , QMap< int , QMap<int , QMap< int, QList<int> > > > > t_alt;
112 		QMap<int , QMap< int , QMap<int , QMap< int, int> > > > t_control;
113 		QMap<int , QMap< int , QMap<int , QMap< int, int> > > > t_select;
114 		QMap<int , QMap< int , QString> > t_words;
115 		QMap<int , QMap< int , QMap<int , QString> > > t_chunks;
116 		for(int p(0);p < m_alt.count(); ++p)
117 		{
118 			for(int w(0);w < m_alt[p].count(); ++w)
119 			{
120 				for(int c(0);c < m_alt[p][w].count(); ++c)
121 				{
122 					for(int g(0);g < m_alt[p][w][c].count(); ++g)
123 					{
124 						if(m_alt[p][w][c][g].count())
125 						{
126 							t_alt[p][w][c][g] = m_alt[p][w][c][g];
127 							t_control[p][w][c][g] = m_control[p][w][c][g];
128 							t_select[p][w][c][g] = m_select[p][w][c][g];
129 							t_words[p][w] = m_words[p][w];
130 							t_chunks[p][w][c] = m_chunks[p][w][c];
131 						}
132 					}
133 				}
134 			}
135 		}
136 		m_alt = t_alt;
137 		m_control = t_control;
138 		m_select = t_select;
139 		m_words = t_words;
140 		m_chunks = t_chunks;
141 	}
142 
143 };
144 
145 class FMAltContextLib : private QObject
146 {
147 	Q_OBJECT
148 
149 	static FMAltContextLib * instance;
150 	static FMAltContextLib * that();
151 	FMAltContextLib();
152 	~FMAltContextLib();
153 
154 	QMap<QString, FMAltContext*> cmap;
155 	QString current;
156 
157 	public:
158 		static FMAltContext * SetCurrentContext(const QString& tid, const QString& font);
159 		static FMAltContext * GetCurrentContext();
160 		static void GetConnected(const QObject * receiver, const char * method);
161 
162 	signals:
163 		void contextChanged();
164 
165 };
166 
167 #endif // FMALTCONTEXT_H
168