File: GdlTablePass.h

package info (click to toggle)
grcompiler 5.2-2.2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 24,352 kB
  • sloc: cpp: 48,550; ansic: 6,104; sh: 4,427; makefile: 197; xml: 190; perl: 127; sed: 21
file content (340 lines) | stat: -rw-r--r-- 11,611 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/*--------------------------------------------------------------------*//*:Ignore this sentence.
Copyright (C) 1999, 2001 SIL International. All rights reserved.

Distributable under the terms of either the Common Public License or the
GNU Lesser General Public License, as specified in the LICENSING.txt file.

File: GdlTablePass.h
Responsibility: Sharon Correll
Last reviewed: Not yet.

Description:
    Implements the classes corresponding to the tables of rules and their passes.
-------------------------------------------------------------------------------*//*:End Ignore*/
#ifdef _MSC_VER
#pragma once
#endif
#ifndef TABLEPASS_INCLUDED
#define TABLEPASS_INCLUDED

/*----------------------------------------------------------------------------------------------
Class: GdlPass
Description: corresponds to a pass within the substitution, linebreak, or positioning table.
Hungarian: pass
----------------------------------------------------------------------------------------------*/

class GdlPass : public GdlObject
{
public:
	//	Constructors & destructors:
	GdlPass(int nNum, int nMaxRuleLoop, int nMaxBackup)
		:	m_nNumber(nNum),
			m_nMaxRuleLoop(nMaxRuleLoop),
			m_nMaxBackup(nMaxBackup),
			m_nCollisionFix(0),
			m_nAutoKern(false),
			m_nCollisionThreshold(0),
			m_nDir(0),
			m_fFlipDir(0),
			m_nGlobalID(-1),
			m_nPreBidiPass(0),
			m_pfsm(NULL)
	{
	}

	~GdlPass();
	void ClearFsmWorkSpace();

	//	Getters:
	int Number()					{ return m_nNumber; }

	bool HasLineBreaks()			{ return m_fLB; }
	bool HasCrossLineContext()		{ return m_fCrossLB; }
	int MaxPreLBSlots()				{ return m_critPreLB; }
	int MaxPostLBSlots()			{ return m_critPostLB; }
	bool HasReprocessing()			{ return m_fReproc; }
	int MaxRuleContext()			{ return m_nMaxRuleContext; }

	int MaxRuleLoop()				{ return m_nMaxRuleLoop; }
	int MaxBackup()					{ return m_nMaxBackup; }
	int CollisionFix()				{ return m_nCollisionFix; }
	int AutoKern()					{ return m_nAutoKern; }
	int CollisionThreshold()		{ return m_nCollisionThreshold; }
	int Direction()					{ return m_nDir; }

	//	Setters:
	void AddRule(GdlRule* prule)		{ m_vprule.push_back(prule); }

	void SetMaxRuleLoop(int n)			{ m_nMaxRuleLoop = n; }
	void SetMaxBackup(int n)			{ m_nMaxBackup = n; }
	void SetCollisionFix(int n)			{ m_nCollisionFix = n; }
	void SetAutoKern(int n)				{ m_nAutoKern = n; }
	void SetCollisionThreshold(int n)	{ m_nCollisionThreshold = n; }
	void SetDirection(int n)			{ m_nDir = n; }
	void SetFlipDirection(bool f)		{ m_fFlipDir = f; }

public:
	//	Parser:
	GdlRule * NewRule(GrpLineAndFile & lnf)
	{
		GdlRule * pruleNew = new GdlRule();
		pruleNew->SetLineAndFile(lnf);
		m_vprule.push_back(pruleNew);
		return pruleNew;
	}

	void AddConstraint(GdlExpression * pexp)
	{
		m_vpexpConstraints.push_back(pexp);
	}

	//	Post-parser:
	void ReplaceAliases();
	void HandleOptionalItems();
	void CheckSelectors();

	//	Pre-compiler:
	void FixRulePreContexts(Symbol psymAnyClass);
	void FixGlyphAttrsInRules(GrcManager * pcman, GrcFont * pfont);
	void FixFeatureTestsInPass(GrcFont * pfont);
	void MarkReplacementClasses(GrcManager * pcman,
		ReplacementClassSet & setpglfc);
	void CheckRulesForErrors(GrcGlyphAttrMatrix * pgax, GrcFont * pfont,
		GdlRenderer * prndr, Symbol psymTable, int grfrco);
	void CheckLBsInRules(Symbol psymTable);
	void RewriteSlotAttrAssignments(GrcManager * pcman, GrcFont * pfont);
	void MaxJustificationLevel(int * pnJLevel);
	bool CompatibleWithVersion(int fxdVersion, int * pfxdNeeded, int * pfxdCpilrNeeded,
		bool * pfFixPassConstraints);
	void MovePassConstraintsToRules(int fxdSilfVersion);
	void CalculateSpaceContextuals(SpaceContextuals * pspconSoFar,
		std::vector<utf16> & vwSpaceGlyphs);

