summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite-engine/src/segment/GrSlotState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/graphite-engine/src/segment/GrSlotState.cpp')
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrSlotState.cpp1481
1 files changed, 0 insertions, 1481 deletions
diff --git a/Build/source/libs/graphite-engine/src/segment/GrSlotState.cpp b/Build/source/libs/graphite-engine/src/segment/GrSlotState.cpp
deleted file mode 100644
index f2d61e45eed..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrSlotState.cpp
+++ /dev/null
@@ -1,1481 +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: GrSlotState.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- GrSlotState class implementation.
--------------------------------------------------------------------------------*//*:End Ignore*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Initialize slots.
-----------------------------------------------------------------------------------------------*/
-// standard for pass 0 slots
-void GrSlotState::Initialize(gid16 chw, GrEngine * pgreng,
- GrFeatureValues fval, int ipass, int ichwSegOffset, int nUnicode)
-{
- Assert(ipass == 0);
- m_chwGlyphID = chw;
- m_chwActual = kInvalidGlyph;
- m_xysGlyphWidth = -1;
- m_bStyleIndex = byte(fval.m_nStyleIndex);
- u_intslot nullSlot;
- nullSlot.pslot = NULL;
- std::fill_n(PUserDefnBuf(), m_cnUserDefn, nullSlot);
- std::fill_n(PCompRefBuf(), m_cnCompPerLig, nullSlot);
- std::fill_n(PSlatiBuf(), m_cnCompPerLig, nullSlot);
- u_intslot * pFeatBuf = PFeatureBuf();
- for (size_t i = 0; i < m_cnFeat; i++)
- pFeatBuf[i].nValue = fval.m_rgnFValues[i];
- m_ipassFsmCol = -1;
- m_colFsm = -1;
-
- m_ipassModified = ipass;
- m_ichwSegOffset = ichwSegOffset;
- m_nUnicode = nUnicode;
- m_vpslotAssoc.clear();
- pgreng->InitSlot(this, nUnicode);
-
- switch (nUnicode)
- {
- case knLRM: m_spsl = kspslLRM; break;
- case knRLM: m_spsl = kspslRLM; break;
- case knLRO: m_spsl = kspslLRO; break;
- case knRLO: m_spsl = kspslRLO; break;
- case knLRE: m_spsl = kspslLRE; break;
- case knRLE: m_spsl = kspslRLE; break;
- case knPDF: m_spsl = kspslPDF; break;
- default:
- Assert(m_spsl == kspslNone);
- m_spsl = kspslNone;
- break;
- }
-}
-
-// line-break slots
-void GrSlotState::Initialize(gid16 chw, GrEngine * pgreng,
- GrSlotState * pslotFeat, int ipass, int ichwSegOffset)
-{
- m_chwGlyphID = chw;
- m_chwActual = kInvalidGlyph;
- m_xysGlyphWidth = -1;
- u_intslot nullSlot;
- nullSlot.pslot = NULL;
- std::fill_n(PUserDefnBuf(), m_cnUserDefn, nullSlot);
- std::fill_n(PCompRefBuf(), m_cnCompPerLig, nullSlot);
- std::fill_n(PSlatiBuf(), m_cnCompPerLig, nullSlot);
- CopyFeaturesFrom(pslotFeat);
- m_ipassModified = ipass;
- m_ichwSegOffset = ichwSegOffset;
- m_nUnicode = -1;
- m_vpslotAssoc.clear();
- pgreng->InitSlot(this);
- // Caller is responsible for setting m_spsl.
- m_ipassFsmCol = -1;
- m_colFsm = -1;
-}
-
-// for inserting new slots after pass 0 (under-pos and unicode are irrelevant)
-void GrSlotState::Initialize(gid16 chw, GrEngine * pgreng,
- GrSlotState * pslotFeat, int ipass)
-{
- m_chwGlyphID = chw;
- m_chwActual = kInvalidGlyph;
- m_xysGlyphWidth = -1;
- u_intslot nullSlot;
- nullSlot.pslot = NULL;
- std::fill_n(PUserDefnBuf(), m_cnUserDefn, nullSlot);
- std::fill_n(PCompRefBuf(), m_cnCompPerLig, nullSlot);
- std::fill_n(PSlatiBuf(), m_cnCompPerLig, nullSlot);
- CopyFeaturesFrom(pslotFeat);
- m_ipassModified = ipass;
- m_ichwSegOffset = kInvalid;
- m_nUnicode = kInvalid;
- m_vpslotAssoc.clear();
- pgreng->InitSlot(this);
- m_spsl = kspslNone;
- m_ipassFsmCol = -1;
- m_colFsm = -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- The slot has been modified by the given pass and therefore is in a new state;
- make a new SlotState initialized from the old one.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::InitializeFrom(GrSlotState * pslotOld, int ipass)
-{
- CopyFrom(pslotOld, false);
-
- m_ipassModified = ipass;
- m_pslotPrevState = pslotOld;
- m_ichwSegOffset = kInvalid;
- m_vpslotAssoc.clear();
- m_vpslotAssoc.push_back(pslotOld);
-
- m_dircProc = pslotOld->m_dircProc;
- m_fDirProcessed = pslotOld->m_fDirProcessed;
-
- // Since we're going on to a new pass, no point in copying these:
- m_ipassFsmCol = -1;
- m_colFsm = -1;
-
- ////FixAttachmentTree(pslotOld);
-}
-
-/*----------------------------------------------------------------------------------------------
- Copy the features and style information from the given slot.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::CopyFeaturesFrom(GrSlotState * pslotSrc)
-{
- m_bStyleIndex = pslotSrc->m_bStyleIndex;
- Assert(m_cnFeat == pslotSrc->m_cnFeat);
- std::copy(pslotSrc->PFeatureBuf(), pslotSrc->PFeatureBuf() + m_cnFeat, PFeatureBuf());
-}
-
-/*----------------------------------------------------------------------------------------------
- Copy the basic information.
- Warning: the functions below will break if GrSlotState and subclasses are given virtual
- methods. In that case, we will need to copy from the address of the first variable in
- GrSlotAbstract.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::CopyFrom(GrSlotState * pslot, bool fCopyEverything)
-{
- GrSlotAbstract::CopyAbstractFrom(pslot);
- std::copy(pslot->m_prgnVarLenBuf, pslot->m_prgnVarLenBuf + CExtraSpace(), m_prgnVarLenBuf);
-
- if (fCopyEverything)
- {
- Assert(false);
- m_ipassModified = pslot->m_ipassModified;
- m_pslotPrevState = pslot->m_pslotPrevState;
- m_ichwSegOffset = pslot->m_ichwSegOffset;
- m_colFsm = pslot->m_colFsm;
- m_ipassFsmCol = pslot->m_ipassFsmCol;
- // TODO: copy m_vpslotAssocs.
- m_fNeutralAssocs = pslot->m_fNeutralAssocs;
- }
-
- m_dislotRootFixed = pslot->m_dislotRootFixed;
-
- m_vdislotAttLeaves.resize(pslot->m_vdislotAttLeaves.size());
- for (size_t i = 0; i < pslot->m_vdislotAttLeaves.size(); i++)
- m_vdislotAttLeaves[i] = pslot->m_vdislotAttLeaves[i];
-
- m_islotPosPass = pslot->m_islotPosPass;
- m_nUnicode = pslot->m_nUnicode;
- m_dircProc = pslot->m_dircProc;
- m_fDirProcessed = pslot->m_fDirProcessed;
- m_cnUserDefn = pslot->m_cnUserDefn;
- m_cnFeat = pslot->m_cnFeat;
- m_bStyleIndex = pslot->m_bStyleIndex;
- m_mAdvanceX = pslot->m_mAdvanceX;
- m_mAdvanceY = pslot->m_mAdvanceY;
- m_mShiftX = pslot->m_mShiftX;
- m_mShiftY = pslot->m_mShiftY;
- m_srAttachTo = pslot->m_srAttachTo;
- m_nAttachLevel = pslot->m_nAttachLevel;
- m_mAttachAtX = pslot->m_mAttachAtX;
- m_mAttachAtY = pslot->m_mAttachAtY;
- m_mAttachAtXOffset = pslot->m_mAttachAtXOffset;
- m_mAttachAtYOffset = pslot->m_mAttachAtYOffset;
- m_mAttachWithX = pslot->m_mAttachWithX;
- m_mAttachWithY = pslot->m_mAttachWithY;
- m_mAttachWithXOffset = pslot->m_mAttachWithXOffset;
- m_mAttachWithYOffset = pslot->m_mAttachWithYOffset;
- m_nAttachAtGpoint = pslot->m_nAttachAtGpoint;
- m_nAttachWithGpoint = pslot->m_nAttachWithGpoint;
- m_fAttachMod = pslot->m_fAttachMod;
- m_fShiftMod = pslot->m_fShiftMod;
- m_fIgnoreAdvance = pslot->m_fIgnoreAdvance;
-
- m_nCompositeLevel = kNegInfinity; // uncalculated, so don't need to copy the positions??
-}
-
-void GrSlotAbstract::CopyAbstractFrom(GrSlotState * pslot)
-{
- u_intslot * pnBufSave = m_prgnVarLenBuf;
- *this = *pslot;
- m_prgnVarLenBuf = pnBufSave;
- Assert(m_prgnVarLenBuf);
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize the output slot from the one use within the passes, with the basic information.
- Warning: this function will break if GrSlotState and subclasses are given virtual
- methods. In that case, we will need to copy from the address of the first variable in
- GrSlotAbstract.
-----------------------------------------------------------------------------------------------*/
-void GrSlotOutput::InitializeOutputFrom(GrSlotState * pslot)
-{
- CopyAbstractFrom(pslot);
-
- // Copy just the component information, which is of length (m_cnCompPerLig * 2)
- //std::copy(pslot->PCompRefBuf(),
- // pslot->PCompRefBuf() + (m_cnCompPerLig * 2),
- // this->PCompRefBufSlout());
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the ID of the actual glyph that will be used for output and metrics. This is the
- same for most glyphs, but will be different for pseudo-glyphs.
-----------------------------------------------------------------------------------------------*/
-gid16 GrSlotAbstract::ActualGlyphForOutput(GrTableManager * ptman)
-{
- if (m_chwActual == kInvalidGlyph)
- m_chwActual = ptman->ActualGlyphForOutput(m_chwGlyphID);
- return m_chwActual;
-}
-/*----------------------------------------------------------------------------------------------
- We are replacing the old slot with the recipient. Replace the pointers in any attachment
- root or attached leaf slots.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::FixAttachmentTree(GrSlotState * pslotOld)
-{
-#if 0
- pslotOld->m_vpslotAttLeaves.CopyTo(m_vpslotAttLeaves);
- for (int islot = 0; islot < m_vpslotAttLeaves.Size(); islot++)
- {
- Assert(m_vpslotAttLeaves[islot]->m_pslotAttRoot == pslotOld);
- m_vpslotAttLeaves[islot]->m_pslotAttRoot = this;
- }
-
- m_pslotAttRoot = pslotOld->m_pslotAttRoot;
- if (m_pslotAttRoot)
- {
- for (int islot = 0; islot < m_pslotAttRoot->m_vpslotAttLeaves.Size(); islot++)
- {
- if (m_pslotAttRoot->m_vpslotAttLeaves[islot] == pslotOld)
- {
- m_pslotAttRoot->m_vpslotAttLeaves.Delete(islot);
- m_pslotAttRoot->m_vpslotAttLeaves.Push(this);
- return;
- }
- }
- Assert(false); // didn't find old slot in the list
- }
-#endif // 0
-}
-
-/*----------------------------------------------------------------------------------------------
- Make sure all the values are cached that are needed to be copied to the output slots
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::EnsureCacheForOutput(GrTableManager * ptman)
-{
- // Make sure the actual glyph ID is set.
- gid16 gidActual = ActualGlyphForOutput(ptman);
-
- // Make sure the glyph metrics are stored.
- Font * pfont = ptman->State()->GetFont();
- if (IsLineBreak(ptman->LBGlyphID()))
- {
- GetGlyphMetric(pfont, kgmetAscent, 0);
- GetGlyphMetric(pfont, kgmetDescent, 0);
- m_xysGlyphX = 0;
- m_xysGlyphY = 0;
- m_xysGlyphHeight = 0;
- m_xysGlyphWidth = 0;
- m_xysAdvX = 0;
- m_xysAdvY = 0;
- m_bIsSpace = true;
- }
- else
- {
- //IsSpace(ptman); // cache this flag--doing bb-top below will do it
-
- GetGlyphMetric(pfont, kgmetAscent, gidActual);
- GetGlyphMetric(pfont, kgmetDescent, gidActual);
- GetGlyphMetric(pfont, kgmetBbTop, gidActual);
- // call above will also cache all the values below
- //GetGlyphMetric(pfont, kgmetBbBottom, gidActual);
- //GetGlyphMetric(pfont, kgmetBbLeft, gidActual);
- //GetGlyphMetric(pfont, kgmetBbRight, gidActual);
- //GetGlyphMetric(pfont, kgmetAdvWidth, gidActual);
- //GetGlyphMetric(pfont, kgmetAdvHeight, gidActual);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the associations for the slot.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::Associate(GrSlotState * pslot)
-{
- m_vpslotAssoc.clear();
- m_vpslotAssoc.push_back(pslot);
-}
-
-void GrSlotState::Associate(GrSlotState * pslotBefore, GrSlotState * pslotAfter)
-{
- m_vpslotAssoc.clear();
- m_vpslotAssoc.push_back(pslotBefore);
- m_vpslotAssoc.push_back(pslotAfter);
-}
-
-void GrSlotState::Associate(std::vector<GrSlotState*> & vpslot)
-{
- m_vpslotAssoc.clear();
- ///vpslot.CopyTo(m_vpslotAssoc); -- bug in CopyTo, so we do it ourselves:
- for (size_t islot = 0; islot < vpslot.size(); ++islot)
- {
- m_vpslotAssoc.push_back(vpslot[islot]);
- }
-
- // Set its character styles and features from the associated slot.
- if (vpslot.size() > 0) // && !m_pslotPrevState
- {
- std::copy(m_vpslotAssoc[0]->PFeatureBuf(),
- m_vpslotAssoc[0]->PFeatureBuf() + m_cnFeat, PFeatureBuf());
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Clear the associations for the slot.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::ClearAssocs()
-{
- m_vpslotAssoc.clear();
-}
-
-/*----------------------------------------------------------------------------------------------
- Return a list of (ie, add into the vector) all the underlying associations, relative
- to the official beginning of the segment.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::AllAssocs(std::vector<int> & vichw)
-{
- if (PassModified() == 0)
- {
- Assert(m_ichwSegOffset != kInvalid);
- vichw.push_back(m_ichwSegOffset);
- }
- else
- {
- for (size_t i = 0; i < m_vpslotAssoc.size(); ++i)
- m_vpslotAssoc[i]->AllAssocs(vichw);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the underlying position of the before-association, relative to the official
- beginning of the segment. May be -1, if this slot maps to a character in the previous
- segment, or >= the length of the segment, if it maps to a character in the following
- segment.
-----------------------------------------------------------------------------------------------*/
-int GrSlotState::BeforeAssoc()
-{
- GrSlotState * pslot = this;
- while (pslot->PassModified() > 0)
- {
- pslot = pslot->RawBeforeAssocSlot();
- if (pslot == NULL)
- {
- return kPosInfinity;
- }
- }
- Assert(pslot->m_ichwSegOffset != kInvalid);
- return pslot->m_ichwSegOffset;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the underlying position of the after-association, relative to the official
- beginning of the segment. May be -1, if this slot maps to a character in the previous
- segment, or >= the length of the segment, if it maps to a character in the following
- segment.
-----------------------------------------------------------------------------------------------*/
-int GrSlotState::AfterAssoc()
-{
- GrSlotState * pslot = this;
- while (pslot->PassModified() > 0)
- {
- pslot = pslot->RawAfterAssocSlot();
- if (pslot == NULL)
- {
- return kNegInfinity;
- }
- }
- Assert(pslot->m_ichwSegOffset != kInvalid);
- return pslot->m_ichwSegOffset;
-}
-
-/*----------------------------------------------------------------------------------------------
- It is possible to get into a state where we are associated with an invalid state.
- For instance, slot C may be associated with slots B1 and B2, but slot B1 is not associated
- with any earlier slot, in which case slot C should remove the association with B1 and just
- be associated with B2.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::CleanUpAssocs()
-{
- for (size_t i = 0; i < m_vpslotAssoc.size(); i++)
- m_vpslotAssoc[i]->CleanUpAssocs();
-
- GrSlotState * pslot;
-
- pslot = RawBeforeAssocSlot();
- while (pslot && BeforeAssoc() == kPosInfinity)
- {
- // The before association is bogus--delete it.
- m_vpslotAssoc.erase(m_vpslotAssoc.begin());
- pslot = RawBeforeAssocSlot();
- }
-
- pslot = RawAfterAssocSlot();
- while (pslot && AfterAssoc() == kNegInfinity)
- {
- // The after association is bogus--delete it.
- m_vpslotAssoc.pop_back();
- pslot = RawAfterAssocSlot();
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Fill in the array of the given output slot with the underlying positions of the
- ligature components, relative to the official beginning of the segment.
- Positions may be < 0, if this slot maps to a character in the previous segment,
- or >= the length of the segment, if it maps to a character in the following segment.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::SetComponentRefsFor(GrSlotOutput * pslout, int slatiArg)
-{
- if (PassModified() > 0)
- {
- GrSlotState * pslot;
- int slati;
- if (HasComponents())
- {
- for (int iComponent = 0; iComponent < m_cnCompPerLig; iComponent++)
- {
- pslot = CompRefSlot(iComponent);
- slati = Slati(iComponent);
- if (pslot)
- {
- Assert(slati != -1);
- Assert(PassModified() >= pslot->PassModified());
- pslot->SetComponentRefsFor(pslout, slati);
- }
- }
- }
- else
- {
- // Follow the chain back through the passes.
- pslot = RawBeforeAssocSlot();
- if (pslot)
- {
- Assert(PassModified() >= pslot->PassModified());
- // Passing slati here is definitely needed for our Arabic font: for instance when
- // you type something like "mla", so the l is transformed into a temporary glyph
- // before creating the ligature. However, this seems to have broken something,
- // which I will probably find eventually. :-(
- pslot->SetComponentRefsFor(pslout, slatiArg);
- //pslot->SetComponentRefsFor(pslout, -1);
- }
- }
- }
- else
- {
- Assert(m_ichwSegOffset != kInvalid);
- pslout->AddComponentReference(m_ichwSegOffset, slatiArg);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Fill in the vector with the underlying positions of the
- ligature components, relative to the official beginning of the segment.
- Positions may be < 0, if this slot maps to a character in the previous segment,
- or >= the length of the segment, if it maps to a character in the following segment.
- ENHANCE: merge with method above.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::AllComponentRefs(std::vector<int> & vichw)
-{
- if (PassModified() > 0)
- {
- GrSlotState * pslot;
- if (HasComponents())
- {
- for (int iComponent = 0; iComponent < m_cnCompPerLig; iComponent++)
- {
- pslot = CompRefSlot(iComponent);
- if (pslot)
- {
- Assert(PassModified() >= pslot->PassModified());
- pslot->AllComponentRefs(vichw);
- }
- }
- }
- else
- {
- // ENHANCE: Strictly speaking we should probably have separate before-
- // and after-lists for the components, but I think it would be pretty
- // rare to have both deletion and ligatures overlapping, so I'm not
- // going to bother with it for now.
- //for (int islot = 0; islot < AssocsSize(); islot++)
- for (int islot = 0; islot < 1; islot++)
- {
- m_vpslotAssoc[islot]->AllComponentRefs(vichw);
- }
- }
- }
- else
- {
- Assert(m_ichwSegOffset != kInvalid);
- vichw.push_back(m_ichwSegOffset);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Get the value of the component.???.ref attribute for the slot.
- Note that 'i' is the local index for the component as defined for this glyph.
-----------------------------------------------------------------------------------------------*/
-GrSlotState * GrSlotState::CompRefSlot(int i)
-{
- Assert(i < m_cnCompPerLig);
- if (i < m_cnCompPerLig)
- return CompRef(i);
- else
- return NULL;
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the value of the component.???.ref attribute for the slot.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::SetCompRefSlot(GrTableManager * ptman, int slati, GrSlotState * pslotComp)
-{
- // Convert the global identifer for the component to the index for this glyph.
- int icomp = ptman->ComponentIndexForGlyph(GlyphID(), slati);
- Assert(icomp != -1);
- if (icomp == -1)
- // Component not defined for this glyph--ignore.
- return;
- Assert(icomp < m_cnCompPerLig);
-
- if (m_fHasComponents == false)
- {
- // None have been set yet; initialize them.
- for (int iLoop = 0; iLoop < m_cnCompPerLig; iLoop++)
- {
- SetCompRef(iLoop, NULL);
- SetSlati(iLoop, -1);
- }
- }
-
- m_fHasComponents = true;
- int iLoop;
- for (iLoop = 0; iLoop < m_cnCompPerLig; iLoop++)
- {
- if (Slati(iLoop) == slati)
- break;
- if (Slati(iLoop) == -1)
- break;
- }
- //if (icomp < m_cnCompPerLig)
- if (iLoop < m_cnCompPerLig)
- {
- //SetCompRef(icomp, pslotComp);
- SetCompRef(iLoop, pslotComp);
- SetSlati(iLoop, slati);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the underlying position for the slot, relative to the official beginning of the
- segment.
-----------------------------------------------------------------------------------------------*/
-int GrSlotState::SegOffset()
-{
- if (m_ichwSegOffset == kInvalid)
- {
- Assert(m_pslotPrevState);
- Assert(m_ipassModified > 0);
- return m_pslotPrevState->SegOffset();
- }
- else
- {
- Assert(m_pslotPrevState == NULL);
- Assert(m_ipassModified == 0);
- return m_ichwSegOffset;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the value of the glyph attribute (in design units, if this is a measurement).
-----------------------------------------------------------------------------------------------*/
-int GrSlotState::GlyphAttrValueEmUnits(GrTableManager * ptman, int nAttrID)
-{
- return ptman->GlyphAttrValue(m_chwGlyphID, nAttrID);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the value of the glyph metric, in design coordinates (ie, based on the font's
- em-square).
-----------------------------------------------------------------------------------------------*/
-int GrSlotState::GlyphMetricEmUnits(GrTableManager * ptman, int nMetricID)
-{
- int mValue;
- if (ptman->State()->GetFont())
- {
- // Get the actual metric, possibly adjusted for hinting, then convert back to
- // design units.
- float xysValue = GlyphMetricLogUnits(ptman, nMetricID);
- mValue = ptman->LogToEmUnits(xysValue);
- }
- else
- // Ask the font directly.
- ////mValue = ???
- mValue = 0;
-
- return mValue;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the value of the glyph attribute, converted to source device coordinates.
- The attribute is assumed to be one whose value is a measurement.
-----------------------------------------------------------------------------------------------*/
-float GrSlotState::GlyphAttrValueLogUnits(GrTableManager * ptman, int nAttrID)
-{
- int mValue = GlyphAttrValueEmUnits(ptman, nAttrID);
- float xysRet = ptman->EmToLogUnits(mValue);
- return xysRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the value of the glyph metric, in the source device's logical units.
-----------------------------------------------------------------------------------------------*/
-float GrSlotState::GlyphMetricLogUnits(GrTableManager * ptman, int nMetricID)
-{
-#ifdef OLD_TEST_STUFF
- if (ptman->GlyphTable() == NULL)
- return 0;
-#endif // OLD_TEST_STUFF
-
-#ifdef _DEBUG
- if (IsLineBreak(ptman->LBGlyphID()))
- {
- Warn("Getting metrics of line-break slot");
- }
-#endif // _DEBUG
- if (IsLineBreak(ptman->LBGlyphID()))
- {
- return 0;
- }
-
- return GetGlyphMetric(ptman->State()->GetFont(), nMetricID,
- ActualGlyphForOutput(ptman));
-}
-
-
-float GrSlotOutput::GlyphMetricLogUnits(Font * pfont, int nMetricID)
-{
- Assert(m_chwActual != kInvalidGlyph);
- if (m_chwActual == kInvalidGlyph)
- return 0;
-
- return GetGlyphMetric(pfont, nMetricID, m_chwActual);
-}
-
-//float GrSlotOutput::GlyphMetricLogUnits(int gmet) -- obsolete: no longer caching these values
-//{
-// // When the font is not passed as an argument, the values better be cached!
-//
-// switch (gmet)
-// { // There may be off by one errors below, depending on what width and height mean
-// case kgmetLsb:
-// return m_xysGlyphX;
-// case kgmetRsb:
-// return (m_xysAdvX - m_xysGlyphX - m_xysGlyphWidth);
-// case kgmetBbTop:
-// return m_xysGlyphY;
-// case kgmetBbBottom:
-// return (m_xysGlyphY - m_xysGlyphHeight);
-// case kgmetBbLeft:
-// return m_xysGlyphX;
-// case kgmetBbRight:
-// return (m_xysGlyphX + m_xysGlyphWidth);
-// case kgmetBbHeight:
-// return m_xysGlyphHeight;
-// case kgmetBbWidth:
-// return m_xysGlyphWidth;
-// case kgmetAdvWidth:
-// return m_xysAdvX;
-// case kgmetAdvHeight:
-// return m_xysAdvY;
-// default:
-// Warn("GetGlyphMetric was asked for an illegal metric.");
-// };
-//
-// return 0;
-//}
-
-
-float GrSlotAbstract::GetGlyphMetric(Font * pfont, int nMetricID, gid16 chwGlyphID)
-{
- GlyphMetric gmet = GlyphMetric(nMetricID);
-
- float yAscent, yDescent;
- gr::Point ptAdvances;
- gr::Rect rectBb;
-
- if (kgmetAscent == gmet)
- {
- //if (m_xysFontAscent != -1)
- // return m_xysFontAscent;
- pfont->getFontMetrics(&yAscent);
- //m_xysFontAscent = xysRet;
- //if (pfont)
- // m_xysFontAscent = yAscent;
- return yAscent;
- }
-
- if (kgmetDescent == gmet)
- {
- //if (m_xysFontDescent != -1)
- // return m_xysFontDescent;
- pfont->getFontMetrics(NULL, &yDescent);
- //m_xysFontDescent = xysRet;
- //if (pfont)
- // m_xysFontDescent = yDescent;
- return yDescent;
- }
-
- float xysGlyphX, xysGlyphY, xysGlyphWidth, xysGlyphHeight, xysAdvX, xysAdvY;
- //if (m_xysGlyphWidth == -1)
- //{
- pfont->getGlyphMetrics(chwGlyphID, rectBb, ptAdvances);
-
- xysGlyphX = rectBb.left;
- xysGlyphY = rectBb.top;
- xysGlyphWidth = (rectBb.right - rectBb.left);
- xysGlyphHeight = (rectBb.top - rectBb.bottom);
- xysAdvX = ptAdvances.x;
- xysAdvY = ptAdvances.y;
-
- m_bIsSpace = (0 == xysGlyphX && 0 == xysGlyphY); // should agree with test done in IsSpace() below
-
- if (m_bIsSpace == 1)
- {
- // White space glyph - only case where nGlyphX == nGlyphY == 0
- // nGlyphWidth & nGlyphHeight are always set to 16 for unknown reasons, so correct.
- xysGlyphWidth = xysGlyphHeight = 0;
- }
- //}
-
- switch (gmet)
- { // There may be off-by-one errors below, depending on what width and height mean
- case kgmetLsb:
- return xysGlyphX;
- case kgmetRsb:
- return (xysAdvX - xysGlyphX - xysGlyphWidth);
- case kgmetBbTop:
- return xysGlyphY;
- case kgmetBbBottom:
- return (xysGlyphY - xysGlyphHeight);
- case kgmetBbLeft:
- return xysGlyphX;
- case kgmetBbRight:
- return (xysGlyphX + xysGlyphWidth);
- case kgmetBbHeight:
- return xysGlyphHeight;
- case kgmetBbWidth:
- return xysGlyphWidth;
- case kgmetAdvWidth:
- return xysAdvX;
- case kgmetAdvHeight:
- return xysAdvY;
- default:
- Warn("GetGlyphMetric was asked for an illegal metric.");
- };
-
- return 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Test the glyph id to see if it is a white space glyph.
-----------------------------------------------------------------------------------------------*/
-int GrSlotState::IsSpace(GrTableManager * ptman)
-{
- gid16 gidActual = ActualGlyphForOutput(ptman);
-
- ////if (m_xysGlyphWidth == -1)
- ////{
- //// res = ptman->State()->GraphicsObject()->GetGlyphMetrics(gidActual,
- //// &m_xysGlyphWidth, &m_xysGlyphHeight,
- //// &m_xysGlyphX, &m_xysGlyphY, &m_xysAdvX, &m_xysAdvY);
- //// if (ResultFailed(res))
- //// {
- //// WARN(res);
- //// return 2; // will test as true but can be distinguished by separate value
- //// }
-
- //// gr::Point ptAdvances;
- //// gr::Rect rectBb;
- //// ptman->State()->Font()->getGlyphMetrics(gidActual, rectBb, ptAdvances);
- ////}
-
- if (m_bIsSpace == -1)
- GetGlyphMetric(ptman->State()->GetFont(), kgmetBbLeft, gidActual);
- // One call is enough to cache the information.
- //GetGlyphMetric(ptman->State()->Font(), kgmetBbBottom, gidActual);
-
- // should agree with test done in GetGlyphMetric() above
- //////m_bIsSpace = (0 == m_xysGlyphX && 0 == m_xysGlyphY);
-
- Assert(m_bIsSpace == 0 || m_bIsSpace == 1);
-
- return m_bIsSpace;
-}
-
-bool GrSlotOutput::IsSpace()
-{
- Assert(m_bIsSpace == 0 || m_bIsSpace == 1);
- return m_bIsSpace;
-}
-
-/*----------------------------------------------------------------------------------------------
- If any of the attach attributes have been modified, fix things up. Set up the attachment
- tree, and set any needed default positions. Zap the cached positions of any following
- glyphs in the stream.
-
- @param psstrm - the stream in which the modifications were made
- @param islotThis - the index of the attached (leaf) slot in the stream;
- -1 if we don't know
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::HandleModifiedPosition(GrTableManager * ptman,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, int islotThis)
-{
- if (!m_fAttachMod && !m_fShiftMod)
- return;
-
- if (islotThis == -1)
- {
- for (int islot = 0; islot < psstrmOut->WritePos(); islot++)
- {
- if (psstrmOut->SlotAt(islot) == this)
- {
- islotThis = islot;
- break;
- }
- }
- Assert(islotThis > -1);
- }
-
- if (m_fAttachMod)
- {
- // Attachments.
-
- // Note that it doesn't make sense to attach a slot to itself, so if the value of
- // the attach.to attribute is 0, that means clear the attachment.
- GrSlotState * pslotNewRoot = AttachRoot(psstrmOut);
-
- AttachToRoot(ptman, psstrmOut, pslotNewRoot);
-
- if (pslotNewRoot)
- {
- // If this is an attachment with no positions, attach the two glyphs side by side
- // in the appropriate order.
- bool fRtl = ((pslotNewRoot->PostBidiDirLevel(ptman) % 2) != 0);
- if ((fRtl && m_srAttachTo < 0) || (!fRtl && m_srAttachTo > 0))
- {
- // The root is on the right, the leaf is on the left.
- if (m_mAttachAtX == kNotYetSet && m_nAttachAtGpoint == kNotYetSet)
- m_mAttachAtX = 0;
- if (m_mAttachWithX == kNotYetSet && m_nAttachWithGpoint == kNotYetSet)
- m_mAttachWithX = short(AdvanceX(ptman));
- }
- else
- {
- // The root is on the left, the leaf is on the right.
- if (m_mAttachAtX == kNotYetSet && m_nAttachAtGpoint == kNotYetSet)
- m_mAttachAtX = short(pslotNewRoot->AdvanceX(ptman));
- if (m_mAttachWithX == kNotYetSet && m_nAttachWithGpoint == kNotYetSet)
- m_mAttachWithX = 0;
- }
- }
- }
- else
- {
- // Shifting, or changing the advance width.
- Assert(m_fShiftMod);
- EnsureLocalAttachmentTree(ptman, psstrmIn, psstrmOut, islotThis);
- ZapMetricsAndPositionDownToBase(psstrmOut);
- ZapMetricsOfLeaves(psstrmOut);
- }
-
- if (psstrmOut->m_ipass == ptman->NumberOfPasses() - 1)
- ptman->InitPosCache(); // cached position is most likely no longer valid
-
- // Invalidate the positions of this and any following glyphs.
- for (int islot = islotThis + 1; islot < psstrmOut->WritePos(); islot++)
- psstrmOut->SlotAt(islot)->ZapPosition();
-
- m_fAttachMod = false;
- m_fShiftMod = false;
-}
-
-/*----------------------------------------------------------------------------------------------
- The shift attribute of a slot has been modified. Make sure any slots that are part of the
- same attachment cluster are local to this stream. The reason for this is so that the
- position calculations stay consistent within the stream.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::EnsureLocalAttachmentTree(GrTableManager * ptman,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, int islotThis)
-{
- if (m_dislotRootFixed)
- {
- GrSlotState * pslotRoot = SlotAtOffset(psstrmOut, m_dislotRootFixed);
- psstrmOut->EnsureLocalCopy(ptman, pslotRoot, psstrmIn);
- pslotRoot = SlotAtOffset(psstrmOut, m_dislotRootFixed); // get the new one!
- pslotRoot->EnsureLocalAttachmentTree(ptman, psstrmIn, psstrmOut, islotThis + m_dislotRootFixed);
- }
- for (size_t islot = 0; islot < m_vdislotAttLeaves.size(); islot++)
- {
- GrSlotState * pslotLeaf = SlotAtOffset(psstrmOut, m_vdislotAttLeaves[islot]);
- psstrmOut->EnsureLocalCopy(ptman, pslotLeaf, psstrmIn);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- The recipient slot is being attached to the argument slot.
- NOTE: the caller is responsible to zap the cached positions of following glyphs
- in the stream.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::AttachToRoot(GrTableManager * ptman, GrSlotStream * psstrm,
- GrSlotState * pslotNewRoot)
-{
- GrSlotState * pslotOldRoot = (m_dislotRootFixed == 0) ?
- NULL :
- SlotAtOffset(psstrm, m_dislotRootFixed);
-
- if (pslotOldRoot)
- {
- if (pslotOldRoot != pslotNewRoot)
- pslotOldRoot->RemoveLeaf(m_dislotRootFixed);
- pslotOldRoot->ZapMetricsAndPositionDownToBase(psstrm);
- pslotOldRoot->ZapMetricsOfLeaves(psstrm);
- }
-
- ZapCompositeMetrics();
-
- if (pslotNewRoot && pslotNewRoot != pslotOldRoot)
- {
- pslotNewRoot->AddLeaf(m_srAttachTo);
- pslotNewRoot->ZapMetricsAndPositionDownToBase(psstrm);
- pslotNewRoot->ZapMetricsOfLeaves(psstrm);
- }
-
- m_dislotRootFixed = m_srAttachTo;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the absolute position of the glyph, relative to the start of the segment,
- in font design units.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::Position(GrTableManager * ptman,
- GrSlotStream * psstrmOut, int * pmXPos, int * pmYPos)
-{
- Assert(!m_fAttachMod); // the attachment tree should be set up
- Assert(!m_fShiftMod);
-
- float xsWidth, xsVisWidth;
- if (m_xsPositionX == kNegInfFloat || m_ysPositionY == kNegInfFloat)
- ptman->CalcPositionsUpTo(psstrmOut->m_ipass, this, &xsWidth, &xsVisWidth);
-
- *pmXPos = ptman->LogToEmUnits(m_xsPositionX);
- *pmYPos = ptman->LogToEmUnits(m_ysPositionY);
-}
-
-/*----------------------------------------------------------------------------------------------
- Recalculate the metrics for this slot, which has attachments on it (or possibly
- did in the past).
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::AdjustRootMetrics(GrTableManager * ptman, GrSlotStream * psstrm)
-{
- Assert(m_dislotRootFixed == m_srAttachTo);
- GrSlotState * pslotRoot = AttachRoot(psstrm);
- CalcRootMetrics(ptman, psstrm, kPosInfinity);
- if (pslotRoot)
- pslotRoot->AdjustRootMetrics(ptman, psstrm);
-}
-
-/*----------------------------------------------------------------------------------------------
- Calculate the composite metrics for this slot.
-
- @param psstrm - stream for which we are calculating it
- @param nLevel - attachment level we are asking for; kPosInifinity means all levels
- @param fThorough - true: do a thorough recalculation; false: don't recalculate
- metrics for leaves (are they assumed to be accurate???)
- --currently not used
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::CalcCompositeMetrics(GrTableManager * ptman, GrSlotStream * psstrm,
- int nLevel, bool fThorough)
-{
- if (m_nCompositeLevel == nLevel)
- return;
-
- if (fThorough)
- {
- Assert(m_dislotRootFixed == m_srAttachTo);
- GrSlotState * pslotRoot = AttachRoot(psstrm);
-
- InitMetrics(ptman, pslotRoot);
-
- for (size_t islot = 0; islot < m_vdislotAttLeaves.size(); islot++)
- {
- GrSlotState * pslotLeaf = SlotAtOffset(psstrm, m_vdislotAttLeaves[islot]);
- if (pslotLeaf->AttachLevel() <= nLevel)
- pslotLeaf->CalcCompositeMetrics(ptman, psstrm, nLevel, fThorough);
- else
- // this slot will be ignored in the composite metrics
- pslotLeaf->ZapRootMetrics();
- }
- CalcRootMetrics(ptman, psstrm, nLevel);
-
- m_nCompositeLevel = nLevel;
- }
- else
- {
- Assert(false); // for now
-
- // Don't bother with the leaves.
- InitRootMetrics(ptman);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Calculate the metrics for this node and all its leaf nodes.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::CalcRootMetrics(GrTableManager * ptman, GrSlotStream * psstrm, int nLevel)
-{
- for (size_t idislot = 0; idislot < m_vdislotAttLeaves.size(); idislot++)
- {
- GrSlotState * pslot = SlotAtOffset(psstrm, m_vdislotAttLeaves[idislot]);
- if (pslot->AttachLevel() > nLevel)
- continue;
-
- m_xsClusterXOffset = min(m_xsClusterXOffset, pslot->m_xsClusterXOffset);
- if (!pslot->m_fIgnoreAdvance)
- {
- m_xsClusterAdv = max(
- m_xsClusterAdv,
- pslot->m_xsClusterAdv + m_xsRootShiftX);
- }
- m_xsClusterBbLeft = min(m_xsClusterBbLeft, pslot->m_xsClusterBbLeft);
- m_xsClusterBbRight = max(m_xsClusterBbRight, pslot->m_xsClusterBbRight);
- m_ysClusterBbTop = max(m_ysClusterBbTop, pslot->m_ysClusterBbTop);
- m_ysClusterBbBottom = min(m_ysClusterBbBottom, pslot->m_ysClusterBbBottom);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Reset the cluster metrics of this slot.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::InitMetrics(GrTableManager * ptman, GrSlotState * pslotRoot)
-{
- InitLeafMetrics(ptman, pslotRoot);
- InitRootMetrics(ptman);
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize the variables that store the offsets of just this node (ignoring any of its
- leaves) relative to the cluster base.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::InitLeafMetrics(GrTableManager * ptman, GrSlotState * pslotRoot)
-{
- float xsShiftX = ptman->EmToLogUnits(ShiftX());
- float ysShiftY = ptman->EmToLogUnits(ShiftY());
-
- if (ptman->RightToLeft())
- xsShiftX *= -1;
-
- if (IsBase())
- {
- // The x-value below has to be zero because the shift is incorporated into
- // m_xsRootShiftX. (m_ysRootShiftY, on the other hand, isn't used anywhere.)
- m_xsOffsetX = 0;
- m_ysOffsetY = ysShiftY;
-
- m_xsRootShiftX = xsShiftX;
- m_ysRootShiftY = ysShiftY;
- Assert(!IsLineBreak(ptman->LBGlyphID())
- || (m_xsRootShiftX == 0 && m_ysRootShiftY == 0));
- return;
- }
-
- Assert(!IsLineBreak(ptman->LBGlyphID()));
-
- // Hint-adjusted logical coordinates equivalent to attach.at and attach.with attributes.
- // If attach.at or attach.with attributes were unset, the defaults for a side-by-side
- // attachment should have been supplied in HandleModifiedPosition().
- float xsAttAtX, ysAttAtY, xsAttWithX, ysAttWithY;
- AttachLogUnits(ptman, pslotRoot, &xsAttAtX, &ysAttAtY, &xsAttWithX, &ysAttWithY);
-
- m_xsOffsetX = xsAttAtX - xsAttWithX;
- m_xsOffsetX += pslotRoot->m_xsOffsetX;
- m_xsOffsetX += xsShiftX;
-
- m_ysOffsetY = ysAttAtY - ysAttWithY;
- m_ysOffsetY += pslotRoot->m_ysOffsetY;
- m_ysOffsetY += ysShiftY;
-
- // Cumulative effect of shifts on this and all base nodes:
- m_xsRootShiftX = pslotRoot->m_xsRootShiftX + xsShiftX;
- m_ysRootShiftY = pslotRoot->m_ysRootShiftY + ysShiftY;
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize the variables that store the offsets of this node taking into account its
- leaves; these are relative to the cluster base.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::InitRootMetrics(GrTableManager * ptman)
-{
- if (IsLineBreak(ptman->LBGlyphID()))
- {
- m_fIgnoreAdvance = true;
- m_xsClusterXOffset = 0;
- m_xsClusterAdv = 0;
- m_xsClusterBbLeft = 0;
- m_xsClusterBbRight = 0;
- m_ysClusterBbTop = 0;
- m_ysClusterBbBottom = 0;
- return;
- }
-
- float xsAdvanceX = ptman->EmToLogUnits(AdvanceX(ptman));
-
- // If the glyph's advance width is zero, then we NEVER want it to have any affect,
- // even if the glyph is attached way out to the right of its base's advance.
- m_fIgnoreAdvance = (xsAdvanceX == 0);
-
- float xsBbLeft = GlyphMetricLogUnits(ptman, kgmetBbLeft);
- float xsBbRight = GlyphMetricLogUnits(ptman, kgmetBbRight);
- float ysBbTop = GlyphMetricLogUnits(ptman, kgmetBbTop);
- float ysBbBottom = GlyphMetricLogUnits(ptman, kgmetBbBottom);
-
- // Any shifts should be ignored for the sake of calculating actual position or width,
- // hence we subtract the cumulative effect of the shifts.
- m_xsClusterXOffset = m_xsOffsetX - m_xsRootShiftX;
- m_xsClusterAdv = m_xsOffsetX + xsAdvanceX - m_xsRootShiftX;
-
- m_xsClusterBbLeft = m_xsOffsetX + xsBbLeft;
- m_xsClusterBbRight = m_xsOffsetX + xsBbRight;
- m_ysClusterBbTop = m_ysOffsetY + ysBbTop;
- m_ysClusterBbBottom = m_ysOffsetY + ysBbBottom;
-}
-
-/*----------------------------------------------------------------------------------------------
- X-offset of a single glyph relative to the previous advance position.
-----------------------------------------------------------------------------------------------*/
-float GrSlotState::GlyphXOffset(GrSlotStream * psstrm, float fakeItalicRatio)
-{
- float xsRet = Base(psstrm)->ClusterRootOffset() + m_xsOffsetX;
-
- // fake an italic slant
- xsRet += m_ysOffsetY * fakeItalicRatio;
-
- return xsRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Y-offsets of a single glyph relative to the previous advance position.
-----------------------------------------------------------------------------------------------*/
-float GrSlotState::GlyphYOffset(GrSlotStream * psstrm)
-{
- return m_ysOffsetY;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the offset of the last leaf of the cluster, relative to this slot, which is
- the base. Return kNegInfinity if there are not enough slots in the stream to tell.
-----------------------------------------------------------------------------------------------*/
-int GrSlotState::LastLeafOffset(GrSlotStream * psstrm)
-{
- int islotRet = 0;
- for (size_t idislot = 0; idislot < m_vdislotAttLeaves.size(); idislot++)
- {
- int dislot = m_vdislotAttLeaves[idislot];
- Assert(dislot != 0);
- if (!psstrm->HasSlotAtPosPassIndex(PosPassIndex() + dislot))
- return kNegInfinity;
- GrSlotState * pslotLeaf = SlotAtOffset(psstrm, dislot);
- int islotTmp = pslotLeaf->LastLeafOffset(psstrm);
- if (islotTmp == kNegInfinity)
- return kNegInfinity;
- islotRet = max(islotRet, (dislot + islotTmp));
- }
- return islotRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the attach positions in the device context's logical units,
- adjusted for hinting if possible.
-
- Note that m_nAttachAt/WithGpoint = 0 is always an invalid value (resulting from a
- glyph attribute that was defined in terms of x/y coordinates that didn't map to an
- actual on-curve point). Therefore the x/y coordinates should be used to do the
- attachment. In the case where we actually want point #0 on the curve,
- m_nAttachAt/WithGpoint will have the special value 'kGpointZero' (the glyph attribute
- is defined this way).
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::AttachLogUnits(GrTableManager * ptman, GrSlotState * pslotRoot,
- float * pxsAttAtX, float * pysAttAtY,
- float * pxsAttWithX, float * pysAttWithY)
-{
- if (m_nAttachAtGpoint == kNotYetSet || m_nAttachAtGpoint == 0)
- {
- // Use x- and y-coordinates; no adjustment for hinting is done.
- int mX = m_mAttachAtX + m_mAttachAtXOffset;
- int mY = m_mAttachAtY + m_mAttachAtYOffset;
-
- *pxsAttAtX = ptman->EmToLogUnits(mX);
- *pysAttAtY = ptman->EmToLogUnits(mY);
- }
- else
- {
- // Look up the actual on-curve point.
- int nGpoint = m_nAttachAtGpoint;
- if (nGpoint == kGpointZero)
- nGpoint = 0;
- bool fImpl = ptman->GPointToXY(pslotRoot->GlyphID(), nGpoint, pxsAttAtX, pysAttAtY);
-
- // Debuggers:
- //int mXTmpAt = m_mAttachAtX + m_mAttachAtXOffset;
- //int mYTmpAt = m_mAttachAtY + m_mAttachAtYOffset;
- //int xsAttAtXTmp = ptman->EmToLogUnits(mXTmpAt);
- //int ysAttAtYTmp = ptman->EmToLogUnits(mYTmpAt);
- //fImpl = false;
-
- if (!fImpl)
- {
- // Fall back to using x- and y-coordinates; no adjustment for hinting.
- int mX = m_mAttachAtX + m_mAttachAtXOffset;
- int mY = m_mAttachAtY + m_mAttachAtYOffset;
- *pxsAttAtX = ptman->EmToLogUnits(mX);
- *pysAttAtY = ptman->EmToLogUnits(mY);
- }
- else
- {
- // Adjust by offsets.
- *pxsAttAtX += ptman->EmToLogUnits(m_mAttachAtXOffset);
- *pysAttAtY += ptman->EmToLogUnits(m_mAttachAtYOffset);
- }
- }
-
- if (m_nAttachWithGpoint == kNotYetSet || m_nAttachWithGpoint == 0)
- {
- // Use x- and y-coordinates; no adjustment for hinting is done.
- int mX = m_mAttachWithX + m_mAttachWithXOffset;
- int mY = m_mAttachWithY + m_mAttachWithYOffset;
-
- *pxsAttWithX = ptman->EmToLogUnits(mX);
- *pysAttWithY = ptman->EmToLogUnits(mY);
- }
- else
- {
- // Look up the actual on-curve point.
- int nGpoint = m_nAttachWithGpoint;
- if (nGpoint == kGpointZero)
- nGpoint = 0;
- bool fImpl = ptman->GPointToXY(m_chwGlyphID, nGpoint, pxsAttWithX, pysAttWithY);
-
- // Debuggers:
- //int mXTmpWith = m_mAttachWithX + m_mAttachWithXOffset;
- //int mYTmpWith = m_mAttachWithY + m_mAttachWithYOffset;
- //int xsAttWithXTmp = ptman->EmToLogUnits(mXTmpWith);
- //int ysAttWithYTmp = ptman->EmToLogUnits(mYTmpWith);
- //fImpl = false;
-
- if (!fImpl)
- {
- // Fall back to using x- and y-coordinates; no adjustment for hinting.
- int mX = m_mAttachWithX + m_mAttachWithXOffset;
- int mY = m_mAttachWithY + m_mAttachWithYOffset;
- *pxsAttWithX = ptman->EmToLogUnits(mX);
- *pysAttWithY = ptman->EmToLogUnits(mY);
- }
- else
- {
- // Adjust by offsets.
- *pxsAttWithX += ptman->EmToLogUnits(m_mAttachWithXOffset);
- *pysAttWithY += ptman->EmToLogUnits(m_mAttachWithYOffset);
- }
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the slot that is 'dislot' slots away from this slot in the given stream.
- Only valid for streams that are the input to or output of positioning passes.
-----------------------------------------------------------------------------------------------*/
-GrSlotState * GrSlotState::SlotAtOffset(GrSlotStream * psstrm, int dislot)
-{
- Assert(psstrm->m_fUsedByPosPass);
- return psstrm->SlotAtPosPassIndex(PosPassIndex() + dislot);
-}
-
-/*----------------------------------------------------------------------------------------------
- If the direction level has not been calculated at this point, assume it is the
- top direction. This should only happen if there was no bidi pass to set it.
- This method should only be called by the positioning passes; it assumes any bidi
- pass has been run.
-----------------------------------------------------------------------------------------------*/
-int GrSlotState::PostBidiDirLevel(GrTableManager * ptman)
-{
- if (m_nDirLevel == -1)
- {
- Assert(!ptman->HasBidiPass());
- return ptman->TopDirectionLevel();
- }
- return m_nDirLevel;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if this glyph represents a LRM code.
-----------------------------------------------------------------------------------------------*/
-bool GrSlotState::IsLrm()
-{
- if (PassModified() == 0)
- return (m_nUnicode == knLRM);
- return m_pslotPrevState->IsLrm();
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if this glyph represents a RLM code.
-----------------------------------------------------------------------------------------------*/
-bool GrSlotState::IsRlm()
-{
- if (PassModified() == 0)
- return (m_nUnicode == knRLM);
- return m_pslotPrevState->IsRlm();
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Used by GlyphInfo
-----------------------------------------------------------------------------------------------*/
-//float GrSlotOutput::AdvanceX(Segment * pseg)
-//{
-// return pseg->EmToLogUnits(m_mAdvanceX);
-//}
-//float GrSlotOutput::AdvanceY(Segment * pseg)
-//{
-// return pseg->EmToLogUnits(m_mAdvanceY);
-//}
-float GrSlotOutput::MaxStretch(Segment * pseg, int level)
-{
- Assert(level == 0);
- return (level == 0) ? pseg->EmToLogUnits(m_mJStretch0) : 0;
-}
-float GrSlotOutput::MaxShrink(Segment * pseg, int level)
-{
- Assert(level == 0);
- return (level == 0) ? pseg->EmToLogUnits(m_mJShrink0) : 0;
-}
-float GrSlotOutput::StretchStep(Segment * pseg, int level)
-{
- Assert(level == 0);
- return (level == 0) ? pseg->EmToLogUnits(m_mJStep0) : 0;
-}
-int GrSlotOutput::JustWeight(int level)
-{
- Assert(level == 0);
- return (level == 0) ? m_nJWeight0 : 0;
-}
-float GrSlotOutput::JustWidth(Segment * pseg, int level)
-{
- Assert(level == 0);
- return (level == 0) ? pseg->EmToLogUnits(m_mJWidth0) : 0;
-}
-float GrSlotOutput::MeasureSolLogUnits(Segment * pseg)
-{
- return pseg->EmToLogUnits(m_mMeasureSol);
-}
-float GrSlotOutput::MeasureEolLogUnits(Segment * pseg)
-{
- return pseg->EmToLogUnits(m_mMeasureEol);
-}
-
-/*----------------------------------------------------------------------------------------------
- Make a copy of the GrSlotOutput. This is used in making an identical copy of the segment.
- Warning: this function will break if GrSlotState and subclasses are given virtual
- methods. In that case, we will need to copy from the address of the first variable in
- GrSlotAbstract.
-----------------------------------------------------------------------------------------------*/
-void GrSlotOutput::ExactCopyFrom(GrSlotOutput * pslout, u_intslot * pnVarLenBuf, int cnExtraPerSlot)
-{
- // The chunk of the object from GrSlotAbstract can be copied exactly,
- // except for the variable-length buffer.
- *this = *pslout;
- m_prgnVarLenBuf = pnVarLenBuf;
- std::copy(pslout->m_prgnVarLenBuf, pslout->m_prgnVarLenBuf + cnExtraPerSlot,
- m_prgnVarLenBuf);
-
- // Now copy the stuff specific to GrSlotOutput.
- m_ichwBeforeAssoc = pslout->m_ichwBeforeAssoc;
- m_ichwAfterAssoc = pslout->m_ichwAfterAssoc;
- m_cComponents = pslout->m_cComponents;
-
- m_isloutClusterBase = pslout->m_isloutClusterBase;
- m_disloutCluster = pslout->m_disloutCluster;
- m_xsClusterXOffset = pslout->m_xsClusterXOffset;
- m_xsClusterAdvance = pslout->m_xsClusterAdvance;
- m_igbb = pslout->m_igbb;
- m_xsAdvanceX = pslout->m_xsAdvanceX;
-// m_ysAdvanceY = pslout->m_ysAdvanceY;
-// m_rectBB = pslout->m_rectBB;
-}
-
-/*----------------------------------------------------------------------------------------------
- Shift the glyph to the opposite end of the segment. This is needed for white-space-only
- segments whose direction is being changed.
-----------------------------------------------------------------------------------------------*/
-void GrSlotOutput::ShiftForDirDepthChange(float dxsSegWidth)
-{
- float dxsShift = dxsSegWidth - m_xsAdvanceX - (2 * m_xsPositionX);
- int tmp; tmp = (int) dxsShift;
- m_xsPositionX += dxsShift;
-// m_rectBB.left += dxsShift;
-// m_rectBB.right += dxsShift;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the indices of all the glyphs attached to this cluster, in logical order.
- Return an empty vector if this glyph is not the base glyph or if there are no
- attached glyphs.
- This method return glyph indices, not slot indices.
-----------------------------------------------------------------------------------------------*/
-void GrSlotOutput::ClusterMembers(Segment * pseg, int isloutThis, std::vector<int> & visloutRet)
-{
- if (m_isloutClusterBase == -1 || m_isloutClusterBase == isloutThis) // yes, a base
- pseg->ClusterMembersForGlyph(isloutThis, m_disloutCluster, visloutRet);
- else
- {
- Assert(visloutRet.size() == 0);
- }
-}
-
-} // namespace gr