diff options
Diffstat (limited to 'Build/source/libs/graphite-engine/src/segment/GrPassActionCode.cpp')
-rw-r--r-- | Build/source/libs/graphite-engine/src/segment/GrPassActionCode.cpp | 1492 |
1 files changed, 0 insertions, 1492 deletions
diff --git a/Build/source/libs/graphite-engine/src/segment/GrPassActionCode.cpp b/Build/source/libs/graphite-engine/src/segment/GrPassActionCode.cpp deleted file mode 100644 index 83c58b27e48..00000000000 --- a/Build/source/libs/graphite-engine/src/segment/GrPassActionCode.cpp +++ /dev/null @@ -1,1492 +0,0 @@ -/*--------------------------------------------------------------------*//*: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: GrPassActionCode.cpp -Responsibility: Sharon Correll -Last reviewed: Not yet. - -Description: - A continution of the GrPass file, including functions to run the action commands. - -This comment could create a merge conflict. It can be removed. -----------------------------------------------------------------------------------------------*/ - -//:>******************************************************************************************** -//:> Include files -//:>******************************************************************************************** -#include "Main.h" - -#ifdef _MSC_VER -#pragma hdrstop -#endif -#undef THIS_FILE -DEFINE_THIS_FILE - -//:End Ignore - -//:>******************************************************************************************** -//:> Forward declarations -//:>******************************************************************************************** - -//:>******************************************************************************************** -//:> Local type definitions -//:>******************************************************************************************** - -typedef signed char Int8; // signed value -typedef unsigned char Uint8; // unsigned value - - -namespace gr -{ - -//:>******************************************************************************************** -//:> Methods -//:>******************************************************************************************** - -/*---------------------------------------------------------------------------------------------- - The main function to run a block of action or constraint code and return a result. - - @param ptman - table manager, for generating new slots; NULL when - running constraints - @param pbStart - address of the first command - @param fConstraints - true if we are running constraint tests; - false if we are running rule actions - @param psstrmIn - input stream - @param psstrmOut - output stream; when running constraints, used to access items - in the precontext - @param islot - slot being processed relative to the start of the rule; - used only for constraints; must be 0 for rule actions -----------------------------------------------------------------------------------------------*/ -int GrPass::RunCommandCode(GrTableManager * ptman, - byte * pbStart, bool fConstraints, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, int islot) -{ - byte * pbNext = pbStart; - -// std::vector<int> vnStack; -// vnStack.EnsureSpace(128); // make it nice and big - m_vnStack.clear(); - - gAssert(fConstraints || islot == 0); - - // There are two states: fMustGet = true means we need to get a slot to work on from - // the input; fMustGet = false means we have a slot and we need to do a Next before - // we can get the next one. - bool fMustGet = !fConstraints; - - bool fInserting = false; // set to true by an Insert command - - int nRet = 0; - - while (true) - { - ActionCommand op = ActionCommand(*pbNext++); - StackMachineFlag smf; - nRet = RunOneCommand(ptman, fConstraints, op, - &pbNext, &fMustGet, &fInserting, - psstrmIn, psstrmOut, islot, - m_vnStack, &smf); - - if (smf == ksmfDone) - return nRet; - - if (smf == ksmfUnderflow) - { - Warn("Underflow in Graphite stack machine"); - gAssert(false); - FontException fexptn; - fexptn.version = -1; - fexptn.subVersion = -1; - fexptn.errorCode = kferrUnknown; - throw fexptn; // disastrous error in rendering; fall back to dumb rendering - } - } - return nRet; // not needed, but to avoid compiler warning -} - -/*---------------------------------------------------------------------------------------------- - Perform a single command. Specifically, read the arguments from the byte buffer and the - run the appropriate functions. - - @param ptman - table manager, for generating new slots; or NULL - @param fConstraints - true if we are running constraints; false if we are running - rule actions - @param op - command operator - @param ppbArg - pointer to first argument - @param pfMustGet - state: getting input or processing it; when running constraints, - always false - @param pfInserting - true if current item is to be inserted, or was inserted - @param psstrmIn - input stream - @param psstrmOut - output stream - @param islot - the slot being processed relative to the beginning of the rule; - only relevant for constraint testing, must be 0 for rule actions - @param vnStack - the stack of values being manipulated - @param psmf - error code, done flag, or continue flag -----------------------------------------------------------------------------------------------*/ -int GrPass::RunOneCommand(GrTableManager * ptman, bool fConstraints, - ActionCommand op, byte ** ppbArg, bool * pfMustGet, bool * pfInserting, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, int islot, - std::vector<int> & vnStack, StackMachineFlag * psmf) -{ - *psmf = ksmfContinue; - - // General purpose variables: - int arg1, arg2, arg3, arg4; - int nSlotRef; - int nInputClass; - int nOutputClass; - int c; - int islotArg; - int nIndex; - int nGlyphAttr; - int nAttLevel; - int nFeat; - int nPState; - SlotAttrName slat; - - int i; - std::vector<int> vnTmp; - - byte * pbNext = *ppbArg; - - int nRet = 0; - - switch (op) - { - case kopNop: - break; - - case kopPushByte: - arg1 = Int8(*pbNext++); - vnStack.push_back(arg1); - break; - case kopPushByteU: - arg1 = Uint8(*pbNext++); - vnStack.push_back(arg1); - break; - case kopPushShort: - arg1 = Int8(*pbNext++); - arg2 = Uint8(*pbNext++); - vnStack.push_back((arg1 << 8) + arg2); - break; - case kopPushShortU: - arg1 = Uint8(*pbNext++); - arg2 = Uint8(*pbNext++); - vnStack.push_back((arg1 << 8) + arg2); - break; - case kopPushLong: - arg1 = Int8(*pbNext++); - arg2 = Uint8(*pbNext++); - arg3 = Uint8(*pbNext++); - arg4 = Uint8(*pbNext++); - vnStack.push_back((arg1 << 24) + (arg2 << 16) + (arg3 << 8) + arg4); - break; - - case kopNeg: - case kopTrunc8: case kopTrunc16: - case kopNot: - DoStackArithmetic1Arg(op, vnStack, psmf); - if (*psmf != ksmfContinue) - return 0; - break; - - case kopAdd: case kopSub: - case kopMul: case kopDiv: - case kopMin: case kopMax: - case kopAnd: case kopOr: - case kopEqual: case kopNotEq: - case kopLess: case kopGtr: - case kopLessEq: case kopGtrEq: - DoStackArithmetic2Args(op, vnStack, psmf); - if (*psmf != ksmfContinue) - return 0; - break; - - case kopCond: - DoConditional(vnStack, psmf); - if (*psmf != ksmfContinue) - return 0; - break; - - case kopNext: - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(!*pfMustGet); - DoNext(ptman, 1, psstrmIn, psstrmOut); - *pfMustGet = true; - *pfInserting = false; - } - break; - case kopNextN: - c = Int8(*pbNext++); - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(false); // for now we don't allow anything other than moving one slot - gAssert(!*pfMustGet); // forward at a time - DoNext(ptman, c, psstrmIn, psstrmOut); - *pfMustGet = true; - } - break; - case kopPutGlyph8bitObs: - case kopPutGlyph: - if (op == kopPutGlyph8bitObs) - nOutputClass = Uint8(*pbNext++); - else - { - nOutputClass = (Uint8(*pbNext++) << 8); - nOutputClass += Uint8(*pbNext++); - } - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(*pfMustGet); - DoPutGlyph(ptman, *pfInserting, nOutputClass, psstrmIn, psstrmOut); - *pfMustGet = false; - } - break; - case kopPutCopy: - nSlotRef = Int8(*pbNext++); - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(*pfMustGet); - DoPutCopy(ptman, *pfInserting, nSlotRef, psstrmIn, psstrmOut); - *pfMustGet = false; - } - break; - case kopPutSubs8bitObs: - case kopPutSubs: - nSlotRef = Int8(*pbNext++); - if (op == kopPutSubs8bitObs) - { - nInputClass = Uint8(*pbNext++); - nOutputClass = Uint8(*pbNext++); - } - else - { - nInputClass = (Uint8(*pbNext++) << 8); - nInputClass += Uint8(*pbNext++); - nOutputClass = (Uint8(*pbNext++) << 8); - nOutputClass += Uint8(*pbNext++); - } - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(*pfMustGet); - DoPutSubs(ptman, *pfInserting, nSlotRef, nInputClass, nOutputClass, - psstrmIn, psstrmOut); - *pfMustGet = false; - } - break; - case kopCopyNext: - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(*pfMustGet); - gAssert(!*pfInserting); // 0 means copy this slot - DoPutCopy(ptman, *pfInserting, 0, psstrmIn, psstrmOut); - DoNext(ptman, 1, psstrmIn, psstrmOut); - // *pfMustGet still = true - } - break; - case kopInsert: - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(*pfMustGet); - *pfInserting = true; - // *pfMustGet still = true - - if (ptman->LoggingTransduction()) - m_pzpst->RecordInsertionAt(psstrmOut->WritePos()); - } - break; - case kopDelete: - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(*pfMustGet); - DoDelete(ptman, psstrmIn, psstrmOut); - *pfMustGet = false; - } - break; - case kopAssoc: - c = Uint8(*pbNext++); - // std::vector<int> vnTmp; - for (i = 0; i < c; i++) - vnTmp.push_back(Int8(*pbNext++)); - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(!*pfMustGet); - DoAssoc(c, vnTmp, *pfInserting, psstrmIn, psstrmOut); - } - break; - case kopCntxtItem: - islotArg = Int8(*pbNext++); - c = Uint8(*pbNext++); - if (fConstraints) - { - // Old approach: - // If this is NOT the relevant item, push TRUE, which causes the subsequent tests - // (which are eventually ORed with it) to become irrelevant. - //vnStack.Push((int)(islotArg != islot)); - - // If this is not the relevant item, skip the specified number of bytes. - if (islotArg != islot) - { - pbNext += c; - vnStack.push_back(1); - } - } - else - { - gAssert(false); - } - break; - - case kopAttrSet: - case kopAttrAdd: - case kopAttrSub: - case kopAttrSetSlot: - slat = SlotAttrName(Uint8(*pbNext++)); // slot attribute ID - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(!*pfMustGet); - DoSetAttr(ptman, op, *pfInserting, slat, -1, vnStack, psstrmIn, psstrmOut); - if (*psmf != ksmfContinue) - return 0; - } - break; - case kopIAttrSet: - case kopIAttrAdd: - case kopIAttrSub: - case kopIAttrSetSlot: - slat = SlotAttrName(Uint8(*pbNext++)); // slot attribute ID - nIndex = Uint8(*pbNext++); // index; eg, global ID for component - if (fConstraints) - { - gAssert(false); - } - else - { - gAssert(!*pfMustGet); - DoSetAttr(ptman, op, *pfInserting, slat, nIndex, vnStack, - psstrmIn, psstrmOut); - if (*psmf != ksmfContinue) - return 0; - } - break; - - case kopPushSlotAttr: - slat = SlotAttrName(Uint8(*pbNext++)); - nSlotRef = Int8(*pbNext++); - if (fConstraints) - nSlotRef += islot + 1; // +1 to peek ahead to a slot we haven't "got" yet - DoPushSlotAttr(ptman, nSlotRef, *pfInserting, slat, -1, vnStack, psstrmIn, psstrmOut); - if (*psmf != ksmfContinue) - return 0; - break; - case kopPushISlotAttr: - slat = SlotAttrName(Uint8(*pbNext++)); - nSlotRef = Int8(*pbNext++); - nIndex = Uint8(*pbNext++); - if (fConstraints) - nSlotRef += islot + 1; // +1 to peek ahead to a slot we haven't "got" yet - DoPushSlotAttr(ptman, nSlotRef, *pfInserting, slat, nIndex, vnStack, psstrmIn, psstrmOut); - if (*psmf != ksmfContinue) - return 0; - break; - - case kopPushGlyphAttrObs: - case kopPushAttToGAttrObs: - case kopPushGlyphAttr: - case kopPushAttToGlyphAttr: - if (op == kopPushGlyphAttrObs || op == kopPushAttToGAttrObs) - nGlyphAttr = Uint8(*pbNext++); - else { - nGlyphAttr = (Uint8(*pbNext++) << 8); - nGlyphAttr += Uint8(*pbNext++); - } - nSlotRef = Int8(*pbNext++); - if (fConstraints) - nSlotRef += islot + 1; // +1 to peek ahead to a slot we haven't "got" yet - if (op == kopPushAttToGlyphAttr || op == kopPushAttToGAttrObs) - DoPushAttToGlyphAttr(ptman, nSlotRef, *pfInserting, nGlyphAttr, - vnStack, psstrmIn, psstrmOut); - else - DoPushGlyphAttr(ptman, nSlotRef, *pfInserting, nGlyphAttr, vnStack, - psstrmIn, psstrmOut); - if (*psmf != ksmfContinue) - return 0; - break; - case kopPushGlyphMetric: - case kopPushAttToGlyphMetric: - nGlyphAttr = Uint8(*pbNext++); - nSlotRef = Int8(*pbNext++); - nAttLevel = Int8(*pbNext++); - if (fConstraints) - nSlotRef += islot + 1; // +1 to peek ahead to a slot we haven't "got" yet - if (op == kopPushAttToGlyphMetric) - DoPushAttToGlyphMetric(ptman, nSlotRef, *pfInserting, nGlyphAttr, nAttLevel, - vnStack, psstrmIn, psstrmOut); - else - DoPushGlyphMetric(ptman, nSlotRef, *pfInserting, nGlyphAttr, nAttLevel, - vnStack, psstrmIn, psstrmOut); - if (*psmf != ksmfContinue) - return 0; - break; - case kopPushFeat: - nFeat = Uint8(*pbNext++); - nSlotRef = Int8(*pbNext++); - if (fConstraints) - nSlotRef += islot + 1; // +1 to peek ahead to a slot we haven't "got" yet -// else -// nSlotRef = 0; - DoPushFeatValue(ptman, nSlotRef, *pfInserting, nFeat, vnStack, psstrmIn, psstrmOut); - if (*psmf != ksmfContinue) - return 0; - break; - case kopPushProcState: - nPState = Uint8(*pbNext++); - gAssert(fConstraints); - DoPushProcState(ptman, nPState, vnStack); - break; - case kopPushVersion: - vnStack.push_back(kRuleVersion); - break; - case kopPopRet: - if ((*psmf = CheckStack(vnStack, 1)) != ksmfContinue) - return 0; - nRet = vnStack.back(); - vnStack.pop_back(); - if (vnStack.size() != 0) - { - gAssert(false); - *psmf = ksmfStackNotEmptied; - } - else - *psmf = ksmfDone; - break; - case kopRetZero: - nRet = 0; - if (vnStack.size() != 0) - { - gAssert(false); - *psmf = ksmfStackNotEmptied; - } - else - *psmf = ksmfDone; - break; - case kopRetTrue: - nRet = 1; - if (vnStack.size() != 0) - { - gAssert(false); - *psmf = ksmfStackNotEmptied; - } - else - *psmf = ksmfDone; - break; - - default: - gAssert(false); - } - - *ppbArg = pbNext; - return nRet; -} - -/*---------------------------------------------------------------------------------------------- - Perform arithmetic functions that take two arguments. -----------------------------------------------------------------------------------------------*/ -void GrPass::DoStackArithmetic2Args(ActionCommand op, std::vector<int> & vnStack, - StackMachineFlag * psmf) -{ - if ((*psmf = CheckStack(vnStack, 2)) != ksmfContinue) - return; - - int nArg2 = vnStack.back(); - vnStack.pop_back(); - int nArg1 = vnStack.back(); - vnStack.pop_back(); - - int nResult; - - switch (op) - { - case kopAdd: nResult = nArg1 + nArg2; break; - case kopSub: nResult = nArg1 - nArg2; break; - case kopMul: nResult = nArg1 * nArg2; break; - case kopDiv: nResult = nArg1 / nArg2; break; - case kopMin: nResult = min(nArg1, nArg2); break; - case kopMax: nResult = max(nArg1, nArg2); break; - case kopAnd: nResult = (nArg1 != 0 && nArg2 != 0)? 1: 0; break; - case kopOr: nResult = (nArg1 != 0 || nArg2 != 0)? 1: 0; break; - case kopEqual: nResult = (nArg1 == nArg2)? 1: 0; break; - case kopNotEq: nResult = (nArg1 != nArg2)? 1: 0; break; - case kopLess: nResult = (nArg1 < nArg2)? 1: 0; break; - case kopLessEq: nResult = (nArg1 <= nArg2)? 1: 0; break; - case kopGtr: nResult = (nArg1 > nArg2)? 1: 0; break; - case kopGtrEq: nResult = (nArg1 >= nArg2)? 1: 0; break; - default: - Assert(false); - } - - vnStack.push_back(nResult); -} - -/*---------------------------------------------------------------------------------------------- - Perform arithmetic functions that take one argument. -----------------------------------------------------------------------------------------------*/ -void GrPass::DoStackArithmetic1Arg(ActionCommand op, std::vector<int> & vnStack, - StackMachineFlag * psmf) -{ - if ((*psmf = CheckStack(vnStack, 1)) != ksmfContinue) - return; - - int nArg = vnStack.back(); - vnStack.pop_back(); - int nResult; - - switch (op) - { - case kopNeg: nResult = nArg * -1; break; - case kopTrunc8: nResult = nArg & 0xFF; break; - case kopTrunc16: nResult = nArg & 0xFFFF; break; - case kopNot: nResult = (nArg == 0)? 1: 0; break; - default: - Assert(false); - } - - vnStack.push_back(nResult); -} - -/*---------------------------------------------------------------------------------------------- - Perform the conditional statement. -----------------------------------------------------------------------------------------------*/ -void GrPass::DoConditional(std::vector<int> & vnStack, StackMachineFlag * psmf) -{ - if ((*psmf = CheckStack(vnStack, 3)) != ksmfContinue) - return; - - int nArg3 = vnStack.back(); - vnStack.pop_back(); - int nArg2 = vnStack.back(); - vnStack.pop_back(); - int nArg1 = vnStack.back(); - vnStack.pop_back(); - - if (nArg1 == 0) - vnStack.push_back(nArg3); - else - vnStack.push_back(nArg2); -} - -/*---------------------------------------------------------------------------------------------- - Check to make sure the stack has the appropriate number of items on it; if not, - return a stack error flag. -----------------------------------------------------------------------------------------------*/ -GrPass::StackMachineFlag GrPass::CheckStack(std::vector<int> & vnStack, int cn) -{ - if (signed(vnStack.size()) < cn) - return ksmfUnderflow; - else - return ksmfContinue; -} - -/*---------------------------------------------------------------------------------------------- - We are finished processing a slot; go on to the next slot, or possibly go backwards. -----------------------------------------------------------------------------------------------*/ -void GrPass::DoNext(GrTableManager * ptman, - int cslot, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - gAssert(cslot == 1); // for now anyway -} - -/*---------------------------------------------------------------------------------------------- - Set the next glyph to be the given class. There should only be one member of the class, - but if there happens to be more than one, just use the first member. - All the slot attributes remain unchanged from the current input slot; associations are - neutralized. - - @param ptman - table manager, for generating new slots - @param fInserting - true if this slot is being inserted, not copied - @param nReplacementClass - class from which to take replacement glyph (corresponding to - selector slot's glyph's index in selector class) - @param psstrmIn / Out - input/output streams -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPutGlyph(GrTableManager * ptman, bool fInserting, int nReplacementClass, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - EngineState * pengst = ptman->State(); - - // If we are exactly at the segment boundary, pass the information on to the output stream. - // Note that inserted items always go outside the segment, if they are at the boundary - // (you DON'T want them between the segment boundary and the LB slot!). - bool fSetSegMin = psstrmIn->AtSegMin() && !fInserting; - bool fSetSegLim = psstrmIn->AtSegLim(); - - // Slot to copy features and text properties from: - GrSlotState * pslotNextInput; - if (psstrmIn->AtEndOfContext()) - { - gAssert(fInserting); - pslotNextInput = psstrmIn->RuleInputSlot(0, psstrmOut); - } - else - pslotNextInput = (fInserting)? psstrmIn->Peek(): psstrmIn->NextGet(); - - gid16 nGlyphReplacement = ptman->GetClassGlyphIDAt(nReplacementClass, 0); - - GrSlotState * pslotNew; - if (fInserting) - { - pengst->NewSlot(nGlyphReplacement, pslotNextInput, m_ipass, &pslotNew); - // leave associations empty; eventually they will be "neutralized" - } - else - { - pengst->NewSlotCopy(pslotNextInput, m_ipass, &pslotNew); - pslotNew->SetGlyphID(nGlyphReplacement); - ptman->SetSlotAttrsFromGlyphAttrs(pslotNew); - } - - if (fSetSegMin) - psstrmOut->SetSegMinToWritePos(false); - if (fSetSegLim) - psstrmOut->SetSegLimToWritePos(false); - psstrmOut->NextPut(pslotNew); -} - -/*---------------------------------------------------------------------------------------------- - Copy a glyph from the given slot in the input to the output. All the associations and slot - attributes are copied from the specified slot as well. Consume a slot from the input - (which may or may not be the slot we're copying). - - @param ptman - table manager, for generating new slots - @param fInserting - true if this slot is being inserted, not copied - @param cslotCopyFrom - slot to copy from - @param psstrmIn / Out - input/output streams -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPutCopy(GrTableManager * ptman, bool fInserting, int cslotCopyFrom, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - EngineState * pengst = ptman->State(); - - // If we are exactly at the segment boundary, pass the information on to the output stream. - // Note that inserted items always go outside the segment, if they are at the boundary. - bool fSetSegMin = psstrmIn->AtSegMin() && !fInserting; - bool fSetSegLim = psstrmIn->AtSegLim(); - - if (!fInserting) - { - gAssert(!psstrmIn->AtEndOfContext()); - // Absorb next slot - psstrmIn->NextGet(); - } - - GrSlotState * pslotCopyFrom = psstrmIn->RuleInputSlot(cslotCopyFrom, psstrmOut); - - GrSlotState * pslotNew; - pengst->NewSlotCopy(pslotCopyFrom, m_ipass, &pslotNew); - - if (fSetSegMin) - psstrmOut->SetSegMinToWritePos(false); - if (fSetSegLim) - psstrmOut->SetSegLimToWritePos(false); - psstrmOut->NextPut(pslotNew); -} - -/*---------------------------------------------------------------------------------------------- - Copy the current slot from the input to the output, substituting the corresponding glyph - in the output class. All the associations and slot attributes remain unchanged from the - current input slot. - - @param ptman - table manager, for generating new slots - @param fInserting - true if this slot is being inserted, not copied - @param cslotSel - selector slot, relative to current slot - @param nSelectorClass - class of selector slot - @param nReplacementClass - class from which to take replacement glyph (corresponding to - selector slot's glyph's index in selector class) - @param psstrmIn / Out - input/output streams -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPutSubs(GrTableManager * ptman, bool fInserting, - int cslotSel, int nSelClass, int nReplacementClass, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - bool fAtSegMin, fAtSegLim; - GrSlotState * pslotNextInput; - DoPutSubsInit(psstrmIn, psstrmOut, fInserting, &pslotNextInput, &fAtSegMin, &fAtSegLim); - - GrSlotState * pslotInSelector = psstrmIn->RuleInputSlot(cslotSel, psstrmOut); - - gid16 gidSelector = pslotInSelector->GlyphID(); - int nSelIndex = ptman->GetIndexInGlyphClass(nSelClass, gidSelector); - gAssert(nSelIndex != -1); - gid16 gidReplacement = (nSelIndex == -1)? - gidSelector: - ptman->GetClassGlyphIDAt(nReplacementClass, nSelIndex); - - DoPutSubsAux(ptman, fInserting, gidReplacement, psstrmIn, psstrmOut, pslotNextInput, - fAtSegMin, fAtSegLim); -} - -/*---------------------------------------------------------------------------------------------- - Copy the current slot from the input to the output, substituting the corresponding glyph - in the output class based on 2 input classes. All the associations and slot attributes - remain unchanged from the current input slot. - - @param ptman - table manager, for generating new slots - @param fInserting - true if this slot is being inserted, not copied - @param cslotSel - selector slot, relative to current slot - @param nSelectorClass - class of selector slot - @param nReplacementClass - class from which to take replacement glyph (corresponding to - selector slot's glyph's index in selector class) - @param psstrmIn / Out - input/output streams -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPutSubs2(GrTableManager * ptman, bool fInserting, - int cslotSel1, int nSelClass1, int cslotSel2, int nSelClass2, int nReplacementClass, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - bool fAtSegMin, fAtSegLim; - GrSlotState * pslotNextInput; - DoPutSubsInit(psstrmIn, psstrmOut, fInserting, &pslotNextInput, &fAtSegMin, &fAtSegLim); - - GrSlotState * pslotInSelector1 = psstrmIn->RuleInputSlot(cslotSel1, psstrmOut); - gid16 gidSelector1 = pslotInSelector1->GlyphID(); - int nSelIndex1 = ptman->GetIndexInGlyphClass(nSelClass1, gidSelector1); - gAssert(nSelIndex1 != -1); - //size_t cClassLen1 = ptman->NumberOfGlyphsInClass(nSelClass1); - - GrSlotState * pslotInSelector2 = psstrmIn->RuleInputSlot(cslotSel2, psstrmOut); - gid16 gidSelector2 = pslotInSelector2->GlyphID(); - int nSelIndex2 = ptman->GetIndexInGlyphClass(nSelClass2, gidSelector2); - gAssert(nSelIndex2 != -1); - size_t cClassLen2 = ptman->NumberOfGlyphsInClass(nSelClass2); - - int nSelIndex = (nSelIndex1 == -1 || nSelIndex2 == -1) ? - -1 : - (nSelIndex1 * static_cast<int>(cClassLen2)) + nSelIndex2; - - gid16 gidReplacement = (nSelIndex == -1)? - gidSelector1: - ptman->GetClassGlyphIDAt(nReplacementClass, nSelIndex); - - DoPutSubsAux(ptman, fInserting, gidReplacement, psstrmIn, psstrmOut, pslotNextInput, - fAtSegMin, fAtSegLim); -} - -/*---------------------------------------------------------------------------------------------- - Copy the current slot from the input to the output, substituting the corresponding glyph - in the output class based on 2 input classes. All the associations and slot attributes - remain unchanged from the current input slot. - - @param ptman - table manager, for generating new slots - @param fInserting - true if this slot is being inserted, not copied - @param cslotSel - selector slot, relative to current slot - @param nSelectorClass - class of selector slot - @param nReplacementClass - class from which to take replacement glyph (corresponding to - selector slot's glyph's index in selector class) - @param psstrmIn / Out - input/output streams -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPutSubs3(GrTableManager * ptman, bool fInserting, - int cslotSel1, int nSelClass1, int cslotSel2, int nSelClass2, int cslotSel3, int nSelClass3, - int nReplacementClass, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - bool fAtSegMin, fAtSegLim; - GrSlotState * pslotNextInput; - DoPutSubsInit(psstrmIn, psstrmOut, fInserting, &pslotNextInput, &fAtSegMin, &fAtSegLim); - - GrSlotState * pslotInSelector1 = psstrmIn->RuleInputSlot(cslotSel1, psstrmOut); - gid16 gidSelector1 = pslotInSelector1->GlyphID(); - int nSelIndex1 = ptman->GetIndexInGlyphClass(nSelClass1, gidSelector1); - gAssert(nSelIndex1 != -1); - //size_t cClassLen1 = ptman->NumberOfGlyphsInClass(nSelClass1); - - GrSlotState * pslotInSelector2 = psstrmIn->RuleInputSlot(cslotSel2, psstrmOut); - gid16 gidSelector2 = pslotInSelector2->GlyphID(); - int nSelIndex2 = ptman->GetIndexInGlyphClass(nSelClass2, gidSelector2); - gAssert(nSelIndex2 != -1); - size_t cClassLen2 = ptman->NumberOfGlyphsInClass(nSelClass2); - -// GrSlotState * pslotInSelector3 = psstrmIn->RuleInputSlot(cslotSel3, psstrmOut); -// gid16 gidSelector3 = pslotInSelector3->GlyphID(); - int nSelIndex3 = ptman->GetIndexInGlyphClass(nSelClass3, gidSelector2); - gAssert(nSelIndex3 != -1); - size_t cClassLen3 = ptman->NumberOfGlyphsInClass(nSelClass3); - - int nSelIndex = (nSelIndex1 == -1 || nSelIndex2 == -1 || nSelIndex3 == -1) ? - -1 : - (((nSelIndex1 * static_cast<int>(cClassLen2)) + nSelIndex2) * static_cast<int>(cClassLen3)) + nSelIndex3; - - gid16 gidReplacement = (nSelIndex == -1)? - gidSelector1: - ptman->GetClassGlyphIDAt(nReplacementClass, nSelIndex); - - DoPutSubsAux(ptman, fInserting, gidReplacement, psstrmIn, psstrmOut, pslotNextInput, - fAtSegMin, fAtSegLim); -} - - -/*---------------------------------------------------------------------------------------------- - Initial common part of all the DoPutSubs... methods. -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPutSubsInit(GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, bool fInserting, - GrSlotState ** ppslotNextInput, bool * pfAtSegMin, bool * pfAtSegLim) -{ - // Do this before reading from stream. - *pfAtSegMin = psstrmIn->AtSegMin(); - *pfAtSegLim = psstrmIn->AtSegLim(); - - // Slot to copy features and text properties from: - if (psstrmIn->AtEndOfContext()) - { - gAssert(fInserting); - *ppslotNextInput = psstrmIn->RuleInputSlot(0, psstrmOut); - } - else - *ppslotNextInput = (fInserting)? psstrmIn->Peek(): psstrmIn->NextGet(); -} - -/*---------------------------------------------------------------------------------------------- - Common part of all the DoPutSubs... methods. -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPutSubsAux(GrTableManager * ptman, bool fInserting, gid16 nGlyphReplacement, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, GrSlotState * pslotNextInput, - bool fAtSegMin, bool fAtSegLim) -{ - EngineState * pengst = ptman->State(); - - // If we are exactly at the segment boundary, pass the information on to the output stream. - // Note that inserted items always go outside the segment, if they are at the boundary. - bool fSetSegMin = fAtSegMin && !fInserting; - bool fSetSegLim = fAtSegLim; - - GrSlotState * pslotNew; - if (fInserting) - { - pengst->NewSlot(nGlyphReplacement, pslotNextInput, m_ipass, &pslotNew); - // leave associations empty; eventually they will be "neutralized" - } - else - { - pengst->NewSlotCopy(pslotNextInput, m_ipass, &pslotNew); - pslotNew->SetGlyphID(nGlyphReplacement); - ptman->SetSlotAttrsFromGlyphAttrs(pslotNew); - } - - if (fSetSegMin) - psstrmOut->SetSegMinToWritePos(false); - if (fSetSegLim) - psstrmOut->SetSegLimToWritePos(false); - psstrmOut->NextPut(pslotNew); -} - -/*---------------------------------------------------------------------------------------------- - A slot has just been inserted. Clear all the associations; eventually (unless we go on - to set the associations explicitly) we will set its before-assoc to the slot after it - and its after-assoc to the slot before it. This makes it basically unselectable. - OBSOLETE - handled by slot initialization code -----------------------------------------------------------------------------------------------*/ -void GrPass::SetNeutralAssocs(GrSlotState * pslotNew, GrSlotStream * psstrmIn) -{ - pslotNew->ClearAssocs(); -} - -/*---------------------------------------------------------------------------------------------- - Delete the next slot in the input. - - @param psstrmIn - input stream - @param psstrmOut - output stream -----------------------------------------------------------------------------------------------*/ -void GrPass::DoDelete(GrTableManager * ptman, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - if (psstrmIn->AtSegMin()) - psstrmOut->SetSegMinToWritePos(); - if (psstrmIn->AtSegLim()) - psstrmOut->SetSegLimToWritePos(); - - GrSlotState * pslot = psstrmIn->NextGet(); - pslot->MarkDeleted(); - - if (ptman->LoggingTransduction()) - m_pzpst->RecordDeletionBefore(psstrmOut->WritePos()); -} - -/*---------------------------------------------------------------------------------------------- - Set the associations for the current slot. Any previous associations will be overwritten. - - @param cn - number of associations - @param vnAssoc - list of associations - @param fInserting - whether current slot was inserted - @param psstrmIn / Out - input/output streams -----------------------------------------------------------------------------------------------*/ -void GrPass::DoAssoc(int cnAssocs, std::vector<int> & vnAssocs, bool fInserting, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - gAssert((unsigned)cnAssocs == vnAssocs.size()); - - // Sort the list of associations. It's okay to use a simple bubble sort - // since we expect the list to be very short. Ideally we should remove duplicates - // too but I don't think duplicates actually hurt anything. - for (int i1 = 0; i1 < cnAssocs - 1; i1++) - { - for (int i2 = i1 + 1; i2 < cnAssocs; i2++) - { - if (vnAssocs[i2] < vnAssocs[i1]) - { - int nTmp = vnAssocs[i2]; - vnAssocs[i2] = vnAssocs[i1]; - vnAssocs[i1] = nTmp; - } - } - } - - std::vector<GrSlotState *> vpslotAssocs; - vpslotAssocs.resize(cnAssocs); - for (int i = 0; i < cnAssocs; i++) - vpslotAssocs[i] = psstrmIn->RuleInputSlot(vnAssocs[i], psstrmOut); - - GrSlotState * pslot = psstrmOut->RuleOutputSlot(); - pslot->Associate(vpslotAssocs); -} - -/*---------------------------------------------------------------------------------------------- - Set a slot attribute for the current slot; the value is on the stack. - - @param op - command - @param fInserting - whether current slot was inserted - @param slat - slot attribute to set - @param slati - slot attribute index, or -1 for non-indexed attribute - @param vnStack - stack to read value from - @param psstrmIn / Out - input/output streams -----------------------------------------------------------------------------------------------*/ -void GrPass::DoSetAttr(GrTableManager * ptman, ActionCommand op, bool fInserting, - SlotAttrName slat, int slati, std::vector<int> & vnStack, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - int nVal = vnStack.back(); - vnStack.pop_back(); - - if (slat == kslatUserDefnV1) - slat = kslatUserDefn; - - if (slati != -1 && slat != kslatCompRef && slat != kslatUserDefn) - { - // Invalid slot attribute index. - gAssert(false); - slati = -1; - } - - if (slati == -1 && (slat == kslatCompRef || slat == kslatUserDefn)) - { - // Missing slot attribute index. - gAssert(false); - slati = 0; - } - - if (slat == kslatPosX || slat == kslatPosY) - { - // Doesn't make sense to set the pos attribute. - gAssert(false); - return; - } - - GrSlotState * pslotIn = psstrmIn->RuleInputSlot(0, psstrmOut); - - GrSlotState * pslotComp; - - int nOldVal; - - if (op == kopAttrAdd || op == kopAttrSub || op == kopIAttrAdd || op == kopIAttrSub) - { - // Incrementing or decrementing. - - gAssert(!fInserting); - - switch (slat) - { - case kslatAdvX: nOldVal = pslotIn->AdvanceX(ptman); break; - case kslatAdvY: nOldVal = pslotIn->AdvanceY(ptman); break; - case kslatShiftX: nOldVal = pslotIn->ShiftX(); break; - case kslatShiftY: nOldVal = pslotIn->ShiftY(); break; - - case kslatAttAtX: nOldVal = pslotIn->AttachAtX(ptman, psstrmIn); break; - case kslatAttAtY: nOldVal = pslotIn->AttachAtY(); break; - case kslatAttAtXoff: nOldVal = pslotIn->AttachAtXOffset(); break; - case kslatAttAtYoff: nOldVal = pslotIn->AttachAtYOffset(); break; - - case kslatAttWithX: nOldVal = pslotIn->AttachWithX(ptman, psstrmIn); break; - case kslatAttWithY: nOldVal = pslotIn->AttachWithY(); break; - case kslatAttWithXoff: nOldVal = pslotIn->AttachWithXOffset(); break; - case kslatAttWithYoff: nOldVal = pslotIn->AttachWithYOffset(); break; - - case kslatUserDefn: nOldVal = pslotIn->UserDefn(slati); break; - - case kslatMeasureSol: nOldVal = pslotIn->MeasureSol(); break; - case kslatMeasureEol: nOldVal = pslotIn->MeasureEol(); break; - - case kslatJStretch: nOldVal = pslotIn->JStretch(); break; - case kslatJShrink: nOldVal = pslotIn->JShrink(); break; - case kslatJStep: nOldVal = pslotIn->JStep(); break; - case kslatJWeight: nOldVal = pslotIn->JWeight(); break; - case kslatJWidth: nOldVal = pslotIn->JWidth(); break; - - // These are kind of odd, but maybe. - case kslatAttLevel: nOldVal = pslotIn->AttachLevel(); break; - case kslatBreak: nOldVal = pslotIn->BreakWeight(); break; - case kslatDir: nOldVal = pslotIn->Directionality(); break; - - default: - // Kind of attribute that it makes no sense to increment. - gAssert(false); - return; - } - - if (op == kopAttrAdd || op == kopIAttrAdd) - nVal = nOldVal + nVal; - else - { - gAssert(op == kopAttrSub || op == kopIAttrSub); - nVal = nOldVal - nVal; - } - } - - GrSlotState * pslotOut = psstrmOut->RuleOutputSlot(); - - if (pslotOut->IsLineBreak(ptman->LBGlyphID())) - { - switch (slat) - { - case kslatAdvX: - case kslatAdvY: - case kslatShiftX: - case kslatShiftY: - - case kslatAttTo: - case kslatAttLevel: - case kslatAttAtX: - case kslatAttAtY: - case kslatAttAtGpt: - case kslatAttAtXoff: - case kslatAttAtYoff: - case kslatAttWithX: - case kslatAttWithY: - case kslatAttWithGpt: - case kslatAttWithXoff: - case kslatAttWithYoff: - - case kslatMeasureSol: - case kslatMeasureEol: - - case kslatJStretch: - case kslatJShrink: - case kslatJStep: - case kslatJWeight: - case kslatJWidth: - slat = kslatNoEffect; - break; - default: - ; // okay, do nothing - } - } - - nVal = GrGlyphSubTable::ConvertValueForVersion(nVal, slat, -1, m_fxdVersion); - - switch (slat) - { - case kslatAdvX: pslotOut->SetAdvanceX(nVal); break; - case kslatAdvY: pslotOut->SetAdvanceY(nVal); break; - case kslatShiftX: pslotOut->SetShiftX(nVal); break; - case kslatShiftY: pslotOut->SetShiftY(nVal); break; - - case kslatAttTo: pslotOut->SetAttachTo(nVal); break; - case kslatAttLevel: pslotOut->SetAttachLevel(nVal); break; - case kslatAttAtX: pslotOut->SetAttachAtX(nVal); break; - case kslatAttAtY: pslotOut->SetAttachAtY(nVal); break; - case kslatAttAtGpt: pslotOut->SetAttachAtGpoint(nVal); break; - case kslatAttAtXoff: pslotOut->SetAttachAtXOffset(nVal); break; - case kslatAttAtYoff: pslotOut->SetAttachAtYOffset(nVal); break; - case kslatAttWithX: pslotOut->SetAttachWithX(nVal); break; - case kslatAttWithY: pslotOut->SetAttachWithY(nVal); break; - case kslatAttWithGpt: pslotOut->SetAttachWithGpoint(nVal); break; - case kslatAttWithXoff: pslotOut->SetAttachWithXOffset(nVal); break; - case kslatAttWithYoff: pslotOut->SetAttachWithYOffset(nVal); break; - - case kslatUserDefn: pslotOut->SetUserDefn(slati, nVal); break; - - case kslatCompRef: - gAssert(nVal - 1 >= psstrmIn->RuleStartReadPos() - psstrmIn->ReadPosForNextGet()); - pslotComp = psstrmIn->RuleInputSlot(nVal, psstrmOut); - pslotOut->SetCompRefSlot(ptman, slati, pslotComp); - break; - - case kslatMeasureSol: pslotOut->SetMeasureSol(nVal); break; - case kslatMeasureEol: pslotOut->SetMeasureEol(nVal); break; - - case kslatJStretch: pslotOut->SetJStretch(nVal); break; - case kslatJShrink: pslotOut->SetJShrink(nVal); break; - case kslatJStep: pslotOut->SetJStep(nVal); break; - case kslatJWeight: pslotOut->SetJWeight(nVal); break; - case kslatJWidth: pslotOut->SetJWidth(nVal); break; - - case kslatBreak: pslotOut->SetBreakWeight(nVal); break; - case kslatDir: pslotOut->SetDirectionality(DirCode(nVal)); break; - case kslatInsert: pslotOut->SetInsertBefore(bool(nVal)); break; - - case kslatNoEffect: - // Do nothing. - break; - - default: - // Kind of attribute that it makes no sense to set. - gAssert(false); - return; - } -} - -/*---------------------------------------------------------------------------------------------- - Push value of a slot attribute onto the stack. - - @param nSlotRef - slot whose attribute we are interested in - @param fInserting - whether current slot was inserted - @param slat - slot attribute to get - @param slati - slot attribute index, or -1 for non-indexed attribute - @param vnStack - stack to push onto - @param psstrmIn - input stream -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPushSlotAttr(GrTableManager * ptman, - int nSlotRef, bool fInserting, - SlotAttrName slat, int slati, std::vector<int> & vnStack, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - GrSlotState * pslot = psstrmIn->RuleInputSlot(nSlotRef, psstrmOut, true); - if (pslot == NULL) - { - // Non-existent pre-context item. - vnStack.push_back(0); - return; - } - - int nVal; - int xyBogus; - - if (slat == kslatUserDefnV1) - slat = kslatUserDefn; - - if (slati != -1 && slat != kslatCompRef && slat != kslatUserDefn) - { - // Invalid slot attribute index. - gAssert(false); - slati = -1; - } - - if (slati == -1 && (slat == kslatCompRef || slat == kslatUserDefn)) - { - // Missing slot attribute index. - gAssert(false); - slati = 0; - } - - switch (slat) - { - case kslatAdvX: nVal = pslot->AdvanceX(ptman); break; - case kslatAdvY: nVal = pslot->AdvanceY(ptman); break; - case kslatShiftX: nVal = pslot->ShiftX(); break; - case kslatShiftY: nVal = pslot->ShiftY(); break; - - case kslatPosX: pslot->Position(ptman, psstrmIn, &nVal, &xyBogus); break; - case kslatPosY: pslot->Position(ptman, psstrmIn, &xyBogus, &nVal); break; - - case kslatAttTo: nVal = pslot->AttachTo(); break; - case kslatAttLevel: nVal = pslot->AttachLevel(); break; - case kslatAttAtX: nVal = pslot->AttachAtX(ptman, psstrmIn); break; - case kslatAttAtY: nVal = pslot->AttachAtY(); break; - case kslatAttAtGpt: nVal = pslot->AttachAtGpoint(); break; - case kslatAttAtXoff: nVal = pslot->AttachAtXOffset(); break; - case kslatAttAtYoff: nVal = pslot->AttachAtYOffset(); break; - case kslatAttWithX: nVal = pslot->AttachWithX(ptman, psstrmIn); break; - case kslatAttWithY: nVal = pslot->AttachWithY(); break; - case kslatAttWithGpt: nVal = pslot->AttachWithGpoint(); break; - case kslatAttWithXoff: nVal = pslot->AttachWithXOffset(); break; - case kslatAttWithYoff: nVal = pslot->AttachWithYOffset(); break; - - case kslatMeasureSol: nVal = pslot->MeasureSol(); break; - case kslatMeasureEol: nVal = pslot->MeasureEol(); break; - - case kslatJStretch: nVal = pslot->JStretch(); break; - case kslatJShrink: nVal = pslot->JShrink(); break; - case kslatJStep: nVal = pslot->JStep(); break; - case kslatJWeight: nVal = pslot->JWeight(); break; - case kslatJWidth: nVal = pslot->JWidth(); break; - - case kslatBreak: nVal = pslot->BreakWeight(); break; - case kslatDir: nVal = pslot->Directionality(); break; - case kslatInsert: nVal = pslot->InsertBefore(); break; - - case kslatUserDefn: nVal = pslot->UserDefn(slati); break; - - // Currently no way to look up component.X.ref. - - default: - // Invalid attribute. - gAssert(false); - nVal = 0; - } - - vnStack.push_back(nVal); -} - -/*---------------------------------------------------------------------------------------------- - Push value of a glyph attribute onto the stack. - - @param nSlotRef - slot whose attribute we are interested in - @param fInserting - whether current slot was inserted - @param nGlyphAttr - glyph attribute to get - @param vnStack - stack to push onto - @param psstrmIn - input stream -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPushGlyphAttr(GrTableManager * ptman, int nSlotRef, bool fInserting, - int nGlyphAttr, - std::vector<int> & vnStack, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - GrSlotState * pslot = psstrmIn->RuleInputSlot(nSlotRef, psstrmOut, true); - if (pslot == NULL) - { - // Non-existent pre-context item. - vnStack.push_back(0); - return; - } - int nVal = pslot->GlyphAttrValueEmUnits(ptman, nGlyphAttr); - vnStack.push_back(nVal); -} - -/*---------------------------------------------------------------------------------------------- - Push value of a glyph attribute onto the stack. The slot of interest is the slot to - which the current slot is attached. - - @param nSlotRef - leaf slot - @param fInserting - whether current slot was inserted - @param nGlyphAttr - glyph attribute to get - @param vnStack - stack to push onto - @param psstrmIn - input stream -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPushAttToGlyphAttr(GrTableManager * ptman, int nSlotRef, bool fInserting, - int nGlyphAttr, std::vector<int> & vnStack, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - // Note that it is the slot in the output stream that has - // the relevant attach.to attribute set. - GrSlotState * pslotLeaf = psstrmOut->RuleOutputSlot(0); - int srAttTo = pslotLeaf->AttachTo(); - if (srAttTo == 0) - { - gAssert(false); - vnStack.push_back(0); - return; - } - - GrSlotState * pslotRoot = psstrmIn->RuleInputSlot(nSlotRef + srAttTo, psstrmOut); - int nVal = pslotRoot->GlyphAttrValueEmUnits(ptman, nGlyphAttr); - vnStack.push_back(nVal); -} - -/*---------------------------------------------------------------------------------------------- - Push value of a glyph metric onto the stack. - - @param nSlotRef - slot whose attribute we are interested in - @param fInserting - whether current slot was inserted - @param nGlyphAttr - glyph attribute to get - @param nAttLevel - for accessing composite metrics - @param vnStack - stack to push onto - @param psstrmIn - input stream -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPushGlyphMetric(GrTableManager * ptman, int nSlotRef, bool fInserting, - int nGlyphAttr, int nAttLevel, - std::vector<int> & vnStack, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - GrSlotState * pslot = psstrmIn->RuleInputSlot(nSlotRef, psstrmOut, true); - if (pslot == NULL) - { - // Non-existent pre-context item. - vnStack.push_back(0); - return; - } - - DoPushGlyphMetricAux(ptman, pslot, nGlyphAttr, nAttLevel, vnStack, psstrmIn); -} - -/*---------------------------------------------------------------------------------------------- - Push value of a glyph metric onto the stack. The slot of interest is the slot to - which the current slot is attached. - - @param nSlotRef - slot whose attribute we are interested in - @param fInserting - whether current slot was inserted - @param nGlyphAttr - glyph attribute to get - @param nAttLevel - for accessing composite metrics - @param vnStack - stack to push onto - @param psstrmIn - input stream - @param psstrmOut - output stream -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPushAttToGlyphMetric(GrTableManager * ptman, int nSlotRef, bool fInserting, - int nGlyphAttr, int nAttLevel, - std::vector<int> & vnStack, - GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - // Note that it is the slot in the output stream that has - // the relevant attach.to attribute set. - GrSlotState * pslotLeaf = psstrmOut->RuleOutputSlot(0); - int srAttTo = pslotLeaf->AttachTo(); - if (srAttTo == 0) - { - gAssert(false); - vnStack.push_back(0); - return; - } - - GrSlotState * pslot = psstrmIn->RuleInputSlot(nSlotRef + srAttTo, psstrmOut); - - DoPushGlyphMetricAux(ptman, pslot, nGlyphAttr, nAttLevel, vnStack, psstrmIn); -} - -/*--------------------------------------------------------------------------------------------*/ - -void GrPass::DoPushGlyphMetricAux(GrTableManager * ptman, - GrSlotState * pslot, int nGlyphAttr, int nAttLevel, - std::vector<int> & vnStack, GrSlotStream * psstrmIn) -{ - int mVal; - GlyphMetric gmet = GlyphMetric(nGlyphAttr); - if (nAttLevel == 0 || gmet == kgmetAscent || gmet == kgmetDescent) - { - mVal = pslot->GlyphMetricEmUnits(ptman, nGlyphAttr); - } - else - { - pslot->CalcCompositeMetrics(ptman, psstrmIn, nAttLevel, true); - - float xy; - switch (gmet) - { - case kgmetLsb: xy = pslot->ClusterLsb(psstrmIn); break; - case kgmetRsb: xy = pslot->ClusterRsb(psstrmIn); break; - case kgmetBbTop: xy = pslot->ClusterBbTop(psstrmIn); break; - case kgmetBbBottom: xy = pslot->ClusterBbBottom(psstrmIn); break; - case kgmetBbLeft: xy = pslot->ClusterBbLeft(psstrmIn); break; - case kgmetBbRight: xy = pslot->ClusterBbRight(psstrmIn); break; - case kgmetBbHeight: xy = pslot->ClusterBbHeight(psstrmIn); break; - case kgmetBbWidth: xy = pslot->ClusterBbWidth(psstrmIn); break; -// case kgmetAdvHeight: xy = pslot->ClusterAdvHeight(psstrmIn); break; - case kgmetAdvWidth: xy = pslot->ClusterAdvWidth(psstrmIn); break; - default: - gAssert(false); - xy = 0; - } - mVal = ptman->LogToEmUnits(xy); - } - - vnStack.push_back(mVal); -} - -/*---------------------------------------------------------------------------------------------- - Push a feature value onto the stack. For rule actions, the slot of interest is the - current slot. - - @param nSlotRef - slot being examined - @param fInserting - whether current slot was inserted - @param nFeat - feature of interest - @param vnStack - stack to push onto - @param psstrmIn - input stream - @param psstrmOut - output stream -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPushFeatValue(GrTableManager * ptman, int nSlotRef, bool fInserting, - int nFeat, std::vector<int> & vnStack, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut) -{ - gAssert(!fInserting); - - GrSlotState * pslot = psstrmIn->RuleInputSlot(nSlotRef, psstrmOut, true); - if (pslot == NULL) - { - // Non-existent pre-context item. - vnStack.push_back(0); - return; - } - - int nVal = pslot->FeatureValue(nFeat); - vnStack.push_back(nVal); -} - -/*---------------------------------------------------------------------------------------------- - Push a processing-state value onto the stack. - - @param nFeat - feature of interest - @param vnStack - stack to push onto -----------------------------------------------------------------------------------------------*/ -void GrPass::DoPushProcState(GrTableManager * ptman, int nPState, std::vector<int> & vnStack) -{ - int nValue; - if (nPState == kpstatJustifyMode) - { - // Convert from internal modes to user modes. - int jmodi = ptman->InternalJustificationMode(); - switch (jmodi) - { - case kjmodiNormal: - case kjmodiCanShrink: - nValue = kjmoduNormal; - break; - case kjmodiMeasure: - nValue = kjmoduMeasure; - break; - case kjmodiJustify: - nValue = kjmoduJustify; - break; - default: - gAssert(false); - nValue = kjmoduNormal; - } - } - else if (nPState == kpstatJustifyLevel) - nValue = 1; // TODO: get justify level from ptman - vnStack.push_back(nValue); -} - -} // namespace gr |