summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite/src/segment/GrTableManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/graphite/src/segment/GrTableManager.h')
-rw-r--r--Build/source/libs/graphite/src/segment/GrTableManager.h583
1 files changed, 583 insertions, 0 deletions
diff --git a/Build/source/libs/graphite/src/segment/GrTableManager.h b/Build/source/libs/graphite/src/segment/GrTableManager.h
new file mode 100644
index 00000000000..e0306c832c7
--- /dev/null
+++ b/Build/source/libs/graphite/src/segment/GrTableManager.h
@@ -0,0 +1,583 @@
+/*--------------------------------------------------------------------*//*:Ignore this sentence.
+Copyright (C) 1999 - 2008 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: GrTableManager.h
+Responsibility: Sharon Correll
+Last reviewed: Not yet.
+
+Description:
+ The GrTableManager class.
+----------------------------------------------------------------------------------------------*/
+#ifdef _MSC_VER
+#pragma once
+#endif
+#ifndef GR_TABLEMAN_INCLUDED
+#define GR_TABLEMAN_INCLUDED
+
+#include <cassert>
+//:End Ignore
+
+namespace gr
+{
+
+class Font;
+
+/*----------------------------------------------------------------------------------------------
+ There is a single instance of Engine State that keeps track of the state of the processing
+ for a single segment generation.
+
+ Hungarian: engst
+----------------------------------------------------------------------------------------------*/
+class EngineState
+{
+ friend class GrTableManager;
+ friend class FontMemoryUsage;
+
+public:
+ EngineState();
+ void Initialize(GrEngine *, GrTableManager *);
+
+ ~EngineState();
+ void DestroySlotBlocks();
+
+ void InitForNewSegment(GrTableManager * ptman);
+
+ void CreateEmpty();
+
+ GrEngine * Engine();
+ GrTableManager * TableManager();
+
+ void CreateSlotStreams();
+
+ GrSlotStream * InputStream(int ipass)
+ {
+ Assert(ipass > 0); // the char stream serves as input to the zeroth pass
+ return m_prgpsstrm[ipass - 1];
+ }
+
+ // Return the stream that serves as output to the given pass.
+ GrSlotStream * OutputStream(int ipass)
+ {
+ Assert(ipass < m_cpass);
+ return m_prgpsstrm[ipass];
+ }
+
+ GrSlotState * AnAdjacentSlot(int ipassArg, int islotArg);
+
+ GrResult GetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel, float * pxysValueRet);
+ GrResult GetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel, int * pxysValueRet);
+ GrResult SetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel, float xysValue);
+ GrResult SetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel, int xysValue);
+
+ enum { kSlotBlockSize = 50 }; // number of slots to allocate in a block
+
+ void InitPosCache()
+ {
+ m_islotPosNext = -1;
+ m_xsPosXNext = 0;
+ m_ysPosYNext = 0;
+ m_dxsTotWidthSoFar = 0;
+ m_dxsVisWidthSoFar = 0;
+ }
+
+ void SetFont(Font * pfont)
+ {
+ m_pfont = pfont;
+ }
+ Font * GetFont()
+ {
+ return m_pfont;
+ }
+
+ bool StartLineContext()
+ {
+ return m_fStartLineContext;
+ }
+ bool EndLineContext()
+ {
+ return m_fEndLineContext;
+ }
+ void SetStartLineContext(bool f)
+ {
+ m_fStartLineContext = f;
+ }
+ void SetEndLineContext(bool f)
+ {
+ m_fEndLineContext = f;
+ }
+
+ void SetInitialLB(bool f = true)
+ {
+ m_fInitialLB = f;
+ }
+
+ void SetFinalLB(bool f = true)
+ {
+ m_fFinalLB = f;
+ }
+
+ void SetInsertedLB(bool f = true)
+ {
+ m_fInsertedLB = f;
+ }
+
+ bool HasInitialLB()
+ {
+ return m_fInitialLB;
+ }
+ bool HasInsertedLB()
+ {
+ return m_fInsertedLB;
+ }
+ bool HasFinalLB()
+ {
+ return m_fFinalLB;
+ }
+
+ void SetExceededSpace(bool f = true)
+ {
+ m_fExceededSpace = f;
+ }
+
+ bool ExceededSpace()
+ {
+ return m_fExceededSpace;
+ }
+
+ void SetHitHardBreak(bool f = true)
+ {
+ m_fHitHardBreak = f;
+ }
+
+ bool HitHardBreak()
+ {
+ return m_fHitHardBreak;
+ }
+
+ void SetRemovedTrWhiteSpace(bool f = true)
+ {
+ m_fRemovedWhtsp = f;
+ }
+
+ bool RemovedTrWhiteSpace()
+ {
+ return m_fRemovedWhtsp;
+ }
+
+ bool WhiteSpaceOnly()
+ {
+ return (m_twsh == ktwshOnlyWs);
+ }
+
+ bool ParaRightToLeft()
+ {
+ return m_fParaRtl;
+ }
+
+ //int PrevPassMaxBackup(int ipass)
+ //{
+ // if (ipass == 0)
+ // return 0;
+ // return Pass(ipass - 1)->MaxBackup();
+ //}
+
+ DirCode InitialStrongDir()
+ {
+ return m_dircInitialStrongDir;
+ }
+ DirCode InitialTermDir()
+ {
+ return m_dircInitialTermDir;
+ }
+
+ void InitializeStreams(GrTableManager * ptman, GrCharStream * pchstrm,
+ int cbPrev, byte * pbPrevSegDat, bool fNeedFinalBreak, int * pislotFinalBreak);
+ int LbSlotToSegLim(int islot, GrCharStream * pchstrm, int cpassLB);
+ int TraceStreamZeroPos(int islotFinal, int nTopDir);
+
+ float EmToLogUnits(int m);
+ int LogToEmUnits(float xys);
+ bool GPointToXY(gid16 chwGlyphID, int nGPoint, float * xs, float * ys);
+
+ void AddJWidthToAdvance(GrSlotStream * psstrm, GrSlotState ** ppslot, int islot,
+ GrSlotState ** ppslotLast, GrSlotState ** ppslotLastBase);
+
+ // Memory management for slots:
+ void NewSlot(gid16 gID, GrFeatureValues fval, int ipass, int ichwSegOffset, int nUnicode,
+ GrSlotState **);
+ void NewSlot(gid16 gID, GrSlotState * pslotFeat, int ipass, int ichwSegOffset,
+ GrSlotState **);
+ void NewSlot(gid16 gID, GrSlotState * pslotFeat, int ipass, GrSlotState **);
+ void NewSlotCopy(GrSlotState * pslotCopyFrom, int ipass,
+ GrSlotState ** pslotRet);
+protected:
+ void NextSlot(GrSlotState ** ppslot);
+
+protected:
+ GrTableManager * m_ptman;
+
+ int m_cFeat;
+ int m_cCompPerLig;
+ int m_cUserDefn;
+
+ int m_jmodi; // justification mode
+ int m_ipassJustCalled; // pass after which justification routine was called;
+ // -1 if we are not in the midst of interacting with the
+ // GrJustifier
+
+ // Pointer to font
+ Font * m_pfont;
+
+ bool m_fStartLineContext; // true if there was a rule that ran over the initial LB
+ bool m_fEndLineContext; // true if there was a rule that ran over the final LB
+
+ // the number of slots inserted in the first stream before the official beginning
+ // of the segment, including any initial line break
+ int m_cslotPreSeg;
+
+ // List of allocated GrSlotStates; hungarian slotblk = prgslot
+ std::vector<GrSlotState *> m_vslotblk;
+ std::vector<u_intslot *> m_vprgnSlotVarLenBufs; // corresponding var-length blocks
+ int m_islotblkCurr;
+ int m_islotNext;
+
+ // Directionality codes from previous segment; these are used by the bidi algorithm
+ // at the initial line-break character.
+ DirCode m_dircInitialStrongDir;
+ DirCode m_dircInitialTermDir;
+
+ LineBrk m_lbPrevEnd;
+
+ // All of the following 3 are true only when there is an actual LB glyph in the stream
+ bool m_fInitialLB; // is there is an initial LB (an actual LB glyph--in all streams)
+ bool m_fFinalLB; // is there is a final LB (in all streams--true when we've hit
+ // the end of the input and end-of-line is true)
+ bool m_fInsertedLB; // is there is a final LB inserted in the output of LB pass
+ // (true when we've backtracked)
+
+ bool m_fExceededSpace; // true if we backtracked due to exceeding space; false if we
+ // haven't backtracked, or we did so for some other reason
+ // (eg, omitting trailing whitespace)
+
+ bool m_fHitHardBreak; // true if we encountered a hard-break in the input stream
+ // (before the natural end of the segment)
+
+ bool m_fRemovedWhtsp; // true if we've hit trailing whitespace characters that we've
+ // removed
+
+ TrWsHandling m_twsh; // white-space handling
+ bool m_fParaRtl; // paragraph direction
+
+ float m_dxsShrinkPossible;
+
+ // The final positioning pass is where we are going to do most of the positioning.
+ // Cache the intermediate results so we don't have to calculate from the beginning of
+ // the segment every time.
+ int m_islotPosNext; // where to continue calculating positions in final output stream
+ // (one past the last base that was calculated)
+ float m_xsPosXNext;
+ float m_ysPosYNext;
+ float m_dxsTotWidthSoFar;
+ float m_dxsVisWidthSoFar;
+
+ int m_cpass; // number of passes
+
+ // array of pass-state objects
+ PassState * m_prgzpst;
+
+ // array of slot streams which are output of passes (input of zeroth
+ // pass is the character stream, not a slot stream):
+ GrSlotStream ** m_prgpsstrm;
+ // For instance, a simple set of passes might look like this:
+ // CharStream
+ // GlyphGenPass pass 0
+ // SlotStream stream 0
+ // SubPass pass 1
+ // SlotStream stream 1
+ // PosPass pass 2
+ // SlotStream stream 2
+ //
+ // m_cpass = 3
+
+}; // end of class EngineState
+
+/*----------------------------------------------------------------------------------------------
+ There is a single instance of GrTableManager that handle the interactions between
+ passes, including the demand-pull mechanism.
+
+ Hungarian: tman
+----------------------------------------------------------------------------------------------*/
+
+class GrTableManager {
+ friend class FontMemoryUsage;
+
+public:
+ // Constructor & destructor:
+ GrTableManager(GrEngine * pgreng)
+ : m_cpass(0),
+ m_fBidi(false),
+ m_prgppass(NULL),
+ m_pgreng(pgreng)
+ {
+ Assert(pgreng);
+ }
+
+ ~GrTableManager();
+
+ bool CreateAndReadPasses(GrIStream & grstrm, int fxdSilfVersion, int fxdRuleVersion,
+ int cpassFont, long lSubTableStart, int * rgnPassOffsets,
+ int ipassSub1Font, int ipassPos1Font, int ipassJust1Font, byte ipassPostBidiFont);
+
+ void CreateEmpty();
+
+ GrEngine * Engine();
+ EngineState * State();
+
+ void Run(Segment * psegNew, Font * pfont, GrCharStream * pchstrm,
+ IGrJustifier * pgjus, int jmodi,
+ LayoutEnvironment & layout,
+ int ichStop, float dxWidth, float dxUnjustified,
+ bool fNeedFinalBreak, bool fMoreText, int ichFontLim,
+ bool fInfiniteWidth, bool fWidthIsCharCount,
+ int ichwCallerBtLim,
+ int nDirDepth, SegEnd estJ);
+
+ GrPass* Pass(int ipass)
+ {
+ Assert(ipass >= 0);
+ return m_prgppass[ipass];
+ }
+
+ int NumberOfPasses()
+ {
+ return m_cpass;
+ }
+
+ int NumberOfLbPasses()
+ {
+ return m_cpassLB;
+ }
+
+ bool HasBidiPass()
+ {
+ return m_fBidi;
+ }
+
+ int FirstPosPass()
+ {
+ return m_ipassPos1;
+ }
+
+ void StorePassStates(PassState * rgzpst);
+
+ // Return the stream that serves as input to the given pass.
+ GrSlotStream * InputStream(int ipass)
+ {
+ return m_engst.InputStream(ipass);
+ }
+ GrSlotStream * OutputStream(int ipass)
+ {
+ return m_engst.OutputStream(ipass);
+ }
+
+ void UnwindAndReinit(int islotNewBreak);
+
+public:
+ int InternalJustificationMode()
+ {
+ return m_engst.m_jmodi;
+ }
+
+ bool ShouldLogJustification()
+ {
+ return (m_engst.m_jmodi != kjmodiNormal);
+ }
+
+ int PrevPassMaxBackup(int ipass)
+ {
+ if (ipass == 0)
+ return 0;
+ return Pass(ipass - 1)->MaxBackup();
+ }
+
+ // Forward to the engine itself
+ gid16 GetGlyphIDFromUnicode(int nUnicode);
+ gid16 ActualGlyphForOutput(utf16 chwGlyphID);
+ GrGlyphTable * GlyphTable();
+
+ gid16 LBGlyphID();
+
+ gid16 GetClassGlyphIDAt(int nClass, int nIndex);
+ int GetIndexInGlyphClass(int nClass, gid16 chwGlyphID);
+ size_t NumberOfGlyphsInClass(int nClass);
+
+ void SetSlotAttrsFromGlyphAttrs(GrSlotState * pslot);
+
+ int NumFeat();
+ int DefaultForFeatureAt(int ifeat);
+ GrFeature * FeatureWithID(featid nID, int * pifeat);
+ GrFeature * Feature(int ifeat);
+ void DefaultsForLanguage(isocode lgcode,
+ std::vector<featid> & vnFeats, std::vector<int> & vnValues);
+
+ bool RightToLeft();
+ int TopDirectionLevel();
+
+ float VerticalOffset();
+
+ int NumUserDefn();
+ int NumCompPerLig();
+
+ int ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID);
+ int GlyphAttrValue(gid16 chwGlyphID, int nAttrID);
+
+ // ---
+
+ bool LoggingTransduction();
+
+ float EmToLogUnits(int m);
+ int LogToEmUnits(float xys);
+ bool GPointToXY(gid16 chwGlyphID, int nGPoint, float * xs, float * ys);
+
+ void CalcPositionsUpTo(int ipass, GrSlotState * pslotLast,
+ float * pxsWidth, float * pxsVisibleWidth);
+
+ void InitPosCache()
+ {
+ m_engst.InitPosCache();
+ }
+
+ bool IsWhiteSpace(GrSlotState * pslot);
+
+ // For transduction logging:
+ bool WriteTransductionLog(std::ostream * pstrmLog,
+ GrCharStream * pchstrm, Segment * psegRet, int cbPrevSetDat, byte * pbPrevSegDat);
+ bool WriteAssociationLog(std::ostream * pstrmLog,
+ GrCharStream * pchstrm, Segment * psegRet);
+ bool WriteXmlLog(std::ostream * pstrmLog,
+ GrCharStream * pchstrm, Segment * psegRet, int cbPrevSegDat, byte * pbPrevSegDat);
+ bool WriteXmlAssocLog(std::ostream * pstrmLog,
+ GrCharStream * pchstrm, Segment * psegRet);
+
+#ifdef TRACING
+ void WriteXductnLog(std::ostream & strmOut, GrCharStream * pchstrm, Segment * psegRet,
+ int cbPrevSegDat, byte * pbPrevSegDat);
+ //bool LogFileName(std::string & staFile);
+ void LogUnderlying(std::ostream & strmOut, GrCharStream * pchstrm, int cchwBackup);
+ void LogPass1Input(std::ostream & strmOut);
+ void LogPassOutput(std::ostream & strmOut, int ipass, int cslotSkipped);
+ void LogAttributes(std::ostream & strmOut, int ipass, bool fJustWidths = false);
+ void LogFinalPositions(std::ostream & strmOut);
+ void LogUnderlyingHeader(std::ostream & strmOut, int ichwMin,
+ int ichwLim, int cchwBackup, int * prgichw16bit);
+ void LogSlotHeader(std::ostream & strmOut, int cslot,
+ int cspPerSlot, int cspLeading, int islotMin = 0);
+ void LogSlotGlyphs(std::ostream & strmOut, GrSlotStream * psstrm);
+ void SlotAttrsModified(int ipass, bool * rgfMods, bool fPreJust, int * pccomp, int *pcassoc);
+ void LogInTable(std::ostream & strmOut, int n);
+ void LogInTable(std::ostream & strmOut, float n);
+ void LogHexInTable(std::ostream & strmOut, gid16 chw, bool fPlus = false);
+ void LogDirCodeInTable(std::ostream & strmOut, int dirc);
+ void LogBreakWeightInTable(std::ostream & strmOut, int lb);
+
+ void WriteXmlLogAux(std::ostream & strmOut,
+ GrCharStream * pchstrm, Segment * psegRet, int cbPrevSegDat, byte * pbPrevSegDat);
+ void LogXmlUnderlying(std::ostream & strmOut, GrCharStream * pchstrm, int cchwBackup, size_t nIndent);
+ void LogXmlUnderlyingAux(std::ostream & strmOut, GrCharStream * pchstrm,
+ int cch32Backup, int cch32Lim, size_t nIndent,
+ bool fLogText, bool fLogFeatures, bool fLogColor, bool fLogStrOff, bool fLogLig, bool fLogGlyphs);
+ void LogXmlPass(std::ostream & strmOut, int ipass, int cslotSkipped, int nIndent);
+
+ void LogXmlTagOpen(std::ostream & strmOut, std::string strTag, size_t nIndent, bool fContent);
+ void LogXmlTagPostAttrs(std::ostream & strmOut, bool fContent);
+ void LogXmlTagClose(std::ostream & strmOut, std::string strTag, size_t nIndent, bool fContent);
+ void LogXmlTagAttr(std::ostream & strmOut, std::string strAttr, int nValue, size_t nIndent = 0);
+ void LogXmlTagAttr(std::ostream & strmOut, std::string strAttr, const char * szValue, size_t nIndent = 0);
+ void LogXmlTagAttrHex(std::ostream & strmOut, std::string strAttr, int nValue, size_t nIndent = 0);
+ std::string HexString(int n1, int n2, int n3, int n4, int n5, int n6);
+ std::string HexString(std::vector<int>);
+ void LogXmlTagColor(std::ostream & strmOut, std::string strAttr, int clrValue, bool fBack,
+ size_t nIndent = 0);
+ void LogXmlDirCode(std::ostream & strmOut, std::string strAttr, int dircValue, size_t nIndent = 0);
+ void LogXmlBreakWeight(std::ostream & strmOut, std::string strAttr, int dircValue,
+ size_t nIndent = 0);
+ void LogXmlComment(std::ostream & strmOut, std::string strComment, size_t nIndent = 0);
+
+#endif // TRACING
+
+protected:
+ void InitNewSegment(Segment * psegNew, Font * pfont, GrCharStream * pchstrm, IGrJustifier * pgjus,
+ int islotStream0Break, int islotSurfaceBreak, bool fStartLine, bool fEndLine, int ichFontLim,
+ LineBrk lbEnd, SegEnd est, int * dichSegLen);
+
+ void InitSegmentAsEmpty(Segment * psegNew, Font * pfont, GrCharStream * pchstrm,
+ bool fStartLine, bool fEndLine);
+
+ void InitSegmentToDelete(Segment * psegNew, Font * pfont, GrCharStream * pchstrm);
+
+ int ChunkInPrev(int ipass, int islot, GrCharStream * pchstrm);
+
+ bool Backtrack(int * islotPrevLB,
+ LineBrk * plbPref, LineBrk lbMax, TrWsHandling, bool fMoreText,
+ int ichwCallerBtLim, LineBrk * plbFound);
+
+ LineBrk IncLineBreak(LineBrk lb);
+
+ void InitializeForNextSeg(Segment* pseg,
+ int islotStream0Break, int islotSurfaceBreak, LineBrk lbEnd,
+ bool fNextSegNeedsContext, GrCharStream * pchstrm);
+
+ void SetFinalPositions(Segment * pseg, bool fWidthIsCharCount);
+ void RecordAssocsAndOutput(Font * pfont, Segment * pseg,
+ TrWsHandling twsh, bool fParaRtl, int nDirDepth);
+
+ void CalculateAssociations(Segment * pseg, int csloutSurface);
+ void AdjustAssocsForOverlaps(Segment * pseg);
+
+ void UnstretchTrailingWs(GrSlotStream * psstrm, int iGlyphLim);
+ void CallJustifier(IGrJustifier * pgjus, int ipassCurr, float dxUnjustified, float dxJustified,
+ bool fEndLine);
+
+ void DetermineShrink(IGrJustifier * pgjus, int ipass);
+
+protected:
+ // Instance variables:
+
+ int m_cpass; // number of passes; zero-th pass is Unicode character -> glyph ID mapping;
+ // Note thatwe always have one positioning pass to measure things even
+ // if there are no tables to run.
+
+ int m_cpassLB; // number of line-break passes
+ int m_ipassPos1; // first positioning pass
+ int m_ipassJust1; // first justification pass (== m_ipassPos1 if none)
+
+ bool m_fBidi; // is there a bidi pass?
+
+ // array of passes:
+ GrPass ** m_prgppass;
+
+ // Pointer back to Graphite engine, to give access to global constants and tables.
+ GrEngine * m_pgreng;
+
+ // State of processing.
+ EngineState m_engst;
+
+ bool m_fLogging;
+
+public:
+ // For test procedures:
+ void SetUpTest(std::wstring);
+
+protected:
+ void TempDebug();
+ int SurfaceLineBreakSlot(int ichw, GrCharStream * pchstrm, bool fInitial);
+ std::wstring ChunkDebugString(int ipass);
+}; // end of class GrTableManager
+
+} // namespace gr
+
+
+#endif // !GR_TABLEMAN_INCLUDED