	void AssignGlobalID(int nID)
	{
		m_nGlobalID = nID;
	}
	bool HasRules()
	{
		return (m_vprule.size() > 0);
	}
	bool ValidPass()
	{
		return (this->HasRules() || this->CollisionFix() > 0);
	}

	void SetPreBidiPass(int n)
	{
		Assert(n == 0 || n == 1);
		m_nPreBidiPass = n;
	}

	//	Compiler:
	int GlobalID()
	{
		return m_nGlobalID;
	}
	int PassDebuggerNumber()
	{
		return m_nGlobalID + m_nPreBidiPass + 1;
	}
	void PassOptimizations(GrcGlyphAttrMatrix * pgax, GrcSymbolTable * psymtbl, unsigned int nAttrIdSkipP);
	void GenerateEngineCode(GrcManager *, int fxdRuleVersion, std::vector<gr::byte> & vbConstraints);
	void GenerateFsm(GrcManager * pcman);
	void GenerateFsmMachineClasses(GrcManager * pcman);
	void GenerateFsmTable(GrcManager * pcman);
	int AssignGlyphIDToMachineClasses(utf16 wGlyphID, int nPassID);
	int MachineClassKey(utf16 wGlyphID, int nPassID);
	void RecordInclusionInClass(utf16 wGlyphID, GdlGlyphClassDefn * pglfc);
	FsmMachineClass * MachineClassMatching(std::vector<FsmMachineClass *> & vpfsmc,
		utf16 wGlyphID);
	void InitializeFsmArrays();
	void MergeIdenticalStates(int ifsFixMin, int ifsCheckMin, int ifsCheckLim);
	int NumberOfFsmMachineClasses();
	void GetMachineClassesForRuleItem(GdlRule  * prule, int irit,
		FsmMachineClassSet & setpfsmc);
	int FindIdenticalState(int ifsToMatch, int ifsMin);
	void ReorderFsmStates(GrcManager * pcman);
	int NumStates();
	int NumAcceptingStates();
	int NumTransitionalStates();
	int NumSuccessStates();
	int NumFinalStates();
	void GenerateStartStates(GrcManager * pcman);

	//	Output:
	int TotalNumGlyphSubRanges();
	void OutputPass(GrcManager * pcman, GrcBinaryStream * pbstrm, int lTableStart);
	void GenerateRuleMaps(std::vector<int> & vnOffsets, std::vector<int> & vnRuleList);
	void OutputFsmTable(GrcBinaryStream * pbstrm);

	//	debuggers:
	void DebugEngineCode(GrcManager * pcman, int fxdRuleVersion, std::ostream & strmOut);
	void DebugRulePrecedence(GrcManager * pcman, std::ostream & strmOut);
	void DebugFsm(GrcManager * pcman, std::ostream & strmOut);
	void DebugFsmTable(GrcManager * pcman, std::ostream & strmOut, bool fWorking);
	void WalkFsmMachineClasses();
	void DebugXmlRules(GrcManager * pcman, std::ofstream & strmOut, std::string staPathToCur,
		Symbol psymTableName);

protected:
	//	Instance variables:
	int m_nNumber;
	int m_nMaxRuleLoop;
	int m_nMaxBackup;
	std::vector<GdlRule*> m_vprule;
	std::vector<GdlExpression *> m_vpexpConstraints; // multiple constraints result from -else if-
	int m_nCollisionFix;
	bool m_nAutoKern;
	int m_nCollisionThreshold;
	int m_nDir;
	bool m_fFlipDir;

	int m_critMinPreContext;
	int m_critMaxPreContext;

	//	for compiler use:
//	int m_nNumber2;		// with respect to all the passes in all tables
	int m_nGlobalID;	// global pass number, not including passes with no rules or bidi pass;
						//		-1 if invalid--no rules
	int m_nPreBidiPass;	// 1 if there is a previous bidi pass, 0 otherwise
	int m_nMaxRuleContext;	// number of slots of input needed

	bool m_fLB;			// true if there is a rule containing line-break items
	bool m_fCrossLB;	// true if there are are cross-line-boundary contextualization rules
	int m_critPreLB;	// max number of slots before a LB slot
	int m_critPostLB;	// max number of slots after a LB slot
	bool m_fReproc;		// true if this pass has reprocessing happening in any of its rules

	//	Finite State Machine construction:

	FsmTable * m_pfsm;

	//	Mapping from glyph ID to column in the FSM
	std::map<utf16, int> m_hmGlyphToColumn;

	//	Master list of machine classes:
	std::vector<FsmMachineClass *> m_vpfsmc;

	//	For each glyph ID, its source-class-set (the set of source-classes it belongs to):
	SourceClassSet m_rgscsInclusions[kMaxTotalGlyphs];

