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
|