	//	For each glyph ID, the machine class it is assigned to:
	FsmMachineClass * m_rgpfsmcAssignments[kMaxTotalGlyphs];

	//	Map enabling us to find the machine class for a given glyph ID's source-class-set.
	//	Each unique combination of source-classes corresponds to a machine class.
	//	The key into the map is the sum of the source-class IDs (for all the
	//	source classes a given glyph is a member of); the value is a list of MachineClasses
	//	whose source-class-IDs add up to that key. For instance, for the key 8 you might
	//	have a value which is a vector of three MachineClasses: the first containing
	//	SourceClasses 2 & 6, the second containing SourceClasses 1, 3, & 4, and the
	//	third containing SourceClass 8.
	std::map<int, MachineClassList> m_hmMachineClassMap;

	std::vector<int> m_vifsWorkToFinal;	// final indices of states, causing them to be ordered
										// as expected by the font/engine data structures:
										//		transitional, non-success
										//		transitional, success
										//		non-transitional, success
	std::vector<int> m_vifsFinalToWork;	// inverse mapping from above vector, mapping the final
										// state indices back to the working indices

	std::vector<int> m_vrowStartStates;

public:
	//	For test procedures:
	int test_NumberOfRules()
	{
		return m_vprule.size();
	}
};


/*----------------------------------------------------------------------------------------------
Class: GdlRuleTable
Description: corresponds to the substitution, linebreak, or positioning table.
Hungarian: rultbl
----------------------------------------------------------------------------------------------*/

class GdlRuleTable : public GdlObject
{
public:
	//	Constructors & destructors:
	GdlRuleTable(Symbol psym)
		:	m_psymName(psym),
			m_fSubstitution(false)
	{
	}

	~GdlRuleTable()
	{
		for (size_t i = 0; i < m_vppass.size(); ++i)
			delete m_vppass[i];
	}

	//	Getters:
	Symbol NameSymbol()		{ return m_psymName; }
	bool Substitution()		{ return m_fSubstitution; }

	//	Setters:
	void SetSubstitution(bool f)	{ m_fSubstitution = f; }

	int NumberOfPasses()
	{
		return m_vppass.size();
	}

public:
	//	Post-parser:
	GdlPass * GetPass(GrpLineAndFile &, int nNumber, int nMaxRuleLoop, int nMaxBackup);
	void ReplaceAliases();
	void HandleOptionalItems();
	void CheckSelectors();

	//	Pre-compiler:
	void FixRulePreContexts(Symbol psymAnyClass);
	void FixGlyphAttrsInRules(GrcManager * pcman, GrcFont * pfont);
	void CheckTablesAndPasses(GrcManager * pcman, int *pnPassNum, int *pipassBidi);
	void MarkReplacementClasses(GrcManager * pcman,
		ReplacementClassSet & setpglfc);
	void CheckRulesForErrors(GrcGlyphAttrMatrix * pgax, GrcFont * pfont, GdlRenderer * prndr);
	void CheckLBsInRules();
	void RewriteSlotAttrAssignments(GrcManager * pcman, GrcFont * pfont);
	void MaxJustificationLevel(int * pnJLevel);
	bool HasCollisionPass();
	bool CompatibleWithVersion(int fxdVersion, int * pfxdNeeded, int * pfxdCpilrNeeded,
		bool * pfFixPassConstraints);
	void MovePassConstraintsToRules(int fxdSilfVersion);
	void CalculateSpaceContextuals(SpaceContextuals * pspconSoFar,
		std::vector<utf16> & vwSpaceGlyphs);

	//	Compiler:
	void PassOptimizations(GrcGlyphAttrMatrix * pgax, GrcSymbolTable * psymtbl, unsigned int nAttrIdSkipP);
	void GenerateFsms(GrcManager * pcman);
	void CalculateContextOffsets(int * pcPrevious, int * pcFollowing, bool * pfLineBreak,
		bool fPos, GdlRuleTable * prultbl1, GdlRuleTable * prultbl2);

	enum { kInfiniteXlbContext = 255 };

	//	Output
	int CountPasses();
	void OutputPasses(GrcManager * pcman, GrcBinaryStream * pbstrm, long lTableStart,
		std::vector<int> & vnOffsets);

	//	debuggers:
	void DebugEngineCode(GrcManager * pcman, int fxdRuleVersion, std::ostream & strmOut);
	void DebugRulePrecedence(GrcManager * pcman, std::ostream & strmOut, int ipassBidi);
	void DebugFsm(GrcManager * pcman, std::ostream & strmOut);
	void DebugXmlRules(GrcManager * pcman, std::ofstream & strmOut, std::string staPathToCur);

protected:
	//	Instance variables:
	Symbol m_psymName;
	bool m_fSubstitution;	// are substitutions (& associations) allowed in
							// this table?
	std::vector<GdlPass*>	m_vppass;
};


#endif // TABLEPASS_INCLUDED