summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite-engine/src/segment
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2009-03-20 07:35:59 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2009-03-20 07:35:59 +0000
commit70a2688732ce8e027c0bbf4cbdc55621c9ca5b57 (patch)
tree0a618c7df46f5a6c6334bcc5b2264cc23ebdbc89 /Build/source/libs/graphite-engine/src/segment
parent200cfaafaed3d870382579503f73a3838b427d51 (diff)
new build system
git-svn-id: svn://tug.org/texlive/trunk@12443 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/graphite-engine/src/segment')
-rw-r--r--Build/source/libs/graphite-engine/src/segment/FileInput.cpp266
-rw-r--r--Build/source/libs/graphite-engine/src/segment/FileInput.h104
-rw-r--r--Build/source/libs/graphite-engine/src/segment/FontCache.cpp308
-rw-r--r--Build/source/libs/graphite-engine/src/segment/FontCache.h105
-rw-r--r--Build/source/libs/graphite-engine/src/segment/FontFace.cpp598
-rw-r--r--Build/source/libs/graphite-engine/src/segment/FontFace.h246
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrCharStream.cpp652
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrCharStream.h183
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrClassTable.cpp382
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrClassTable.h188
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrEngine.cpp2030
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrEngine.h622
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrFSM.cpp526
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrFSM.h245
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrFeature.cpp321
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrFeatureValues.h71
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrGlyphTable.cpp650
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrGlyphTable.h429
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrPass.cpp1995
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrPass.h748
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrPassActionCode.cpp1492
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrPseudoMap.h48
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrSlotState.cpp1481
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrSlotState.h1287
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrSlotStream.cpp2368
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrSlotStream.h577
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrTableManager.cpp2691
-rw-r--r--Build/source/libs/graphite-engine/src/segment/GrTableManager.h583
-rw-r--r--Build/source/libs/graphite-engine/src/segment/Main.h181
-rw-r--r--Build/source/libs/graphite-engine/src/segment/Makefile.am26
-rw-r--r--Build/source/libs/graphite-engine/src/segment/MemoryUsage.cpp781
-rw-r--r--Build/source/libs/graphite-engine/src/segment/Platform.cpp113
-rw-r--r--Build/source/libs/graphite-engine/src/segment/Segment.cpp3547
-rw-r--r--Build/source/libs/graphite-engine/src/segment/SegmentAux.cpp256
-rw-r--r--Build/source/libs/graphite-engine/src/segment/TestFSM.cpp3416
-rw-r--r--Build/source/libs/graphite-engine/src/segment/TestPasses.cpp1005
-rw-r--r--Build/source/libs/graphite-engine/src/segment/TransductionLog.cpp2091
-rw-r--r--Build/source/libs/graphite-engine/src/segment/XmlTransductionLog.cpp1583
-rw-r--r--Build/source/libs/graphite-engine/src/segment/resource.h15
39 files changed, 0 insertions, 34210 deletions
diff --git a/Build/source/libs/graphite-engine/src/segment/FileInput.cpp b/Build/source/libs/graphite-engine/src/segment/FileInput.cpp
deleted file mode 100644
index 52969532cd3..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/FileInput.cpp
+++ /dev/null
@@ -1,266 +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: FileInput.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Contains the functions for reading from a TT file. (These are functions, not methods
- associated with a class.)
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-
-#include "GrCommon.h"
-#include "GrData.h"
-#ifndef _WIN32
-#include "GrMstypes.h"
-#endif
-#include "GrDebug.h"
-#include <fstream>
-#include <iostream>
-#include <string>
-#include "FileInput.h"
-#include "GrResult.h"
-
-//#ifndef _MSC_VER
-//#include "config.h"
-//#endif
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods of GrBufferIStream
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Constructor.
-----------------------------------------------------------------------------------------------*/
-GrBufferIStream::GrBufferIStream()
-{
- m_pbStart = NULL;
- m_pbNext = NULL;
- m_pbLim = NULL;
-}
-
-/*----------------------------------------------------------------------------------------------
- Destructor.
-----------------------------------------------------------------------------------------------*/
-GrBufferIStream::~GrBufferIStream()
-{
- Close();
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize the stream.
-----------------------------------------------------------------------------------------------*/
-#ifdef GR_FW
-bool GrBufferIStream::Open(std::wstring stuFileName, int kMode)
-#else
-bool GrBufferIStream::Open(const char * pcFileName, std::ios::openmode kMode)
-#endif
-{
- Assert(false); // use OpenBuffer
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize the stream to a buffer.
-----------------------------------------------------------------------------------------------*/
-bool GrBufferIStream::OpenBuffer(byte * pbBuffer, int cb)
-{
- Assert(m_pbStart == NULL);
- Assert(m_pbNext == NULL);
- Assert(m_pbLim == NULL);
-
- m_pbStart = pbBuffer;
- m_pbNext = pbBuffer;
- if (cb > 0)
- m_pbLim = m_pbStart + cb;
- // otherwise we don't know the length
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Close the stream.
-----------------------------------------------------------------------------------------------*/
-void GrBufferIStream::Close()
-{
- m_pbStart = NULL;
- m_pbNext = NULL;
- m_pbLim = NULL;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read a byte from the stream.
-----------------------------------------------------------------------------------------------*/
-byte GrBufferIStream::ReadByteFromFont()
-{
- byte bInput = *m_pbNext;
- m_pbNext += isizeof(byte);
- if (m_pbLim && m_pbNext > m_pbLim)
- THROW(kresReadFault);
- return bInput;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read a short (signed 16-bit) word from the stream. Switch the bytes from big-endian
- to little-endian format.
-----------------------------------------------------------------------------------------------*/
-short GrBufferIStream::ReadShortFromFont()
-{
- short snInput = *(short *)m_pbNext;
- m_pbNext += isizeof(short);
- if (m_pbLim && m_pbNext > m_pbLim)
- THROW(kresReadFault);
- snInput = lsbf(snInput);
- return snInput;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read a wide character (unsigned 16-bit word) from the stream.
- Switch the bytes from big-endian to little-endian format.
-----------------------------------------------------------------------------------------------*/
-utf16 GrBufferIStream::ReadUShortFromFont()
-{
- utf16 chwInput = *(utf16 *)m_pbNext;
- m_pbNext += isizeof(utf16);
- if (m_pbLim && m_pbNext > m_pbLim)
- THROW(kresReadFault);
- chwInput = lsbf(chwInput);
- return chwInput;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read a standard (32-bit) word from the stream. Switch the bytes from big-endian
- to little-endian format.
-----------------------------------------------------------------------------------------------*/
-int GrBufferIStream::ReadIntFromFont()
-{
- int nInput = *(int *)m_pbNext;
- m_pbNext += isizeof(int);
- if (m_pbLim && m_pbNext > m_pbLim)
- THROW(kresReadFault);
- nInput = lsbf(nInput);
- return nInput;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read a block of data from the stream. DON'T switch the bytes from big-endian
- to little-endian format.
-----------------------------------------------------------------------------------------------*/
-void GrBufferIStream::ReadBlockFromFont(void * pvInput, int cb)
-{
- std::copy(m_pbNext, m_pbNext + cb, reinterpret_cast<byte*>(pvInput));
- m_pbNext += cb;
- if (m_pbLim && m_pbNext > m_pbLim)
- THROW(kresReadFault);
-}
-
-/*----------------------------------------------------------------------------------------------
- Get the absolute position of the font-file stream (relative to the beginning of
- the file). For buffers, we just return the byte position in the buffer.
-----------------------------------------------------------------------------------------------*/
-void GrBufferIStream::GetPositionInFont(long * plPos)
-{
- *plPos = (m_pbNext - m_pbStart);
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the position of the font-file stream to the given absolute position (relative
- to the beginning of the file). For buffers, assume the position is relative to the
- beginning of the buffer.
-----------------------------------------------------------------------------------------------*/
-void GrBufferIStream::SetPositionInFont(long lPos)
-{
- m_pbNext = m_pbStart + lPos;
- if (m_pbLim && m_pbNext > m_pbLim)
- THROW(kresReadFault);
-}
-
-
-//:>********************************************************************************************
-//:> Swap byte order.
-//:>********************************************************************************************
-int swapb(int nArg)
-{
-#if WORDS_BIGENDIAN
-return nArg;
-#else
- int b1, b2, b3, b4;
- b1 = ((nArg & 0xFF000000) >> 24) & 0x000000FF; // remove sign extension
- b2 = ((nArg & 0x00FF0000) >> 8); // & 0x0000FF00;
- b3 = ((nArg & 0x0000FF00) << 8); // & 0x00FF0000;
- b4 = ((nArg & 0x000000FF) << 24); // & 0xFF000000;
- int nRet = b1 | b2 | b3 | b4;
- return nRet;
-#endif
-}
-
-unsigned int swapb(unsigned int nArg)
-{
-#if WORDS_BIGENDIAN
-return nArg;
-#else
- int b1, b2, b3, b4;
- b1 = ((nArg & 0xFF000000) >> 24) & 0x000000FF; // remove sign extension
- b2 = ((nArg & 0x00FF0000) >> 8); // & 0x0000FF00;
- b3 = ((nArg & 0x0000FF00) << 8); // & 0x00FF0000;
- b4 = ((nArg & 0x000000FF) << 24); // & 0xFF000000;
- int nRet = b1 | b2 | b3 | b4;
- return nRet;
-#endif
-}
-
-utf16 swapb(utf16 chwArg)
-{
-#if WORDS_BIGENDIAN
-return chwArg;
-#else
- utf16 b1, b2;
- b1 = ((chwArg & 0xFF00) >> 8) & 0x00FF; // remove sign extension
- b2 = ((chwArg & 0x00FF) << 8); // & 0xFF00;
- utf16 chwRet = b1 | b2;
- return chwRet;
-#endif
-}
-
-short swapb(short snArg)
-{
-#if WORDS_BIGENDIAN
-return snArg;
-#else
- short b1, b2;
- b1 = ((snArg & 0xFF00) >> 8) & 0x00FF; // remove sign extension
- b2 = ((snArg & 0x00FF) << 8); // & 0xFF00;
- short snRet = b1 | b2;
- return snRet;
-#endif
-}
-
-} //namespace gr
-
diff --git a/Build/source/libs/graphite-engine/src/segment/FileInput.h b/Build/source/libs/graphite-engine/src/segment/FileInput.h
deleted file mode 100644
index f8c32b762eb..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/FileInput.h
+++ /dev/null
@@ -1,104 +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: FileInput.h
-Responsibility: Sharon Correll
-Last reviewed: not yet
-
-Description:
- Defines utility functions for reading from a font file.
-----------------------------------------------------------------------------------------------*/
-
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef FILEINPUT_INCLUDED
-#define FILEINPUT_INCLUDED
-
-//:End Ignore
-
-namespace gr
-{
-
-int swapb(int nArg);
-unsigned int swapb(unsigned int nArg);
-utf16 swapb(utf16 chwArg);
-short swapb(short snArg);
-
-// Most significant byte first (converting from least-sig-first):
-inline int msbf(int nArg) { return swapb(nArg); }
-inline unsigned int msbf(unsigned int nArg) { return swapb(nArg); }
-inline utf16 msbf(utf16 chwArg) { return swapb(chwArg); }
-inline short msbf(short chwArg) { return swapb(chwArg); }
-
-// Least significant byte first (converting from most-sig first):
-inline int lsbf(int nArg) { return swapb(nArg); }
-inline unsigned int lsbf(unsigned int nArg) { return swapb(nArg); };
-inline utf16 lsbf(utf16 chwArg) { return swapb(chwArg); }
-inline short lsbf(short chwArg) { return swapb(chwArg); }
-
-class GrIStream
-{
-public:
- virtual void Close() = 0;
-
- virtual byte ReadByteFromFont() = 0;
- virtual short ReadShortFromFont() = 0;
- virtual utf16 ReadUShortFromFont() = 0;
- virtual int ReadIntFromFont() = 0;
- virtual void ReadBlockFromFont(void * pvInput, int cb) = 0;
-
- virtual void GetPositionInFont(long * plPos) = 0;
- virtual void SetPositionInFont(long lPos) = 0;
-
- virtual bool OpenBuffer(byte * pbBuffer, int cb) = 0;
- virtual void CloseBuffer() = 0;
-
-protected:
- virtual ~GrIStream() {}
-};
-
-
-/*----------------------------------------------------------------------------------------------
- A stream that reads from a buffer rather than a file.
-----------------------------------------------------------------------------------------------*/
-class GrBufferIStream : public GrIStream
-{
-public:
- GrBufferIStream();
- ~GrBufferIStream();
-
- #ifdef GR_FW
- virtual bool Open(std::wstring stuFileName, std::ios::openmode kMode);
- #else
- virtual bool Open(const char * pcFileName, std::ios::openmode kMode);
- #endif
- virtual void Close();
-
- virtual byte ReadByteFromFont();
- virtual short ReadShortFromFont();
- virtual utf16 ReadUShortFromFont();
- virtual int ReadIntFromFont();
- virtual void ReadBlockFromFont(void * pvInput, int cb);
-
- virtual void GetPositionInFont(long * plPos);
- virtual void SetPositionInFont(long lPos);
-
- virtual bool OpenBuffer(byte * pbBuffer, int cb);
- virtual void CloseBuffer()
- {
- Close();
- }
-
-protected:
- byte * m_pbStart;
- byte * m_pbNext;
- byte * m_pbLim;
-};
-
-} // namespace gr
-
-#endif // !FILEINPUT_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/FontCache.cpp b/Build/source/libs/graphite-engine/src/segment/FontCache.cpp
deleted file mode 100644
index f0540463e3b..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/FontCache.cpp
+++ /dev/null
@@ -1,308 +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: FontCache.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- A cache of all the font-face objects.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-// any other headers (not precompiled)
-
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-namespace gr
-{
-
-/*----------------------------------------------------------------------------------------------
- Store the given font-face in the cache. Overwrite whatever was there before.
- Return NULL if there is nothing appropriate there.
-----------------------------------------------------------------------------------------------*/
-void FontCache::GetFontFace(std::wstring strFaceName, bool fBold, bool fItalic,
- FontFace ** ppfface)
-{
- int ifci = FindCacheItem(strFaceName);
- if (ifci < 0) // no fonts of that family present
- {
- *ppfface = NULL;
- return;
- }
-
- CacheItem * pfci = m_prgfci + ifci;
- if (fBold)
- {
- if (fItalic)
- *ppfface = pfci->pffaceBI;
- else
- *ppfface = pfci->pffaceBold;
- }
- else
- {
- if (fItalic)
- *ppfface = pfci->pffaceItalic;
- else
- *ppfface = pfci->pffaceRegular;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Store the given font-face in the cache. Overwrite whatever was there before.
-----------------------------------------------------------------------------------------------*/
-void FontCache::CacheFontFace(std::wstring strFaceName, bool fBold, bool fItalic,
- FontFace * pfface)
-{
- if (m_prgfci == NULL)
- Initialize();
-
- int ifciIns = FindCacheItem(strFaceName);
- int ifci = ifciIns;
- if (ifciIns < 0)
- {
- ifci = (ifciIns + 1) * -1;
- InsertCacheItem(ifci);
- std::copy(strFaceName.c_str(), strFaceName.c_str() +
- (strFaceName.size() + 1), m_prgfci[ifci].szFaceName);
- }
-
- CacheItem * pfci = m_prgfci + ifci;
-
- bool fPrevNull;
- if (fBold)
- {
- if (fItalic)
- {
- fPrevNull = (pfci->pffaceBI == NULL);
- pfci->pffaceBI = pfface;
- }
- else
- {
- fPrevNull = (pfci->pffaceBold == NULL);
- pfci->pffaceBold = pfface;
- }
- }
- else
- {
- if (fItalic)
- {
- fPrevNull = (pfci->pffaceItalic == NULL);
- pfci->pffaceItalic = pfface;
- }
- else
- {
- fPrevNull = (pfci->pffaceRegular == NULL);
- pfci->pffaceRegular = pfface;
- }
- }
-
- if (fPrevNull && (pfface != NULL))
- m_cfface++;
-}
-
-/*----------------------------------------------------------------------------------------------
- Remove the given font-face from the cache. Return false if it couldn't be found.
-----------------------------------------------------------------------------------------------*/
-bool FontCache::RemoveFontFace(std::wstring strFaceName, bool fBold, bool fItalic,
- bool fZapCache)
-{
- int ifci = FindCacheItem(strFaceName);
- if (ifci < 0)
- {
- return false;
- }
-
- bool fPrevVal;
- CacheItem * pfci = m_prgfci + ifci;
- if (fBold)
- {
- if (fItalic)
- {
- fPrevVal = (pfci->pffaceBI != NULL);
- pfci->pffaceBI = NULL;
- }
- else
- {
- fPrevVal = (pfci->pffaceBold != NULL);
- pfci->pffaceBold = NULL;
- }
- }
- else
- {
- if (fItalic)
- {
- fPrevVal = (pfci->pffaceItalic != NULL);
- pfci->pffaceItalic = NULL;
- }
- else
- {
- fPrevVal = (pfci->pffaceRegular != NULL);
- pfci->pffaceRegular = NULL;
- }
- }
-
- if (fPrevVal)
- m_cfface--;
-
- Assert(m_cfface >= 0);
-
- if (m_flush == kflushAuto && fZapCache)
- {
- DeleteIfEmpty();
- }
-
- return fPrevVal;
-}
-
-/*----------------------------------------------------------------------------------------------
- Search for the font-family in the cache and return its index.
- If not present, return a negative number indicating where it was expected.
-----------------------------------------------------------------------------------------------*/
-int FontCache::FindCacheItem(std::wstring strFaceName)
-{
- if (m_cfci == 0)
- return -1;
-
- Assert(m_prgfci);
-
- // Use a binary-chop search.
-
- int ifciLow = 0;
- int ifciHigh = m_cfci;
- while (true)
- {
- int ifciMid = (ifciHigh + ifciLow) >> 1; // divide by 2
- CacheItem * pfci = m_prgfci + ifciMid;
- int tst = wcscmp(strFaceName.c_str(), (const wchar_t *)pfci->szFaceName);
- if (tst == 0)
- return ifciMid; // found it
- if (ifciLow + 1 == ifciHigh)
- {
- // not there; return where expected: 0 -> -1, 1 -> -2
- Assert(ifciMid == ifciLow);
- if (tst < 0)
- return (ifciLow * -1) - 1;
- else
- return (ifciHigh * -1) - 1;
- }
-
- // Keep looking.
- if (tst < 0)
- ifciHigh = ifciMid;
- else
- ifciLow = ifciMid;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Insert space in the cache at location ifci.
-----------------------------------------------------------------------------------------------*/
-void FontCache::InsertCacheItem(int ifci)
-{
- if (m_cfci == m_cfciMax)
- {
- // Cache is full; double the space.
- CacheItem * m_prgfciOld = m_prgfci;
- m_prgfci = new CacheItem[m_cfciMax * 2];
- std::copy(m_prgfciOld, m_prgfciOld + m_cfciMax, m_prgfci);
- delete[] m_prgfciOld;
- m_cfciMax *= 2;
- }
-
- // This copy involves overlapping ranges, so we need copy_backward not copy
- // to satisfy the preconditions
- std::copy_backward(m_prgfci + ifci, m_prgfci + m_cfci, m_prgfci + m_cfci + 1);
- m_cfci++;
-
- // Initialize inserted item.
- CacheItem * pfci = m_prgfci + ifci;
- pfci->pffaceRegular = NULL;
- pfci->pffaceBold = NULL;
- pfci->pffaceItalic = NULL;
- pfci->pffaceBI = NULL;
-}
-
-/*----------------------------------------------------------------------------------------------
- Delete the cache if it is empty.
-----------------------------------------------------------------------------------------------*/
-void FontCache::DeleteIfEmpty()
-{
- if (m_cfface <= 0)
- // All items are NULL; delete this cache. Probably this is because
- // the program is exiting.
- FontFace::ZapFontCache();
-}
-
-/*----------------------------------------------------------------------------------------------
- Check that the cache is indeed empty.
-----------------------------------------------------------------------------------------------*/
-void FontCache::AssertEmpty()
-{
-#ifdef _DEBUG
- for (int ifci = 0; ifci < m_cfci; ifci++)
- {
- CacheItem * pfci = m_prgfci + ifci;
- Assert(pfci->pffaceRegular == NULL);
- Assert(pfci->pffaceBold == NULL);
- Assert(pfci->pffaceItalic == NULL);
- Assert(pfci->pffaceBI == NULL);
- }
-#endif // _DEBUG
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the flush mode on the cache to indicate whether or not it should be deleted when
- it becomes empty.
-----------------------------------------------------------------------------------------------*/
-void FontCache::SetFlushMode(int flush)
-{
- m_flush = flush;
-
- if (m_flush == kflushAuto)
- {
- // Delete any font faces that have no remaining corresponding fonts.
- // Work backwards so as we remove items the loop still works.
- for (int ifci = m_cfci; --ifci >= 0; )
- {
- CacheItem * pfci = m_prgfci + ifci;
- if (pfci->pffaceRegular && pfci->pffaceRegular->NoFonts())
- RemoveFontFace(pfci->szFaceName, false, false, false);
- if (pfci->pffaceBold && pfci->pffaceBold->NoFonts())
- RemoveFontFace(pfci->szFaceName, true, false, false);
- if (pfci->pffaceItalic && pfci->pffaceItalic->NoFonts())
- RemoveFontFace(pfci->szFaceName, false, true, false);
- if (pfci->pffaceBI && pfci->pffaceBI->NoFonts())
- RemoveFontFace(pfci->szFaceName, true, true, false);
- }
-
- if (m_cfface <= 0)
- FontFace::ZapFontCache();
- }
-}
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/FontCache.h b/Build/source/libs/graphite-engine/src/segment/FontCache.h
deleted file mode 100644
index 56da5ab26b8..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/FontCache.h
+++ /dev/null
@@ -1,105 +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: FontCache.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- A cache of all the font-face objects known to mankind. There is exactly one instance
- of a FontCache.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef FONTCACHE_INCLUDED
-#define FONTCACHE_INCLUDED
-
-//:End Ignore
-
-namespace gr
-{
-
-class FontFace;
-class FontMemoryUsage;
-
-/*----------------------------------------------------------------------------------------------
- TODO: change from a sorted list to a hash table, if performance so requires.
-----------------------------------------------------------------------------------------------*/
-class FontCache {
- friend class FontMemoryUsage;
-
-public:
- FontCache()
- {
- m_cfci = 0;
- m_prgfci = NULL;
- m_cfciMax = 0;
- m_cfface = 0;
- m_flush = kflushAuto;
- }
-
- ~FontCache()
- {
- delete[] m_prgfci;
- m_prgfci = NULL;
- m_cfci = 0;
- m_cfciMax = 0;
- m_cfface = 0;
- }
-
- void Initialize()
- {
- m_cfci = 0;
- m_prgfci = new CacheItem[12];
- m_cfciMax = 12;
- m_cfface = 0;
- }
-
- struct CacheItem
- {
- wchar_t szFaceName[32]; // type should match std::wstring
- FontFace * pffaceRegular;
- FontFace * pffaceBold;
- FontFace * pffaceItalic;
- FontFace * pffaceBI;
- };
-
- void GetFontFace(std::wstring strFaceName, bool fBold, bool fItalic, FontFace ** ppfface);
- void CacheFontFace(std::wstring strFaceName, bool fBold, bool fItalic, FontFace * pfface);
- bool RemoveFontFace(std::wstring strFaceName, bool fBold, bool fItalic, bool fZapCache = true);
- void DeleteIfEmpty();
- void AssertEmpty();
-
- int GetFlushMode()
- {
- return m_flush;
- }
- void SetFlushMode(int);
-
- // Debugging:
- //bool DbgCheckFontCache();
-
- void calculateMemoryUsage(FontMemoryUsage & fmu);
-
-protected:
- int FindCacheItem(std::wstring strFaceName);
- void InsertCacheItem(int ifci);
-
-protected:
- // member variables;
- int m_cfci; // number of items (font-families)
- int m_cfciMax; // amount of space available
- int m_cfface; // number of font-faces
- CacheItem * m_prgfci;
-
- int m_flush;
-};
-
-} // namespace gr
-
-
-#endif // !FONTCACHE_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/FontFace.cpp b/Build/source/libs/graphite-engine/src/segment/FontFace.cpp
deleted file mode 100644
index 45461fe63ac..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/FontFace.cpp
+++ /dev/null
@@ -1,598 +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: GrEngine.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description: Contains the implementation of the FontFace class.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-#include <functional>
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-// any other headers (not precompiled)
-
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-FontCache * FontFace::s_pFontCache = 0;
-
-//:>********************************************************************************************
-//:> New interface
-//:>********************************************************************************************
-/*----------------------------------------------------------------------------------------------
- Return the appropriate FontFace, initialized with Graphite tables.
- Called from the font constructor.
-----------------------------------------------------------------------------------------------*/
-FontFace * FontFace::GetFontFace(Font * pfont,
- std::wstring strFaceName, bool fBold, bool fItalic,
- bool fDumbFallback)
-{
- if (s_pFontCache == NULL)
- s_pFontCache = new FontCache;
-
- FontFace * pfface;
- s_pFontCache->GetFontFace(strFaceName, fBold, fItalic, &pfface);
- if (pfface)
- return pfface;
-
- // Create a new font face.
- pfface = new FontFace();
- pfface->InitFontFace(pfont, strFaceName, fBold, fItalic, fDumbFallback);
- return pfface;
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize the engine using the given Graphite font.
-----------------------------------------------------------------------------------------------*/
-GrResult FontFace::InitFontFace(Font * pfont,
- std::wstring stuFaceName, bool fBold, bool fItalic,
- bool fDumbFallback)
-{
- AssertPtrN(pfont);
-
- m_pgreng = new GrEngine;
- m_pgreng->m_pfface = this;
-
- m_pgreng->m_nScriptTag = 0; // not currently used, but set it to something
-
- std::wstring stuFeatures;
-
- //stuFeatures = stuFeaturesArg;
-
- if (wcscmp(stuFaceName.c_str(), m_pgreng->m_stuFaceName.c_str()) != 0)
- {
- s_pFontCache->RemoveFontFace(m_pgreng->FaceName(), m_pgreng->Bold(), m_pgreng->Italic());
-
- m_pgreng->DestroyEverything(); // nothing we've cached is safe or useful.
- m_pgreng->m_stuFaceName = stuFaceName; // if this is buggy, using assign might fix it
- }
-
- //GrResult res = kresFail;
-//#ifdef GR_FW
-// // Read from the control file indicated by the registry, if any.
-// std::wstring stuFaceNameTmp;
-// stuFaceNameTmp.assign(rgchFaceName, wcslen(rgchFaceName));
-// res = InitFromControlFile(pfont, stuFaceName.c_str(), fBold, fItalic);
-//#endif // GR_FW
-
- // Read directly from the font.
- m_pgreng->DestroyContents();
- GrResult res = kresUnexpected;
- try {
- res = m_pgreng->ReadFontTables(pfont, fItalic);
- }
- catch (...)
- {
- if (fDumbFallback && m_pgreng->DumbFallback() && !m_pgreng->BadFont())
- {
- // If we have a basically good font but can't do Graphite,
- // just go with empty tables, which should be set up.
- res = m_pgreng->m_resFontRead;
- }
- else
- {
- if (m_cfonts == 0)
- {
- //s_pFontCache->DeleteIfEmpty();
- //Assert(s_pFontCache == 0);
- delete this; // will also delete GrEngine
- }
- else
- {
- delete m_pgreng;
- }
- m_pgreng = NULL;
- throw; // throw original exception
- }
- }
-
- m_pgreng->m_resFontValid = res;
-
- m_pgreng->m_fBold = fBold;
- m_pgreng->m_fItalic = fItalic;
-
- s_pFontCache->CacheFontFace(m_pgreng->FaceName(), fBold, fItalic, this);
-
- return m_pgreng->m_resFontValid;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the cmap and Graphite tables from the font that is selected into the graphics
- device.
-
- @return A GrResult indicating whether we were successful in loading the Graphite font:
- - kresOk means success
- - kresFail means the Graphite font could not be found or the basic font tables
- (head, name, cmap) could not be loaded
- - kresUnexpected means the Graphite tables could not be loaded
- - kresFalse means it is not a Graphite font at all (has no Silf table).
-----------------------------------------------------------------------------------------------*/
-GrResult GrEngine::ReadFontTables(Font * pfont, bool fItalic)
-{
- GrResult res = kresOk;
- m_ferr = kferrOkay;
- GrBufferIStream grstrm;
-
- FontException fexptn;
- fexptn.version = -1;
- fexptn.subVersion = -1;
-
- bool fOk = false;
-
- const void * pHeadTbl; const void * pSileTbl; const void * pSilfTbl;
- const void * pFeatTbl; const void * pGlatTbl; const void * pGlocTbl; const void * pSillTbl;
- //const void * pCmapTbl; const void * pNameTbl;
- size_t cbHeadSz, cbSilfSz, cbFeatSz, cbGlatSz, cbGlocSz, cbSillSz;
- //size_t cbCmapSz, cbSileSz, cbNameSz;
-
- m_fFakeItalic = false;
-
- bool fBasicTables = false;
- bool fSilf = false; // does the font have some sort of Silf table?
- int nCheckSum = 0;
-
- bool fBadBase = false,
- fMismatchedBase = false,
- fFontIsItalic = false;
-
- // First read the head table. This gives us the checksum that we are using as a
- // unique identifer. If it is the same as the one stored, and things appear set up,
- // don't reload the tables.
- res = (pHeadTbl = pfont->getTable(TtfUtil::TableIdTag(ktiHead), &cbHeadSz)) ? kresOk : kresFail;
- fOk = pHeadTbl && (cbHeadSz == 0 || TtfUtil::CheckTable(ktiHead, pHeadTbl, cbHeadSz));
- if (res == kresFail)
- {
- m_stuInitError = L"could not locate head table for Graphite rendering";
- m_ferr = kferrFindHeadTable;
- goto LUnexpected;
- }
- if (!fOk)
- {
- m_stuInitError = L"could not read design units for Graphite rendering";
- m_ferr = kferrReadDesignUnits;
- goto LUnexpected;
- }
- m_mFontEmUnits = TtfUtil::DesignUnits(pHeadTbl);
- nCheckSum = TtfUtil::HeadTableCheckSum(pHeadTbl);
- fFontIsItalic = TtfUtil::IsItalic(pHeadTbl);
-
- if (m_nFontCheckSum == nCheckSum && m_ptman)
- return m_resFontRead; // already initialized in some form
-
- DestroyContents();
-
- Assert(!m_ptman);
- Assert(!m_pctbl);
- Assert(!m_pgtbl);
- Assert(!m_prgpsd);
- m_prgpsd = NULL;
- m_cpsd = 0;
-
- m_ptman = new GrTableManager(this);
-
- m_fFakeItalic = (fItalic && !fFontIsItalic);
-
- // Look for an Sile table. If there is one, this is an extension font containing only
- // the Graphite tables. Read the base font name out of the Sile table, and use it to
- // read the cmap. Then replace the original font name to read the Graphite tables.
-
- m_fUseSepBase = false;
- m_stuBaseFaceName.erase();
-
- // TODO: rework the handling of the Sile table.
- pSileTbl = NULL;
- //pSileTbl = pfont->getTable(TtfUtil::TableIdTag(ktiSile));
- //if (pSileTbl)
- //{
- // pgg->get_FontCharProperties(&chrpOriginal);
- // grstrm.OpenBuffer(pSileTbl, sile_tbl.size());
- // m_fUseSepBase = ReadSileTable(pgg, grstrm, 0, &m_mFontEmUnits, &fMismatchedBase);
- // grstrm.Close();
-
- // if (!m_fUseSepBase)
- // {
- // SwitchGraphicsFont(pgg, false); // back to Graphite table font
- // m_stuBaseFaceName.erase();
- // fBadBase = true;
- // m_fUseSepBase = false;
- // }
- // // Otherwise leave the GrGraphics in a state to read from the base font.
- //}
-
- // We don't need the offset table, and there's no way to get it anyway
- // without a font file.
-
- // cmap and name
- Assert(!m_fCmapTblCopy);
- Assert(!m_fNameTblCopy);
- fOk = SetCmapAndNameTables(pfont);
- if (!fOk)
- {
- goto LUnexpected;
- }
-
- fBasicTables = true;
-
- // If we have a bad base file, don't do Graphite stuff.
- if (fBadBase || fMismatchedBase)
- goto LUnexpected;
-
- /****
- Obtain font name from InitNew() now instead of reading from font file. InitNew should
- should have a correct font name passed to it since it should come from a font registered
- by GrFontInst.exe. This commented code could be use to verify name in font file matches.
- NOTE: if we ever use this code again, make sure we're using the base font name table,
- not the Graphite wrapper font name table.
- // find the font family name
- if (!TtfUtil::Get31EngFamilyInfo(vbName.Begin(), lnNameOff, lnNameSz))
- { // use Name table which is Symbol encode instead
- // this could cause problems if a real Symbol writing system is used in the name table
- // however normally real Unicode values are used instead a Symbol writing system
- if (!TtfUtil::Get30EngFamilyInfo(vbName.Begin(), lnNameOff, lnNameSz))
- {
- ReturnResult(kresFail);
- }
- // test for Symbol writing system. first byte of Unicode id should be 0xF0
- if (vbName[lnNameOff + 1] == (unsigned char)0xF0) // 1 - Unicode id is big endian
- ReturnResult(kresFail);
- }
- if (!TtfUtil::SwapWString(vbName.Begin() + lnNameOff, lnNameSz / isizeof(utf16)))
- ReturnResult(kresFail);
-
- m_stuFaceName = std::wstring((utf16 *)(vbName.begin() + lnNameOff), lnNameSz / isizeof(utf16));
- ****/
-
- // Silf
- res = (pSilfTbl = pfont->getTable(TtfUtil::TableIdTag(ktiSilf), &cbSilfSz)) ? kresOk : kresFail;
- fOk = pSilfTbl && (cbSilfSz == 0 || TtfUtil::CheckTable(ktiSilf, pSilfTbl, cbSilfSz));
- if (!fOk)
- {
- m_stuInitError = L"could not load Silf table for Graphite rendering";
- m_ferr = kferrLoadSilfTable;
- goto LUnexpected;
- }
-
- // Feat
- res = (pFeatTbl = pfont->getTable(TtfUtil::TableIdTag(ktiFeat), &cbFeatSz)) ? kresOk : kresFail;
- fOk = pFeatTbl && (cbFeatSz == 0 || TtfUtil::CheckTable(ktiFeat, pFeatTbl, cbFeatSz));
- if (!fOk)
- {
- // TODO: just create an empty set of features, since this is not disastrous.
- m_stuInitError = L"could not load Feat table for Graphite rendering";
- m_ferr = kferrLoadFeatTable;
- goto LUnexpected;
- }
-
- // Glat
- res = (pGlatTbl = pfont->getTable(TtfUtil::TableIdTag(ktiGlat), &cbGlatSz)) ? kresOk : kresFail;
- fOk = pGlatTbl && (cbGlatSz == 0 || TtfUtil::CheckTable(ktiGlat, pGlatTbl, cbGlatSz));
- if (!fOk)
- {
- m_stuInitError = L"could not load Glat table for Graphite rendering";
- m_ferr = kferrLoadGlatTable;
- goto LUnexpected;
- }
-
- // Gloc
- res = (pGlocTbl = pfont->getTable(TtfUtil::TableIdTag(ktiGloc), &cbGlocSz)) ? kresOk : kresFail;
- fOk = pGlocTbl && (cbGlocSz == 0 || TtfUtil::CheckTable(ktiGloc, pGlocTbl, cbGlocSz));
- if (!fOk)
- {
- m_stuInitError = L"could not load Gloc table for Graphite rendering";
- m_ferr = kferrLoadGlocTable;
- goto LUnexpected;
- }
-
- // Sill
- try {
- res = (pSillTbl = pfont->getTable(TtfUtil::TableIdTag(ktiSill), &cbSillSz)) ? kresOk : kresFail;
- fOk = pSillTbl && (cbSillSz == 0 || TtfUtil::CheckTable(ktiSill, pSillTbl, cbSillSz));
- }
- catch (...)
- {
- fOk = true;
- pSillTbl = NULL;
- }
- // if table couldn't be loaded, this is not disastrous.
-
-// ibGlocStart = cbGlatTbl;
- fOk = CheckTableVersions(&grstrm,
- (byte *)pSilfTbl, 0,
- (byte *)pGlocTbl, 0,
- (byte *)pFeatTbl, 0,
- &m_fxdBadVersion);
- if (!fOk)
- {
-// wchar_t rgch1[50];
-// wchar_t rgch2[50];
-//#if defined(_WIN32)
-// // This version does not work in Windows, in spite of being documented:
-// // swprintf(rgch, 50, L"%d", (m_fxdBadVersion >> 16));
-// // Removing the size argument make it work.
-// swprintf(rgch1, L"%d", (m_fxdBadVersion >> 16));
-// swprintf(rgch2, L"%d", (m_fxdBadVersion & 0x0000FFFF));
-//#else
-// swprintf(rgch1, 50, L"%d", (m_fxdBadVersion >> 16));
-// swprintf(rgch2, 50, L"%d", (m_fxdBadVersion & 0x0000FFFF));
-//#endif
- char rgch[50]; // more than enough space to print two 16-bit ints
- char *pch = &rgch[0];
- sprintf(rgch, "%d.%d", (m_fxdBadVersion >> 16), (m_fxdBadVersion & 0x0000FFFF));
- std::wstring stu = L"unsupported version (";
- //stu.append(rgch1);
- //stu.append(L".");
- //stu.append(rgch2);
- while (*pch != 0)
- stu.push_back((wchar_t)*pch++);
- stu.append(L") of Graphite tables");
- m_stuInitError.assign(stu.c_str());
- m_ferr = kferrBadVersion;
- goto LUnexpected;
- }
-
- try
- {
- // Parse the "Silf" table.
- grstrm.OpenBuffer((byte*)pSilfTbl, cbSilfSz);
- int chwGlyphIDMax, fxdVersion;
- bool f = ReadSilfTable(grstrm, 0, 0, &chwGlyphIDMax, &fxdVersion);
- grstrm.Close();
- if (!f)
- {
- m_ferr = kferrReadSilfTable;
- fexptn.errorCode = m_ferr;
- throw fexptn;
- }
-
- // Parse the "Gloc" and "Glat" tables.
- {
- GrBufferIStream grstrmGlat;
-
- grstrm.OpenBuffer((byte *)pGlocTbl, cbGlocSz);
- grstrmGlat.OpenBuffer((byte *)pGlatTbl, cbGlatSz);
- f = ReadGlocAndGlatTables(grstrm, 0, grstrmGlat, 0, chwGlyphIDMax, fxdVersion);
- grstrm.Close();
- grstrmGlat.Close();
- if (!f)
- {
- m_ferr = kferrReadGlocGlatTable;
- fexptn.errorCode = m_ferr;
- throw fexptn;
- }
- }
-
- // Parse the "Feat" table.
- grstrm.OpenBuffer((byte *)pFeatTbl, cbFeatSz);
- f = ReadFeatTable(grstrm, 0);
- grstrm.Close();
- if (!f)
- {
- m_ferr = kferrReadFeatTable;
- fexptn.errorCode = m_ferr;
- throw fexptn;
- }
-
- // Parse the "Sill" table.
- if (pSillTbl)
- {
- grstrm.OpenBuffer((byte *)pSillTbl, cbFeatSz);
- f = ReadSillTable(grstrm, 0);
- grstrm.Close();
- if (!f)
- {
- m_ferr = kferrReadSillTable;
- fexptn.errorCode = m_ferr;
- throw fexptn;
- }
- }
- else
- m_langtbl.CreateEmpty();
- }
- catch (...)
- {
- fSilf = false;
- m_resFontRead = kresUnexpected;
- try {
- DestroyContents(false);
- }
- catch (...)
- {}
- goto LUnexpected;
- }
-
- m_stuErrCtrlFile.erase();
- m_nFontCheckSum = nCheckSum;
- m_resFontRead = kresOk;
- m_ferr = kferrOkay;
- ReturnResult(kresOk);
-
-LUnexpected:
- // Don't do this, because it is possible to use a base font with an empty Graphite
- // engine:
- //if (m_fUseSepBase || m_stuBaseFaceName.Length() > 0)
- //{
- // SwitchGraphicsFont(pgg, false); // back to Graphite table font
- // m_stuBaseFaceName.erase();
- // m_fUseSepBase = false;
- //}
-
- CreateEmpty();
- m_nFontCheckSum = nCheckSum;
- if (!fBasicTables)
- m_resFontRead = kresFail; // bad font
- else if (!fSilf)
- m_resFontRead = kresFalse; // no Silf table--not a Graphite font
- else
- m_resFontRead = kresUnexpected; // couldn't read the Graphite tables
-
- fexptn.errorCode = m_ferr;
- fexptn.version = m_fxdBadVersion >> 16;
- fexptn.subVersion = m_fxdBadVersion & 0x0000FFFF;
- throw fexptn;
-
- ReturnResult(m_resFontRead);
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the cmap and name tables.
-
- This is called from two places. One is when we first initialize the engine. Also, if the
- font tables have not been actually copied from the font, they may have been deleted
- when the font was deleted. So when reusing the engine, set them to something valid based
- on the current font.
-----------------------------------------------------------------------------------------------*/
-bool GrEngine::SetCmapAndNameTables(Font * pfont)
-{
- GrResult res = kresOk;
- bool fOk;
- const void * pCmapTbl;
- const void * pNameTbl;
- size_t cbCmapSz, cbNameSz;
-
- // cmap
- if (!m_fCmapTblCopy)
- {
- res = (pCmapTbl = pfont->getTable(TtfUtil::TableIdTag(ktiCmap), &cbCmapSz)) ? kresOk : kresFail;
- fOk = pCmapTbl && (cbCmapSz == 0 || TtfUtil::CheckTable(ktiCmap, pCmapTbl, cbCmapSz));
- if (!fOk)
- {
- m_stuInitError = L"could not locate cmap table";
- m_ferr = kferrFindCmapTable;
- return false;
- }
-
- if (pCmapTbl && cbCmapSz > 0)
- {
- // Make a private copy of the cmap for the engine's use.
- m_pCmapTbl = new byte[cbCmapSz];
- std::copy(reinterpret_cast<const byte*>(pCmapTbl),
- reinterpret_cast<const byte*>(pCmapTbl) + cbCmapSz, m_pCmapTbl);
- m_fCmapTblCopy = true;
- m_cbCmapTbl = cbCmapSz;
- }
- else
- {
- m_pCmapTbl = const_cast<byte*>(reinterpret_cast<const byte*>(pCmapTbl));
- m_fCmapTblCopy = false;
- }
-
- // MS Unicode cmap
- m_pCmap_3_1 = TtfUtil::FindCmapSubtable(m_pCmapTbl, 3, 1);
- m_pCmap_3_10 = TtfUtil::FindCmapSubtable(m_pCmapTbl, 3, 10);
- if (!m_pCmap_3_1)
- m_pCmap_3_1 = TtfUtil::FindCmapSubtable(m_pCmapTbl, 3, 0);
- if (!m_pCmap_3_1)
- {
- m_stuInitError = L"failure to load cmap subtable";
- m_ferr = kferrLoadCmapSubtable;
- return false;
- }
- if (!TtfUtil::CheckCmap31Subtable(m_pCmap_3_1))
- {
- m_stuInitError = L"checking cmap subtable failed";
- m_ferr = kferrCheckCmapSubtable;
- return false;
- }
- }
- else
- {
- Assert(m_pCmapTbl);
- }
-
- // name table - eventually need feature label strings
-
- // Currently the only stuff we're getting from the name table are our feature names,
- // so use the version from the Graphite font (not the base font if any).
- //////if (m_fUseSepBase)
- ////// pgg->SetupGraphics(&chrpOriginal);
-
- if (!m_fNameTblCopy)
- {
- res = (pNameTbl = (byte *)pfont->getTable(TtfUtil::TableIdTag(ktiName), &cbNameSz)) ? kresOk : kresFail;
- fOk = pNameTbl && (cbNameSz == 0 || TtfUtil::CheckTable(ktiName, pNameTbl, cbNameSz));
- if (!fOk)
- {
- m_stuInitError = L"could not locate name table";
- m_ferr = kferrFindNameTable;
- return false;
- }
-
- if (pNameTbl && cbNameSz > 0)
- {
- // Make a private copy of the name table for the engine's use.
- m_pNameTbl = new byte[cbNameSz];
- std::copy(reinterpret_cast<const byte*>(pNameTbl),
- reinterpret_cast<const byte*>(pNameTbl) + cbNameSz, m_pNameTbl);
- m_fNameTblCopy = true;
- m_cbNameTbl = cbNameSz;
- }
- else
- {
- m_pNameTbl = const_cast<byte*>(reinterpret_cast<const byte*>(pNameTbl));
- m_fNameTblCopy = false;
- }
- }
- else
- {
- Assert(m_pNameTbl);
- }
-
- return true;
-}
-
-
-//void FontFace::DbgCheckFontFace()
-//{
-// Assert(m_cfonts < 5000);
-// Assert(m_cfonts >= 0);
-// wchar_t chw0 = m_pgreng->m_stuFaceName[0];
-// Assert(chw0 >= 0x0040); // A
-// Assert(chw0 <= 0x007A); // z
-//}
-
-} // namespace gr
-
-//:End Ignore
diff --git a/Build/source/libs/graphite-engine/src/segment/FontFace.h b/Build/source/libs/graphite-engine/src/segment/FontFace.h
deleted file mode 100644
index 7f2684a5908..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/FontFace.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*--------------------------------------------------------------------
-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: FontFace.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Contains the definition of the FontFace class.
- TODO: Merge with GrEngine.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef FONTFACE_INCLUDED
-#define FONTFACE_INCLUDED
-#include <limits>
-
-#ifdef _MSC_VER
-#include <crtdbg.h>
-#endif
-
-namespace gr
-{
-
-class IGrJustifier;
-class Segment;
-
-
-/*----------------------------------------------------------------------------------------------
- The GrEngine serves as the top level object that knows how to run Graphite tables
- and generate Graphite segments.
-
- Primarily, this class implements IRenderEngine, which allows it to serve as a FW
- rendering engine. It also implements ISimpleInit, a general interface for initializing
- using a string. Finally, it implements ITraceControl, a very simple interface which
- allows a client to flip a flag indicating whether or not we want to output a log of
- the Graphite transduction process.
-
- Hungarian: greng
-----------------------------------------------------------------------------------------------*/
-class FontFace
-{
- friend class gr::FontMemoryUsage;
-
-public:
- FontFace()
- {
- m_cfonts = 0;
- }
-
- ~FontFace()
- {
- if (s_pFontCache)
- s_pFontCache->RemoveFontFace(m_pgreng->FaceName(), m_pgreng->Bold(), m_pgreng->Italic());
- delete m_pgreng;
- }
-
- void IncFontCount()
- {
- m_cfonts++;
- }
- void DecFontCount()
- {
- m_cfonts--;
- if (m_cfonts <= 0 && (s_pFontCache == NULL || s_pFontCache->GetFlushMode() == kflushAuto))
- delete this;
- }
-
- bool NoFonts()
- {
- return (m_cfonts <= 0);
- }
-
- static FontFace * GetFontFace(Font * pfont,
- std::wstring strFaceName, bool fBold, bool fItalic,
- bool fDumbFallback = false);
-
- GrResult InitFontFace(Font * pfont,
- std::wstring stuFaceName, bool fBold, bool fItalic,
- bool fDumbLayout);
-
- FontErrorCode IsValidForGraphite(int * pnVersion, int * pnSubVersion)
- {
- return m_pgreng->IsValidForGraphite(pnVersion, pnSubVersion);
- }
-
- static void ZapFontCache()
- {
- if (s_pFontCache)
- {
- s_pFontCache->AssertEmpty();
- delete s_pFontCache;
- }
- s_pFontCache = NULL;
- }
-
- static void SetFlushMode(int flush)
- {
- if (s_pFontCache == NULL)
- s_pFontCache = new FontCache;
- s_pFontCache->SetFlushMode(flush);
- }
- static int GetFlushMode()
- {
- if (s_pFontCache == NULL)
- s_pFontCache = new FontCache;
- return s_pFontCache->GetFlushMode();
- }
-
- // Temporary, until interface gets thoroughly reworked:
- GrEngine * GraphiteEngine()
- {
- return m_pgreng;
- }
-
- // Feature access:
- size_t NumberOfFeatures()
- {
- return m_pgreng->NumberOfFeatures_ff();
- }
- featid FeatureID(size_t ifeat)
- {
- return m_pgreng->FeatureID_ff(ifeat);
- }
- size_t FeatureWithID(featid id)
- {
- return m_pgreng->FeatureWithID_ff(id);
- }
- bool GetFeatureLabel(size_t ifeat, lgid language, utf16 * label)
- {
- return m_pgreng->GetFeatureLabel_ff(ifeat, language, label);
- }
- int GetFeatureDefault(size_t ifeat) // index of default setting
- {
- return m_pgreng->GetFeatureDefault_ff(ifeat);
- }
- size_t NumberOfSettings(size_t ifeat)
- {
- return m_pgreng->NumberOfSettings_ff(ifeat);
- }
- int GetFeatureSettingValue(size_t ifeat, size_t ifset)
- {
- return m_pgreng->GetFeatureSettingValue_ff(ifeat, ifset);
- }
- bool GetFeatureSettingLabel(size_t ifeat, size_t ifset, lgid language, utf16 * label)
- {
- return m_pgreng->GetFeatureSettingLabel_ff(ifeat, ifset, language, label);
- }
- // Feature-label language access:
- size_t NumberOfFeatLangs()
- {
- return m_pgreng->NumberOfFeatLangs_ff();
- }
- short FeatLabelLang(int ilang)
- {
- return m_pgreng->GetFeatLabelLang_ff(ilang);
- }
- // Language access:
- size_t NumberOfLanguages()
- {
- return m_pgreng->NumberOfLanguages_ff();
- }
- isocode LanguageCode(size_t ilang)
- {
- return m_pgreng->GetLanguageCode_ff(ilang);
- }
-
- // Script Direction access:
- ScriptDirCode ScriptDirection() const throw()
- {
- unsigned int script_dirs = 0;
- OLECHAR err_dummy = 0;
- m_pgreng->get_ScriptDirection(&script_dirs, &err_dummy, 1);
- return ScriptDirCode(script_dirs);
- }
-
- bool BadFont(FontErrorCode * pferr = NULL)
- {
- return m_pgreng->BadFont(pferr);
- }
- bool DumbFallback(FontErrorCode * pferr = NULL)
- {
- return m_pgreng->DumbFallback(pferr);
- }
-
-public:
- // For use in segment creation:
- void RenderLineFillSegment(Segment * pseg, Font * pfont, ITextSource * pts,
- LayoutEnvironment & layout,
- toffset ichStart, toffset ichStop, float xsMaxWidth, bool fBacktracking)
- {
- m_pgreng->MakeSegment(pseg, pfont, pts, NULL, layout,
- ichStart, ichStop, xsMaxWidth, fBacktracking, false, 0, kestMoreLines);
- }
- void RenderRangeSegment(Segment * pseg, Font * pfont,
- ITextSource * pts, LayoutEnvironment & layout,
- toffset ichStart, toffset ichStop)
- {
- m_pgreng->MakeSegment(pseg, pfont, pts, NULL, layout,
- ichStart, ichStop, kPosInfFloat, false, false, 0, kestMoreLines);
- }
- void RenderJustifiedSegment(Segment * pseg, Font * pfont,
- ITextSource * pts, LayoutEnvironment & layout,
- toffset ichStart, toffset ichStop, float xsCurrentWidth, float xsDesiredWidth)
- {
- m_pgreng->MakeSegment(pseg, pfont, pts, NULL, layout,
- ichStart, ichStop, xsCurrentWidth, false, true, xsDesiredWidth, kestMoreLines);
- }
-
- // Debugging.
- //static bool DbgCheckFontCache()
- //{
- // if (s_pFontCache)
- // return s_pFontCache->DbgCheckFontCache();
- // else
- // return true;
- //}
- //void DbgCheckFontFace();
-
- static void calculateAllMemoryUsage(FontMemoryUsage & fmu);
- void calculateMemoryUsage(FontMemoryUsage & fmu);
-
-protected:
- // Number of fonts in existence that use this face; when it goes to zero, delete.
- int m_cfonts;
-
- // Static variable:
- static FontCache * s_pFontCache;
-
- // Member variables:
- GrEngine * m_pgreng;
-};
-
-} // namespace gr
-
-
-#if defined(GR_NO_NAMESPACE)
-using namespace gr;
-#endif
-
-
-#endif // !FONTFACE_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/GrCharStream.cpp b/Build/source/libs/graphite-engine/src/segment/GrCharStream.cpp
deleted file mode 100644
index 20b5a46ab76..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrCharStream.cpp
+++ /dev/null
@@ -1,652 +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: GrCharStream.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Implements the GrCharStream class.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Constructor.
-----------------------------------------------------------------------------------------------*/
-GrCharStream::GrCharStream(ITextSource * pgts, int ichrMin, int ichrLim,
- bool fStartLine, bool fEndLine)
- : m_pgts(pgts),
- m_ichrMin(ichrMin),
- m_ichrLim(ichrLim),
- m_ichrPos(ichrMin),
- m_fStartLine(fStartLine),
- m_fEndLine(fEndLine),
- m_cchrBackedUp(0),
- m_ichrRunMin(0),
- m_ichrRunLim(0),
- m_ichlRunOffset(kPosInfinity),
- m_ichrRunOffset(kPosInfinity)
-{
- #if 0 // ??? surely m_cnRunMax and m_prgnRunText are undefined at this point
- if (m_cchlRunMax > -1)
- delete[] m_prgchlRunText;
- #endif
- m_cchlRunMax = -1;
- m_prgchlRunText = NULL;
-
- m_vislotNextChunkMap.clear();
-
- m_utf = m_pgts->utfEncodingForm();
-}
-
-/*----------------------------------------------------------------------------------------------
- Restart the stream when an error has a occurred and we need to fall back to dumb rendering.
-----------------------------------------------------------------------------------------------*/
-void GrCharStream::Restart()
-{
- if (m_cchlRunMax > -1)
- delete[] m_prgchlRunText;
-
- m_ichrPos = m_ichrMin;
- m_cchrBackedUp = 0;
- m_ichrRunMin = 0;
- m_ichrRunLim = 0;
- m_ichlRunOffset = kPosInfinity;
- m_ichrRunOffset = kPosInfinity;
-
- m_cchlRunMax = -1;
- m_prgchlRunText = NULL;
-
- m_vislotNextChunkMap.clear();
-}
-
-/*----------------------------------------------------------------------------------------------
- Get the next character from the stream.
-
- @param pichwSegOffset - index of this character from the beginning of the segment
- @param pcchRaw - number of raw (UTF-16 or UTF-8) chars consumed to get one complete
- Unicode codepoint.
-----------------------------------------------------------------------------------------------*/
-int GrCharStream::NextGet(GrTableManager * ptman,
- GrFeatureValues * pfval, int * pichrSegOffset, int * pcchr)
-{
- if (AtEnd())
- {
- Assert(m_ichrPos == m_ichrLim);
- return 0;
- }
-
- int m_ichrMinBackedUp = m_ichrMin - m_cchrBackedUp;
-
- if ((m_ichrRunOffset + m_ichrRunMin) >= m_ichrRunLim)
- {
- // Get the next run of characters
-
- std::pair<toffset, toffset> pairRange = m_pgts->propertyRange(m_ichrPos);
- m_ichrRunMin = pairRange.first;
- m_ichrRunLim = pairRange.second;
-
- // The only time the run extends before what we want is on the first run.
- Assert((m_ichrRunMin == m_ichrPos) // m_ichwPos is beginning of run
- || (m_ichrPos == m_ichrMinBackedUp)); // first run
- // Pretend like the run starts where we need it:
- m_ichrRunMin = max(m_ichrRunMin, m_ichrMinBackedUp);
- Assert(m_ichrRunMin == m_ichrPos);
-
- if (m_cchlRunMax != -1 && m_cchlRunMax < m_ichrRunLim - m_ichrRunMin)
- {
- // Text buffer is too small: delete it and create a new one.
- delete[] m_prgchlRunText;
- m_cchlRunMax = -1;
- }
-
- if (m_cchlRunMax == -1)
- {
- // Note that combining surrogates or UTF-8 will always result in the same or fewer
- // number of characters needed in m_prgchlRunText, so the following is safe:
- m_cchlRunMax = m_ichrRunLim - m_ichrRunMin;
- m_prgchlRunText = new int[m_cchlRunMax];
- }
-
- utf32 * prgchlRunText32 = NULL;
- utf16 * prgchwRunText16 = NULL;
- utf8 * prgchsRunText8 = NULL;
-
- int cchGot;
- switch (m_utf)
- {
- case kutf8:
- prgchsRunText8 = new utf8[m_ichrRunLim - m_ichrRunMin];
- cchGot = m_pgts->fetch(m_ichrRunMin, m_ichrRunLim - m_ichrRunMin, prgchsRunText8);
- break;
- case kutf16:
- prgchwRunText16 = new utf16[m_ichrRunLim - m_ichrRunMin];
- cchGot = m_pgts->fetch(m_ichrRunMin, m_ichrRunLim - m_ichrRunMin, prgchwRunText16);
- break;
- default:
- Assert(false);
- // Assume UTF-32: fall through
- case kutf32:
- prgchlRunText32 = new utf32[m_ichrRunLim - m_ichrRunMin];
- cchGot = m_pgts->fetch(m_ichrRunMin, m_ichrRunLim - m_ichrRunMin, prgchlRunText32);
- break;
- }
-
- int ichlUtf32 = 0;
- for (int ichr = 0; ichr < m_ichrRunLim - m_ichrRunMin; ichr++)
- {
- if (ichr == m_ichrPos - m_ichrRunMin)
- {
- m_ichrRunOffset = ichr;
- m_ichlRunOffset = ichlUtf32;
- }
- Assert(m_ichrRunOffset != kPosInfinity || ichr < m_ichrPos - m_ichrRunMin);
-
- int cchrUsed;
- switch (m_utf)
- {
- case kutf8:
- m_prgchlRunText[ichlUtf32] = Utf8ToUtf32(prgchsRunText8 + ichr,
- m_ichrRunLim - m_ichrRunMin - ichr, &cchrUsed);
- break;
- case kutf16:
- m_prgchlRunText[ichlUtf32] = Utf16ToUtf32(prgchwRunText16 + ichr,
- m_ichrRunLim - m_ichrRunMin - ichr, &cchrUsed);
- break;
- default:
- Assert(false);
- // Assume UTF-32: fall through
- case kutf32:
- m_prgchlRunText[ichlUtf32] = prgchlRunText32[ichlUtf32];
- cchrUsed = 1;
- break;
- }
-
- m_vislotNextChunkMap.push_back(ichlUtf32);
- for (int i = 1; i < cchrUsed; i++)
- m_vislotNextChunkMap.push_back(-1);
- ichr += cchrUsed - 1;
- ichlUtf32++;
- }
- delete[] prgchlRunText32;
- delete[] prgchwRunText16;
- delete[] prgchsRunText8;
-
- while (m_ichrLim - m_ichrRunMin < signed(m_vislotNextChunkMap.size())
- && m_vislotNextChunkMap[m_ichrLim - m_ichrRunMin] == -1)
- {
- // Invalid surrogate boundary; this is really a bug in the application program,
- // but adjust here to avoid a crash!
- m_ichrLim--;
- }
-
- SetUpFeatureValues(ptman, m_ichrPos);
-
- Assert(m_ichrRunOffset >= 0);
- Assert(m_ichrRunOffset < m_ichrRunLim - m_ichrRunMin);
- Assert(m_vislotNextChunkMap.size() == (unsigned) m_ichrRunLim - m_ichrMinBackedUp);
- }
-
- int chlRet = m_prgchlRunText[m_ichlRunOffset];
- *pfval = m_fvalRunFeats;
- *pichrSegOffset = m_ichrPos - m_ichrMin; // offset from the official start of the segment
- // of the first 16-bit char
- int ichrPosPrev = m_ichrPos;
- ++m_ichlRunOffset;
- do {
- ++m_ichrPos;
- ++m_ichrRunOffset;
- } while (m_ichrPos - m_ichrMinBackedUp < signed(m_vislotNextChunkMap.size())
- && m_vislotNextChunkMap[m_ichrPos - m_ichrMinBackedUp] == -1);
-
- *pcchr = m_ichrPos - ichrPosPrev; // number of raw chars consumed
- Assert(m_utf != kutf8 || *pcchr <= 6);
- Assert(m_utf != kutf16 || *pcchr <= 2);
-
- Assert(m_ichrPos == (m_ichrRunMin + m_ichrRunOffset));
- Assert(m_ichrPos <= m_ichrLim);
-
- /* KLUDGE for debugging
- if (m_ichrPos == 1)
- nRet = 0x1018;
- else if (m_ichrPos == 2)
- nRet = 0x1039;
- else if (m_ichrPos == 3)
- nRet = 0x101b;
- else if (m_ichrPos == 4)
- nRet = 0x1032;
- else if (m_ichrPos == 5)
- nRet = 0x1037;
- else if (m_ichrPos == 6)
- nRet = 0x1037;
- */
-
- return chlRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Convert UTF-8 to UTF-32--a single character's worth. Also pass back the number of 8-bit
- items consumed.
-----------------------------------------------------------------------------------------------*/
-utf32 GrCharStream::Utf8ToUtf32(utf8 * prgchs, int cchs, int * pcchsUsed)
-{
- if (cchs <= 0)
- {
- *pcchsUsed = 0;
- return 0;
- }
-
- long chlRet = DecodeUtf8(prgchs, cchs, pcchsUsed);
- Assert(chlRet > 0);
- if (chlRet == -1)
- {
- // Some error occurred. Just treat the UTF-8 as UTF-32.
- *pcchsUsed = 1;
- return (utf32)prgchs[0];
- }
- else
- return chlRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Convert UTF-16 to UTF-32--a single character's worth. Also pass back the number of 16-bit
- items consumed.
-----------------------------------------------------------------------------------------------*/
-utf32 GrCharStream::Utf16ToUtf32(utf16 * prgchw, int cchw, int * pcchwUsed)
-{
- if (cchw <= 0)
- {
- *pcchwUsed = 0;
- return 0;
- }
-
- unsigned int nUtf32;
- bool fSurrogate = FromSurrogatePair(prgchw[0], ((cchw < 2) ? 0 : prgchw[1]), &nUtf32);
- *pcchwUsed = (fSurrogate) ? 2 : 1;
- return (int)nUtf32;
-
-/*
- // For testing:
- int nCharRet;
- if (cchw >= 2 && prgchw[0] == '^' && prgchw[1] == 'a')
- {
- nCharRet = 'A';
- *pcchwUsed = 2;
- }
- else if (cchw >= 3 && prgchw[0] == '#' && prgchw[1] == '#' &&
- prgchw[2] == 'B')
- {
- nCharRet = 'b';
- *pcchwUsed = 3;
- }
- else if (cchw >= 1)
- {
- nCharRet = prgchw[0];
- *pcchwUsed = 1;
- }
- else
- {
- nCharRet = 0;
- *pcchwUsed = 0;
- }
- return nCharRet;
-*/
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if the given position is at the boundary of a Unicode character; return false
- if it is between two parts of pair of surrogates.
-----------------------------------------------------------------------------------------------*/
-bool GrCharStream::AtUnicodeCharBoundary(ITextSource * pgts, int ichr)
-{
- int cchr = pgts->getLength();
- if (ichr <= 0 || ichr >= cchr)
- return true;
-
- UtfType utf = pgts->utfEncodingForm();
-
- // Note that we never need more than a handful of characters.
- int ichrMinGet = max(0, ichr - 1);
- int ichrLimGet = ichr + 1;
- utf16 rgchwText16[3];
- utf8 rgchsText8[3];
- bool fRet;
- switch (utf)
- {
- case kutf8:
- pgts->fetch(ichrMinGet, ichrLimGet - ichrMinGet, rgchsText8);
- fRet = AtUnicodeCharBoundary(rgchsText8, ichrLimGet - ichrMinGet,
- ichr - ichrMinGet, utf);
- break;
- case kutf16:
- pgts->fetch(ichrMinGet, ichrLimGet - ichrMinGet, rgchwText16);
- fRet = AtUnicodeCharBoundary(rgchwText16, ichrLimGet - ichrMinGet,
- ichr - ichrMinGet, utf);
- break;
- default:
- Assert(false);
- case kutf32:
- fRet = true;
- break;
- }
-
- return fRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if the given position is at the boundary of a Unicode character; return false
- if it is between two parts of pair of surrogates.
-----------------------------------------------------------------------------------------------*/
-bool GrCharStream::AtUnicodeCharBoundary(utf16 * prgchw, int cchw, int ichr, UtfType utf)
-{
- Assert(ichr >= 0);
- Assert(ichr <= cchw);
-
- if (ichr == 0)
- return true;
- if (ichr >= cchw)
- return true;
-
- switch (utf)
- {
- case kutf16:
- {
- unsigned int nUtf32;
- bool fMiddleOfPair = FromSurrogatePair(prgchw[ichr - 1], prgchw[ichr], &nUtf32);
- return !fMiddleOfPair;
- }
- case kutf8:
- {
- // 16-bit buffer being treated like UTF-8.
- utf8 rgchs[2];
- rgchs[1] = (utf8)prgchw[ichr];
- return AtUnicodeCharBoundary(rgchs, 2, 1, kutf8);
- }
- case kutf32:
- default:
- return true;
- }
-
-/*
- // temp stuff for debugging:
- if (ichr > 0 && cchw >= 1 && prgchw[ichr-1] == '^' && prgchw[ichr] == 'a')
- {
- return false;
- }
- if (ichr > 0 && cchw >= 2 && prgchw[ichr-1] == '#' && prgchw[ichr] == '#' &&
- prgchw[ichr+1] == 'B')
- {
- return false;
- }
- if (ichr > 1 && cchw >= 1 && prgchw[ichr-2] == '#' && prgchw[ichr-1] == '#' &&
- prgchw[ichr] == 'B')
- {
- return false;
- }
-
- return true;
-*/
-}
-
-bool GrCharStream::AtUnicodeCharBoundary(utf8 * prgchs, int cchs, int ichs, UtfType utf)
-{
- Assert(ichs >= 0);
- Assert(ichs <= cchs);
-
- Assert(utf == kutf8);
-
- if (ichs == 0)
- return true;
- if (ichs >= cchs)
- return true;
-
- if (cchs == 0)
- return true;
-
- // A bit pattern of 10xxxxxx indicates a continuation of a sequence
- // (11xxxxxx means the first byte of a sequence, 0xxxxxxx means a single character).
-
- utf8 chsTest = prgchs[ichs] & 0xC0;
- return (chsTest != 0x80);
-}
-
-/*----------------------------------------------------------------------------------------------
- Convert the given pair of characters into a single 32-bit Unicode character. Return
- true if they are a legitimate surrogate pair. If not, just return the first of the
- two 16-bit characters.
-----------------------------------------------------------------------------------------------*/
-bool GrCharStream::FromSurrogatePair(utf16 chwIn1, utf16 chwIn2, unsigned int * pchlOut)
-{
- if ((chwIn1 < kzUtf16HighFirst) || (chwIn1 > kzUtf16HighLast)
- || (chwIn2 < kzUtf16LowFirst) || (chwIn2 > kzUtf16LowLast))
- {
- // Not a surrogate
- *pchlOut = (unsigned int)chwIn1;
- return false;
- }
- else
- {
- *pchlOut = ((chwIn1 - kzUtf16HighFirst) << kzUtf16Shift) + chwIn2 + kzUtf16Inc;
- return true;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Decode 1-6 bytes in the character string from UTF-8 format to Unicode (UCS-4).
- As a side-effect, cbOut is set to the number of UTF-8 bytes consumed.
-
- @param rgchUtf8 Pointer to a a character array containing UTF-8 data.
- @param cchUtf8 Number of characters in the array.
- @param cbOut Reference to an integer for holding the number of input (8-bit) characters
- consumed to produce the single output Unicode character.
-
- @return A single Unicode (UCS-4) character. If an error occurs, return -1.
-----------------------------------------------------------------------------------------------*/
-long GrCharStream::DecodeUtf8(const utf8 * rgchUtf8, int cchUtf8, int * pcbOut)
-{
- // check for valid input
- AssertArray(rgchUtf8, cchUtf8);
- if ((cchUtf8 == 0) || (rgchUtf8[0] == '\0'))
- {
- *pcbOut = (cchUtf8) ? 1 : 0;
- return 0;
- }
- //
- // decode the first byte of the UTF-8 sequence
- //
- long lnUnicode;
- int cbExtra;
- int chsUtf8 = *rgchUtf8++ & 0xFF;
- if (chsUtf8 >= kzUtf8Flag6) // 0xFC
- {
- lnUnicode = chsUtf8 & kzUtf8Mask6;
- cbExtra = 5;
- }
- else if (chsUtf8 >= kzUtf8Flag5) // 0xF8
- {
- lnUnicode = chsUtf8 & kzUtf8Mask5;
- cbExtra = 4;
- }
- else if (chsUtf8 >= kzUtf8Flag4) // 0xF0
- {
- lnUnicode = chsUtf8 & kzUtf8Mask4;
- cbExtra = 3;
- }
- else if (chsUtf8 >= kzUtf8Flag3) // 0xE0
- {
- lnUnicode = chsUtf8 & kzUtf8Mask3;
- cbExtra = 2;
- }
- else if (chsUtf8 >= kzUtf8Flag2) // 0xC0
- {
- lnUnicode = chsUtf8 & kzUtf8Mask2;
- cbExtra = 1;
- }
- else // 0x00
- {
- lnUnicode = chsUtf8;
- cbExtra = 0;
- }
- if (cbExtra >= cchUtf8)
- {
- return -1;
- }
-
- switch (cbExtra)
- {
- case 5:
- lnUnicode <<= kzUtf8ByteShift;
- chsUtf8 = *rgchUtf8++ & 0xFF;
- if ((chsUtf8 & ~kzByteMask) != 0x80)
- return -1;
- lnUnicode += chsUtf8 & kzByteMask;
- // fall through
- case 4:
- lnUnicode <<= kzUtf8ByteShift;
- chsUtf8 = *rgchUtf8++ & 0xFF;
- if ((chsUtf8 & ~kzByteMask) != 0x80)
- return -1;
- lnUnicode += chsUtf8 & kzByteMask;
- // fall through
- case 3:
- lnUnicode <<= kzUtf8ByteShift;
- chsUtf8 = *rgchUtf8++ & 0xFF;
- if ((chsUtf8 & ~kzByteMask) != 0x80)
- return -1;
- lnUnicode += chsUtf8 & kzByteMask;
- // fall through
- case 2:
- lnUnicode <<= kzUtf8ByteShift;
- chsUtf8 = *rgchUtf8++ & 0xFF;
- if ((chsUtf8 & ~kzByteMask) != 0x80)
- return -1;
- lnUnicode += chsUtf8 & kzByteMask;
- // fall through
- case 1:
- lnUnicode <<= kzUtf8ByteShift;
- chsUtf8 = *rgchUtf8++ & 0xFF;
- if ((chsUtf8 & ~kzByteMask) != 0x80)
- return -1;
- lnUnicode += chsUtf8 & kzByteMask;
- break;
- case 0:
- // already handled
- break;
- default:
- Assert(false);
- }
- if ((unsigned long)lnUnicode > kzUnicodeMax)
- {
- return -1;
- }
- *pcbOut = cbExtra + 1;
- return lnUnicode;
-}
-
-/*----------------------------------------------------------------------------------------------
- Get the current feature values and character properties from the stream.
-----------------------------------------------------------------------------------------------*/
-void GrCharStream::CurrentFeatures(GrTableManager * ptman, GrFeatureValues * pfval)
-{
- if (m_ichrRunOffset == kPosInfinity)
- {
- // Not yet set up.
- if (AtEnd())
- {
- // Empty stream; no valid values.
- Assert(false);
- return;
- }
-
- // Get the settings from the first character.
- int ichrSegOffset;
- int ichrPosSave = m_ichrPos;
- int ichrRunOffsetSave = m_ichrRunOffset;
- int ichlRunOffsetSave = m_ichlRunOffset;
- int cMapSize = m_vislotNextChunkMap.size();
- int cchrConsumed;
- NextGet(ptman, pfval, &ichrSegOffset, &cchrConsumed);
- // Put the character back.
- m_ichrPos = ichrPosSave;
- m_ichrRunOffset = ichrRunOffsetSave;
- m_ichlRunOffset = ichlRunOffsetSave;
- while (signed(m_vislotNextChunkMap.size()) > cMapSize)
- m_vislotNextChunkMap.pop_back();
- }
- else
- {
- *pfval = m_fvalRunFeats;
- //*ppchrp = &m_chrpRun;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the feature settings from the text properties.
-
- Eventually, handle style index here?
-----------------------------------------------------------------------------------------------*/
-void GrCharStream::SetUpFeatureValues(GrTableManager * ptman, int ichr)
-{
- // Set all the features to their default values.
- for (int i = 0; i < kMaxFeatures; ++i)
- {
- m_fvalRunFeats.m_rgnFValues[i] = ptman->DefaultForFeatureAt(i);
- }
- m_fvalRunFeats.m_nStyleIndex = 0;
-
- // Add in the defaults for the language of the text.
- std::vector<featid> vnFeats;
- std::vector<int> vnValues;
- isocode lgcode = m_pgts->getLanguage(ichr);
- ptman->DefaultsForLanguage(lgcode, vnFeats, vnValues);
- size_t ifeatLp;
- int ifeat;
- for (ifeatLp = 0; ifeatLp < vnFeats.size(); ifeatLp++)
- {
- ptman->FeatureWithID(vnFeats[ifeatLp], &ifeat);
- m_fvalRunFeats.m_rgnFValues[ifeat] = vnValues[ifeatLp];
- }
-
- // Add in the explicit feature settings.
- FeatureSetting rgfset[kMaxFeatures];
- int cfeat = m_pgts->getFontFeatures(ichr, rgfset);
-
- for (ifeatLp = 0; ifeatLp < (size_t)cfeat; ifeatLp++)
- {
- ptman->FeatureWithID(rgfset[ifeatLp].id, &ifeat);
- if (ifeat >= 0)
- m_fvalRunFeats.m_rgnFValues[ifeat] = rgfset[ifeatLp].value;
- }
-}
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/GrCharStream.h b/Build/source/libs/graphite-engine/src/segment/GrCharStream.h
deleted file mode 100644
index 892435d376e..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrCharStream.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*--------------------------------------------------------------------*//*:Ignore this sentence.
-Copyright (C) 1999 - 2008 SIL International. All rights reserved.
-
-Distributable under the terms of either the Common Public License or the
-GNU Lesser General Public License, as specified in the LICENSING.txt file.
-
-File: GrCharStream.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
-
-
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef GR_CHARSTREAM_INCLUDED
-#define GR_CHARSTREAM_INCLUDED
-
-//:End Ignore
-
-namespace gr
-{
-
-/*----------------------------------------------------------------------------------------------
- Makes a stream out of a text string that is serving as input to the process.
-
- Hungarian: chstrm
-----------------------------------------------------------------------------------------------*/
-class GrCharStream
-{
-public:
- // Constructor and destructor:
- GrCharStream(ITextSource * pgts, int ichrMin, int ichrLim,
- bool fStartLine, bool fEndLine);
-
- ~GrCharStream()
- {
- if (m_cchlRunMax >= 0)
- delete[] m_prgchlRunText;
- }
-
- // Getters:
- ITextSource * TextSrc() { return m_pgts; }
- int Min() { return m_ichrMin; }
- int Pos() { return m_ichrPos; }
- int Lim() { return m_ichrLim; }
- bool StartLine() { return m_fStartLine; }
- bool EndLine() { return m_fEndLine; }
-
- // offset from the beginning of the segment
- int SegOffset() { return m_ichrPos - m_ichrMin; }
- int SegOffset(int ichr) { return ichr - m_ichrMin; }
-
- bool AtEnd()
- {
- return (m_ichrPos >= m_ichrLim);
- }
-
- // The input string is empty.
- bool IsEmpty()
- {
- return (m_ichrLim - m_ichrMin == 0);
- }
-
- // When we are restarting in order to create a segment other than the first,
- // back up the position in the stream slightly in order to reprocess a few characters
- // before the line-break.
- void Backup(int cchrToReprocess)
- {
- Assert(m_ichrPos >= cchrToReprocess);
- m_ichrPos -= cchrToReprocess;
- m_ichrRunOffset = kPosInfinity;
- m_cchrBackedUp = cchrToReprocess;
- }
-
- // When we found a hard-break in the input stream, we need to put it back, and since
- // we're done, we set the end of the stream to that position.
- void HitHardBreak()
- {
- m_ichrPos -= 1;
- m_ichrRunOffset -= 1;
- m_ichrLim = m_ichrPos;
- }
-
- void Restart();
-
- int NextGet(GrTableManager *, GrFeatureValues * pfval, int * ichrSegOffset, int * pcchr);
-
- void CurrentFeatures(GrTableManager * ptman, GrFeatureValues * pfval);
-
- // For transduction logging:
- int GetLogData(GrTableManager * ptman, int * rgnChars, bool * rgfNewRun,
- GrFeatureValues * rgfval, int cchwBackup,
- int * pcchwMaxRaw);
- void GetLogDataRaw(GrTableManager * ptman, int cchw, int cchwBackup,
- int cchwMax16bit, int * prgnChars,
- utf16 * prgchw2, utf16 * prgchw3, utf16 * prgchw4, utf16 * prgchw5, utf16 * prgchw6,
- int * prgichwRaw);
-
-protected:
- void SetUpFeatureValues(GrTableManager * ptman, int ichr);
-public:
- static utf32 Utf8ToUtf32(utf8 * prgchs8bit, int cchs, int * pcchsUsed);
- static utf32 Utf16ToUtf32(utf16 * prgchw16bit, int cchw, int * pcchwUsed);
- bool AtUnicodeCharBoundary(int cchr)
- {
- return AtUnicodeCharBoundary(m_pgts, cchr);
- }
- static bool AtUnicodeCharBoundary(ITextSource * pgts, int ichr);
- static bool AtUnicodeCharBoundary(utf8 * prgchs, int cchs, int ichs, UtfType utf);
- static bool AtUnicodeCharBoundary(utf16 * prgchw, int cchw, int ichr, UtfType utf);
- static bool FromSurrogatePair(utf16 chwIn1, utf16 chwIn2, unsigned int * pch32Out);
- static long DecodeUtf8(const utf8 * rgchUtf8, int cchUtf8, int * pcbOut);
-
-protected:
- // Instance variables:
- // Hungarian note: chr = raw characters, chl = long characters (UTF-32)
- // chs = short characters (UTF-8), chw = wide characters (UTF-16)
- ITextSource * m_pgts; // string to render
- UtfType m_utf; // what encoding form the text-source uses
- int m_ichrMin; // official start of segment relative to beginning of string
- int m_ichrLim; // end of stream (potential end of seg) relative to beginning of string
- int m_ichrPos; // stream position (0 = start of string)
- bool m_fStartLine; // true if a line-break character should be prepended
- bool m_fEndLine; // true if a line-break character should be appended
- int m_cchrBackedUp; // number of characters backed up before beginning of segment
-
- // We read a run's worth of data at a time and cache it in the following variables:
- int m_cchlRunMax; // size of buffer allocated
- int * m_prgchlRunText; // buffer containing current run
- int m_ichrRunMin; // start of run relative to beginning of string
- int m_ichrRunLim; // end of run relative to beginning of string
- int m_ichlRunOffset; // index into m_prgchlRunText; kPosInfinity if nothing set up
- int m_ichrRunOffset; // corresponding index into text source
- GrFeatureValues m_fvalRunFeats;
-
- std::vector<int> m_vislotNextChunkMap; // maps from 16-bit chars to 32-bit chars & glyphs
-
- enum
- {
- kzUtf8Mask1 = 0x7F,
- kzUtf8Mask2 = 0x1F,
- kzUtf8Mask3 = 0x0F,
- kzUtf8Mask4 = 0x07,
- kzUtf8Mask5 = 0x03,
- kzUtf8Mask6 = 0x01
- };
-
- enum
- {
- kzUtf8Flag1 = 0x00,
- kzUtf8Flag2 = 0xC0,
- kzUtf8Flag3 = 0xE0,
- kzUtf8Flag4 = 0xF0,
- kzUtf8Flag5 = 0xF8,
- kzUtf8Flag6 = 0xFC
- };
-
- enum
- {
- kzByteMask = 0x3F,
- kzByteMark = 0x80,
- kzUtf8ByteShift = 6,
- kzUnicodeMax = 0x7FFFFFFF
- };
-
- enum
- {
- kzUtf16Shift = 10,
- kzUtf16Inc = 0x2400,
- kzUtf16HighFirst = 0xD800,
- kzUtf16HighLast = 0xDBFF,
- kzUtf16LowFirst = 0xDC00,
- kzUtf16LowLast = 0xDFFF
- };
-};
-
-} // namespace gr
-
-#endif // !GR_CHARSTREAM_INCLUDED
-
diff --git a/Build/source/libs/graphite-engine/src/segment/GrClassTable.cpp b/Build/source/libs/graphite-engine/src/segment/GrClassTable.cpp
deleted file mode 100644
index 43316fdc04a..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrClassTable.cpp
+++ /dev/null
@@ -1,382 +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: GrClassTable.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Implements the GrClassTable class and related classes.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Fill in by reading from the file stream.
-----------------------------------------------------------------------------------------------*/
-bool GrClassTable::ReadFromFont(GrIStream & grstrm, int fxdVersion)
-{
- long lClassMapStart;
- grstrm.GetPositionInFont(&lClassMapStart);
-
- // number of classes
- m_ccls = grstrm.ReadUShortFromFont();
- if (m_ccls >= kMaxReplcmtClasses)
- return false; // bad table
- if (fxdVersion < 0x00030000 && m_ccls > kMaxReplcmtClassesV1_2)
- return false; // bad table
-
- // number of linear classes
- m_cclsLinear = grstrm.ReadUShortFromFont();
- if (m_cclsLinear > m_ccls)
- return false; // bad table
-
- // class offsets
- m_prgichwOffsets = new data16[m_ccls + 1];
- gAssert(m_prgichwOffsets);
- if (!m_prgichwOffsets)
- return false; // bad table
-
- data16 * pchw = m_prgichwOffsets;
- int icls;
- for (icls = 0; icls <= m_ccls; icls++, pchw++)
- {
- *pchw = grstrm.ReadUShortFromFont();
- }
-
- // Offsets are relative to the start class map; make them relative to the class list
- // itself, and in terms of utf16s, not bytes.
- long lClassesPos;
- grstrm.GetPositionInFont(&lClassesPos);
- int cbDiff = lClassesPos - lClassMapStart;
- for (icls = 0; icls <= m_ccls; icls++)
- {
- m_prgichwOffsets[icls] = data16(int(m_prgichwOffsets[icls]) - cbDiff);
- gAssert((m_prgichwOffsets[icls] & 0x00000001) == 0);
- if ((m_prgichwOffsets[icls] & 0x00000001) != 0)
- return false; // bad table
- m_prgichwOffsets[icls] >>= 1; // divide by 2
- }
-
- // classes - slurp entire block (data remains in big-endian format)
- m_prgchwBIGGlyphList = new data16[m_prgichwOffsets[m_ccls]];
- gAssert(m_prgchwBIGGlyphList);
- if (!m_prgchwBIGGlyphList)
- return false; // bad table
- grstrm.ReadBlockFromFont(m_prgchwBIGGlyphList,
- m_prgichwOffsets[m_ccls] * isizeof(data16));
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Set up an empty class table.
-----------------------------------------------------------------------------------------------*/
-void GrClassTable::CreateEmpty()
-{
- // number of classes
- m_ccls = 0;
- // number of linear classes
- m_cclsLinear = 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Search for the glyph ID using a fast binary search, and return the matching index.
-----------------------------------------------------------------------------------------------*/
-int GrInputClass::FindIndex(gid16 gid)
-{
- int digixInit = InitialSearchRange();
- int igixStart = StartSearch();
-#ifdef _DEBUG
- int cgix = NumberOfGlyphs();
- int nPowerOf2 = 1;
- while (nPowerOf2 <= cgix)
- nPowerOf2 <<= 1;
- nPowerOf2 >>= 1;
- // Now nPowerOf2 is the max power of 2 <= cgix
- gAssert((1 << LoopCount()) == nPowerOf2); // LoopCount() == log2(nPowerOf2)
- gAssert(digixInit == nPowerOf2);
- gAssert(igixStart == cgix - digixInit);
-#endif // _DEBUG
-
- int digixCurr = digixInit;
-
- GrGlyphIndexPair * pgixCurr = m_pgixFirst + igixStart;
- while (digixCurr > 0)
- {
- int nTest;
- if (pgixCurr < m_pgixFirst)
- nTest = -1;
- else
- nTest = pgixCurr->GlyphID() - gid;
-
- if (nTest == 0)
- return pgixCurr->Index();
-
- digixCurr >>= 1; // divide by 2
- if (nTest < 0)
- pgixCurr += digixCurr;
- else // (nTest > 0)
- pgixCurr -= digixCurr;
- }
-
- return -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the selector index for the given glyph ID.
-----------------------------------------------------------------------------------------------*/
-int GrClassTable::FindIndex(int icls, gid16 chwGlyphID)
-{
- if (icls >= m_ccls)
- {
- gAssert(false); // bad compiler problem
- return 0;
- }
-
- if (icls < m_cclsLinear)
- {
- // The class is an output class--uses linear format--and is being used as an
- // input class. Shouldn't happen if the compiler is working right.
- gAssert(false); // comment out for test procedures
-
- // Do a slow linear search to find the glyph ID.
- int ichwMin = m_prgichwOffsets[icls];
- int ichwLim = m_prgichwOffsets[icls+1];
- int cchw = ichwLim - ichwMin;
-
- for (int ichw = 0; ichw < cchw; ichw++)
- {
- if (GlyphAt(ichwMin + ichw) == chwGlyphID)
- return ichw;
- }
- return -1;
- }
-
- // Slurp the class into an instance so we can see what's there.
- GrInputClass clsin;
- int ichwMin = m_prgichwOffsets[icls];
- int ichwLim = m_prgichwOffsets[icls+1];
- clsin.CopyFrom(GlyphListLoc(ichwMin), (ichwLim - ichwMin));
-
- // Do a fast binary search to find our glyph.
- int iRet = clsin.FindIndex(chwGlyphID);
- return iRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the glyph ID at the selector index.
-----------------------------------------------------------------------------------------------*/
-gid16 GrClassTable::GetGlyphID(int icls, int ichw)
-{
- if (ichw < 0)
- {
- gAssert(false);
- return 0;
- }
-
- if (icls >= m_cclsLinear)
- {
- // The class is an input class--sorted by glyph ID--and is being used as an
- // output class. Shouldn't happen if the compiler is working right.
- gAssert(false); // comment out for test procedures
-
- if (icls >= m_ccls) // bad compiler problem
- return 0;
-
- // Do a slow linear search to find the index and answer the matching glyph.
- // Slurp the class into an instance so we can see what's there.
- GrInputClass clsin;
- int ichwMin = m_prgichwOffsets[icls];
- int ichwLim = m_prgichwOffsets[icls+1];
- clsin.CopyFrom(GlyphListLoc(ichwMin), (ichwLim - ichwMin));
-
- int cgix = clsin.NumberOfGlyphs();
- for (int igix = 0; igix < cgix; igix++)
- {
- GrGlyphIndexPair * m_pgix = clsin.m_pgixFirst + igix;
- if (m_pgix->Index() == ichw)
- return m_pgix->GlyphID();
- }
- return 0;
- }
-
- int ichwMin = m_prgichwOffsets[icls];
- int ichwLim = m_prgichwOffsets[icls+1];
-
- if (ichw >= ichwLim - ichwMin)
- return 0;
- else
- return GlyphAt(ichwMin + ichw);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the number of glyphs in the class.
-----------------------------------------------------------------------------------------------*/
-int GrClassTable::NumberOfGlyphsInClass(int icls)
-{
- int ichwMin = m_prgichwOffsets[icls];
- int ichwLim = m_prgichwOffsets[icls+1];
-
- if (icls >= m_cclsLinear)
- {
- if (icls >= m_ccls) // bad compiler problem
- return 0;
-
- GrInputClass clsin;
- clsin.CopyFrom(GlyphListLoc(ichwMin), (ichwLim - ichwMin));
-
- int cgix = clsin.NumberOfGlyphs();
- return cgix;
- }
- else
- {
- gAssert(false); // this method should not be used for output classes.
- return ichwLim - ichwMin;
- }
-}
-
-//:>********************************************************************************************
-//:> For test procedures
-//:>********************************************************************************************
-
-//:Ignore
-
-#ifdef OLD_TEST_STUFF
-/*----------------------------------------------------------------------------------------------
- General test of class table.
-----------------------------------------------------------------------------------------------*/
-void GrClassTable::SetUpTestData()
-{
- m_ccls = 7; // number of classes
- m_cclsLinear = 4; // number of classes in linear format
-
- m_prgchwBIGGlyphList = new gid16[100];
-
- m_prgichwOffsets = new data16[7+1];
-
- gid16 * pchw = m_prgchwBIGGlyphList;
-
- // Output class 0: uppercase consonants B - H
- m_prgichwOffsets[0] = 0;
- *pchw++ = msbf(gid16(66)); *pchw++ = msbf(utf16(67)); *pchw++ = msbf(utf16(68));
- *pchw++ = msbf(gid16(70)); *pchw++ = msbf(utf16(71)); *pchw++ = msbf(utf16(72));
-
- // Output class 1: grave vowels
- m_prgichwOffsets[1] = 6;
- *pchw++ = msbf(gid16(192)); // A
- *pchw++ = msbf(gid16(224)); // a
- *pchw++ = msbf(gid16(200)); // E
- *pchw++ = msbf(gid16(232)); // e
- *pchw++ = msbf(gid16(204)); // I
- *pchw++ = msbf(gid16(236)); // i
- *pchw++ = msbf(gid16(210)); // O
- *pchw++ = msbf(gid16(243)); // o
- *pchw++ = msbf(gid16(217)); // U
- *pchw++ = msbf(gid16(249)); // u
-
- // Output class 2: circumflex vowels
- m_prgichwOffsets[2] = 6 + 10;
- *pchw++ = msbf(gid16(194)); // A
- *pchw++ = msbf(gid16(226)); // a
- *pchw++ = msbf(gid16(202)); // E
- *pchw++ = msbf(gid16(234)); // e
- *pchw++ = msbf(gid16(206)); // I
- *pchw++ = msbf(gid16(238)); // i
- *pchw++ = msbf(gid16(212)); // O
- *pchw++ = msbf(gid16(244)); // o
- *pchw++ = msbf(gid16(219)); // U
- *pchw++ = msbf(gid16(251)); // u
-
- // Output class 3: diaeresis vowels, uppercase
- m_prgichwOffsets[3] = 16 + 10;
- *pchw++ = msbf(gid16(196)); // A
- *pchw++ = msbf(gid16(196)); // A
- *pchw++ = msbf(gid16(203)); // E
- *pchw++ = msbf(gid16(203)); // E
- *pchw++ = msbf(gid16(207)); // I
- *pchw++ = msbf(gid16(207)); // I
- *pchw++ = msbf(gid16(214)); // O
- *pchw++ = msbf(gid16(214)); // O
- *pchw++ = msbf(gid16(220)); // U
- *pchw++ = msbf(gid16(220)); // U
-
- // Input class 4: lowercase consonants b - h
- m_prgichwOffsets[4] = 26 + 10; // = 36
- *pchw++ = msbf(gid16(6));
- *pchw++ = msbf(gid16(4)); *pchw++ = msbf(gid16(2)); *pchw++ = msbf(gid16(6-4));
- *pchw++ = msbf(gid16(98)); *pchw++ = msbf(gid16(0));
- *pchw++ = msbf(gid16(99)); *pchw++ = msbf(gid16(1));
- *pchw++ = msbf(gid16(100)); *pchw++ = msbf(gid16(2));
- *pchw++ = msbf(gid16(102)); *pchw++ = msbf(gid16(3));
- *pchw++ = msbf(gid16(103)); *pchw++ = msbf(gid16(4));
- *pchw++ = msbf(gid16(104)); *pchw++ = msbf(gid16(5));
-
- // Input class 5: vowels
- m_prgichwOffsets[5] = 36 + 4 + 6*2; // = 52
- *pchw++ = msbf(gid16(10));
- *pchw++ = msbf(gid16(8)); *pchw++ = msbf(utf16(3)); *pchw++ = msbf(utf16(10-8));
- *pchw++ = msbf(gid16(65)); *pchw++ = msbf(gid16(0)); // A
- *pchw++ = msbf(gid16(69)); *pchw++ = msbf(gid16(2)); // E
- *pchw++ = msbf(gid16(73)); *pchw++ = msbf(gid16(4)); // I
- *pchw++ = msbf(gid16(79)); *pchw++ = msbf(gid16(6)); // O
- *pchw++ = msbf(gid16(85)); *pchw++ = msbf(gid16(8)); // U
- *pchw++ = msbf(gid16(97)); *pchw++ = msbf(gid16(1)); // a
- *pchw++ = msbf(gid16(101)); *pchw++ = msbf(gid16(3)); // e
- *pchw++ = msbf(gid16(105)); *pchw++ = msbf(gid16(5)); // i
- *pchw++ = msbf(gid16(111)); *pchw++ = msbf(gid16(7)); // o
- *pchw++ = msbf(gid16(117)); *pchw++ = msbf(gid16(9)); // u
-
- // Input class 6: acute vowels
- m_prgichwOffsets[6] = 52 + 4 + 10*2; // = 76
- *pchw++ = msbf(gid16(10));
- *pchw++ = msbf(gid16(8)); *pchw++ = msbf(gid16(3)); *pchw++ = msbf(gid16(10-8));
- *pchw++ = msbf(gid16(193)); *pchw++ = msbf(gid16(0)); // A
- *pchw++ = msbf(gid16(201)); *pchw++ = msbf(gid16(2)); // E
- *pchw++ = msbf(gid16(205)); *pchw++ = msbf(gid16(4)); // I
- *pchw++ = msbf(gid16(211)); *pchw++ = msbf(gid16(6)); // O
- *pchw++ = msbf(gid16(218)); *pchw++ = msbf(gid16(8)); // U
- *pchw++ = msbf(gid16(225)); *pchw++ = msbf(gid16(1)); // a
- *pchw++ = msbf(gid16(233)); *pchw++ = msbf(gid16(3)); // e
- *pchw++ = msbf(gid16(237)); *pchw++ = msbf(gid16(5)); // i
- *pchw++ = msbf(gid16(243)); *pchw++ = msbf(gid16(7)); // o
- *pchw++ = msbf(gid16(250)); *pchw++ = msbf(gid16(9)); // u
-
- m_prgichwOffsets[7] = 76 + 4 + 10*2; // = 100
-};
-
-#endif // OLD_TEST_STUFF
-
-} // namespace gr
-
-//:End Ignore
-
diff --git a/Build/source/libs/graphite-engine/src/segment/GrClassTable.h b/Build/source/libs/graphite-engine/src/segment/GrClassTable.h
deleted file mode 100644
index 67d6940862c..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrClassTable.h
+++ /dev/null
@@ -1,188 +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: GrClassTable.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- The GrClassTable and related classes that store the classes that are used in substitutions.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef GR_CTABLE_INCLUDED
-#define GR_CTABLE_INCLUDED
-
-//:End Ignore
-
-namespace gr
-{
-
-/*----------------------------------------------------------------------------------------------
- A glyph ID / index pair, a member of the GrInputClass where the items are sorted
- by glyph ID.
-
- Hungarian: gix
-----------------------------------------------------------------------------------------------*/
-class GrGlyphIndexPair
-{
- friend class GrInputClass;
- friend class GrClassTable;
-
- gid16 GlyphID() { return lsbf(m_gidBIG); }
- data16 Index() { return lsbf(m_nBIGIndex); }
-
- gid16 m_gidBIG;
- data16 m_nBIGIndex;
-};
-
-/*----------------------------------------------------------------------------------------------
- A class consisting of a mapping from glyph ID to index, used for classes that
- function as input classes (eg, occurrng in the left-hand side of a rule).
-
- Hungarian: clsin
-----------------------------------------------------------------------------------------------*/
-class GrInputClass
-{
- friend class GrClassTable;
-
-protected:
- /*------------------------------------------------------------------------------------------
- Copy the raw memory into the instance.
- ------------------------------------------------------------------------------------------*/
- void CopyFrom(data16 * pchwStart, int cchw)
- {
- m_cgixBIG = pchwStart[0];
- m_digixBIGInit = pchwStart[1];
- m_cBIGLoop = pchwStart[2];
- m_igixBIGStart = pchwStart[3];
-
- int cgix = NumberOfGlyphs();
- m_pgixFirst = m_prggixBuffer;
- if (cgix > 64)
- {
- m_vgix.resize(cgix);
- m_pgixFirst = &m_vgix[0];
- }
- gAssert((4 + (cgix * 2)) == cchw);
- #ifdef _DEBUG
- memset(m_pgixFirst, 0, cgix * isizeof(GrGlyphIndexPair));
- #endif
- Assert(sizeof(GrGlyphIndexPair) == sizeof(gid16) + sizeof(data16));
- GrGlyphIndexPair * pgixStart = reinterpret_cast<GrGlyphIndexPair*>(pchwStart + 4);
- std::copy(pgixStart, pgixStart + cgix, m_pgixFirst);
- }
-
- int NumberOfGlyphs() { return lsbf(m_cgixBIG); }
- int LoopCount() { return lsbf(m_cBIGLoop); }
- int InitialSearchRange() { return lsbf(m_digixBIGInit); }
- int StartSearch() { return lsbf(m_igixBIGStart); }
-
- int FindIndex(gid16 gid);
-
-protected:
- // Instance variables:
- data16 m_cgixBIG; // number of glyphs in the class
-
- // constants for fast binary search
- data16 m_digixBIGInit; // (max power of 2 <= m_cgix);
- // size of initial range to consider
- data16 m_cBIGLoop; // log2(max power of 2 <= m_cgix);
- // indicates how many iterations are necessary
- data16 m_igixBIGStart; // m_cgix - m_digixInit;
- // where to start search
-
- GrGlyphIndexPair m_prggixBuffer[64];
- std::vector<GrGlyphIndexPair> m_vgix;
- GrGlyphIndexPair * m_pgixFirst;
-};
-
-
-/*----------------------------------------------------------------------------------------------
- Contains all the classes used for substitution rules.
-
- Hungarian: ctbl
-----------------------------------------------------------------------------------------------*/
-
-class GrClassTable
-{
- friend class FontMemoryUsage;
-
-public:
- // Constructor & destructor:
- GrClassTable()
- : m_prgichwOffsets(NULL),
- m_prgchwBIGGlyphList(NULL)
- {
- }
-
- ~GrClassTable()
- {
- delete[] m_prgichwOffsets;
- delete[] m_prgchwBIGGlyphList;
- }
-
- int NumberOfClasses() { return m_ccls; }
- int NumberOfInputClasses() { return m_ccls - m_cclsLinear; }
- int NumberOfOutputClasses() { return m_cclsLinear; }
-
- bool ReadFromFont(GrIStream & grstrm, int fxdVersion);
- void CreateEmpty();
-
- int FindIndex(int icls, gid16 chwGlyphID);
- gid16 GetGlyphID(int icls, int ichw);
- int NumberOfGlyphsInClass(int icls);
-
- gid16 GlyphAt(int ichw)
- {
- return lsbf(m_prgchwBIGGlyphList[ichw]);
- }
- data16 * GlyphListLoc(int ichw)
- {
- return m_prgchwBIGGlyphList + ichw;
- }
-
-protected:
- // Instance variables:
- int m_ccls; // number of classes
- int m_cclsLinear; // number of classes in linear format
-
- data16 * m_prgichwOffsets;
-
- // Two formats are included in the following array: the first section consists of
- // flat ordered lists of glyphs, used for the "output" classes that use linear format.
- // This provides an index-to-glyph mapping.
- // The second section contains data in the format of GrInputClasses, used for "input"
- // classes that need a binary-search format. This provides a glyph-to-index mapping.
- // We don't create instances of GrInputClasses, because that would make reading
- // from the ECF file slow. Instead we just set up a single instance at the time
- // we're interested in it.
- // NOTE that all this data has been slurped directly from the ECF file and therefore
- // uses BIG-ENDIAN format.
- gid16 * m_prgchwBIGGlyphList;
-
-//:Ignore
-#ifdef OLD_TEST_STUFF
-public:
- // For test procedures:
- void SetUpTestData();
- void SetUpRuleActionTest();
- void SetUpRuleAction2Test();
- void SetUpAssocTest();
- void SetUpAssoc2Test();
- void SetUpDefaultAssocTest();
- void SetUpFeatureTest();
- void SetUpLigatureTest();
- void SetUpLigature2Test();
-#endif // OLD_TEST_STUFF
-//:End Ignore
-};
-
-} // namespace gr
-
-#endif // !GR_CTABLE_INCLUDED
-
diff --git a/Build/source/libs/graphite-engine/src/segment/GrEngine.cpp b/Build/source/libs/graphite-engine/src/segment/GrEngine.cpp
deleted file mode 100644
index 0fda68df880..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrEngine.cpp
+++ /dev/null
@@ -1,2030 +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: GrEngine.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description: Contains the implementation of the GrEngine class.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-#include <functional>
-#include <cstring>
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-// any other headers (not precompiled)
-
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-
-//:>********************************************************************************************
-//:> General functions
-//:>********************************************************************************************
-
-bool compareCmap(const byte *lhs, const byte *rhs)
-{
- using namespace gr;
-
- typedef const struct index {data16 version; data16 numberSubtables;} *const IndexPtr;
- typedef const struct enc {data16 platID; data16 platSpecID; data32 offset;} *const EncPtr;
-
- // Calculate the size of the cmap.
-
- IndexPtr rhsIndex = IndexPtr(rhs);
- size_t numSubTbl = lsbf(rhsIndex->numberSubtables);
- size_t cbCmapSz = sizeof(index) + sizeof(enc) * numSubTbl;
- EncPtr encTbl = EncPtr(rhs + sizeof(index));
-
- for (size_t iSubTbl = 0; iSubTbl < numSubTbl; iSubTbl++)
- //for (int iSubTbl = numSubTbl - 1; iSubTbl >= 0; --iSubTbl)
- {
- const data16 *const mapTbl = reinterpret_cast<const data16 *>(rhs + lsbf((int)encTbl[iSubTbl].offset));
- int format = lsbf(*mapTbl);
- switch (format)
- {
- // 16-bit lengths
- case 0:
- case 2:
- case 4:
- case 6:
- cbCmapSz += lsbf((data16)unsigned(mapTbl[1]));
- break;
- // 32-bit lengths
- case 8:
- case 10:
- case 12:
- cbCmapSz += lsbf((int)unsigned(reinterpret_cast<const data32 *>(mapTbl)[1]));
- break;
- default:
- Assert(false);
- }
- }
-
- // Do the comparison.
- return (memcmp(lhs, rhs, cbCmapSz) ? false : true);
-}
-
-
-//:>********************************************************************************************
-//:> GrEngine class.
-//:>********************************************************************************************
-
-GrEngine::GrEngine()
-{
- /////////////_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF); ////////////////
-
-
- m_cref = 1;
- BasicInit();
-}
-
-void GrEngine::BasicInit()
-{
- m_pfface = NULL;
-
- m_ptman = NULL;
- m_pctbl = NULL;
- m_pgtbl = NULL;
- m_prgpsd = NULL;
- m_cpsd = 0;
- m_cfeat = 0;
- m_mFontEmUnits = -1;
- m_dysOffset = 0;
-
- ////m_tbufCmap.reset();
- m_pCmap_3_1 = NULL;
- m_pCmap_3_10 = NULL;
- ////m_tbufNameTbl.reset();
- // new interface stuff:
- m_pCmapTbl = NULL;
- m_pNameTbl = NULL;
- m_fCmapTblCopy = false;
- m_fNameTblCopy = false;
-
- m_fLogXductn = false;
-
- m_resFontValid = kresInvalidArg; // not yet initialized
- m_ferr = kferrUninitialized;
- m_fxdBadVersion = 0;
-
- m_fSmartReg = false;
- m_fSmartBold = false;
- m_fSmartItalic = false;
- m_fSmartBI = false;
- m_fFakeItalicCache = false;
- m_fFakeBICache = false;
- m_strCtrlFileReg.erase();
- m_strCtrlFileBold.erase();
- m_strCtrlFileItalic.erase();
- m_strCtrlFileBI.erase();
- m_fFakeItalic = false;
- m_stuCtrlFile.erase();
- m_stuInitError.erase();
- m_stuErrCtrlFile.erase();
- m_stuFaceName.erase();
- m_stuBaseFaceName.erase();
- m_fUseSepBase = false;
- m_stuFeatures.erase();
-
- m_nFontCheckSum = 0;
-
- m_fInErrorState = false;
-
- m_rglcidFeatLabelLangs = NULL; // initialize lazily, when needed
- m_clcidFeatLabelLangs = 0;
-}
-
-GrEngine::~GrEngine()
-{
- DestroyEverything();
- #ifdef _MSC_VER
- if (!_CrtCheckMemory())
- {
- OutputDebugString(L"bad memory");
- }
- #endif
-}
-
-/*----------------------------------------------------------------------------------------------
- Clean everything out (destructor or reinitializing with a different face name).
-----------------------------------------------------------------------------------------------*/
-void GrEngine::DestroyEverything()
-{
- DestroyContents();
- #ifdef _MSC_VER
- if (!_CrtCheckMemory())
- {
- OutputDebugString(L"bad memory");
- }
- #endif
-
- m_strCtrlFileReg.erase();
- m_strCtrlFileBold.erase();
- m_strCtrlFileItalic.erase();
- m_strCtrlFileBI.erase();
- m_fSmartReg = false;
- m_fSmartBold = false;
- m_fSmartItalic = false;
- m_fSmartBI = false;
- m_fFakeItalicCache = false;
- m_fFakeBICache = false;
- m_stuBaseFaceName.erase();
-
- //m_stuFaceName.erase();
- //m_stuFaceName = L"this is not a usable or valid string";
- m_fUseSepBase = false;
- m_stuFeatures.erase();
-}
-
-void GrEngine::DestroyContents(bool fDestroyCmap)
-{
- if (fDestroyCmap)
- {
- ////m_tbufCmap.reset();
- m_pCmap_3_1 = NULL;
- m_pCmap_3_10 = NULL;
-
- if (m_fCmapTblCopy)
- delete[] m_pCmapTbl;
- if (m_fNameTblCopy)
- delete[] m_pNameTbl;
- m_pCmapTbl = NULL;
- m_pNameTbl = NULL;
- m_fCmapTblCopy = false;
- m_fNameTblCopy = false;
- }
-
- delete m_ptman;
- delete m_pctbl;
- delete m_pgtbl;
- delete[] m_prgpsd;
- m_ptman = NULL;
- m_pctbl = NULL;
- m_pgtbl = NULL;
- m_prgpsd = NULL;
-
- ////m_tbufNameTbl.reset();
-
- m_stuCtrlFile.erase();
- m_stuInitError.erase();
-
- m_resFontValid = kresInvalidArg;
- m_ferr = kferrUninitialized;
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the number of features.
-----------------------------------------------------------------------------------------------*/
-size_t GrEngine::NumberOfFeatures_ff()
-{
- return (size_t)m_cfeat;
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the feature ID for the ifeat-th feature.
-----------------------------------------------------------------------------------------------*/
-featid GrEngine::FeatureID_ff(size_t ifeat)
-{
- return (featid)m_rgfeat[ifeat].ID();
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the index of the feature with the given ID.
-----------------------------------------------------------------------------------------------*/
-size_t GrEngine::FeatureWithID_ff(featid fid)
-{
- int ifeatRet;
- /* GrFeature * pfeat = */
- FeatureWithID(fid, &ifeatRet);
- return (size_t)ifeatRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the label for the ifeat-th feature.
-----------------------------------------------------------------------------------------------*/
-bool GrEngine::GetFeatureLabel_ff(size_t ifeat, lgid nLanguage, utf16 * rgchwLabel)
-{
- std::wstring stu = m_rgfeat[ifeat].Label(this, nLanguage);
-
- int cch = stu.size();
- cch = min(cch, 127); // 1 char for zero-termination
- std::copy(stu.data(), stu.data() + cch, rgchwLabel);
- rgchwLabel[cch] = 0;
-
- return (cch > 0);
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the index of the default setting. Return -1 if it cannot be found.
-----------------------------------------------------------------------------------------------*/
-int GrEngine::GetFeatureDefault_ff(size_t ifeat)
-{
- GrFeature * pfeat = m_rgfeat + ifeat;
- int defaultValue = pfeat->DefaultValue();
- int cfset = pfeat->NumberOfSettings();
- int rgnSettings[100];
- pfeat->Settings(100, rgnSettings);
- Assert(cfset < 100); // TODO: improve this
- for (int ifset = 0; ifset < cfset; ifset++)
- {
- if (rgnSettings[ifset] == defaultValue)
- return ifset;
- }
- return -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the number of settings for the ifeat-th feature.
-----------------------------------------------------------------------------------------------*/
-size_t GrEngine::NumberOfSettings_ff(size_t ifeat)
-{
- return m_rgfeat[ifeat].NumberOfSettings();
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the value of the ifset-th setting for the ifeat-th feature.
-----------------------------------------------------------------------------------------------*/
-int GrEngine::GetFeatureSettingValue_ff(size_t ifeat, size_t ifset)
-{
- return m_rgfeat[ifeat].NthSetting(ifset);
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the UI label for the given feature setting.
-----------------------------------------------------------------------------------------------*/
-bool GrEngine::GetFeatureSettingLabel_ff(size_t ifeat, size_t ifset, lgid language,
- utf16 * rgchwLabel)
-{
- std::wstring stu = m_rgfeat[ifeat].NthSettingLabel(this, ifset, language);
-
- int cch = stu.size();
- cch = min(cch, 127); // 1 char for zero-termination
- // Note: the wchar_t label was originally assigned from utf16 data, so although wchar_t is
- // utf32 on some platforms the conversion back to utf16 should still give correct results.
- std::copy(stu.data(), stu.data() + cch, rgchwLabel);
- rgchwLabel[cch] = 0;
-
- return (cch > 0);
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the number of languages that are possible among the feature labels.
-----------------------------------------------------------------------------------------------*/
-size_t GrEngine::NumberOfFeatLangs_ff()
-{
- SetUpFeatLangList();
- return m_clcidFeatLabelLangs;
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the language LCID for the feature-label language with the given index.
-----------------------------------------------------------------------------------------------*/
-short GrEngine::GetFeatLabelLang_ff(size_t ilang)
-{
- SetUpFeatLangList();
- return m_rglcidFeatLabelLangs[ilang];
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the number of supported languages.
-----------------------------------------------------------------------------------------------*/
-size_t GrEngine::NumberOfLanguages_ff()
-{
- return (size_t)m_langtbl.NumberOfLanguages();
-}
-
-/*----------------------------------------------------------------------------------------------
- For FontFace: return the language code for the language with the given index.
-----------------------------------------------------------------------------------------------*/
-isocode GrEngine::GetLanguageCode_ff(size_t ilang)
-{
- return m_langtbl.LanguageCode(ilang);
-}
-
-/*----------------------------------------------------------------------------------------------
- Set up the list of all the languages that are present in the feature labels.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpFeatLangList()
-{
- if (m_rglcidFeatLabelLangs)
- return;
-
- int rgnNameIDs[kMaxFeatures];
- for (int ifeat = 0; ifeat < m_cfeat; ifeat++)
- rgnNameIDs[ifeat] = m_rgfeat[ifeat].NameId();
- short rglcid[128]; // 128 is the number expected by TtfUtil::GetLangsForNames
- m_clcidFeatLabelLangs = TtfUtil::GetLangsForNames(m_pNameTbl, 3, 1, rgnNameIDs, m_cfeat, rglcid);
- m_rglcidFeatLabelLangs = new short[m_clcidFeatLabelLangs];
- memcpy(m_rglcidFeatLabelLangs, rglcid, sizeof(short) * m_clcidFeatLabelLangs);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the maximum size needed for the block of data to pass between segments, that is,
- to reinitialize the engine based on the results of the previously generated segment.
- This value must match what is in GrTableManager::InitializeStreams() and
- InitializeForNextSeg(). 256 is an absolute maximum imposed by the interface.
-
- In Graphite, what this block of data will contain is information about cross-line
- contextualization and some directionality information.
-
- Assumes InitNew() has already been called to set the font name.
-----------------------------------------------------------------------------------------------*/
-GrResult GrEngine::get_SegDatMaxLength(int * pcb)
-{
- ChkGrOutPtr(pcb);
-
- if (m_resFontValid == kresInvalidArg)
- ReturnResult(kresUnexpected); // engine not initialized
-
- GrResult res = m_resFontValid;
- if (m_resFontValid == kresFail || m_resFontValid == kresUnexpected || m_resFontValid == kresFalse)
- res = kresOk; // invalid font
- if (ResultFailed(res))
- ReturnResult(res);
-
- Assert(m_ptman);
- if (!m_ptman)
- *pcb = 256;
- else
- *pcb = m_ptman->NumberOfPasses() + 4;
-
- ReturnResult(res);
-}
-
-/*----------------------------------------------------------------------------------------------
- @return The supported script direction(s). If more than one, the application is
- responsible for choosing the most appropriate.
-----------------------------------------------------------------------------------------------*/
-GrResult GrEngine::get_ScriptDirection(unsigned int * pgrfsdc, OLECHAR * prgchwErrMsg, int cchMaxErrMsg)
-{
- ChkGrOutPtr(pgrfsdc);
- ChkGrArrayArg(prgchwErrMsg, cchMaxErrMsg);
-
- if (m_resFontValid == kresInvalidArg)
- ReturnResult(kresUnexpected); // engine not initialized
-
- GrResult res = m_resFontValid;
-
- *pgrfsdc = m_grfsdc;
-
-// ClearFontError(prgchwErrMsg, cchMaxErrMsg);
-// try
-// {
-// if (m_resFontValid == kresFail || m_resFontValid == kresUnexpected || m_resFontValid == kresFalse)
-// {
-// RecordFontLoadError(prgchwErrMsg, cchMaxErrMsg);
-// res = kresOk;
-// }
-// *pgrfsdc = m_grfsdc;
-// }
-// catch (Throwable & thr)
-// {
-// res = (GrResult)thr.Error();
-// *pgrfsdc = kfsdcHorizLtr;
-// }
-// catch (...)
-// {
-// res = WARN(kresFail);
-// *pgrfsdc = kfsdcHorizLtr;
-// }
-
- ReturnResult(res);
-}
-
-/*----------------------------------------------------------------------------------------------
- Get an glyph attribute from the engine that will help the GrJustifier in its work.
-----------------------------------------------------------------------------------------------*/
-GrResult GrEngine::getGlyphAttribute(int iGlyph, int jgat, int nLevel, float * pValueRet)
-{
- return m_ptman->State()->GetGlyphAttrForJustification(iGlyph, jgat, nLevel, pValueRet);
-}
-
-GrResult GrEngine::getGlyphAttribute(int iGlyph, int jgat, int nLevel, int * pValueRet)
-{
- return m_ptman->State()->GetGlyphAttrForJustification(iGlyph, jgat, nLevel, pValueRet);
-}
-
-/*----------------------------------------------------------------------------------------------
- Set an glyph attribute in the engine as a result of the decisions made by the
- GrJustifier.
-----------------------------------------------------------------------------------------------*/
-GrResult GrEngine::setGlyphAttribute(int iGlyph, int jgat, int nLevel, float value)
-{
- return m_ptman->State()->SetGlyphAttrForJustification(iGlyph, jgat, nLevel, value);
-}
-
-GrResult GrEngine::setGlyphAttribute(int iGlyph, int jgat, int nLevel, int value)
-{
- return m_ptman->State()->SetGlyphAttrForJustification(iGlyph, jgat, nLevel, value);
-}
-
-//:>********************************************************************************************
-//:> Non-FieldWorks interface methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Make a complete segment that can be used to measure and do line-breaking.
-
- OBSOLETE - delete
-----------------------------------------------------------------------------------------------*/
-/*
-GrResult GrEngine::MakeMeasuredSegment(
- Font * pfont, ITextSource * pgts,
- int ichMin, int ichLim,
- bool fParaRtl,
- Segment ** ppsegRet, SegEnd * pest,
- std::ostream * pstrmLog,
- OLECHAR * prgchwErrMsg, int cchMaxErrMsg)
-{
- int dichContext, dichLimSeg;
- float dxWidth;
- return MakeSegment(ksegmodeMsfr,
- pfont, pgts, NULL, ichMin, ichLim, false, false,
- 100000, klbClipBreak, ktwshAll, // not used
- fParaRtl,
- ppsegRet, &dxWidth,
- 0, NULL, 0, NULL, NULL, &dichContext, // not used
- pstrmLog,
- prgchwErrMsg, cchMaxErrMsg,
- -1, false, false, klbClipBreak, // not used
- &dichLimSeg, pest,
- false, 100000, kestMoreLines); // not used
-}
-*/
-
-/*----------------------------------------------------------------------------------------------
- Make a segment from the given range, regardless of the kind of line-break that results.
-
- OBSOLETE - delete
-----------------------------------------------------------------------------------------------*/
-/*
-GrResult GrEngine::MakeSegmentFromRange(
- Font * pfont, ITextSource * pgts, IGrJustifier * pgj,
- int ichMin, int ichLim,
- bool fStartLine, bool fEndLine,
- TrWsHandling twsh, bool fParaRtl,
- Segment ** ppsegRet, float * pdxWidth, SegEnd * pest,
- int cbPrev, byte * pbPrevSegDat, int cbNextMax, byte * pbNextSegDat, int * pcbNextSegDat,
- int * pdichwContext,
- std::ostream * pstrmLog,
- OLECHAR * prgchwErrMsg, int cchwMaxErrMsg)
-{
- int dichLimSegBogus;
- return MakeSegment(ksegmodeMsfr, pfont, pgts, pgj,
- ichMin, ichLim,
- fStartLine, fEndLine,
- 10000, klbWordBreak, // not used
- twsh, fParaRtl,
- ppsegRet, pdxWidth,
- //cbPrev, pbPrevSegDat, cbNextMax, pbNextSegDat, pcbNextSegDat, pdichwContext,
- 0, NULL, 0, NULL, NULL, NULL,
- pstrmLog,
- prgchwErrMsg, cchwMaxErrMsg,
- ichLim, false, false, klbClipBreak, // not used
- &dichLimSegBogus, pest,
- 10000, kestMoreLines); // not used
-}
-*/
-
-
-//:>********************************************************************************************
-//:> Other methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Create a segment.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::MakeSegment(
- // Common parameters
- Segment * psegNew,
- Font * pfont, ITextSource * pgts, IGrJustifier * pjus,
- LayoutEnvironment & layout,
- int ichMin, int ichLim,
- // for finding a break point
- float dxMaxWidth,
- bool fBacktracking,
- // for justification
- bool fJust, float dxJustifiedWidthJ, SegEnd estJ)
-{
- ChkGrArgPtr(pgts);
- ChkGrArgPtrN(pjus);
- ChkGrOutPtr(psegNew);
- Assert(layout.bestBreak() <= layout.worstBreak());
-
- if (pjus == NULL)
- pjus = layout.justifier();
-
- if (m_resFontValid == kresInvalidArg)
- // Uninitialized.
- return; // ReturnResult(kresUnexpected);
-
- SetCmapAndNameTables(pfont);
-
- int segmode = ksegmodeRange; // segment from range
- if (fJust)
- segmode = ksegmodeJust; // justified segment
- else if (dxMaxWidth < kPosInfFloat)
- segmode = ksegmodeBreak; // find break point
-
- // Temporary:
- if (!this->m_ptman)
- {
- Warn("No Graphite tables");
- m_ptman = new GrTableManager(this);
- CreateEmpty();
- }
-
- // GrResult hr = kresOk;
- m_fInErrorState = false;
-
- bool fBold, fItalic;
- GetStyles(pfont, ichMin, &fBold, &fItalic);
-
- GetWritingSystemDirection(pgts, ichMin);
-
- // Find the end of the range to render with the current font.
- int nDirDepth = 0;
- int ichFontLim = FindFontLim(pgts, ichMin, &nDirDepth);
- int ichStrmLim = 0;
- int ichSegLim = 0;
- switch (segmode)
- {
- case ksegmodeBreak: // find break point
- // Here ichLim should be the end of the text-source, unless we're backtracking.
- ichStrmLim = min(ichFontLim, ichLim);
- ichSegLim = -1; // unknown
- break;
- case ksegmodeJust: // stretching an existing segment to achieve justification
- ichStrmLim = ichFontLim;
- ichSegLim = ichLim;
- break;
- //case ksegmodeMms: // MakeMeasuredSegment
- // ichLim = ichFontLim;
- // ichStrmLim = ichFontLim;
- // ichSegLim = -1; // process to the end of the stream
- // break;
- case ksegmodeRange: // segment from range
- ichLim = min(ichLim, ichFontLim);
- ichStrmLim = ichFontLim;
- ichSegLim = (ichLim == kPosInfinity) ? -1 : ichLim;
- break;
- default:
- Assert(false);
- }
-
- // Initialize the graphics object with the font and character properties.
- // SILE
- ////if (m_fUseSepBase)
- ////{
- //// Assert(m_stuBaseFaceName.size() > 0);
- //// SetUpGraphics(pgg, pgts, ichMin, m_stuBaseFaceName);
- ////}
- ////else
- //// SetUpGraphics(pgg, pgts, ichMin, m_stuFaceName);
-
- GrResult res = kresOk;
-
- Assert(m_ptman);
- m_ptman->State()->SetFont(pfont);
-
- // Create a character stream on the text source.
- GrCharStream * pchstrm = new GrCharStream(pgts, ichMin, ichStrmLim,
- layout.startOfLine(), layout.endOfLine());
-
- // TODO: change vertical offset to work on a character-by-character basis
- m_dysOffset = (pgts->getVerticalOffset(ichMin) * pfont->getDPIy()) / 72;
-
- // Run the tables and get back a segment.
-
- bool fMoreText = false;
- int ichCallerBtLim = -1;
- bool fInfiniteWidth = false;
- switch (segmode)
- {
- //case ksegmodeMms:
- case ksegmodeBreak:
- case ksegmodeRange:
- if (segmode == ksegmodeBreak)
- {
- fMoreText = ((ichFontLim < ichLim) || fBacktracking);
- ichCallerBtLim = (fBacktracking) ? ichLim : -1;
- fInfiniteWidth = false;
- }
- //else if (segmode == ksegmodeMms)
- //{
- // fMoreText = false;
- // ichCallerBtLim = -1;
- // fInfiniteWidth = true;
- // Assert(twsh == ktwshAll);
- //}
- else if (segmode == ksegmodeRange)
- {
- int ichTextLim;
- ichTextLim = pgts->getLength();
- fMoreText = (ichLim < ichTextLim);
- ichCallerBtLim = -1;
- fInfiniteWidth = true;
- }
- try {
- m_ptman->Run(psegNew, pfont, pchstrm, pjus,
- ((pjus) ? kjmodiCanShrink : kjmodiNormal),
- layout,
- ichSegLim, dxMaxWidth, 0,
- fBacktracking, fMoreText, ichFontLim, fInfiniteWidth, false,
- ichCallerBtLim,
- nDirDepth, estJ);
- }
- catch (...)
- {
- // Disastrous problem in rendering.
- if (!layout.dumbFallback())
- throw; // throws original exception
-
- // Try dumb rendering.
- if (m_fUseSepBase)
- SwitchGraphicsFont(true); // use the base font, which has real glyphs
-
- m_fInErrorState = true;
- res = RunUsingEmpty(psegNew, pfont, pchstrm, layout,
- ichSegLim,
- dxMaxWidth,
- fBacktracking, fMoreText, fInfiniteWidth,
- ichCallerBtLim,
- nDirDepth, estJ);
- }
- break;
-
- case ksegmodeJust: // justified segment
- {
- m_ptman->Run(psegNew, pfont, pchstrm, pjus, kjmodiJustify, layout,
- ichSegLim,
- dxJustifiedWidthJ, dxMaxWidth,
- false, false, // not used
- ichFontLim,
- true, // infinite width
- false, // kludge
- -1,
- nDirDepth, estJ);
- //&dxWidth, &est);
- Assert((ichLim - ichMin) == (psegNew->stopCharacter() - psegNew->startCharacter()));
- break;
- }
-
- default:
- Assert(false);
- }
-
- delete pchstrm;
-
- if (m_fUseSepBase)
- SwitchGraphicsFont(false);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return an indication of whether an error happened in trying to load Graphite tables.
-----------------------------------------------------------------------------------------------*/
-FontErrorCode GrEngine::IsValidForGraphite(int * pnVersion, int * pnSubVersion)
-{
- if (pnVersion)
- *pnVersion = m_fxdBadVersion >> 16;
- if (pnSubVersion)
- *pnSubVersion = m_fxdBadVersion & 0x0000FFFF;
-
- return m_ferr;
-}
-
-/*----------------------------------------------------------------------------------------------
- Record a system error indicating that the font could not be loaded properly.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-void GrEngine::RecordFontLoadError(OLECHAR * prgchwErrMsg, int cchMax)
-{
- if (prgchwErrMsg == NULL || cchMax == 0)
- return;
-
- std::wstring stuMessage = L"Error in initializing Graphite font \"";
- stuMessage.append(m_stuFaceName);
- if (m_stuErrCtrlFile.size())
- {
- stuMessage.append(L"\" (");
- stuMessage.append(m_stuErrCtrlFile);
- stuMessage.append(L")");
- }
- else
- stuMessage.append(L"\"");
- if (m_stuInitError.size())
- {
- stuMessage.append(L"--\n");
- stuMessage.append(m_stuInitError);
- }
-
- std::fill_n(prgchwErrMsg, cchMax, 0);
- std::copy(stuMessage.data(), stuMessage.data() + min(cchMax - 1, signed(stuMessage.size())),
- prgchwErrMsg);
-}
-
-/*----------------------------------------------------------------------------------------------
- Record a system error indicating a bad error in rendering using a supposedly valid font.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-void GrEngine::RecordFontRunError(OLECHAR * prgchwErrMsg, int cchMax, GrResult res)
-{
- if (prgchwErrMsg == NULL || cchMax == 0)
- return;
-
- std::wstring stuMessage = L"Error in rendering using Graphite font \"";
- stuMessage.append(m_stuFaceName);
- if (m_stuErrCtrlFile.size())
- {
- stuMessage.append(L"\" (");
- stuMessage.append(m_stuErrCtrlFile);
- stuMessage.append(L")");
- }
- else
- stuMessage.append(L"\"");
-
- std::fill_n(prgchwErrMsg, cchMax, 0);
- std::copy(stuMessage.data(), stuMessage.data() + min(cchMax - 1, signed(stuMessage.size())),
- prgchwErrMsg);
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize the font error message buffer to zero. This way we can be sure to recognize
- an error condition by the fact that the buffer is non-zero.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-void GrEngine::ClearFontError(OLECHAR * prgchwErrMsg, int cchMaxErrMsg)
-{
- std::fill_n(prgchwErrMsg, cchMaxErrMsg, 0);
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the overall direction of the writing system based on the text properties.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::GetWritingSystemDirection(ITextSource * pgts, int ichwMin)
-{
-#ifdef OLD_TEST_STUFF
- // for test procedures:
- if (m_stuInitialize == "RightToLeftLayout")
- {
- m_fRightToLeft = true;
- return;
- }
-#endif // OLD_TEST_STUFF
-
- m_fRightToLeft = pgts->getRightToLeft(ichwMin);
-}
-
-/*----------------------------------------------------------------------------------------------
- Find the end of the range that uses the current font.
-
- @param pgts - contains text to render
- @param ichwMinFont - beginning of range to render with this font
- @param pnDirDepth - return direction depth: 0=LTR, 1=RTL
-
- @return The lim of the range that could be rendered by this font. Also the direction depth.
-----------------------------------------------------------------------------------------------*/
-int GrEngine::FindFontLim(ITextSource * pgts, int ichwMinFont, int * pnDirDepth)
-{
- int ichwTextLen = (int)pgts->getLength();
-
- int ichwLimRange; // range that can be rendered without breaking contextualization.
- int ichwMinNext = ichwMinFont;
-
- while (true)
- {
- std::pair<toffset, toffset> pairRange = pgts->propertyRange(ichwMinNext);
- // int ichwMinRun = pairRange.first;
- int ichwLimRun = pairRange.second;
- *pnDirDepth = pgts->getDirectionDepth(ichwMinNext);
-
- //if (ichwLim > -1 && ichwLim < ichwLimRun)
- //{
- // // Stopping in the middle of a run
- // return ichwLim;
- //}
-
- // We can at least go to the end of this run.
- ichwLimRange = ichwLimRun;
- if (ichwLimRun >= ichwTextLen)
- {
- // Hit the end of the text-source
- return ichwLimRange;
- }
- else
- {
- // If the following run is the same as this run except for color and underlining,
- // we don't have to break here.
- if (!pgts->sameSegment(ichwMinNext, ichwLimRun))
- return ichwLimRange;
- }
- ichwMinNext = ichwLimRun;
- }
-
- return ichwLimRange;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the version number from the tables, and return false if any are a version this
- implementation of the engine can't handle.
-----------------------------------------------------------------------------------------------*/
-bool GrEngine::CheckTableVersions(GrIStream * pgrstrm,
- byte *pSilfTbl, int lSilfStart,
- byte *pGlobTbl, int lGlocStart,
- byte *pFeatTbl, int lFeatStart,
- int * pfxdBadVersion)
-{
- pgrstrm->OpenBuffer(pSilfTbl, isizeof(int));
- pgrstrm->SetPositionInFont(lSilfStart);
- *pfxdBadVersion = ReadVersion(*pgrstrm);
- pgrstrm->CloseBuffer();
- if (*pfxdBadVersion > kSilfVersion)
- return false;
-
- pgrstrm->OpenBuffer(pGlobTbl, lGlocStart + isizeof(int));
- pgrstrm->SetPositionInFont(lGlocStart);
- *pfxdBadVersion = ReadVersion(*pgrstrm);
- pgrstrm->CloseBuffer();
- if (*pfxdBadVersion > kGlocVersion)
- return false;
-
- pgrstrm->OpenBuffer(pFeatTbl, isizeof(int));
- pgrstrm->SetPositionInFont(lFeatStart);
- *pfxdBadVersion = ReadVersion(*pgrstrm);
- pgrstrm->CloseBuffer();
- if (*pfxdBadVersion > kFeatVersion)
- return false;
-
- *pfxdBadVersion = 0;
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Reinterpret the version number from a font table.
-----------------------------------------------------------------------------------------------*/
-int GrEngine::ReadVersion(GrIStream & grstrm)
-{
- int fxdVersion = grstrm.ReadIntFromFont();
-
- if (fxdVersion < 0x00010000)
- fxdVersion = 0x00010000; // kludge for bug with which some fonts were generated
-
- return fxdVersion;
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize the engine from the test file. Used for test procedures.
-----------------------------------------------------------------------------------------------*/
-//:Ignore
-#ifdef OLD_TEST_STUFF
-void GrEngine::InitFromControlFileTest()
-{
- IStreamPtr qstrm;
- FileStream::Create(m_stuCtrlFile, STGM_READ, &qstrm);
-
- int nSilfOffset, nGlocOffset, nGlatOffset, nFeatOffset;
-
- nSilfOffset = ReadIntFromFont(qstrm);
- nGlocOffset = ReadIntFromFont(qstrm);
- nGlatOffset = ReadIntFromFont(qstrm);
- nFeatOffset = ReadIntFromFont(qstrm);
- nSill
-
- // Read the "Silf" table.
- int chwMaxGlyphID;
- int fxdVersion;
- ReadSilfTable(qstrm, nSilOffset, 0, &chwMaxGlyphID, &fxdVersion);
-
- // Read the "Gloc" and "Glat" tables.
- ReadGlocAndGlatTables(qstrm, nGlocOffset, qstrm, nGlatOffset, chwMaxGlyphID, fxdVersion);
-
- // Read the "Feat" table.
- ReadFeatTable(qstrm, nFeatOffset);
-}
-#endif // OLD_TEST_STUFF
-//:End Ignore
-
-
-/*----------------------------------------------------------------------------------------------
- Return whether the text is asking for bold and/or italic text.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::GetStyles(Font * pfont, int ichwMin, bool * pfBold, bool * pfItalic)
-{
- *pfBold = pfont->bold();
- *pfItalic = pfont->italic();
-}
-
-/*----------------------------------------------------------------------------------------------
- Switch the Graphics object between the Graphite table file and the base font.
- Should only be called when we know we are using a base font, or when we are reading
- the base font to see if it is valid.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SwitchGraphicsFont(bool fBase)
-{
- Assert(!fBase || m_stuBaseFaceName.size() > 0);
-
- //LgCharRenderProps chrp;
- //pgg->get_FontCharProperties(&chrp);
- //if (fBase)
- //{
- // wcsncpy(chrp.szFaceName, m_stuBaseFaceName.data(), m_stuBaseFaceName.size() + 1);
- // chrp.szFaceName[31] = 0;
- //}
- //else
- //{
- // wcsncpy(chrp.szFaceName, m_stuFaceName.data(), m_stuFaceName.size() + 1);
- // chrp.szFaceName[31] = 0;
- //}
- //pgg->SetupGraphics(&chrp);
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the contents of the "Silf" table from the stream, which is on an extended
- TrueType font file. Specifically, read the iSubTable-th sub-table (for now there is
- only one).
-
- WARNING: any changes to this method must be accompanied by equivalent changes to
- CreateEmpty().
-----------------------------------------------------------------------------------------------*/
-bool GrEngine::ReadSilfTable(GrIStream & grstrm, long lTableStart, int iSubTable,
- int * pchwMaxGlyphID, int * pfxdSilfVersion)
-{
- grstrm.SetPositionInFont(lTableStart);
-
- // version
- *pfxdSilfVersion = ReadVersion(grstrm);
- if (*pfxdSilfVersion > kSilfVersion)
- // Version we don't know how to handle.
- return false;
-
- if (*pfxdSilfVersion >= 0x00030000)
- // compiler version
- grstrm.ReadIntFromFont();
-
- // number of tables
- unsigned short cSubTables = grstrm.ReadUShortFromFont();
- Assert(cSubTables == 1); // for now
- Assert(cSubTables <= kMaxSubTablesInFont);
- if (cSubTables != 1 || cSubTables > kMaxSubTablesInFont)
- return false;
-
- if (*pfxdSilfVersion >= 0x00020000)
- // reserved
- grstrm.ReadShortFromFont();
-
- // subtable offsets
- int nSubTableOffsets[kMaxSubTablesInFont];
- int i;
- for (i = 0; i < cSubTables; i++)
- {
- nSubTableOffsets[i] = grstrm.ReadIntFromFont();
- }
-
- grstrm.SetPositionInFont(lTableStart + nSubTableOffsets[iSubTable]);
-
- // Now we are at the beginning of the desired sub-table.
-
- // Get the position of the start of the table.
- long lSubTableStart;
- grstrm.GetPositionInFont(&lSubTableStart);
-
- // rule version
- int fxdRuleVersion = (*pfxdSilfVersion >= 0x00030000) ?
- ReadVersion(grstrm) :
- *pfxdSilfVersion;
-
- long lPassBlockPos = -1;
- long lPseudosPos = -1;
- if (*pfxdSilfVersion >= 0x00030000)
- {
- lPassBlockPos = grstrm.ReadUShortFromFont() + lSubTableStart;
- lPseudosPos = grstrm.ReadUShortFromFont() + lSubTableStart;
- }
-
- // maximum glyph ID
- data16 chwTmp;
- *pchwMaxGlyphID = grstrm.ReadUShortFromFont();
-
- // extra ascent and descent
- m_mXAscent = grstrm.ReadShortFromFont();
- m_mXDescent = grstrm.ReadShortFromFont();
-
- // TODO: decide whether we want these:
- m_mXAscent = 0;
- m_mXDescent = 0;
-
- // number of passes
- byte cPasses = grstrm.ReadByteFromFont();
- // index of first substitution pass
- byte ipassSub1 = grstrm.ReadByteFromFont();
- // index of first positioning pass
- byte ipassPos1 = grstrm.ReadByteFromFont();
- // index of first justification pass
- byte ipassJust1 = grstrm.ReadByteFromFont();
- // index of first reordered pass, or 0xFF if no reordering
- byte ipassReordered1 = grstrm.ReadByteFromFont();
- if (*pfxdSilfVersion < 0x00020000)
- {
- Assert(ipassJust1 == cPasses || ipassJust1 == ipassPos1);
- ipassJust1 = ipassPos1;
- }
-
- // Sanity checks.
- if (cPasses > kMaxPasses || ipassSub1 > cPasses || ipassPos1 > cPasses)
- return false; // bad table
-
- // line-break flag
- int nLineBreak = grstrm.ReadByteFromFont();
- if (nLineBreak != 0 && nLineBreak != 1)
- return false; // bad table
- m_fLineBreak = (bool)nLineBreak;
-
- // range of possible cross-line-boundary contextualization
- m_cchwPreXlbContext = grstrm.ReadByteFromFont();
- m_cchwPostXlbContext = grstrm.ReadByteFromFont();
-
- // actual glyph ID for pseudo-glyph (ID of bogus attribute)
- byte bTmp; // unsigned
- bTmp = grstrm.ReadByteFromFont();
- m_chwPseudoAttr = bTmp;
- // breakweight
- bTmp = grstrm.ReadByteFromFont();
- m_chwBWAttr = bTmp;
- // directionality
- bTmp = grstrm.ReadByteFromFont();
- m_chwDirAttr = bTmp;
-
- // Sanity checks--don't bother with these, I don't seem to be able to know what are reasonable values.
- //if (m_chwPseudoAttr > 200 || m_chwBWAttr > 200 || m_chwDirAttr > 200)
- // return false; // bad table
-
- if (*pfxdSilfVersion >= 0x00020000)
- {
- // reserved
- grstrm.ReadByteFromFont();
- grstrm.ReadByteFromFont();
-
- // justification levels
- m_cJLevels = grstrm.ReadByteFromFont();
- if (m_cJLevels > kMaxJLevels)
- return false; // bad table
- m_fBasicJust = (m_cJLevels == 0);
- m_chwJStretch0 = 0xffff; // if no justification
- m_chwJShrink0 = 0xffff;
- m_chwJStep0 = 0xffff;
- m_chwJWeight0 = 0xffff;
- for (int i = 0; i < m_cJLevels; i++)
- {
- // justification glyph attribute IDs
- bTmp = grstrm.ReadByteFromFont();
- if (i == 0)
- m_chwJStretch0 = bTmp;
- bTmp = grstrm.ReadByteFromFont();
- if (i == 0)
- m_chwJShrink0 = bTmp;
- bTmp = grstrm.ReadByteFromFont();
- if (i == 0)
- m_chwJStep0 = bTmp;
- bTmp = grstrm.ReadByteFromFont();
- if (i == 0)
- m_chwJWeight0 = bTmp;
- bTmp = grstrm.ReadByteFromFont(); // runto
- // reserved
- grstrm.ReadByteFromFont();
- grstrm.ReadByteFromFont();
- grstrm.ReadByteFromFont();
- }
- }
- else
- {
- m_cJLevels = 0;
- m_fBasicJust = true;
- m_chwJStretch0 = 0xffff;
- m_chwJShrink0 = 0xffff;
- m_chwJStep0 = 0xffff;
- m_chwJWeight0 = 0xffff;
- }
-
- // number of component attributes
- chwTmp = grstrm.ReadUShortFromFont();
- m_cComponents = chwTmp;
-
- // number of user-defined slot attributes
- m_cnUserDefn = grstrm.ReadByteFromFont();
- if (m_cnUserDefn > kMaxUserDefinableSlotAttrs)
- return false; // bad table
-
- // max number of ligature components per glyph
- m_cnCompPerLig = grstrm.ReadByteFromFont();
- if (m_cnCompPerLig > 16)
- return false; // bad table
-
- // directions supported
- bTmp = grstrm.ReadByteFromFont();
- m_grfsdc = bTmp;
- if (m_grfsdc > kfsdcHorizLtr + kfsdcHorizRtl + kfsdcVertFromLeft + kfsdcVertFromRight)
- return false; // bad table
-
- // reserved
- bTmp = grstrm.ReadByteFromFont();
- bTmp = grstrm.ReadByteFromFont();
- bTmp = grstrm.ReadByteFromFont();
-
- // critical features
- int cCriticalFeatures;
- if (*pfxdSilfVersion >= 0x00020000)
- {
- // reserved
- bTmp = grstrm.ReadByteFromFont();
-
- cCriticalFeatures = grstrm.ReadByteFromFont();
- Assert(cCriticalFeatures == 0);
- if (cCriticalFeatures != 0)
- return false; // bad table
-
- // reserved
- bTmp = grstrm.ReadByteFromFont();
- }
-
- // rendering behaviors--ignore for now
- byte cBehaviors = grstrm.ReadByteFromFont();
- data16 chwBehaviors[kMaxRenderingBehavior];
- for (i = 0; i < cBehaviors; i++)
- {
- chwBehaviors[i] = grstrm.ReadUShortFromFont();
- }
-
- // linebreak glyph ID
- m_chwLBGlyphID = grstrm.ReadUShortFromFont();
-
- // Jump to the beginning of the pass offset block, if we have this information.
- if (*pfxdSilfVersion >= 0x00030000)
- grstrm.SetPositionInFont(lPassBlockPos);
- else
- // Otherwise assume that's where we are!
- Assert(lPassBlockPos == -1);
-
- // offsets to passes, relative to the start of this subtable;
- // note that we read (cPasses + 1) of these
- int nPassOffsets[kMaxPasses];
- for (i = 0; i <= cPasses; i++)
- {
- nPassOffsets[i] = grstrm.ReadIntFromFont();
- }
-
- // Jump to the beginning of the pseudo-glyph info block, if we have this information.
- if (*pfxdSilfVersion >= 0x00030000)
- grstrm.SetPositionInFont(lPseudosPos);
- else
- // Otherwise assume that's where we are!
- Assert(lPseudosPos == -1);
-
- // number of pseudo-glyphs and search constants
- short snTmp;
- snTmp = grstrm.ReadShortFromFont();
- m_cpsd = snTmp;
- snTmp = grstrm.ReadShortFromFont();
- m_dipsdInit = snTmp;
- snTmp = grstrm.ReadShortFromFont();
- m_cPsdLoop = snTmp;
- snTmp = grstrm.ReadShortFromFont();
- m_ipsdStart = snTmp;
-
- // unicode-to-pseudo map
- m_prgpsd = new GrPseudoMap[m_cpsd];
- for (i = 0; i < m_cpsd; i++)
- {
- if (*pfxdSilfVersion <= 0x00010000)
- {
- utf16 chwUnicode = grstrm.ReadUShortFromFont();
- m_prgpsd[i].SetUnicode(chwUnicode);
- }
- else
- {
- int nUnicode = grstrm.ReadIntFromFont();
- m_prgpsd[i].SetUnicode(nUnicode);
- }
- gid16 chwPseudo = grstrm.ReadUShortFromFont();
- m_prgpsd[i].SetPseudoGlyph(chwPseudo);
- }
-
- // class table
- m_pctbl = new GrClassTable();
- if (!m_pctbl->ReadFromFont(grstrm, *pfxdSilfVersion))
- return false;
-
- // passes
- return m_ptman->CreateAndReadPasses(grstrm, *pfxdSilfVersion, fxdRuleVersion,
- cPasses, lSubTableStart, nPassOffsets,
- ipassSub1, ipassPos1, ipassJust1, ipassReordered1);
-}
-
-/*----------------------------------------------------------------------------------------------
- Set up the engine with no Graphite smarts at all, just dummy tables.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::CreateEmpty()
-{
- // Silf table
-
- m_mXAscent = 0;
- m_mXDescent = 0;
-
- m_fLineBreak = false;
-
- // range of possible cross-line-boundary contextualization
- m_cchwPreXlbContext = 0;
- m_cchwPostXlbContext = 0;
-
- // Bogus attribute IDs:
- m_chwPseudoAttr = 1; // actual glyph ID for pseudo-glyph (ID of bogus attribute)
- m_chwBWAttr = 2; // breakweight
- m_chwDirAttr = 3; // directionality
-
- m_cComponents = 0; // number of component attributes
-
- m_cnUserDefn = 0; // number of user-defined slot attributes
- m_cnCompPerLig = 0; // max number of ligature components
-
- m_grfsdc = kfsdcHorizLtr; // supported script direction
-
- // linebreak glyph ID
- m_chwLBGlyphID = 0xFFFE;
-
- // number of pseudo-glyphs and search constants
- m_cpsd = 0;
- m_dipsdInit = 0;
- m_cPsdLoop = 0;
- m_ipsdStart = 0;
-
- // class table
- m_pctbl = new GrClassTable();
- m_pctbl->CreateEmpty();
-
- // passes
- if (m_ptman != 0)
- m_ptman->CreateEmpty();
-
- // Gloc and Glat tables
- m_pgtbl = new GrGlyphTable();
- m_pgtbl->SetNumberOfGlyphs(0);
- m_pgtbl->SetNumberOfComponents(0);
- m_pgtbl->SetNumberOfStyles(1); // for now
-
- m_pgtbl->CreateEmpty();
-
- // Feat table
- m_cfeat = 0;
- m_rglcidFeatLabelLangs = NULL;
- m_clcidFeatLabelLangs = 0;
-
- // Language table
- m_langtbl.CreateEmpty();
-}
-
-/*----------------------------------------------------------------------------------------------
- Create the glyph table and fill it in from the font stream.
-----------------------------------------------------------------------------------------------*/
-bool GrEngine::ReadGlocAndGlatTables(GrIStream & grstrmGloc, long lGlocStart,
- GrIStream & grstrmGlat, long lGlatStart,
- int chwGlyphIDMax, int fxdSilfVersion)
-{
- // Determine the highest used glyph ID number.
-// int chwGlyphIDMax = m_chwLBGlyphID;
-// for (int ipsd = 0; ipsd < m_cpsd; ipsd++)
-// {
-// if (m_prgpsd[ipsd].PseudoGlyph() > chwGlyphIDMax)
-// chwGlyphIDMax = m_prgpsd[ipsd].PseudoGlyph();
-// }
-
- // Create the glyph table.
- m_pgtbl = new GrGlyphTable();
- m_pgtbl->SetNumberOfGlyphs(chwGlyphIDMax + 1);
- m_pgtbl->SetNumberOfComponents(m_cComponents);
- m_pgtbl->SetNumberOfStyles(1); // for now
-
- return m_pgtbl->ReadFromFont(grstrmGloc, lGlocStart, grstrmGlat, lGlatStart,
- m_chwBWAttr, m_chwJStretch0, m_cJLevels, m_cnCompPerLig, fxdSilfVersion);
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the contents of the "Feat" table from the stream, which is on an extended
- TrueType font file.
-----------------------------------------------------------------------------------------------*/
-bool GrEngine::ReadFeatTable(GrIStream & grstrm, long lTableStart)
-{
- short snTmp;
- data16 chwTmp;
- int nTmp;
-
- grstrm.SetPositionInFont(lTableStart);
-
- // version
- int fxdVersion = ReadVersion(grstrm);
- if (fxdVersion > kFeatVersion)
- return false;
-
- // number of features
- int cfeat;
- cfeat = grstrm.ReadUShortFromFont();
- if (cfeat > kMaxFeatures)
- return false; // bad table;
-
- // reserved
- chwTmp = grstrm.ReadUShortFromFont();
- nTmp = grstrm.ReadIntFromFont();
-
- std::vector<featid> vnIDs; // unsigned ints
- std::vector<int> vnOffsets;
- std::vector<int> vcfset;
-
- m_cfeat = 0;
- int ifeat;
- for (ifeat = 0; ifeat < cfeat; ifeat++)
- {
- // ID
- featid nID;
- if (fxdVersion >= 0x00020000)
- nID = (unsigned int)grstrm.ReadIntFromFont();
- else
- nID = grstrm.ReadUShortFromFont();
- vnIDs.push_back(nID);
- // number of settings
- data16 cfset = grstrm.ReadUShortFromFont();
- vcfset.push_back(cfset);
- if (fxdVersion >= 0x00020000)
- grstrm.ReadShortFromFont(); // pad bytes
- // offset to settings list
- nTmp = grstrm.ReadIntFromFont();
- vnOffsets.push_back(nTmp);
- // flags
- chwTmp = grstrm.ReadUShortFromFont();
- Assert(chwTmp == 0x8000); // mutually exclusive
- // index into name table of UI label
- int nNameId = grstrm.ReadShortFromFont();
-
- if (fxdVersion <= 0x00020000 && nID == GrFeature::knLangFeatV2)
- {
- // Ignore the obsolete "lang" feature which has ID = 1
- vnIDs.pop_back();
- vcfset.pop_back();
- vnOffsets.pop_back();
- continue;
- }
- AddFeature(nID, nNameId, cfset);
- }
-
- // default feature setting value and name strings;
- for (ifeat = 0; ifeat < m_cfeat; ifeat++)
- {
- GrFeature * pfeat = m_rgfeat + ifeat;
- Assert(pfeat->ID() == vnIDs[ifeat]);
-
- grstrm.SetPositionInFont(lTableStart + vnOffsets[ifeat]);
-
- // Each feature has been initialized with blank spots for the number of settings
- // it has.
- int cfset = vcfset[ifeat];
- Assert(pfeat->NumberOfSettings() == cfset);
- for (int ifset = 0; ifset < cfset; ifset++)
- {
- snTmp = grstrm.ReadShortFromFont(); // yes, signed (TT feat table spec says unsigned)
- short snTmp2 = grstrm.ReadShortFromFont();
- pfeat->AddSetting(snTmp, snTmp2);
-
- if (ifset == 0)
- {
- // default setting value--first in list
- pfeat->SetDefault(snTmp);
- }
- }
- }
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the contents of the "Sill" table from the stream, which is on an extended
- TrueType font file.
-----------------------------------------------------------------------------------------------*/
-bool GrEngine::ReadSillTable(GrIStream & grstrm, long lTableStart)
-{
- grstrm.SetPositionInFont(lTableStart);
-
- // version
- int fxdVersion = ReadVersion(grstrm);
- if (fxdVersion > kSillVersion)
- return false;
-
- return m_langtbl.ReadFromFont(&grstrm, fxdVersion);
-}
-
-/*----------------------------------------------------------------------------------------------
- An error happened in running the tables. Set up temporary dummy tables, and try running
- with dumb rendering.
- Return kresUnexpected if even running the empty tables crashed, kresFail otherwise.
-----------------------------------------------------------------------------------------------*/
-GrResult GrEngine::RunUsingEmpty(Segment * psegNew, Font * pfont,
- GrCharStream * pchstrm, LayoutEnvironment & layout,
- int ichStop,
- float dxMaxWidth,
- bool fNeedFinalBreak, bool fMoreText, bool fInfiniteWidth,
- int ichwCallerBtLim,
- int nDirDepth, SegEnd estJ)
-{
- // Save the current state of the engine.
- int mXAscentSave = m_mXAscent;
- int mXDescentSave = m_mXDescent;
- bool fLineBreakSave = m_fLineBreak;
- int cchwPreXlbContextSave = m_cchwPreXlbContext;
- int cchwPostXlbContextSave = m_cchwPostXlbContext;
- data16 chwPseudoAttrSave = m_chwPseudoAttr;
- data16 chwBWAttrSave = m_chwBWAttr;
- data16 chwDirAttrSave = m_chwDirAttr;
- int cComponentsSave = m_cComponents;
- int cnUserDefnSave = m_cnUserDefn;
- int cnCompPerLigSave = m_cnCompPerLig;
- unsigned int grfsdcSave = m_grfsdc;
- gid16 chwLBGlyphIDSave = m_chwLBGlyphID;
- int cpsdSave = m_cpsd;
- int dipsdInitSave = m_dipsdInit;
- int cPsdLoopSave = m_cPsdLoop;
- int ipsdStartSave = m_ipsdStart;
- GrTableManager * ptmanSave = m_ptman;
- GrClassTable * pctblSave = m_pctbl;
- GrGlyphTable * pgtblSave = m_pgtbl;
- int cfeatSave = m_cfeat;
- GrResult resFontReadSave = m_resFontRead;
-
- GrResult res = kresFail;
-
- pchstrm->Restart();
-
- // Create dummy versions of the tables and run them.
- m_pctbl = NULL;
- m_pgtbl = NULL;
- m_ptman = new GrTableManager(this);
- m_ptman->State()->SetFont(pfont);
- CreateEmpty();
-
- try
- {
- m_ptman->Run(psegNew, pfont, pchstrm, NULL, kjmodiNormal, layout,
- ichStop, dxMaxWidth, 0,
- fNeedFinalBreak, fMoreText, -1, fInfiniteWidth, false,
- ichwCallerBtLim,
- nDirDepth, estJ);
- }
- catch(...)
- {
- // Still didn't work. Oh, well, not much we can do.
- res = kresUnexpected;
- }
-
- psegNew->SetErroneous(true);
-
- if (m_ptman)
- delete m_ptman;
- if (m_pctbl)
- delete m_pctbl;
- if (m_pgtbl)
- delete m_pgtbl;
-
- // Put everything back the way it was.
- m_mXAscent = mXAscentSave;
- m_mXDescent = mXDescentSave;
- m_fLineBreak = fLineBreakSave;
- m_cchwPreXlbContext = cchwPreXlbContextSave;
- m_cchwPostXlbContext = cchwPostXlbContextSave;
- m_chwPseudoAttr = chwPseudoAttrSave;
- m_chwBWAttr = chwBWAttrSave;
- m_chwDirAttr = chwDirAttrSave;
- m_cComponents = cComponentsSave;
- m_cnUserDefn = cnUserDefnSave;
- m_cnCompPerLig = cnCompPerLigSave;
- m_grfsdc = grfsdcSave;
- m_chwLBGlyphID = chwLBGlyphIDSave;
- m_cpsd = cpsdSave;
- m_dipsdInit = dipsdInitSave;
- m_cPsdLoop = cPsdLoopSave;
- m_ipsdStart = ipsdStartSave;
- m_ptman = ptmanSave;
- m_pctbl = pctblSave;
- m_pgtbl = pgtblSave;
- m_cfeat = cfeatSave;
- m_resFontRead = resFontReadSave;
-
- return res;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the glyph ID for the given Unicode value.
-----------------------------------------------------------------------------------------------*/
-gid16 GrEngine::GetGlyphIDFromUnicode(int nUnicode)
-{
- gid16 chwGlyphID = MapToPseudo(nUnicode);
- if (chwGlyphID != 0)
- return chwGlyphID; // return a pseudo-glyph
-
-#ifdef OLD_TEST_STUFF
- if (!m_pCmap31)
- // test procedures
- return chwUnicode;
-#endif // OLD_TEST_STUFF
-
- // Otherwise, get the glyph ID from the font's cmap.
-
- if (m_pCmap_3_10)
- return gid16(TtfUtil::Cmap310Lookup(m_pCmap_3_10, nUnicode));
- else if (m_pCmap_3_1)
- return gid16(TtfUtil::Cmap31Lookup(m_pCmap_3_1, nUnicode));
- else
- return 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the pseudo-glyph corresponding to the given Unicode input, or 0 if none.
-----------------------------------------------------------------------------------------------*/
-gid16 GrEngine::MapToPseudo(int nUnicode)
-{
- if (m_cpsd == 0)
- return 0;
-
-#ifdef _DEBUG
- int nPowerOf2 = 1;
- while (nPowerOf2 <= m_cpsd)
- nPowerOf2 <<= 1;
- nPowerOf2 >>= 1;
- // Now nPowerOf2 is the max power of 2 <= m_cpds
- Assert((1 << m_cPsdLoop) == nPowerOf2); // m_cPsdLoop == log2(nPowerOf2)
- Assert(m_dipsdInit == nPowerOf2);
- Assert(m_ipsdStart == m_cpsd - m_dipsdInit);
-#endif // _DEBUG
-
- int dipsdCurr = m_dipsdInit;
-
- GrPseudoMap * ppsdCurr = m_prgpsd + m_ipsdStart;
- while (dipsdCurr > 0)
- {
- int nTest;
- if (ppsdCurr < m_prgpsd)
- nTest = -1;
- else
- nTest = ppsdCurr->Unicode() - nUnicode;
-
- if (nTest == 0)
- return ppsdCurr->PseudoGlyph();
-
- dipsdCurr >>= 1; // divide by 2
- if (nTest < 0)
- ppsdCurr += dipsdCurr;
- else // (nTest > 0)
- ppsdCurr -= dipsdCurr;
- }
-
- return 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the actual glyph ID to use for glyph metrics and output. For most glyphs, this
- is just the glyph ID we're already working with, but for pseudo-glyphs it will something
- different.
-----------------------------------------------------------------------------------------------*/
-gid16 GrEngine::ActualGlyphForOutput(gid16 chwGlyphID)
-{
- gid16 chwActual = gid16(GlyphAttrValue(chwGlyphID, m_chwPseudoAttr));
- if (chwActual == 0)
- return chwGlyphID; // not a pseudo, we're already working with the actual glyph ID
- else
- return chwActual;
-}
-
-/*----------------------------------------------------------------------------------------------
- Look up name based on lang id and name id in name table.
- Currently used to look up feature names.
-----------------------------------------------------------------------------------------------*/
-std::wstring GrEngine::StringFromNameTable(int nLangID, int nNameID)
-{
- std::wstring stuName;
- stuName.erase();
- size_t lOffset = 0, lSize = 0;
-
- // The Graphite compiler stores our names in either
- // the MS (platform id = 3) Unicode (writing system id = 1) table
- // or the MS Symbol (writing system id = 0) table. Try MS Unicode first.
- // lOffset & lSize are in bytes.
- // new interface:
- if (!TtfUtil::GetNameInfo(m_pNameTbl, 3, 1, nLangID, nNameID, lOffset, lSize))
- {
- if (!TtfUtil::GetNameInfo(m_pNameTbl, 3, 0, nLangID, nNameID, lOffset, lSize))
- {
- return stuName;
- }
- }
-
- size_t cchw = (unsigned(lSize) / sizeof(utf16));
- utf16 * pchwName = new utf16[cchw+1]; // lSize - byte count for Uni str
- const utf16 *pchwSrcName = reinterpret_cast<const utf16*>(m_pNameTbl + lOffset);
- std::transform(pchwSrcName, pchwSrcName + cchw, pchwName, std::ptr_fun<utf16,utf16>(lsbf));
- pchwName[cchw] = 0; // zero terminate
- #ifdef _WIN32
- stuName.assign((const wchar_t*)pchwName, cchw);
- #else
- wchar_t * pchwName32 = new wchar_t[cchw+1]; // lSize - byte count for Uni str
- for (int i = 0; i <= signed(cchw); i++) {
- pchwName32[i] = pchwName[i];
- }
- stuName.assign(pchwName32, cchw);
- delete [] pchwName32;
- #endif
-
- delete [] pchwName;
- return stuName;
-}
-
-/*----------------------------------------------------------------------------------------------
- Add a feature (eg, when loading from the font).
-----------------------------------------------------------------------------------------------*/
-void GrEngine::AddFeature(featid nID, int nNameId, int cfset, int nDefault)
-{
- if (m_cfeat >= kMaxFeatures)
- return;
-
- int ifeat = m_cfeat;
- m_rgfeat[ifeat].Initialize(nID, nNameId, cfset, nDefault);
-// m_hmnifeat.Insert(nID, ifeat);
- m_cfeat++;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the feature with the given ID, or NULL if none.
-----------------------------------------------------------------------------------------------*/
-GrFeature * GrEngine::FeatureWithID(featid nID, int * pifeat)
-{
- for (int ifeat = 0; ifeat < m_cfeat; ifeat++)
- {
- if (m_rgfeat[ifeat].ID() == nID)
- {
- *pifeat = ifeat;
- return m_rgfeat + ifeat;
- }
- }
- *pifeat = -1;
- return NULL;
-
-
- // Alternate implementation if we end up with so many features that we need to use
- // a hash map:
-// int ifeat;
-// if (m_hmnifeat.Retrieve(nID, &ifeat))
-// {
-// Assert(ifeat < kMaxFeatures);
-// return m_rgfeat + ifeat; // may be NULL
-// }
-// else
-// return NULL;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the default for the feature at the given index in the array.
-----------------------------------------------------------------------------------------------*/
-int GrEngine::DefaultForFeatureAt(int ifeat)
-{
- Assert(ifeat < kMaxFeatures);
- if (ifeat >= m_cfeat || ifeat < 0)
- return 0; // undefined feature
-
- return m_rgfeat[ifeat].DefaultValue();
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the default for the feature at the given index in the array.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetDefaultForFeatureAt(int ifeat, int nValue)
-{
- Assert(ifeat < kMaxFeatures);
- Assert(ifeat < m_cfeat);
- if (ifeat >= 0)
- m_rgfeat[ifeat].SetDefault(nValue);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the default feature settings for the given language.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::DefaultsForLanguage(isocode lgcode,
- std::vector<featid> & vnFeats, std::vector<int> & vnValues)
-{
- m_langtbl.LanguageFeatureSettings(lgcode, vnFeats, vnValues);
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize the directionality and breakweight attributes of a new slot based on its
- glyph ID.
- REVIEW: we could optimize by not initializing from the glyph table right away,
- but waiting until we need the value.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::InitSlot(GrSlotState * pslot, int nUnicode)
-{
- gid16 chwGlyphID = pslot->GlyphID();
-
- if (m_ptman->InternalJustificationMode() != kjmodiNormal)
- {
- if (m_cJLevels > 0)
- {
- Assert(m_cJLevels == 1); // for now
- // TODO: do this at level 0.
- pslot->SetJStretch(m_pgtbl->GlyphAttrValue(chwGlyphID, m_chwJStretch0));
- pslot->SetJShrink( m_pgtbl->GlyphAttrValue(chwGlyphID, m_chwJShrink0));
- pslot->SetJStep( m_pgtbl->GlyphAttrValue(chwGlyphID, m_chwJStep0));
- pslot->SetJWeight( m_pgtbl->GlyphAttrValue(chwGlyphID, m_chwJWeight0));
- }
- else if (nUnicode == knSpace)
- {
- // Basic stretch/shrink for whitespace.
- // TODO: do this at level 0.
- Assert(m_fBasicJust);
- int mAdv = pslot->AdvanceX(m_ptman);
- pslot->SetJStretch(mAdv * 100); // stretch up to 100 times natural width
- pslot->SetJShrink(mAdv / 4); // shrink to 75%
- pslot->SetJWeight(1);
- }
- }
-
- if (m_pgtbl && !m_pgtbl->IsEmpty())
- {
- // Initialize from glyph table.
- pslot->SetBreakWeight(m_pgtbl->GlyphAttrValue(chwGlyphID, m_chwBWAttr));
-
- DirCode dirc = DirCode(m_pgtbl->GlyphAttrValue(chwGlyphID, m_chwDirAttr));
- if (BidiCode(nUnicode) && (chwGlyphID == 0 || dirc == kdircNeutral))
- // A built-in character for the bidi algorithm that is not defined in the font but
- // must be given a special directionality:
- goto LDefaults;
-
- pslot->SetDirectionality(dirc);
-
- return;
- }
-
-LDefaults:
- // Otherwise, in fill defaults for some basic values.
- if (pslot->BreakWeight() == GrSlotState::kNotYetSet8)
- {
- switch (nUnicode)
- {
- case knSpace:
- pslot->SetBreakWeight(klbWordBreak);
- break;
- case knHyphen:
- pslot->SetBreakWeight(klbHyphenBreak);
- break;
- default:
- pslot->SetBreakWeight(klbLetterBreak);
- }
- }
-
- if ((int)pslot->Directionality() == GrSlotState::kNotYetSet8)
- {
- switch (nUnicode)
- {
- case knSpace:
- pslot->SetDirectionality(kdircWhiteSpace);
- break;
- case knLRM:
- pslot->SetDirectionality(kdircL);
- break;
- case knRLM:
- pslot->SetDirectionality(kdircR);
- break;
- case knLRO:
- pslot->SetDirectionality(kdircLRO);
- break;
- case knRLO:
- pslot->SetDirectionality(kdircRLO);
- break;
- case knLRE:
- pslot->SetDirectionality(kdircLRE);
- break;
- case knRLE:
- pslot->SetDirectionality(kdircRLE);
- break;
- case knPDF:
- pslot->SetDirectionality(kdircPDF);
- break;
- default:
- if (chwGlyphID == LBGlyphID())
- pslot->SetDirectionality(kdircNeutral);
- else
- pslot->SetDirectionality(kdircL);
- }
- }
- else
- Assert(false); // currently no way to set directionality ahead of time
-}
-
-/*----------------------------------------------------------------------------------------------
- We have just changed this slot's glyph ID. Change the directionality and breakweight
- attributes of a new slot based on its glyph ID.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetSlotAttrsFromGlyphAttrs(GrSlotState * pslot)
-{
- InitSlot(pslot);
-}
-
-/*----------------------------------------------------------------------------------------------
- Create a new segment.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::NewSegment(Segment ** ppseg)
-{
- *ppseg = new Segment;
-}
-
-/*----------------------------------------------------------------------------------------------
- Methods to pass on to the tables.
-----------------------------------------------------------------------------------------------*/
-gid16 GrEngine::GetClassGlyphIDAt(int nClass, int nIndex)
-{
- if (nIndex < 0)
- return 0;
- if (nClass < 0)
- return 0;
-
- try {
- return m_pctbl->GetGlyphID(nClass, nIndex);
- }
- catch (...)
- {
- return 0;
- }
-}
-
-int GrEngine::GetIndexInGlyphClass(int nClass, gid16 chwGlyphID)
-{
- try {
- return m_pctbl->FindIndex(nClass, chwGlyphID);
- }
- catch (...)
- {
- return -1;
- }
-}
-
-size_t GrEngine::NumberOfGlyphsInClass(int nClass)
-{
- try {
- return m_pctbl->NumberOfGlyphsInClass(nClass);
- }
- catch (...)
- {
- return 0;
- }
-}
-
-int GrEngine::GlyphAttrValue(gid16 chwGlyphID, int nAttrID)
-{
-#ifdef OLD_TEST_STUFF
- if (!m_pgtbl) // test procedures
- return 0;
-#endif // OLD_TEST_STUFF
-
- return m_pgtbl->GlyphAttrValue(chwGlyphID, nAttrID);
-}
-
-int GrEngine::ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID)
-{
-#ifdef OLD_TEST_STUFF
- if (!m_pgtbl) // test procedures
- return -1;
-#endif // OLD_TEST_STUFF
-
- return m_pgtbl->ComponentIndexForGlyph(chwGlyphID, nCompID);
-}
-
-
-//:>********************************************************************************************
-//:> For test procedures
-//:>********************************************************************************************
-
-//:Ignore
-
-#ifdef OLD_TEST_STUFF
-
-void GrEngine::SetUpPseudoGlyphTest()
-{
- m_cpsd = 5;
-
- m_prgpsd = new GrPseudoMap[m_cpsd];
-
- m_prgpsd[0].SetUnicode(65);
- m_prgpsd[0].SetPseudoGlyph(1065);
-
- m_prgpsd[1].SetUnicode(66);
- m_prgpsd[1].SetPseudoGlyph(1066);
-
- m_prgpsd[2].SetUnicode(67);
- m_prgpsd[2].SetPseudoGlyph(1067);
-
- m_prgpsd[3].SetUnicode(68);
- m_prgpsd[3].SetPseudoGlyph(1068);
-
- m_prgpsd[4].SetUnicode(69);
- m_prgpsd[4].SetPseudoGlyph(1069);
-
- m_dipsdInit = 4;
- m_cPsdLoop = 2;
- m_ipsdStart = 1;
-}
-
-#endif // OLD_TEST_STUFF
-
-
-//:>********************************************************************************************
-//:> New interface
-//:>********************************************************************************************
-/*----------------------------------------------------------------------------------------------
- Store the default features values as specified by the client.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::AssignDefaultFeatures(int cfeat, FeatureSetting * prgfset)
-{
- for (int ifeatIn = 0; ifeatIn < cfeat; ifeatIn++)
- {
- int ifeat;
- FeatureWithID(prgfset[ifeatIn].id, &ifeat);
- if (ifeat >= 0 )
- SetDefaultForFeatureAt(ifeat, prgfset[ifeatIn].value);
- }
-}
-
-bool GrEngine::LoggingTransduction()
-{
- Assert(false);
- //return m_pfface->getLogging();
- //return m_fLogXductn;
- return true;
-}
-
-} // namespace gr
-
-//:End Ignore
-
diff --git a/Build/source/libs/graphite-engine/src/segment/GrEngine.h b/Build/source/libs/graphite-engine/src/segment/GrEngine.h
deleted file mode 100644
index 81b54e805bc..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrEngine.h
+++ /dev/null
@@ -1,622 +0,0 @@
-/*--------------------------------------------------------------------
-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: GrEngine.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Contains the definition of the GrEngine class.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef GR_ENGINE_INCLUDED
-#define GR_ENGINE_INCLUDED
-#include <limits>
-
-#ifdef _MSC_VER
-#include <crtdbg.h>
-#endif
-
-namespace gr
-{
-class IGrJustifier;
-class Segment;
-
-
-/*----------------------------------------------------------------------------------------------
- The GrEngine serves as the top level object that knows how to run Graphite tables
- and generate Graphite segments.
-
- Primarily, this class implements IRenderEngine, which allows it to serve as a FW
- rendering engine. It also implements ISimpleInit, a general interface for initializing
- using a string. Finally, it implements ITraceControl, a very simple interface which
- allows a client to flip a flag indicating whether or not we want to output a log of
- the Graphite transduction process.
-
- Hungarian: greng
-----------------------------------------------------------------------------------------------*/
-class GrEngine : public GraphiteProcess
-{
- friend class FontFace;
- friend class FontMemoryUsage;
-
-public:
- // Constructors & destructors:
- GrEngine();
- void BasicInit();
- virtual ~GrEngine();
- void DestroyContents(bool fDestroyCmap = true);
-
- // ISimpleInit methods:
- ////GrResult InitNew(const byte * prgb, int cb); -- obsolete
- ////GrResult get_InitializationData(int cchMax, OLECHAR * rgchw, int * pcch); -- obsolete
-
- // ITraceControl methods:
- //GrResult SetTracing(int n);
- //GrResult GetTracing(int * pnOptions);
-
- // IRenderingFeatures methods:
- //GrResult GetFeatureIDs(int cMax, int * prgFids, int * pcfid);
- //GrResult GetFeatureLabel(int fid, int nLanguage, int cchMax, OLECHAR * rgchw, int * pcch);
- //GrResult GetFeatureValues(int fid, int cfvalMax,
- // int * prgfval, int * pcfval, int * pfvalDefault);
- //GrResult GetFeatureValueLabel(int fid, int fval, int nLanguage,
- // int cchMax, OLECHAR * rgchw, int * pcch);
-
- // IRenderEngine methods:
- ////GrResult InitRenderer(IGrGraphics * pgg, OLECHAR * prgchData, int cchData); -- obsolete
- ////GrResult FontIsValid(OLECHAR * prgchwErrMsg, int cchMaxErrMsg);
-
- GrResult get_SegDatMaxLength(int * pcb);
-
- //GrResult FindBreakPoint(Font * pfont, ITextSource * pgts, DELETE
- // int ichMin, int ichLim, int ichLimBacktrack,
- // bool fNeedFinalBreak,
- // bool fStartLine,
- // float dxMaxWidth,
- // LineBrk lbPref, LineBrk lbMax,
- // TrWsHandling twsh, bool fParaRtoL,
- // Segment ** ppsegRet,
- // int * pdichwLimSeg, float * pdxWidth, SegEnd * pest,
- // int cbPrev, byte * pbPrevSegDat,
- // int cbNextMax, byte * pbNextSegDat, int * pcbNextSegDat,
- // int * pdichwContext,
- // std::ostream * pstrmLog,
- // OLECHAR * prgchwErrMsg, int cchMaxErrMsg);
-
- //GrResult FindBreakPointWJust(Font * pfont, ITextSource * pgts, IGrJustifier * pgjus,
- // int ichMin, int ichLim, int ichLimBacktrack, DELETE
- // bool fNeedFinalBreak,
- // bool fStartLine,
- // float dxMaxWidth,
- // LineBrk lbPref, LineBrk lbMax,
- // TrWsHandling twsh, bool fParaRtoL,
- // Segment ** ppsegRet,
- // int * pdichwLimSeg, float * pdxWidth, SegEnd * pest,
- // int cbPrev, byte * pbPrevSegDat,
- // int cbNextMax, byte * pbNextSegDat, int * pcbNextSegDat,
- // int * pdichwContext,
- // std::ostream * pstrmLog,
- // OLECHAR * prgchwErrMsg, int cchMaxErrMsg);
-
- GrResult get_ScriptDirection(unsigned int * pgrfsdc, OLECHAR * prgchwErrMsg, int cchMaxErrMsg);
-
- // DELETE
- //GrResult MakeJustifiedSegment(Font * pfont, ITextSource * pgts, IGrJustifier * pgj,
- // int ichMin, int ichLim,
- // bool fStartLine, bool fEndLine,
- // float dxUnjustifiedWidth, float dxJustifiedWidth,
- // TrWsHandling twsh, SegEnd est, LineBrk lb,
- // bool fParaRtl,
- // Segment ** ppsegRet, float * pdxWidth,
- // //int cbPrev, byte * pbPrevSegDat, int cbNextMax, byte * pbNextSegDat, int * pcbNextSegDat, int * pdichwContext,
- // std::ostream * pstrmLog,
- // OLECHAR * prgchwErrMsg, int cchwMaxErrMsg);
-
- // IJustifyingRenderer methods:
- // These methods return kresInvalidArg if the attribute ID is invalid or inappropriate;
- // kresFail if the engine is not in an appropriate state to return the information.
- virtual GrResult getGlyphAttribute(int iGlyph, int jgat, int nLevel, float * pValueRet);
- virtual GrResult getGlyphAttribute(int iGlyph, int jgat, int nLevel, int * pValueRet);
- virtual GrResult setGlyphAttribute(int iGlyph, int jgat, int nLevel, float value);
- virtual GrResult setGlyphAttribute(int iGlyph, int jgat, int nLevel, int value);
-
- // Interface methods not used by FW:
-
- ////GrResult IsGraphiteFont(IGrGraphics * pgg); -- obsolete
-
- ////GrResult FontAscentAndDescent(IGrGraphics * pgg, int * pysAscent, int * pysDescent); -- obsolete
-
- //GrResult MakeMeasuredSegment(
- // Font * pfont, ITextSource * pgts,
- // int ichMin, int ichLim,
- // bool fParaRtl,
- // Segment ** ppsegRet, SegEnd * pest,
- // std::ostream * pstrmLog,
- // OLECHAR * prgchwErrMsg, int cchMaxErrMsg);
-
- //GrResult MakeSegmentFromRange(Font * pfont, ITextSource * pgts, IGrJustifier * pgj,
- // int ichMin, int ichLim,
- // bool fStartLine, bool fEndLine,
- // TrWsHandling twsh, bool fParaRtl,
- // Segment ** ppsegRet, float * pdxWidth, SegEnd * pest,
- // int cbPrev, byte * pbPrevSegDat, int cbNextMax, byte * pbNextSegDat, int * pcbNextSegDat,
- // int * pdichwContext,
- // std::ostream * pstrmLog,
- // OLECHAR * prgchwErrMsg, int cchwMaxErrMsg);
-
- // NEW interface
-
- GrResult ReadFontTables(Font * pfont, bool fItalic);
-
- FontErrorCode IsValidForGraphite(int * pnVersion, int * pnSubVersion);
-
- // Other public methods
-
- GrResult FindBreakPointAux(Font * pfont, ITextSource * pgts, IGrJustifier * pgjus,
- int ichwMin, int ichwLim, int ichwLimBacktrack,
- bool fNeedFinalBreakArg, bool fStartLine, bool fEndLine,
- float dxMaxWidth, bool fWidthIsCharCount,
- LineBrk lbPref, LineBrk lbMax, TrWsHandling twsh, bool fParaRtl,
- Segment ** ppsegRet,
- int * pdichwLimSeg,
- float * pdxWidth, SegEnd * pest,
- int cbPrev, byte * pbPrevSegDat,
- int cbNextMax, byte * pbNextSegDat, int * pcbNextSegDat,
- int * pdichwContext,
- std::ostream * pstrmLog,
- OLECHAR * prgchwErrMsg, int cchMaxErrMsg);
-
- gid16 GetGlyphIDFromUnicode(int nUnicode);
- gid16 ActualGlyphForOutput(utf16 chwGlyphID);
-
- int GetFontEmUnits()
- {
- return m_mFontEmUnits;
- }
-
- gid16 LBGlyphID()
- {
- return m_chwLBGlyphID;
- }
-
- gid16 GetClassGlyphIDAt(int nClass, int nIndex);
- int GetIndexInGlyphClass(int nClass, gid16 chwGlyphID);
- size_t NumberOfGlyphsInClass(int nClass);
- int GlyphAttrValue(gid16 chwGlyphID, int nAttrID);
- int ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID);
-
- ////void InitFontName(std::wstring stuInitialize, std::wstring & stuFaceName, std::wstring & stuFeatures); -- obsolete
- void RecordFontLoadError(OLECHAR * prgchwErrMsg, int cchMaxErrMsg);
- void RecordFontRunError(OLECHAR * prgchwErrMsg, int cchMaxErrMsg, GrResult res);
- void ClearFontError(OLECHAR * prgchwErrMsg, int cchMaxErrMsg);
- void GetWritingSystemDirection(ITextSource * pgts, int ichwMin);
- ////GrResult SetUp(IGrGraphics * pgg, std::wstring stuFeatures); -- obsolete
- ////GrResult SetUp(IGrGraphics * pgg, std::wstring stuFeaturesArg, bool fBold, bool fItalic); -- obsolete
-
- GrResult RunUsingEmpty(Segment * psegNew, Font * pfont,
- GrCharStream * pchstrm, LayoutEnvironment & layout,
- int ichStop,
- float dxMaxWidth,
- bool fNeedFinalBreak, bool fMoreText, bool fInfiniteWidth,
- int ichwCallerBtLim,
- int nDirDepth, SegEnd estJ);
- bool InErrorState()
- {
- return m_fInErrorState;
- }
-
- std::wstring FaceName()
- {
- return m_stuFaceName;
- }
- std::wstring BaseFaceName()
- {
- Assert(m_stuBaseFaceName.size() == 0 || m_fUseSepBase);
- return m_stuBaseFaceName; // empty if not using separate base font
- }
- bool Bold()
- {
- return m_fBold;
- }
- bool Italic()
- {
- return m_fItalic;
- }
-
- void GetStyles(Font * pfont, int ichwMin, bool * pfBold, bool * pfItalic);
- void SwitchGraphicsFont(bool fBase);
-
- void AddFeature(featid nID, int nNameId, int cfset, int nDefault = 0);
- GrFeature * FeatureWithID(featid nID, int * pifeat);
- int DefaultForFeatureAt(int ifeat);
- void SetDefaultForFeatureAt(int ifeat, int nValue);
- GrFeature * Feature(int ifeat)
- {
- if (ifeat >= kMaxFeatures)
- return NULL;
- return m_rgfeat + ifeat;
- }
- void DefaultsForLanguage(isocode lgcode,
- std::vector<featid> & vnFeats, std::vector<int> & vnValues);
- std::wstring StringFromNameTable(int nNameId, int nLang);
-
- void InitSlot(GrSlotState *, int nUnicode = -1);
- void SetSlotAttrsFromGlyphAttrs(GrSlotState *);
-
- bool RightToLeft()
- {
- return m_fRightToLeft;
- }
- int TopDirectionLevel()
- {
- return (m_fRightToLeft) ? 1 : 0;
- }
-
- GrGlyphTable * GlyphTable()
- {
- return m_pgtbl;
- }
-
- GrClassTable * ClassTable()
- {
- return m_pctbl;
- }
-
- int NumFeat()
- {
- return m_cfeat;
- }
-
- bool LineBreakFlag()
- {
- return m_fLineBreak;
- }
-
- int PreXlbContext()
- {
- return m_cchwPreXlbContext;
- }
-
- int PostXlbContext()
- {
- return m_cchwPostXlbContext;
- }
-
- int ExtraAscent()
- {
- return m_mXAscent;
- }
-
- int ExtraDescent()
- {
- return m_mXDescent;
- }
-
- float VerticalOffset()
- {
- return m_dysOffset;
- }
-
- int NumUserDefn()
- {
- return m_cnUserDefn;
- }
-
- int NumCompPerLig()
- {
- return m_cnCompPerLig;
- }
-
- bool BasicJustification()
- {
- return m_fBasicJust;
- }
-
- bool LoggingTransduction();
- //{
- // return m_pfface->getLogging();
- // //return m_fLogXductn;
- //}
-
- bool FakeItalic()
- {
- return m_fFakeItalic;
- }
-
- void NewSegment(Segment ** ppseg);
-
- static int ReadVersion(GrIStream & grstrm);
-
- /*----------------------------------------------------------------------------------------------
- Function to convert between coordinate systems.
- This is identical to the built-in MulDiv function except that it rounds with better
- precision.
-
- TODO: move these out of GrEngine to someplace more general.
- ----------------------------------------------------------------------------------------------*/
- inline static int GrIntMulDiv(const int v, const int n, const int d)
- {
- return int(n < 0 ?
- (double(v * n)/double(d)) - 0.5 :
- (double(v * n)/double(d)) + 0.5);
- }
- inline static float GrFloatMulDiv(const float v, const float n, const float d)
- {
- return v * n / d;
- }
- inline static float GrIFIMulDiv(const int v, const float n, const int d)
- {
- return float(double(v) * n / double(d));
- }
- inline static int GrFIFMulDiv(const float v, const int n, const float d)
- {
- return int(n < 0 ?
- (v * double(n) / double(d)) - 0.5 :
- (v * double(n) / double(d)) + 0.5);
- }
- inline static int RoundFloat(const float n)
- {
- return int(n < 0 ? n - 0.5 : n + 0.5);
- }
-
-protected:
- // Member variables:
-
- long m_cref;
-
- //////////// Font information ////////////
-
- bool m_fBold;
- bool m_fItalic;
-
- // do we have the capacity to perform smart rendering for the various styles?
- bool m_fSmartReg;
- bool m_fSmartBold;
- bool m_fSmartItalic;
- bool m_fSmartBI;
- // are the italics faked using a slant?
- bool m_fFakeItalicCache;
- bool m_fFakeBICache;
- // control files for styled text; empty means not yet determined
- std::wstring m_strCtrlFileReg; // regular
- std::wstring m_strCtrlFileBold; // bold
- std::wstring m_strCtrlFileItalic; // italic
- std::wstring m_strCtrlFileBI; // bold-italic
-
- bool m_fFakeItalic; // true if we are simulating an italic slant in positioning
-
- std::wstring m_stuCtrlFile; // control file (.ttf file) from which we got
- // currently loaded files
-
- std::wstring m_stuInitError; // description of any error that happened while initializing
- // the engine
- std::wstring m_stuErrCtrlFile; // file for which the error occurred
-
- std::wstring m_stuFaceName; // eg, "Times New Roman"
- std::wstring m_stuFeatures;
-
- bool m_fUseSepBase;
- std::wstring m_stuBaseFaceName; // from Sile table; empty if we are not using a separate
- // control file
-
- GrResult m_resFontRead; // kresOk if the Graphite font was loaded successfully;
- // kresFail if the font could not be found or basic tables couldn't be read;
- // kresFalse if the Silf table is not present;
- // kresUnexpected if the Graphite tables could not be loaded
-
- GrResult m_resFontValid; // kresInvalidArg if the engine is not yet initialized
- // Originally:
- // kresOk if Graphite font & dc font match cmaps
- // kresUnexpected/kresFalse if dumb rendering
- // kresFail if dumb rendering with no cmap
- // But now it is apparently just = to m_resFontRead otherwise.
- FontErrorCode m_ferr;
- int m_fxdBadVersion;
-
- int m_nFontCheckSum; // when loading a font using the GrGraphics, remember the
- // check sum as a unique identifer
-
- int m_nScriptTag; // from the pertinent writing system; currently not used
- unsigned int m_grfsdc; // supported script directions
-
- bool m_fRightToLeft; // overall writing-system direction
-
- int m_mXAscent; // extra ascent, in font's em-units
- int m_mXDescent; // extra descent, in font's em_units
-
- float m_dysOffset; // vertical offset, in logical units (eg, for super/subscript)
-
- bool m_fBasicJust; // true if there are no complex justification tables/rules in the
- // font, so we use basic whitespace justification
- int m_cJLevels; // number of justification levels
-
- GrTableManager * m_ptman;
- GrClassTable * m_pctbl;
- GrGlyphTable * m_pgtbl;
-
- FontFace * m_pfface;
-
- GrFeature m_rgfeat[kMaxFeatures];
-// HashMap<int, int> m_hmnifeat; // maps from feature IDs to indices in the array
-// // Review: do we need this, or is a linear search adequate?
- int m_cfeat; // number of features present
-
- short * m_rglcidFeatLabelLangs; // LCIDs (language IDs) for all the labels in the feature table
- size_t m_clcidFeatLabelLangs;
-
- GrLangTable m_langtbl;
-
- // are line-breaks relevant at all?
- bool m_fLineBreak;
- // ranges for possible cross-line-boundary contextualization
- int m_cchwPreXlbContext;
- int m_cchwPostXlbContext;
-
- // magic glyph attribute numbers
- data16 m_chwPseudoAttr; // actual-for-pseudo fake glyph attribute
- data16 m_chwBWAttr; // break-weight
- data16 m_chwDirAttr; // directionality
- data16 m_chwJStretch0; // justify.0.stretch
- data16 m_chwJShrink0; // justify.0.shrink
- data16 m_chwJStep0; // justify.0.step
- data16 m_chwJWeight0; // justify.0.weight
-
- gid16 m_chwLBGlyphID; // magic line-break glyph ID
-
- int m_cComponents; // number of glyph attributes at the beginning of the glyph table
- // that actually represent ligature components
-
- int m_cnUserDefn; // number of user-defined slot attributes
- int m_cnCompPerLig; // max number of components needed per ligature
-
- int m_mFontEmUnits; // number of design units in the Em square for the font
-
- // for pseudo-glyph mappings
- int m_cpsd; // number of psuedo-glyphs
- GrPseudoMap * m_prgpsd;
- int m_dipsdInit; // (max power of 2 <= m_cpsd);
- // size of initial range to consider
- int m_cPsdLoop; // log2(max power of 2 <= m_cpsd);
- // indicates how many iterations are necessary
- int m_ipsdStart; // m_cpsd - m_dipsdInit;
- // where to start search
-
- // for Unicode to glyph ID mapping
- ////TableBuffer m_tbufCmap; // hold the full cmap table
- void * m_pCmap_3_1; // point to the MS Unicode cmap subtable
- // uses platform 3 writing system 1 or 0, preferably 1
- // use for Unicode to Glyph ID conversion
- void * m_pCmap_3_10;
- byte * m_pCmapTbl;
- bool m_fCmapTblCopy;
- int m_cbCmapTbl; // needed only for memory instrumentation
-
- // for feature names and maybe other strings from font later
- ////TableBuffer m_tbufNameTbl; // hold full name table; use Name() method to access
- byte * m_pNameTbl;
- bool m_fNameTblCopy;
- int m_cbNameTbl; // needed only for memory instrumentation
-
- bool m_fLogXductn; // true if we want to log the transduction process
-
- bool m_fInErrorState; // true if we are handling a rendering error
-
- // Other protected methods:
-
- enum {
- ksegmodeBreak = 0, // FindBreakPoint
- ksegmodeJust, // MakeJustifiedSegment
- //ksegmodeMms, // MakeMeasuredSegment
- ksegmodeRange // MakeSegmentFromRange
- };
-
- void MakeSegment(
- // Common parameters
- Segment * psegRet,
- Font * pfont, ITextSource * pgts, IGrJustifier * pjus,
- LayoutEnvironment & layout,
- int ichMin, int ichLim,
- // for finding a line break
- float dxMaxWidth,
- bool fBacktracking,
- // for making a justified segment
- bool fJust, float dxJustifiedWidthJ, SegEnd estJ);
-
- int FindFontLim(ITextSource * pgts, int ichFontMin, int * pnDirDepth);
-
-#ifdef GR_FW
- ////GrResult InitFromControlFile(IGrGraphics * pgg, std::wstring stuFaceName,
- //// bool fBold, bool fItalic); -- obsolete
- ////GrResult ReadFromControlFile(std::wstring stuFontFile); -- obsolete
-// GrResult GetFallBackFont(std::wstring * pstu);
-#endif
-
- ////GrResult ReadFromGraphicsFont(IGrGraphics * pgg, bool fItalic); -- obsolete
- void DestroyEverything();
-
- bool CheckTableVersions(GrIStream * pgrstrm,
- byte *silf_tbl, int lSilfStart,
- byte *gloc_tbl, int lGlocStart,
- byte *feat_tbl, int lFeatStart,
- int * pfxdBadVersion);
- //bool ReadSileTable(GrIStream & grstrm, long lTableSTart,
- // int * pmFontEmUnits, bool * pfMismatchedBase);
- bool ReadSilfTable(GrIStream & grstrm, long lTableStart, int iSubTable,
- int * pchwMaxGlyphID, int * pfxdVersion);
- bool ReadGlocAndGlatTables(GrIStream & grstrm, long lGlocStart, GrIStream & glat_strm, long lGlatStart,
- int chwMaxGlyphID, int fxdSilfVersion);
- bool ReadFeatTable(GrIStream & grstrm, long lTableStart);
- bool ReadSillTable(GrIStream & grstrm, long lTableStart);
- bool SetCmapAndNameTables(Font * pfont);
-
- void CreateEmpty();
-
- bool BadFont(FontErrorCode * pferr = NULL)
- {
- if (pferr)
- *pferr = m_ferr;
- return (m_resFontValid == kresFail || m_resFontRead == kresFail);
- }
- bool DumbFallback(FontErrorCode * pferr = NULL)
- {
- if (pferr)
- *pferr = m_ferr;
- return (m_resFontValid != kresOk || m_resFontRead != kresOk);
- }
-
- gid16 MapToPseudo(int nUnicode);
-
- // NEW interface
- void AssignDefaultFeatures(int cfeat, FeatureSetting * prgfset);
-
- // Feature access for FontFace:
- size_t NumberOfFeatures_ff();
- featid FeatureID_ff(size_t ifeat);
- size_t FeatureWithID_ff(featid id);
- bool GetFeatureLabel_ff(size_t ifeat, lgid language, utf16 * label);
- int GetFeatureDefault_ff(size_t ifeat);
- size_t NumberOfSettings_ff(size_t ifeat);
- int GetFeatureSettingValue_ff(size_t ifeat, size_t ifset);
- bool GetFeatureSettingLabel_ff(size_t ifeat, size_t ifset, lgid language, utf16 * label);
- // Feature-label languages:
- size_t NumberOfFeatLangs_ff();
- short GetFeatLabelLang_ff(size_t ilang);
- // Language access for FontFace:
- size_t NumberOfLanguages_ff();
- isocode GetLanguageCode_ff(size_t ilang);
-
- void SetUpFeatLangList();
-
-//:Ignore
-#ifdef OLD_TEST_STUFF
- // For test procedures:
- void SetUpCrossLineContextTest();
- void SetUpPseudoGlyphTest();
- void SetUpRuleActionTest();
- void SetUpRuleAction2Test();
- void SetUpAssocTest();
- void SetUpAssoc2Test();
- void SetUpDefaultAssocTest();
- void SetUpFeatureTest();
- void SetUpLigatureTest();
- void SetUpLigature2Test();
-
- void InitFromControlFileTest();
-#endif // OLD_TEST_STUFF
-//:End Ignore
-};
-
-} // namespace gr
-
-#if defined(GR_NO_NAMESPACE)
-using namespace gr;
-#endif
-
-
-#endif // !GR_ENGINE_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/GrFSM.cpp b/Build/source/libs/graphite-engine/src/segment/GrFSM.cpp
deleted file mode 100644
index 53182edab0d..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrFSM.cpp
+++ /dev/null
@@ -1,526 +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: GrFSM.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Implements the finite state machine.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-#include <cstring>
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-// any other headers (not precompiled)
-
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Fill in the FSM by reading from the font stream.
- Assumes the stream is in the correct position.
-----------------------------------------------------------------------------------------------*/
-bool GrFSM::ReadFromFont(GrIStream & grstrm, int fxdVersion)
-{
- short snTmp;
-
- // number of FSM states
- snTmp = grstrm.ReadShortFromFont();
- m_crow = snTmp;
- // number of transitional states
- snTmp = grstrm.ReadShortFromFont();
- int crowTransitional = snTmp;
- // number of success states
- snTmp = grstrm.ReadShortFromFont();
- int crowSuccess = snTmp;
- m_crowFinal = m_crow - crowTransitional;
- m_crowNonAcpt = m_crow - crowSuccess;
- m_rowFinalMin = crowTransitional;
- // number of columns
- snTmp = grstrm.ReadShortFromFont();
- m_ccol = snTmp;
-
- // Sanity checks.
- if (crowTransitional > m_crow || crowSuccess > m_crow)
- return false; // bad table
- // TODO: add a sanity check for m_ccol.
-
- // number of FSM glyph ranges and search constants
- snTmp = grstrm.ReadShortFromFont();
- m_cmcr = snTmp;
- snTmp = grstrm.ReadShortFromFont();
- m_dimcrInit = snTmp;
- snTmp = grstrm.ReadShortFromFont();
- m_cLoop = snTmp;
- snTmp = grstrm.ReadShortFromFont();
- m_imcrStart = snTmp;
-
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- for (int imcr = 0; imcr < m_cmcr; imcr++)
- {
- m_prgmcr[imcr].m_chwFirst = grstrm.ReadUShortFromFont();
- m_prgmcr[imcr].m_chwLast = grstrm.ReadUShortFromFont();
- m_prgmcr[imcr].m_col = grstrm.ReadUShortFromFont();
- }
-
- // rule map and offsets (extra item at end gives final offset, ie, total)
- m_prgirulnMin = new data16[crowSuccess + 1];
- data16 * pchw = m_prgirulnMin;
- int i;
- for (i = 0; i < (crowSuccess + 1); i++, pchw++)
- {
- *pchw = grstrm.ReadUShortFromFont();
- }
-
- // Last offset functions as the total length of the rule list.
- // Note that the number of rules in the map is not necessarily equal to the number of
- // rules in the pass; some rules may be listed multiply, if they are matched by more
- // than one state.
- int crulInMap = m_prgirulnMin[crowSuccess];
- m_prgrulnMatched = new data16[crulInMap];
- m_crulnMatched = crulInMap;
- pchw = m_prgrulnMatched;
- for (i = 0; i < crulInMap; i++, pchw++)
- {
- *pchw = grstrm.ReadUShortFromFont();
- }
-
- // min rule pre-context number of items
- byte bTmp = grstrm.ReadByteFromFont();
- m_critMinRulePreContext = bTmp;
- // max rule pre-context number of items
- bTmp = grstrm.ReadByteFromFont();
- m_critMaxRulePreContext = bTmp;
-
- if (m_critMinRulePreContext > kMaxSlotsPerRule || m_critMaxRulePreContext > kMaxSlotsPerRule)
- return false; // bad table
-
- int cStartStates = m_critMaxRulePreContext - m_critMinRulePreContext + 1;
-
- // start states
- m_prgrowStartStates = new short[cStartStates];
- short * psn = m_prgrowStartStates;
- for (int ic = 0; ic < cStartStates; ic++, psn++)
- {
- *psn = grstrm.ReadShortFromFont();
- }
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Fill in the FSM's state table by reading from the font stream.
- Assumes the stream is in the correct position.
-----------------------------------------------------------------------------------------------*/
-bool GrFSM::ReadStateTableFromFont(GrIStream & grstrm, int fxdVersion)
-{
- int cCells = ((m_crow - m_crowFinal) * m_ccol);
- m_prgrowTransitions = new short[cCells];
- short * psn = m_prgrowTransitions;
- for (int iCell = 0; iCell < cCells; iCell++, psn++)
- {
- *psn = grstrm.ReadShortFromFont();
- }
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Use the transition table to find a rule or rules that match; then run the contraint
- code to see if the rule is active. Return the rule number of the rule to be applied.
-
- @param ppass - pass, which knows how to run constraint code
- @param psstrmIn - input stream
- @param psstrmOut - output stream (from which to get recently output slots)
-----------------------------------------------------------------------------------------------*/
-int GrFSM::GetRuleToApply(GrTableManager * ptman, GrPass * ppass,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut)
-{
- // List of accepting states and corresponding count of slots that were
- // matched by each.
- int prgrowAccepting[kMaxSlotsPerRule];
- int prgcslotMatched[kMaxSlotsPerRule];
-
- // Run the transition table until it jams.
- int crowAccepting = RunTransitionTable(ppass, psstrmIn, psstrmOut,
- prgrowAccepting, prgcslotMatched);
-
- // Nothing matched; fail quickly.
- if (crowAccepting == 0)
- return -1;
-
- int * prow = prgrowAccepting + crowAccepting - 1;
- int * pcslot = prgcslotMatched + crowAccepting - 1; // # of slots matched AFTER the curr pos
-
- // Quick test for common case of exactly one rule matched.
- if (crowAccepting == 1 &&
- (m_prgirulnMin[*prow - m_crowNonAcpt + 1] - m_prgirulnMin[*prow - m_crowNonAcpt]) == 1)
- {
- int iruln = m_prgirulnMin[*prow - m_crowNonAcpt];
- int ruln = m_prgrulnMatched[iruln];
- if (RunConstraintAndRecordLog(ptman, ppass, ruln, psstrmIn, psstrmOut,
- ppass->PreModContextForRule(ruln), *pcslot))
- {
- return ruln;
- }
- else
- return -1;
- }
-
- // Several rules were matched. We need to sort them and then run the constraints
- // for each rule, accepting the first one whose constraints succeed.
-
- // Count up the number of rules that matched and allocate a buffer of the right size.
- int crulMatched = 0;
- while (prow >= prgrowAccepting)
- {
- crulMatched +=
- m_prgirulnMin[*prow - m_crowNonAcpt + 1] - m_prgirulnMin[*prow - m_crowNonAcpt];
- --prow;
- }
- MatchedRule * prgmr = new MatchedRule[crulMatched];
-
- prow = prgrowAccepting + crowAccepting - 1;
-
- // Do a dumb insertion sort, ordering primarily by sort key (largest first)
- // and secondarily by the order in the original file (rule number).
- // Review: is this kind of sort fast enough? We assuming that we usually only
- // have a handful of matched rules.
- int cmr = 0;
- while (prow >= prgrowAccepting)
- {
- int iruln = m_prgirulnMin[*prow - m_crowNonAcpt];
- // Get all the rules matches by a single state.
- while (iruln < m_prgirulnMin[*prow - m_crowNonAcpt + 1])
- {
- int ruln = m_prgrulnMatched[iruln];
- int nSortKey = ppass->SortKeyForRule(ruln);
- int cslot = *pcslot;
- int imr;
- for (imr = 0; imr < cmr; imr++)
- {
- if (nSortKey > prgmr[imr].nSortKey ||
- (nSortKey == prgmr[imr].nSortKey && ruln < prgmr[imr].ruln))
- {
- // Insert here.
- memmove(prgmr+imr+1, prgmr+imr, (isizeof(MatchedRule) * (cmr - imr)));
- prgmr[imr].ruln = ruln;
- prgmr[imr].nSortKey = nSortKey;
- prgmr[imr].cslot = cslot;
- break;
- }
- }
- if (imr >= cmr)
- {
- prgmr[cmr].ruln = ruln;
- prgmr[cmr].nSortKey = nSortKey;
- prgmr[cmr].cslot = cslot;
- }
- cmr++;
-
- iruln++;
- }
- --prow;
- --pcslot;
- }
-
-
- for (int imr = 0; imr < cmr; imr++)
- {
- int ruln = prgmr[imr].ruln;
- if (RunConstraintAndRecordLog(ptman, ppass, ruln, psstrmIn, psstrmOut,
- ppass->PreModContextForRule(ruln), prgmr[imr].cslot))
- {
- // Success!
- delete[] prgmr;
- return ruln;
- }
- }
-
- // No rule matched or the constraints failed.
- delete[] prgmr;
- return -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- Run the transition table, generating a list of rows corresponding to accepting states.
-
- @param psstrmIn - input stream
- @param prgrowAccepting - array to fill in with accepting rows
- @param prgcslotMatched - corresponding array with number of slots matched
-----------------------------------------------------------------------------------------------*/
-int GrFSM::RunTransitionTable(GrPass * ppass, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int * prgrowAccepting, int * prgcslotMatched)
-{
- int ipass = ppass->PassNumber();
-
- // Remember we're reading the pre-context items from the output stream, not the input.
- int cslotPreContextAvail = psstrmOut->WritePos();
-
- if (cslotPreContextAvail < m_critMinRulePreContext)
- return 0; // not enough input to match any rule
-
- // Look backwards by the number of pre-context items for this pass, but not earlier
- // than the beginning of the stream.
- int cslot = -1 * min(cslotPreContextAvail, m_critMaxRulePreContext);
-
- // Normally the start state is state 0. But if we are near the beginning of the stream,
- // we may need to adjust due to the fact that we don't have enough input yet to
- // match the pre-context items in all the rules. So in effect we skip some states
- // corresponding to the earlier items that aren't present.
- int row = m_prgrowStartStates[max(0, m_critMaxRulePreContext - cslotPreContextAvail)];
-
- int * prowTop = prgrowAccepting;
- int * pcslotTop = prgcslotMatched;
- while (true)
- {
- if (row >= m_rowFinalMin)
- // final state--jammed
- return (prowTop - prgrowAccepting);
-
- if (psstrmIn->SlotsPendingInContext() <= cslot)
- // no more input
- return (prowTop - prgrowAccepting);
-
- // Figure out what column the input glyph belong in.
- // Since this is a time-critical routine, we cache the results for the current pass.
- GrSlotState * pslot = (cslot < 0) ?
- psstrmOut->PeekBack(cslot) :
- psstrmIn->Peek(cslot);
- int col;
- if (pslot->PassNumberForColumn() == ipass)
- {
- col = pslot->FsmColumn();
- }
- else
- {
- gid16 chwGlyphID = (cslot < 0) ?
- psstrmOut->PeekBack(cslot)->GlyphID() :
- psstrmIn->Peek(cslot)->GlyphID();
- col = FindColumn(chwGlyphID);
- pslot->CacheFsmColumn(ipass, col);
- }
- int rowNext;
- if (col < 0)
- rowNext = 0;
- else
- rowNext = m_prgrowTransitions[(row * m_ccol) + col];
-
- if (rowNext == 0) // jammed
- return (prowTop - prgrowAccepting);
-
- cslot++;
- if (rowNext >= m_crowNonAcpt) // or (rowNext < 0)
- {
- // Accepting state--push it on the stack.
- //rowNext *= -1;
- gAssert((prowTop - prgrowAccepting) < kMaxSlotsPerRule);
- *prowTop++ = rowNext;
- *pcslotTop++ = cslot;
- }
- row = rowNext;
-
- gAssert((prowTop - prgrowAccepting) == (pcslotTop - prgcslotMatched));
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Run the transition table, generating a list of rows corresponding to accepting states.
- Optimized to avoid matrix arithmetic for non-accepting states.
-
- Review: do we need to use this version?
-
- @param psstrmIn - input stream
- @param prgrowAccepting - array to fill in with accepting rows
- @param prgcslotMatched - corresponding array with number of slots matched
-----------------------------------------------------------------------------------------------*/
-#if 0
-
-int GrFSM::RunTransitionTableOptimized(GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int * prgrowAccepting, int * prgcslotMatched)
-{
- int cslot = 0;
- int ichwRowOffset = 0;
- int ichwRowOffsetLim = m_crowFinal * m_ccol; // number of cells
- int * prowTop = prgrowAccepting;
- int * pcslotTop = prgcslotMatched;
- while (true)
- {
- if (ichwRowOffset >= ichwRowOffsetLim)
- // final state--jammed
- return (prowTop - prgrowAccepting);
-
- if (psstrmIn->SlotsPendingInContext() < cslot)
- // no more input
- return (prowTop - prgrowAccepting);
-
- gid16 chwGlyphID = psstrmIn->Peek(cslot)->GlyphID();
- int col = FindColumn(chwGlyphID);
- short cellValue = *(m_prgprgrowXitions + ichwRowOffset + col);
-
- if (cellValue == 0) // jammed
- return (prowTop - prgrowAccepting);
-
- cslot++;
- if (cellValue < 0)
- {
- // Accepting state--push it on the stack.
- int rowNext = cellValue * -1;
- gAssert((prowTop - prgrowAccepting) < kMaxSlotsPerRule);
- *prowTop++ = rowNext;
- *pcslotTop++ = cslot;
- ichwRowOffset = rowNext * m_ccol;
- }
- else
- ichwRowOffset = cellValue;
-
- gAssert((prowTop - prgrowAccepting) == (pcslotTop - prgcslotMatched));
- }
-}
-
-#endif // 0
-
-
-/*----------------------------------------------------------------------------------------------
- Run all the constraints for the rules matched by the state that we have reached.
- The rules are ordered as they were in the GDL file. When we hit a constraint that
- matches, return the corresponding rule number. Return -1 if no rule passed.
-
- @param ppass - pass, which knows how to actually run the constraints
- @param psstrmIn - input stream
- @param cslotMatched - number of slots matched; constraints must be run for each of these
-----------------------------------------------------------------------------------------------*/
-//:Ignore
-int GrFSM::RunConstraints_Obsolete(GrTableManager * ptman, GrPass * ppass, int row,
- GrSlotStream * psstrmIn, int cslotMatched)
-{
- int iruln = m_prgirulnMin[row - m_crowNonAcpt];
- while (iruln < m_prgirulnMin[row - m_crowNonAcpt + 1])
- {
- int ruln = m_prgrulnMatched[iruln];
- bool fSuccess = ppass->RunConstraint(ptman, ruln, psstrmIn, NULL, 0, cslotMatched);
- if (fSuccess)
- {
- if (ptman->LoggingTransduction())
- ppass->RecordRuleFired(psstrmIn->ReadPosForNextGet(), ruln);
- return ruln;
- }
- else
- {
- if (ptman->LoggingTransduction())
- ppass->RecordRuleFailed(psstrmIn->ReadPosForNextGet(), ruln);
- }
-
- iruln++;
- }
- return -1; // no rule succeeded
-}
-//:End Ignore
-
-/*----------------------------------------------------------------------------------------------
- Run the constraints for the given rule, and record whether it failed or succeeded in the
- transduction log.
-
- @param ppass - pass, which knows how to actually run the constraints
- @param psstrmIn - input stream
- @param cslotPreModContext - number of slots before the current position that must be tested
- @param islotLimMatched - number of slots matched AFTER the current position
-
- @return True if the constraints succeeded.
-----------------------------------------------------------------------------------------------*/
-bool GrFSM::RunConstraintAndRecordLog(GrTableManager * ptman, GrPass * ppass, int ruln,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int cslotPreModContext, int islotLimMatched)
-{
- bool fSuccess = ppass->RunConstraint(ptman, ruln, psstrmIn, psstrmOut,
- cslotPreModContext, islotLimMatched);
-
- if (ptman->LoggingTransduction())
- {
- if (fSuccess)
- ppass->RecordRuleFired(psstrmIn->ReadPosForNextGet(), ruln);
- else
- ppass->RecordRuleFailed(psstrmIn->ReadPosForNextGet(), ruln);
- }
-
- return fSuccess;
-}
-
-/*----------------------------------------------------------------------------------------------
- Search for the class range containing the glyph ID, and return the matching FSM column.
- Does a fast binary search that uses only shifts, no division.
-----------------------------------------------------------------------------------------------*/
-int GrFSM::FindColumn(gid16 chwGlyphID)
-{
- #ifdef _DEBUG
- // Check that the pre-calculated constants are correct.
- int nPowerOf2 = 1;
- while (nPowerOf2 <= m_cmcr)
- nPowerOf2 <<= 1;
- nPowerOf2 >>= 1;
- // Now nPowerOf2 is the max power of 2 <= m_cclsrg.
- // m_cLoop is not needed for our purposes, but it is included because it is part of
- // the TrueType standard.
- gAssert(1 << m_cLoop == nPowerOf2); // m_cloop == log2(nPowerOf2)
- gAssert(m_dimcrInit == nPowerOf2);
- gAssert(m_imcrStart == m_cmcr - m_dimcrInit);
- #endif
-
- int dimcrCurr = m_dimcrInit;
-
- GrFSMClassRange * pmcrCurr = m_prgmcr + m_imcrStart;
- while (dimcrCurr > 0)
- {
- int nTest;
- if (pmcrCurr < m_prgmcr)
- nTest = -1;
- else
- {
- nTest = pmcrCurr->m_chwFirst - chwGlyphID;
- if (nTest < 0 && chwGlyphID <= pmcrCurr->m_chwLast)
- //nTest = 0;
- // This is a tiny bit more efficient:
- return pmcrCurr->m_col;
- }
-
- if (nTest == 0)
- // found it
- return pmcrCurr->m_col;
-
- dimcrCurr >>= 1; // divide by 2
- if (nTest < 0)
- pmcrCurr += dimcrCurr;
- else // (nTest > 0)
- pmcrCurr -= dimcrCurr;
- }
-
- return -1;
-}
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/GrFSM.h b/Build/source/libs/graphite-engine/src/segment/GrFSM.h
deleted file mode 100644
index b1909553daa..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrFSM.h
+++ /dev/null
@@ -1,245 +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: GrFSM.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- The GrFSM class, which is the mechanism that examines input in a glyph stream and
- determines which rule matches and should be run.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef FSM_INCLUDED
-#define FSM_INCLUDED
-
-//:End Ignore
-
-namespace gr
-{
-
-class GrPass;
-
-/*----------------------------------------------------------------------------------------------
- A machine class range consists of a range of contiguous glyph IDs that map to
- a single column in the FSM (a machine class). (Note that there might be more than one
- range mapping to a given column.)
-
- Keep in mind that these "classes" are completely different from the classes that
- are used for substitution. These are used only for matching by the FSM.
-
- Hungarian: mcr
-----------------------------------------------------------------------------------------------*/
-class GrFSMClassRange
-{
- friend class GrFSM;
-
-protected:
- gid16 m_chwFirst; // first glyph ID in range
- gid16 m_chwLast; // last glyph ID in range
- data16 m_col; // column (machine class) to which this range maps
-};
-
-/*----------------------------------------------------------------------------------------------
- The finite state machine that is used to match sequences of glyphs and
- determine which rule to apply. There is one FSM per pass.
-
- The states in the FSM are grouped and ordered in the following way:
- - non-accepting states (no rule completely matched)
- - accepting non-final states (a rule matched, but a longer rule is possible)
- - final states (a rule matched and no longer rule is possible)
- In other words, we have:
- - transition, non-accepting
- - transition, accepting
- - non-transition, accepting
- The transition states have information about the next state to transition to;
- the accepting states have information about the rule(s) that matched.
-
- There are three main data structures that are part of the finite state machine:
-
- (1) the transition matrix: m_prgprgrowXitions. It contains a row for each transition
- state (non-accepting states plus accepting non-final states), and a column for each
- machine class. The cell values indicate the next state to transition to for the
- matched input. A positive number indicates that the next state is a non-accepting state;
- a negative value indicates an accepting state. Zero means there is no next state;
- no more matches are possible; machine has "jammed."
-
- (2) the matched-rule list: m_prgrulnMatched. This is a list of rule numbers,
- which are indices into the pass's action- and constraint-code arrays.
- It contains the numbers of the rules matched by the first accepting state,
- followed by those matched by the second accepting state, etc. For each state,
- the rules must be ordered using the same order of the rules in the RDL file.
-
- (3) the matched-rule-offsets list: m_prgirulnMin. This gives the starting index into
- the matched-rule list for each accepting state. (Non-accepting states are not included,
- so the first item is for state m_crowNonAcpt.)
-
- In addition, the FSM interacts with the action- and constraint-code lists in the pass
- itself. These lists are indexed by rule number (the values of m_prgrulnMatched).
- When some input matches the rule, the constraint-code is run; if it succeeds,
- the rule number is returned to the caller and that rule is applied (ie, the action-code
- is run).
-
- Hungarian: fsm
-
- Other hungarian:
- row - row (state)
- col - column (machine class)
- ruln - rule number
-
- REVIEW: This is quite a time-critical class, and there are two potential optimizations
- that have been proposed for the value of a cell:
-
- (1) use a negative cell number to indicate an accepting state and a positive number
- to indicate a non-accepting state. So this gives a comparison with zero rather than
- some arbitrary number
-
- (2) have the positive numbers--the most common case--be the actual byte offset into the
- table rather than the row number. This saves matrix multiplication at each step,
- ie, "m_prgsnTransitions[(row * m_ccol) + col]".
-
- The two versions are implemented in RunTransitionTable and RunTransitionTableOptimized.
- Do these seem to be worth the inconvenience of added complexity in understanding
- and debugging?
-----------------------------------------------------------------------------------------------*/
-class GrFSM
-{
- friend class FontMemoryUsage;
-
-public:
- GrFSM() :
- m_prgirulnMin(NULL),
- m_prgrulnMatched(NULL),
- m_prgrowTransitions(NULL),
- m_prgibStateDebug(NULL),
- m_prgmcr(NULL),
- m_prgrowStartStates(NULL)
- {
- }
-
- ~GrFSM()
- {
- delete[] m_prgirulnMin;
- delete[] m_prgrulnMatched;
-
- delete[] m_prgrowTransitions;
-
- delete[] m_prgibStateDebug;
-
- delete[] m_prgmcr;
-
- delete[] m_prgrowStartStates;
- }
-
- bool ReadFromFont(GrIStream & grstrm, int fxdVersion);
- bool ReadStateTableFromFont(GrIStream & grstrm, int fxdVersion);
-
- int GetRuleToApply(GrTableManager *, GrPass * ppass,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
-
- int RunTransitionTable(GrPass * ppass, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int * prgrowAccepting, int * prgcslotMatched);
- int RunTransitionTableOptimized(GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int * prgrowAccepting, int * prgcslotMatched);
- bool RunConstraintAndRecordLog(GrTableManager *, GrPass * ppass, int ruln,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int cslotPreModContext, int cslotMatched);
-
- int RunConstraints_Obsolete(GrTableManager *, GrPass * ppass, int row, GrSlotStream * psstrmIn,
- int cslotMatched);
-
- // For sorting matched rules
- struct MatchedRule // mr
- {
- int ruln;
- int nSortKey;
- int cslot; // number of slots matched AFTER the current stream position
- };
-
- int MaxRulePreContext()
- {
- return m_critMaxRulePreContext;
- }
-
-protected:
- int FindColumn(gid16 chwGlyphID);
-protected:
- // Instance variables:
- int m_crow; // number of rows (states)
- int m_crowFinal; // number of final states; no transitions for these
- int m_rowFinalMin; // index of first final row
- int m_crowNonAcpt; // number of non-accepting states; no rule indices for these
-
- int m_ccol; // number of columns (machine classes)
-
- data16 * m_prgirulnMin; // m_crow-m_crowNonAcpt+1 of these;
- // index within m_prgrulnMatched, start of matched
- // rules for each accepting state
-
- data16 * m_prgrulnMatched; // long ordered list of rule indices matched by
- // subsequent states; total length is sum of number
- // of rules matched for each accepting state
- int m_crulnMatched; // needed only for memory instrumentation
-
- // Transition matrix--for optimized version:
-// short ** m_prgprgrowXitions; // ((m_crow-m_crowFinal) * m_ccol) of these;
- // positive number indicates
- // next state is non-accepting; negative number is
- // negative of accepting state.
-
- // Transition matrix--for current version:
- short * m_prgrowTransitions; // ((m_crow-m_crowFinal) * m_ccol) of these
-
- // debugger string offsets
- data16 * m_prgibStateDebug; // for transition states; (m_crow-m_crul+1) of these
-
- // constants for fast binary search; these are generated by the compiler so that the
- // engine doesn't have to take time to do it
- data16 m_dimcrInit; // (max power of 2 <= m_cmcr);
- // size of initial range to consider
- data16 m_cLoop; // log2(max power of 2 <= m_cmcr);
- // indicates how many iterations are necessary
- data16 m_imcrStart; // m_cmcr - m_dimcrInit;
- // where to start search
-
- int m_cmcr; // number of machine-class-ranges
- GrFSMClassRange * m_prgmcr; // array of class ranges; we search these to find the
- // mapping to the machine-class-column
-
- // minimum and maximum number of items in the rule contexts before the first modified
- // item.
- int m_critMinRulePreContext;
- int m_critMaxRulePreContext;
-
- // start states--row in the FSM to start on depending on how many bogus slots we
- // are skipping; (max rule-precontext - min rule-precontext + 1) of these;
- // first always = zero
- short * m_prgrowStartStates;
-
-//:Ignore
-#if OLD_TEST_STUFF
-public:
- // For test procedures:
- void SetUpSimpleFSMTest();
- void SetUpRuleActionTest();
- void SetUpRuleAction2Test(int);
- void SetUpAssocTest(int);
- void SetUpAssoc2Test(int);
- void SetUpDefaultAssocTest();
- void SetUpFeatureTest();
- void SetUpLigatureTest(int);
- void SetUpLigature2Test(int);
-#endif // OLD_TEST_STUFF
-//:End Ignore
-
-};
-
-} // namespace gr
-
-
-#endif // !FSM_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/GrFeature.cpp b/Build/source/libs/graphite-engine/src/segment/GrFeature.cpp
deleted file mode 100644
index 61970d56949..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrFeature.cpp
+++ /dev/null
@@ -1,321 +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: GrFeature.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Implements the GrFeature class.
--------------------------------------------------------------------------------*//*:End Ignore*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-#include <cstring>
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> GrFeature Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Initialize the feature.
-----------------------------------------------------------------------------------------------*/
-void GrFeature::Initialize(featid nID, int nNameId, int cfset, int nDefault)
-{
- m_nID = nID;
- m_nNameId = nNameId;
- m_nDefault = nDefault;
-
- m_vnVal.resize(cfset);
- for (unsigned int ifset = 0; ifset < m_vnVal.size(); ifset++)
- m_vnVal[ifset] = INT_MAX;
- m_vnNameId.resize(cfset);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the feature settings.
-----------------------------------------------------------------------------------------------*/
-int GrFeature::Settings(int cMax, int * prgnVal)
-{
- int cRet = min(cMax, signed(m_vnVal.size()));
- for (int ifset = 0; ifset < cRet; ifset++)
- prgnVal[ifset] = m_vnVal[ifset];
- return cRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Add a feature setting.
-----------------------------------------------------------------------------------------------*/
-void GrFeature::AddSetting(int nVal, int nNameId)
-{
- Assert(nVal != INT_MAX);
- unsigned int ifset;
- for (ifset = 0; ifset < m_vnVal.size(); ifset++)
- {
- if (m_vnVal[ifset] == nVal)
- return; // already there
- }
- for (ifset = 0; ifset < m_vnVal.size(); ifset++)
- {
- if (m_vnVal[ifset] == INT_MAX)
- {
- m_vnVal[ifset] = nVal;
- m_vnNameId[ifset] = nNameId;
- return;
- }
- }
- m_vnVal.push_back(nVal);
- m_vnNameId.push_back(nNameId);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if the given setting is valid according to the font's feature table.
-----------------------------------------------------------------------------------------------*/
-bool GrFeature::IsValidSetting(int nVal)
-{
- for (unsigned int ifset = 0; ifset < m_vnVal.size(); ifset++)
- {
- if (m_vnVal[ifset] == nVal)
- return true;
- }
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the feature label from the name table.
-----------------------------------------------------------------------------------------------*/
-std::wstring GrFeature::Label(GrEngine * pgreng, int nLang)
-{
- std::wstring stu = pgreng->StringFromNameTable(nLang, m_nNameId);
- if (stu == L"NoName")
- stu.erase();
- return stu;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the feature value label from the name table.
-----------------------------------------------------------------------------------------------*/
-std::wstring GrFeature::SettingLabel(GrEngine * pgreng, int nVal, int nLang)
-{
- for (unsigned int ifset = 0; ifset < m_vnVal.size(); ifset++)
- {
- if (m_vnVal[ifset] == nVal)
- {
- std::wstring stu = pgreng->StringFromNameTable(nLang, m_vnNameId[ifset]);
- if (stu == L"NoName")
- stu.erase();
- return stu;
- }
- }
- Assert(false); // setting is not valid
- return L"";
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the given setting value.
-----------------------------------------------------------------------------------------------*/
-int GrFeature::NthSetting(int ifset)
-{
- if (ifset >= (int)m_vnVal.size())
- return -1;
- else
- return m_vnVal[ifset];
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the feature value label for the given index.
-----------------------------------------------------------------------------------------------*/
-std::wstring GrFeature::NthSettingLabel(GrEngine * pgreng, int ifset, int nLang)
-{
- std::wstring stu;
-
- if (ifset >= (int)m_vnVal.size())
- stu.erase();
- else
- {
- stu = pgreng->StringFromNameTable(nLang, m_vnNameId[ifset]);
- if (stu == L"NoName")
- stu.erase();
- }
- return stu;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the feature setting label.
-----------------------------------------------------------------------------------------------*/
-// void GrFeature::SetSettingLabel(int nVal, std::wstring stuLabel, int nLang)
-// {
-// for (int ifset = 0; ifset < m_vfset.size(); ifset++)
-// {
-// if (m_vfset[ifset].m_nVal == nVal)
-// {
-// m_vfset[ifset].m_hmnstuLabels.Insert(nLang, stuLabel, true);
-// return;
-// }
-// }
-// Assert(false); // setting is not valid
-// }
-
-
-//:>********************************************************************************************
-//:> GrLangTable Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Read the languages from the font.
-----------------------------------------------------------------------------------------------*/
-bool GrLangTable::ReadFromFont(GrIStream * pgrstrm, int fxdVersion)
-{
- GrIStream & grstrm = *pgrstrm;
-
- // number of languages
- m_clang = (size_t)grstrm.ReadUShortFromFont();
-
- // search constants
- m_dilangInit = grstrm.ReadUShortFromFont();
- m_cLoop = grstrm.ReadUShortFromFont();
- m_ilangStart = grstrm.ReadUShortFromFont();
-
- // Slurp the data into the buffers. The "+1" represents a bogus ending entry that quickly
- // gives us the size of the feature list. Note that the resulting data is all big-endian.
- int cb = (m_clang + 1) * sizeof(LangEntry);
- m_prglang = new LangEntry[m_clang + 1];
- grstrm.ReadBlockFromFont(m_prglang, cb);
-
- m_cbOffset0 = (lsbf)(m_prglang[0].cbOffsetBIG);
-
- Assert((lsbf)(m_prglang[m_clang].cFeaturesBIG) == 0); // bogus entry has no settings
- cb = (lsbf)(m_prglang[m_clang].cbOffsetBIG) - m_cbOffset0;
- Assert(cb % sizeof(FeatSet) == 0); // # of bytes fits nicely into FeatSet class
- int cfset = cb / sizeof(FeatSet);
- m_prgfset = new FeatSet[cfset];
- m_cfset = cfset;
- grstrm.ReadBlockFromFont(m_prgfset, cb);
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Create an empty language table to use for dumb rendering, or when there is no valid
- Sill table.
-----------------------------------------------------------------------------------------------*/
-void GrLangTable::CreateEmpty()
-{
- m_prglang = NULL;
- m_prgfset = NULL;
- m_clang = 0;
- m_dilangInit = 0;
- m_cLoop = 0;
- m_ilangStart = 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return information about the language with the given ID by filling in the given vectors
- with the feature ids and values. Will wipe out any data in the vectors already.
-----------------------------------------------------------------------------------------------*/
-void GrLangTable::LanguageFeatureSettings(isocode lgcode,
- std::vector<featid> & vnFeatId, std::vector<int> & vnValues)
-{
- vnFeatId.clear();
- vnValues.clear();
-
- int ilang = FindIndex(lgcode);
- if (ilang == -1)
- return; // no such language: leave vectors empty
-
- LangEntry * plang = m_prglang + ilang;
- int cbOffset = lsbf(plang->cbOffsetBIG) - m_cbOffset0;
- Assert(cbOffset % sizeof(FeatSet) == 0);
- byte * pbFeatSet = reinterpret_cast<byte*>(m_prgfset) + cbOffset;
- FeatSet * pfset = reinterpret_cast<FeatSet*>(pbFeatSet);
- for (int ifset = 0; ifset < lsbf(plang->cFeaturesBIG); ifset++)
- {
- vnFeatId.push_back(lsbf(pfset[ifset].featidBIG));
- vnValues.push_back(lsbf(pfset[ifset].valueBIG));
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the code for the language at the given index.
-----------------------------------------------------------------------------------------------*/
-isocode GrLangTable::LanguageCode(size_t ilang)
-{
- isocode lgcodeRet;
- if (ilang > m_clang)
- {
- std::fill_n(lgcodeRet.rgch, 4, '\0');
- return lgcodeRet;
- }
- LangEntry * plang = m_prglang + ilang;
- std::copy(plang->rgchCode, plang->rgchCode + 4, lgcodeRet.rgch);
- return lgcodeRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the index of the language in the list.
-----------------------------------------------------------------------------------------------*/
-int GrLangTable::FindIndex(isocode lgcode)
-{
- if (m_clang == 0)
- return -1;
-#ifdef _DEBUG
- int nPowerOf2 = 1;
- while (nPowerOf2 <= signed(m_clang))
- nPowerOf2 <<= 1;
- nPowerOf2 >>= 1;
- // Now nPowerOf2 is the max power of 2 <= m_clang
- gAssert((1 << m_cLoop) == nPowerOf2); // m_cLoop == log2(nPowerOf2)
- gAssert(m_dilangInit == nPowerOf2);
- gAssert(m_ilangStart == m_clang - m_dilangInit);
-#endif // _DEBUG
-
- int dilangCurr = m_dilangInit;
-
- int ilangCurr = m_ilangStart; // may become < 0
- while (dilangCurr > 0)
- {
- int nTest;
- if (ilangCurr < 0)
- nTest = -1;
- else
- {
- LangEntry * plangCurr = m_prglang + ilangCurr;
- nTest = strcmp(plangCurr->rgchCode, lgcode.rgch);
- }
-
- if (nTest == 0)
- return ilangCurr;
-
- dilangCurr >>= 1; // divide by 2
- if (nTest < 0)
- ilangCurr += dilangCurr;
- else // (nTest > 0)
- ilangCurr -= dilangCurr;
- }
-
- return -1;
-}
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/GrFeatureValues.h b/Build/source/libs/graphite-engine/src/segment/GrFeatureValues.h
deleted file mode 100644
index de9eda0f03f..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrFeatureValues.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*--------------------------------------------------------------------*//*:Ignore this sentence.
-Copyright (C) 1999 - 2008 SIL International. All rights reserved.
-
-Distributable under the terms of either the Common Public License or the
-GNU Lesser General Public License, as specified in the LICENSING.txt file.
-
-File: GrFeatureValues.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
-
-
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef GR_FEATVAL_INCLUDED
-#define GR_FEATVAL_INCLUDED
-
-//:End Ignore
-
-namespace gr
-{
-
-/*----------------------------------------------------------------------------------------------
- A convenient way to group together style and feature information that interacts
- with the rules.
-
- Hungarian: fval
-----------------------------------------------------------------------------------------------*/
-class GrFeatureValues
-{
- friend class GrCharStream;
- friend class GrSlotAbstract;
- friend class GrSlotState;
-
-public:
- // Standard constructor:
- GrFeatureValues()
- {
- m_nStyleIndex = 0;
- std::fill(m_rgnFValues, m_rgnFValues + kMaxFeatures, 0);
- }
-
- // Copy constructor:
- GrFeatureValues(const GrFeatureValues & fval)
- {
- m_nStyleIndex = fval.m_nStyleIndex;
- std::copy(fval.m_rgnFValues, fval.m_rgnFValues + kMaxFeatures, m_rgnFValues);
- }
-
- bool FeatureValue(size_t ifeat)
- {
- return m_rgnFValues[ifeat];
- }
-
- // For transduction logging:
-#ifdef TRACING
- void WriteXductnLog(GrTableManager * ptman, std::ostream &);
-#endif // TRACING
-
-protected:
- int m_nStyleIndex;
- int m_rgnFValues[kMaxFeatures];
-};
-
-} // namespace gr
-
-
-#endif // !GR_FEATVAL_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/GrGlyphTable.cpp b/Build/source/libs/graphite-engine/src/segment/GrGlyphTable.cpp
deleted file mode 100644
index 8643eae8cb8..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrGlyphTable.cpp
+++ /dev/null
@@ -1,650 +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: GrGlyphTable.cpp
-Responsibility: Sharon Correll
-Last reviewed: 10Aug99, JT, quick look over
-
-Description:
- Implements the GrGlyphTable class and related classes.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Fill in the glyph table from the font stream.
-----------------------------------------------------------------------------------------------*/
-bool GrGlyphTable::ReadFromFont(GrIStream & grstrmGloc, long lGlocStart,
- GrIStream & grstrmGlat, long lGlatStart,
- data16 chwBWAttr, data16 chwJStrAttr, int cJLevels, int cnCompPerLig,
- int fxdSilfVersion)
-{
- // Create the glyph sub-table for the single style.
- GrGlyphSubTable * pgstbl = new GrGlyphSubTable();
-
- // Gloc table--offsets into Glat table
- grstrmGloc.SetPositionInFont(lGlocStart);
-
- // version
- int fxdGlocVersion = GrEngine::ReadVersion(grstrmGloc);
- if (fxdGlocVersion > kGlocVersion)
- return false;
-
- // flags
- short snFlags = grstrmGloc.ReadShortFromFont();
-
- // number of attributes
- unsigned short cAttrs = grstrmGloc.ReadUShortFromFont();
-
- // Create a single sub-table for the single style.
- pgstbl->Initialize(fxdSilfVersion, snFlags, chwBWAttr, chwJStrAttr, data16(chwJStrAttr + cJLevels),
- m_cglf, cAttrs, cnCompPerLig);
-
- SetSubTable(0, pgstbl);
-
- return pgstbl->ReadFromFont(grstrmGloc, m_cglf, grstrmGlat, lGlatStart);
-}
-
-bool GrGlyphSubTable::ReadFromFont(GrIStream & grstrmGloc, int cGlyphs,
- GrIStream & grstrmGlat, long lGlatStart)
-{
- // attribute value offsets--slurp
- if (m_fGlocShort)
- {
- grstrmGloc.ReadBlockFromFont(m_prgibBIGAttrValues, ((cGlyphs + 1) * sizeof(data16)));
- }
- else
- {
- grstrmGloc.ReadBlockFromFont(m_prgibBIGAttrValues, ((cGlyphs + 1) * sizeof(data32)));
- }
-
- // length of buffer needed for glyph attribute values:
- int cbBufLen = GlocLookup(data16(cGlyphs));
-
- // TODO: slurp debugger offsets: 'm_prgibBIGGlyphAttrDebug'
-
- m_pgatbl = new GrGlyphAttrTable();
- m_pgatbl->Initialize(m_fxdSilfVersion, cbBufLen);
-
- // Glat table
- grstrmGlat.SetPositionInFont(lGlatStart);
-
- // version
- int fxdGlatVersion = grstrmGlat.ReadIntFromFont();
- if (fxdGlatVersion > kGlatVersion)
- return false;
-
- // Back up over the version number and include it right in the attribute value entry
- // buffer, since the offsets take it into account.
- grstrmGlat.SetPositionInFont(lGlatStart);
-
- // Slurp the entire block of entries.
- grstrmGlat.ReadBlockFromFont(m_pgatbl->m_prgbBIGEntries, cbBufLen);
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Create an empty glyph table with no glyph attributes.
-----------------------------------------------------------------------------------------------*/
-void GrGlyphTable::CreateEmpty()
-{
- // Create the glyph sub-table for the single style.
- GrGlyphSubTable * pgstbl = new GrGlyphSubTable();
-
- // Create a single sub-table for the single style.
- pgstbl->Initialize(0, 0, 0, 0, 0, m_cglf, 0, 0);
-
- SetSubTable(0, pgstbl);
-
- pgstbl->CreateEmpty();
-}
-
-void GrGlyphSubTable::CreateEmpty()
-{
- m_pgatbl = new GrGlyphAttrTable();
- m_pgatbl->Initialize(0, 0);
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialization.
-----------------------------------------------------------------------------------------------*/
-void GrGlyphSubTable::Initialize(int fxdSilfVersion, utf16 chwFlags,
- data16 chwBWAttr, data16 chwJStrAttr, data16 chwJStrHWAttr,
- int cGlyphs, int cAttrs, int cnCompPerLig)
-{
- m_fxdSilfVersion = fxdSilfVersion;
- m_fHasDebugStrings = HasAttrNames(chwFlags);
- m_nAttrIDLim = cAttrs;
- m_chwBWAttr = chwBWAttr;
- m_chwJStrAttr = chwJStrAttr;
- m_chwJStrHWAttr = chwJStrHWAttr;
- m_fGlocShort = !LongFormat(chwFlags);
-
- if (m_fGlocShort)
- { // item # cGlyphs holds length, which is convenient for dealing with last item
- m_prgibBIGAttrValues = new byte[(cGlyphs + 1) * sizeof(data16)];
- }
- else
- {
- m_prgibBIGAttrValues = new byte[(cGlyphs + 1) * sizeof(data32)];
- }
-
-
- if (m_fHasDebugStrings)
- {
- m_prgibBIGGlyphAttrDebug = new data16[cAttrs + 1];
- }
-
- // Make a cache to hold a list of defined components for each glyph. This is
- // calculated lazily, as needed, so we also include (as the first item) a flag to
- // indicate whether or not it has been calculated; hence the "+1".
- m_cnCompPerLig = cnCompPerLig;
- m_prgnDefinedComponents = new int[(m_cnCompPerLig + 1) * cGlyphs];
- std::fill_n(m_prgnDefinedComponents, (m_cnCompPerLig + 1) * cGlyphs, 0);
-
- // Now the instance is ready to have the locations and the debug strings
- // read from the file.
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the attribute value for the given glyph.
-----------------------------------------------------------------------------------------------*/
-int GrGlyphSubTable::GlyphAttrValue(gid16 chwGlyphID, int nAttrID)
-{
- if (m_nAttrIDLim == 0)
- {
- // No attributes defined (eg, invalid font)
- return 0;
- }
- if (nAttrID >= m_nAttrIDLim || nAttrID >= 0xFF)
- {
- gAssert(false);
- return 0;
- }
- int ibMin = GlocLookup(chwGlyphID); // where this glyph's attrs start
- int ibLim = GlocLookup(chwGlyphID + 1); // where next glyph starts
-
- int nRet = m_pgatbl->GlyphAttr16BitValue(ibMin, ibLim, byte(nAttrID));
- if ((data16)nAttrID == m_chwJStrAttr)
- {
- // For justify.stretch, which can be a 32-bit value, add on the high word.
- unsigned int nRetHW = m_pgatbl->GlyphAttr16BitValue(ibMin, ibLim, byte(m_chwJStrHWAttr));
- nRet = (nRetHW << 16) | nRet;
- }
- return ConvertValueForVersion(nRet, nAttrID);
-}
-
-/*----------------------------------------------------------------------------------------------
- Convert the glyph attribute value from the version of the font table to what is
- expected by the engine.
-----------------------------------------------------------------------------------------------*/
-int GrGlyphSubTable::ConvertValueForVersion(int nValue, int nAttrID)
-{
- return ConvertValueForVersion(nValue, nAttrID, (int)m_chwBWAttr, m_fxdSilfVersion);
-}
-
-int GrGlyphSubTable::ConvertValueForVersion(int nValue, int nAttrID, int nBWAttr, int fxdVersion)
-{
- if ((nBWAttr >= 0 && nAttrID == (int)nBWAttr) ||
- (nBWAttr == -1 && nAttrID == (int)kslatBreak))
- {
- if (fxdVersion < 0x00020000)
- {
- //switch (nValue)
- //{
- //case klbv1WordBreak: return klbWordBreak;
- //case klbv1HyphenBreak: return klbHyphenBreak;
- //case klbv1LetterBreak: return klbLetterBreak;
- //case klbv1ClipBreak: return klbClipBreak;
- //default:
- // break;
- //}
- //switch (nValue * -1)
- //{
- //case klbv1WordBreak: return (klbWordBreak * -1);
- //case klbv1HyphenBreak: return (klbHyphenBreak * -1);
- //case klbv1LetterBreak: return (klbLetterBreak * -1);
- //case klbv1ClipBreak: return (klbClipBreak * -1);
- //default:
- // break;
- //}
-
- // Breakweight values in version 2 are 10 times what they were in version 1.
- if (abs(nValue) <= 7)
- return nValue * 10;
- }
- }
- return nValue;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the attribute value a glyph. Loop through the attribute runs, looking
- for the one containing the given attribute. Assume the value is 0 if not found.
-
- @param ibMin - byte offset of first run for the glyph of interest
- @param ibLim - byte offset of first run for the following glyph
- @param bAttrID - attribute to find
-----------------------------------------------------------------------------------------------*/
-int GrGlyphAttrTable::GlyphAttr16BitValue(int ibMin, int ibLim, byte bAttrID)
-{
- GrGlyphAttrRun gatrun;
- byte * pbBIGEnt = m_prgbBIGEntries + ibMin;
-
- while (pbBIGEnt < m_prgbBIGEntries + ibLim)
- {
- // Suck the run of attribute values into the instance, so we can see
- // what's there.
- gatrun.CopyFrom(pbBIGEnt);
-
- if (bAttrID < gatrun.m_bMinAttrID)
- // Attribute not found--assume value is 0.
- return 0;
- else if (gatrun.m_bMinAttrID + gatrun.m_cAttrs > bAttrID)
- {
- // Found the value in this run.
- data16 chw = lsbf(gatrun.m_rgchwBIGValues[bAttrID - gatrun.m_bMinAttrID]);
- if ((chw & 0x8000) == 0)
- return (int)chw;
- else
- return 0xFFFF0000 | chw; // sign extension
- }
- else
- // Go to next run.
- pbBIGEnt += gatrun.ByteCount();
- }
-
- // Attribute not found--assume value is 0;
- return 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Given a point on the glyph, determine which component (if any) the point is in, and return
- its index relative to the components that are defined for this glyph; ie, the index within
- the compRef array.
- Return -1 if the click with not inside any component, or if there are no components
- defined for this glyph.
- CURRENTLY NOT USED - if ever used, need to incorporate floating point
-----------------------------------------------------------------------------------------------*/
-int GrGlyphSubTable::ComponentContainingPoint(gid16 chwGlyphID, int x, int y)
-{
- int i = CalculateDefinedComponents(chwGlyphID);
- for (int inComp = 0; inComp < m_cnCompPerLig; inComp++)
- {
- // The m_pnComponents list holds a list of the component attributes that are defined
- // for this glyph, padded with -1's.
- int nCompID = m_prgnDefinedComponents[i + inComp];
- if (nCompID == -1)
- break; // hit the end of the list
-
- // The value of the component attribute is actually the attribute ID for the
- // first of the component box fields--the top. There should a contiguous group of
- // four fields: top, bottom, left, right.
- int nFieldIDMin = GlyphAttrValue(chwGlyphID, nCompID);
- gAssert(nFieldIDMin != 0);
- int nTop = GlyphAttrValue(chwGlyphID, nFieldIDMin);
- int nBottom = GlyphAttrValue(chwGlyphID, nFieldIDMin + 1);
- int nLeft = GlyphAttrValue(chwGlyphID, nFieldIDMin + 2);
- int nRight = GlyphAttrValue(chwGlyphID, nFieldIDMin + 3);
-
- if (nLeft <= x && x < nRight &&
- nBottom <= y && y < nTop)
- {
- return inComp;
- }
- }
- return -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- Fill in the box with the source-device coordinates corresponding to the given component.
- The rectangle is relative to the top-left of the glyph.
- Return false if the component is not defined.
-
- @param xysEmSquare - of the font, in logical units
- @param chwGlyphID - the glyph of interest
- @param icomp - the component of interest (eg, for the "oe" ligature,
- the index for component.o would be 0,
- and the index for component.e would be 1);
- these is as defined by the glyph, not as used in the rules
- @param mFontEmUnits - the number of em-units in the font, for scaling
- @param dysFontAscent - ascent of the font, for adjusting coordinate systems
- @param pxsLeft, pxsRight, pysTop, pysBottom
- - return values, in source device coordinates
- @param fTopOrigin - convert values to a coordinate system where the origin is the
- top of the line, not the baseline
-----------------------------------------------------------------------------------------------*/
-bool GrGlyphSubTable::ComponentBoxLogUnits(float xysEmSquare,
- gid16 chwGlyphID, int icomp, int mFontEmUnits, float dysFontAscent,
- float * pxsLeft, float * pysTop, float * pxsRight, float * pysBottom,
- bool fTopOrigin)
-{
- int i = CalculateDefinedComponents(chwGlyphID);
-
- // The m_pnComponents list holds a list of the component attributes that are defined
- // for this glyph, padded with -1's.
- int nCompID = m_prgnDefinedComponents[i + icomp];
- if (nCompID == -1)
- {
- // Ooops, the component is undefined for this glyph.
- *pxsLeft = 0;
- *pxsRight = 0;
- *pysTop = 0;
- *pysBottom = 0;
- return false;
- }
-
- // The value of the component attribute is actually the attribute ID for the
- // first of the component box fields--the top. There should a contiguous group of
- // four fields: top, bottom, left, right.
- int nFieldIDMin = GlyphAttrValue(chwGlyphID, nCompID);
- if (nFieldIDMin == 0)
- {
- // Component inadequately defined. This can happen when we defined components
- // for a glyph and then substituted another glyph for it.
- *pxsLeft = 0;
- *pxsRight = 0;
- *pysTop = 0;
- *pysBottom = 0;
- return false;
- }
- int mTop = GlyphAttrValue(chwGlyphID, nFieldIDMin);
- int mBottom = GlyphAttrValue(chwGlyphID, nFieldIDMin + 1);
- int mLeft = GlyphAttrValue(chwGlyphID, nFieldIDMin + 2);
- int mRight = GlyphAttrValue(chwGlyphID, nFieldIDMin + 3);
-
- ////int xysFontEmUnits;
- ////// ysHeight should correspond to the pixels in the font's em square
- ////GrResult res = pgg->GetFontEmSquare(&xysFontEmUnits);
- ////if (ResultFailed(res))
- //// return false;
-
- *pxsLeft = GrEngine::GrIFIMulDiv(mLeft, xysEmSquare, mFontEmUnits);
- *pxsRight = GrEngine::GrIFIMulDiv(mRight, xysEmSquare, mFontEmUnits);
- *pysTop = GrEngine::GrIFIMulDiv(mTop, xysEmSquare, mFontEmUnits);
- *pysBottom = GrEngine::GrIFIMulDiv(mBottom, xysEmSquare, mFontEmUnits);
-
- if (*pxsLeft > *pxsRight)
- {
- float xsTmp = *pxsLeft;
- *pxsLeft = *pxsRight;
- *pxsRight = xsTmp;
- }
- if (*pysTop < *pysBottom)
- {
- float ysTmp = *pysTop;
- *pysTop = *pysBottom;
- *pysBottom = ysTmp;
- }
-
- if (fTopOrigin)
- {
- // Currently top and bottom coordinates are such that 0 is the baseline and positive is
- // upwards, while for the box we want to return, 0 is the top of the glyph and positive
- // is downwards. So switch systems.
- *pysTop = (dysFontAscent - *pysTop);
- *pysBottom = (dysFontAscent - *pysBottom);
- }
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Calculate the list of defined components for the given glyph, if any.
- Return the index to the first relevant item in the array.
- Private.
- TODO: With the current implementation that stores the glyph ids in each slot, this
- mechanism is redundant and obsolete, and should be removed.
-----------------------------------------------------------------------------------------------*/
-int GrGlyphSubTable::CalculateDefinedComponents(gid16 chwGlyphID)
-{
- // The first item is a flag indicating whether the list has been calculated.
- int iFlag = chwGlyphID * (m_cnCompPerLig + 1); // index of has-been-calculated flag
- int iMin = iFlag + 1; // first actual value; +1 in order to skip the flag
- if (m_prgnDefinedComponents[iFlag] == 0)
- {
- int iTmp = iMin;
- for (int nCompID = 0; nCompID < m_cComponents; nCompID++)
- {
- if (ComponentIsDefined(chwGlyphID, nCompID))
- m_prgnDefinedComponents[iTmp++] = nCompID;
- if (iTmp - iMin >= m_cnCompPerLig)
- break; // ignore any components beyond the maximum allowed
- }
- // Fill in the rest of the list with -1.
- for( ; iTmp < iMin + m_cnCompPerLig; iTmp++)
- m_prgnDefinedComponents[iTmp] = -1;
-
- m_prgnDefinedComponents[iFlag] = 1; // has been calculated
- }
- return iMin;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if the given attr ID, which is a component definition attribute, indicates
- that that component is defined for the given glyph.
-
- @param chwGlyphID - the glyph of interest
- @param nAttrID - the attribute of interest, assumed to be a component glyph
- attribute (eg. component.e.top)
-----------------------------------------------------------------------------------------------*/
-bool GrGlyphSubTable::ComponentIsDefined(gid16 chwGlyphID, int nAttrID)
-{
- gAssert(nAttrID < m_cComponents);
- if (nAttrID >= m_cComponents)
- return false;
-
- return (GlyphAttrValue(chwGlyphID, nAttrID) != 0);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the index of the given component as defined for the given glyph ID. that is,
- convert the global ID for the component to the one within this glyph. Return -1
- if the component is not defined for the given glyph.
- For instance, given the glyph ID "oe" (the oe ligature) and the attr ID for component.o,
- the result would be 0; for component.e the result would be 1.
-----------------------------------------------------------------------------------------------*/
-int GrGlyphSubTable::ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID)
-{
- int i = CalculateDefinedComponents(chwGlyphID);
-
- for (int iLp = 0; iLp < m_cnCompPerLig; iLp++)
- {
- if (m_prgnDefinedComponents[i + iLp] == nCompID)
- return iLp;
- }
- return -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the ID of the nth defined component attribute for the given glyph.
-----------------------------------------------------------------------------------------------*/
-//int GrGlyphSubTable::NthComponentID(gid16 chwGlyphID, int n)
-//{
-// int i = CalculateDefinedComponents(chwGlyphID);
-// return m_pnComponents[i + 1 + n];
-//}
-
-
-//:>********************************************************************************************
-//:> For test procedures
-//:>********************************************************************************************
-
-//:Ignore
-#ifdef OLD_TEST_STUFF
-
-void GrGlyphTable::SetUpTestData()
-{
- SetNumberOfGlyphs(5);
- SetNumberOfStyles(1);
-
- GrGlyphSubTable * pgstbl = new GrGlyphSubTable();
- gAssert(pgstbl);
-
- pgstbl->Initialize(1, 0, 5, 10, 4);
- SetSubTable(0, pgstbl);
-
- pgstbl->SetUpTestData();
-}
-
-/***********************************************************************************************
- TODO: This method is BROKEN because m_prgibBIGAttrValues has been changed. It is no
- longer a utf16 *. The Gloc table can contain 16-bit or 32-bit entries and must be
- accessed accordingly.
-***********************************************************************************************/
-void GrGlyphSubTable::SetUpTestData()
-{
- m_pgatbl = new GrGlyphAttrTable();
- m_pgatbl->Initialize(0, 48);
-
- m_prgibBIGAttrValues[0] = byte(msbf(data16(0)));
- m_prgibBIGAttrValues[1] = byte(msbf(data16(6))));
- m_prgibBIGAttrValues[2] = byte(msbf(data16(20)));
- m_prgibBIGAttrValues[3] = byte(msbf(data16(20)));
- m_prgibBIGAttrValues[4] = byte(msbf(data16(40)));
- m_prgibBIGAttrValues[5] = byte(msbf(data16(48)));
-
- m_pgatbl->SetUpTestData();
-}
-
-void GrGlyphAttrTable::SetUpTestData()
-{
- // Glyph 0 (1 run; offset = 0):
- // 1 = 11 = 0x0B
- // 2 = 22 = 0x16
- // 0102 000B 0016
- //
- // Glyph 1 (2 runs; offset = 3*2 = 6):
- // 0 = 5
- // 1 = 6
- // 2 = 7
- // 8 = 8
- // 9 = 9
- // 0003 0005 0006 0007
- // 0802 0008 0009
- //
- // Glyph 2 (0 runs; offset = 6 + 7*2 = 20):
- // all values = 0
- //
- // Glyph 3 (5 runs; offset = 20):
- // 1 = 111 = 0x006F
- // 3 = 333 = 0x00DE
- // 5 = 555 = 0x022B
- // 7 = 777 = 0x0309
- // 9 = 999 = 0x03E7
- // 0101 006F
- // 0301 00DE
- // 0501 022B
- // 0701 0309
- // 0901 03E7
- //
- // Glyph 4 (1 run; offset = 20 + 10*2 = 40):
- // 5 = 4
- // 6 = 4
- // 7 = 4
- // 0503 0004 0004 0004
- //
- // Glyph 5 (offset = 40 + 4*2 = 48)
-
- byte * pbBIG = m_prgbBIGEntries;
-
- GrGlyphAttrRun gatrun;
-
- // Glyph 0
- gatrun.m_bMinAttrID = 1;
- gatrun.m_cAttrs = 2;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(11));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(22));
- memcpy(pbBIG, &gatrun, 6);
- pbBIG += 6;
-
- // Glyph 1
- gatrun.m_bMinAttrID = 0;
- gatrun.m_cAttrs = 3;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(5));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(6));
- gatrun.m_rgchwBIGValues[2] = msbf(data16(7));
- memcpy(pbBIG, &gatrun, 8);
- pbBIG += 8;
- gatrun.m_bMinAttrID = 8;
- gatrun.m_cAttrs = 2;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(8));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(9));
- memcpy(pbBIG, &gatrun, 6);
- pbBIG += 6;
-
- // Glyph 2: no data
-
- // Glyph 3
- gatrun.m_bMinAttrID = 1;
- gatrun.m_cAttrs = 1;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(111));
- memcpy(pbBIG, &gatrun, 4);
- pbBIG += 4;
- gatrun.m_bMinAttrID = 3;
- gatrun.m_cAttrs = 1;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(333));
- memcpy(pbBIG, &gatrun, 4);
- pbBIG += 4;
- gatrun.m_bMinAttrID = 5;
- gatrun.m_cAttrs = 1;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(555));
- memcpy(pbBIG, &gatrun, 4);
- pbBIG += 4;
- gatrun.m_bMinAttrID = 7;
- gatrun.m_cAttrs = 1;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(777));
- memcpy(pbBIG, &gatrun, 4);
- pbBIG += 4;
- gatrun.m_bMinAttrID = 9;
- gatrun.m_cAttrs = 1;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(999));
- memcpy(pbBIG, &gatrun, 4);
- pbBIG += 4;
-
- // Glyph 4
- gatrun.m_bMinAttrID = 5;
- gatrun.m_cAttrs = 3;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(4));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(4));
- gatrun.m_rgchwBIGValues[2] = msbf(data16(4));
- memcpy(pbBIG, &gatrun, 8);
- pbBIG += 8;
-
- gAssert(pbBIG == m_prgbBIGEntries + 48);
-}
-
-#endif // OLD_TEST_STUFF
-
-} // namespace gr
-
-//:End Ignore
diff --git a/Build/source/libs/graphite-engine/src/segment/GrGlyphTable.h b/Build/source/libs/graphite-engine/src/segment/GrGlyphTable.h
deleted file mode 100644
index bec0e518dee..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrGlyphTable.h
+++ /dev/null
@@ -1,429 +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: GrGlyphTable.h
-Responsibility: Sharon Correll
-Last reviewed: 10Aug99, JT, quick look over
-
-Description:
- The GrGlyphTable and related classes that store the values of glyph attributes.
-
- For each glyph in a TrueType font, Graphite has a list of glyph attributes (which
- are defined in the GDL script file). Since most of the values will be zero, we save space
- by only storing the non-zero values.
-
- Eventually it may be possible to have more than one TrueType font compiled into a single
- glyph table, hence the need for multiple sub-tables. For now we assume that there is only
- one font file and only one sub-table.
-
- Note that BIG in a variable name means that the data is in big-endian format, or is a range
- of bytes that must be interpreted as a run of wide chars or ints in big-endian format.
--------------------------------------------------------------------------------*//*:End Ignore*/
-
-//:Ignore
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef GR_GTABLE_INCLUDED
-#define GR_GTABLE_INCLUDED
-//:End Ignore
-
-namespace gr
-{
-
-class Font;
-
-/*----------------------------------------------------------------------------------------------
- A run of non-zero attribute values for a single glyph, where the attribute IDs
- are contiguous.
-
- NOTE: it is assumed that the format of this class matches the byte order of the data as it
- is read directly from the TTF/ECF file--that is, it is big-endian.
-
- Hungarian: gatrun
-----------------------------------------------------------------------------------------------*/
-
-class GrGlyphAttrRun
-{
- friend class GrGlyphTable;
- friend class GrGlyphSubTable;
- friend class GrGlyphAttrTable;
-
- enum {
- kMaxAttrsPerRun = 255
- };
-
- /*------------------------------------------------------------------------------------------
- Copy the raw memory (starting at the given byte) into the instance. This method must
- reflect the format of the "Glat_entry" as it is stored in the file and slurped into
- memory.
- ------------------------------------------------------------------------------------------*/
- void CopyFrom(byte * pbBIGEnt)
- {
- m_bMinAttrID = *pbBIGEnt;
- m_cAttrs = *(pbBIGEnt + 1);
- if (m_cAttrs >= kMaxAttrsPerRun)
- {
- gAssert(false);
- m_cAttrs = kMaxAttrsPerRun;
- }
- #ifdef _DEBUG
- // Probably not strictly necessary to zero the array, but convenient for debugging.
- // Removed from release build for optimization
- std::fill(m_rgchwBIGValues, m_rgchwBIGValues + kMaxAttrsPerRun, 0);
- #endif
- // this is mixing types of data16 and byte pointers!
- const data16 * prgchw = reinterpret_cast<const data16*>(pbBIGEnt + 2);
- std::copy(prgchw, prgchw + m_cAttrs, m_rgchwBIGValues);
- }
-
- int ByteCount()
- {
- return (2 + (m_cAttrs * isizeof(data16)));
- }
-
-protected:
- byte m_bMinAttrID; // ID of first attribute in the run
- byte m_cAttrs; // number of attributes in the run
- data16 m_rgchwBIGValues[kMaxAttrsPerRun];
-};
-
-/*----------------------------------------------------------------------------------------------
- Contains runs of attribute values for all the glyphs in the font; corresponds to
- the "Glat" table in the font.
-
- Hungarian: gatbl
-----------------------------------------------------------------------------------------------*/
-
-class GrGlyphAttrTable
-{
- friend class GrGlyphTable;
- friend class GrGlyphSubTable;
- friend class FontMemoryUsage;
-
-protected:
- // Constructor:
- GrGlyphAttrTable()
- {
- m_prgbBIGEntries = NULL;
- }
-
- // Destructor:
- ~GrGlyphAttrTable()
- {
- delete[] m_prgbBIGEntries;
- }
-
- // Initialization:
- void Initialize(int fxdSilfVersion, int cbBufLen)
- {
- m_fxdSilfVersion = fxdSilfVersion;
- m_cbEntryBufLen = cbBufLen;
- m_prgbBIGEntries = new byte[cbBufLen];
- // Now the instance is ready to have all the glyph attr entries slurped into
- // the byte array from the file.
- }
-
- int GlyphAttr16BitValue(int ibMin, int ibLim, byte bAttrID);
-
-protected:
- int m_fxdSilfVersion; // version number of the Silf table, which is used
- // to interpret the attribute values
-
- // Block of variable-length glyph attribute runs, matching the format of
- // GrGlyphAttrRun. We don't store instances of that class here because they
- // are variable length, and it would be too slow to read them individually from the
- // font. Instead, we set up a single instance in the method that accesses the values;
- // having this instance will help debugging. Eventually we may want to do without it,
- // if it would help efficiency.
- int m_cbEntryBufLen; // needed only for memory instrumentation
- byte * m_prgbBIGEntries;
-
-//:Ignore
-#ifdef OLD_TEST_STUFF
-public:
- // For test procedures:
- void SetUpTestData();
- void SetUpLigatureTest();
- void SetUpLigature2Test();
-#endif // OLD_TEST_STUFF
-
-//:End Ignore
-
-};
-
-/*----------------------------------------------------------------------------------------------
- One glyph table per font (style) file; corresponds to the "Gloc" table in the font.
- Currently there is only considered to be one style per file, so there is only one of
- these. It holds the (non-zero) glyph attribute values for every glyph in the font.
-
- Hungarian: gstbl
-
- Review: Eventually we may need to make a subclass that uses 32-bit values for the offsets,
- or just use a separate array pointer in this class. Which would be preferable?
-----------------------------------------------------------------------------------------------*/
-
-class GrGlyphSubTable
-{
- friend class GrGlyphTable;
- friend class FontMemoryUsage;
-
-public:
- // Constructor:
- GrGlyphSubTable() :
- m_pgatbl(NULL),
- m_prgibBIGAttrValues(NULL),
- m_prgibBIGGlyphAttrDebug(NULL),
- m_prgnDefinedComponents(NULL)
- {
- }
- // Destructor:
- ~GrGlyphSubTable()
- {
- delete m_pgatbl;
- delete[] m_prgibBIGAttrValues;
- if (m_fHasDebugStrings)
- delete[] m_prgibBIGGlyphAttrDebug;
- delete[] m_prgnDefinedComponents;
- }
-
- // Initialization:
- bool ReadFromFont(GrIStream & gloc_strm, int cGlyphs,
- GrIStream & glat_strm, long lGlatStart);
- void Initialize(int fxdSilfVersion, data16 chwFlags,
- data16 chwBWAttr, data16 chwJStrAttr, data16 chwJStrHWAttr,
- int cGlyphs, int cAttrs, int cnCompPerLig);
-
- void CreateEmpty();
-
- void SetNumberOfComponents(int c)
- {
- m_cComponents = c;
- }
-
- // General:
- int NumberOfGlyphAttrs() { return m_nAttrIDLim; } // 0..(m_nAttrIDLim-1)
-
- int GlyphAttrValue(gid16 chwGlyphID, int nAttrID);
-
- // Ligatures:
- int ComponentContainingPoint(gid16 chwGlyphID, int x, int y);
- bool ComponentBoxLogUnits(float xysEmSquare, gid16 chwGlyphID, int icomp,
- int mFontEmUnits, float dysAscent,
- float * pxsLeft, float * pysTop, float * pxsRight, float * pysBottom,
- bool fTopOrigin = true);
-protected:
- int CalculateDefinedComponents(gid16 chwGlyphID);
- bool ComponentIsDefined(gid16 chwGlyphID, int nAttrID);
- int ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID);
-// int NthComponentID(gid16 chwGlyphID, int n);
- int ConvertValueForVersion(int nRet, int nAttrID);
-
-public:
- static int ConvertValueForVersion(int nRet, int nAttrID, int nBWAttr, int fxdVersion);
-
- // Flags:
- bool LongFormat(data16 chwFlags) // 32-bit values?
- {
- return ((chwFlags & 0x01) == 0x01); // bit 0
- }
- bool HasAttrNames(data16 chwFlags)
- {
- return ((chwFlags & 0x02) == 0x02); // bit 1
- }
- int GlocLookup(data16 chwGlyphId)
- {
- if (m_fGlocShort)
- {
- unsigned short su = ((unsigned short *)m_prgibBIGAttrValues)[chwGlyphId];
- return lsbf(su);
- }
- else
- { unsigned int u = ((unsigned int *)m_prgibBIGAttrValues)[chwGlyphId];
- return lsbf((int)u);
- }
- }
-
-protected:
- int m_fxdSilfVersion; // version number of the Silf table, which is used
- // to interpret the attribute values
- bool m_fHasDebugStrings; // are debugging strings loaded into memory?
-
- int m_nAttrIDLim; // number of glyph attributes
- int m_cComponents; // number of initial glyph attributes that
- // represent ligature components
- int m_cnCompPerLig;
-
- GrGlyphAttrTable * m_pgatbl;
- byte * m_prgibBIGAttrValues; // byte offsets for glyph attr values - BIG endian
- bool m_fGlocShort; // flag for Gloc table format
- data16 * m_prgibBIGGlyphAttrDebug; // byte offsets for glyph attr debug strings - BIG endian
-
- data16 m_chwBWAttr; // breakweight attr ID; needed for converting
- // between versions
-
- // Attr IDs for justify.0.stretch and justify.0.stretchHW; these must always be looked
- // up in tandem.
- data16 m_chwJStrAttr;
- data16 m_chwJStrHWAttr;
-
- int * m_prgnDefinedComponents; // for each glyph, cache list of component attributes that
- // are defined
-
-//:Ignore
-#ifdef OLD_TEST_STUFF
-public:
- // For test procedures:
- void SetUpTestData();
- void SetUpLigatureTest();
- void SetUpLigature2Test();
-#endif // OLD_TEST_STUFF
-
-//:End Ignore
-};
-
-/*----------------------------------------------------------------------------------------------
- Holds all the information about glyph attributes.
-
- Hungarian: gtbl
-----------------------------------------------------------------------------------------------*/
-
-class GrGlyphTable
-{
- friend class GrGlyphSubTable;
- friend class FontMemoryUsage;
-
-public:
- // Constructor:
- GrGlyphTable()
- {
- m_cglf = 0;
- m_cComponents = 0;
- m_cgstbl = 0;
- m_vpgstbl.clear();
- }
-
- // Destructor:
- ~GrGlyphTable()
- {
- for (int i = 0; i < m_cgstbl; ++i)
- delete m_vpgstbl[i];
- }
-
- bool ReadFromFont(GrIStream & gloc_strm, long lGlocStart,
- GrIStream & glat_strm, long lGlatStart,
- data16 chwBWAttr, data16 chwJStrAttr, int cJLevels, int cnCompPerLig,
- int fxdSilfVersion);
-
- void CreateEmpty();
-
- // Setters:
- void SetNumberOfGlyphs(int c)
- {
- m_cglf = c;
- }
- void SetNumberOfStyles(int c)
- {
- m_cgstbl = c;
- m_vpgstbl.resize(c);
- }
- void SetNumberOfComponents(int c)
- {
- m_cComponents = c;
- for (unsigned int ipgstbl = 0; ipgstbl < m_vpgstbl.size(); ipgstbl++)
- m_vpgstbl[ipgstbl]->SetNumberOfComponents(c);
- }
- void SetSubTable(int i, GrGlyphSubTable * pgstbl)
- {
- if (signed(m_vpgstbl.size()) <= i)
- {
- gAssert(false);
- m_vpgstbl.resize(i+1);
- }
- m_vpgstbl[i] = pgstbl;
- m_vpgstbl[i]->SetNumberOfComponents(m_cComponents);
- }
-
- // Getters:
- int NumberOfGlyphs() { return m_cglf; }
- int NumberOfStyles() { return m_cgstbl; }
-
- int NumberOfGlyphAttrs()
- {
- // All of the sub-tables should have the same number of glyph attributes,
- // so just ask the first.
- return m_vpgstbl[0]->NumberOfGlyphAttrs();
- }
-
- int GlyphAttrValue(gid16 chwGlyphID, int nAttrID)
- {
- gAssert(m_cgstbl == 1);
- return m_vpgstbl[0]->GlyphAttrValue(chwGlyphID, nAttrID);
- }
- // Eventually:
- //int GlyphAttrValue(gid16 chwGlyphID, int nAttrID, int nStyleIndex)
- //{
- // return m_vpgstbl[nStyleIndex]->GlyphAttrValue(chwGlyphID, nAttrID);
- //}
-
- int ComponentContainingPoint(gid16 chwGlyphID, int x, int y)
- {
- gAssert(m_cgstbl == 1);
- return m_vpgstbl[0]->ComponentContainingPoint(chwGlyphID, x, y);
- }
- // Eventually:
- //int ComponentContainingPoint(gid16 chwGlyphID, int nStyleIndex, int x, int y)
- //{
- // gAssert(m_cgstbl == 1);
- // return m_vpgstbl[nStyleIndex]->ComponentContainingPoint(chwGlyphID, nAttrID);
- //}
-
- bool ComponentBoxLogUnits(float xysEmSquare, gid16 chwGlyphID, int icomp,
- int mFontEmUnits, float dysAscent,
- float * pxsLeft, float * pysTop, float * pxsRight, float * pysBottom,
- bool fTopOrigin = true)
- {
- gAssert(m_cgstbl == 1);
- return m_vpgstbl[0]->ComponentBoxLogUnits(xysEmSquare,
- chwGlyphID, icomp, mFontEmUnits, dysAscent,
- pxsLeft, pysTop, pxsRight, pysBottom,
- fTopOrigin);
- }
-
- int ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID)
- {
- gAssert(m_cgstbl == 1);
- return m_vpgstbl[0]->ComponentIndexForGlyph(chwGlyphID, nCompID);
- }
-
- bool IsEmpty()
- {
- return (m_cglf == 0);
- }
-
-protected:
- int m_cglf; // number of glyphs
- int m_cComponents; // number of defined components
- int m_cgstbl; // number of sub-tables, corresponding to font files;
- // for now there is only one
-
- std::vector<GrGlyphSubTable *> m_vpgstbl;
-
-//:Ignore
-#ifdef OLD_TEST_STUFF
-public:
- // For test procedures:
- void SetUpTestData();
- void SetUpLigatureTest();
- void SetUpLigature2Test();
-#endif // OLD_TEST_STUFF
-//:End Ignore
-
-};
-
-} // namespace gr
-
-#endif // !GR_GTABLE_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/GrPass.cpp b/Build/source/libs/graphite-engine/src/segment/GrPass.cpp
deleted file mode 100644
index 26eb3a3deb6..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrPass.cpp
+++ /dev/null
@@ -1,1995 +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: GrPass.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Implements the GrPass class and subclasses.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-/*----------------------------------------------------------------------------------------------
- Constructors and initializers
-----------------------------------------------------------------------------------------------*/
-GrPass::GrPass(int i)
- : m_ipass(i),
- m_fxdVersion(0),
- m_nMaxRuleContext(0),
- m_pfsm(NULL),
- m_nMaxRuleLoop(0),
- m_nMaxBackup(0),
- m_crul(0),
- m_prgchwRuleSortKeys(NULL),
- m_prgcritRulePreModContext(NULL),
- m_cbPassConstraint(0),
- m_prgibConstraintStart(NULL),
- m_prgibActionStart(NULL),
- m_prgbPConstraintBlock(NULL),
- m_prgbConstraintBlock(NULL),
- m_prgbActionBlock(NULL),
- m_cbConstraints(0),
- m_cbActions(0),
- m_prgibConstraintDebug(NULL),
- m_prgibRuleDebug(NULL),
- m_fCheckRules(false),
- m_prgfRuleOkay(NULL),
- m_vnStack(128),
- m_pzpst(NULL)
-{
-}
-
-void PassState::InitForNewSegment(int ipass, int nMaxChunk)
-{
- m_ipass = ipass;
- m_nRulesSinceAdvance = 0;
- m_nMaxChunk = nMaxChunk;
- m_cslotSkipToResync = 0;
- m_fDidResyncSkip = false;
- InitializeLogInfo();
-}
-
-void PassState::InitializeLogInfo()
-{
- m_crulrec = 0;
- std::fill_n(m_rgcslotDeletions, 128, 0);
- std::fill_n(m_rgfInsertion, 128, false);
-}
-
-/*----------------------------------------------------------------------------------------------
- Destructors
-----------------------------------------------------------------------------------------------*/
-GrPass::~GrPass()
-{
- delete m_pfsm;
-
- delete[] m_prgchwRuleSortKeys;
-
- delete[] m_prgcritRulePreModContext;
-
- delete[] m_prgibConstraintStart;
- delete[] m_prgibActionStart;
-
- delete[] m_prgbPConstraintBlock;
- delete[] m_prgbConstraintBlock;
- delete[] m_prgbActionBlock;
-
- delete[] m_prgfRuleOkay;
-
- delete[] m_prgibConstraintDebug;
- delete[] m_prgibRuleDebug;
-}
-
-/*----------------------------------------------------------------------------------------------
- Fill in the pass by reading from the font stream.
-----------------------------------------------------------------------------------------------*/
-bool GrPass::ReadFromFont(GrIStream & grstrm, int fxdSilfVersion, int fxdRuleVersion,
- int nOffset)
-{
- long lPassInfoStart;
- grstrm.GetPositionInFont(&lPassInfoStart);
-
- m_fxdVersion = fxdSilfVersion;
-
- m_fCheckRules = (fxdRuleVersion > kRuleVersion);
-
-// Assert(nOffset == lPassInfoStart);
- if (lPassInfoStart != nOffset)
- {
- grstrm.SetPositionInFont(nOffset);
- }
-
- // flags - ignore for now
- //byte bTmp = grstrm.ReadByteFromFont();
- grstrm.ReadByteFromFont();
-
- // MaxRuleLoop
- m_nMaxRuleLoop = grstrm.ReadByteFromFont();
-
- // max rule context
- m_nMaxRuleContext = grstrm.ReadByteFromFont();
-
- // MaxBackup
- m_nMaxBackup = grstrm.ReadByteFromFont();
-
- // number of rules
- m_crul = grstrm.ReadShortFromFont();
- // TODO: add a sanity check for the number of rules.
-
- // offset to pass constraint code, relative to start of subtable
- int nPConstraintOffset = 0;
- long lFsmPos = -1;
- if (fxdSilfVersion >= 0x00020000)
- {
- if (fxdSilfVersion >= 0x00030000)
- lFsmPos = grstrm.ReadUShortFromFont() + nOffset; // offset to row info
- else
- grstrm.ReadShortFromFont(); // pad bytes
- nPConstraintOffset = grstrm.ReadIntFromFont();
- }
- // offset to rule constraint code, relative to start of subtable
- //int nConstraintOffset = grstrm.ReadIntFromFont();
- grstrm.ReadIntFromFont();
- // offset to action code, relative to start of subtable
- //int nActionOffset = grstrm.ReadIntFromFont();
- grstrm.ReadIntFromFont();
- // offset to debug strings; 0 if stripped
- //int nDebugOffset = grstrm.ReadIntFromFont();
- grstrm.ReadIntFromFont();
-
- // Jump to beginning of FSM, if we have this information.
- if (fxdSilfVersion >= 0x00030000)
- grstrm.SetPositionInFont(lFsmPos);
- else
- // Otherwise assume that's where we are!
- Assert(lFsmPos == -1);
-
- m_pfsm = new GrFSM();
-
- m_pfsm->ReadFromFont(grstrm, fxdSilfVersion);
-
- // rule sort keys
- m_prgchwRuleSortKeys = new data16[m_crul];
- data16 * pchw = m_prgchwRuleSortKeys;
- int irul;
- for (irul = 0; irul < m_crul; irul++, pchw++)
- {
- *pchw = grstrm.ReadUShortFromFont();
- }
-
- // rule pre-mod-context item counts
- m_prgcritRulePreModContext = new byte[m_crul];
- byte * pb = m_prgcritRulePreModContext;
- for (irul = 0; irul < m_crul; irul++, pb++)
- {
- *pb = grstrm.ReadByteFromFont();
- }
-
- // constraint offset for pass-level constraints
- if (fxdSilfVersion >= 0x00020000)
- {
- // reserved - pad byte
- grstrm.ReadByteFromFont();
- // Note: pass constraints have not been fully implemented.
- m_cbPassConstraint = grstrm.ReadUShortFromFont();
- }
- else
- m_cbPassConstraint = 0;
-
- // constraint and action offsets for rules
- m_prgibConstraintStart = new data16[m_crul + 1];
- pchw = m_prgibConstraintStart;
- for (irul = 0; irul <= m_crul; irul++, pchw++)
- {
- *pchw = grstrm.ReadUShortFromFont();
- }
-
- m_prgibActionStart = new data16[m_crul + 1];
- pchw = m_prgibActionStart;
- for (irul = 0; irul <= m_crul; irul++, pchw++)
- {
- *pchw = grstrm.ReadUShortFromFont();
- }
-
- // FSM state table
- m_pfsm->ReadStateTableFromFont(grstrm, fxdSilfVersion);
-
- if (fxdSilfVersion >= 0x00020000)
- // reserved - pad byte
- grstrm.ReadByteFromFont();
-
- // Constraint and action blocks
- int cb = m_cbPassConstraint;
- m_prgbPConstraintBlock = new byte[cb];
- grstrm.ReadBlockFromFont(m_prgbPConstraintBlock, cb);
- m_cbConstraints = cb;
-
- cb = m_prgibConstraintStart[m_crul];
- m_prgbConstraintBlock = new byte[cb];
- grstrm.ReadBlockFromFont(m_prgbConstraintBlock, cb);
- m_cbConstraints += cb;
-
- cb = m_prgibActionStart[m_crul];
- m_prgbActionBlock = new byte[cb];
- grstrm.ReadBlockFromFont(m_prgbActionBlock, cb);
- m_cbActions = cb;
-
- // Rule-validity flags
- m_prgfRuleOkay = new bool[m_crul];
- for (irul = 0; irul < m_crul; irul++)
- m_prgfRuleOkay[irul] = !m_fCheckRules;
-
- // TODO SharonC/AlanW: debuggers
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize a bogus pass with no rules. Currently this is used to make a single positioning
- pass if there was none in the font.
-----------------------------------------------------------------------------------------------*/
-void GrPass::InitializeWithNoRules()
-{
- m_crul = 0;
- m_nMaxRuleContext = 1;
- m_nMaxRuleLoop = 1;
- m_nMaxBackup = 0;
- m_pfsm = NULL;
- m_prgchwRuleSortKeys = NULL;
- m_prgcritRulePreModContext = NULL;
-}
-
-/*----------------------------------------------------------------------------------------------
- Extend the output stream by the given number of characters.
- (Overridden by GrBidiPass.)
-
- @param ptman - table manager
- @param psstrmIn/Out - streams being processed
- @param cslotNeededByNext - the number of slots being requested by the following pass
- @param twsh - how we are handling trailing white-space
- @param pnRet - return value
- @param pcslotGot - return the number of slots gotten
- @param pislotFinalBreak - return the index of the final slot, when we are removing
- the trailing white-space and so the end of the segment
- will be before the any actual line-break slot
-
- @return kNextPass if we were able to generated the number requested, or processing is
- complete; otherwise return the number of slots needed from the previous pass.
-----------------------------------------------------------------------------------------------*/
-void GrPass::ExtendOutput(GrTableManager * ptman,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int cslotNeededByNext, TrWsHandling twsh,
- int * pnRet, int * pcslotGot, int * pislotFinalBreak)
-{
- // Kludge to generate an error in rendering:
- //int z = 50;
- //int t = ((5 * 10) / z) - 1;
- //if (this->m_ipass == 4)
- //{
- // int x; x = z / t;
- //}
-
- int islotInitReadPos = psstrmIn->ReadPos();
- int islotInitWritePos = psstrmOut->WritePos();
-
- int cslotToGet = max(cslotNeededByNext,
- m_pzpst->NeededToResync() - psstrmOut->WritePos());
- int cslotGot = 0;
-
- gid16 chwLB = ptman->LBGlyphID();
-
- // While we haven't got the number of slot we've been asked for, and there is enough
- // available in the input, run rules, filling up the output.
-
- while ((cslotToGet > 0 && cslotGot < cslotToGet)
- // Don't leave this pass until we've got the index offset. This is especially
- // needed for input to the positioning pass, but it doesn't hurt to make it a
- // general rule.
- || !psstrmOut->GotIndexOffset()
- // Don't leave this pass until all the slots to reprocess have been
- // completely handled.
- || (psstrmIn->SlotsToReprocess() > 0)
- // Don't leave this pass until there is a complete cluster in the output
- || (islotInitWritePos == psstrmOut->WritePos())
- || (psstrmOut->MaxClusterSlot(islotInitWritePos, psstrmOut->WritePos()) > 0))
- {
- int cslotAvailable = psstrmIn->TotalSlotsPending();
- int cslotNeedMore = MaxRuleContext() - cslotAvailable + ptman->PrevPassMaxBackup(m_ipass);
-
- // This test should not be necessary, but just in case.
- if (psstrmIn->PastEndOfPositioning(false))
- cslotNeedMore = 0; // the input stream is done
-
- if (// Not enough available in the input:
- (cslotNeedMore > 0 && !psstrmIn->FullyWritten())
-
- // && psstrmIn->SegLimIfKnown() == -1) && -- no, because substitution passes may need
- // to consider slots beyond the seg limit
-
- // Positioning passes need to know where they are in relation to the initial
- // line-break.
- || (IsPosPass() && !psstrmIn->GotIndexOffset())
-
- // The following can happen on backtracking, when we undo stuff before the
- // beginning of the segment:
- || !ptman->Pass(m_ipass - 1)->DidResyncSkip())
- {
- // Ask previous pass for more input.
- *pnRet = max(cslotNeedMore, 1);
- *pnRet = max(*pnRet, cslotNeededByNext - cslotGot);
- *pcslotGot = cslotGot;
- return;
- }
-
- Assert(ptman->Pass(m_ipass - 1)->DidResyncSkip());
-
- bool fDoneThisPass = (cslotAvailable == 0);
- if (psstrmIn->SlotsToReprocess() == 0)
- {
- fDoneThisPass = fDoneThisPass ||
- psstrmIn->PastEndOfPositioning(false) ||
- psstrmOut->PastEndOfPositioning(true);
- }
-
- if (fDoneThisPass)
- {
- // No more input to process--this pass is done.
- Assert(psstrmIn->SlotsToReprocess() == 0);
- psstrmIn->ClearReprocBuffer();
-
- if (twsh == ktwshNoWs && m_ipass == ptman->NumberOfLbPasses())
- {
- *pnRet = RemoveTrailingWhiteSpace(ptman, psstrmOut, twsh, pislotFinalBreak);
- if (*pnRet == kBacktrack) // entire segment was white-space:
- return; // backtrack, which will fail
- }
- DoResyncSkip(psstrmOut);
- DoCleanUpSegMin(ptman, psstrmIn, islotInitReadPos, psstrmOut);
- psstrmOut->MarkFullyWritten();
- *pnRet = kNextPass;
- *pcslotGot = cslotGot;
- return;
- }
-
- if (twsh == ktwshOnlyWs && m_ipass == ptman->NumberOfLbPasses() + 1)
- {
- // Note that this is the first pass after the linebreak pass, so psstrmInput
- // is the output of the linebreak pass.
- GrSlotState * pslotNext = psstrmIn->Peek();
- if (!pslotNext->IsLineBreak(chwLB) &&
- pslotNext->Directionality() != kdircWhiteSpace &&
- psstrmIn->SegMin() > -1 && psstrmIn->SegMin() <= psstrmIn->ReadPos())
- {
- // We are only allowing white-space in this segment and we hit
- // something else. Don't process any further.
- if (psstrmIn->SegLimIfKnown() > -1 &&
- psstrmIn->SegLimIfKnown() <= psstrmIn->ReadPos())
- {
- // Already inserted a line-break; we're done.
- DoResyncSkip(psstrmOut);
- psstrmOut->MarkFullyWritten();
- *pnRet = kNextPass;
- *pcslotGot = cslotGot;
- return;
- }
- while (psstrmIn->SlotsToReprocess() > 0)
- {
- psstrmOut->CopyOneSlotFrom(psstrmIn);
- psstrmOut->SetPosForNextRule(0, psstrmIn, IsPosPass());
- }
- psstrmIn->ClearReprocBuffer();
- *pnRet = kBacktrack;
- return;
- }
- }
-
- // Otherwise, we have enough input to run a rule.
-
- psstrmIn->SetRuleStartReadPos();
- psstrmOut->SetRuleStartWritePos();
-
- int ruln = -1;
- if (m_pfsm)
- ruln = m_pfsm->GetRuleToApply(ptman, this, psstrmIn, psstrmOut);
- ruln = CheckRuleValidity(ruln);
- RunRule(ptman, ruln, psstrmIn, psstrmOut);
-
- cslotGot = psstrmOut->WritePos() - islotInitWritePos;
- psstrmOut->CalcIndexOffset(ptman);
- }
-
- DoResyncSkip(psstrmOut);
- DoCleanUpSegMin(ptman, psstrmIn, islotInitReadPos, psstrmOut);
-
- // We're past the point where we care about anything in the reprocessing buffer.
- Assert(psstrmIn->NoReproc());
- psstrmIn->ClearReprocBuffer();
-
- if (psstrmOut->PastEndOfPositioning(true))
- psstrmOut->MarkFullyWritten();
-
- *pnRet = kNextPass;
- *pcslotGot = cslotGot;
-}
-
-/*----------------------------------------------------------------------------------------------
- Extend the output stream by the given number of characters.
- For a GrBidiPass, if we are at a direction change, get the entire
- range of upstream glyphs, reverse them, and treat them as one chunk.
- Otherwise just pass one slot through.
-
- @param ptman - table manager
- @param psstrmInput/Output - streams being processed
- @param cslotNeededByNext - the number of slots being requested by the following pass
- @param twsh - how we are handling trailing white-space
- @param pnRet - return value
- @param pcslotGot - return the number of slots gotten
- @param pislotFinalBreak - not used in this version
-
- @return 1 if we need more glyphs from the previous pass
-----------------------------------------------------------------------------------------------*/
-void GrBidiPass::ExtendOutput(GrTableManager * ptman,
- GrSlotStream* psstrmIn, GrSlotStream* psstrmOut,
- int cslotNeededByNext, TrWsHandling twsh,
- int * pnRet, int * pcslotGot, int * pislotFinalBreak)
-{
- Assert(psstrmIn->SlotsToReprocess() == 0);
-
- int islotInitReadPos = psstrmIn->ReadPos();
- int islotInitWritePos = psstrmOut->WritePos();
-
- Assert(m_pzpst->NeededToResync() == 0);
-
- int cslotToGet = max(cslotNeededByNext,
- m_pzpst->NeededToResync() - psstrmOut->WritePos());
- int cslotGot = 0;
- int nTopDir;
- if (twsh == ktwshOnlyWs)
- nTopDir = (ptman->State()->ParaRightToLeft()) ? 1 : 0;
- else
- nTopDir = ptman->TopDirectionLevel();
-
- while (cslotToGet > 0 && cslotGot < cslotToGet)
- {
- int islotChunkO = psstrmOut->WritePos();
- int islotChunkI = psstrmIn->ReadPos();
-
- // Need at least one character to test.
- if (psstrmIn->SlotsPending() < 1 || !ptman->Pass(m_ipass-1)->DidResyncSkip())
- {
- if (!psstrmIn->FullyWritten())
- {
- // Ask previous pass for more input.
- *pnRet = max(cslotToGet - psstrmIn->SlotsPending(), 1);
- *pnRet = max(*pnRet, cslotNeededByNext - cslotGot);
- *pcslotGot = cslotGot;
- return;
- }
- else
- {
- Assert(ptman->Pass(m_ipass-1)->DidResyncSkip());
- Assert(psstrmIn->SlotsToReprocess() == 0);
- psstrmIn->ClearReprocBuffer();
- DoResyncSkip(psstrmOut);
- DoCleanUpSegMin(ptman, psstrmIn, islotInitReadPos, psstrmOut);
- psstrmOut->MarkFullyWritten();
- *pnRet = kNextPass;
- *pcslotGot = cslotGot;
- return;
- }
- }
-
- std::vector<int> vislotStarts;
- std::vector<int> vislotStops;
- int islotReverseLim = psstrmIn->DirLevelRange(ptman->State(),
- psstrmIn->ReadPos(), nTopDir,
- vislotStarts, vislotStops);
- //int islotReverseLim = psstrmIn->OldDirLevelRange(pengst, psstrmIn->ReadPos(), nTopDir);
- if (islotReverseLim == -1)
- {
- // We haven't got the full range of reversed text yet--
- // ask for more input.
- *pnRet = max(1, cslotNeededByNext - cslotGot);
- *pcslotGot = cslotGot;
- return;
- }
-
- // Okay, we have enough input to do the reversal, if any.
-
- int cslotToReverse = islotReverseLim - psstrmIn->ReadPos();
-
- // Never reverse the final linebreak; leave it at the end.
- if (cslotToReverse > 0 && islotReverseLim > 0)
- {
- GrSlotState * pslotLast = psstrmIn->SlotAt(islotReverseLim - 1);
- if (pslotLast->IsFinalLineBreak(ptman->LBGlyphID()))
- {
- for (size_t i = 0; i < vislotStops.size(); i++)
- if (vislotStops.back() == islotReverseLim - 1)
- vislotStops.back() = islotReverseLim - 2;
- islotReverseLim--;
- cslotToReverse--;
- }
- }
-
- psstrmIn->SetRuleStartReadPos();
- psstrmOut->SetRuleStartWritePos();
-
- if (cslotToReverse == 0)
- {
- psstrmOut->CopyOneSlotFrom(psstrmIn);
- }
- else
- {
- int islotNextWritePos = psstrmOut->WritePos() + cslotToReverse;
- int islotNextReadPos = psstrmIn->ReadPos() + cslotToReverse;
- if (vislotStarts.size() == 0)
- {
- Assert(false); // this should have been done by DirLevelRange
- vislotStarts.push_back(psstrmIn->ReadPos());
- vislotStops.push_back(islotNextReadPos - 1);
- }
- Assert(vislotStarts.back() == psstrmIn->ReadPos());
- Assert(vislotStops.back() == islotNextReadPos - 1);
- int cslotNotCopied = Reverse(ptman, psstrmIn, psstrmOut, vislotStarts, vislotStops);
- //Reverse(nTopDir + 1,
- // psstrmIn, psstrmIn->ReadPos(), islotReverseLim,
- // psstrmOut, psstrmOut->WritePos() + cslotToReverse - 1, psstrmOut->WritePos()-1);
-
- islotNextWritePos -= cslotNotCopied; // bidi markers that are not passed through
-
- psstrmIn->SetReadPos(islotNextReadPos);
- psstrmOut->SetWritePos(islotNextWritePos);
-
- // It's quite strange to have the segment start or end in the middle of stuff to
- // reverse (because the LB forms a natural terminator), but at any rate,
- // if that happens, record the segment lim at the corresponding place in the
- // output stream.
- int islotSegMinIn = psstrmIn->SegMin();
- if (islotSegMinIn > -1 &&
- psstrmIn->ReadPos() - cslotToReverse <= islotSegMinIn &&
- islotSegMinIn < psstrmIn->ReadPos())
- {
- Assert(islotSegMinIn == psstrmIn->ReadPos() - cslotToReverse); // normal situation
- psstrmOut->SetSegMin(
- psstrmOut->WritePos() - (psstrmIn->ReadPos() - islotSegMinIn));
- }
- int islotSegLimIn = psstrmIn->SegLimIfKnown();
- if (islotSegLimIn > -1 &&
- psstrmIn->ReadPos() - cslotToReverse <= islotSegLimIn &&
- islotSegLimIn < psstrmIn->ReadPos())
- {
- Assert(islotSegLimIn == psstrmIn->ReadPos() - cslotToReverse); // normal situation
- psstrmOut->SetSegLim(
- psstrmOut->WritePos() - (psstrmIn->ReadPos() - islotSegLimIn));
- }
- }
-
- psstrmOut->SetPosForNextRule(0, psstrmIn, false);
-
- // Record the chunk mappings:
- MapChunks(psstrmIn, psstrmOut, islotChunkI, islotChunkO, 0);
-
- cslotGot = psstrmOut->WritePos() - islotInitWritePos;
- psstrmOut->CalcIndexOffset(ptman);
- }
-
- DoResyncSkip(psstrmOut);
- DoCleanUpSegMin(ptman, psstrmIn, islotInitReadPos, psstrmOut);
-
- // We're past the point where we care about anything in the reprocessing buffer.
- Assert(psstrmIn->NoReproc());
- psstrmIn->ClearReprocBuffer();
-
- Assert(psstrmIn->SlotsToReprocess() == 0);
-
- if (psstrmOut->PastEndOfPositioning(true))
- psstrmOut->MarkFullyWritten();
-
- *pnRet = kNextPass;
- *pcslotGot = cslotGot;
-}
-
-/*----------------------------------------------------------------------------------------------
- Generate slots containing glyph IDs for the underlying character data,
- incrementing the input pointer as we go.
-
- @param ptman - table manager
- @param pchstrm - input character stream
- @param psstrmOutput - output slot stream
- @param ichSegLim - known end of segment, index into the text; or -1;
- the lim of the of char-stream itself represents
- the end of the text-source; this lim is the
- known desired end of the segment
- @param cchwPostXlbContext - number of characters that may be needed from the following line;
- valid when ichSegLim > -1
- @param lb - breakweight to use for inserted LB
- @param cslotToGet - the number of slots being requested by the following pass
- @param fNeedFinalBreak - true if the end of the segment needs to be a valid break point
- @param pislotFinalBreak - the end of this segment
-----------------------------------------------------------------------------------------------*/
-int GrPass::ExtendGlyphIDOutput(GrTableManager * ptman,
- GrCharStream * pchstrm, GrSlotStream * psstrmOut, int ichSegLim, int cchwPostXlbContext,
- LineBrk lb, int cslotToGet, bool fNeedFinalBreak, TrWsHandling twsh,
- int * pislotFinalBreak)
-{
- EngineState * pengst = ptman->State();
-
- // This pass should be the glyph-generation pass.
- Assert(dynamic_cast<GrGlyphGenPass*>(this));
- Assert(m_pzpst->m_cslotSkipToResync == 0);
- m_pzpst->m_fDidResyncSkip = true;
-
- for (int islot = 0; islot < cslotToGet; ++islot)
- {
- int islotChunkO = psstrmOut->WritePos();
- int islotChunkI = pchstrm->SegOffset();
-
- if (pchstrm->AtEnd()
- || (ichSegLim > -1 && pchstrm->Pos() == ichSegLim))
- {
- if (psstrmOut->SegLimIfKnown() > -1 &&
- psstrmOut->SegLimIfKnown() <= psstrmOut->WritePos())
- {
- // Already found the end of this stream.
- }
- else
- {
- if (pchstrm->EndLine() && !fNeedFinalBreak)
- // (if we need a good final break, don't just append an LB;
- // make it backtrack and find a valid break point)
- {
- // Only need to get a good break when we're backtracking; otherwise we
- // already know it.
- Assert(ichSegLim == -1 || !fNeedFinalBreak);
- // Notice that we're cheating here: we're putting the LB in the zeroth
- // stream instead of in the output of the linebreak table.
- psstrmOut->AppendLineBreak(ptman, pchstrm,
- (pchstrm->AtEnd() ? klbWordBreak : lb),
- ((ptman->RightToLeft()) ? kdircRlb : kdircLlb), -1, false,
- pchstrm->SegOffset());
- if (pchstrm->AtEnd())
- pengst->SetFinalLB();
- else
- pengst->SetInsertedLB(true);
- }
- else
- {
- // Don't actually insert a line-break glyph.
- psstrmOut->SetSegLimToWritePos();
- }
- *pislotFinalBreak = psstrmOut->WritePos() - 1;
- if (ptman->NumberOfLbPasses() > 0 && pengst->HasInitialLB())
- {
- // Because we cheated above: the output stream of the linekbreak table
- // has an initial LB, which this stream doesn't have. Adjust the position
- // of the final break to match what it will be in the output of the
- // lb table.
- *pislotFinalBreak += 1;
- }
- }
-
- if (twsh == ktwshNoWs && m_ipass == ptman->NumberOfLbPasses())
- {
- int nRet = RemoveTrailingWhiteSpace(ptman, psstrmOut, twsh, pislotFinalBreak);
- if (nRet == kBacktrack) // entire segment was white-space:
- return kBacktrack; // backtrack, which will fail
- }
- if (pchstrm->AtEnd())
- {
- psstrmOut->MarkFullyWritten();
- return kNextPass;
- }
- // otherwise we may need a few more characters for line-boundary contextualization.
- }
-
- int ichwSegOffset; // offset from the official start of the segment
- int cchw; // number of 16-bit chars consumed
- GrFeatureValues fval;
- int nUnicode = pchstrm->NextGet(ptman, &fval, &ichwSegOffset, &cchw);
- gid16 chwGlyphID = ptman->GetGlyphIDFromUnicode(nUnicode);
-
- if (nUnicode == knCR || nUnicode == knLF || nUnicode == knLineSep || nUnicode == knParaSep ||
- nUnicode == knORC)
- {
- // Hard line-break: we're done.
- // Note that we don't include the hard-break character in this segment.
- pchstrm->HitHardBreak();
- pengst->SetHitHardBreak();
- psstrmOut->MarkFullyWritten();
- return kNextPass;
- }
-
- GrSlotState * pslotNew;
- ptman->State()->NewSlot(chwGlyphID, fval, 0, ichwSegOffset, nUnicode, &pslotNew);
-
- psstrmOut->NextPut(pslotNew);
- psstrmOut->MapInputChunk(islotChunkI, islotChunkO, pchstrm->SegOffset(), false, false);
- // Mapping the output chunks of the char stream has already been handled by the
- // char stream.
-
- }
-
- psstrmOut->CalcIndexOffset(ptman);
-
- if (psstrmOut->PastEndOfPositioning(true)
- || (ichSegLim > -1 && pchstrm->Pos() > ichSegLim + cchwPostXlbContext))
- {
- // We have enough for this segment.
- psstrmOut->MarkFullyWritten();
- }
-
- return kNextPass;
-}
-
-/*----------------------------------------------------------------------------------------------
- Extend the output stream until it is using up the allotted amount of
- physical space. Return kNextPass when all data has been processed successfully.
- Return kBacktrack when space overflows, indicating that we need to backtrack
- and find a break point. Otherwise, return the number of slots we
- need from the previous pass.
-
- @param fWidthIsCharCount - kludge for test procedures
- @param fInfiniteWidth - don't test for more space
- @param fMustBacktrack - true if we need a good final break and haven't found one yet
- @param lbMax - max allowed for the final slot
- @param twsh - how we are handling trailing white-space
-----------------------------------------------------------------------------------------------*/
-int GrPass::ExtendFinalOutput(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput,
- float xsSpaceAllotted, bool fWidthIsCharCount, bool fInfiniteWidth,
- bool fHaveLineBreak, bool fMustBacktrack, LineBrk lbMax, TrWsHandling twsh,
- int * pislotLB, float * pxsWidth)
-{
- EngineState * pengst = ptman->State();
-
- // This pass should be the final positioning pass.
- Assert(dynamic_cast<GrPosPass*>(this));
-
- // It would be very strange to be positioning based on something that happened in
- // previous line. -- not true any more, since this will include the max-precontext-length.
-// Assert(m_cslotSkipToResync == 0);
-
- int islotOutputLB = -1;
- //int islotInitWritePos = psstrmOutput->WritePos();
- int islotNoLbUpTo = psstrmOutput->WritePos();;
-
- while (true)
- {
- // Do this right up front, so we are only measuring actual output.
- if (m_pzpst->CanResyncSkip(psstrmOutput))
- m_pzpst->DoResyncSkip(psstrmOutput);
-
- bool fMoreSpace;
- if (!m_pzpst->DidResyncSkip())
- fMoreSpace = true;
- else if (fInfiniteWidth)
- fMoreSpace = true;
- else
- fMoreSpace = psstrmOutput->MoreSpace(ptman,
- xsSpaceAllotted, fWidthIsCharCount,
- true, // always ignore trailing white space when we are first making the segment
- twsh,
- pxsWidth);
- if (!fMoreSpace)
- {
- // Overflowed available space; backtrack and find a line break.
- while (psstrmInput->SlotsToReprocess() > 0)
- {
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
- psstrmOutput->SetPosForNextRule(0, psstrmInput, IsPosPass());
- }
- psstrmInput->ClearReprocBuffer();
-
- *pislotLB = -1;
- pengst->SetExceededSpace();
- pengst->SetHitHardBreak(false);
- return kBacktrack;
- }
-
- if (islotOutputLB != -1 && psstrmInput->SlotsToReprocess() == 0)
- {
- // Hit the inserted line break--we're done.
- psstrmInput->ClearReprocBuffer();
- *pislotLB = islotOutputLB;
- return kNextPass;
- }
-
- int nslotAvailable = psstrmInput->SlotsPending();
- if ((nslotAvailable - ptman->PrevPassMaxBackup(m_ipass)
- < MaxRuleContext() && !psstrmInput->FullyWritten())
- || !ptman->Pass(m_ipass-1)->DidResyncSkip())
- {
- // Not enough available in the input--ask previous pass for more input.
- // Ten is an arbitrary value--we ask for more that we really need to cut down
- // on the number of times we loop between passes.
- return max(MaxRuleContext() - (nslotAvailable - 10), 1);
- }
-
- Assert(ptman->Pass(m_ipass - 1)->DidResyncSkip());
-
- if (nslotAvailable == 0)
- {
- // No more input to process. If we have a valid line-break, or we don't care,
- // we're done. Otherwise backtrack to find a valid break point.
- Assert(psstrmInput->SlotsToReprocess() == 0);
- psstrmInput->ClearReprocBuffer();
- if (fMustBacktrack)
- {
- *pislotLB = -1;
- return kBacktrack;
- }
- else
- {
- psstrmOutput->MarkFullyWritten();
- return kNextPass;
- }
- }
-
- // Otherwise, we have enough input to run a rule.
-
- psstrmInput->SetRuleStartReadPos();
- psstrmOutput->SetRuleStartWritePos();
-
- int ruln = -1;
- if (m_pfsm)
- ruln = m_pfsm->GetRuleToApply(ptman, this, psstrmInput, psstrmOutput);
- ruln = CheckRuleValidity(ruln);
- RunRule(ptman, ruln, psstrmInput, psstrmOutput);
-
- if (fHaveLineBreak)
- {
- islotOutputLB =
- psstrmOutput->FindFinalLineBreak(ptman->LBGlyphID(),
- islotNoLbUpTo, psstrmOutput->WritePos());
- islotNoLbUpTo = psstrmOutput->WritePos();
- }
-
- psstrmOutput->CalcIndexOffset(ptman);
- }
-
- Assert(false);
-
- psstrmInput->ClearReprocBuffer();
- *pislotLB = -1;
- return kNextPass;
-}
-
-/*----------------------------------------------------------------------------------------------
- Remove undesirable trailing white-space.
-----------------------------------------------------------------------------------------------*/
-int GrPass::RemoveTrailingWhiteSpace(GrTableManager * ptman, GrSlotStream * psstrmOut,
- TrWsHandling twsh, int * pislotFinalBreak)
-{
- EngineState * pengst = ptman->State();
-
- Assert(twsh == ktwshNoWs);
- Assert(m_ipass == ptman->NumberOfLbPasses()); // output of (final) lb pass
-
- int islotTmp = psstrmOut->FinalSegLim();
- if (islotTmp <= 0)
- return kNextPass;
-
- GrSlotState * pslotLast = psstrmOut->SlotAt(islotTmp-1);
- if (islotTmp > 0 && pslotLast->IsFinalLineBreak(ptman->LBGlyphID()))
- {
- islotTmp--;
- pslotLast = (islotTmp > 0) ? psstrmOut->SlotAt(islotTmp-1) : NULL;
- }
- bool fRemovedWs = false;
- while (islotTmp > 0 && pslotLast->Directionality() == kdircWhiteSpace)
- {
- islotTmp--;
- pslotLast = (islotTmp > 0) ? psstrmOut->SlotAt(islotTmp-1) : NULL;
- fRemovedWs = true;
- }
- if (fRemovedWs)
- {
- if (islotTmp <= 0)
- {
- // Entire segment was white-space: backtrack, which will fail.
- return kBacktrack;
- }
- psstrmOut->SetSegLim(islotTmp);
- *pislotFinalBreak = islotTmp - 1;
- pengst->SetFinalLB(false);
- pengst->SetRemovedTrWhiteSpace();
- ptman->UnwindAndReinit(islotTmp - 1);
- }
-
- return kNextPass;
-}
-
-/*----------------------------------------------------------------------------------------------
- Keep track of whether we're advancing through the input satisfactorily;
- if not, forcibly advance. This is a safety net to avoid infinite loops; it
- should never be necessary if they've set up their tables right.
-----------------------------------------------------------------------------------------------*/
-void GrPass::CheckInputProgress(GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput,
- int islotOrigInput)
-{
- int islotInput = psstrmInput->ReadPosForNextGet();
-// Assert(islotInput >= islotOrigInput); -- no longer true now that we can back up
-
- if (islotInput <= psstrmInput->ReadPosMax())
- {
- // Didn't advance.
- if (m_pzpst->m_nRulesSinceAdvance >= m_nMaxRuleLoop)
- {
- bool fAdvanced = false;
- // Forcibly advance. First try to advance to where we backed up from.
- while (!psstrmInput->AtEnd() &&
- psstrmInput->ReadPosForNextGet() < psstrmInput->ReadPosMax())
- {
- RecordHitMaxRuleLoop(psstrmInput->ReadPosForNextGet());
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
- fAdvanced = true;
- }
- // If that didn't do anything productive, just advance one slot.
- if (!fAdvanced && !psstrmInput->AtEndOfContext())
- {
- RecordHitMaxRuleLoop(psstrmInput->ReadPosForNextGet());
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
- }
-
- m_pzpst->m_nRulesSinceAdvance = 0;
- }
- else m_pzpst->m_nRulesSinceAdvance++;
- }
- else m_pzpst->m_nRulesSinceAdvance = 0;
-
- psstrmInput->SetReadPosMax(islotInput);
-}
-
-/*----------------------------------------------------------------------------------------------
- Record the chunks in the streams' chunk maps.
-
- psstrmIn/Out - streams being processed
- islotChunkIn/Out - start of chunks
- cslotReprocessed - number of slots to reprocess before the rule was run
-----------------------------------------------------------------------------------------------*/
-void GrPass::MapChunks(GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int islotChunkIn, int islotChunkOut, int cslotReprocessed)
-{
- if (islotChunkOut > psstrmOut->WritePos())
- {
- // backing up
- int islotReadPosTmp = psstrmIn->ReadPosForNextGet();
-/// Assert((islotChunkIn - islotReadPosTmp) == (islotChunkOut - psstrmOut->WritePos()));
-// psstrmIn->MapOutputChunk(psstrmOut->WritePos() - 1, islotReadPosTmp - 1,
-// islotChunkOut, true, 0, true);
-// psstrmOut->MapInputChunk(islotReadPosTmp - 1, psstrmOut->WritePos() - 1,
-// islotChunkIn, true, true);
-
- // Resync.
- if (psstrmOut->WritePos() == 0)
- {
- // Clear all the chunks.
- psstrmIn->MapOutputChunk(-1, -1, 0, true, 0, true);
- psstrmOut->MapInputChunk(-1, -1, islotReadPosTmp, true, true);
- psstrmIn->AssertChunkMapsValid(psstrmOut);
- return;
- }
- else if (islotReadPosTmp == 0)
- {
- // Clear all the chunks.
- psstrmIn->MapOutputChunk(-1, -1, psstrmOut->WritePos(), true, 0, true);
- psstrmOut->MapInputChunk(-1, -1, 0, true, true);
- psstrmIn->AssertChunkMapsValid(psstrmOut);
- return;
- }
- // Find the beginning of the current chunk.
- int islotChunkOutAdj = min(islotChunkOut, psstrmOut->WritePos() - 1);
- int islotChunkInAdj = psstrmOut->ChunkInPrev(islotChunkOutAdj);
- while (islotChunkInAdj == -1 && islotChunkOutAdj > 0)
- islotChunkInAdj = psstrmOut->ChunkInPrev(--islotChunkOutAdj);
-
- if (islotChunkInAdj == -1)
- {
- // Couldn't find the beginning of any chunk; zap them all.
- psstrmIn->MapOutputChunk(-1, -1, psstrmOut->WritePos(), true, 0, true);
- psstrmOut->MapInputChunk(-1, -1, psstrmOut->ReadPos(), true, true);
- psstrmIn->AssertChunkMapsValid(psstrmOut);
- return;
- }
-
- if (psstrmIn->ChunkInNext(islotChunkInAdj) != islotChunkOutAdj)
- {
- islotChunkOutAdj = psstrmIn->ChunkInNext(islotChunkInAdj);
- while (islotChunkOutAdj == -1 && islotChunkInAdj > 0)
- islotChunkOutAdj = psstrmIn->ChunkInNext(--islotChunkInAdj);
- }
-
- psstrmIn->MapOutputChunk(islotChunkOutAdj, islotChunkInAdj,
- psstrmOut->WritePos(), false, 0, true);
- psstrmOut->MapInputChunk(islotChunkInAdj, islotChunkOutAdj,
- psstrmIn->ReadPos(), false, true);
- }
- else if (islotChunkOut == psstrmOut->WritePos())
- // no output generated--continue the previous chunk
- ;
- else if (islotChunkIn == psstrmIn->ReadPos())
- // no input consumed
- ;
- else
- {
- psstrmIn->MapOutputChunk(islotChunkOut, islotChunkIn, psstrmOut->WritePos(),
- (cslotReprocessed > 0), cslotReprocessed, false);
- psstrmOut->MapInputChunk(islotChunkIn, islotChunkOut, psstrmIn->ReadPos(),
- (cslotReprocessed > 0), false);
- }
-
- psstrmIn->AssertChunkMapsValid(psstrmOut);
-
- m_pzpst->m_nMaxChunk = max(m_pzpst->m_nMaxChunk, psstrmIn->LastNextChunkLength());
-}
-
-/*----------------------------------------------------------------------------------------------
- This method is something of a kludge. During the course of running the rules we try to
- keep track of the seg-min location, but sometimes that gets confused due to insertions
- and deletions at the segment boundaries.
-----------------------------------------------------------------------------------------------*/
-void GrSubPass::DoCleanUpSegMin(GrTableManager * ptman,
- GrSlotStream * psstrmIn, int islotInitReadPos, GrSlotStream * psstrmOut)
-{
- int islotSegMinIn = psstrmIn->SegMin();
- if (islotSegMinIn == -1)
- return; // input doesn't even know it
- if (islotInitReadPos > islotSegMinIn)
- return; // should already have figured it out
-
- // Otherwise this batch of processing likely set the seg-min on the output stream,
- // so check it out.
-
- // First, if the seg-min of the input stream is zero, it should be zero on the output.
- if (islotSegMinIn == 0)
- {
- psstrmOut->SetSegMin(0, true);
- return;
- }
-
- // If there is an initial line-break, the seg-min should be just before it.
- int islot;
- if (ptman->State()->HasInitialLB())
- {
- gid16 chwLB = ptman->LBGlyphID();
-
- // Unfortunately, the seg-min from the previous segment can get off, too. :-(
- // Fix it, while we're at it.
- if (!psstrmIn->SlotAt(islotSegMinIn)->IsInitialLineBreak(chwLB))
- {
- for (islot = 0; islot < psstrmIn->ReadPos(); islot++)
- if (psstrmIn->SlotAt(islot)->IsInitialLineBreak(chwLB))
- {
- psstrmIn->SetSegMin(islot, true);
- break;
- }
- }
- if (psstrmOut->SegMin() > -1
- && psstrmOut->SlotAt(psstrmOut->SegMin())->IsInitialLineBreak(chwLB))
- {
- return; // already okay
- }
- for (islot = 0; islot < psstrmOut->WritePos(); islot++)
- if (psstrmOut->SlotAt(islot)->IsInitialLineBreak(chwLB))
- {
- psstrmOut->SetSegMin(islot, true);
- return;
- }
- Assert(false); // couldn't find it
- }
-
- // Otherwise, figure it out using the associations. First observe that the seg-min
- // will be in the corresponding chunk to the seg-min of the previous pass.
- int islotChunkMinIn = psstrmIn->ChunkInNextMin(islotSegMinIn);
- int islotChunkLimIn = psstrmIn->ChunkInNextLim(islotSegMinIn);
- if (islotChunkMinIn == -1) islotChunkMinIn = 0;
- if (islotChunkLimIn == -1) islotChunkLimIn = 1;
-
- int islotChunkMinOut = psstrmIn->ChunkInNext(islotChunkMinIn);
- int islotChunkLimOut = psstrmIn->ChunkInNext(islotChunkLimIn);
- if (islotChunkMinOut == -1) islotChunkMinOut = 0;
- if (islotChunkLimOut == -1) islotChunkLimOut = 1;
-
- int islotSegMinOut = psstrmOut->SegMin();
- if (islotSegMinOut == -1)
- {
- // No reasonable guess; try to figure it out.
- for (islot = islotChunkMinOut; islot < islotChunkLimOut; islot++)
- {
-// GrSlotState * pslotOut = psstrmOut->SlotAt(islot);
- if (psstrmOut->SlotAt(islot)->BeforeAssoc() == 0)
- {
- islotSegMinOut = islot;
- break;
- }
- }
- if (islotSegMinOut == -1)
- {
- // Ick, couldn't figure it out. Let's hope we set it to something reasonable earlier.
- Assert(psstrmOut->SegMin() > -1);
- return;
- }
- }
- // else we have a reasonable guess
-
- // islotSegMinOut is the best or at leastfirst slot in the chunk that maps into the segment.
- // But if there is an adjacent slot inserted before it and it is in the chunk,
- // we want to include that also.
- while (islotSegMinOut > islotChunkMinOut
- && psstrmOut->SlotAt(islotSegMinOut-1)->BeforeAssoc() >= 0)
- {
- islotSegMinOut--;
- }
- psstrmOut->SetSegMin(islotSegMinOut, true);
-}
-
-/*----------------------------------------------------------------------------------------------
- If we are in a state where we are supposed to skip some of the initial output,
- do so. The purpose of this is to resync when restarting for a segment other than the
- first. Caller should ensure that there are enough slots to skip.
-----------------------------------------------------------------------------------------------*/
-int PassState::DoResyncSkip(GrSlotStream * psstrmOutput)
-{
- if (m_fDidResyncSkip)
- return 0;
-
- if (m_cslotSkipToResync == 0)
- {
- m_fDidResyncSkip = true;
- return 0;
- }
-
- if (!CanResyncSkip(psstrmOutput))
- {
- Assert(false); // caller makes sure this doesn't happen
- return (m_cslotSkipToResync - psstrmOutput->WritePos());
- }
-
- psstrmOutput->ResyncSkip(m_cslotSkipToResync);
- m_fDidResyncSkip = true;
-
- return 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Run a constraint for a single rule.
-
- @param ruln - rule to test
- @param psstrmIn - input stream
- @param psstrmOut - for accessing items in the pre-context
- @param cslotPreModContext - the number of items that need to be tested prior to the
- current stream position
- @param cslotMatched - the number of items matched after the current stream position
-----------------------------------------------------------------------------------------------*/
-bool GrPass::RunConstraint(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int cslotPreModContext, int cslotMatched)
-{
- int nRet = 0;
-
- if (m_prgibConstraintStart == NULL)
- return true;
-
- int biStart = int(m_prgibConstraintStart[ruln]);
- if (biStart == 0)
- return true; // no constraints
-
- for (int islot = -cslotPreModContext; islot < cslotMatched; islot++)
- {
- nRet = RunCommandCode(ptman, m_prgbConstraintBlock + biStart, true,
- psstrmIn, psstrmOut, islot);
-
- if (nRet == 0) // one slot failed
- return false;
- }
-
- return (nRet != 0);
-}
-
-/*----------------------------------------------------------------------------------------------
- Check that we can interpret all the commands in the rule. If not, return -1 indicating
- that we don't want to run a rule after all. This can happen when the version of the compiler
- that generated the font is later than this engine.
-----------------------------------------------------------------------------------------------*/
-int GrPass::CheckRuleValidity(int ruln)
-{
- if (ruln == -1)
- return -1;
-
- if (m_prgfRuleOkay[ruln])
- return ruln;
-
- int biStart = m_prgibActionStart[ruln];
- byte * pbNext = m_prgbActionBlock + biStart;
-
- // 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;
-
-// int nRet = 0;
-
- while (true) // exit by encountering PopRet or RetTrue or RetZero
- {
- ActionCommand op = ActionCommand(*pbNext++);
-
- switch (op)
- {
- case kopNop:
- break;
-
- case kopPushByte:
- pbNext++;
- break;
- case kopPushByteU:
- pbNext++;
- break;
- case kopPushShort:
- pbNext++;
- pbNext++;
- break;
- case kopPushShortU:
- pbNext++;
- pbNext++;
- break;
- case kopPushLong:
- pbNext++;
- pbNext++;
- pbNext++;
- pbNext++;
- break;
-
- case kopNeg:
- case kopTrunc8: case kopTrunc16:
- case kopNot:
- 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:
- break;
-
- case kopCond:
- break;
-
- case kopNext:
- break;
- case kopNextN:
- c = *pbNext; pbNext++; // count
- break;
- case kopPutGlyph8bitObs:
- nOutputClass = *pbNext++;
- break;
- case kopPutGlyph:
- pbNext += 2;
- break;
- case kopPutCopy:
- nSlotRef = *pbNext++;
- break;
- case kopPutSubs8bitObs:
- nSlotRef = *pbNext++;
- nInputClass = *pbNext++;
- nOutputClass = *pbNext++;
- break;
- case kopPutSubs:
- nSlotRef = *pbNext++;
- pbNext += 4; // 2 bytes each for classes
- break;
- case kopCopyNext:
- break;
- case kopInsert:
- break;
- case kopDelete:
- break;
- case kopAssoc:
- c = *pbNext; pbNext++;
- for (i = 0; i < c; i++)
- pbNext++;
- break;
- case kopCntxtItem:
- islotArg = *pbNext++;
- c = *pbNext++;
- break;
-
- case kopAttrSet:
- case kopAttrAdd:
- case kopAttrSub:
- case kopAttrSetSlot:
- pbNext++; // slot attribute ID
- break;
- case kopIAttrSet:
- case kopIAttrAdd:
- case kopIAttrSub:
- case kopIAttrSetSlot:
- pbNext++; // slot attribute ID
- nIndex = *pbNext++; // index; eg, global ID for component
- break;
-
- case kopPushSlotAttr:
- pbNext++;
- nSlotRef = *pbNext++;
- break;
- case kopPushISlotAttr:
- pbNext++;
- nSlotRef = *pbNext++;
- nIndex = *pbNext++;
- break;
-
- case kopPushGlyphAttrObs:
- case kopPushAttToGAttrObs:
- nGlyphAttr = *pbNext++;
- nSlotRef = *pbNext++;
- break;
- case kopPushGlyphAttr:
- case kopPushAttToGlyphAttr:
- *pbNext += 3;
- break;
- case kopPushGlyphMetric:
- case kopPushAttToGlyphMetric:
- nGlyphAttr = *pbNext++;
- nSlotRef = *pbNext++;
- nAttLevel = *pbNext++;
- break;
- case kopPushFeat:
- nFeat = *pbNext++;
- nSlotRef = *pbNext++;
- break;
-
- case kopPushProcState:
- nPState = *pbNext++;
- break;
- case kopPushVersion:
- break;
-
- case kopPopRet:
- case kopRetZero:
- case kopRetTrue:
- m_prgfRuleOkay[ruln] = true;
- return ruln;
-
- default:
- // Uninterpretable command:
- return -1;
- }
- }
-
- return ruln; // to keep compiler from griping
-}
-
-/*----------------------------------------------------------------------------------------------
- Runs the rule, if any, otherwise just passes one character through.
- The rule does nothing but set the line-break weights for the slots.
-
- @param ptman - the table manager that allocates slots
- @param ruln - number of rule to run; -1 if none applies
- @param psstrmIn/Out - input/output stream
-----------------------------------------------------------------------------------------------*/
-void GrLineBreakPass::RunRule(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut)
-{
- // Remember the beginnings of the new chunk:
- int islotIn = psstrmIn->ReadPos();
- int islotOut = psstrmOut->WritePos();
- int cslotReprocessed = psstrmIn->SlotsToReprocess();
-
- if (ruln == -1)
- {
-#ifdef OLD_TEST_STUFF
- if (RunTestRules(ptman, ruln, psstrmIn, psstrmOut))
-#else
- if (false)
-#endif // OLD_TEST_STUFF
- {}
- else
- // Just pass one glyph through.
- {
- psstrmOut->CopyOneSlotFrom(psstrmIn);
- psstrmOut->SetPosForNextRule(0, psstrmIn, false);
- }
- }
- else
- {
- // Run the rule.
-#ifdef OLD_TEST_STUFF
- if (RunTestRules(ptman, ruln, psstrmIn, psstrmOut))
-#else
- if (false)
-#endif // OLD_TEST_STUFF
- {}
- else
- {
- int biStart = m_prgibActionStart[ruln];
- int iResult = RunCommandCode(ptman, m_prgbActionBlock + biStart, false,
- psstrmIn, psstrmOut, 0);
- psstrmOut->SetPosForNextRule(iResult, psstrmIn, false);
- }
- }
-
- CheckInputProgress(psstrmIn, psstrmOut, islotIn);
-
- MapChunks(psstrmIn, psstrmOut, islotIn, islotOut, cslotReprocessed);
-}
-
-/*----------------------------------------------------------------------------------------------
- Runs the rule, if any, otherwise just passes one character through.
- Keeps track of the association information in the slots and chunk
- mappings for backtracking.
-
- @param ptman - the table manager that allocates slots
- @param ruln - number of rule to run; -1 if none applies
- @param psstrmIn/Out - input / output streams
-----------------------------------------------------------------------------------------------*/
-void GrSubPass::RunRule(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut)
-{
- // Remember the beginnings of the new chunk:
- int islotIn = psstrmIn->ReadPosForNextGet();
- int islotOut = psstrmOut->WritePos();
- int cslotReprocessed = psstrmIn->SlotsToReprocess();
-
- if (ruln == -1)
- {
-#ifdef OLD_TEST_STUFF
- if (RunTestRules(ptman, ruln, psstrmIn, psstrmOut))
-#else
- if (false)
-#endif // OLD_TEST_STUFF
- {}
- else
- // Just pass one glyph through.
- {
- psstrmOut->CopyOneSlotFrom(psstrmIn);
- psstrmOut->SetPosForNextRule(0, psstrmIn, false);
- }
- }
- else
- {
- // Run the rule.
-#ifdef OLD_TEST_STUFF
- if (RunTestRules(ptman, ruln, psstrmIn, psstrmOut))
-#else
- if (false)
-#endif // OLD_TEST_STUFF
- {}
- else
- /****************************/
- {
- int biStart = m_prgibActionStart[ruln];
- int iResult = RunCommandCode(ptman, m_prgbActionBlock + biStart, false,
- psstrmIn, psstrmOut, 0);
- psstrmOut->SetPosForNextRule(iResult, psstrmIn, false);
-
- // Restore if we need line-boundary contextualization based on physical locations
- ////psstrmOut->SetLBContextFlag(ptman, islotOut);
- }
- }
-
- CheckInputProgress(psstrmIn, psstrmOut, islotIn);
-
- MapChunks(psstrmIn, psstrmOut, islotIn, islotOut, cslotReprocessed);
-}
-
-/*----------------------------------------------------------------------------------------------
- Runs the rule, if any, otherwise just positions one character in the standard way.
- Keeps track of (among other things) the overall physical size of the output
- and chunk mappings.
-
- @param ptman - the table manager that allocates slots
- @param ruln - number of rule to run; -1 if none applies
- @param psstrmIn / Out - input / output streams
-----------------------------------------------------------------------------------------------*/
-void GrPosPass::RunRule(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut)
-{
- // Remember the beginnings of the new chunk:
- int islotIn = psstrmIn->ReadPosForNextGet();
- int islotOut = psstrmOut->WritePos();
- int cslotReprocessed = psstrmIn->SlotsToReprocess();
-
- int iResult = 0;
-
- Assert(psstrmIn->GotIndexOffset());
- // Don't do any positioning in anything being processed from the previous line.
- if (psstrmIn->ReadPosForNextGet() < psstrmIn->IndexOffset())
- ruln = -1;
-
- if (ruln == -1)
- {
- // Just position one glyph in the standard way.
- psstrmOut->CopyOneSlotFrom(psstrmIn);
- iResult = 0;
- }
- else
- {
- // Run the rule.
-#ifdef OLD_TEST_STUFF
- if (RunTestRules(ptman, ruln, psstrmIn, psstrmOut))
-#else
- if (false)
-#endif // OLD_TEST_STUFF
- {}
- else
- {
- int biStart = m_prgibActionStart[ruln];
- iResult = RunCommandCode(ptman, m_prgbActionBlock + biStart, false,
- psstrmIn, psstrmOut, 0);
- }
- }
-
- // Make sure an entire cluster is present in the output stream. Actually there might be
- // interleaved clusters, which is the purpose for the loop.
- int dislotClusterMax = 0;
- do {
- dislotClusterMax = psstrmIn->MaxClusterSlot(islotIn, psstrmIn->ReadPos());
- Assert(dislotClusterMax >= 0);
- for (int islot = 0; islot < dislotClusterMax; islot++)
- psstrmOut->CopyOneSlotFrom(psstrmIn);
- iResult -= dislotClusterMax;
- } while (dislotClusterMax > 0);
-
- psstrmOut->SetPosForNextRule(iResult, psstrmIn, true);
-
- // Restore if we need line-boundary contextualization based on physical locations
- ////psstrmOut->SetLBContextFlag(ptman, islotOut);
-
- if (ruln > -1)
- {
- psstrmOut->CalcIndexOffset(ptman);
- // Update the attachment trees and cluster metrics for slots modified by this rule.
- // Note that this loop assumes that the reprocess buffer points to the identical
- // slot objects as the output stream (not copies of the slots).
- for (int islot = islotIn - psstrmIn->SlotsSkippedToResync();
- islot < psstrmOut->WritePos() + psstrmIn->SlotsToReprocess();
- islot++)
- {
- psstrmOut->SlotAt(islot)->HandleModifiedPosition(ptman, psstrmIn, psstrmOut, islot);
- }
- }
-
- CheckInputProgress(psstrmIn, psstrmOut, islotIn);
-
- MapChunks(psstrmIn, psstrmOut, islotIn, islotOut, cslotReprocessed);
-
- psstrmOut->AssertStreamIndicesValid(psstrmIn);
-}
-
-/*----------------------------------------------------------------------------------------------
- Perform the reversal for internal bidirectionality.
- Caller is responsible for updating the read- and write-positions.
- Private.
-
- OBSOLETE
-
- @param nCurrDirection - direction level of range of reverse
- @param psstrmIn, psstrmOut - streams
- @param islotInMin, islotInLim - range to reverse
- @param islotOutMin,islotOutLim - corresponding output positions; note that islotOutMin
- will be greater than islotOutLim if we are reversing
- reversing the slots (direction is odd)
-----------------------------------------------------------------------------------------------*/
-#if 0
-void GrBidiPass::OldReverse(int nCurrDirection,
- GrSlotStream * psstrmIn, int islotInMin, int islotInLim,
- GrSlotStream * psstrmOut, int islotOutMin, int islotOutLim)
-{
- int oInc = (islotOutLim > islotOutMin)? 1: -1; // which direction output is moving in
- // buffer (if dir is even, oInc == 1;
- // if odd, oInc == -1)
-
- int islotITmp = islotInMin;
- int islotOTmp = islotOutMin;
-
- while (islotITmp != islotInLim) {
- // Find end of sub-range at current level to reverse.
- int islotSubLim = psstrmIn->OldDirLevelRange(NULL, islotITmp, nCurrDirection);
- Assert(islotSubLim >= 0);
-
- if (islotSubLim == islotITmp) {
- // Current slot is at this level--just copy it.
- psstrmOut->SimpleCopyFrom(psstrmIn, islotITmp, islotOTmp);
- islotOTmp += oInc;
- islotITmp++;
- }
- else {
- // There is a sub-range that needs to be reversed.
- int islotONext = islotOTmp + ((islotSubLim-islotITmp) * oInc);
- OldReverse(nCurrDirection+1,
- psstrmIn, islotITmp, islotSubLim,
- psstrmOut, islotONext - oInc, islotOTmp - oInc);
- islotOTmp = islotONext;
- islotITmp = islotSubLim;
- }
- }
-}
-#endif
-
-/*----------------------------------------------------------------------------------------------
- Perform the reversal for internal bidirectionality.
- Caller is responsible for updating the read- and write-positions.
- Return the number of slots NOT copied because they were markers.
- Private.
-
- @param psstrmIn, psstrmOut - streams
- @param vislotStarts, vislotStops - indices of ranges to reverse, from inner to outer
-----------------------------------------------------------------------------------------------*/
-int GrBidiPass::Reverse(GrTableManager * ptman,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- std::vector<int> & vislotStarts, std::vector<int> & vislotStops)
-{
- Assert(vislotStarts.size() == vislotStops.size());
-
- std::vector<int> vislotMap; // list of slot indices in the order they should be copied
- // into the output
-
- int islotOuterStart = vislotStarts.back();
- int islotOuterStop = vislotStops.back();
-
- // Initialize map as if nothing is reversed; eg for [2, 9]: (2 3 4 5 6 7 8 9)
- int islot;
- for (islot = 0; islot <= (islotOuterStop - islotOuterStart); islot++)
- vislotMap.push_back(islot + islotOuterStart);
-
- // Do the inner reversals first, followed by the outer reversals.
- size_t iislot;
- for (iislot = 0; iislot < vislotStarts.size(); iislot++)
- {
- // Reverse the run.
- int islotStart = vislotStarts[iislot] - islotOuterStart;
- int islotStop = vislotStops[iislot] - islotOuterStart;
- int islot1, islot2;
- for (islot1 = islotStart, islot2 = islotStop; islot1 < islot2; islot1++, islot2--)
- {
- int islotTmp = vislotMap[islot1];
- vislotMap[islot1] = vislotMap[islot2];
- vislotMap[islot2] = islotTmp;
- }
- }
-
- // With vislotStarts = [7, 5, 2] and vislotStops = [8, 8, 9], we get
- // first: (2 3 4 5 6 8 7 9)
- // then: (2 3 4 7 8 5 6 9)
- // and finally: (9 6 5 8 7 4 3 2)
-
- // Now copy the slots.
-
- int islotOutStart = psstrmOut->WritePos();
- int cslotNotCopied = 0;
- for (iislot = 0; iislot < vislotMap.size(); iislot++)
- {
- GrSlotState * pslot = psstrmIn->SlotAt(vislotMap[iislot]);
- // Don't copy bidi markers unless they have been set to use a specific glyph.
- if (pslot->IsBidiMarker() && pslot->ActualGlyphForOutput(ptman) == 0)
- cslotNotCopied++;
- else
- psstrmOut->SimpleCopyFrom(psstrmIn, vislotMap[iislot],
- iislot + islotOutStart - cslotNotCopied);
- }
- return cslotNotCopied;
-}
-
-/*----------------------------------------------------------------------------------------------
- Unwind the output for this pass, given that a change was assumed to have occurred
- in the input at the given position. Return the position to which we unwound.
-----------------------------------------------------------------------------------------------*/
-int GrPass::Unwind(GrTableManager * ptman,
- int islotChanged, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- bool fFirst)
-{
- // Back up the number of slots required for the longest rule context,
- // but if we land in the middle of a chunk, go forward to its boundary.
- int islotIn = max(islotChanged - m_pzpst->MaxChunk(), 0);
- if (!psstrmIn->NoReproc())
- islotIn = min(islotIn, psstrmIn->ReprocMin());
- psstrmIn->ClearReprocBuffer();
- int islotOut = 0;
- if (islotIn < psstrmIn->SlotsSkippedToResync() ||
- islotIn == 0 ||
- psstrmIn->ReadPos() == 0)
- {
- // The next-chunk-map is invalid. The beginning of the chunk is 0.
- islotIn = 0;
- islotOut = 0;
- }
- else if (islotIn >= psstrmIn->ReadPos())
- {
- // No need to unwind.
- Assert(psstrmIn->NoReproc());
- return psstrmOut->WritePos();
- }
- else
- {
- Assert(islotIn < psstrmIn->ReadPos());
- islotIn = min(islotIn, psstrmIn->ReadPos() - 1);
- while (islotIn < psstrmIn->ReadPos() &&
- (islotOut = psstrmIn->ChunkInNext(islotIn)) == -1)
- {
- ++islotIn;
- }
- if (islotIn == psstrmIn->ReadPos())
- islotOut = psstrmOut->WritePos();
- }
-
- Assert(islotOut != -2); // because the chunk size must be <= than the max-chunk,
- // so we should never hit the end of the output stream
-
- // Now we've found a chunk boundary.
-
-// if (fFirst)
-// Unattach(psstrmIn, islotIn, psstrmOut, islotOut, islotChanged);
-// else
-// Unattach(psstrmIn, islotIn, psstrmOut, islotOut, -1);
-
- psstrmIn->UnwindInput(islotIn, PreBidiPass());
- psstrmOut->UnwindOutput(islotOut, IsPosPass());
-
- if (psstrmIn->ReadPos() < psstrmIn->SlotsSkippedToResync())
- {
- ptman->Pass(m_ipass - 1)->UndoResyncSkip();
- psstrmIn->ClearSlotsSkippedToResync();
- }
- if (psstrmOut->WritePos() < psstrmOut->SlotsSkippedToResync())
- {
- Assert(psstrmOut->SlotsSkippedToResync() == m_pzpst->m_cslotSkipToResync);
- UndoResyncSkip();
- psstrmOut->ClearSlotsSkippedToResync();
- }
-
- if (ptman->LoggingTransduction())
- m_pzpst->UnwindLogInfo(islotIn, islotOut);
-
- return islotOut;
-}
-
-/*----------------------------------------------------------------------------------------------
- For a GrBidiPass, just unwind to the beginning of the reordered chunk.
-----------------------------------------------------------------------------------------------*/
-int GrBidiPass::Unwind(GrTableManager * ptman,
- int islotChanged, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- bool fFirst)
-{
- int islotIn;
- int islotOut;
-
- if (islotChanged == 0)
- {
- islotIn = 0;
- islotOut = 0;
- }
- else {
- islotIn = min(islotChanged, psstrmIn->ReadPos());
- islotIn = max(islotIn - 1, 0);
- while (islotIn > 0 && !StrongDir(psstrmIn->SlotAt(islotIn)->Directionality()))
- {
- psstrmIn->SlotAt(islotIn)->ZapDirLevel();
- islotIn--;
- }
- Assert(islotIn == 0 || psstrmIn->SlotAt(islotIn)->DirHasBeenProcessed());
- islotOut = 0;
- while (islotIn > 0 && (islotOut = psstrmIn->ChunkInNext(islotIn)) == -1)
- --islotIn;
- }
-
- if (islotOut == -1 || islotOut == -2)
- islotOut = 0;
-
- // Now we've found a chunk boundary; islotI and islotO are the positions in the
- // input and output streams, respectively.
-
- psstrmIn->UnwindInput(islotIn, false);
- psstrmOut->UnwindOutput(islotOut, false);
-
- if (psstrmOut->WritePos() < m_pzpst->m_cslotSkipToResync)
- {
- Assert(false); // shouldn't be any of this mess for the Bidi pass
- m_pzpst->m_fDidResyncSkip = false;
- }
-
- if (ptman->LoggingTransduction())
- m_pzpst->UnwindLogInfo(islotIn, islotOut);
-
- return islotOut;
-}
-
-/*----------------------------------------------------------------------------------------------
- Reinitialize part of the transduction logging information when we unwind the pass.
-----------------------------------------------------------------------------------------------*/
-void PassState::UnwindLogInfo(int islotIn, int islotOut)
-{
- while (m_crulrec > 0 && m_rgrulrec[m_crulrec-1].m_islot >= islotIn)
- {
- m_crulrec--;
- m_rgrulrec[m_crulrec].m_islot = 0;
- m_rgrulrec[m_crulrec].m_irul = 0;
- m_rgrulrec[m_crulrec].m_fFired = false;
- }
-
- for (int islot = islotOut; islot < 128; islot++)
- {
- m_rgcslotDeletions[islot] = 0;
- m_rgfInsertion[islot] = false;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Undo the side effects of attachments, ie, fix up the attachment trees as we unwind.
-
- @param islotLB the index of the line-break that was just inserted, or -1 if this is
- not the first pass to include line-breaks; we want to skip this slot
- in the processing in this method
-
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-//:Ignore
-void GrPosPass::Unattach(GrSlotStream * psstrmIn, int islotIn,
- GrSlotStream * psstrmOut, int islotOut, int islotLB)
-{
- // Because this is a positioning pass, there is a one-to-one correspondence between
- // the slots in the input and the slots in the output. Thus we can make simplifying
- // assumptions. Specifically, the chunk sizes are equal, except for the possiblity
- // of a LB slot that we just inserted in the input stream.
-#if 0
-
-#ifdef _DEBUG
- int islotDiff = (psstrmIn->ReadPos() - islotIn) - (psstrmOut->WritePos() - islotOut);
- if (islotLB == -1)
- Assert(islotDiff == 0);
- else
- Assert(islotDiff == 1);
-#endif // _DEBUG
-
- int islotInLp = psstrmIn->ReadPos();
- int islotOutLp = psstrmOut->WritePos();
- for ( ; islotInLp-- > islotIn && islotOutLp-- > islotOut; )
- {
- if (islotLB == islotInLp)
- {
- GrSlotState * pslotTmp = psstrmIn->SlotAt(islotInLp);
- islotInLp--;
- }
-
- GrSlotState * pslotIn = psstrmIn->SlotAt(islotInLp);
- GrSlotState * pslotOut = psstrmOut->SlotAt(islotOutLp);
-
- if (pslotIn != pslotOut)
- {
- GrSlotState * pslotInRoot = pslotIn->AttachRoot();
- GrSlotState * pslotOutRoot = pslotOut->AttachRoot();
-
- if (pslotOutRoot)
- pslotOutRoot->RemoveLeaf(pslotOut);
- if (pslotInRoot)
- pslotInRoot->AddLeaf(pslotIn);
- }
- }
-#endif // 0
-}
-//:End Ignore
-
-
-/*----------------------------------------------------------------------------------------------
- Record the fact that the given rule's constraint failed, for the purpose of logging
- the transduction process.
-----------------------------------------------------------------------------------------------*/
-void GrPass::RecordRuleFailed(int islot, int irul)
-{
- m_pzpst->RecordRule(islot, irul, false);
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Record the fact that the given rule fired, for the purpose of logging
- the transduction process.
-----------------------------------------------------------------------------------------------*/
-void GrPass::RecordRuleFired(int islot, int irul)
-{
- m_pzpst->RecordRule(islot, irul, true);
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Record the fact that we forcibly advanced due to the max-rule-loop.
-----------------------------------------------------------------------------------------------*/
-void GrPass::RecordHitMaxRuleLoop(int islot)
-{
- m_pzpst->RecordRule(islot, PassState::kHitMaxRuleLoop);
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Record the fact that we forcibly advanced due to the max-backup.
-
- In theory it should be possible to call this, but in reality, it is pretty hard to be
- able to say that there is a rule that would have fired except it was prevent by
- MaxBackup. So currently this method is not called.
-----------------------------------------------------------------------------------------------*/
-void GrPass::RecordHitMaxBackup(int islot)
-{
- m_pzpst->RecordRule(islot, PassState::kHitMaxBackup);
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Record some rule-related activity on a slot.
-----------------------------------------------------------------------------------------------*/
-void PassState::RecordRule(int islot, int irul, bool fFired)
-{
- if (m_crulrec >= 128)
- return;
-
- m_rgrulrec[m_crulrec].m_irul = irul;
- m_rgrulrec[m_crulrec].m_islot = islot;
- m_rgrulrec[m_crulrec].m_fFired = true;
- m_rgrulrec[m_crulrec].m_fFired = fFired;
- m_crulrec++;
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Record the fact that a slot was deleted before the given slot (in the output).
-----------------------------------------------------------------------------------------------*/
-void PassState::RecordDeletionBefore(int islot)
-{
- if (islot >= 128)
- return;
-
- (m_rgcslotDeletions[islot])++;
-}
-
-/*----------------------------------------------------------------------------------------------
- Record the fact that the given slot was inserted into the output.
-----------------------------------------------------------------------------------------------*/
-void PassState::RecordInsertionAt(int islot)
-{
- if (islot >= 128)
- return;
-
- m_rgfInsertion[islot] = true;
-}
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/GrPass.h b/Build/source/libs/graphite-engine/src/segment/GrPass.h
deleted file mode 100644
index d4d6a16a9dc..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrPass.h
+++ /dev/null
@@ -1,748 +0,0 @@
-/*--------------------------------------------------------------------*//*:Ignore this sentence.
-Copyright (C) 1999 - 2008 SIL International. All rights reserved.
-
-Distributable under the terms of either the Common Public License or the
-GNU Lesser General Public License, as specified in the LICENSING.txt file.
-
-File: GrPass.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- The GrPass class and subclasses.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef PASS_INCLUDED
-#define PASS_INCLUDED
-
-//:End Ignore
-
-namespace gr
-{
-
-/*----------------------------------------------------------------------------------------------
- This class stores the state of processing in a single pass.
-
- Hungarian: zpst
-----------------------------------------------------------------------------------------------*/
-
-class PassState {
- friend class GrPass;
- friend class GrGlyphGenPass;
- friend class GrLineBreakPass;
- friend class GrSubPass;
- friend class GrBidiPass;
- friend class GrPosPass;
- friend class FontMemoryUsage;
-
-public:
- PassState()
- {
- }
-
- void InitForNewSegment(int ipass, int nMaxChunk);
- void InitializeLogInfo();
-
- int MaxChunk()
- {
- return m_nMaxChunk;
- }
-
- void SetResyncSkip(int c)
- {
- m_cslotSkipToResync = c;
- m_fDidResyncSkip = false;
- }
- int NeededToResync()
- {
- if (m_fDidResyncSkip)
- return 0;
- return m_cslotSkipToResync;
- }
- bool DidResyncSkip()
- {
- return m_fDidResyncSkip;
- }
- bool CanResyncSkip(GrSlotStream * psstrmOutput)
- {
- if (m_fDidResyncSkip)
- return true; // already did it
- // Are we in the position to do the resync-skip?
- return m_cslotSkipToResync <= psstrmOutput->WritePos();
- }
- int DoResyncSkip(GrSlotStream * psstrmOutput);
- void UndoResyncSkip()
- {
- m_fDidResyncSkip = false;
- }
-
- void UnwindLogInfo(int islotIn, int islotOut);
- void RecordRule(int islot, int irul, bool fFired = false);
- void RecordDeletionBefore(int islot);
- void RecordInsertionAt(int islot);
-#ifdef TRACING
- void LogRulesFiredAndFailed(std::ostream & strmOut, GrSlotStream * psstrmIn);
- void LogInsertionsAndDeletions(std::ostream & strmOut, GrSlotStream * psstrmOut);
- void LogXmlRules(std::ostream & strmOut, GrTableManager *, GrSlotStream * psstrmIn, int nIndent);
- void LogXmlGlyphs(std::ostream & strmOut, GrTableManager * ptman, GrSlotStream * psstrmOut,
- int ipassJust1, bool fPreJust, bool fPostJust, bool fBidi, bool fBidiNext, int cslotsSkipped,
- int nIndent);
-#endif // TRACING
-
-protected:
- int m_ipass;
-
- // Used to avoid infinite loops. If m_nRulesSinceAdvance > m_nMaxRuleLoop,
- // and we have not passed the stream's ReadPosMax, forcibly advance.
- int m_nRulesSinceAdvance;
-
- // Maximum length of chunk, used when unwinding the streams during backtracking. This
- // must be initialized to m_nMaxRuleContext, but that is not always adequate, because
- // when there is reprocessing going on the chunks may be longer.
- int m_nMaxChunk;
-
- // Indicates how much of the pass's initial output should be automatically
- // skipped over in order to resync with a chunk boundary. This handles the situation
- // where we are reprocessing a little of the previous segment in order to handle
- // cross-line-boundary contextuals. The goal is to skip over the output until we hit
- // what we know (from processing the previous segment) is a chunk boundary.
- //
- // In most cases (and always when this is the first segment of the
- // writing system) this number is 0.
- int m_cslotSkipToResync;
- bool m_fDidResyncSkip;
-
- enum {
- kHitMaxBackup = -1,
- kHitMaxRuleLoop = -2
- };
-
- // For logging transduction process: record of one rule matched or fired
- struct RuleRecord
- {
- int m_irul; // rule index, or kHitMaxBackup or kHitMaxRuleLoop
- int m_islot; // slot index of input stream
- bool m_fFired;
- };
- RuleRecord m_rgrulrec[128];
- int m_crulrec;
-
- int m_rgcslotDeletions[128]; // number of deletions before slot i in output
- bool m_rgfInsertion[128]; // true if slot i in output was inserted
-};
-
-/*----------------------------------------------------------------------------------------------
- This class handles finding and applying rules from the pass and storing
- the results in the appropriate stream.
-
- Hungarian: pass
-----------------------------------------------------------------------------------------------*/
-class GrPass {
- friend class FontMemoryUsage;
-
-protected:
- // Action command codes; these MUST match the corresponding definitions in the compiler:
- enum ActionCommand {
- kopNop = 0,
-
- kopPushByte, kopPushByteU, kopPushShort, kopPushShortU, kopPushLong,
-
- kopAdd, kopSub, kopMul, kopDiv,
- kopMin, kopMax,
- kopNeg,
- kopTrunc8, kopTrunc16,
-
- kopCond,
-
- kopAnd, kopOr, kopNot,
- kopEqual, kopNotEq,
- kopLess, kopGtr, kopLessEq, kopGtrEq,
-
- kopNext, kopNextN, kopCopyNext,
- kopPutGlyph8bitObs, kopPutSubs8bitObs, kopPutCopy,
- kopInsert, kopDelete,
- kopAssoc,
- kopCntxtItem,
-
- kopAttrSet, kopAttrAdd, kopAttrSub,
- kopAttrSetSlot,
- kopIAttrSetSlot,
- kopPushSlotAttr, kopPushGlyphAttrObs,kopPushGlyphMetric, kopPushFeat,
- kopPushAttToGAttrObs, kopPushAttToGlyphMetric,
- kopPushISlotAttr,
-
- kopPushIGlyphAttr, // not implemented
-
- kopPopRet, kopRetZero, kopRetTrue,
- kopIAttrSet, kopIAttrAdd, kopIAttrSub,
- kopPushProcState, kopPushVersion,
- kopPutSubs, kopPutSubs2, kopPutSubs3,
- kopPutGlyph, kopPushGlyphAttr, kopPushAttToGlyphAttr
-
- };
-
- enum StackMachineFlag {
- ksmfDone = 0,
- ksmfContinue,
- ksmfUnderflow,
- ksmfStackNotEmptied
- };
-
-public:
- // Constructor:
- GrPass(int i);
- // Destructor:
- virtual ~GrPass();
-
- int PassNumber() { return m_ipass; }
-
- bool ReadFromFont(GrIStream & grstrm, int fxdSilfVersion, int fxdRuleVersion, int nOffset);
- void InitializeWithNoRules();
-
- virtual void SetTopDirLevel(int n)
- { // only GrBidiPass does anything interesting
- }
-
- void SetPassState(PassState * pzpst)
- {
- m_pzpst = pzpst;
- }
-
- virtual void ExtendOutput(GrTableManager *,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput, int nslotToGet,
- TrWsHandling twsh,
- int * pnRet, int * pcslotGot, int * pislotFinalBreak);
-
- int ExtendGlyphIDOutput(GrTableManager *, GrCharStream *,
- GrSlotStream *, int ichSegLim, int cchwPostXlbContext,
- LineBrk lb, int cslotToGet, bool fNeedFinalBreak,
- TrWsHandling twsh, int * pislotFinalBreak);
-
- int ExtendFinalOutput(GrTableManager *, GrSlotStream * psstrmInput,
- GrSlotStream * psstrmOutput,
- float xsSpaceAllotted, bool fWidthIsCharCount, bool fInfiniteWidth,
- bool fHaveLineBreak, bool fMustBacktrack,
- LineBrk lbMax, TrWsHandling twsh,
- int * pislotLB, float * pxsWidth);
-
- int RemoveTrailingWhiteSpace(GrTableManager * ptman, GrSlotStream * psstrmOut,
- TrWsHandling twsh, int * pislotFinalBreak);
-
- virtual int Unwind(GrTableManager * ptman,
- int islotChanged, GrSlotStream *psstrmInput, GrSlotStream * psstrmOutput,
- bool fFirst);
-
- int MaxBackup()
- {
- return m_nMaxBackup;
- }
-
- bool DidResyncSkip()
- {
- return m_pzpst->DidResyncSkip();
- }
- int DoResyncSkip(GrSlotStream * psstrmOutput)
- {
- return m_pzpst->DoResyncSkip(psstrmOutput);
- }
-
- void UndoResyncSkip()
- {
- m_pzpst->UndoResyncSkip();
- }
- void SetResyncSkip(int n)
- {
- m_pzpst->SetResyncSkip(n);
- }
-
- virtual void DoCleanUpSegMin(GrTableManager * ptman,
- GrSlotStream * psstrmIn, int islotInitReadPos, GrSlotStream * psstrmOut)
- {
- }
-
- virtual bool IsPosPass()
- {
- return false;
- }
-
- virtual bool PreBidiPass() = 0;
-
- bool RunConstraint(GrTableManager *, int ruln,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int cslotPreModContext, int cslotMatched);
-
- int RunCommandCode(GrTableManager * ptman,
- byte * pbStart, bool fConstraints,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, int islot);
-
-protected:
- int 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);
- void DoStackArithmetic2Args(ActionCommand op, std::vector<int> & vnStack,
- StackMachineFlag * psmf);
- void DoStackArithmetic1Arg(ActionCommand op, std::vector<int> & vnStack,
- StackMachineFlag * psmf);
- void DoConditional(std::vector<int> & vnStack, StackMachineFlag * psmf);
- StackMachineFlag CheckStack(std::vector<int> & vnStack, int cn);
- void DoNext(GrTableManager * ptman,
- int cslot, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPutGlyph(GrTableManager * ptman, bool fInserting, int nReplacementClass,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPutCopy(GrTableManager * ptman, bool fInserting, int cslotCopyFrom,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPutSubs(GrTableManager * ptman, bool fInserting,
- int cslotSel, int nSelClass, int nReplacementClass,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPutSubs2(GrTableManager * ptman, bool fInserting,
- int cslotSel1, int nSelClass1, int cslotSel2, int nSelClass2, int nReplacementClass,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPutSubs3(GrTableManager * ptman, bool fInserting,
- int cslotSel1, int nSelClass1, int cslotSel2, int nSelClass2, int cslotSel3, int nSelClass3,
- int nReplacementClass, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPutSubsInit(GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, bool fInserting,
- GrSlotState ** ppslotNextPut, bool * pfAtSegMin, bool * pfAtSegLim);
- void DoPutSubsAux(GrTableManager * ptman, bool fInserting, gid16 nGlyphReplacement,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, GrSlotState * pslotNextInput,
- bool fAtSegMin, bool fAtSegLim);
- void SetNeutralAssocs(GrSlotState * pslotNew, GrSlotStream * psstrmIn);
- void DoDelete(GrTableManager * ptman,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoAssoc(int cnAssocs, std::vector<int> & vnAssocs, bool fInserting,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoSetAttr(GrTableManager * ptman,
- ActionCommand op, bool fInserrting,
- SlotAttrName slat, int slati, std::vector<int> & vnStack,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPushSlotAttr(GrTableManager * ptman,
- int nSlotRef, bool fInserting,
- SlotAttrName slat, int slati, std::vector<int> & vnStack,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPushGlyphAttr(GrTableManager * ptman, int nSlotRef, bool fInserting,
- int nGlyphAttr, std::vector<int> & vnStack,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPushAttToGlyphAttr(GrTableManager * ptman, int nSlotRef, bool fInserting,
- int nGlyphAttr, std::vector<int> & vnStack,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPushGlyphMetric(GrTableManager * ptman, int nSlotRef, bool fInserting,
- int nGlyphAttr, int nAttLevel, std::vector<int> & vnStack,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPushAttToGlyphMetric(GrTableManager * ptman, int nSlotRef, bool fInserting,
- int nGlyphAttr, int nAttLevel, std::vector<int> & vnStack,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPushFeatValue(GrTableManager * ptman, int islot, bool fInsering,
- int nFeat, std::vector<int> & vnStack,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- void DoPushProcState(GrTableManager * ptman, int nPState, std::vector<int> & vnStack);
-protected:
- void DoPushGlyphMetricAux(GrTableManager * ptman,
- GrSlotState * pslot, int nGlyphAttr, int nAttLevel,
- std::vector<int> & vnStack, GrSlotStream * psstrmIn);
-public:
- int SortKeyForRule(int ruln)
- {
- Assert(ruln < m_crul);
- return m_prgchwRuleSortKeys[ruln];
- }
- int PreModContextForRule(int ruln)
- {
- Assert(ruln < m_crul);
- return m_prgcritRulePreModContext[ruln];
- }
-
- int MaxRulePreContext()
- {
- if (m_pfsm)
- return m_pfsm->MaxRulePreContext();
- else
- return 0;
- }
-
- void RecordRuleFailed(int islot, int irul);
- void RecordRuleFired(int islot, int irul);
- void RecordHitMaxRuleLoop(int islot);
- void RecordHitMaxBackup(int islot);
-#ifdef TRACING
- void LogRulesFiredAndFailed(std::ostream & strmOut, GrSlotStream * psstrmIn);
- void LogInsertionsAndDeletions(std::ostream & strmOut, GrSlotStream * psstrmOut);
- void LogXmlRules(std::ostream & strmOut, GrTableManager * ptman,
- GrSlotStream * psstrmIn, int nIndent);
- void LogXmlGlyphs(std::ostream & strmOut, GrTableManager * ptman, GrSlotStream * psstrmOut,
- int ipassJust1, bool fPreJust, bool fPostJust, int cslotsSkipped, int nIndent);
-#endif // TRACING
-
-protected:
- int CheckRuleValidity(int ruln);
-
- virtual void RunRule(GrTableManager *, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput) = 0;
-
- void CheckInputProgress(GrSlotStream* input, GrSlotStream* psstrmOutput,
- int islotOrigInput);
-
- void MapChunks(GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- int islotChunkI, int islotChunkO, int cslotReprocessed);
-
- virtual void Unattach(GrSlotStream * psstrmIn, int islotIn, // GrPosPass overrides
- GrSlotStream * psstrmOut, int islotOut, int islotLB)
- {
- }
-
- friend class EngineState; // let it call the method below
- virtual int MaxRuleContext() // GrBidiPass overrides
- {
- return m_nMaxRuleContext;
- }
-
-protected:
- // Instance variables:
-
- int m_ipass; // index of pass
-
- int m_fxdVersion;
-
- // number of items required from previous pass; don't access directly, use the getter
- // method, because GrBidiPass overrides to always use 1.
- int m_nMaxRuleContext;
-
- GrFSM * m_pfsm; // Finite State Machine to give next rule
-
- int m_nMaxRuleLoop; // maximum number of rules to process before forcibly
- // advancing input position
-
- int m_nMaxBackup;
-
- int m_crul; // number of rules
-
- // rule sort keys, indicating precedence of rules; m_crul of these
- data16 * m_prgchwRuleSortKeys;
-
- // for each rule, the number of items in the context before the first modified item
- // that the constraints need to be tested on
- byte * m_prgcritRulePreModContext;
-
- // offset for pass-level constraints; just 1 of these
- data16 m_cbPassConstraint;
- // offsets for constraint and action code; m_crul+1 of each of these (the last
- // indicates the total byte count)
- data16 * m_prgibConstraintStart;
- data16 * m_prgibActionStart;
-
- // blocks of constraint and action code
- byte * m_prgbPConstraintBlock; // pass-level constraints
- byte * m_prgbConstraintBlock; // rule constraints
- byte * m_prgbActionBlock;
-
- int m_cbConstraints; // needed for memory instrumentation only
- int m_cbActions; // needed for memory instrumentation only
-
- bool m_fHasDebugStrings;
- data16 * m_prgibConstraintDebug; // m_crul+1 of these
- data16 * m_prgibRuleDebug; // m_crul+1 of these
-
- bool m_fCheckRules;
- bool * m_prgfRuleOkay;
-
- std::vector<int> m_vnStack; // for stack machine processing (more efficient than creating the
- // vector each time)
-
- // state of process for this pass
- PassState * m_pzpst;
-
-public:
-#ifdef OLD_TEST_STUFF
- // For test procedures:
- StrAnsi m_staBehavior;
-
- virtual void SetUpTestData();
-
- // overridden on appropriate subclasses:
- virtual void SetUpReverseNumbersTest() { Assert(false); }
- virtual void SetUpBidiNumbersTest() { Assert(false); }
-
- virtual void SetUpCrossLineContextTest() { Assert(false); }
- virtual void SetUpReprocessTest() { Assert(false); }
- virtual void SetUpLineEdgeContextTest(int ipass) { Assert(false); }
- virtual void SetUpBidiAlgorithmTest() { Assert(false); }
- virtual void SetUpPseudoGlyphsTest() { Assert(false); }
- virtual void SetUpSimpleFSMTest() { Assert(false); }
- virtual void SetUpRuleActionTest() { Assert(false); }
- virtual void SetUpRuleAction2Test() { Assert(false); }
- virtual void SetUpAssocTest() { Assert(false); }
- virtual void SetUpAssoc2Test() { Assert(false); }
- virtual void SetUpDefaultAssocTest() { Assert(false); }
- virtual void SetUpFeatureTest() { Assert(false); }
- virtual void SetUpLigatureTest() { Assert(false); }
- virtual void SetUpLigature2Test() { Assert(false); }
-#endif // OLD_TEST_STUFF
-
-}; // end of class GrPass
-
-
-/*----------------------------------------------------------------------------------------------
- The initial pass that generates glyph IDs from Unicode input.
-
- Hungarian: pass
-----------------------------------------------------------------------------------------------*/
-class GrGlyphGenPass : public GrPass
-{
- friend class FontMemoryUsage;
-
-public:
- GrGlyphGenPass(int ipass) : GrPass(ipass)
- {
- }
-
- virtual bool PreBidiPass()
- {
- return true;
- }
-
-protected:
- // Irrelevant when generating glyphs.
- virtual void RunRule(GrTableManager *, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
- {
- Assert(false);
- }
-
-}; // end of class GrGlyphGenPass
-
-
-/*----------------------------------------------------------------------------------------------
- A pass containing rules that set the break weight values.
-
- Hungarian: pass
-----------------------------------------------------------------------------------------------*/
-class GrLineBreakPass : public GrPass
-{
- friend class FontMemoryUsage;
-
-public:
- GrLineBreakPass(int ipass) : GrPass(ipass)
- {
- }
-
- virtual bool PreBidiPass()
- {
- return true;
- }
-
-protected:
- virtual void RunRule(GrTableManager *, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput);
-
-public:
-#ifdef OLD_TEST_STUFF
- // For test procedures:
- bool RunTestRules(GrTableManager *, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
- bool RunTestRules(GrTableManager *, int ruln, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
-
- virtual void SetUpCrossLineContextTest();
- bool RunCrossLineContextTest(GrTableManager*, GrSlotStream* psstrmIn,
- GrSlotStream* psstrmOut);
-
- virtual void SetUpReprocessTest();
- bool RunReprocessTest(GrTableManager *, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut);
-
- virtual void SetUpAssocTest();
- virtual void SetUpLigatureTest();
-#endif // OLD_TEST_STUFF
-
-}; // end of class GrLineBreakPass
-
-
-/*----------------------------------------------------------------------------------------------
- A pass containing substitution rules.
-
- Hungarian: pass
-----------------------------------------------------------------------------------------------*/
-class GrSubPass : public GrPass
-{
- friend class FontMemoryUsage;
-
-public:
- GrSubPass(int ipass) : GrPass(ipass)
- {
- }
-
- virtual bool PreBidiPass()
- {
- return true;
- }
-
-protected:
- virtual void RunRule(GrTableManager *, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput);
-
- virtual void DoCleanUpSegMin(GrTableManager * ptman,
- GrSlotStream * psstrmIn, int islotInitReadPos, GrSlotStream * psstrmOut);
-
-public:
-#ifdef OLD_TEST_STUFF
- // For test procedures:
- bool RunTestRules(GrTableManager *, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
- bool RunTestRules(GrTableManager *, int ruln, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
-
- virtual void SetUpReverseNumbersTest();
- bool RunReverseNumbersTest(GrTableManager*, GrSlotStream* psstrmIn,
- GrSlotStream* psstrmOut);
-
- virtual void SetUpBidiNumbersTest();
- bool RunBidiNumbersTest(GrTableManager*, GrSlotStream* psstrmIn,
- GrSlotStream* psstrmOut);
-
- virtual void SetUpCrossLineContextTest();
- bool RunCrossLineContextTest(GrTableManager*, GrSlotStream* psstrmIn,
- GrSlotStream* psstrmOut);
-
- virtual void SetUpReprocessTest();
- bool RunReprocessTest(GrTableManager *, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
-
- virtual void SetUpLineEdgeContextTest(int ipass);
- bool RunLineEdgeContextTest(GrTableManager *, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
-
- virtual void SetUpBidiAlgorithmTest();
- bool RunBidiAlgorithmTest(GrTableManager *, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
-
- virtual void SetUpPseudoGlyphsTest();
- bool RunPseudoGlyphsTest(GrTableManager *, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
-
- virtual void SetUpSimpleFSMTest();
- bool RunSimpleFSMTest(GrTableManager *, int ruln, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
- virtual void SetUpRuleActionTest();
- virtual void SetUpRuleAction2Test();
- virtual void SetUpAssocTest();
- virtual void SetUpAssoc2Test();
- virtual void SetUpDefaultAssocTest();
- virtual void SetUpFeatureTest();
- virtual void SetUpLigatureTest();
- virtual void SetUpLigature2Test();
-#endif // OLD_TEST_STUFF
-
-}; // end of class GrSubPass
-
-
-/*----------------------------------------------------------------------------------------------
- This class is the one the knows how to handle bidi reordering, including backtracking.
-
- Hungarian: pass
-----------------------------------------------------------------------------------------------*/
-class GrBidiPass : public GrSubPass
-{
- friend class FontMemoryUsage;
-
-public:
- // Constructor:
- GrBidiPass(int ipass)
- : GrSubPass(ipass),
- m_nTopDirection(0)
- {
- }
-
- virtual void SetTopDirLevel(int n)
- {
- m_nTopDirection = n;
- }
-
- virtual bool PreBidiPass()
- {
- return false;
- }
-
- virtual void ExtendOutput(GrTableManager *,
- GrSlotStream * psstrmI, GrSlotStream * psstrmO, int nslotToGet,
- TrWsHandling twsh,
- int * pnRet, int * pcslotGot, int * pislotFinalBreak);
-
- virtual int Unwind(GrTableManager * ptman,
- int islotChanged, GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- bool fFirst);
-protected:
- virtual int MaxRuleContext()
- {
- return 1;
- }
-
-private:
- //void OldReverse(int nCurrDirection,
- // GrSlotStream * psstrmI, int islotI1, int islotI2,
- // GrSlotStream * psstrmO, int islotO1, int islotO2);
-
- int Reverse(GrTableManager * ptman,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut,
- std::vector<int> & vislotStarts, std::vector<int> & vislotStops);
-
-protected:
- // Instance variables:
- int m_nTopDirection; // 0 for LTR, 1 for RTL -- CURRENTLY NOT USED; need to
- // initialize it when we set the writing system direction
-
-#ifdef OLD_TEST_STUFF
-public:
- // For test procedures:
- ////virtual void SetUpTestData();
- virtual void SetUpBidiNumbersTest();
- virtual void SetUpBidiAlgorithmTest();
-#endif // OLD_TEST_STUFF
-
-}; // end of class GrBidiPass
-
-
-/*----------------------------------------------------------------------------------------------
- A pass containing positioning rules.
-
- Hungarian: pass
-----------------------------------------------------------------------------------------------*/
-class GrPosPass : public GrPass
-{
- friend class FontMemoryUsage;
-
-public:
- GrPosPass(int ipass) : GrPass(ipass)
- {
- }
-
- virtual bool IsPosPass()
- {
- return true;
- }
-
- virtual bool PreBidiPass()
- {
- return false;
- }
-
-protected:
- virtual void RunRule(GrTableManager *, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput);
-
- virtual void Unattach(GrSlotStream * psstrmIn, int islotIn,
- GrSlotStream * psstrmOut, int islotOut, int islotLB);
-
-public:
-#ifdef OLD_TEST_STUFF
- // For test procedures:
- bool RunTestRules(GrTableManager *, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
- bool RunTestRules(GrTableManager *, int ruln, GrSlotStream * psstrmIn,
- GrSlotStream * psstrmOut);
-#endif // OLD_TEST_STUFF
-
-}; // end of class GrPosPass
-
-} // namespace gr
-
-
-#endif // PASS_INCLUDED
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
diff --git a/Build/source/libs/graphite-engine/src/segment/GrPseudoMap.h b/Build/source/libs/graphite-engine/src/segment/GrPseudoMap.h
deleted file mode 100644
index c6fec210808..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrPseudoMap.h
+++ /dev/null
@@ -1,48 +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: GrPseudoMap.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- The GrPseudoMap class.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef GR_PSEUDOMAP_INCLUDED
-#define GR_PSEUDOMAP_INCLUDED
-
-//:End Ignore
-
-namespace gr
-{
-
-/*----------------------------------------------------------------------------------------------
- A mapping between a Unicode value and a pseudo-glyph.
-
- Hungarian: psd
-----------------------------------------------------------------------------------------------*/
-
-class GrPseudoMap
-{
-public:
- unsigned int Unicode() { return m_nUnicode; }
- gid16 PseudoGlyph() { return m_chwPseudo; }
-
- void SetUnicode(int n) { m_nUnicode = n; }
- void SetPseudoGlyph(gid16 chw) { m_chwPseudo = chw; }
-
-protected:
- // Instance variables:
- unsigned int m_nUnicode;
- gid16 m_chwPseudo;
-};
-
-} // namespace gr
-
-#endif // !GR_PSEUDOMAP_INCLUDED
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
diff --git a/Build/source/libs/graphite-engine/src/segment/GrSlotState.h b/Build/source/libs/graphite-engine/src/segment/GrSlotState.h
deleted file mode 100644
index d000927d1a4..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrSlotState.h
+++ /dev/null
@@ -1,1287 +0,0 @@
-/*--------------------------------------------------------------------*//*:Ignore this sentence.
-Copyright (C) 1999 - 2008 SIL International. All rights reserved.
-
-Distributable under the terms of either the Common Public License or the
-GNU Lesser General Public License, as specified in the LICENSING.txt file.
-
-File: GrSlotState.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Copyright (C) 1999 by SIL International. All rights reserved.
-
-Description:
- Classes GrSlotAbstract, GrSlotState, and GrSlotOutput
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef SLOTSTATE_INCLUDED
-#define SLOTSTATE_INCLUDED
-
-namespace gr
-{
-
-class GrSlotAbstract;
-class GrSlotState;
-class GrSlotOutput;
-class GrSlotStream;
-class Font;
-
-//:End Ignore
-
-
-/*----------------------------------------------------------------------------------------------
- Subsumes GrSlotState and GrSlotOutput, both of which represent a single glyph
- and its slot attributes and features.
-
- Hungarian: slab
-----------------------------------------------------------------------------------------------*/
-class GrSlotAbstract
-{
- friend class GrSlotStream;
- friend class GlyphInfo;
-
-public:
- // Constructor:
- GrSlotAbstract()
- {
- }
-
- ~GrSlotAbstract()
- {
- // the table manager is responsible for destroying the contents of m_prgnVarLenBuf
- }
-
- void BasicInitializeAbstract(int cnCompPerLig, u_intslot * pnBuf)
- {
- m_dirc = kNotYetSet8;
- m_lb = kNotYetSet8;
- m_fInsertBefore = true;
- m_nDirLevel = -1;
-
- m_bIsSpace = -1; // unknown
-
- m_fInsertBefore = true;
-
- m_mMeasureSol = 0;
- m_mMeasureEol = 0;
-
- m_mJStretch0 = 0;
- m_mJShrink0 = 0;
- m_mJStep0 = 0;
- m_nJWeight0 = 0;
- m_mJWidth0 = 0;
-
- m_cnCompPerLig = byte(cnCompPerLig);
- m_prgnVarLenBuf = pnBuf;
- }
-
- void CopyAbstractFrom(GrSlotState * pslot);
-
- void SetBufferPtr(u_intslot * pn)
- {
- m_prgnVarLenBuf = pn;
- }
-
- gid16 GlyphID() { return m_chwGlyphID; }
- gid16 RawActualGlyph() { return m_chwActual; }
- float GetGlyphMetric(Font * pfont, int nGlyphMetricID, gid16 chwGlyphID);
-
- //GrSlotState * CompRefSlot(int i);
-
- int BreakWeight()
- {
- return (int)m_lb;
- }
- DirCode Directionality()
- {
- return DirCode(int(m_dirc));
- }
- int InsertBefore()
- {
- return m_fInsertBefore;
- }
- int MeasureSol()
- {
- return m_mMeasureSol;
- }
- int MeasureEol()
- {
- return m_mMeasureEol;
- }
-
- int DirLevel()
- {
- return m_nDirLevel;
- }
-
- int SpecialSlotFlag()
- {
- return m_spsl;
- }
- void SetSpecialSlotFlag(int spsl)
- {
- m_spsl = sdata8(spsl);
- }
-
- enum {
- kNotYetSet = 0x7FFF,
- kNotYetSet8 = 0x7F,
- kInvalidGlyph = 0xFFFF
- };
-
- gid16 ActualGlyphForOutput(GrTableManager * ptman);
-
- // Needed for GlyphInfo:
- float XPosition()
- {
- return m_xsPositionX;
- }
- float YPosition()
- {
- return m_ysPositionY; // relative to baseline (positive is up)
- }
-
-protected:
- gid16 m_chwGlyphID;
- gid16 m_chwActual; // actual glyph to output (which is a different glyph for pseudos)
-
- sdata8 m_spsl; // special slot flag: LB, bidi marker
-
-// bool m_fInitialLB; // for LB slots: true if this is the initial LB;
- // false if it is the terminating LB
- // TODO: remove
-
- sdata8 m_dirc; // default = kNotYetSet8 (read from glyph attr)
- sdata8 m_lb; // default = kNotYetSet8 (read from glyph attr)
-
- sdata8 m_nDirLevel;
-
- // Slot attributes that are used by GrSlotOutput:
- short m_mMeasureSol;
- short m_mMeasureEol;
-
- unsigned short m_mJStretch0;
- unsigned short m_mJShrink0;
- unsigned short m_mJStep0;
- int m_mJWidth0;
- byte m_nJWeight0;
-
- bool m_fInsertBefore; // default = true
-
- sdata8 m_bIsSpace; // 0 = false, 1 = true, -1 = unknown
-
- byte m_cnCompPerLig;
- // There is a large block managed by either the GrTableManager (for GrSlotState)
- // or the segment (for GrSlotOutput); this variable points at the sub-buffer for this
- // particular slot:
- u_intslot * m_prgnVarLenBuf;
-
- float m_xsPositionX;
- float m_ysPositionY;
-
-}; // end of class GrSlotAbstract
-
-
-/*----------------------------------------------------------------------------------------------
- A GrSlotState represents one slot as modified by a pass in the table.
- Each time a slot state is modified, a new instance is created, copying the relevant
- information.
-
- Hungarian: slot
-
- Other hungarian:
- m - integer indicating glyph design units ("em-units")
- sr - integer indicating slot reference
-----------------------------------------------------------------------------------------------*/
-class GrSlotState : public GrSlotAbstract
-{
- friend class GrSlotStream;
- friend class FontMemoryUsage;
-
-public:
- enum { kNeutral = 99 };
-
- // Constructors:
- GrSlotState()
- : GrSlotAbstract(),
- m_pslotPrevState(NULL)
- {
- m_vpslotAssoc.clear();
- //m_fInitialLB = false; // TODO: remove
- m_spsl = kspslNone;
- m_fNeutralAssocs = false;
- m_dircProc = kdircUnknown;
- m_fDirProcessed = false;
-
- m_vdislotAttLeaves.clear();
- m_fAttachMod = false;
- m_fShiftMod = false;
- m_dislotRootFixed = 0;
- ZapCompositeMetrics();
- }
-
- ~GrSlotState()
- {
- }
-
- void BasicInitialize(int cnUserDefn, int cnCompPerLig, int cnFeat, u_intslot * pnBuf)
- {
- BasicInitializeAbstract(cnCompPerLig, pnBuf);
-
- m_xysGlyphWidth = -1;
- m_xysFontAscent = -1;
- m_xysFontDescent = -1;
-
- m_mAdvanceX = kNotYetSet;
- m_mAdvanceY = kNotYetSet;
- m_mShiftX = 0;
- m_mShiftY = 0;
-
- m_fAdvXSet = false; // for transduction logging
- m_fAdvYSet = false;
-
- m_srAttachTo = 0;
- m_nAttachLevel = 0;
-
- m_mAttachAtX = kNotYetSet;
- m_mAttachAtY = 0;
- m_nAttachAtGpoint = kNotYetSet;
- m_mAttachAtXOffset = 0;
- m_mAttachAtYOffset = 0;
- m_mAttachWithX = kNotYetSet;
- m_mAttachWithY = 0;
- m_nAttachWithGpoint = kNotYetSet;
- m_mAttachWithXOffset = 0;
- m_mAttachWithYOffset = 0;
-
- m_islotPosPass = kNotYetSet;
-
- m_cnUserDefn = byte(cnUserDefn);
- m_cnFeat = byte(cnFeat);
-
- m_fHasComponents = false;
- }
-
- void Initialize(gid16 chw, GrEngine *, GrFeatureValues fval,
- int ipass, int ichwSegOffset, int nUnicode = -1);
- void Initialize(gid16 chw, GrEngine *, GrSlotState * pslotFeat,
- int ipass, int ichwSegOffset);
- void Initialize(gid16 chw, GrEngine *, GrSlotState * pslotFeat,
- int ipass);
-
- void InitializeFrom(GrSlotState * pslot, int ipass);
- void CopyFeaturesFrom(GrSlotState * pslotSrc);
- void FixAttachmentTree(GrSlotState * pslotOld);
-
- void CopyFrom(GrSlotState * pslot, bool fCopyEverything = true);
-
- // General:
- int RawSegOffset() { return m_ichwSegOffset; }
-
- void SetGlyphID(gid16 chw)
- {
- m_chwGlyphID = chw;
- m_chwActual = kInvalidGlyph;
- m_xysGlyphWidth = -1; // indicate glyph metrics are invalid
- m_ipassFsmCol = -1;
- m_colFsm = -1;
- }
-
- int PosPassIndex()
- {
- return m_islotPosPass;
- }
- void SetPosPassIndex(int islot, bool fInputToPosPass1)
- {
- // If we're resetting it, it should be to the same value as before:
- Assert(fInputToPosPass1 || m_islotPosPass == kNotYetSet || m_islotPosPass == islot);
- m_islotPosPass = islot;
- }
- void IncPosPassIndex()
- {
- m_islotPosPass++;
- }
- void ZapPosPassIndex()
- {
- m_islotPosPass = kNotYetSet;
- }
-
- int StyleIndex() { return m_bStyleIndex; }
-
- int AttachTo() { return m_srAttachTo; }
- int AttachLevel() { return m_nAttachLevel; }
-
- int RawAttachAtX() { return m_mAttachAtX; }
- int AttachAtY() { return m_mAttachAtY; }
- int AttachAtGpoint() { return m_nAttachAtGpoint; }
- int AttachAtXOffset() { return m_mAttachAtXOffset; }
- int AttachAtYOffset() { return m_mAttachAtYOffset; }
-
- int RawAttachWithX() { return m_mAttachWithX; }
- int AttachWithY() { return m_mAttachWithY; }
- int AttachWithGpoint() { return m_nAttachWithGpoint; }
- int AttachWithXOffset() { return m_mAttachWithXOffset; }
- int AttachWithYOffset() { return m_mAttachWithYOffset; }
-
- void Associate(GrSlotState *);
- void Associate(GrSlotState *, GrSlotState *);
- void Associate(std::vector<GrSlotState*> &);
- void ClearAssocs();
-
- int AssocsSize() { return m_vpslotAssoc.size(); }
- GrSlotState * RawBeforeAssocSlot()
- {
- if (m_vpslotAssoc.size() == 0)
- return NULL;
- return m_vpslotAssoc[0];
- }
- GrSlotState * RawAfterAssocSlot()
- {
- if (m_vpslotAssoc.size() == 0)
- return NULL;
- return m_vpslotAssoc.back();
- }
- ////GrSlotState * AssocSlot(int i) { return m_vpslotAssoc[i]; }
-
- GrSlotState * AssocSlot(int i)
- {
- if (i < 0)
- return NULL;
- if (i >= signed(m_vpslotAssoc.size()))
- return NULL;
-
- GrSlotState * pslotAssoc = m_vpslotAssoc[i];
- // handle possible reprocessing
- while (pslotAssoc && pslotAssoc->PassModified() == m_ipassModified)
- pslotAssoc = pslotAssoc->m_pslotPrevState;
- return pslotAssoc;
- }
-
- void AllAssocs(std::vector<int> & vichw);
- int BeforeAssoc();
- int AfterAssoc();
-
- void CleanUpAssocs();
-
- void SetComponentRefsFor(GrSlotOutput *, int iComp = -1);
- void AllComponentRefs(std::vector<int> & vichw);
-
- int PassModified() { return m_ipassModified; }
- int SegOffset();
- int UnderlyingPos();
- GrSlotState * PrevState() { return m_pslotPrevState; }
-
- void MarkDeleted() // for now, do nothing
- {
- }
-
- int IsSpace(GrTableManager * ptman);
-
- // TODO: remove argument from these methods; it is no longer needed.
- bool IsLineBreak(gid16 chwLB)
- {
- return (IsInitialLineBreak(chwLB) || IsFinalLineBreak(chwLB));
- //return (m_chwGlyphID == chwLB); // TODO: remove
- }
- bool IsInitialLineBreak(gid16 chwLB)
- {
- return (m_spsl == kspslLbInitial);
- //return (IsLineBreak(chwLB) && m_fInitialLB == true); // TODO: remove
- }
- bool IsFinalLineBreak(gid16 chwLB)
- {
- return (m_spsl == kspslLbFinal);
- //return (IsLineBreak(chwLB) && m_fInitialLB == false); // TODO: remove
- }
-
- bool IsBidiMarker()
- {
- switch (m_spsl)
- {
- case kspslLRM:
- case kspslRLM:
- case kspslLRO:
- case kspslRLO:
- case kspslLRE:
- case kspslRLE:
- case kspslPDF:
- return true;
- default:
- return false;
- }
- return false;
- }
-
- bool HasComponents() { return m_fHasComponents; }
-
- // Directionality as determined by the bidi algorithm
- DirCode DirProcessed() // return the value
- {
- Assert(m_dirc != kNotYetSet8);
- if (m_dircProc == kdircUnknown)
- m_dircProc = DirCode(m_dirc);
- return m_dircProc;
- }
- void SetDirProcessed(DirCode dirc) // set the directionality
- {
- m_dircProc = dirc;
- }
- bool DirHasBeenProcessed() // has this slot been fully processed?
- {
- return m_fDirProcessed;
- }
- void MarkDirProcessed() // this slot has been fully processed
- {
- m_fDirProcessed = true;
- }
-
- int RawAdvanceX() { return m_mAdvanceX; }
- int RawAdvanceY() { return m_mAdvanceY; }
- int ShiftX() { return m_mShiftX; }
- int ShiftY() { return m_mShiftY; }
-
- // Slot attributes that must be calculated:
-
- int AdvanceX(GrTableManager * ptman)
- {
- if (m_mAdvanceX == kNotYetSet)
- // Initialize it from the glyph metric (adjusted for hinting).
- m_mAdvanceX = short(GlyphMetricEmUnits(ptman, kgmetAdvWidth));
- return m_mAdvanceX;
- }
-
- int AdvanceY(GrTableManager * ptman)
- {
- if (m_mAdvanceY == kNotYetSet)
- // Initialize it from the glyph metric (adjusted for hinting).
- m_mAdvanceY = short(GlyphMetricEmUnits(ptman, kgmetAdvHeight));
- return m_mAdvanceY;
- }
-
- int AttachAtX(GrTableManager * ptman, GrSlotStream * psstrm)
- {
- if (m_mAttachAtX == kNotYetSet)
- {
- Assert(false); // Should have already been set in HandleModifiedPosition,
- // but just in case...
- if (m_srAttachTo == 0)
- return 0;
- else
- m_mAttachAtX = short(AttachRoot(psstrm)->AdvanceX(ptman)); // attach on the right
- }
- return m_mAttachAtX;
- }
-
- int AttachWithX(GrTableManager * ptman, GrSlotStream * psstrm)
- {
- if (m_mAttachAtX == kNotYetSet)
- {
- Assert(false); // Should have already been set in HandleModifiedPosition,
- // but just in case.
- if (!m_srAttachTo == 0)
- return 0;
- else
- m_mAttachAtX = 0; // attach on the right
- }
- return m_mAttachAtX;
- }
-
- int JStretch()
- {
- return m_mJStretch0;
- }
- int JShrink()
- {
- return m_mJShrink0;
- }
- int JStep()
- {
- return m_mJStep0;
- }
- int JWeight()
- {
- return m_nJWeight0;
- }
- int JWidth()
- {
- return m_mJWidth0;
- }
-
- // Slot attribute setters:
-
- void SetAdvanceX(int mVal)
- {
- Assert(mVal < 0xFFFF); m_mAdvanceX = short(mVal & 0xFFFF); m_fShiftMod = true;
- m_fAdvXSet = true; // for transduction logging
- }
- void SetAdvanceY(int mVal)
- {
- Assert(mVal < 0xFFFF); m_mAdvanceY = short(mVal & 0xFFFF); m_fShiftMod = true;
- m_fAdvYSet = true; // for transduction logging
- }
- void SetShiftX(int mVal)
- {
- Assert(mVal < 0xFFFF); m_mShiftX = short(mVal & 0xFFFF);
- m_fShiftMod = true;
- }
- void SetShiftY(int mVal)
- {
- Assert(mVal < 0xFFFF); m_mShiftY = short(mVal & 0xFFFF);
- m_fShiftMod = true;
- }
-
- void SetAttachTo(int srVal)
- {
- Assert(srVal < 0xFFFF);
- m_srAttachTo = short(srVal & 0xFFFF);
- m_fAttachMod = true;
- }
- void SetAttachLevel(int nVal) {
- Assert(nVal < 0xFFFF); m_nAttachLevel = short(nVal & 0xFFFF); m_fAttachMod = true; }
-
- void SetAttachAtX(int mVal)
- {
- Assert(mVal < 0xFFFF);
- m_mAttachAtX = short(mVal) & 0xFFFF;
- m_fAttachMod = true;
- }
- void SetAttachAtY(int mVal) {
- Assert(mVal < 0xFFFF); m_mAttachAtY = short(mVal & 0xFFFF); m_fAttachMod = true; }
- void SetAttachAtGpoint(int nVal) {
- m_nAttachAtGpoint = short(nVal); m_fAttachMod = true; }
- void SetAttachAtXOffset(int mVal) {
- Assert(mVal < 0xFFFF); m_mAttachAtXOffset = short(mVal & 0xFFFF); m_fAttachMod = true; }
- void SetAttachAtYOffset(int mVal) {
- Assert(mVal < 0xFFFF); m_mAttachAtYOffset = short(mVal & 0xFFFF); m_fAttachMod = true; }
-
- void SetAttachWithX(int mVal) {
- Assert(mVal < 0xFFFF); m_mAttachWithX = short(mVal & 0xFFFF); m_fAttachMod = true; }
- void SetAttachWithY(int mVal) {
- Assert(mVal < 0xFFFF); m_mAttachWithY = short(mVal & 0xFFFF); m_fAttachMod = true; }
- void SetAttachWithGpoint(int nVal) {
- m_nAttachWithGpoint = short(nVal); m_fAttachMod = true; }
- void SetAttachWithXOffset(int mVal) {
- Assert(mVal < 0xFFFF); m_mAttachWithXOffset = short(mVal & 0xFFFF); m_fAttachMod = true; }
- void SetAttachWithYOffset(int mVal) {
- Assert(mVal < 0xFFFF); m_mAttachWithYOffset = short(mVal & 0xFFFF); m_fAttachMod = true; }
-
- void SetCompRefSlot(GrTableManager * ptman, int i, GrSlotState * pslotComp);
-
- void SetBreakWeight(int lb) { m_lb = sdata8(lb); }
- void SetInsertBefore(bool f) { m_fInsertBefore = f; }
-
- void SetDirectionality(DirCode dirc) { m_dirc = sdata8(dirc); }
- void SetDirLevel(int n) { m_nDirLevel = sdata8(n); }
-
- void SetMeasureSol(int mVal) { m_mMeasureSol = short(mVal); }
- void SetMeasureEol(int mVal) { m_mMeasureEol = short(mVal); }
-
- void SetJStretch(int mVal) { m_mJStretch0 = short(mVal); }
- void SetJShrink(int mVal) { m_mJShrink0 = short(mVal); }
- void SetJStep(int mVal) { m_mJStep0 = short(mVal); }
- void SetJWeight(int nVal) { m_nJWeight0 = byte(nVal); }
- void SetJWidth(int mVal) { m_mJWidth0 = mVal; }
- void AddJWidthToAdvance(GrTableManager * ptman)
- {
- // Don't change m_fShiftMod.
- m_mAdvanceX = short(m_mJWidth0 + AdvanceX(ptman)); // make sure it is calculated
- m_mJWidth0 = 0;
- m_fAdvXSet = true; // for transduction logging
- }
-
- int PostBidiDirLevel(GrTableManager * ptman);
-
- bool BaseEarlierInStream();
-
- void ZapDirLevel()
- {
- m_nDirLevel = -1;
- m_dircProc = kdircUnknown;
- m_fDirProcessed = false;
- }
-
- int GlyphAttrValueEmUnits(GrTableManager * ptman, int nAttrID);
- int GlyphMetricEmUnits(GrTableManager * ptman, int nGlyphMetricID);
-
- float GlyphAttrValueLogUnits(GrTableManager * ptman, int nAttrID);
- float GlyphMetricLogUnits(GrTableManager * ptman, int nGlyphMetricID);
-
-// void HandleModifiedCluster(GrTableManager * ptman,
-// GrSlotStream * psstrm, int islotThis);
- void HandleModifiedPosition(GrTableManager * ptman,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, int islotThis);
-
- void CalcCompositeMetrics(GrTableManager * ptman, GrSlotStream * psstrm,
- int nLevel, bool fThorough = false);
-
- void Position(GrTableManager * ptman,
- GrSlotStream * psstrmOut, int * pmXPos, int * pmYPos);
-
- void ZapPosition()
- {
- m_xsPositionX = kNegInfFloat;
- m_ysPositionY = kNegInfFloat;
- }
-
- void SetXPos(float xs)
- {
- m_xsPositionX = xs;
- }
- void SetYPos(float ys)
- {
- m_ysPositionY = ys; // relative to baseline (positive is up)
- }
-
- float ClusterRootOffset() { return -m_xsClusterXOffset; } // the offset of the root
- // relative to the whole cluster
-
- float ClusterAdvWidthFrom(float xs) { return xs + m_xsClusterAdv; }
- float ClusterBbLeftFrom(float xs) { return xs + m_xsClusterBbLeft; }
- float ClusterBbRightFrom(float xs) { return xs + m_xsClusterBbRight; }
-
- float ClusterLsb(GrSlotStream * psstrm, float xs)
- {
- return ClusterBbLeft(psstrm) + xs;
- }
- float ClusterRsb(GrSlotStream * psstrm, float xs)
- {
- return ClusterAdvWidthFrom(xs) - ClusterBbRightFrom(xs);
- }
-
- float ClusterAdvWidth(GrSlotStream * psstrm)
- {
- return ClusterAdvWidthFrom(Base(psstrm)->ClusterRootOffset());
- }
-// int ClusterAdvHeight(GrSlotStream * psstrm)
-// {
-// Assert(m_mAdvanceY != kNotYetSet);
-// return EmUnitsToTwips(m_mAdvanceY);
-// }
- float ClusterBbLeft(GrSlotStream * psstrm)
- {
- return ClusterBbLeftFrom(Base(psstrm)->ClusterRootOffset());
- }
- float ClusterBbRight(GrSlotStream * psstrm)
- {
- return ClusterBbRightFrom(Base(psstrm)->ClusterRootOffset());
- }
- float ClusterBbTop(GrSlotStream * psstrm)
- {
- return m_ysClusterBbTop;
- }
- float ClusterBbBottom(GrSlotStream * psstrm)
- {
- return m_ysClusterBbBottom;
- }
- float ClusterBbWidth(GrSlotStream * psstrm)
- {
- return m_xsClusterBbRight - m_xsClusterBbLeft + 1;
- }
- float ClusterBbHeight(GrSlotStream * psstrm)
- {
- return m_ysClusterBbTop - m_ysClusterBbBottom + 1;
- }
- float ClusterLsb(GrSlotStream * psstrm)
- {
- return ClusterBbLeft(psstrm);
- }
- float ClusterRsb(GrSlotStream * psstrm)
- {
- return ClusterAdvWidth(psstrm) - ClusterBbRight(psstrm);
- }
-
- float GlyphXOffset(GrSlotStream * psstrm, float fakeItalicRatio = 0);
- float GlyphYOffset(GrSlotStream * psstrm = NULL);
-
- bool IsBase()
- {
- Assert(m_dislotRootFixed == m_srAttachTo);
- return (m_dislotRootFixed == 0);
- }
-
- bool HasClusterMembers()
- {
- return (m_vdislotAttLeaves.size() > 0);
- }
-
- GrSlotState * AttachRoot(GrSlotStream * psstrm)
- {
- if (m_srAttachTo == 0)
- return NULL;
- else
- return SlotAtOffset(psstrm, m_srAttachTo);
- }
-
- int AttachRootPosPassIndex()
- {
- return PosPassIndex() + m_srAttachTo;
- }
-
- GrSlotState * Base(GrSlotStream * psstrm)
- {
- GrSlotState * pslotRoot = AttachRoot(psstrm);
- if (!pslotRoot)
- return this;
- else
- return pslotRoot->Base(psstrm);
- }
-
- int LastLeafOffset(GrSlotStream * psstrm);
-
- void AddLeaf(int dislot)
- {
- m_vdislotAttLeaves.push_back(dislot * -1);
- }
- void RemoveLeaf(int dislot)
- {
- for (size_t iislot = 0; iislot < m_vdislotAttLeaves.size(); iislot++)
- {
- if (m_vdislotAttLeaves[iislot] == dislot * -1)
- {
- m_vdislotAttLeaves.erase(m_vdislotAttLeaves.begin() + iislot);
- return;
- }
- }
- Assert(false);
- }
-
- bool HasAsRoot(GrSlotStream * psstrm, GrSlotState * pslot)
- {
- GrSlotState * pslotRoot = AttachRoot(psstrm);
- if (pslotRoot == pslot)
- return true;
- else if (pslotRoot == NULL)
- return false;
- else
- return pslotRoot->HasAsRoot(psstrm, pslot);
- }
-
- bool HasAsPreviousState(GrSlotState * pslot)
- {
- if (this == pslot)
- return true;
- else
- return m_pslotPrevState->HasAsPreviousState(pslot);
- }
-
- void EnsureCacheForOutput(GrTableManager * ptman);
-
- bool IsLrm();
- bool IsRlm();
-
- // Cache of FSM column information for the most recent pass:
- int FsmColumn() { return m_colFsm; }
- int PassNumberForColumn() { return m_ipassFsmCol; }
- void CacheFsmColumn(int ipass, int col)
- {
- m_colFsm = col;
- m_ipassFsmCol = ipass;
- }
-
- // Variable-length buffer--includes four sub-buffers:
- // * user-defined variables
- // * component.???.ref assignments
- // * mapping from components used to global attribute IDs for components
- // * feature values
-
- // user-defined slot attributes
- int UserDefn(int slati)
- {
- Assert(slati < m_cnUserDefn);
- return m_prgnVarLenBuf[slati].nValue;
- }
- void SetUserDefn(int slati, int nVal)
- {
- Assert(slati < m_cnUserDefn);
- m_prgnVarLenBuf[slati].nValue = nVal;
- }
- u_intslot * PUserDefnBuf()
- {
- return m_prgnVarLenBuf;
- }
-
- // pointer to the associated slot which is the value of the comp.ref attribute
- GrSlotState * CompRef(int slati)
- {
- Assert(slati < m_cnCompPerLig);
- return m_prgnVarLenBuf[m_cnUserDefn + slati].pslot;
- }
- void SetCompRef(int slati, GrSlotState * pvSlot)
- {
- Assert(slati < m_cnCompPerLig);
- m_prgnVarLenBuf[m_cnUserDefn + slati].pslot = pvSlot;
- }
- u_intslot * PCompRefBuf()
- {
- return m_prgnVarLenBuf + m_cnUserDefn;
- }
-
- // global component identifier
- int Slati(int i)
- {
- Assert(i < m_cnCompPerLig);
- return m_prgnVarLenBuf[m_cnUserDefn + m_cnCompPerLig + i].nValue;
- }
- void SetSlati(int i, int n)
- {
- Assert(i < m_cnCompPerLig);
- m_prgnVarLenBuf[m_cnUserDefn + m_cnCompPerLig + i].nValue = n;
- }
- u_intslot * PSlatiBuf()
- {
- return m_prgnVarLenBuf + m_cnUserDefn + m_cnCompPerLig;
- }
-
- // feature settings
- int FeatureValue(int i)
- {
- Assert(i < m_cnFeat);
- return m_prgnVarLenBuf[m_cnUserDefn + (m_cnCompPerLig * 2) + i].nValue;
- }
-
- u_intslot * PFeatureBuf()
- {
- return m_prgnVarLenBuf + m_cnUserDefn + (m_cnCompPerLig * 2);
- }
-
- int CExtraSpace()
- {
- return m_cnUserDefn + (m_cnCompPerLig * 2) + m_cnFeat;
- }
-
- GrSlotState * CompRefSlot(int i);
-
- void GetFeatureValues(GrFeatureValues * pfval)
- {
- pfval->m_nStyleIndex = m_bStyleIndex;
- std::fill(pfval->m_rgnFValues, pfval->m_rgnFValues + kMaxFeatures, 0);
- for (size_t i = 0; i < m_cnFeat; i++)
- pfval->m_rgnFValues[i] = PFeatureBuf()[i].nValue;
- }
-
- // For transduction logging:
-#ifdef TRACING
- void SlotAttrsModified(bool * rgfMods, bool fPreJust, int * pccomp, int * pcassoc);
- void LogSlotAttributeValue(GrTableManager *, std::ostream &, int ipass, int slat, int icomp,
- bool fPreJust, bool fPostJust);
- void LogAssociation(GrTableManager * ptman,
- std::ostream & strmOut, int ipass, int iassoc, bool fBoth, bool fAfter);
- void LogXmlAttributes(std::ostream & strmOut, GrTableManager * ptman, GrSlotStream * psstrmOut,
- int ipass, int islot,
- bool fPreJust, bool fPostJust, bool fBidi, bool fBidiNext, int nIndent);
- int GetSlotAttrValue(std::ostream & strmOut, GrTableManager * ptman,
- int ipass, int slat, int iIndex, bool fPreJust, bool fPostJust);
- int m_islotTmpIn; // for use by transduction log; index of slot in input stream
- int m_islotTmpOut; // ditto; index of slot in output stream
-#endif // TRACING
-
-protected:
-
- // Instance variables:
- int m_ipassModified; // pass in which this slot was modified
-
- GrSlotState * m_pslotPrevState;
-
- int m_ichwSegOffset; // for original (pass 0) slot states: position in
- // underlying text relative to the official
- // beginning of the segment;
- // should == kInvalid for other slot states
- int m_islotPosPass; // index of slot in positioning streams, relative to first official
- // slot in the segment (possibly the LB slot)
-
- int m_colFsm; // which FSM column this glyph corresponds to...
- int m_ipassFsmCol; // ...for the most recent pass
-
- std::vector<GrSlotState*> m_vpslotAssoc; // association mappings
-
- bool m_fNeutralAssocs; // true if we've set the associations to some neutral
- // default, rather than them being set explicitly
- // within a rule
-
- int m_nUnicode; // for debugging
-
- DirCode m_dircProc; // directionality as processed in bidi algorithm
- bool m_fDirProcessed;
-
- // affects length of variable-length buffer
- byte m_cnUserDefn;
- byte m_cnFeat;
-
- byte m_bStyleIndex;
-
- // Slot attributes:
- short m_mAdvanceX;
- short m_mAdvanceY;
- short m_mShiftX;
- short m_mShiftY;
-
- short m_srAttachTo;
- short m_nAttachLevel;
-
- short m_mAttachAtX;
- short m_mAttachAtY;
- short m_mAttachAtXOffset;
- short m_mAttachAtYOffset;
- short m_mAttachWithX;
- short m_mAttachWithY;
- short m_mAttachWithXOffset;
- short m_mAttachWithYOffset;
-
- short m_nAttachAtGpoint;
- short m_nAttachWithGpoint;
-
- // Raw glyph metrics (directly from font)
- float m_xysFontAscent;
- float m_xysFontDescent;
- float m_xysGlyphWidth;
- float m_xysGlyphHeight;
- float m_xysGlyphX;
- float m_xysGlyphY;
- float m_xysAdvX;
- float m_xysAdvY;
-
- // Attachment and metrics
-
- // This is a flag that is set whenever we change the value of any of the attach
- // slot attributes. Then when we want to find out something about the attachments,
- // if it is set, we have some work to do in updating the pointers and metrics.
- bool m_fAttachMod;
-
- // This is a flag that is set whenever we change the value of any of the shift or
- // advance slot attributes. It forces us to zap the metrics.
- bool m_fShiftMod;
-
- // This glyph (and all its leaves, if any) have a zero advance width;
- // never allow it to affect the advance width of a cluster it is part of.
- bool m_fIgnoreAdvance;
-
- int m_dislotRootFixed; // the offset of the slot (relative to this one) that considers
- // this slot to be one of its leaves
- std::vector<int> m_vdislotAttLeaves;
-
- // The following are used by the CalcCompositeMetrics() method and depend on
- // the cluster level that was passed as an argument.
-
- int m_nCompositeLevel; // cluster level last used to calculate composite metrics;
- // kNegInfinity if uncalculated
-
- // offsets for this node only, relative to cluster base
- float m_xsOffsetX;
- float m_ysOffsetY; // relative to baseline (positive is up)
-
- // offsets for this node and its leaves, relative to cluster base (y-coords are
- // relative to baseline)
- float m_xsClusterXOffset;
- float m_xsClusterAdv;
- float m_xsClusterBbLeft;
- float m_xsClusterBbRight;
- float m_ysClusterBbTop;
- float m_ysClusterBbBottom;
-
- // cumulative total of shifts for this node and roots; advance needs to ignore these
- float m_xsRootShiftX;
- float m_ysRootShiftY;
-
- bool m_fHasComponents; // default = false
-
- // Private methods:
-
- void CopyAbstractFrom(GrSlotState * pslot);
-
- void AdjustRootMetrics(GrTableManager * ptman, GrSlotStream *);
- void InitMetrics(GrTableManager * ptman, GrSlotState * pslotRoot);
- void InitLeafMetrics(GrTableManager * ptman, GrSlotState * pslotRoot);
- void InitRootMetrics(GrTableManager * ptman);
- void CalcRootMetrics(GrTableManager * ptman, GrSlotStream *, int nLevel);
- void AttachToRoot(GrTableManager * ptman, GrSlotStream *, GrSlotState * pslotNewRoot);
- void AttachLogUnits(GrTableManager * ptman,
- GrSlotState * pslotRoot,
- float * pxsAttAtX, float * pysAttAtY,
- float * pxsAttWithX, float * pysAttWithY);
-
- GrSlotState * SlotAtOffset(GrSlotStream * psstrm, int dislot); // ENHANCE SharonC: inline?
-
- void EnsureLocalAttachmentTree(GrTableManager * ptman,
- GrSlotStream * psstrmIn, GrSlotStream * psstrmOut, int islotThis);
-
- void ZapCompositeMetrics()
- {
- m_nCompositeLevel = kNegInfinity;
- m_xsPositionX = kNegInfFloat;
- m_ysPositionY = kNegInfFloat;
- m_xsOffsetX = 0;
- m_ysOffsetY = 0;
- m_xsRootShiftX = 0;
- m_ysRootShiftY = 0;
- ZapRootMetrics();
- }
-
- void ZapRootMetrics()
- {
- m_xsClusterXOffset = 0;
- m_xsClusterAdv = 0;
- m_xsClusterBbLeft = 0;
- m_xsClusterBbRight = 0;
- m_ysClusterBbTop = 0;
- m_ysClusterBbBottom = 0;
- m_fIgnoreAdvance = false;
- }
-
- void ZapMetricsAndPositionDownToBase(GrSlotStream * psstrm)
- {
- ZapCompositeMetrics();
- if (m_dislotRootFixed)
- SlotAtOffset(psstrm, m_dislotRootFixed)->ZapMetricsAndPositionDownToBase(psstrm);
- }
-
- void ZapMetricsOfLeaves(GrSlotStream * psstrm, bool fThis = false)
- {
- if (fThis)
- ZapCompositeMetrics();
- for (size_t islot = 0; islot < m_vdislotAttLeaves.size(); islot++)
- {
- SlotAtOffset(psstrm, m_vdislotAttLeaves[islot])->ZapMetricsOfLeaves(psstrm, true);
- }
- }
-
-public: // for transduction logging
- bool m_fAdvXSet;
- bool m_fAdvYSet;
-
-}; // end of class GrSlotState
-
-
-/*----------------------------------------------------------------------------------------------
- A GrSlotOutput represents one slot as the final output of the final pass. These
- are recorded in the segment.
-
- Hungarian: slout
-----------------------------------------------------------------------------------------------*/
-class GrSlotOutput : public GrSlotAbstract
-{
- friend class GlyphInfo;
- friend class Segment;
- friend class SegmentMemoryUsage;
-
-public:
- GrSlotOutput()
- {
- m_cComponents = 0;
- m_isloutClusterBase = -1; // not part of any cluster
- m_disloutCluster = 0;
- m_igbb = -1;
- }
-
- void ExactCopyFrom(GrSlotOutput * pslout, u_intslot * pnVarLenBuf, int cnExtraPerSlot);
-
- void InitializeOutputFrom(GrSlotState * pslot);
-
- int BeforeAssoc()
- {
- return m_ichwBeforeAssoc; // relative to the official beginning of the segment
- }
- int AfterAssoc()
- {
- return m_ichwAfterAssoc; // relative to the official beginning of the segment
- }
-
- void SetBeforeAssoc(int ichw)
- {
- m_ichwBeforeAssoc = ichw;
- }
- void SetAfterAssoc(int ichw)
- {
- m_ichwAfterAssoc = ichw;
- }
- void AddComponentReference(int ichw, int slati)
- {
- if (m_cComponents >= m_cnCompPerLig)
- {
- Assert(false); // ignore the requested component ref
- }
- else
- {
- m_prgnVarLenBuf[m_cComponents].nValue
- = ichw;
-
- // OBSOLETE comment:
- // Maps the used components to the defined components. Normally this will be
- // one-to-one and the buffer will hold [0,1,2...]. But possibly we may
- // have defined components a, b, and c, but only mapped a and c to actual
- // characters. This buffer will then hold [0,2].
-
- m_prgnVarLenBuf[m_cnCompPerLig + m_cComponents].nValue
- = slati;
-
-// Assert(iComp >= m_cComponents); // because we process them in order they are defined
- // in, but we could have skipped some that are
- // defined
- m_cComponents++;
- }
- }
- int NumberOfComponents() // the number used by the rules
- {
- return m_cComponents;
- }
- // Index of ligature components, relative to the beginning of the segment.
- // iComp is index of components USED in this glyph.
- int UnderlyingComponent(int iComp)
- {
- Assert(iComp < m_cnCompPerLig);
- return m_prgnVarLenBuf[iComp].nValue;
- }
- int ComponentId(int iComp)
- {
- return m_prgnVarLenBuf[m_cnCompPerLig + iComp].nValue;
- }
-
- //u_intslot * PCompRefBufSlout()
- //{
- // return m_prgnVarLenBuf;
- //}
-
- int CExtraSpaceSlout()
- {
- return (m_cnCompPerLig * 2);
- }
-
- void SetClusterBase(int islout)
- {
- m_isloutClusterBase = islout;
- }
-
- int ClusterBase()
- {
- return m_isloutClusterBase;
- }
-
- bool IsPartOfCluster()
- {
- return (m_isloutClusterBase > -1);
- }
-
- //int NumClusterMembers()
- //{
- // return m_visloutClusterMembers.size();
- //}
- //int ClusterMember(int iislout)
- //{
- // return m_visloutClusterMembers[iislout];
- //}
-
- void AddClusterMember(int isloutThis, int isloutAttached)
- {
- m_disloutCluster = sdata8(max(int(m_disloutCluster), abs(isloutThis - isloutAttached)));
- }
-
- void ClusterMembers(Segment * pseg, int islout, std::vector<int> & visloutRet);
-
- int ClusterRange()
- {
- return m_disloutCluster;
- }
-
- float ClusterXOffset() { return m_xsClusterXOffset; }
- float ClusterAdvance() { return m_xsClusterAdvance; }
- void SetClusterXOffset(float xs) { m_xsClusterXOffset = xs; }
- void SetClusterAdvance(float xs) { m_xsClusterAdvance = xs; }
-
- float GlyphMetricLogUnits(Font * pfont, int nGlyphMetric);
- //float GlyphMetricLogUnits(int nMetricID);
-
- int GlyphBbIndex() { return m_igbb; }
- void SetGlyphBbIndex (int i) { m_igbb = i; }
-
- Rect BoundingBox(Font & font)
- {
- Rect rectBB;
- rectBB.left = m_xsPositionX + GlyphMetricLogUnits(&font, kgmetBbLeft);
- if (IsSpace())
- rectBB.right = m_xsPositionX + GlyphMetricLogUnits(&font, kgmetAdvWidth);
- else
- rectBB.right = m_xsPositionX + GlyphMetricLogUnits(&font, kgmetBbRight);
- rectBB.top = m_ysPositionY + GlyphMetricLogUnits(&font, kgmetBbTop);
- rectBB.bottom = m_ysPositionY + GlyphMetricLogUnits(&font, kgmetBbBottom);
- return rectBB;
- }
-
- bool IsLineBreak()
- {
- return (IsInitialLineBreak() || IsFinalLineBreak());
- }
- bool IsInitialLineBreak()
- {
- return (m_spsl == kspslLbInitial);
- }
- bool IsFinalLineBreak()
- {
- return (m_spsl == kspslLbFinal);
- }
-
- //float AdvanceXMetric()
- //{
- // return m_xysAdvX;
- //}
-
- bool IsSpace();
-
- void AdjustPosXBy(float dxs)
- {
- m_xsPositionX += dxs;
- //m_rectBB.left += dxs;
- //m_rectBB.right += dxs;
- }
-
- void ShiftForDirDepthChange(float dxsSegWidth);
-
- // Used by GlyphInfo
- int IndexAttachedTo();
- //inline float AdvanceX(Segment * pseg);
- //inline float AdvanceY(Segment * pseg);
- float MaxStretch(Segment * pseg, int level);
- float MaxShrink(Segment * pseg, int level);
- float StretchStep(Segment * pseg, int level);
- int JustWeight(int level);
- float JustWidth(Segment * pseg, int level);
- float MeasureSolLogUnits(Segment * pseg);
- float MeasureEolLogUnits(Segment * pseg);
- Rect ComponentRect(Segment * pseg, int icomp);
-
-protected:
- // Instance variables:
-
- sdata8 m_cComponents;
-
- data8 m_disloutCluster; // how far to search on either side of this glyph to find
- // other members of the cluster;
- // 0 means there are no cluster members or this glyph is
- // attached to some other base
-
- int m_isloutClusterBase; // the index of the slot that serves as the base for the
- // cluster this slot is a part of; -1 if not part of cluster
-
- int m_ichwBeforeAssoc; // index of associated character in the string
- int m_ichwAfterAssoc; // (relative to the official beginning of the segment)
- // char might possibly not be officially in this segment,
- // in which case value is infinity
-
- // Measurements for highlighting an entire cluster, relative to origin of this slot,
- // which is the cluster base.
- float m_xsClusterXOffset;
- float m_xsClusterAdvance; // for single non-cluster glyphs, advance width of positioned glyph
-
- // Index into m_prggbb in Segment; -1 indicates a line break slot that is not rendered:
- int m_igbb;
-
- float m_xsAdvanceX;
-// float m_ysAdvanceY; -- not used
-// Rect m_rectBB;
-
-}; // end of class GrSlotOutput
-
-} // namespace gr
-
-
-#endif // !SLOTSTATE_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/GrSlotStream.cpp b/Build/source/libs/graphite-engine/src/segment/GrSlotStream.cpp
deleted file mode 100644
index db6a5c8af7e..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrSlotStream.cpp
+++ /dev/null
@@ -1,2368 +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: GrSlotStream.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- GrSlotStream class implementation.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#include "GrConstants.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Answer true if there is nothing valid available to read from the stream.
-----------------------------------------------------------------------------------------------*/
-bool GrSlotStream::AtEnd()
-{
- Assert(AssertValid());
-
- if (m_islotReprocPos > -1 && m_islotReprocPos < signed(m_vpslotReproc.size()))
- return false;
-
- if (m_islotSegLim > -1 && m_islotReadPos >= m_islotSegLim)
- // We've determined the segment limit, and we're at or past it.
- return true;
-
- return (m_islotReadPos == m_islotWritePos);
-}
-
-/*----------------------------------------------------------------------------------------------
- Answer true if there is nothing at all available to read from the stream.
- For substitution passes, we need to consider slots that may be beyond what we know
- will be the official end of the segment.
-----------------------------------------------------------------------------------------------*/
-bool GrSlotStream::AtEndOfContext()
-{
- if (m_fUsedByPosPass)
- return AtEnd();
-
- if (m_islotReprocPos > -1 && m_islotReprocPos < signed(m_vpslotReproc.size()))
- return false;
-
- return (m_islotReadPos == m_islotWritePos);
-}
-
-/*----------------------------------------------------------------------------------------------
- Append a slot to the end of the stream.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::NextPut(GrSlotState * pslot)
-{
- Assert(AssertValid());
-
- if (m_islotWritePos < signed(m_vpslot.size()))
- {
- m_vpslot[m_islotWritePos] = pslot;
- }
- else
- {
- m_vpslot.push_back(pslot);
- m_vislotPrevChunkMap.push_back(-1);
- m_vislotNextChunkMap.push_back(-1);
- }
-
- if (m_fUsedByPosPass && GotIndexOffset())
- pslot->SetPosPassIndex(m_islotWritePos - m_cslotPreSeg, m_fInputToPosPass1);
-
- m_islotWritePos++;
-}
-
-/*----------------------------------------------------------------------------------------------
- Get the next slot from the stream.
-----------------------------------------------------------------------------------------------*/
-GrSlotState * GrSlotStream::NextGet()
-{
- Assert(AssertValid());
- Assert(!AtEndOfContext());
-
- GrSlotState * pslotRet;
-
- if (m_islotReprocPos > -1)
- {
- if (m_islotReprocPos >= signed(m_vpslotReproc.size()))
- {
- // Finished reprocessing.
- Assert((unsigned)m_islotReprocPos == m_vpslotReproc.size());
- m_islotReprocPos = -1;
- // But leave the m_vpslotReproc array in place so that earlier slots can
- // be accessed by the rules.
- pslotRet = m_vpslot[m_islotReadPos];
- m_islotReadPos++;
- }
- else
- {
- // Read from the reprocess buffer.
- pslotRet = m_vpslotReproc[m_islotReprocPos];
- m_islotReprocPos++;
- }
- }
- else
- {
- // Read normally.
- pslotRet = m_vpslot[m_islotReadPos];
- m_islotReadPos++;
- }
-
- Assert(!m_fUsedByPosPass || pslotRet->PosPassIndex() != GrSlotAbstract::kNotYetSet);
-
- return pslotRet;
-}
-
-/*---------------------------------------------------------------------------------------------
- Peek at the next slot from the stream (dislot = 0 means the very next slot).
- Only used for peeking forward. RuleInputSlot is used for accessing any possible
- slot in the rule's context.
-----------------------------------------------------------------------------------------------*/
-GrSlotState * GrSlotStream::Peek(int dislot)
-{
- Assert(AssertValid());
- Assert(!AtEndOfContext());
- Assert(dislot >= 0);
-
- GrSlotState * pslotRet;
-
- if (m_islotReprocPos > -1)
- {
- int cslotReproc = m_vpslotReproc.size() - m_islotReprocPos; // num left in reproc buffer
- if (dislot >= cslotReproc)
- {
- // Not quite enough slots in the reprocess buffer.
- pslotRet = m_vpslot[m_islotReadPos + dislot - cslotReproc];
- }
- else if (m_islotReprocPos + dislot < 0)
- {
- // Reading prior to the reprocess buffer
- pslotRet = m_vpslot[m_islotReadPos + dislot - cslotReproc];
- }
- else
- {
- // Read from the reprocess buffer.
- pslotRet = m_vpslotReproc[m_islotReprocPos + dislot];
- }
- }
- else
- {
- // Read normally.
- Assert(m_islotWritePos - m_islotReadPos > dislot);
- pslotRet = m_vpslot[m_islotReadPos + dislot];
- }
-
- return pslotRet;
-}
-
-/*---------------------------------------------------------------------------------------------
- Treat the stream, which is really the output stream, as an input stream,
- retrieving a recently output slot. This happens when we are reading before the
- current stream position when the rule is being matched, or before the original
- stream position when the rule is being run.
-
- @param dislot - how far back to peek before the write position
- when the rule started; a negative number
- (NOTE: the current write position is irrelevant)
- @param fNullOkay - true if it's okay to return NULL in the situation where we're asking
- for something before the beginning of the stream
-----------------------------------------------------------------------------------------------*/
-GrSlotState * GrSlotStream::PeekBack(int dislot, bool fNullOkay)
-{
- Assert(dislot < 0);
- if (dislot < m_islotRuleStartWrite * -1)
- {
- Assert(fNullOkay);
- return NULL;
- }
- GrSlotState * pslotRet;
- if (m_islotReprocPos > -1)
- {
- if (dislot < m_islotReprocLim - m_islotRuleStartWrite &&
- dislot >= m_islotReprocLim - m_islotRuleStartWrite - signed(m_vpslotReproc.size()))
- {
- // Read from the reprocess buffer.
- // Review: this is weird; can it ever happen?
- pslotRet = m_vpslotReproc[m_vpslotReproc.size()
- - (m_islotReprocLim - m_islotRuleStartWrite) + dislot];
- }
- else
- pslotRet = m_vpslot[m_islotRuleStartWrite + dislot];
- }
- else
- pslotRet = m_vpslot[m_islotRuleStartWrite + dislot];
-
- return pslotRet;
-}
-
-/*---------------------------------------------------------------------------------------------
- Skip the given number of slots in the stream.
- ENHANCE: implement more efficiently
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::Skip(int dislot)
-{
- for (int islot = 0; islot < dislot; ++islot)
- NextGet();
-}
-
-/*----------------------------------------------------------------------------------------------
- Perform assertions to ensure that the stream is in a valid state.
-----------------------------------------------------------------------------------------------*/
-bool GrSlotStream::AssertValid()
-{
- Assert(m_islotWritePos <= signed(m_vpslot.size()));
- Assert(m_islotReadPos <= m_islotWritePos);
- // Streams used by the positioning passes (input or output) should not be working
- // with slots beyond the segment lim
- Assert(m_islotSegLim == -1 || !m_fUsedByPosPass || m_islotReadPos <= m_islotSegLim);
- Assert(m_vpslot.size() == m_vislotPrevChunkMap.size());
- Assert(m_vpslot.size() == m_vislotNextChunkMap.size());
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the number of slots that have been completely output by the previous pass but not
- yet processed by the following pass. ("Completely" output means that they do not need
- to be reprocessed by the same pass, only then are they available as valid input.)
- Include any slots that are present by virtue of needing to be reprocessed by the
- corresponding output stream.
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::SlotsPending()
-{
- Assert(AssertValid());
- if (m_islotSegLim > -1)
- return (m_islotSegLim - m_islotReadPos + SlotsToReprocess());
- else
- return (m_islotWritePos - m_islotReadPos + SlotsToReprocess());
-}
-
-int GrSlotStream::SlotsPendingInContext()
-{
- Assert(AssertValid());
- if (m_fUsedByPosPass)
- return SlotsPending();
- else
- return (m_islotWritePos - m_islotReadPos + SlotsToReprocess());
-}
-
-int GrSlotStream::TotalSlotsPending()
-{
- int cslot = SlotsPendingInContext();
- if (m_fUsedByPosPass && m_islotSegLim > -1)
- {
- int ctmp = m_islotWritePos - m_islotReadPos + SlotsToReprocess();
- if (ctmp > cslot)
- {
- int x; x = 3;
- }
- cslot = max(cslot, ctmp);
- }
- return cslot;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if this pass is input or output to a positioning pass and we're past the end
- of the segment. So this stream is virtually finished.
-----------------------------------------------------------------------------------------------*/
-bool GrSlotStream::PastEndOfPositioning(bool fOutput)
-{
- if (m_fUsedByPosPass && m_islotSegLim > -1)
- {
- if (fOutput) // this stream is functioning as an output stream
- return (m_islotWritePos >= m_islotSegLim);
- else // this stream is functioning as an input stream
- return (m_islotReadPos >= m_islotSegLim);
- }
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- Mark the stream as fully written, so that the output pass doesn't keep trying to ask
- for more input.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::MarkFullyWritten()
-{
- m_fFullyWritten = true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the position of the first glyph at or following the given position
- that is in the top direction, or -1 if we do not have a complete range.
-
- @param ptman
- @param islotStart
- @nTopDirLevel - top direction: 0 = left-to-right, 1 = right-to-left
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::OldDirLevelRange(EngineState * pengst, int islotStart, int nTopDirLevel)
-{
- Assert(m_islotReadPos <= islotStart);
- Assert(islotStart < m_islotWritePos);
-
- int islot = islotStart;
- int nSlotDirLevel = GetSlotDirLevel(pengst, islot, nTopDirLevel, nTopDirLevel,
- kdircUnknown, kdircNeutral);
- if (nSlotDirLevel == -1)
- return -1;
- while (nSlotDirLevel > nTopDirLevel)
- {
- islot++;
- if (islot >= m_islotWritePos)
- {
- if (m_fFullyWritten)
- return islot;
- else
- return -1;
- }
- else if (m_islotSegLim > -1 && islot >= m_islotSegLim)
- {
- return islot;
- }
-
- nSlotDirLevel = GetSlotDirLevel(pengst, islot, nTopDirLevel, nTopDirLevel,
- kdircUnknown, kdircNeutral);
- if (nSlotDirLevel == -1)
- return -1;
- }
- return islot;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the position of the first glyph at or following the given position
- that is in the top direction, or -1 if we do not have a complete range.
-
- @param ptman
- @param islotStart
- @nTopDirLevel - top direction: 0 = left-to-right, 1 = right-to-left
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::DirLevelRange(EngineState * pengst, int islotStart, int nTopDirLevel,
- std::vector<int> & vislotStarts, std::vector<int> & vislotStops)
-{
- Assert(m_islotReadPos <= islotStart);
- Assert(islotStart < m_islotWritePos);
-
- std::vector<int> vislotStartStack; // indices of starts of ranges to reverse
-
- // Stack corresponding to embedding and override markers:
- std::vector<DirCode> vdircMarkerStack;
- std::vector<DirCode> vdircOverrideStack;
- std::vector<int> vnLevelStack;
-
- vislotStarts.clear();
- vislotStops.clear();
-
- //vislotStartStack.Push(islot);
-
- int islotSegLim = (FullyWritten() || m_islotSegLim > -1) ?
- FinalSegLim() :
- WritePos() + 100; // arbitrarily large number
-
- if (islotStart > islotSegLim)
- {
- // Don't do anything fancy with stuff beyond the end of the segment.
- return 0;
- }
-
- DirCode dircMarker = kdircNeutral; // none so far
- int nCurrLevel = nTopDirLevel;
- int nMarkerLevel = nTopDirLevel;
- //bool fHitMark = false;
- DirCode dircOverride = kdircNeutral;
- int islot = islotStart;
- Assert(islot <= m_islotWritePos);
-
- while (true)
- {
- GrSlotState * pslot = m_vpslot[islot];
- DirCode dirc = pslot->DirProcessed();
- bool fIncludeLast = false;
- int nSlotDirLevel;
- if (dirc == kdircLRO || dirc == kdircLRE) // steps X1, X3 in the Unicode bidi algorithm
- {
- vdircMarkerStack.push_back(dircMarker);
- vdircOverrideStack.push_back(dircOverride);
- vnLevelStack.push_back(nCurrLevel);
- dircMarker = dirc;
- dircOverride = (dirc == kdircLRO) ? kdircL : kdircNeutral;
- nSlotDirLevel = (nCurrLevel % 2) ?
- nCurrLevel + 1 : nCurrLevel + 2; // next highest LTR level
- nMarkerLevel = nSlotDirLevel;
-
- pslot->SetDirProcessed(dircMarker);
- pslot->SetDirLevel(nMarkerLevel);
- pslot->MarkDirProcessed();
- }
- else if (dirc == kdircRLO || dirc == kdircRLE) // steps X2, X4
- {
- vdircMarkerStack.push_back(dircMarker);
- vdircOverrideStack.push_back(dircOverride);
- vnLevelStack.push_back(nCurrLevel);
- dircMarker = dirc;
- dircOverride = (dirc == kdircRLO) ? kdircR : kdircNeutral;
- nSlotDirLevel = (nCurrLevel % 2) ?
- nCurrLevel + 2 : nCurrLevel + 1; // next highest RTL level
- nMarkerLevel = nSlotDirLevel;
-
- pslot->SetDirProcessed(dircMarker);
- pslot->SetDirLevel(nMarkerLevel);
- pslot->MarkDirProcessed();
- }
- else if (dirc == kdircPDF)
- {
- if (dircMarker == kdircNeutral)
- pslot->SetDirProcessed((nCurrLevel % 2) ? kdircR : kdircL);
- else
- pslot->SetDirProcessed(RightToLeftDir(dircMarker) ? kdircPdfR : kdircPdfL);
- pslot->SetDirLevel(nMarkerLevel);
- pslot->MarkDirProcessed();
-
- if (vnLevelStack.size())
- {
- dircMarker = vdircMarkerStack.back();
- vdircMarkerStack.pop_back();
- dircOverride = vdircOverrideStack.back();
- vdircOverrideStack.pop_back();
- nMarkerLevel = vnLevelStack.back();
- vnLevelStack.pop_back();
- nSlotDirLevel = nMarkerLevel;
- fIncludeLast = true;
- }
- else // ignore
- nSlotDirLevel = nCurrLevel;
- }
- else
- {
- nSlotDirLevel = GetSlotDirLevel(pengst, islot, nTopDirLevel, nMarkerLevel,
- dircMarker, dircOverride);
- if (nSlotDirLevel == -1)
- return -1; // not enough slots
- }
-
- Assert(pengst->WhiteSpaceOnly() || nCurrLevel >= nTopDirLevel);
- while (nSlotDirLevel > nCurrLevel)
- {
- vislotStartStack.push_back(islot);
- nCurrLevel++;
- }
- // otherwise...
- while (nTopDirLevel <= nCurrLevel && nSlotDirLevel < nCurrLevel)
- {
- if (vislotStartStack.size())
- {
- int islotStartTmp = vislotStartStack.back();
- vislotStartStack.pop_back();
- vislotStarts.push_back(islotStartTmp);
- vislotStops.push_back(islot - 1); // previous character was the end of the range
- }
- else
- Assert(pengst->WhiteSpaceOnly()); // the space is higher than the segment itself
- nCurrLevel--;
- }
- // In the case of white-space-only segments, the space may be bumped up to a level
- // higher than the segment itself.
- Assert(pengst->WhiteSpaceOnly() || vislotStartStack.size() + nTopDirLevel == (unsigned)nCurrLevel);
- Assert(pengst->WhiteSpaceOnly() || vnLevelStack.size() == vdircMarkerStack.size());
- Assert(pengst->WhiteSpaceOnly() || vdircOverrideStack.size() == vdircMarkerStack.size());
-
- if (nCurrLevel <= nTopDirLevel)
- {
- if (fIncludeLast)
- {
- // Include in the range to reverse the PDF or the char after the LRM/RLM.
- // (Note: don't use a size_t below: we are decrementing below zero.)
- for (int i = signed(vislotStops.size()) - 1; i >= 0 && vislotStops[i] == islot-1; i--)
- {
- vislotStops[i] = islot;
- }
- islot++;
- }
- break; // reached end of reversible range
- }
-
- islot++;
- if (islot >= m_islotWritePos)
- {
- if (m_fFullyWritten)
- break; // end of input
- else
- return -1; // not enough slots
- }
- else if (islot >= islotSegLim)
- {
- break; // end of input
- }
- }
-
- // Reached the end of a reversable range.
- while (vislotStartStack.size() > 0)
- {
- int islotStartTmp = vislotStartStack.back();
- vislotStartStack.pop_back();
- vislotStarts.push_back(islotStartTmp);
- //vislotStops.push_back(min(islot, ReadPos() - 1));
- //vislotStops.push_back(min(islot, max(ReadPos() - 1, islotStartTmp)));
- vislotStops.push_back(min(islot - 1, islotSegLim - 1));
- nCurrLevel--;
- }
- Assert(pengst->WhiteSpaceOnly() || nCurrLevel == nTopDirLevel);
- Assert(vislotStarts.size() == vislotStops.size());
-
- // The start- and stop-lists were generated in the order that we hit the stops, in other
- // words, from inner to outer. Which is the order in which we need to do the reversals, too.
-
- return islot;
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Return the direction level of the glyph at the given position, according to the
- Unicode bidi algorithm. Return -1 if there aren't enough slots in the stream to
- figure it out.
-
- ???? How should this handle the reprocessing sub-stream????
-
- @param ptman
- @param islot - slot for which information is requested
- @param nOuterLevel - 0 = left-to-right, 1 = right-to-left
- @param nCurrLevel
- @param dircMarker - most recent override or embedding marker, if any
- (for interpreting PDF codes)
- @param dircOverride - override imposed by LRO or RLO
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::GetSlotDirLevel(EngineState * pengst, int islot,
- int nOuterLevel, int nCurrLevel, DirCode dircMarker, DirCode dircOverride)
-{
-// Assert(m_psstrmReprocess == NULL);
-
- GrSlotState * pslot = m_vpslot[islot];
-
- int nDirLevel = pslot->DirLevel();
- if (nDirLevel > -1)
- // already figured out
- return nDirLevel;
-
- if (pengst->WhiteSpaceOnly())
- {
- // White-space-only segments should not have any reordering.
- nDirLevel = pengst->ParaRightToLeft();
- pslot->SetDirLevel(nDirLevel);
- pslot->MarkDirProcessed();
- return nDirLevel;
- }
-
- DirCode dirc = pslot->DirProcessed();
-
- if (!pslot->DirHasBeenProcessed() && (WeakDir(dirc) || NeutralDir(dirc)) )
- {
- // Resolve weak and neutral types; process an entire run of weak types at once,
- // in several passes.
-
- int islotWeakRunLim = islot + 1;
- while (true)
- {
- if (islotWeakRunLim >= m_islotWritePos)
- {
- if (!m_fFullyWritten)
- return -1; // get more slots
- else
- break;
- }
- else if (m_islotSegLim > -1 && islotWeakRunLim >= SegLimIfKnown())
- {
- break;
- }
- if (StrongDir(m_vpslot[islotWeakRunLim]->DirProcessed()))
- // ignore the line-break; we need the next strong dir after that
- //// && !m_vpslot[islotWeakRunLim]->IsFinalLineBreak(ptman->LBGlyphID()))
- {
- break;
- }
- if (m_vpslot[islotWeakRunLim]->DirProcessed() == kdircPDF &&
- dircMarker != kdircUnknown)
- {
- // A valid PDF is a strong code. TODO: replace kdircPDF with kdircPdfL/R
- break;
- }
-
- islotWeakRunLim++;
- }
-
- int islotLp;
-
- // X6. Handle directional overrides: LRO, RLO.
- if (dircOverride != kdircNeutral)
- {
- for (islotLp = islot; islotLp < islotWeakRunLim; islotLp++)
- {
- m_vpslot[islotLp]->SetDirProcessed(dircOverride);
- m_vpslot[islotLp]->MarkDirProcessed();
- }
- goto LSetDir;
- }
-
- DirCode dircLp;
- //DirCode dircTmp;
-
- // W1. Non-spacing marks get the type of the previous slot.
- for (islotLp = islot; islotLp < islotWeakRunLim; islotLp++)
- {
- Assert(!m_vpslot[islotLp]->DirHasBeenProcessed());
-
- if (m_vpslot[islotLp]->DirProcessed() == kdircNSM)
- {
-#ifdef _DEBUG
- if (islotLp <= 0)
- {
- Warn("Pathological case in bidi algorithm");
- }
-#endif // _DEBUG
- dircLp = AdjacentNonBndNeutralCode(pengst, islotLp - 1, -1, dircMarker);
-
- m_vpslot[islotLp]->SetDirProcessed(dircLp);
- }
- }
-
- // W2. European numbers are changed to Arabic numbers if the previous strong type
- // was an Arabic letter.
- DirCode dircPrevStrong = AdjacentStrongCode(pengst, islot - 1, -1, dircMarker);
- if (dircPrevStrong == kdircRArab)
- {
- for (islotLp = islot; islotLp < islotWeakRunLim; islotLp++)
- {
- dircLp = m_vpslot[islotLp]->DirProcessed();
- if (dircLp == kdircEuroNum)
- m_vpslot[islotLp]->SetDirProcessed(kdircArabNum);
- }
- }
-
- // W4. A single European separator between two Latin numbers changes to a Latin number.
- // A single common separator between two numbers of the same type changes to that
- // type.
- for (islotLp = islot; islotLp < islotWeakRunLim; islotLp++)
- {
- dircLp = m_vpslot[islotLp]->DirProcessed();
- if ((dircLp == kdircEuroSep || dircLp == kdircComSep) &&
- islotLp + 1 < m_islotWritePos) // don't test last slot in stream
- {
- DirCode dircPrev = AdjacentNonBndNeutralCode(pengst, islotLp - 1, -1, dircMarker);
- DirCode dircNext = AdjacentNonBndNeutralCode(pengst, islotLp + 1, 1, dircMarker);
- if (dircPrev == dircNext)
- {
- if (dircLp == kdircEuroSep && dircPrev == kdircEuroNum)
- {
- m_vpslot[islotLp]->SetDirProcessed(kdircEuroNum);
- }
- else if (dircLp == kdircComSep &&
- (dircPrev == kdircEuroNum || dircPrev == kdircArabNum))
- {
- m_vpslot[islotLp]->SetDirProcessed(dircPrev);
- }
- }
- }
- }
-
- // W5, W6. A sequence of European number terminators adjacent to Latin numbers changes
- // to Latin numbers.
- // This appears to be an ambiguity in the official algorithm: do we search backward
- // first, or forward? For our purposes, it is easier to search backward first.
- for (islotLp = islot; islotLp < islotWeakRunLim; islotLp++)
- {
- dircLp = m_vpslot[islotLp]->DirProcessed();
- if (dircLp == kdircEuroTerm || dircLp == kdircBndNeutral)
- {
- if (TerminatorSequence(pengst, islotLp - 1, -1, dircMarker) == kdircEuroNum)
- dircLp = kdircEuroNum;
- else
- {
- if (TerminatorSequence(pengst, islotLp + 1, 1, dircMarker) == kdircEuroNum)
- dircLp = kdircEuroNum;
- // else could possibly be unknown if we are at the end of the stream
- }
- }
-
- // W6. Separators and terminators change to neutral. (Don't change
- // boundary neutrals at this point, because that would confuse step Pre-L1.)
- if (dircLp == kdircEuroSep || dircLp == kdircEuroTerm || dircLp == kdircComSep)
- {
- dircLp = kdircNeutral;
- }
- m_vpslot[islotLp]->SetDirProcessed(dircLp);
- }
-
- // W7. European numbers are changed to plain left-to-right if the previous strong type
- // was left-to-right.
- dircPrevStrong = AdjacentStrongCode(pengst, islot - 1, -1, dircMarker);
- if (dircPrevStrong == kdircL)
- {
- for (islotLp = islot; islotLp < islotWeakRunLim; islotLp++)
- {
- dircLp = (m_vpslot[islotLp]->DirProcessed());
- if (dircLp == kdircEuroNum)
- m_vpslot[islotLp]->SetDirProcessed(kdircL);
- }
- }
-
- // Pre-L1. Make a list of all the trailing whitespace characters that need to take
- // on the direction of the final line break (ie, the top direction). We can't actually
- // change them yet, because that would confuse the loop below. But we have to
- // record them now because they might get changed in the loop below.
- std::vector<int> vislotTrailingWS;
- int islotFinalLB = -1;
- for (islotLp = islotWeakRunLim; islotLp-- > islot; )
- {
- if (m_vpslot[islotLp]->IsFinalLineBreak(pengst->TableManager()->LBGlyphID()))
- {
- islotFinalLB = islotLp;
- for (int islotLp2 = islotLp; islotLp2-- > islot; )
- {
- dircLp = m_vpslot[islotLp2]->DirProcessed();
- if (dircLp == kdircWhiteSpace || dircLp == kdircBndNeutral)
- vislotTrailingWS.push_back(islotLp2);
- else
- break; // hit something other than whitespace or neutral
- }
- break;
- }
- }
-
- // N1. A sequence of neutrals takes the direction of the strong surrounding text if
- // the text on both sides has the same direction. Latin and Arabic numbers are treated
- // as if they are right-to-left.
- // (If they are not the same, leave the type as neutral.)
- for (islotLp = islot; islotLp < islotWeakRunLim; islotLp++)
- {
- dircLp = m_vpslot[islotLp]->DirProcessed();
-
- // Change Boundary Neutrals to plain neutrals (must happen after Pre-L1).
- if (dircLp == kdircBndNeutral)
- {
- m_vpslot[islotLp]->SetDirProcessed(kdircNeutral);
- dircLp = kdircNeutral;
- }
-
- if (NeutralDir(dircLp))
- {
- // First, look for either a strong code or a number. If we get at least
- // one strong code and a number with the same direction, use that strong
- // code.
- DirCode dircPrev = AdjacentStrongCode(pengst, islotLp - 1, -1, dircMarker, true);
- DirCode dircNext = AdjacentStrongCode(pengst, islotLp + 1, 1, dircMarker, true);
-
- if (dircNext == kdircUnknown)
- return -1;
-
- if (dircPrev == kdircUnknown)
- dircPrev = dircNext;
-
- DirCode dircResult = kdircUnknown;
- if (dircNext == kdircNeutral)
- {}
- else if (RightToLeftDir(dircPrev) == RightToLeftDir(dircNext) &&
- (StrongDir(dircNext) || StrongDir(dircPrev)))
- {
- // Got a strong matching direction.
- dircResult = (StrongDir(dircPrev)) ? dircPrev : dircNext;
- }
- else if (dircNext == kdircPdfL || dircNext == kdircPdfR)
- {
- // A following PDF flag wins, because it represents the edge of a run.
- dircResult = dircNext;
- }
- else if (StrongDir(dircNext) && StrongDir(dircPrev))
- { // We must have text in different directions.
- }
- else
- {
- // Try again, insisting on strong codes, no numbers.
- if (!StrongDir(dircPrev))
- dircPrev = AdjacentStrongCode(pengst, islotLp - 1, -1, dircMarker, false);
- if (!StrongDir(dircNext))
- dircNext = AdjacentStrongCode(pengst, islotLp + 1, 1, dircMarker, false);
- if (dircPrev == kdircUnknown)
- dircPrev = dircNext;
-
- if (RightToLeftDir(dircPrev) == RightToLeftDir(dircNext) &&
- (StrongDir(dircNext) || StrongDir(dircPrev)))
- {
- // Got a strong matching direction.
- dircResult = (StrongDir(dircPrev)) ? dircPrev : dircNext;
- }
- }
-
- if (dircResult != kdircUnknown)
- {
- dircResult = (RightToLeftDir(dircResult)) ? kdircR : kdircL;
- m_vpslot[islotLp]->SetDirProcessed(dircResult);
- }
- // else leave as neutral
- }
- }
-
- // L1. Now change trailing neutrals recorded above to the directionality of
- // the immediately following line-break, if any.
- if (islotFinalLB != -1)
- {
- DirCode dircLB = m_vpslot[islotFinalLB]->DirProcessed();
- dircLB = (dircLB == kdircLlb) ? kdircL : kdircR;
- for (int iislot = 0; iislot < signed(vislotTrailingWS.size()); iislot++)
- {
- int islotTmp = vislotTrailingWS[iislot];
- m_vpslot[islotTmp]->SetDirProcessed(dircLB);
- }
- }
-
- // Mark all the slots processed.
- for (islotLp = islot; islotLp < islotWeakRunLim; islotLp++)
- m_vpslot[islotLp]->MarkDirProcessed();
- }
- else
- m_vpslot[islot]->MarkDirProcessed();
-
-LSetDir:
-
- // Final resolution.
-
- dirc = pslot->DirProcessed();
-
- if (dirc != kdircLlb && dirc != kdircRlb && dircOverride != kdircNeutral)
- {
- // Enforce whatever is imposed by the override.
- m_vpslot[islot]->SetDirProcessed(dircOverride);
- nDirLevel = nCurrLevel;
- }
- else if ((nCurrLevel % 2) == 0) // current level is even (left-to-right)
- {
- switch (dirc)
- {
- case kdircNeutral:
- case kdircWhiteSpace:
- nDirLevel = nCurrLevel;
- break;
-
- case kdircL:
- nDirLevel = nCurrLevel;
- break;
-
- case kdircLlb:
- case kdircRlb: // all line-breaks have the direction of the paragraph
- nDirLevel = nOuterLevel;
- break;
-
- case kdircR:
- case kdircRArab:
- nDirLevel = nCurrLevel + 1;
- break;
-
- case kdircEuroNum:
- case kdircArabNum:
- nDirLevel = nCurrLevel + 2;
- break;
-
- default:
- Assert(false);
- nDirLevel = nCurrLevel;
- }
- }
- else // current level is odd (right-to-left)
- {
- switch (dirc)
- {
- case kdircNeutral:
- case kdircWhiteSpace:
- nDirLevel = nCurrLevel;
- break;
-
- case kdircR:
- //case kdircRlb:
- case kdircRArab:
- nDirLevel = nCurrLevel;
- break;
-
- case kdircL:
- //case kdircLlb:
- case kdircEuroNum:
- case kdircArabNum:
- nDirLevel = nCurrLevel + 1;
- break;
-
- case kdircLlb:
- case kdircRlb: // all line-breaks have the direction of the paragraph
- nDirLevel = nOuterLevel;
- break;
-
- default:
- Assert(false);
- nDirLevel = nCurrLevel;
- }
- }
- pslot->SetDirLevel(nDirLevel);
-
- return nDirLevel;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the next or previous strong code, kdircNeutral if we don't find one,
- or kdircUnknown if we need more slots to process.
-
- @param islot - index of slot of interest
- @param nInc - +1 to search forward, -1 to search backward
- @param fNumbersAreStrong - true if we want to treat numbers as having strong
- directionality
- @param dircPDF - how to interpret PDF codes (from corresponding RLO, etc)
-----------------------------------------------------------------------------------------------*/
-DirCode GrSlotStream::AdjacentStrongCode(EngineState * pengst, int islot, int nInc,
- DirCode dircPDF, bool fNumbersAreStrong)
-{
- if (islot < 0)
- return pengst->InitialStrongDir();
-
- else if (islot >= m_islotWritePos)
- {
- if (m_fFullyWritten || (m_islotSegLim > -1 && islot >= SegLimIfKnown()))
- return kdircNeutral;
- else
- return kdircUnknown;
- }
-
- DirCode dirc = m_vpslot[islot]->DirProcessed();
-
- if (dirc == kdircPDF && StrongDir(dircPDF))
- return (RightToLeftDir(dircPDF)) ? kdircPdfR : kdircPdfL;
- if (StrongDir(dirc))
- return dirc;
- if (fNumbersAreStrong && (dirc == kdircEuroNum || dirc == kdircArabNum))
- return dirc;
-
- return AdjacentStrongCode(pengst, islot + nInc, nInc, dircPDF, fNumbersAreStrong);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return kdircEuroNum if there is a terminator sequence starting or ending with a
- European number. Return kdircUnknown if we need more slots to process.
- Return kdircNeutral otherwise.
-
- @param islot - index of slot of interest
- @param nInc - +1 to search forward, -1 to search backward
- @param dircPDF - how to interpret PDF codes (from corresponding RLO, etc)
-----------------------------------------------------------------------------------------------*/
-DirCode GrSlotStream::TerminatorSequence(EngineState * pengst, int islot, int nInc,
- DirCode dircPDF)
-{
- if (islot < 0)
- return pengst->InitialTermDir();
-
- else if (islot >= m_islotWritePos)
- {
- if (m_fFullyWritten)
- return kdircNeutral;
- else
- return kdircUnknown;
- }
-
- DirCode dirc = m_vpslot[islot]->DirProcessed();
-
- if (dirc == kdircPDF)
- return (RightToLeftDir(dircPDF)) ? kdircPdfR : kdircPdfL;
- else if (dirc == kdircEuroNum)
- // number found at end of terminator sequence
- return kdircEuroNum;
- else if (dirc == kdircEuroTerm)
- // yes, this slot is a terminator; are there more?
- return TerminatorSequence(pengst, islot + nInc, nInc, dircPDF);
- else if (dirc == kdircLlb || dirc == kdircRlb)
- // line-break slot--ignore and keep going
- return TerminatorSequence(pengst, islot + nInc, nInc, dircPDF);
- else if (dirc == kdircBndNeutral)
- // boundary neutral--ignore and keep going
- return TerminatorSequence(pengst, islot + nInc, nInc, dircPDF);
- else
- // no number found
- return kdircNeutral;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the previous code that is not a Boundary Neutral. Return Other Neutral if there
- is no such.
-
- @param islot - index of slot of interest
- @param nInc - +1 to search forward, -1 to search backward
- @param dircPDF - how to interpret PDF codes (from corresponding RLO, etc)
-----------------------------------------------------------------------------------------------*/
-DirCode GrSlotStream::AdjacentNonBndNeutralCode(EngineState * pengst, int islot, int nInc,
- DirCode dircPDF)
-{
- Assert(islot < m_islotWritePos);
- if (islot < 0)
- return kdircNeutral; // or should we use: ptman->InitialStrongDir() ??
-
- else if (islot >= m_islotWritePos)
- {
- if (m_fFullyWritten)
- return kdircNeutral;
- else
- return kdircUnknown;
- }
-
- DirCode dirc = m_vpslot[islot]->DirProcessed();
-
- if (dirc == kdircBndNeutral)
- return AdjacentNonBndNeutralCode(pengst, islot + nInc, nInc, dircPDF);
- else if (dirc == kdircPDF)
- return (RightToLeftDir(dircPDF)) ? kdircPdfR : kdircPdfL;
- else
- return dirc;
-}
-
-/*----------------------------------------------------------------------------------------------
- Directionality type functions.
-----------------------------------------------------------------------------------------------*/
-bool StrongDir(DirCode dirc)
-{
- return (dirc == kdircL || dirc == kdircR || dirc == kdircRArab ||
- dirc == kdircLRO || dirc == kdircRLO || dirc == kdircLRE || dirc == kdircRLE ||
- dirc == kdircPdfL || dirc == kdircPdfR);
-}
-
-bool WeakDir(DirCode dirc)
-{
- return (dirc == kdircEuroNum || dirc == kdircEuroSep ||
- dirc == kdircEuroTerm || dirc == kdircArabNum ||
- dirc == kdircComSep || dirc == kdircBndNeutral || dirc == kdircNSM);
-}
-
-bool NeutralDir(DirCode dirc)
-{
- return (dirc == kdircWhiteSpace || dirc == kdircNeutral);
-}
-
-/*----------------------------------------------------------------------------------------------
- Special values used by the bidi algorithm.
-----------------------------------------------------------------------------------------------*/
-bool BidiCode(int nUnicode)
-{
- switch (nUnicode)
- {
- case knLRM:
- case knRLM:
- case knLRO:
- case knRLO:
- case knLRE:
- case knRLE:
- case knPDF:
- return true;
- default:
- break;
- }
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if the directionality should be treated as right-to-left.
- Used for the step of resolving neutrals (N1).
-----------------------------------------------------------------------------------------------*/
-bool RightToLeftDir(DirCode dirc)
-{
- switch (dirc)
- {
- case kdircL:
- case kdircLRO:
- case kdircLRE:
- case kdircPdfL:
- return false;
-
- case kdircR:
- case kdircRArab:
- case kdircArabNum:
- case kdircEuroNum:
- case kdircRLO:
- case kdircRLE:
- case kdircPdfR:
- return true;
-
- case kdircNeutral:
- return false;
-
- default:
- Assert(false);
- return false;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Copy a slot from prevStream, incrementing the positions.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::CopyOneSlotFrom(GrSlotStream * psstrmPrev)
-{
-#ifdef _DEBUG
- gid16 chw; chw = psstrmPrev->Peek()->GlyphID();
-#endif
-
- // If we are exactly at the segment boundary, pass the information on to this stream.
- if (psstrmPrev->AtSegMin())
- SetSegMinToWritePos();
- if (psstrmPrev->AtSegLim())
- SetSegLimToWritePos();
-
- NextPut(psstrmPrev->NextGet());
-
- AssertValid();
- psstrmPrev->AssertValid();
-}
-
-/*----------------------------------------------------------------------------------------------
- Copy one slot from the input stream to the recipient, which is the output stream.
- Used when reversing ranges of glyphs; caller is responsible for adjusting the read-
- and write-positions of the streams.
-
- REVIEW: How should this handle the reprocessing sub-stream? Currently this is not a problem
- because this function is only used by the bidi pass, which never has intra-pass
- reprocessing.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::SimpleCopyFrom(GrSlotStream * psstrmI, int islotInput, int islotOutput)
-{
- if (signed(m_vpslot.size()) < islotOutput + 1)
- {
- m_vpslot.resize(islotOutput + 1);
- m_vislotPrevChunkMap.resize(islotOutput + 1);
- m_vislotNextChunkMap.resize(islotOutput + 1);
- }
-
- m_vpslot[islotOutput] = psstrmI->m_vpslot[islotInput];
- m_vislotPrevChunkMap[islotOutput] = -1;
- m_vislotNextChunkMap[islotOutput] = -1;
-
- Assert(m_fUsedByPosPass);
- if (m_fUsedByPosPass && GotIndexOffset())
- m_vpslot[islotOutput]->SetPosPassIndex(islotOutput - m_cslotPreSeg, m_fInputToPosPass1);
-
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if there is physical space to add more glyphs, false if the positioning
- has caused them to use all the alotted space. Recipient is assumed to be output
- stream from the final pass.
-
- @param ptman - table manager, for handling the positioning
- @param pgg - graphics device
- @param xsSpaceAllotted - how much space is available
- @param fWidthIsCharCount - kludge for test procedures
- @param fIgnoreTrailingWS - true if we are ignoring trailing white-space (currently
- always true)
- @param twsh - how the segment is handling trailing white-space
- @param pxsWidth - return width of stuff so far
-----------------------------------------------------------------------------------------------*/
-bool GrSlotStream::MoreSpace(GrTableManager * ptman,
- float xsSpaceAllotted, bool fWidthIsCharCount,
- bool fIgnoreTrailingWS, TrWsHandling twsh,
- float * pxsWidth)
-{
- Assert(ptman->NumberOfPasses() - 1 == m_ipass);
-
- if (fWidthIsCharCount)
- {
- // Used in test procedures
- *pxsWidth = (float)m_islotWritePos;
- return (m_islotWritePos < xsSpaceAllotted);
- }
- else
- {
- *pxsWidth = -1;
- if (!GotIndexOffset())
- return true;
- if (WritePos() <= IndexOffset())
- return true;
- int dislot = MaxClusterSlot(WritePos());
- if (dislot == kNegInfinity || dislot > 0)
- // We're in the middle of processing a cluster--we have to keep processing,
- // so for now assume there is more space.
- return true;
-
- float xsWidth, xsVisWidth;
- ptman->CalcPositionsUpTo(m_ipass, NULL, &xsWidth, &xsVisWidth);
-
- *pxsWidth = (fIgnoreTrailingWS || twsh == ktwshOnlyWs) ? xsVisWidth : xsWidth;
- return (*pxsWidth < xsSpaceAllotted);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Work backwards from the prevLineBreak position (or if none, the readPos) to find the
- previous line-break of the given weight or less. Return the position of the inserted
- line-break slot, or -1 if no appropriate break point was found. Recipient should be
- the output of the final line break pass, or if none, the output of the
- glyph-generation pass.
-
- @param ptman - table manager, for supplying new slots
- @param islotPrevBreak - position of previous inserted line break
- @param fInsertedLB - did we actually insert a line-break glyph before?
- @param islotStartTry - where to start looking, or -1 for the end of the stream
- @param lb - (max) break weight to allow
- @param twsh - how we are handling trailing white-space
- @param islotMin - first slot that is officially part of the segment (after initial LB)
- @param plbNextToTry - the best we found
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::InsertLineBreak(GrTableManager * ptman,
- int islotPrevBreak, bool fInsertedLB, int islotStartTry,
- LineBrk lb, TrWsHandling twsh, int islotMin,
- LineBrk * plbNextToTry)
-{
- EngineState * pengst = ptman->State();
-
- Assert(!fInsertedLB || islotPrevBreak > -1);
-
- int ichwSegOffset;
- int islot;
- LineBrk lbFound;
- if (!FindSegmentEnd(ptman, islotStartTry, lb, twsh, islotMin,
- &islot, &ichwSegOffset, &lbFound, plbNextToTry))
- {
- return -1; // didn't find a legal break
- }
-
- GrSlotState * pslotCopyFeat = pengst->AnAdjacentSlot(m_ipass, islot + 1);
- Assert(pslotCopyFeat);
-
- if (islotPrevBreak > -1 && fInsertedLB)
- {
- //GrSlotState * pslotOld = m_vpslot[islotPrevBreak];
-
- m_vpslot.erase(m_vpslot.begin() + islotPrevBreak);
- m_vislotPrevChunkMap.erase(m_vislotPrevChunkMap.begin() + islotPrevBreak);
- m_vislotNextChunkMap.erase(m_vislotNextChunkMap.begin() + islotPrevBreak);
- AdjustPrevStreamNextChunkMap(ptman, islotPrevBreak + 1, -1);
- }
- else
- {
- m_islotReadPos++;
- m_islotWritePos++;
- }
-
- GrSlotState * pslotNew;
- pengst->NewSlot(ptman->LBGlyphID(), pslotCopyFeat, 0, ichwSegOffset, &pslotNew);
-
- pslotNew->SetSpecialSlotFlag(kspslLbFinal);
- pslotNew->SetBreakWeight(lbFound);
- pslotNew->SetDirectionality(ptman->RightToLeft() ? kdircRlb : kdircLlb);
-
- int islotLB = islot + 1;
- m_vpslot.insert(m_vpslot.begin() + islotLB, pslotNew);
- // Inserting -1 makes it part of a chunk with the previous char/glyph
- m_vislotPrevChunkMap.insert(m_vislotPrevChunkMap.begin() + islotLB, -1);
- m_vislotNextChunkMap.insert(m_vislotNextChunkMap.begin() + islotLB, -1);
- AdjustPrevStreamNextChunkMap(ptman, islotLB, 1);
- // We don't need to adjust the following stream because we are going to unwind it anyway.
-
- if (m_fUsedByPosPass && GotIndexOffset())
- {
- pslotNew->SetPosPassIndex(islot - m_cslotPreSeg, m_fInputToPosPass1);
- // Increment the stream index for the following slots.
- for (int islotTmp = islotLB;
- islotTmp < ((islotPrevBreak == -1) ? m_islotWritePos : islotPrevBreak + 1);
- islotTmp++)
- {
- SlotAt(islotTmp)->IncPosPassIndex();
- }
- }
-
- m_islotSegLim = islotLB + 1; // after the line-break glyph
-
- return islotLB;
-}
-
-/*----------------------------------------------------------------------------------------------
- Make a segment break that does not correspond to a line break; ie, don't insert
- a line-break glyph.
-
- Work backwards from the prevLineBreak position (or if none, the readPos) to find the
- previous line-break of the given weight or less. Return the position of the final slot
- in the segment, or -1 if no appropriate break point was found. Recipient should be
- the output of the final line break pass, if any, or the glyph-generation pass.
-
- @param ptman - table manager, for supplying new slots
- @param islotPrevBreak - position of previous inserted line break
- @param fInsertedLB - did we actually insert a line-break glyph previously; currently
- ignored
- @param islotStartTry - where to start looking, or -1 for the end of the stream
- @param lb - (max) break weight to allow
- @param twsh - how we are handling trailing white-space
- @param islotMin - first slot that is officially part of the segment (after initial LB)
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::MakeSegmentBreak(GrTableManager * ptman,
- int islotPrevBreak, bool fInsertedLB, int islotStartTry,
- LineBrk lb, TrWsHandling twsh, int islotMin,
- LineBrk * plbNextToTry)
-{
- int ichwSegOffset;
- int islot;
- LineBrk lbFound;
- if (!FindSegmentEnd(ptman, islotStartTry, lb, twsh, islotMin,
- &islot, &ichwSegOffset, &lbFound, plbNextToTry))
- {
- return -1; // didn't find a legal break
- }
-
- // Review: do we need to delete any previously-inserted line-break glyph from the stream?
- // Doesn't seem like this has been a problem so far.
-
- m_islotSegLim = islot + 1; // after the final glyph of this segment
-
- return islot;
-}
-
-/*----------------------------------------------------------------------------------------------
- Work backwards from the prev line break position (or if none, the readPos) to find an
- earlier line-break of the given weight or less.
- Recipient should be the output of the final line break pass, if any, or the output
- of the glyph-generation pass.
-
- @param ptman - table manager, for supplying new slots
- @param islotStartTry - where to start looking, or -1 for the end of the stream
- @param lb - (max) break weight to allow
- @param twsh - how we are handling trailing white-space
- @param islotMin - first slot that is officially part of the segment (after initial LB)
- @param pislot - slot AFTER which the break will go (not the lim of the segment)
- @param pichwSegOffset - offset relative to the segment
- @param plbFound - weight of break to be created
- @param plbNextToTry - best found, in case we didn't find one at the requested level
-
- @return Whether or not an appropriate break was found.
-----------------------------------------------------------------------------------------------*/
-bool GrSlotStream::FindSegmentEnd(GrTableManager * ptman,
- int islotStartTry, LineBrk lb, TrWsHandling twsh, int islotMin,
- int * pislot, int * pichwSegOffset, LineBrk * plbFound,
- LineBrk * plbNextToTry)
-{
- Assert(AssertValid());
- Assert(m_ipass == ptman->NumberOfLbPasses());
-
- if (islotStartTry < 0)
- return false;
-
- *pislot = islotStartTry;
- GrSlotState * pslot = m_vpslot[*pislot];
- *plbNextToTry = klbClipBreak; // worst break
-
- ptman->State()->SetRemovedTrWhiteSpace(false);
-
- while (twsh != ktwshOnlyWs) // in white-space only case, ignore lb values
- {
- if (*pislot < islotMin)
- {
- return false;
- }
- *plbFound = LineBrk(pslot->m_lb);
- // Sanity check
- if (abs(*plbFound) > klbClipBreak)
- {
-// Assert(false);
- Warn("Unusually large breakweight");
- *plbFound = (LineBrk)((*plbFound < 0) ? -klbClipBreak : klbClipBreak);
- }
- *plbNextToTry = (LineBrk)(min(static_cast<int>(*plbNextToTry), abs(*plbFound)));
- *pichwSegOffset = pslot->SegOffset();
-
- if (int(*plbFound) >= 0 && *plbFound <= lb)
- break;
-
- --(*pislot);
- if (*pislot < 0)
- {
- return false;
- }
- pslot = m_vpslot[*pislot];
-
- if (int(*plbFound) <= 0 && ((int)*plbFound * -1) <= lb)
- {
- *plbFound = LineBrk(int(*plbFound) * -1);
- break;
- }
- }
-
- // Found a good break.
-
- if (twsh == ktwshOnlyWs)
- {
- // white-space-only segment
- while (pslot->Directionality() != kdircWhiteSpace)
- {
- --(*pislot);
- if (*pislot < 0)
- return false;
- pslot = m_vpslot[*pislot];
- *pichwSegOffset = pslot->SegOffset();
- }
- }
- else if (twsh == ktwshNoWs)
- {
- // no trailing white-space: remove it
- while (pslot->Directionality() == kdircWhiteSpace)
- {
- --(*pislot);
- if (*pislot < 0)
- return false;
- pslot = m_vpslot[*pislot];
- *pichwSegOffset = pslot->SegOffset();
- ptman->State()->SetRemovedTrWhiteSpace(true);
- }
- }
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if the stream (which should be the output of the last linebreak pass) has
- a better break at some earlier point than the one we found.
-
- @param islotBreak - position of inserted or final break point in stream, or index
- of last valid slot
-----------------------------------------------------------------------------------------------*/
-bool GrSlotStream::HasEarlierBetterBreak(int islotBreak, LineBrk lbFound, gid16 chwLB)
-{
- Assert(AssertValid());
-
- int islot = islotBreak;
- if (SlotAt(islot)->IsFinalLineBreak(chwLB))
- islot--;
-
- if (lbFound == klbNoBreak)
- lbFound = (LineBrk)SlotAt(islot)->BreakWeight();
-
- while (islot >= 0)
- {
- if (SlotAt(islot)->IsInitialLineBreak(chwLB))
- return false;
- if (SlotAt(islot)->BreakWeight() < lbFound)
- return true;
- islot--;
- }
-
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- Make sure the stream contains a local instance of the given slot, not a copy used by
- a previous pass.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::EnsureLocalCopy(GrTableManager * ptman, GrSlotState * pslot,
- GrSlotStream * psstrmIn)
-{
- //Assert(m_vpslot[islot + m_cslotPreSeg] == pslot);
- Assert(pslot->PassModified() <= m_ipass);
-
- if (pslot->PassModified() < m_ipass)
- {
- int islot = pslot->PosPassIndex();
- Assert(SlotAtPosPassIndex(islot) == pslot);
- GrSlotState * pslotNew;
- ptman->State()->NewSlotCopy(pslot, m_ipass, &pslotNew);
- m_vpslot[islot + m_cslotPreSeg] = pslotNew;
-
- psstrmIn->ReplaceSlotInReprocessBuffer(pslot, pslotNew);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- A slot has been replace within the coorsponding output stream. Make sure the reprocess
- buffer of this stream constains the same slot.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::ReplaceSlotInReprocessBuffer(GrSlotState * pslotOld, GrSlotState * pslotNew)
-{
- if (m_islotReprocPos > -1)
- {
- for (size_t islot = 0; islot < m_vpslotReproc.size(); islot++)
- {
- if (m_vpslotReproc[islot] == pslotOld)
- m_vpslotReproc[islot] = pslotNew;
- }
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Inserting a line break can potentially alter the directionality of preceeding glyphs.
- Zap the information that has been calculated.
-
- @param islotLB - index of the inserted final line-break glyph
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::ZapCalculatedDirLevels(int islotLB)
-{
- int islot;
- for (islot = m_islotWritePos; islot-- > islotLB; )
- m_vpslot[islot]->ZapDirLevel();
-
- for (islot = islotLB; islot-- > 0; )
- {
- if (StrongDir(m_vpslot[islot]->Directionality()))
- // We've found a strong direction code; don't need to zap beyond this point.
- return;
-
- m_vpslot[islot]->ZapDirLevel();
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the slot index of the last slot in the cluster for the just-processed chunk,
- relative to the last slot in the chunk.
-
- Return kNegInfinity if there are not enough slots in the stream to tell. This can
- happen while we are in the middle of processing a cluster.
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::MaxClusterSlot(int islotChunkMin, int islotChunkLim)
-{
- Assert(islotChunkLim > islotChunkMin);
-
- if (!m_fUsedByPosPass)
- return 0; // no clusters yet
-
- int islotRet = SlotAt(islotChunkLim - 1)->PosPassIndex();
-
- for (int islot = islotChunkMin; islot < islotChunkLim; islot++)
- {
- GrSlotState * pslot = SlotAt(islot);
-
- if (m_cslotPreSeg == -1)
- return kNegInfinity;
- if (!HasSlotAtPosPassIndex(pslot->AttachRootPosPassIndex()))
- return kNegInfinity;
-
- GrSlotState * pslotBase = pslot->Base(this);
-
- int dislotOffset = pslotBase->LastLeafOffset(this);
- if (dislotOffset == kNegInfinity)
- return kNegInfinity;
- islotRet = max(islotRet, pslotBase->PosPassIndex() + dislotOffset);
- }
-
- // Make it relative to the last slot in the chunk.
- islotRet -= SlotAt(islotChunkLim - 1)->PosPassIndex();
-
- return islotRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the break weight of the given slot, which should be a line-break.
- OBSOLETE??
-----------------------------------------------------------------------------------------------*/
-LineBrk GrSlotStream::BreakWeightAt(gid16 chwLB, int islot)
-{
- GrSlotState * pslot = GetSlotAt(islot);
- Assert(pslot->IsLineBreak(chwLB));
- return LineBrk(pslot->m_lb);
-}
-
-/*----------------------------------------------------------------------------------------------
- Append an initial or final line break of the given weight to the stream.
-
- @param ptman - table manager, for generating new slot
- @param lb - break weight for the line-break glyph
- @param dirc - directionality code for the line-break glyph
- @param islotLB - where to insert, or -1 if at the end
- @param fInitial - is this an initial line-break, or a final break?
- @param ichwSegOffset - offset relative to the beginning of the segment
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::AppendLineBreak(GrTableManager * ptman, GrCharStream * pchstrm,
- LineBrk lb, DirCode dirc, int islotLB, bool fInitial, int ichwSegOffset)
-{
- EngineState * pengst = ptman->State();
-
- Assert(AssertValid());
-/// Assert(m_islotReprocPos == -1);
-
- Assert(islotLB == -1 || fInitial);
- if (islotLB == -1)
- islotLB = m_islotWritePos;
-
-// int islot = m_islotWritePos;
-
- GrSlotState * pslotCopyFeat = pengst->AnAdjacentSlot(m_ipass, islotLB);
- GrSlotState * pslotNew;
- if (pslotCopyFeat)
- pengst->NewSlot(ptman->LBGlyphID(), pslotCopyFeat, 0, ichwSegOffset, &pslotNew);
- else
- {
- GrFeatureValues fval;
- pchstrm->CurrentFeatures(ptman, &fval);
- pengst->NewSlot(ptman->LBGlyphID(), fval, 0, ichwSegOffset, -1, &pslotNew);
- }
-
- pslotNew->m_lb = sdata8(lb);
- pslotNew->SetSpecialSlotFlag(fInitial ? kspslLbInitial : kspslLbFinal);
- //pslotNew->m_fInitialLB = fInitial; // TODO: remove
- pslotNew->SetDirectionality(dirc);
-
- m_vpslot.insert(m_vpslot.begin() + islotLB, pslotNew);
- // Make it part of a chunk with previous char/glyph
- m_vislotPrevChunkMap.insert(m_vislotPrevChunkMap.begin() + islotLB, -1);
- m_vislotNextChunkMap.insert(m_vislotNextChunkMap.begin() + islotLB, -1);
- if (m_ipass > 0)
- AdjustPrevStreamNextChunkMap(ptman, islotLB, 1);
-
- m_islotWritePos++;
-
- if (m_fUsedByPosPass && GotIndexOffset())
- {
- pslotNew->SetPosPassIndex(islotLB - m_cslotPreSeg, m_fInputToPosPass1);
- // Increment the stream index for the following slots.
- for (int islotTmp = islotLB + 1; islotTmp < m_islotWritePos; islotTmp++)
- {
- SlotAt(islotTmp)->IncPosPassIndex();
- }
- }
-
- if (fInitial)
- m_islotSegMin = islotLB; // just before the LB
- else
- m_islotSegLim = islotLB + 1; // just after the LB
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the index of the line break glyph within the specified range, or -1 if none.
- Recipient is functioning as the output stream.
-
- @param chwLB - glyph ID being used for line-break glyphs
- @param islotMin/Lim - range to search
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::FindFinalLineBreak(gid16 chwLB, int islotMin, int islotLim)
-{
- for (int islot = islotMin; islot < islotLim; ++islot)
- {
- if (m_vpslot[islot]->IsFinalLineBreak(chwLB))
- return islot;
- }
- return -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- A slot has been inserted (nInc == 1) or deleted (nInc == -1). Adjust the next-chunk map
- of the previous stream to match.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::AdjustPrevStreamNextChunkMap(GrTableManager * ptman, int islotMod, int nInc)
-{
- if (m_ipass == 0)
- return; // no previous stream to adjust
-
- int islotTmp = max(islotMod - 5, 0);
- while (islotTmp > 0 && m_vislotPrevChunkMap[islotTmp] == -1)
- islotTmp--;
-
- ptman->InputStream(m_ipass)->AdjustNextChunkMap(
- ((islotTmp <= 0) ? 0 : m_vislotPrevChunkMap[islotTmp]),
- islotMod, nInc);
-}
-
-/*----------------------------------------------------------------------------------------------
- An insertion or deletion has occurred at the given location in the following stream
- (specifically of an line-break glyph). Adjust the next-chunk-map accordingly so
- the indices still match.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::AdjustNextChunkMap(int islotMin, int islotInsOrDel, int nInc)
-{
- for (int islot = islotMin; islot < m_islotWritePos; islot++)
- {
- if (m_vislotNextChunkMap[islot] != -1 && m_vislotNextChunkMap[islot] >= islotInsOrDel)
- m_vislotNextChunkMap[islot] += nInc;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Unwind the read position of the stream, so that the following pass will begin
- reading from the new position. The recipient is functioning as the input stream.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::UnwindInput(int islotNewPos, bool fPreBidiPass)
-{
- Assert(m_islotReprocPos == -1);
- Assert(islotNewPos <= m_islotReadPos);
-
- int islot;
- for (islot = islotNewPos; islot < m_islotReadPos; ++islot)
- m_vislotNextChunkMap[islot] = -1;
-
- m_islotReadPos = islotNewPos;
- m_islotReadPosMax = m_islotReadPos;
-
- Assert(m_islotReadPos <= m_islotWritePos);
- if (fPreBidiPass)
- {
- for (islot = m_islotReadPos; islot < m_islotWritePos; ++islot)
- SlotAt(islot)->ZapDirLevel();
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Unwind the write position of the stream, so that the pass will begin writing
- at the new position. The recipient is functioning as the output stream
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::UnwindOutput(int islotNewPos, bool fOutputOfPosPass)
-{
- Assert(islotNewPos <= m_islotWritePos);
-
- int islot;
- for (islot = islotNewPos; islot < m_islotWritePos; ++islot)
- {
- m_vislotPrevChunkMap[islot] = -1;
-
- if (!fOutputOfPosPass && m_fUsedByPosPass)
- // This stream is the input to the first positioning pass, ie, the output
- // of the last sub pass or the bidi pass. Zap the stream indices,
- // since unwinding this pass could cause them to be invalid due to a later
- // reordering.
- SlotAt(islot)->ZapPosPassIndex();
- }
-
- m_islotWritePos = islotNewPos;
-
- m_fFullyWritten = false;
-
- if (m_islotSegMin > m_islotWritePos)
- m_islotSegMin = -1;
- if (m_islotSegLim > m_islotWritePos)
- m_islotSegLim = -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- We've just created a new chunk, with the recipient as the output stream. The beginning
- of the chunk is passed as 'islotOutput' and the end of the chunk is assumed to be the
- write-position of the recipient. Store the mappings into the corresponding
- input position.
-
- @param islotInputMin - beginning of chunk in input stream
- @param islotOutputMin - beginning of chunk in output stream (recipient)
- @param islotInputLim - end of chunk in input stream (currently not used)
- @param fSkipChunkStart - if true, either we have reprocessed part of a
- previously created chunk,
- or there was no input consumed;
- in either case, don't record the beginning of the chunk,
- just make this chunk be part of the previous
- @param fBackingUp - this chunk results in the stream position moving backwards,
- so clear anything we're backing over
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::MapInputChunk(int islotInputMin, int islotOutputMin, int islotInputLim,
- bool fSkipChunkStart, bool fBackingUp)
-{
- Assert(AssertValid());
- Assert(islotOutputMin >= -1);
-
- if (!fSkipChunkStart)
- {
- Assert(islotOutputMin >= 0);
- if (islotOutputMin >= 0) // just in case an invalid value was passed
- m_vislotPrevChunkMap[islotOutputMin] = islotInputMin;
- }
-
- int islot;
- for (islot = max(0, islotOutputMin + 1); islot < m_islotWritePos; ++islot)
- m_vislotPrevChunkMap[islot] = -1; // not a chunk boundary
-
-// if (fBackingUp && m_islotWritePos < m_vislotPrevChunkMap.Size())
-// m_vislotPrevChunkMap[m_islotWritePos] = -1;
-
- if (fBackingUp)
- for (islot = m_islotWritePos; islot < signed(m_vislotPrevChunkMap.size()); islot++)
- m_vislotPrevChunkMap[islot] = -1;
-
-// m_vislotPrevChunkMap[m_islotWritePos] = islotInputLim;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the length of the final chunk, where the recipient is the input stream.
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::LastNextChunkLength()
-{
- int cslotRet = 1;
- for (int islot = m_islotReadPos; islot-- > 0; )
- {
- if (m_vislotNextChunkMap[islot] != -1)
- return cslotRet;
- cslotRet++;
- }
- return cslotRet + 1;
-}
-
-/*----------------------------------------------------------------------------------------------
- We've just created a new chunk, with the recipient as the input stream. The beginning of
- the chunk is passed as 'islotInputMin' and the end of the chunk is assumed to be the
- read-position of the recipient. Store the mappings into the corresponding
- output position.
-
- @param islotOutputMin - beginning of chunk in output stream
- @param islotInputMin - beginning of chunk in input stream (recipient)
- @param islotOutputLim - end of chunk in output stream (currently not used)
- @param fSkipChunkStart - if true, either we have reprocessed part of a
- previously created chunk,
- or there was no output generated;
- in either case, don't record the beginning of the chunk,
- just make this chunk be part of the previous
- @param fBackingUp - this chunk results in the stream position moving backwards,
- so clear anything we're backing over
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::MapOutputChunk(int islotOutputMin, int islotInputMin, int islotOutputLim,
- bool fSkipChunkStart, int cslotReprocess, bool fBackingUp)
-{
- Assert(AssertValid());
-
- // Note: islotInputMin can be less than -1 if there is a large reprocess buffer near the
- // beginning of the input stream. In which case, fSkipChunk start should be true and
- // cslotReprocess large enough to keep any of the stuff below from having any problems.
- //Assert(islotInputMin >= -1);
-
- if (!fSkipChunkStart)
- {
- Assert(islotInputMin >= 0);
- if (islotInputMin >= 0) // just in case an invalid value was passed
- m_vislotNextChunkMap[islotInputMin] = islotOutputMin;
- }
-
- int islot;
- for (islot = max(0, islotInputMin + 1 + cslotReprocess); islot < m_islotReadPos; ++islot)
- m_vislotNextChunkMap[islot] = -1; // not a chunk boundary
-
-// if (fBackingUp && m_islotReadPos < m_vislotNextChunkMap.Size())
-// m_vislotNextChunkMap[m_islotReadPos] = -1;
-
- if (fBackingUp)
- for (islot = m_islotReadPos; islot < signed(m_vislotNextChunkMap.size()); islot++)
- m_vislotNextChunkMap[islot] = -1;
-
-// m_vislotNextChunkMap[m_islotReadPos] = islotOutputLim;
-}
-
-/*----------------------------------------------------------------------------------------------
- Ensure that the chunk maps for a pair of streams match properly. The recipient is
- the input stream.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::AssertChunkMapsValid(GrSlotStream * psstrmOut)
-{
-#ifdef _DEBUG
- GrSlotStream * psstrmIn = this;
-
- Assert(m_ipass == 0 || (m_ipass + 1 == psstrmOut->m_ipass));
-
- int islotMapNext;
- int islotMapPrev;
- int islot;
- for (islot = 0; islot < m_islotReadPos; ++islot)
- {
- islotMapNext = psstrmIn->ChunkInNext(islot);
- Assert(islotMapNext != -2);
- if (islotMapNext != -1)
- {
- islotMapPrev = psstrmOut->ChunkInPrev(islotMapNext);
- if (islotMapPrev == -2)
- {
- Assert(islot == psstrmOut->WritePos());
- }
- else
- {
- Assert(islot == islotMapPrev);
- }
- }
- }
-
- for (islot = 0; islot < psstrmOut->m_islotWritePos; ++islot)
- {
- islotMapPrev = psstrmOut->ChunkInPrev(islot);
- Assert(islotMapPrev != -2);
- if (islotMapPrev != -1)
- {
- islotMapNext = psstrmIn->ChunkInNext(islotMapPrev);
- if (islotMapNext == -2)
- {
- Assert(islot == psstrmIn->ReadPos());
- }
- else
- {
- Assert(islot == islotMapNext);
- }
- }
- }
-#endif // _DEBUG
-}
-
-/*----------------------------------------------------------------------------------------------
- Ensure that corresponding items in the streams of a positioning pass have matching
- stream indices. The recipient is the output stream.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::AssertStreamIndicesValid(GrSlotStream * psstrmIn)
-{
-#ifdef _DEBUG
- if (!GotIndexOffset())
- return;
-
- Assert(m_fUsedByPosPass);
-
- for (int islot = 0; islot < WritePos(); islot++)
- {
- GrSlotState * pslotOut = SlotAt(islot);
- GrSlotState * pslotIn =
- psstrmIn->SlotAt(islot + psstrmIn->IndexOffset() - IndexOffset());
- Assert(pslotOut->PosPassIndex() == pslotIn->PosPassIndex());
- Assert(pslotOut->HasAsPreviousState(pslotIn));
- }
-#endif // _DEBUG
-}
-
-/*----------------------------------------------------------------------------------------------
- Ensure that the roots of all attachments made in this chunk are present
- in the output stream. (Currently the compiler ensures this by making it an error
- to write rules that don't do this.)
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::AssertAttachmentsInOutput(int islotMin, int islotLim)
-{
-#ifdef _DEBUG
- for (int islot = islotMin; islot < islotLim; islot++)
- {
- GrSlotState * pslotOut = SlotAt(islot);
- int dislot = pslotOut->AttachTo();
- Assert(islotMin <= islot + dislot);
- Assert(islot + dislot < islotLim);
- }
-#endif // _DEBUG
-}
-
-/*----------------------------------------------------------------------------------------------
- Answer the slot index corresponding to the start of the chunk (as mapped to the following
- stream).
- ENHANCE: make more robust.
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::ChunkInNextMin(int islot)
-{
- int islotRet = islot;
- while (m_vislotNextChunkMap[islotRet] == -1 && islotRet > 0)
- --islotRet;
- return islotRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Answer the slot index corresponding to the end of the chunk (as mapped to the following
- stream).
- ENHANCE: make more robust.
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::ChunkInNextLim(int islot)
-{
- int islotRet = islot + 1;
- if (islotRet == m_islotReadPos)
- return islot;
- while (m_vislotNextChunkMap[islotRet] == -1 && islotRet < m_islotReadPos)
- {
- ++islotRet;
- Assert(islotRet < signed(m_vislotNextChunkMap.size()));
- }
- return islotRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Skip over the given number slots. This is used to resync the streams when we
- are restarting a new segment. Specifically the output stream informs the
- input stream of the number of slots to skip to get the boundary for a chunk that
- the output finds interesting.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::ResyncSkip(int cslot)
-{
- Assert(AssertValid());
- m_islotReadPos += cslot;
- m_cslotSkippedForResync = cslot;
- // Should never skip past the beginning of the line.
- Assert(m_islotSegMin == -1 || m_islotReadPos <= m_islotSegMin);
-}
-
-/*----------------------------------------------------------------------------------------------
- Record the number of slots in the stream that are previous to the official start of the
- segment.
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::CalcIndexOffset(GrTableManager * ptman)
-{
- if (GotIndexOffset())
- return; // already figured it
-
- if (m_islotSegMin > -1)
- {
- m_cslotPreSeg = m_islotSegMin;
- if (m_fUsedByPosPass)
- {
- for (int islotPre = 0; islotPre < WritePos(); islotPre++)
- {
- SlotAt(islotPre)->SetPosPassIndex(islotPre - m_cslotPreSeg,
- m_fInputToPosPass1);
- }
- }
- }
- // else can't figure it out yet
-
- // Old code:
-#if 0
- gid16 chwLB = ptman->LBGlyphID();
-
- for (int islot = 0; islot < WritePos(); islot++)
- {
- if (SlotAt(islot)->IsLineBreak(chwLB))
- {
- if (SlotAt(islot)->IsInitialLineBreak(chwLB))
- {
- m_cslotPreSeg = islot;
- }
- else
- {
- // Otherwise, we hit the final line break, which is kind of strange, because
- // in this case there is no initial line break, and we should have set
- // m_cslotPreSeg to 0 immediately when it was initialized.
- Assert(false);
- m_cslotPreSeg = 0;
- }
-
- if (m_fUsedByPosPass)
- {
- for (int islotPre = 0; islotPre < WritePos(); islotPre++)
- {
- SlotAt(islotPre)->SetPosPassIndex(islotPre - m_cslotPreSeg,
- m_fInputToPosPass1);
- }
- }
- return;
- }
-
- }
- // No line breaks yet, so no way to tell.
-#endif
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the positions in the streams for the next rule. The recipient is the output stream.
- If we are moving backwards, copy part of the output stream back to (a temporary buffer
- in) the input stream, so that we can reprocess it.
-
- @param cslotArg - how far to skip forward or back; most commonly zero
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::SetPosForNextRule(int cslotArg, GrSlotStream * psstrmIn,
- bool fOutputOfPosPass)
-{
- Assert(AssertValid());
-
- int cslot = cslotArg;
- // Can't reprocess what has already been read by the next pass. MaxBackup should allow
- // the flexibility needed, but if not, we fix it here.
- if (m_islotWritePos + cslot < m_islotReadPos)
- cslot = m_islotReadPos - m_islotWritePos;
-
- Assert(psstrmIn->m_ipass == m_ipass-1);
-
- if (cslot >= 0)
- {
- // Skipping forward.
- Assert(cslot <= psstrmIn->SlotsPendingInContext());
- for (int islot = 0; islot < cslot; islot++)
- CopyOneSlotFrom(psstrmIn);
- }
- else
- {
- // Reprocessing.
-
- // Save corresponding positions before doing the back-up.
- int islotReadPosInSave = psstrmIn->ReadPosForNextGet();
- int islotWritePosOutSave = this->WritePos();
-
- std::vector<GrSlotState*> vpslotTmp;
- int islot;
- if (psstrmIn->SlotsToReprocess() > 0)
- {
- // Stick any slots still to reprocess in a temporary buffer.
- for (islot = psstrmIn->m_islotReprocPos;
- islot < signed(psstrmIn->m_vpslotReproc.size());
- islot++)
- {
- vpslotTmp.push_back(psstrmIn->m_vpslotReproc[islot]);
- }
- }
-
- psstrmIn->ClearReprocBuffer();
- psstrmIn->m_islotReprocLim = psstrmIn->m_islotReadPos;
-
- for (islot = cslot; islot < 0; islot++)
- psstrmIn->m_vpslotReproc.push_back(m_vpslot[m_islotWritePos+islot]);
- for (islot = 0; islot < signed(vpslotTmp.size()); islot++)
- psstrmIn->m_vpslotReproc.push_back(vpslotTmp[islot]);
- psstrmIn->m_islotReprocPos = 0;
-
- if (!fOutputOfPosPass && m_fUsedByPosPass)
- {
- // Last substitution pass; zap the stream indices, since they may
- // now be invalid.
- for (islot = 0; islot < signed(psstrmIn->m_vpslotReproc.size()); islot++)
- psstrmIn->m_vpslotReproc[islot]->ZapPosPassIndex();
- }
-
- // If either the min or lim is in the middle of the reprocess buffer,
- // adjust as necessary to match where it is in the output stream.
- int islotSegMinIn = psstrmIn->SegMin();
- if (islotSegMinIn > -1 &&
- psstrmIn->ReadPosForNextGet() <= islotSegMinIn &&
- islotSegMinIn < islotReadPosInSave)
- {
- Assert(this->SegMin() > -1);
- int dislotIn = islotReadPosInSave - islotSegMinIn;
- int dislotOut = islotWritePosOutSave - SegMin();
- psstrmIn->SetSegMin(islotSegMinIn + dislotIn - dislotOut, true);
- if (psstrmIn->m_cslotPreSeg > psstrmIn->SegMin())
- psstrmIn->m_cslotPreSeg = -1;
- }
- int islotSegLimIn = psstrmIn->SegLimIfKnown();
- if (islotSegLimIn > -1 &&
- psstrmIn->ReadPosForNextGet() <= islotSegLimIn &&
- islotSegLimIn < islotReadPosInSave)
- {
- int islotSegLimOut = this->SegLimIfKnown();
- Assert(islotSegLimOut > -1);
- int dislotIn = islotReadPosInSave - islotSegLimIn;
- int dislotOut = islotWritePosOutSave - islotSegLimOut;
- psstrmIn->SetSegLim(islotSegLimIn + dislotIn - dislotOut);
- }
-
- m_islotWritePos += cslot;
-
- if (m_islotSegMin >= m_islotWritePos)
- m_islotSegMin = -1;
- if (m_islotSegLim >= m_islotWritePos)
- m_islotSegLim = -1;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- If a rule was run over a LB glyph, set the appropriate flag in the table manager.
- CURRENTLY NOT USED
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::SetLBContextFlag(GrTableManager * ptman, int islotStart)
-{
- gid16 chwLB = ptman->LBGlyphID();
- for (int islot = islotStart; islot < WritePos(); islot++)
- {
- GrSlotState * pslot = SlotAt(islot);
- if (pslot->IsInitialLineBreak(chwLB))
- ptman->State()->SetStartLineContext(true);
- if (pslot->IsFinalLineBreak(chwLB))
- ptman->State()->SetEndLineContext(true);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the number of slots that have been output by the current pass but must be
- reprocessed by this same pass. The recipient is serving as the input stream.
-----------------------------------------------------------------------------------------------*/
-int GrSlotStream::SlotsToReprocess()
-{
- Assert(AssertValid());
-
- if (m_islotReprocPos == -1)
- return 0;
- return (m_vpslotReproc.size() - m_islotReprocPos);
-}
-
-/*----------------------------------------------------------------------------------------------
- Get the input at the given slot, that is, the original input, ignoring the issue of
- reprocessing.
-----------------------------------------------------------------------------------------------*/
-GrSlotState * GrSlotStream::GetSlotAt(int islot)
-{
- return m_vpslot[islot];
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the "current" input item from the rule's perspective, ie, the last slot read.
- So dislotOffset = 0 means not the slot at the read position but one slot earlier.
-
- If dislotOffset is less the the original read position that was in effect at the
- beginning of the rule, we need to read from the output stream, which has the
- up-to-date values. See the class comment for more details.
-
- @param dislotOffset - offset from current stream position
- @param fNullOkay - true if it's okay to return NULL in the situation where we're asking
- for something before the beginning of the stream
-----------------------------------------------------------------------------------------------*/
-
-GrSlotState * GrSlotStream::RuleInputSlot(int dislotOffset, GrSlotStream * psstrmOutput,
- bool fNullOkay)
-{
- Assert(m_islotRuleStartRead <= m_islotReadPos);
-
- if (dislotOffset > 0)
- return Peek(dislotOffset - 1);
-
- int cslotOffsetBack = dislotOffset * -1;
-
- if (m_islotReprocLim > -1)
- {
- // There is a reprocess buffer.
-
- // Position when starting the rule should never be earlier than the
- // beginning of the reprocess buffer.
- Assert(m_islotRuleStartRead >= m_islotReprocLim - signed(m_vpslotReproc.size()));
-
- // number of items following the reprocess buffer:
- int cslotPostReproc = m_islotReadPos - m_islotReprocLim;
-
- if (cslotOffsetBack >= cslotPostReproc)
- {
- // number of items in the reprocess buffer that were valid when the rule
- // was started:
- int cslotValidReproc = m_islotReprocLim - m_islotRuleStartRead;
-
- if (cslotOffsetBack >= cslotPostReproc + cslotValidReproc)
- {
- // Read from the output stream.
- int dislotTmp = dislotOffset - 1 + cslotPostReproc + cslotValidReproc;
- Assert(dislotTmp < 0);
- return psstrmOutput->PeekBack(dislotTmp);
- }
- else
- {
- if (m_islotReprocPos > -1)
- {
- // Current read pos is inside reprocess buffer.
- Assert(cslotPostReproc == 0);
- int islotStartReadReprocBuf = m_vpslotReproc.size() - cslotValidReproc;
- Assert(islotStartReadReprocBuf >= 0);
- int islotInReprocBuf = m_islotReprocPos - cslotOffsetBack - 1;
- if (islotInReprocBuf < islotStartReadReprocBuf)
- {
- // Return a slot from before the reprocess buffer, from the
- // output stream (which is serving as our input stream for precontext
- // items).
- return psstrmOutput->PeekBack(islotInReprocBuf - islotStartReadReprocBuf);
- }
- else if (islotInReprocBuf < 0)
- {
- Assert(false);
- //int islotReprocMin = m_islotReprocLim - m_vpslotReproc.Size();
- //return m_vpslot[islotReprocMin + islotInReprocBuf];
- }
- else
- // Read from the reprocess buffer.
- return m_vpslotReproc[islotInReprocBuf];
- }
- else
- // Looking backwards into the reprocess buffer.
- return m_vpslotReproc[
- m_vpslotReproc.size() - cslotOffsetBack + cslotPostReproc - 1];
- }
- }
- }
-
- // There is no reprocess buffer, or it is not a factor.
-
- if (m_islotReadPos + dislotOffset - 1 < m_islotRuleStartRead)
- {
- // Read from the output stream.
- return psstrmOutput->PeekBack(m_islotReadPos + dislotOffset - 1 - m_islotRuleStartRead,
- fNullOkay);
- }
- else
- {
- // Read normally from the input stream.
- return m_vpslot[m_islotReadPos - cslotOffsetBack - 1];
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the "current" output item from the rule's perspective, ie, the last slot written.
- So dislotOffset = 0 means not the slot at the write position but one slot earlier.
-----------------------------------------------------------------------------------------------*/
-
-GrSlotState * GrSlotStream::RuleOutputSlot(int dislotOffset)
-{
- return m_vpslot[m_islotWritePos - 1 + dislotOffset];
-}
-
-/*----------------------------------------------------------------------------------------------
- For any slot in the final output that has no associations, set the "before" pointer to
- the following slot and the "after" pointer to the preceding slot. The idea of this is
- that it will make it impossible to select a the glyph separately.
-
- Note that if the slot is the first on the line, it will not be associated with
- a slot in the previous segment.
-
- @param chwLB - the glyph IB for the line-break glyphs
-----------------------------------------------------------------------------------------------*/
-void GrSlotStream::SetNeutralAssociations(gid16 chwLB)
-{
- for (int islot = 0; islot < m_islotWritePos; ++islot)
- {
- GrSlotState * pslot = SlotAt(islot);
- if (pslot->PassModified() > 0 &&
- (pslot->BeforeAssoc() == kPosInfinity || pslot->AfterAssoc() == kNegInfinity))
- {
- pslot->CleanUpAssocs();
- if (pslot->BeforeAssoc() != kPosInfinity && pslot->AfterAssoc() != kNegInfinity)
- continue;
-
- Assert(pslot->BeforeAssoc() == kPosInfinity && pslot->AfterAssoc() == kNegInfinity);
-
- GrSlotState * pslotBefore = FindAssociatedSlot(islot, 1, chwLB);
- GrSlotState * pslotAfter = FindAssociatedSlot(islot, -1, chwLB);
-
- if (pslotBefore && pslotAfter)
- pslot->Associate(pslotBefore, pslotAfter);
- else if (pslotBefore)
- pslot->Associate(pslotBefore);
- else if (pslotAfter)
- pslot->Associate(pslotAfter);
- else
- // Weird, but can happen with an empty segment.
- Warn("No assocations");
-
-// Assert(pslot->m_vpslotAssoc.Size() > 0);
- pslot->m_fNeutralAssocs = true;
- }
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Find the next or previous slot in the final output that has explicit associations, or
- return NULL if none.
-
- @param islot - starting slot
- @param nInc - +1 if we want to find the next slot, -1 if we want the previous slot
- @param chwLB - the glyph IB for the line-break glyphs
-----------------------------------------------------------------------------------------------*/
-GrSlotState * GrSlotStream::FindAssociatedSlot(int islot, int nInc, gid16 chwLB)
-{
- int islotNext = islot + nInc;
-
- while (islotNext >= 0 && islotNext < m_islotWritePos)
- {
- GrSlotState * pslotRet = SlotAt(islotNext);
- if (pslotRet->IsLineBreak(chwLB))
- { }
- else if (pslotRet->PassModified() == 0 ||
- (pslotRet->m_vpslotAssoc.size() > 0 && pslotRet->m_fNeutralAssocs == false))
- {
- return pslotRet;
- }
- islotNext += nInc;
- }
- return NULL;
-}
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/GrSlotStream.h b/Build/source/libs/graphite-engine/src/segment/GrSlotStream.h
deleted file mode 100644
index 006191252dc..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrSlotStream.h
+++ /dev/null
@@ -1,577 +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: GrSlotStream.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Classes GrSlotStream and GrSlotState.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef SLOTSTREAM_INCLUDED
-#define SLOTSTREAM_INCLUDED
-
-//:End Ignore
-
-namespace gr
-{
-
-class EngineState;
-class Font;
-
-/*----------------------------------------------------------------------------------------------
- Each GrSlotStream represents the output of one pass, which also serves as the input
- of the following pass. Hence it has two positions, a write position for when it is
- serving as an output stream, and a read position for when it is serving as an input
- stream. The TableManager holds a list of the streams.
-
- The reading of slot streams is complicated by two factors. First, it may be necessary
- to access the "pre-context" items of a rule, which are the slots before the current
- stream position at the point when the rule is matched. These items will not be modified
- by the rule, but may have been modified by a previous rule in the same pass, Therefore
- we need to read these slots from the output stream, rather than the input stream,
- because the output stream has the current slot attribute values that we want to work with.
- In order make this happen, we keep track of the read and write positions of
- the streams at the time the current rule was matched (m_islotRuleStartRead and
- m_islotRuleStartWrite) and whenever we try to read a slot before m_islotRuleStartRead,
- we read the corresponding slot from the output stream instead.
-
- Second, a rule may explicitly set the advance position so that some items are
- actually reprocessed (and potentially modified) by the same pass. When this happens,
- we actually copy the slots to reprocess from the output stream back
- into a temporary buffer (m_vpslotReproc) in the input stream, and set up the stream so
- that the next read operations will read from the buffer.
-
- It gets tricky because these two mechanisms can overlap with each other, so care
- must be taken to read from the right place: the input stream in the normal way,
- the reprocess buffer, or the output stream. See the RuleInputSlot method.
-
- Another messy bit of code has to do with maintaining chunks. These are used for
- backtracking and unwinding after inserting a line-break. Adjacent streams have maps
- showing how many slots were processed by a single rule; the maps must be consisent
- between adjacent rules. The following is an example of a pair of valid chunk maps:
-
- Input stream Output stream
- Pos next-map prev-map
- 0 0 0
- 1 -1 -1
- 2 2 2
- 3 4 -1
- 4 -1 3
- 5 -1 -1
- 6 7 -1
- 7 -1 6
- 8 -1 -1
-
- A -1 means that slot is not at the beginning of a chunk. Otherwise, there must be a
- corresponding value in the parallel map of the adjacent stream--eg, the input stream's
- next-map(3) == 4 and the output stream's prev-map(4) == 3. Assertions are run
- regularly to ensure that the chunk maps stay valid.
-
- So above, the first chunk corresponds to slots 0-1 in the input and 0-1 in the output;
- two slots were processed by the rule. The second chunk corresponds to slot 2
- in the input and slots 2-3 in the output (a slot was inserted).
- The third corresponds to slots 3-5 in the input and 4-6 in the output (three slots
- processed). The fourth chunk covers slots 6-8 in the input and 7-8 in the output
- (one slot was deleted).
-
- ENHANCE SharonC: explain the effect of skipped slots on the chunk maps.
-
- Hungarian: sstrm
-----------------------------------------------------------------------------------------------*/
-class GrSlotStream {
-
- friend class GrSlotState;
- friend class FontMemoryUsage;
-
-public:
- // Constructor:
- GrSlotStream(int ipass)
- {
- m_ipass = ipass;
- m_vpslot.clear();
- m_vislotPrevChunkMap.clear();
- m_vislotNextChunkMap.clear();
- m_vpslotReproc.clear();
- }
-
- // Destructor:
- ~GrSlotStream()
- {
- ReleaseSlots(0, m_vpslot.size());
- }
-
- void ReleaseSlots(int islotMin, int islotLim)
- {
- // A slot stream is responsible for deleting the slot states that it created,
- // that is, the ones whose modified tag equals this stream's pass index.
- // NO LONGER TRUE - there is a master list of them managed by the GrTableManager.
-// for (int islot = islotMin; islot < islotLim; ++islot)
-// {
-// if (m_vpslot[islot]->m_ipassModified == m_ipass)
-// delete m_vpslot[islot];
-// }
- }
-
- // Getters:
- int WritePos() { return m_islotWritePos; }
- int ReadPos() { return m_islotReadPos; }
- bool FullyWritten() { return m_fFullyWritten; }
-
- int SlotsPresent() { return m_vpslot.size(); }
-
- // Setters:
- void SetWritePos(int islot)
- {
- m_islotWritePos = islot;
- }
- void SetReadPos(int islot)
- {
- m_islotReadPos = islot;
- }
-
- void Initialize(int ipassPos1, bool fAnythingPrevious)
- {
- m_islotWritePos = 0;
- m_islotReadPos = 0;
- m_islotReprocPos = -1;
- m_islotReprocLim = -1;
- m_islotRuleStartRead = 0;
- m_islotRuleStartWrite = 0;
- m_islotReadPosMax = 0;
- m_cslotSkippedForResync = 0;
- m_cslotPreSeg = (fAnythingPrevious) ? -1 : 0;
- m_fFullyWritten = false;
- m_islotSegMin = -1;
- m_islotSegLim = -1;
- m_fUsedByPosPass = (m_ipass + 1 >= ipassPos1);
- m_fInputToPosPass1 = (m_ipass + 1 == ipassPos1);
- m_vpslot.clear(); // not responsible for destroying the slots
- m_vislotPrevChunkMap.clear();
- m_vislotNextChunkMap.clear();
- }
-
-public:
- bool AtEnd();
- bool AtEndOfContext();
- void NextPut(GrSlotState* pslot);
- GrSlotState * NextGet();
- GrSlotState * Peek(int dislot = 0);
- GrSlotState * PeekBack(int dislot, bool fNullOkay = false);
- void Skip(int = 1);
- GrSlotState * SlotAt(int islot)
- {
- return m_vpslot[islot];
- }
-
- int OutputOfPass()
- {
- return m_ipass;
- }
-
- // This function is intended to be used within positioning passes where there is a
- // one-to-one correspondence beween the slots in consecutive streams.
- GrSlotState * OutputSlotAt(int islot)
- {
- return Peek(islot - ReadPosForNextGet());
- }
-
- int ReadPosForNextGet()
- {
- return ReadPos() - SlotsToReprocess();
- }
-
- // Only valid for streams that are the input or output to a positioning pass.
- GrSlotState * SlotAtPosPassIndex(int islot)
- {
- Assert(GotIndexOffset());
- Assert(m_fUsedByPosPass);
- return m_vpslot[islot + m_cslotPreSeg];
- }
-
- // Only valid for streams that are the input or output to a positioning pass.
- bool HasSlotAtPosPassIndex(int islot)
- {
- Assert(GotIndexOffset());
- Assert(m_fUsedByPosPass);
- return (signed(m_vpslot.size()) > (islot + m_cslotPreSeg));
- }
-
- bool AssertValid();
- void AssertChunkMapsValid(GrSlotStream * psstrmOut);
- void AssertStreamIndicesValid(GrSlotStream * psstrmIn);
- void AssertAttachmentsInOutput(int islotMin, int islotLim);
- bool NoReproc()
- {
- return (m_islotReprocPos == -1 || (m_islotReprocPos >= signed(m_vpslotReproc.size())));
- }
-
- int SlotsPending();
- int SlotsPendingInContext();
- int TotalSlotsPending();
- bool PastEndOfPositioning(bool fOutput);
-
- void ClearReprocBuffer()
- {
- m_islotReprocPos = -1;
- m_islotReprocLim = -1;
- m_vpslotReproc.clear();
- }
-
- int ReprocLim()
- {
- return m_islotReprocLim;
- }
-
- int ReprocMin()
- {
- Assert(m_islotReprocPos > -1);
- return m_islotReprocLim - m_vpslot.size();
- }
-
- int RuleStartReadPos()
- {
- return m_islotRuleStartRead;
- }
-
- void SetRuleStartReadPos()
- {
- if (m_islotReprocPos > -1)
- m_islotRuleStartRead = m_islotReprocLim - SlotsToReprocess();
- else
- m_islotRuleStartRead = m_islotReadPos;
- }
-
- int RuleStartWritePos()
- {
- return m_islotRuleStartWrite;
- }
-
- void SetRuleStartWritePos()
- {
- m_islotRuleStartWrite = m_islotWritePos;
- }
-
- void MarkFullyWritten();
-
- void SetSegMin(int islot, bool fAdjusting = false)
- {
- Assert(fAdjusting || m_islotSegMin == -1 || m_islotSegMin == islot);
- m_islotSegMin = islot;
- }
- void SetSegMinToWritePos(bool fMod = true)
- {
- if (m_islotSegMin == -1)
- m_islotSegMin = m_islotWritePos;
- else
- Assert(m_islotSegMin <= m_islotWritePos); // eg, already set to before the initial LB
- }
- int SegMin()
- {
- return m_islotSegMin;
- }
- void SetSegLim(int islot)
- {
- m_islotSegLim = islot;
- }
- void SetSegLimToWritePos(bool fMod = true)
- {
- if (m_islotSegLim > -1 && !fMod)
- {
- Assert(m_islotSegLim <= m_islotWritePos);
- return;
- }
- m_islotSegLim = m_islotWritePos;
- }
- int SegLimIfKnown()
- {
- return m_islotSegLim;
- }
- int FinalSegLim()
- {
- if (m_islotSegLim > -1)
- return m_islotSegLim;
- else
- return m_islotWritePos;
- }
-
- // Return true if we are exactly at the segment min.
- bool AtSegMin()
- {
- if (m_islotSegMin == -1)
- return false;
- return (m_islotSegMin == ReadPosForNextGet());
- }
-
- // Return true if we are exactly at the segment lim.
- bool AtSegLim()
- {
- if (m_islotSegLim == -1)
- return false;
- return (m_islotSegLim == ReadPosForNextGet());
- }
-
- int ReadPosMax()
- {
- return m_islotReadPosMax;
- }
- void SetReadPosMax(int islot)
- {
- m_islotReadPosMax = std::max(m_islotReadPosMax, islot);
- }
-
- int OldDirLevelRange(EngineState * pengst, int islotStart, int nTopDirection);
- int DirLevelRange(EngineState * pengst, int islotStart, int nTopDirection,
- std::vector<int> & vislotStarts, std::vector<int> & vislotStops);
- int GetSlotDirLevel(EngineState * pengst, int islot,
- int nOuterLevel, int nCurrLevel, DirCode dircMarker, DirCode dircOverride);
- DirCode AdjacentStrongCode(EngineState * pengst, int islot, int nInc,
- DirCode dircPDF, bool fNumbersAreStrong = false);
- DirCode TerminatorSequence(EngineState * pengst, int islot, int nInc, DirCode dircPDF);
- DirCode AdjacentNonBndNeutralCode(EngineState * pengst, int islot, int nInc,
- DirCode dircPDF);
-
- void CopyOneSlotFrom(GrSlotStream * psstrmPrev);
- void SimpleCopyFrom(GrSlotStream * psstrmI, int islotInput, int islotOutput);
-
- bool MoreSpace(GrTableManager * ptman,
- float xsSpaceAllotted, bool fWidthIsCharCount,
- bool fIgnoreTrailingWS, TrWsHandling twsh,
- float * pxsWidth);
-
- int InsertLineBreak(GrTableManager * ptman,
- int islotPrevBreak, bool fInsertedLB, int islotStartTry,
- LineBrk lb, TrWsHandling twsh, int islotMin, LineBrk * plbNextToTry);
- int MakeSegmentBreak(GrTableManager * ptman,
- int islotPrevBreak, bool fInsertedLB, int islotStartTry,
- LineBrk lb, TrWsHandling twsh, int islotMin, LineBrk * plbNextToTry);
- bool FindSegmentEnd(GrTableManager * ptman,
- int islotStartTry, LineBrk lb, TrWsHandling twsh, int islotMin,
- int * pislot, int * pichwSegOffset,
- LineBrk * plbFound, LineBrk * plbNextToTry);
- bool HasEarlierBetterBreak(int islotBreak, LineBrk lbFound, gid16 chwLB);
- LineBrk BreakWeightAt(gid16 chwLB, int islot);
- void AppendLineBreak(GrTableManager *, GrCharStream * pchstrm,
- LineBrk, DirCode dirc, int islot, bool fInitial, int ichwSegOffset);
- int FindFinalLineBreak(gid16 chwLB, int islotMin, int islotLim);
- void AdjustPrevStreamNextChunkMap(GrTableManager * ptman, int islotMod, int nInc);
- void AdjustNextChunkMap(int islotMin, int islotMod, int nInc);
-
- void EnsureLocalCopy(GrTableManager * ptman, GrSlotState * pslot, GrSlotStream * psstrmIn);
- void ReplaceSlotInReprocessBuffer(GrSlotState * pslotOld, GrSlotState * pslotNew);
-
- void ZapCalculatedDirLevels(int islotLB);
-
- int MaxClusterSlot(int islotChunkLim)
- {
- return MaxClusterSlot(islotChunkLim - 1, islotChunkLim);
- }
- int MaxClusterSlot(int islotChunkMin, int islotChunkLim);
-
- void UnwindInput( int islot, bool fPreBidiPass);
- void UnwindOutput(int islot, bool fOutputOfPosPass);
-
- void MapInputChunk( int islotIn, int islotOut, int islotInLim,
- bool fReprocessing, bool fBackingUp);
- void MapOutputChunk(int islotOut, int islotIn, int islotOutLim,
- bool fReprocessing, int cslotReprocess, bool fBackingUp);
-
- int LastNextChunkLength();
-
- int ChunkInPrev(int i)
- {
- Assert(i >= 0);
- Assert(i < signed(m_vislotPrevChunkMap.size()));
- Assert(i < m_islotWritePos);
- return m_vislotPrevChunkMap[i];
- }
- int ChunkInNext(int i)
- {
- Assert(i >= 0);
- Assert(i < signed(m_vislotNextChunkMap.size()));
- Assert(i < m_islotReadPos);
- return m_vislotNextChunkMap[i];
- }
-
- int ChunkInNextMin(int islot);
- int ChunkInNextLim(int islot);
-
- void ResyncSkip(int nslot);
- int SlotsSkippedToResync()
- {
- return m_cslotSkippedForResync;
- }
- void ClearSlotsSkippedToResync()
- {
- m_cslotSkippedForResync = 0;
- }
-
- int IndexOffset()
- {
- Assert(GotIndexOffset()); // should have been calculated
- return m_cslotPreSeg;
- }
- void SetIndexOffset(int c)
- {
- m_cslotPreSeg = c;
- }
- bool GotIndexOffset()
- {
- return (m_cslotPreSeg >= 0);
- }
- void CalcIndexOffset(GrTableManager * ptman);
-
- void SetPosForNextRule(int nslot, GrSlotStream * psstrmInput, bool fOutputOfPosPass);
- void SetLBContextFlag(GrTableManager * ptman, int islotStart);
- int SlotsToReprocess();
-
- void SetNeutralAssociations(gid16 chwLB);
-protected:
- GrSlotState * FindAssociatedSlot(int islot, int nInc, gid16 chwLB);
-
- GrSlotState * GetSlotAt(int islot);
-
-public:
- // Used by the action code:
- void BackupReadPos(int cslot = 1)
- {
- for (int islot = 0; islot < cslot; islot++)
- {
- if (m_islotReprocLim > -1 && m_islotReprocLim == m_islotReadPos)
- {
- if (m_islotReprocPos == -1)
- m_islotReprocPos = m_vpslotReproc.size() - 1;
- else
- --m_islotReprocPos;
- Assert(m_islotReprocPos >= 0);
- }
- else
- --m_islotReadPos;
- }
- }
-
- GrSlotState * RuleInputSlot(int dislot = 0, GrSlotStream * psstrmOut = NULL,
- bool fNullOkay = false);
- GrSlotState * RuleOutputSlot(int dislot = 0);
-
- void PutSlotAt(GrSlotState * pslot, int islot)
- {
- // Currently only used for the final pass, when applying justify.width to
- // the advance width.
- Assert(signed(m_vpslot.size()) > islot);
- Assert(WritePos() > islot);
- Assert(ReadPos() <= islot);
- Assert(SlotsToReprocess() == 0);
- m_vpslot[islot] = pslot;
- }
-
-protected:
- // Instance variables:
- int m_ipass; // which pass this stream is serving as OUTPUT of
-
- std::vector<GrSlotState*> m_vpslot; // the slots being processed
-
- // Chunking information:
- std::vector<int> m_vislotPrevChunkMap; // chunk mapping into previous stream;
- // -1 if not at a chunk boundary
- // (this information is needed for
- // reinitialization after inserting a line break)
-
- std::vector<int> m_vislotNextChunkMap; // chunk mapping into next stream, or -1
- // (this information is needed for backtracking)
-
- // Since most streams serve as both input and output, there are two positions.
- // Note that readPos <= writePos always.
- int m_islotWritePos; // where previous pass should put next output
- int m_islotReadPos; // where following pass should start processing from
-
- // When we are reprocessing some of the output from the next stream:
- std::vector<GrSlotState*> m_vpslotReproc; // temporary buffer
- int m_islotReprocLim; // the read position corresponding to the end of the reprocess
- // buffer; -1 if buffer is invalid
- int m_islotReprocPos; // index into m_vpslotReproc from where we should read next;
- // -1 if we are not reprocessing
-
- int m_islotRuleStartRead; // read position when the rule was started; any requests before
- // this point should access the output stream, because it has
- // the most up-to-date values.
- int m_islotRuleStartWrite; // write position when the rule started
-
- bool m_fFullyWritten; // set to true when we can't get any more from the
- // previous pass; initially false.
-
- int m_islotSegMin; // the official min of the segment; -1 if not yet set
- int m_islotSegLim; // the official lim of the segment; -1 if not yet set
- // (only set for the output of the final line-break pass
- // and those beyond)
-
- int m_cslotSkippedForResync; // number of slots skipped to resync;
- // specifically, the number of slots' worth of the
- // next-chunk-map that are invalid, not mapped
- // to any slots in the following stream
-
- int m_cslotPreSeg; // number of slots previous to the official beginning of the segment;
- // -1 if we haven't figured it out yet. Used for keeping streams
- // in the positioning pass in sync; not particularly useful for
- // substitution passes, and will possibly be left uncalculated.
-
- bool m_fUsedByPosPass; // true if this is input to or output from a positioning pass
- bool m_fInputToPosPass1; // true if this is the input to the first positioning pass
-
- // Max value of m_islotReadPos; used for recognizing infinite loops and forcibly
- // advancing (see GrPass::CheckInputProgress).
- int m_islotReadPosMax;
-
-public:
- // For transduction logging:
-#ifdef TRACING
-// void LogSlotGlyphs(std::ofstream & strmOut, gid16 chwLB);
-#endif // TRACING
-
- // For test procedures:
- int NumberOfSlots() { return m_vpslot.size(); }
- GrSlotState * LastSlotWritten()
- {
- if (m_islotWritePos == 0)
- return NULL;
- else
- return m_vpslot[m_islotWritePos-1];
- }
- GrSlotState * LastSlotRead()
- {
- if (m_islotReadPos == 0)
- return NULL;
- else
- return m_vpslot[m_islotReadPos-1];
- }
-
- gid16 GlyphIDAt(int islot)
- {
- return m_vpslot[islot]->m_chwGlyphID;
- }
-
- int PreChunk() // answer the number of prepended items that are not in any chunk;
- // should be obsolete now
- {
- int islot;
- for (islot = 0; islot < m_islotReadPos; ++islot)
- {
- if (m_vislotNextChunkMap[islot] != -1)
- return islot;
- }
- Assert(false);
- return islot;
- }
-
-}; // end of class GrSlotStream
-
-} // namespace gr
-
-
-#endif // !SLOTSTREAM_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/GrTableManager.cpp b/Build/source/libs/graphite-engine/src/segment/GrTableManager.cpp
deleted file mode 100644
index fde364e7e2e..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrTableManager.cpp
+++ /dev/null
@@ -1,2691 +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: GrTableManager.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- GrTableManager, which handles the interactions between passes, including the demand-pull
- algorithm.
--------------------------------------------------------------------------------*//*:End Ignore*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-//#ifndef _WIN32
-#include <stdlib.h>
-#include <math.h>
-//#endif
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Constructors and initializers
-----------------------------------------------------------------------------------------------*/
-EngineState::EngineState()
- : m_ipassJustCalled(-1),
- m_fStartLineContext(false),
- m_fEndLineContext(false),
- ////m_pgg(NULL),
- m_cslotPreSeg(0),
- m_islotblkCurr(-1),
- m_islotNext(kSlotBlockSize),
- m_fInitialLB(false),
- m_fFinalLB(false),
- m_fInsertedLB(false),
- m_fExceededSpace(false),
- m_fHitHardBreak(false),
- m_fRemovedWhtsp(false),
- m_dxsShrinkPossible(GrSlotState::kNotYetSet),
- m_islotPosNext(-1),
- m_xsPosXNext(0),
- m_ysPosYNext(0),
- m_dxsTotWidthSoFar(0),
- m_dxsVisWidthSoFar(0),
- m_prgzpst(NULL),
- m_prgpsstrm(NULL)
-{
- m_vslotblk.clear();
- m_vprgnSlotVarLenBufs.clear();
-}
-
-void EngineState::Initialize(GrEngine * pgreng, GrTableManager * ptman)
-{
- m_ptman = ptman;
- m_cpass = ptman->NumberOfPasses(); // duplicate for convenience
-
- m_cUserDefn = pgreng->NumUserDefn();
- m_cFeat = pgreng->NumFeat();
- m_cCompPerLig = pgreng->NumCompPerLig();
-
- if (m_prgzpst)
- delete[] m_prgzpst;
- m_prgzpst = new PassState[m_cpass];
- ptman->StorePassStates(m_prgzpst);
-}
-
-/*----------------------------------------------------------------------------------------------
- Destructors
-----------------------------------------------------------------------------------------------*/
-GrTableManager::~GrTableManager()
-{
- for (int ipass = 0; ipass < m_cpass; ++ipass)
- delete Pass(ipass);
-
- delete[] m_prgppass;
-}
-
-EngineState::~EngineState()
-{
- DestroySlotBlocks();
-
- delete[] m_prgzpst;
-
- if (m_prgpsstrm)
- {
- for (int isstrm = 0; isstrm < m_cpass; ++isstrm)
- delete OutputStream(isstrm);
-
- delete[] m_prgpsstrm;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Delete all the slots.
-----------------------------------------------------------------------------------------------*/
-void EngineState::DestroySlotBlocks()
-{
- Assert(m_vslotblk.size() == m_vprgnSlotVarLenBufs.size());
- for (size_t islotblk = 0; islotblk < m_vslotblk.size(); ++islotblk)
- {
- delete[] m_vslotblk[islotblk];
- delete[] m_vprgnSlotVarLenBufs[islotblk];
- }
- m_vslotblk.clear();
- m_vprgnSlotVarLenBufs.clear();
-}
-
-/*----------------------------------------------------------------------------------------------
- Create the passes, and them fill them in by reading from the file stream.
-----------------------------------------------------------------------------------------------*/
-bool GrTableManager::CreateAndReadPasses(GrIStream & grstrm,
- int fxdSilfVersion, int fxdRuleVersion,
- int cpassFont, long lSubTableStart, int * rgnPassOffsets,
- int ipassSub1Font, int ipassPos1Font, int ipassJust1Font, byte ipassPostBidiFont)
-{
- Assert(ipassSub1Font <= ipassJust1Font);
- Assert(ipassJust1Font <= ipassPos1Font);
- Assert(ipassPos1Font <= cpassFont);
- if (ipassSub1Font > ipassJust1Font || ipassJust1Font > ipassPos1Font
- || ipassPos1Font > cpassFont)
- {
- return false; // bad table
- }
-
- // Adjusted indices based on the fact that we have a glyph generation pass that is
- // pass 0, and possibly a bidi pass:
- m_cpass = cpassFont + 1;
- int ipassLB1, ipassSub1, ipassBidi, ipassPos1, ipassJust1;
- ipassLB1 = 1;
- ipassSub1 = ipassSub1Font + 1;
- if (ipassPostBidiFont == 0xFF)
- {
- // No bidi pass.
- m_fBidi = false;
- // Add 1 below to account for the glyph-generation pass.
- ipassPos1 = ipassPos1Font + 1;
- ipassJust1 = ipassJust1Font + 1;
- ipassBidi = ipassJust1;
- }
- else
- {
- m_fBidi = true;
- m_cpass++;
- Assert(ipassPostBidiFont == ipassJust1Font);
- ipassJust1 = ipassJust1Font + 2;
- ipassPos1 = ipassPos1Font + 2;
- ipassBidi = ipassJust1 - 1;
- }
-
- // Always make at least one positioning pass, even if there are no rules.
- if (ipassPos1 == m_cpass)
- {
- m_cpass++;
- }
-
- m_prgppass = new GrPass*[m_cpass + 1];
- m_prgppass[0] = new GrGlyphGenPass(0);
-
- int ipass = 1;
- int ipassFont = 0;
- m_cpassLB = 0;
- m_ipassJust1 = 1;
- m_ipassPos1 = 1;
- for ( ; ipass < m_cpass; ipass++, ipassFont++)
- {
- if (ipass < ipassSub1)
- {
- m_prgppass[ipass] = new GrLineBreakPass(ipass);
- m_prgppass[ipass]->ReadFromFont(grstrm, fxdSilfVersion, fxdRuleVersion,
- lSubTableStart + rgnPassOffsets[ipassFont]);
- m_cpassLB++;
- m_ipassJust1++;
- m_ipassPos1++;
- }
- else if (ipassSub1 <= ipass && ipass < ipassBidi)
- {
- m_prgppass[ipass] = new GrSubPass(ipass);
- m_prgppass[ipass]->ReadFromFont(grstrm, fxdSilfVersion, fxdRuleVersion,
- lSubTableStart + rgnPassOffsets[ipassFont]);
- m_ipassJust1++;
- m_ipassPos1++;
- }
- else if (ipassBidi == ipass && ipass < ipassJust1)
- {
- m_prgppass[ipass] = new GrBidiPass(ipass);
- m_prgppass[ipass]->SetTopDirLevel(TopDirectionLevel());
- ipassFont--; // no corresponding pass in font
- m_ipassJust1++;
- m_ipassPos1++;
- }
- else if (ipassJust1 <= ipass && ipass < ipassPos1)
- {
- // A justification pass is, in essence, a substitution pass.
- m_prgppass[ipass] = new GrSubPass(ipass);
- m_prgppass[ipass]->ReadFromFont(grstrm, fxdSilfVersion, fxdRuleVersion,
- lSubTableStart + rgnPassOffsets[ipassFont]);
- m_ipassPos1++;
- }
- else if (ipassPos1 <= ipass)
- {
- m_prgppass[ipass] = new GrPosPass(ipass);
- if (ipassFont < cpassFont)
- {
- m_prgppass[ipass]->ReadFromFont(grstrm, fxdSilfVersion, fxdRuleVersion,
- lSubTableStart + rgnPassOffsets[ipassFont]);
- }
- else
- {
- // No positioning pass in font: create a bogus one.
- m_prgppass[ipass]->InitializeWithNoRules();
- }
- }
- else
- {
- Assert(false);
- return false; // bad table
- }
- }
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Create passes corresponding to an invalid font.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::CreateEmpty()
-{
- m_cpass = 2;
-
- m_prgppass = new GrPass*[2];
- m_prgppass[0] = new GrGlyphGenPass(0);
-
- m_prgppass[1] = new GrPosPass(1);
- m_prgppass[1]->InitializeWithNoRules();
-
- m_ipassPos1 = 1;
- m_cpassLB = 0;
- m_fBidi = false;
-
- m_engst.CreateEmpty();
-}
-
-void EngineState::CreateEmpty()
-{
- m_fStartLineContext = false;
- m_fEndLineContext = false;
-}
-
-/*----------------------------------------------------------------------------------------------
- Create the slot streams corresponding to the passes.
-----------------------------------------------------------------------------------------------*/
-void EngineState::CreateSlotStreams()
-{
- if (m_prgpsstrm)
- return;
-
- m_prgpsstrm = new GrSlotStream * [m_cpass];
- for (int ipass = 0; ipass < m_cpass; ++ipass)
- {
- m_prgpsstrm[ipass] = new GrSlotStream(ipass);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Store information about the pass-states in the pass objects.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::StorePassStates(PassState * rgzpst)
-{
- for (int ipass = 0; ipass < m_cpass; ipass++)
- Pass(ipass)->SetPassState(rgzpst + ipass);
-}
-
-/*----------------------------------------------------------------------------------------------
- Demand-driven loop: with goal of filling up final slot stream, loop backward and forward
- filling up slot streams until final stream has reached physical capacity.
-
- @param pgjus - justification agent; NULL if justification is of no interest
- @param jmodi - (internal) justification mode
- @param fStartLine, fEndLine
- @param ichSegLim - known end of segment; -1 when using backtracking
- @param dxWidthRequested - available width; when justifying, exact width desired
- @param dxUnjustifiedWidth - when justifying, what the width would be normally
- @param fNeedFinalBreak - true if the end of the segment needs to be a valid break point
- @param fMoreText - true if char stream doesn't go up to text-stream lim
- @param ichFontLim - end of the range that could be rendered by this font
- @param fInfiniteWidth - used for "measured" segments
- @param fWidthIsCharCount - kludge for test procedures: the width is a character count,
- not a pixel count
- @param lbPref - try for longest segment ending with this breakweight
- - when justifying, lb to assume
- @param lbMax - max (last resort) breakweight if no preferred break possible
- @param ichwCallerBtLim - caller's backtrack lim; -1 if caller is not backtracking
- @param twsh - how to handle trailing white-space
- @param fParaRtl - overall paragraph direction
- @param nDirDepth - direction depth of this segment
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::Run(Segment * psegNew, Font * pfont,
- GrCharStream * pchstrm, IGrJustifier * pgjus, int jmodi,
- LayoutEnvironment & layout,
- int ichSegLim,
- float dxWidthRequested, float dxUnjustifiedWidth,
- bool fNeedFinalBreak, bool fMoreText, int ichFontLim,
- bool fInfiniteWidth, bool fWidthIsCharCount,
- int ichwCallerBtLim,
- int nDirDepth, SegEnd estJ)
-{
- bool fStartLine = layout.startOfLine();
- bool fEndLine = layout.endOfLine();
- LineBrk lbPref = layout.bestBreak();
- LineBrk lbMax = layout.worstBreak();
- TrWsHandling twsh = layout.trailingWs();
- bool fParaRtl = layout.rightToLeft();
- Segment * psegPrev = layout.prevSegment();
- Segment * psegInit = layout.segmentForInit();
- std::ostream * pstrmLog = layout.loggingStream();
-
- m_engst.Initialize(Engine(), this); // do this after the tables have been fully read
- m_engst.m_jmodi = jmodi;
- m_engst.m_ipassJustCalled = -1;
- m_engst.m_twsh = twsh;
- m_engst.m_fParaRtl = fParaRtl;
- m_engst.m_dxsShrinkPossible = GrSlotState::kNotYetSet;
- m_fLogging = (pstrmLog != NULL);
-
- int cbPrev;
- byte * pbPrevSegDat = NULL;
- if (psegPrev)
- cbPrev = psegPrev->NextSegInitBuffer(&pbPrevSegDat);
- else if (psegInit)
- cbPrev = psegInit->ThisSegInitBuffer(&pbPrevSegDat);
- else
- cbPrev = 0;
-
- if (pchstrm->IsEmpty())
- {
- m_engst.m_lbPrevEnd = klbNoBreak;
- InitSegmentAsEmpty(psegNew, pfont, pchstrm, fStartLine, fEndLine);
- psegNew->SetWidths(0, 0);
- psegNew->SetUpOutputArrays(pfont, this, NULL, 0, 0, 0, twsh,
- fParaRtl, nDirDepth, true);
- psegNew->SetLayout(layout);
- return;
- }
-
- int islotUnderBreak = -1; // position of inserted or final break point in underlying
- // data; none so far (if an actual LB has been inserted,
- // this is the index of that slot; otherwise it is the
- // index of the last valid slot)
- int islotSurfaceBreak = -1; // position of line break in surface stream; none so far
- LineBrk lbBestToTry = lbPref;
- LineBrk lbFound = klbNoBreak;
-
- float dxMaxWidth = dxWidthRequested;
-
- if (m_engst.m_jmodi == kjmodiJustify)
- {
- Assert(fInfiniteWidth);
- lbBestToTry = klbClipBreak;
- lbFound = lbPref;
- }
-
- float dxWidth;
-
- std::vector<int> vnslotNeeded;
- vnslotNeeded.resize(m_cpass);
-
- m_engst.InitializeStreams(this, pchstrm, cbPrev, pbPrevSegDat, fNeedFinalBreak, &islotUnderBreak);
-
- int ipassCurr;
- int nNeedInput; // kNextPass: go on to the next pass
- // kBacktrack: need to insert a line break
- // > 0: need more input from previous pass
-
- int cchwPostXlbContext = m_pgreng->PostXlbContext();
- if (ichSegLim > -1)
- {
- // When we know exactly where the end of the segment will be, get as much as
- // we need from the character stream, and then fill up the remaining streams.
- // (3 below is an arbitrary number; we just want to get slightly more than
- // we really need.)
- vnslotNeeded[0] = ichSegLim - pchstrm->Min() + cchwPostXlbContext + 3;
- for (int ipass = 1; ipass < m_cpass; ipass++)
- vnslotNeeded[ipass] = 10000;
- // Start at pass 0.
- ipassCurr = 0;
- }
- else
- {
- // When we're doing line-breaking to find the end of the segment, use the
- // demand-driven approach that tries to fill up the available space.
- vnslotNeeded[m_cpass - 1] = 1;
-
- // Start at the last pass. (It might be more efficient to start at the first pass and
- // generate a small arbitrary number of glyphs.)
- ipassCurr = m_cpass - 1;
- }
-
- while (ipassCurr < m_cpass)
- {
- if (ipassCurr == 0)
- {
- int nNeedNow = vnslotNeeded[0];
- // Zeroth pass: generate glyph IDs from the underlying input.
- nNeedInput = Pass(0)->ExtendGlyphIDOutput(this,
- pchstrm, OutputStream(0), ichSegLim, cchwPostXlbContext, lbPref,
- nNeedNow, fNeedFinalBreak, m_engst.m_twsh, &islotUnderBreak);
- Assert(nNeedInput == kNextPass || nNeedInput == kBacktrack);
- vnslotNeeded[0] -= nNeedNow;
- }
- else if (ipassCurr < m_cpass - 1)
- {
- // Middle pass.
- int cslotNeedNow = vnslotNeeded[ipassCurr];
- cslotNeedNow = max(1, cslotNeedNow);
- int cslotGot;
- Pass(ipassCurr)->ExtendOutput(this,
- InputStream(ipassCurr), OutputStream(ipassCurr), cslotNeedNow, twsh,
- &nNeedInput, &cslotGot, &islotUnderBreak);
- vnslotNeeded[ipassCurr] -= cslotGot;
- //if (nNeedInput != kNextPass && nNeedInput != kBacktrack)
- // nNeedInput = max(nNeedInput, cslotNeedNow - cslotGot);
- }
- else // (ipassCurr == m_cpass - 1)
- {
- // Final pass: position and test allotted space.
- float dxWidthWShrink = dxMaxWidth;
- if (m_engst.m_dxsShrinkPossible != GrSlotState::kNotYetSet)
- dxWidthWShrink += (int)m_engst.m_dxsShrinkPossible;
- nNeedInput = Pass(ipassCurr)->ExtendFinalOutput(this,
- InputStream(ipassCurr), OutputStream(ipassCurr),
- dxWidthWShrink, fWidthIsCharCount, fInfiniteWidth,
- (islotUnderBreak > -1), (fNeedFinalBreak && lbFound == klbNoBreak),
- lbMax, twsh,
- &islotSurfaceBreak, &dxWidth);
- }
-
- if (m_engst.m_jmodi == kjmodiJustify)
- {
- if (ipassCurr < m_ipassJust1 && !OutputStream(ipassCurr)->FullyWritten())
- {
- // When justifying, fill up all the streams up to the point where we need
- // to interact with the justification routine.
- // I think this code is obsolete.
- int nStillNeed = 1000;
- if ((ipassCurr == 1 && nNeedInput != kNextPass) || ipassCurr == 0)
- nStillNeed = ichSegLim - (pchstrm->Pos() - pchstrm->Min())
- + cchwPostXlbContext + 3;
- if (nStillNeed > 0)
- {
- if (nNeedInput == kNextPass)
- ipassCurr++; // repeat this pass
- nNeedInput = nStillNeed;
- }
- }
- else if (nNeedInput == kNextPass && ipassCurr + 1 == m_ipassJust1)
- {
- CallJustifier(pgjus, ipassCurr, dxUnjustifiedWidth, dxWidthRequested, fEndLine);
- }
- }
- DetermineShrink(pgjus, ipassCurr);
-
- if (nNeedInput == kBacktrack)
- {
- // Final output has overflowed its space--find (or adjust) the break point.
-
- bool fFoundBreak = Backtrack(&islotUnderBreak,
- &lbBestToTry, lbMax, twsh, fMoreText, ichwCallerBtLim, &lbFound);
- if (!fFoundBreak)
- {
- // Nothing will fit. Initialize the new segment just enough so that
- // we can delete it.
- InitSegmentToDelete(psegNew, pfont, pchstrm);
- return;
- }
- }
- else if (nNeedInput == kNextPass)
- {
- // This pass is sufficiently full--return to following pass.
- ipassCurr++;
- }
- else
- {
- // Get more input from previous pass.
- ipassCurr--;
- vnslotNeeded[ipassCurr] = nNeedInput;
- }
- }
-
- // At this point we have fully transduced all the text for this segment.
-
- // Figure out why we broke the segment and what the caller is supposed to do about it.
- SegEnd est;
- if (m_engst.m_jmodi == kjmodiJustify)
- {
- // Don't change what was passed in.
- est = estJ;
- }
- else if (m_engst.m_fRemovedWhtsp) // (islotUnderBreak > -1 && twsh == ktwshNoWs)
- {
- Assert(!m_engst.m_fInsertedLB);
- est = kestMoreWhtsp;
- }
-
- else if (m_engst.m_fHitHardBreak)
- {
- est = kestHardBreak;
- }
-
- else if (!m_engst.m_fExceededSpace && !fMoreText)
- // Rendered to the end of the original requested range.
- est = kestNoMore;
-
-// else if (!m_fExceededSpace && !fNextIsSameWs && fMoreText)
-// // Writing system break; may be more room on the line. But see tweak below.
-// *pest = kestWsBreak;
-
- else if (m_engst.m_fExceededSpace)
- {
- // Exceeded available space, found a legal break.
- if (twsh == ktwshNoWs && m_engst.m_fRemovedWhtsp)
- est = kestMoreWhtsp;
- else
- est = kestMoreLines;
- }
-
- else if (twsh == ktwshOnlyWs)
- {
- est = kestOkayBreak; // but see tweak below
- }
-
- else
- {
- // Broke because of something like a font change. Determine whether this is a legal
- // break or not.
- // TODO SharonC: handle the situation where it is legal to break BEFORE the first
- // character of the following segment.
- Assert(fMoreText);
- //Assert(fNextIsSameWs);
- if (ichwCallerBtLim > -1)
- {
- Assert(m_engst.m_fInsertedLB);
- }
- else if (ichSegLim > -1)
- {
- // We stopped where caller said to.
- Assert(fInfiniteWidth);
- }
- else
- {
- Assert(!m_engst.m_fInsertedLB);
- Assert(islotUnderBreak == -1 || m_engst.m_fFinalLB);
- }
- int islotTmp = OutputStream(m_cpass - 1)->WritePos();
- GrSlotState * pslotTmp;
- if (m_engst.m_fFinalLB || m_engst.m_fInsertedLB)
- pslotTmp = OutputStream(m_cpass-1)->SlotAt(islotTmp - 2);
- else
- pslotTmp = OutputStream(m_cpass-1)->SlotAt(islotTmp - 1);
-
- if (abs(pslotTmp->BreakWeight()) <= lbPref)
- est = kestOkayBreak;
-
- else if (abs(pslotTmp->BreakWeight()) > lbMax)
- est = kestBadBreak;
-
- else if (OutputStream(m_cpassLB)->HasEarlierBetterBreak(islotUnderBreak, lbFound,
- this->LBGlyphID()))
- {
- est = kestBadBreak;
- }
- else
- est = kestOkayBreak;
-
- // We no longer have the ability to know whether or not the next segment will use
- // the same writing system.
- //if (est == kestBadBreak && m_engst.m_fExceededSpace && !fNextIsSameWs && fMoreText)
- // est = kestWsBreak;
- }
-
- // Make a segment out of it and return it.
- int dichSegLen;
- InitNewSegment(psegNew, pfont, pchstrm, pgjus,
- islotUnderBreak, islotSurfaceBreak, fStartLine, fEndLine, ichFontLim, lbFound, est,
- &dichSegLen);
- if (psegNew->segmentTermination() == kestNothingFit)
- {
- return;
- }
- else if (psegNew->segmentTermination() == kestHardBreak &&
- psegNew->startCharacter() == psegNew->stopCharacter())
- {
- // Empty segment caused by a hard-break.
- m_engst.m_lbPrevEnd = klbNoBreak;
- psegNew->SetWidths(0, 0);
- psegNew->SetUpOutputArrays(pfont, this, NULL, 0, 0, 0, twsh,
- fParaRtl, nDirDepth, true);
- psegNew->SetLayout(layout);
- return;
- }
-
- psegNew->RecordInitializationForThisSeg(cbPrev, pbPrevSegDat);
-
- if ((est == kestNoMore || est == kestWsBreak) && twsh == ktwshOnlyWs &&
- dichSegLen < pchstrm->Lim() - pchstrm->Min())
- {
- // If we are asking for white-space only, and we didn't use up everything in the font
- // range, we could possibly have gotten an initial white-space only segment
- // (as opposed to a writing system break).
- est = kestOkayBreak;
- psegNew->FixTermination(est);
- }
-
- SetFinalPositions(psegNew, fWidthIsCharCount);
-
- // Do this before fixing up the associations below, so we can see the raw ones produced by the
- // rules themselves.
- //if (m_pgreng->LoggingTransduction())
- // WriteTransductionLog(pchstrm, *ppsegRet,
- // cbPrev, pbPrevSegDat, pbNextSegDat, pcbNextSegDat);
- WriteTransductionLog(pstrmLog, pchstrm, psegNew, cbPrev, pbPrevSegDat);
-
- RecordAssocsAndOutput(pfont, psegNew, twsh, fParaRtl, nDirDepth);
-
- // Do this after fixing up the associations.
- //if (m_pgreng->LoggingTransduction())
- // WriteAssociationLog(pchstrm, *ppsegRet);
- WriteAssociationLog(pstrmLog, pchstrm, psegNew);
-
- psegNew->SetLayout(layout);
-}
-
-/*----------------------------------------------------------------------------------------------
- Create a new segment to return.
-
- @param pchstrm - input stream
- @param pgjus - justification agent, in case this segment needs to be
- stretched or shrunk
- @param islotLBStreamBreak - position of inserted line break slot (which should be equal
- to the position in the glyph generation stream);
- -1 if no line-break was inserted (we rendered to the
- end of the range)
- @param islotSurfaceBreak - position of line break slot in final (surface) stream
- @param fStartLine - does this segment start a line?
- @param fEndLine - does this segment end a line?
- @param ichFontLim - end of range that could be rendered by this font
- @param lbEndFound - line break found; possibly adjusted here
- @param est - why did the segment terminate
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::InitNewSegment(Segment * psegNew,
- Font * pfont, GrCharStream * pchstrm, IGrJustifier * pgjus,
- int islotLBStreamBreak, int islotSurfaceBreak, bool fStartLine, bool fEndLine, int ichFontLim,
- LineBrk lbEndFound, SegEnd est, int * pdichSegLen)
-{
- LineBrk lbStart = m_engst.m_lbPrevEnd;
- LineBrk lbEnd = lbEndFound;
- if (est == kestBadBreak)
- lbEnd = klbLetterBreak;
-
- int ichwMin = pchstrm->Min();
- int ichwLim;
-
-// int cslotPreSegStream0 = m_cslotPreSeg;
-// if (m_fInitialLB && m_cpassLB > 0)
-// {
-// // Initial LB is included in m_cslotPreSeg, but is not in stream 0.
-// // --Not really needed, because both islotLBStreamBreak and m_cslotPreSeg take
-// // the initial LB into account if it is there.
-// cslotPreSegStream0--;
-// }
-
- // No longer have to subtract this, because the chunk map takes it into
- // consideration.
- //int cslotPreInitialLB = m_cslotPreSeg - (m_fInitialLB ? 1 : 0);
-
- //int ichwOldTmp;
-
- if (m_engst.m_fInsertedLB)
- {
- Assert(islotLBStreamBreak > -1);
- int ichwSegLim = m_engst.LbSlotToSegLim(islotLBStreamBreak, pchstrm, m_cpassLB);
- ichwLim = ichwSegLim + pchstrm->Min(); // - cslotPreInitialLB;
-
- // Old result, for debugging:
- //ichwOldTmp = islotLBStreamBreak + pchstrm->Min() - m_cslotPreSeg;
- }
- else if (m_engst.m_fFinalLB || islotLBStreamBreak == -1)
- ichwLim = pchstrm->Lim();
- else
- {
- int ichwSegLim = m_engst.LbSlotToSegLim(islotLBStreamBreak, pchstrm, m_cpassLB);
- ichwLim = ichwSegLim + pchstrm->Min(); // - cslotPreInitialLB;
-
- // Old result, for debugging:
- // islotLBStreamBreak is the last slot in the segment, not the LB glyph; hence +1.
- //ichwOldTmp = islotLBStreamBreak + pchstrm->Min() - m_cslotPreSeg + 1;
- }
-
- *pdichSegLen = ichwLim - ichwMin;
-
- if (ichwMin >= ichwLim)
- {
- if (est == kestHardBreak)
- {
- // Empty segment cause by a hard-break.
- InitSegmentAsEmpty(psegNew, pfont, pchstrm, fStartLine, fEndLine);
- psegNew->FixTermination(est);
- }
- else
- {
- // Invalid empty segment.
- Assert(ichwMin == ichwLim);
- InitSegmentToDelete(psegNew, pfont, pchstrm);
- }
- return;
- }
-
- Assert(psegNew);
-
- psegNew->Initialize(pchstrm->TextSrc(),
- ichwMin, ichwLim,
- lbStart, lbEnd, est, fStartLine, fEndLine, m_pgreng->RightToLeft());
-
- psegNew->SetEngine(m_pgreng);
- psegNew->SetFont(pfont);
- psegNew->SetJustifier(pgjus);
- psegNew->SetFaceName(m_pgreng->FaceName(), m_pgreng->BaseFaceName());
-
- bool fNextSegNeedsContext =
- !(est == kestNoMore || est == kestWsBreak
- || ichwLim >= pchstrm->Lim() || ichwLim >= ichFontLim);
-
- InitializeForNextSeg(psegNew, islotLBStreamBreak, islotSurfaceBreak, lbEnd,
- fNextSegNeedsContext, pchstrm);
-
- psegNew->SetPreContext(0 - m_pgreng->PreXlbContext());
-}
-
-/*----------------------------------------------------------------------------------------------
- The newly created segment is invalid, for instance, because we were backtracking and
- couldn't find a valid break point. Initialize it just enough so that it can be
- deleted by the client.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::InitSegmentToDelete(Segment * psegNew, Font * pfont,
- GrCharStream * pchstrm)
-{
- psegNew->Initialize(pchstrm->TextSrc(), 0, 0,
- klbClipBreak, klbClipBreak, kestNothingFit, false, false,
- m_pgreng->RightToLeft());
-
- psegNew->SetEngine(m_pgreng);
- psegNew->SetFont(pfont);
- psegNew->SetJustifier(NULL); // can't justify an empty segment
- psegNew->SetFaceName(m_pgreng->FaceName(), m_pgreng->BaseFaceName());
- psegNew->SetPreContext(0);
-}
-
-/*----------------------------------------------------------------------------------------------
- Map from the given slot (which is generally the final LB slot) to the end of the segment,
- taking into account the fact that a single slot may represent two 16-bit surrogates.
-
- There are several approaches that seem reasonable but do NOT work. (I tried them!)
- You can't calculate it directly from the length of the streams, because that doesn't take
- into account the possible presence of surrogate pairs in the character stream. You can't
- use the chunk map at the point of the LB, because if a rule spanned a LB the chunk won't
- have ended there and so there won't be any valid information.
-
- What seems to work is to figure out the slot(s) in the zeroth stream using the associations
- and then use the segment offset for this slot. This should be reliable because there is
- always a one-to-one correspondence between glyphs in the line-break passes (ie, no
- insertions or deletions), so the associations should be dependable and straightforward.
-----------------------------------------------------------------------------------------------*/
-int EngineState::LbSlotToSegLim(int islotLB, GrCharStream * pchstrm, int cpassLB)
-{
- Assert(islotLB < OutputStream(cpassLB)->WritePos());
-
- // Figure out the corresponding characters in the zeroth stream. These should be straight-
- // forward to figure out because no substitutions are permitted in the LB passes.
- // I do the slots before and after the LB, if possible, as a sanity check.
- GrSlotStream * psstrmLB = OutputStream(cpassLB);
- GrSlotState * pslotPreLB = (m_fFinalLB || m_fInsertedLB) ?
- psstrmLB->SlotAt(islotLB - 1) :
- psstrmLB->SlotAt(islotLB);
- GrSlotState * pslotPostLB = (psstrmLB->WritePos() > islotLB + 1) ?
- psstrmLB->SlotAt(islotLB + 1) :
- NULL;
-
- int ichwPreLB = pslotPreLB->AfterAssoc();
-
- int ichwSegLim;
- if (pslotPostLB)
- {
- ichwSegLim = pslotPostLB->BeforeAssoc();
- Assert(ichwPreLB + 1 == ichwSegLim
- || ichwPreLB + 2 == ichwSegLim); // in case of a surrogate
- }
- else
- {
- ichwSegLim = ichwPreLB + 1;
- while (!pchstrm->AtUnicodeCharBoundary(ichwSegLim))
- ichwSegLim++;
- Assert(pchstrm->AtUnicodeCharBoundary(ichwSegLim));
- }
-
- // Old buggy routine that doesn't handle the case where a rule (and hence the chunk map) did
- // not end at the LB character:
- // Map backwards through the LB pass streams, if any.
- //int islotAdjusted = islotLB + 1; // after the LB
- //for (int ipass = m_cpassLB; ipass > 0; ipass--)
- //{
- // islotAdjusted = ChunkInPrev(ipass, islotAdjusted, pchstrm);
- //}
- //
- //int ichwSegLim = ChunkInPrev(0, islotAdjusted, pchstrm);
-
- // Mapping from 32-bit to 16-bit should only increase the index. Except that there
- // may be a LB in the slot stream that is not in the character stream, so it could be
- // one less.
- Assert(ichwSegLim + m_cslotPreSeg >= islotLB - 1);
-
- return ichwSegLim;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the chunk mapping into the previous stream, taking into account the fact that it
- is not recorded for the write-position.
-----------------------------------------------------------------------------------------------*/
-int GrTableManager::ChunkInPrev(int ipass, int islot, GrCharStream * pchstrm)
-{
- GrSlotStream * psstrmOut = OutputStream(ipass);
- GrSlotStream * psstrmIn = (ipass == 0) ? NULL : InputStream(ipass);
-
- int islotTmp = islot;
- int islotAdjusted;
- do {
- if (islot >= psstrmOut->WritePos())
- {
- Assert(islot == psstrmOut->WritePos());
- islotAdjusted = (ipass == 0) ? pchstrm->SegOffset() : psstrmIn->ReadPos();
- Assert(islotAdjusted > -1);
- }
- else
- islotAdjusted = psstrmOut->ChunkInPrev(islotTmp);
- islotTmp--;
- } while (islotAdjusted == -1);
-
- return islotAdjusted;
-}
-
-/*----------------------------------------------------------------------------------------------
- Create a new segment corresponding to an empty string.
-
- @param pchstrm - input stream
- @param fStartLine - does this segment start a line?
- @param fEndLine - does this segment end a line?
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::InitSegmentAsEmpty(Segment * psegNew, Font * pfont,
- GrCharStream * pchstrm, bool fStartLine, bool fEndLine)
-{
- LineBrk lbStart = m_engst.m_lbPrevEnd;
- LineBrk lbEnd = klbNoBreak;
-
- int ichwMin = 0;
- int ichwLim = 0;
-
- Assert(psegNew);
-
- psegNew->Initialize(pchstrm->TextSrc(), ichwMin, ichwLim,
- lbStart, lbEnd, kestNoMore, fStartLine, fEndLine, m_pgreng->RightToLeft());
-
- psegNew->SetEngine(m_pgreng);
- psegNew->SetFont(pfont);
- psegNew->SetJustifier(NULL); // can't justify an empty segment
- psegNew->SetFaceName(m_pgreng->FaceName(), m_pgreng->BaseFaceName());
-
- byte pbNextSegDat[256];
- int cbNextSegDat;
- int * pcbNextSegDat = &cbNextSegDat;
-
- // Initialization for (theoretical) next segment.
- byte * pb = pbNextSegDat;
- *pb++ = byte(lbEnd);
- *pb++ = kdircNeutral;
- *pb++ = kdircNeutral;
- *pb++ = 0;
- for (int ipass = 0; ipass < m_cpass; ipass++)
- *pb++ = 0;
- *pcbNextSegDat = 0;
- psegNew->RecordInitializationForNextSeg(*pcbNextSegDat, pbNextSegDat);
-
- psegNew->SetPreContext(0);
-}
-
-/*----------------------------------------------------------------------------------------------
- Find a line-break and unwind the passes. Return true if we were able to
- backtrack successfully (which may have meant using a less-than-optimal line-break).
- Return false if no line-break could be found (because maxBreakWeight did not allow
- letter breaks or clipping--generally because there was already something on this
- line).
-
- @param pislotPrevBreak - position of previously-created break, -1 if none;
- this is the index of the line-break glyph if any,
- or the index of the last slot in the segment;
- adjusted to contain the position of the newly
- found break
- @param plbMin - minimum (best) line break weight to try
- @param lbMax - maximum (worst possible) line break weight
- @param twsh - how to handle trailing white-space
- @param fMoreText - true if char stream doesn't go up to original lim
- @param ichwCallerBtLim - caller's backtrack lim; -1 if caller is not backtracking
- @param plbFound - kind of line-break created
-----------------------------------------------------------------------------------------------*/
-bool GrTableManager::Backtrack(int * pislotPrevBreak,
- LineBrk * plbMin, LineBrk lbMax, TrWsHandling twsh, bool fMoreText,
- int ichwCallerBtLim,
- LineBrk * plbFound)
-{
- int islotStartTry;
- //if (*pislotPrevBreak == ichwCallerBtLim - 1)
- //{
- // islotStartTry = *pislotPrevBreak;
- //}
- //else
- if (*pislotPrevBreak == -1)
- {
- // If no line break has been found so far, figure out where to start trying based
- // on where the final stream choked.
- GrSlotStream * psstrmFinal = OutputStream(m_cpass-1);
- if ((islotStartTry
- = m_engst.TraceStreamZeroPos(psstrmFinal->WritePos()-1, TopDirectionLevel()))
- == -1)
- {
- // Just start looking at the end of what's been generated.
- islotStartTry = OutputStream(m_cpassLB)->ReadPos() - 1;
- }
- }
- else
- {
- // Start just before previous line break.
- if (m_engst.m_fInsertedLB || m_engst.m_fFinalLB)
- islotStartTry = *pislotPrevBreak - 2; // skip inserted LB and previous slot
- else
- islotStartTry = *pislotPrevBreak - 1; // skip previous slot
- }
- if (ichwCallerBtLim > -1 && islotStartTry > ichwCallerBtLim - 1)
- {
- islotStartTry = ichwCallerBtLim - 1;
- }
-
- // Determine if we want to insert an actual line-break "glyph". Don't do that if
- // we are omitting trailing white space or we are at a writing-system or font break.
- bool fInsertLB;
- if (twsh == ktwshNoWs)
- // omitting trailing white-space
- fInsertLB = false;
- else if (twsh == ktwshOnlyWs)
- // trailing white-space segment
- fInsertLB = true;
- else if (ichwCallerBtLim > -1)
- // backtracking
- fInsertLB = true;
- else if (*pislotPrevBreak > -1)
- // no longer at the edge of the writing system or font
- fInsertLB = true;
- else if (!fMoreText)
- // at final edge of total range to render
- fInsertLB = true;
- else
- fInsertLB = false;
-
- // Try to insert a line-break in the output of the (final) line-break pass (if any, or
- // the output of the glyph-generation pass). First try the preferred (strictest)
- // break weight and gradually relax.
- LineBrk lb = *plbMin;
- Assert(*plbMin <= lbMax);
- GrSlotStream * psstrmLB = OutputStream(m_cpassLB);
- islotStartTry = min(islotStartTry, psstrmLB->WritePos() - 1);
- int islotNewBreak = -1;
- while (lb <= lbMax)
- {
- LineBrk lbNextToTry;
- if (fInsertLB)
- {
- islotNewBreak = psstrmLB->InsertLineBreak(this,
- *pislotPrevBreak, m_engst.m_fInsertedLB, islotStartTry,
- lb, twsh, m_engst.m_cslotPreSeg, &lbNextToTry);
- }
- else
- {
- islotNewBreak = psstrmLB->MakeSegmentBreak(this,
- *pislotPrevBreak, m_engst.m_fInsertedLB, islotStartTry,
- lb, twsh, m_engst.m_cslotPreSeg, &lbNextToTry);
- }
- if (islotNewBreak > -1)
- break;
- if (lb >= lbMax)
- break;
- lb = IncLineBreak(lb); // relax the break weight
- }
-
- if (islotNewBreak == -1)
- {
- return false;
- }
-
- // We've successfully inserted a line break.
-
- if (fInsertLB)
- m_engst.m_fInsertedLB = true;
-
- m_engst.m_fFinalLB = false;
-
- UnwindAndReinit(islotNewBreak);
-
- *pislotPrevBreak = islotNewBreak;
- *plbMin = lb; // return the best break we were able to find, so we don't keep trying
- // for a better one when we know now that we can't find it
- *plbFound = lb;
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- This method is called after backtracking or removing trailing white-space.
- Unwind the following slot streams as necessary depending on where the change was made.
-
- @param islotNewBreak - in output of (final) line-break pass
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::UnwindAndReinit(int islotNewBreak)
-{
- OutputStream(m_cpassLB)->ZapCalculatedDirLevels(islotNewBreak);
-
- // Mark the passes before the line-break pass as fully written, so that if there
- // isn't a line-break glyph to intercept, we don't keep trying to get more input
- // from them.
- int ipass;
- for (ipass = 1; ipass < m_cpassLB + 1; ++ipass)
- {
- InputStream(ipass)->MarkFullyWritten();
- }
-
- // Unwind the passes to the changed positions.
- // Note that we don't need to unwind pass 0, since all it does is generate glyph IDs.
- // Also we don't need to unwind the line-break passes, because conceptually they happen
- // before the break is inserted.
-
- int islotChgPos = islotNewBreak;
- bool fFirst = true;
- for (ipass = m_cpassLB + 1 ; ipass < m_cpass ; ++ipass)
- {
- islotChgPos =
- Pass(ipass)->Unwind(this, islotChgPos, InputStream(ipass), OutputStream(ipass),
- fFirst);
- fFirst = false;
- }
- // For anything that may have been skipped in the final output:
- OutputStream(m_cpass - 1)->SetReadPos(0);
- OutputStream(m_cpass - 1)->SetReadPosMax(0);
- Pass(m_cpass - 1)->UndoResyncSkip();
- OutputStream(m_cpass - 1)->ClearSlotsSkippedToResync();
-
- m_engst.InitPosCache();
-
- m_engst.m_dxsShrinkPossible = GrSlotState::kNotYetSet; // recalculate it
-}
-
-/*----------------------------------------------------------------------------------------------
- Store information in the newly created segment that will allow us to reinitalize
- the streams in order to process the next segment, appropriately handling any
- cross-line-boundary contextuals.
-
- The information required is the number of glyphs in the first stream that must
- be reprocessed, and a skip-offset between each stream indicating the beginning
- of chunk boundaries.
-
- In most cases, where there are no cross-line-boundary contextuals, all these numbers
- will be zero.
-
- The buffer generated is of the following format (all are 1 byte, unsigned):
- end breakweight
- previous strong directionality code
- previous terminator dir code
- restart backup
- skip offsets for each pass
- This format must match what is generated by InitializeStreams.
-
- @param pseg - newly created segment
- @param islotUnderBreak - position of line break inserted in underlying stream (output
- of glyph-generation pass--stream 0); -1 if we rendered to
- the end of the range
- @param islotSurfaceBreak - position of line break in surface stream;
- -1 if we rendered to the end of the range
- @param lbEnd - kind of line-break at the end of this segment
- @param fNextSegNeedsContext - true if we need to remember the context for the next seg
- @param pchstrm - character stream input for this segment
- @param cbNextMax - amount of space available in the buffer
- @param pbNextSegDat - buffer for initializing next segment
- @param pcbNextSegDat - amount of space used in buffer
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::InitializeForNextSeg(Segment * pseg,
- int islotUnderBreak, int islotSurfaceBreak, LineBrk lbEnd,
- bool fNextSegNeedsContext, GrCharStream * pchstrm)
-{
- byte pbNextSegDat[256];
- int cbNextSegDat;
- int * pcbNextSegDat = &cbNextSegDat;
-
- std::vector<int> vcslotSkipOffsets;
- vcslotSkipOffsets.resize(m_cpass);
-
- byte * pb = pbNextSegDat;
-
- if (!fNextSegNeedsContext)
- {
- // No contextualization between this segment and the next, whatever kind of renderer
- // it might use.
- *pcbNextSegDat = 0;
- return;
- }
-
- gid16 chwLB = LBGlyphID();
-
- int islotUnderLim = islotUnderBreak;
- if (!m_engst.m_fInsertedLB && !m_engst.m_fFinalLB)
- // Then islotUnderBreak is the position of the last slot in the segment; increment
- // to get the lim in stream zero.
- islotUnderLim++;
-
- int islotSurfaceLim = islotSurfaceBreak;
- if (islotSurfaceLim == -1)
- islotSurfaceLim = OutputStream(m_cpass - 1)->FinalSegLim();
-
- *pb++ = byte(lbEnd);
-
- // Find previous strong and terminator directionality codes.
-
- GrSlotStream * psstrm = OutputStream(m_cpass - 1);
- DirCode dircStrong = kdircNeutral;
- DirCode dircTerm = kdircNeutral;
- int islot;
- for (islot = islotSurfaceLim; islot-- > 0; )
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- DirCode dirc = pslot->Directionality();
- if (dircTerm == kdircNeutral && dirc == kdircEuroTerm)
- dircTerm = dirc;
- if (StrongDir(dirc))
- {
- dircStrong = dirc;
- break;
- }
- }
- *pb++ = byte(dircStrong);
- *pb++ = byte(dircTerm);
-
- // Record how much of each pass to redo in the next segment.
- // The basic algorithm is described in the "WR Data Transform Engine" document.
- // But here we are doing a variation on what is described there. We are calculating
- // the backup locations for BOTH the rule start locations and the necessary pre-contexts.
- // It is the precontext values that are recorded for use by the following segment. But we
- // also calculate the positions for the rule-start locations to make sure there is enough
- // pre-context at each pass.
-
- int islotRS = islotSurfaceLim; // rule-start positions
- int islotPC = islotRS; // to handle pre-context positions
-
- // If line-breaks are irrelevant to this font, we don't need to bother.
- bool fGiveUp = !m_pgreng->LineBreakFlag();
-
- int ipass;
- for (ipass = m_cpass - 1; ipass >= 0 && !fGiveUp; --ipass)
- {
- GrSlotStream * psstrmIn = (ipass == 0) ? NULL : InputStream(ipass);
- GrSlotStream * psstrmOut = OutputStream(ipass);
- int islotBackupMin = (ipass == 0) ? 0 : psstrmOut->SegMin();
- if (ipass >= m_cpassLB && m_engst.m_fInitialLB)
- islotBackupMin++; // how far we can back up--not before the start of this segment
-
- int islotPrevRS = 0; // corresponding slot in the previous stream for rule-start position
- int islotPrevPC = 0; // same for pre-context position
-
- // Initially we have to include at least this many prior slots:
- int cslotSkipOffset = 0;
-
- if (islotRS == psstrmOut->WritePos())
- {
- islotPrevRS = (ipass == 0) ? pchstrm->Pos() : psstrmIn->ReadPos();
- }
- else
- {
- // Ignore the final line-break, because it is explicitly inserted during
- // the (final) line-break pass.
-// if (ipass == m_cpassLB && psstrm->SlotAt(islotRS)->IsFinalLineBreak(chwLB))
-// {
-// Assert(islotRS > 0);
-// islotRS--;
-// }
- // Ignore the chunk in the pass that generated the line break that corresponds
- // to the inserted line break being chunked with the previous glyph--we don't
- // want to treat that as a cross-line-boundary contextual!
- if (ipass == m_cpassLB && psstrmOut->SlotAt(islotRS)->IsFinalLineBreak(chwLB))
- {
-// Assert(psstrm->ChunkInPrev(islotRS) == -1);
- if (islotRS + 1 == psstrmOut->WritePos())
- islotPrevRS = (ipass == 0) ? pchstrm->SegOffset() : psstrmIn->ReadPos();
- else
- islotPrevRS = psstrmOut->ChunkInPrev(islotRS + 1);
- }
- else
- {
- // Back up to the beginning of a chunk.
- while (islotRS >= islotBackupMin &&
- (islotPrevRS = psstrmOut->ChunkInPrev(islotRS)) == -1)
- {
- --islotRS;
- //++cslotSkipOffset;
- }
- }
- }
- if (islotPrevRS == -1 || islotRS < islotBackupMin) // hit the start of the segment
- {
- // In order to get enough context to be sure to run the same rules again,
- // we'd have to back up into the previous segment. Too complicated, so give up.
- fGiveUp = true;
- break;
- }
-
- int cslotPreContext = Pass(ipass)->MaxRulePreContext();
-LBackupPC:
- if (islotPC == psstrmOut->WritePos())
- {
- islotPrevPC = (ipass == 0) ? pchstrm->Pos() : psstrmIn->ReadPos();
- }
- else
- {
- if (ipass == m_cpassLB && psstrmOut->SlotAt(islotPC)->IsFinalLineBreak(chwLB))
- {
- if (islotPC+1 == psstrmOut->WritePos())
- islotPrevPC = (ipass == 0) ? pchstrm->SegOffset() : psstrmIn->ReadPos();
- else
- islotPrevPC = psstrmOut->ChunkInPrev(islotPC+1);
- }
- else
- {
- // Back up to the beginning of a chunk; also make sure there are enough slots
- // to handle the required pre-context for this pass.
- while (islotPC >= islotBackupMin &&
- ((islotPrevPC = psstrmOut->ChunkInPrev(islotPC)) == -1 ||
- islotPrevRS - islotPrevPC < cslotPreContext))
- {
- --islotPC;
- ++cslotSkipOffset;
- }
- }
- }
- if (islotPC >= islotBackupMin && islotPrevRS - islotPrevPC < cslotPreContext)
- {
- --islotPC;
- ++cslotSkipOffset;
- goto LBackupPC;
- }
- if (islotPrevPC == -1 || islotPC < islotBackupMin) // hit the start of the segment
- {
- fGiveUp = true;
- break;
- }
-
- vcslotSkipOffsets[ipass] = cslotSkipOffset;
-
- islotRS = islotPrevRS;
- islotPC = islotPrevPC;
-
- if (ipass == 0)
- {
- // Convert from underlying chars to stream-zero slots.
- islotRS += m_engst.m_cslotPreSeg;
- islotPC += m_engst.m_cslotPreSeg;
- }
- }
-
- // The following should be the case unless they tried to position contextually across
- // the line break boundary, which is a very strange thing to do! - no longer true,
- // because the pre-context is now included in this count, and it normal to have
- // a pre-context in the final positioning pass.
- //Assert(vcslotSkipOffsets[m_cpass-1] == 0);
-
- // Also no adjustments are made by the glyph-generation pass, so this should always
- // be true:
- Assert(vcslotSkipOffsets[0] == 0);
-
- // The number of slots in the underlying input previous to the line-break
- // that must be reprocessed:
- int cslotPreLB = islotUnderLim - islotPC;
-
- if (fGiveUp)
- {
- // We can't reasonably provide enough context, so don't try to do it at all.
- cslotPreLB = 0;
- for (ipass = 0; ipass < m_cpass; ipass++)
- vcslotSkipOffsets[ipass] = 0;
- }
-
- Assert(cslotPreLB >= 0);
- Assert(cslotPreLB < 0xFF);
-
- *pb++ = byte(cslotPreLB);
- for (ipass = 0; ipass < m_cpass; ipass++)
- *pb++ = byte(vcslotSkipOffsets[ipass]);
-
- *pcbNextSegDat = 4 + m_cpass;
-
- pseg->RecordInitializationForNextSeg(*pcbNextSegDat, pbNextSegDat);
-}
-/*----------------------------------------------------------------------------------------------
- Make sure the final positions are set for every glyph.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::SetFinalPositions(Segment * pseg, bool fWidthIsCharCount)
-{
- float xsTotalWidth, xsVisWidth;
-
-#ifdef OLD_TEST_STUFF
- if (fWidthIsCharCount)
- xsTotalWidth = xsVisWidth = 0;
- else
-#endif // OLD_TEST_STUFF
-
- // Make sure the final positions are set for every glyph.
- CalcPositionsUpTo(m_cpass-1, reinterpret_cast<GrSlotState *>(NULL),
- &xsTotalWidth, &xsVisWidth);
- pseg->SetWidths(xsVisWidth, xsTotalWidth);
-}
-
-/*----------------------------------------------------------------------------------------------
- Calculate the associations, and record the output slots in the segment.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::RecordAssocsAndOutput(Font * pfont, Segment * pseg,
- TrWsHandling twsh, bool fParaRtl, int nDirDepth)
-{
- int cchwUnderlying = pseg->stopCharacter() - pseg->startCharacter();
- GrSlotStream * psstrmFinal = OutputStream(m_cpass-1);
- int csloutSurface = psstrmFinal->WritePos() - psstrmFinal->IndexOffset(); // # of output slots
-
- psstrmFinal->SetNeutralAssociations(LBGlyphID());
-
- pseg->SetUpOutputArrays(pfont, this, psstrmFinal, cchwUnderlying, csloutSurface, LBGlyphID(),
- twsh, fParaRtl, nDirDepth);
-
- // Set underlying-to-surface assocations in the segment.
- CalculateAssociations(pseg, csloutSurface);
-}
-
-/*----------------------------------------------------------------------------------------------
- Calculate the underlying-to-surface associations and ligature mappings.
- Assumes the arrays have been properly initialized.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::CalculateAssociations(Segment * pseg, int csloutSurface)
-{
- GrSlotStream * psstrmFinal = OutputStream(m_cpass-1);
-
- std::vector<int> vichwAssocs;
- std::vector<int> vichwComponents;
-
- for (int islot = psstrmFinal->IndexOffset(); islot < psstrmFinal->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrmFinal->SlotAt(islot);
- int islout = islot - psstrmFinal->IndexOffset();
- if (!pslot->IsLineBreak(LBGlyphID()))
- {
- vichwAssocs.clear();
- pslot->AllAssocs(vichwAssocs);
-
- size_t iichw;
- for (iichw = 0; iichw < vichwAssocs.size(); ++iichw)
- {
- pseg->RecordSurfaceAssoc(vichwAssocs[iichw], islout, 0);
- }
-
- vichwComponents.clear();
- if (pslot->HasComponents())
- pslot->AllComponentRefs(vichwComponents);
-
- for (iichw = 0; iichw < vichwComponents.size(); iichw++)
- {
- pseg->RecordLigature(vichwComponents[iichw], islout, iichw);
- }
- }
- }
-
- AdjustAssocsForOverlaps(pseg);
- pseg->CleanUpAssocsVectors();
-
-// pseg->AdjustForOverlapsWithPrevSeg(); // for any characters officially in the
- // previous segment but rendered in this one,
- // or vice versa
-
- // TODO SharonC: for all characters that are right-to-left in the underlying stream,
- // reverse the before and after flags in the segment.
-}
-
-/*----------------------------------------------------------------------------------------------
- For any slots associated with characters in the new segment but not rendered in the
- segment, adjust the underlying-to-surface mappings accordingly. Ie, set the before
- mapping to kNegInfinity for slots at the beginning of the streams, and set the
- after mapping to kPosInfinity for slots at the end of the streams.
-
- TODO SharonC: Rework this method more carefully to handle each slot exactly once. The current
- approach could possibly, for instance, process a slot that is inserted in one pass
- and deleted in the next.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::AdjustAssocsForOverlaps(Segment * pseg)
-{
- if (!m_engst.m_fInitialLB && !m_engst.m_fFinalLB && !m_engst.m_fInsertedLB)
- // no cross-line contextualization possible
- return;
-
- gid16 chwLB = LBGlyphID();
- std::vector<int> vichwAssocs;
-
- // Process any slots output by any substitution pass (or later) on either side of the
- // line-breaks. These are the relevant slots that are rendered in the previous and
- // following segments.
- for (int ipass = m_cpass; ipass-- > m_cpassLB + 1; )
- {
- GrSlotStream * psstrm = OutputStream(ipass);
- int islotMin = (ipass == m_cpass - 1) ? psstrm->IndexOffset() : 0;
-
- if (m_engst.m_fInitialLB)
- {
- for (int islot = islotMin; ; islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- if (pslot->IsInitialLineBreak(chwLB))
- break;
- Assert(!pslot->IsFinalLineBreak(chwLB));
- if (pslot->PassModified() != ipass)
- continue;
-
- vichwAssocs.clear();
- pslot->AllAssocs(vichwAssocs);
- for (size_t iichw = 0; iichw < vichwAssocs.size(); ++iichw)
- pseg->MarkSlotInPrevSeg(vichwAssocs[iichw], islot);
- }
- }
-
- if ((m_engst.m_fFinalLB || m_engst.m_fInsertedLB) && ipass > m_cpassLB)
- {
- for (int islot = psstrm->WritePos(); islot-- > islotMin ; )
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- if (pslot->IsFinalLineBreak(chwLB))
- break;
- Assert(!pslot->IsInitialLineBreak(chwLB));
- if (pslot->PassModified() != ipass)
- continue;
-
- vichwAssocs.clear();
- pslot->AllAssocs(vichwAssocs);
- for (size_t iichw = 0; iichw < vichwAssocs.size(); ++iichw)
- pseg->MarkSlotInNextSeg(vichwAssocs[iichw], islot);
- }
- }
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Initialize all the streams. In particular, process the information about the
- skip-offsets to handle segments other than the first.
-
- @param cbPrev - number of bytes in the pbPrevSegDat buffer
- @param pbPrevSegDat - buffer in the following format (all are 1 byte, unsigned):
- prev seg's end breakweight
- prev seg's previous strong directionality code
- prev seg's previous terminator dir code
- restart backup
- skip offsets for each pass
- This format must match what is generated by InitializeForNextSeg.
-----------------------------------------------------------------------------------------------*/
-void EngineState::InitializeStreams(GrTableManager * ptman,
- GrCharStream * pchstrm,
- int cbPrev, byte * pbPrevSegDat, bool fNeedFinalBreak, int * pislotFinalBreak)
-{
- int cpassLB = ptman->NumberOfLbPasses();
- int ipassPos1 = ptman->FirstPosPass();
-
- CreateSlotStreams();
-
- int cslotBackup = 0;
-
- InitForNewSegment(ptman);
-
- if (cbPrev == 0)
- {
- m_lbPrevEnd = klbNoBreak;
- m_dircInitialStrongDir = kdircNeutral;
- m_dircInitialTermDir = kdircNeutral;
- for (int ipass = 0; ipass < m_cpass; ++ipass)
- {
- OutputStream(ipass)->Initialize(ipassPos1, false);
- m_prgzpst[ipass].SetResyncSkip(0);
-
- if (ptman->LoggingTransduction())
- m_prgzpst[ipass].InitializeLogInfo();
- }
- }
- else
- {
- Assert(cbPrev >= 4);
- byte * pb = pbPrevSegDat;
-
- m_lbPrevEnd = LineBrk(*pb++);
-
- // Directionality codes from the previous segment.
- m_dircInitialStrongDir = DirCode((int)*pb++);
- m_dircInitialTermDir = DirCode((int)*pb++);
-
- cslotBackup = (int)*pb++;
- Assert((cbPrev == 4 || cslotBackup == 0) || cbPrev == m_cpass + 4);
-
- for (int ipass = 0; ipass < m_cpass; ++ipass)
- {
- OutputStream(ipass)->Initialize(ipassPos1, true);
- if (cbPrev == 4)
- m_prgzpst[ipass].SetResyncSkip(0); // different writing system
- else
- m_prgzpst[ipass].SetResyncSkip(*pb++);
-
- if (ptman->LoggingTransduction())
- m_prgzpst[ipass].InitializeLogInfo();
- }
-
- pchstrm->Backup(cslotBackup);
- }
-
- if (cbPrev > 0 || pchstrm->StartLine())
- {
- // Go ahead and run the initial line-break passes (if any), and then insert
- // a line-break at the appropriate place where the new segment will begin.
- int cslotToGet = cslotBackup;
-LGetMore:
- ptman->Pass(0)->ExtendGlyphIDOutput(ptman, pchstrm, OutputStream(0),
- -1, 0, klbWordBreak,
- cslotToGet, fNeedFinalBreak, m_twsh, pislotFinalBreak);
- OutputStream(0)->SetSegMin(cslotBackup);
- for (int ipass = 1; ipass <= cpassLB; ipass++)
- {
- if (cslotToGet > 0)
- {
- int nRet = kNextPass;
- int cslotGot;
- ptman->Pass(ipass)->ExtendOutput(ptman,
- InputStream(ipass), OutputStream(ipass),
- cslotToGet, m_twsh, &nRet, &cslotGot, pislotFinalBreak);
- if (nRet != kNextPass)
- {
- cslotToGet = 1;
- goto LGetMore;
- }
- }
- OutputStream(ipass)->SetSegMin(cslotBackup);
- }
- Assert(OutputStream(cpassLB)->WritePos() >= cslotBackup);
- m_cslotPreSeg = cslotBackup;
- if (pchstrm->StartLine())
- {
- OutputStream(cpassLB)->AppendLineBreak(ptman, pchstrm, m_lbPrevEnd,
- (ptman->RightToLeft() ? kdircRlb : kdircLlb), cslotBackup, true, -1);
- SetInitialLB();
- m_cslotPreSeg++;
- if (cpassLB > 0 && *pislotFinalBreak > -1)
- // See corresponding kludge in GrPass::ExtendGlyphIDOutput.
- *pislotFinalBreak += 1;
- }
- else
- {
- OutputStream(cpassLB)->SetSegMin(cslotBackup);
- }
- OutputStream(cpassLB)->CalcIndexOffset(ptman);
- }
-
- else
- {
- Assert(cslotBackup == 0);
- OutputStream(0)->SetSegMin(0);
- m_cslotPreSeg = 0;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Reinitialize as we start to generate a new segment.
-----------------------------------------------------------------------------------------------*/
-void EngineState::InitForNewSegment(GrTableManager * ptman)
-{
- // Set up a fresh batch of slots.
- DestroySlotBlocks();
- m_islotblkCurr = -1;
- m_islotNext = kSlotBlockSize;
-
- m_fInitialLB = false;
- m_fFinalLB = false;
- m_fInsertedLB = false;
- m_fExceededSpace = false;
- m_fHitHardBreak = false;
- m_fRemovedWhtsp = false;
- InitPosCache();
- //////m_pgg = pgg;
-
- for (int ipass = 0; ipass < m_cpass; ipass++)
- m_prgzpst[ipass].InitForNewSegment(ipass, ptman->Pass(ipass)->MaxRuleContext());
-}
-
-/*----------------------------------------------------------------------------------------------
- Calculate the position in stream zero of the given slot in the final stream,
- based on the associations. (This will be the same as the position at the end of the
- line-break passes, which is really what we want.)
-
- @param islotFinal - index of the final slot in the final stream
-----------------------------------------------------------------------------------------------*/
-int EngineState::TraceStreamZeroPos(int islotFinal, int nTopDir)
-{
- GrSlotStream * psstrmFinal = OutputStream(m_cpass - 1);
- if (psstrmFinal->WritePos() == 0)
- return -1;
-
- GrSlotState * pslot = psstrmFinal->SlotAt(islotFinal);
-
- // If we're in the middle of reordered bidi stuff, just use the end of the stream.
- if (pslot->DirLevel() > nTopDir)
- return -1;
-
- int islot = pslot->BeforeAssoc();
- if (islot == kPosInfinity || islot < 0)
- return -1;
- return islot + m_cslotPreSeg;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the next higher (more relaxed, less desirable) line break weight.
-----------------------------------------------------------------------------------------------*/
-LineBrk GrTableManager::IncLineBreak(LineBrk lb)
-{
- Assert(lb != klbClipBreak);
- return (LineBrk)((int)lb + 1);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return a pointer to a slot that is near the current position in the given stream.
- Return NULL if no slots have been output at all.
- This is used for initializing features of line-break slots.
- @param ipassArg - pass at which to start looking
- @param islot - slot to look for; -1 if considering the current position
-----------------------------------------------------------------------------------------------*/
-GrSlotState * EngineState::AnAdjacentSlot(int ipassArg, int islot)
-{
- int ipass = ipassArg;
- while (ipass >= 0)
- {
- GrSlotStream * psstrm = OutputStream(ipass);
- if (psstrm->NumberOfSlots() > 0)
- {
- if (islot == -1)
- {
- if (psstrm->AtEnd())
- return psstrm->SlotAt(psstrm->WritePos() - 1);
- else
- return psstrm->Peek();
- }
- else
- {
- if (psstrm->WritePos() <= islot)
- return psstrm->SlotAt(psstrm->WritePos() - 1);
- else
- return psstrm->SlotAt(islot);
- }
- }
- ipass--;
- }
- return NULL;
-}
-
-/*----------------------------------------------------------------------------------------------
- Simple access methods.
-----------------------------------------------------------------------------------------------*/
-GrEngine * GrTableManager::Engine()
-{
- return m_pgreng;
-}
-
-EngineState * GrTableManager::State()
-{
- return &m_engst;
-}
-
-GrEngine * EngineState::Engine()
-{
- return m_ptman->Engine();
-}
-
-GrTableManager * EngineState::TableManager()
-{
- return m_ptman;
-}
-
-/*----------------------------------------------------------------------------------------------
- Memory management for slots
-----------------------------------------------------------------------------------------------*/
-
-// standard for pass 0 slots
-void EngineState::NewSlot(
- gid16 gID, GrFeatureValues fval, int ipass, int ichwSegOffset, int nUnicode,
- GrSlotState ** ppslotRet)
-{
- NextSlot(ppslotRet);
- (*ppslotRet)->Initialize(gID, Engine(), fval, ipass, ichwSegOffset, nUnicode);
-}
-
-// line-break slots
-void EngineState::NewSlot(
- gid16 gID, GrSlotState * pslotFeat, int ipass, int ichwSegOffset,
- GrSlotState ** ppslotRet)
-{
- NextSlot(ppslotRet);
- (*ppslotRet)->Initialize(gID, Engine(), pslotFeat, ipass, ichwSegOffset);
-}
-
-// for inserting new slots after pass 0 (under-pos and unicode are irrelevant)
-void EngineState::NewSlot(
- gid16 gID, GrSlotState * pslotFeat, int ipass,
- GrSlotState ** ppslotRet)
-{
- NextSlot(ppslotRet);
- (*ppslotRet)->Initialize(gID, Engine(), pslotFeat, ipass);
-}
-
-// for making a new version of the slot initialized from the old
-void EngineState::NewSlotCopy(GrSlotState * pslotCopyFrom, int ipass,
- GrSlotState ** ppslotRet)
-{
- NextSlot(ppslotRet);
- (*ppslotRet)->InitializeFrom(pslotCopyFrom, ipass);
-}
-
-void EngineState::NextSlot(GrSlotState ** ppslotRet)
-{
- int cnExtraPerSlot = m_cUserDefn + (m_cCompPerLig * 2) + m_cFeat;
- if (m_islotNext >= kSlotBlockSize)
- {
- // Allocate a new block of slots
- GrSlotState * slotblkNew = new GrSlotState[kSlotBlockSize];
- u_intslot * prgnSlotBuf = new u_intslot[kSlotBlockSize * cnExtraPerSlot];
-
- m_vslotblk.push_back(slotblkNew);
- m_vprgnSlotVarLenBufs.push_back(prgnSlotBuf);
- m_islotblkCurr++;
- m_islotNext = 0;
- Assert((unsigned)m_islotblkCurr == m_vslotblk.size()-1);
- }
-
- *ppslotRet = m_vslotblk[m_islotblkCurr] + m_islotNext;
- (*ppslotRet)->BasicInitialize(m_cUserDefn, m_cCompPerLig, m_cFeat,
- (m_vprgnSlotVarLenBufs[m_islotblkCurr] + (m_islotNext * cnExtraPerSlot)));
- m_islotNext++;
-}
-
-/*----------------------------------------------------------------------------------------------
- Convert the number of font design units into source device logical units.
-----------------------------------------------------------------------------------------------*/
-float GrTableManager::EmToLogUnits(int m)
-{
- return m_engst.EmToLogUnits(m);
-}
-
-float EngineState::EmToLogUnits(int m)
-{
- if (m == 0)
- return 0;
-
- float xysFontEmSquare;
- m_pfont->getFontMetrics(NULL, NULL, &xysFontEmSquare);
-
- // mEmUnits should be equal to the design units in the font's em square
- int mEmUnits = Engine()->GetFontEmUnits();
- if (mEmUnits <= 0)
- {
- Warn("Failed to obtain font em-units");
- return (float)m;
- }
-
- return GrEngine::GrIFIMulDiv(m, xysFontEmSquare, mEmUnits);
-}
-
-/*----------------------------------------------------------------------------------------------
- Convert the source device coordinates to font design units.
-----------------------------------------------------------------------------------------------*/
-int GrTableManager::LogToEmUnits(float xys)
-{
- return m_engst.LogToEmUnits(xys);
-}
-
-int EngineState::LogToEmUnits(float xys)
-{
- if (xys == 0)
- return 0;
-
- float xysFontEmSquare;
- m_pfont->getFontMetrics(NULL, NULL, &xysFontEmSquare);
-
- // mEmUnits should be equal to the design units in the font's em square
- int mEmUnits = Engine()->GetFontEmUnits();
- if (mEmUnits < 0)
- {
- Warn("Failed to obtain font em-units");
- return (int)xys;
- }
-
- return GrEngine::GrFIFMulDiv(xys, mEmUnits, xysFontEmSquare);
-}
-
-/*----------------------------------------------------------------------------------------------
- Find the coordinates for a given glyph point.
- Return true on success, false otherwise.
-----------------------------------------------------------------------------------------------*/
-bool GrTableManager::GPointToXY(gid16 chwGlyphID, int nGPoint, float * pxs, float * pys)
-{
- return m_engst.GPointToXY(chwGlyphID, nGPoint, pxs, pys);
-}
-
-bool EngineState::GPointToXY(gid16 chwGlyphID, int nGPoint, float * pxs, float * pys)
-{
- *pxs = INT_MIN;
- *pys = INT_MIN;
- Point pointRet;
- m_pfont->getGlyphPoint(chwGlyphID, nGPoint, pointRet);
- *pxs = pointRet.x;
- *pys = pointRet.y;
-
- return true;
-}
-
-/*----------------------------------------------------------------------------------------------
- Call the justification routines.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::CallJustifier(IGrJustifier * pgjus, int ipassCurr,
- float dxUnjustified, float dxJustified, bool fEndLine)
-{
- // Indicates the stream the justification routines will read and modify:
- m_engst.m_ipassJustCalled = ipassCurr;
-
- int iGlyphMin = OutputStream(ipassCurr)->SegMin();
- int iGlyphLim = OutputStream(ipassCurr)->SegLimIfKnown();
- if (iGlyphLim == -1)
- iGlyphLim = OutputStream(ipassCurr)->WritePos();
-
- GrSlotStream * psstrm = OutputStream(ipassCurr);
- if (m_pgreng->BasicJustification() && fEndLine)
- UnstretchTrailingWs(psstrm, iGlyphLim);
-
- pgjus->adjustGlyphWidths(m_pgreng, iGlyphMin, iGlyphLim, dxUnjustified, dxJustified);
-
- // After returning, reading and modifying slot attributes is not permitted:
- m_engst.m_ipassJustCalled = -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- For the basic justification approach, remove stretch from the trailing whitespace.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::UnstretchTrailingWs(GrSlotStream * psstrm, int iGlyphLim)
-{
- int islot = iGlyphLim - 1;
- while (islot >= 0)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- if (pslot->IsLineBreak(LBGlyphID()))
- { } // keep looking for the trailing space
- else if (pslot->IsSpace(this))
- pslot->SetJStretch(0); // TODO: do this at level 0
- else
- // something other than space--quit
- return;
- islot--;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Determine how much shrink is permissible.
-
- This method is really used only for testing the shrink mechanism, since at this time
- we don't allow low-end justification to do any shrinking.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::DetermineShrink(IGrJustifier * pgjus, int ipassCurr)
-{
- if (m_engst.m_dxsShrinkPossible != GrSlotState::kNotYetSet)
- return;
-
- if (m_engst.m_jmodi != kjmodiCanShrink || pgjus == NULL)
- {
- m_engst.m_dxsShrinkPossible = 0;
- return;
- }
-
- if (ipassCurr != m_ipassJust1 - 1)
- return;
-
- GrSlotStream * psstrm = OutputStream(ipassCurr);
- if (!psstrm->FullyWritten())
- return;
-
- // Normally just answer 0. To test shrinking, turn on the code below.
- m_engst.m_dxsShrinkPossible = 0;
-
-#if TEST_SHRINK
- int mTotal = 0;
- int mShrink = 0;
- int islotLim = psstrm->SegLimIfKnown();
- if (islotLim == -1)
- islotLim = psstrm->WritePos();
- for ( ; islotLim >= 0; islotLim--)
- {
- // Trailing white space is not shrinkable.
- GrSlotState * pslot = psstrm->SlotAt(islotLim - 1);
- if (pslot->IsLineBreak(LBGlyphID()))
- continue;
- if (!pslot->IsSpace(this))
- break;
- }
- int islot;
- for (islot = psstrm->SegMin(); islot < islotLim; islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- if (pslot->IsLineBreak(LBGlyphID()))
- continue;
- mTotal += pslot->AdvanceX(this);
- mShrink += pslot->JShrink();
- }
-
- // Say that we are allowed to shrink up to 10% of the width of the segment.
- mShrink = min(mShrink, mTotal/10);
- m_engst.m_dxsShrinkPossible = EmToLogUnits(mShrink);
-#endif // TEST_SHRINK
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the attribute of the given slot, back to the justification routine. Return
- logical units.
-----------------------------------------------------------------------------------------------*/
-GrResult EngineState::GetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel,
- float * pValueRet)
-{
- GrResult res;
- int valueRetInt = 0;
- switch(jgat)
- {
- case kjgatWeight:
- case kjgatStretchInSteps:
- case kjgatBreak:
- res = GetGlyphAttrForJustification(iGlyph, jgat, nLevel, &valueRetInt);
- *pValueRet = (float)valueRetInt;
- return res;
- default:
- break;
- }
-
- if (m_ipassJustCalled == -1)
- return kresUnexpected;
-
- if (nLevel != 1)
- return kresInvalidArg;
-
- GrSlotStream * psstrm = OutputStream(m_ipassJustCalled);
-
- if (iGlyph < -1 || iGlyph >= psstrm->WritePos())
- return kresInvalidArg;
-
- GrSlotState * pslot = psstrm->SlotAt(iGlyph);
-
- // bool fConvertUnits = true;
-
- switch(jgat)
- {
- case kjgatStretch:
- *pValueRet = EmToLogUnits(pslot->JStretch());
- break;
- case kjgatShrink:
- *pValueRet = EmToLogUnits(pslot->JShrink());
- break;
- case kjgatStep:
- *pValueRet = EmToLogUnits(pslot->JStep());
- break;
- default:
- return kresNotImpl;
- }
- return kresOk;
-}
-
-GrResult EngineState::GetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel,
- int * pValueRet)
-{
- GrResult res;
- float valueRetFloat;
- switch(jgat)
- {
- case kjgatStretch:
- case kjgatShrink:
- case kjgatStep:
- res = GetGlyphAttrForJustification(iGlyph, jgat, nLevel, &valueRetFloat);
- *pValueRet = GrEngine::RoundFloat(valueRetFloat);
- return res;
- default:
- break;
- }
-
- if (m_ipassJustCalled == -1)
- return kresUnexpected;
-
- if (nLevel != 1)
- return kresInvalidArg;
-
- GrSlotStream * psstrm = OutputStream(m_ipassJustCalled);
-
- if (iGlyph < -1 || iGlyph >= psstrm->WritePos())
- return kresInvalidArg;
-
- GrSlotState * pslot = psstrm->SlotAt(iGlyph);
-
- int mStretch, mStep;
- //float xsStretch, xsStep;
-
- switch(jgat)
- {
- case kjgatWeight:
- *pValueRet = pslot->JWeight();
- break;
- case kjgatStretchInSteps:
- // ???? should this be calculated in terms of logical units??
- // Probably doesn't matter, since the logical units are floating point, so the
- // level of precision is about the same.
- mStretch = pslot->JStretch();
- mStep = pslot->JStep();
- if (mStep == 0)
- return kresUnexpected;
- *pValueRet = int(mStretch / mStep); // round down
- break;
- //case kjgatStretchInSteps:
- // xsStretch = EmToLogUnits(pslot->JStretch());
- // xsStep = EmToLogUnits(pslot->JStep());
- // if (xsStep == 0)
- // return kresUnexpected;
- // *pValueRet = int(xsStretch / xsStep); // round down
- // break;
- case kjgatBreak:
- *pValueRet = pslot->BreakWeight();
- break;
- default:
- return kresNotImpl;
- }
- return kresOk;
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the attribute of the given slot, for the justification routine.
-----------------------------------------------------------------------------------------------*/
-GrResult EngineState::SetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel,
- float value)
-{
- GrResult res;
- int valueInt;
- switch(jgat)
- {
- case kjgatWeight:
- case kjgatStretchInSteps:
- case kjgatBreak:
- valueInt = (int)value;
- res = SetGlyphAttrForJustification(iGlyph, jgat, nLevel, valueInt);
- return res;
- default:
- break;
- }
-
- if (m_ipassJustCalled == -1)
- return kresUnexpected;
-
- if (nLevel != 1)
- return kresInvalidArg;
-
- GrSlotStream * psstrm = OutputStream(m_ipassJustCalled);
-
- if (iGlyph < -1 || iGlyph >= psstrm->WritePos())
- return kresInvalidArg;
-
- GrSlotState * pslot = psstrm->SlotAt(iGlyph);
-
- int mValue = LogToEmUnits(value);
- mValue = min(mValue, 0xFFFF); // truncate to an unsigned short
-
- // Review: do we really want to allow them to set stretch/shrink/step/weight? The normal
- // thing for them to do is set width.
- switch(jgat)
- {
- case kjgatStretch:
- pslot->SetJStretch(mValue);
- break;
- case kjgatShrink:
- pslot->SetJShrink(mValue);
- break;
- case kjgatStep:
- pslot->SetJStep(mValue);
- break;
- case kjgatWidth:
- pslot->SetJWidth(mValue);
- break;
- default:
- return kresNotImpl;
- }
- return kresOk;
-}
-
-GrResult EngineState::SetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel,
- int value)
-{
- GrResult res;
- float valueFloat;
- switch(jgat)
- {
- case kjgatStretch:
- case kjgatShrink:
- case kjgatStep:
- case kjgatWidth:
- valueFloat = (float)value;
- res = SetGlyphAttrForJustification(iGlyph, jgat, nLevel, valueFloat);
- return res;
- default:
- break;
- }
-
- if (m_ipassJustCalled == -1)
- return kresUnexpected;
-
- if (nLevel != 1)
- return kresInvalidArg;
-
- GrSlotStream * psstrm = OutputStream(m_ipassJustCalled);
-
- if (iGlyph < -1 || iGlyph >= psstrm->WritePos())
- return kresInvalidArg;
-
- GrSlotState * pslot = psstrm->SlotAt(iGlyph);
-
- int mValue, cSteps;
- switch(jgat)
- {
- case kjgatWeight:
- pslot->SetJWeight(value);
- break;
- case kjgatWidthInSteps:
- cSteps = value;
- mValue = pslot->JStep();
- if (mValue == 0)
- return kresUnexpected;
- pslot->SetJWidth(mValue * cSteps);
- break;
- default:
- return kresNotImpl;
- }
- return kresOk;
-}
-
-//:>--------------------------------------------------------------------------------------------
-//:> Functions to forward to the engine.
-//:>------------------------------------------------------------------------------------------*/
-gid16 GrTableManager::GetGlyphIDFromUnicode(int nUnicode)
-{
- return m_pgreng->GetGlyphIDFromUnicode(nUnicode);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-gid16 GrTableManager::ActualGlyphForOutput(utf16 chw)
-{
- return m_pgreng->ActualGlyphForOutput(chw);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-GrGlyphTable * GrTableManager::GlyphTable()
-{
- return m_pgreng->GlyphTable();
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-gid16 GrTableManager::LBGlyphID()
-{
- return m_pgreng->LBGlyphID();
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-gid16 GrTableManager::GetClassGlyphIDAt(int nClass, int nIndex)
-{
- return m_pgreng->GetClassGlyphIDAt(nClass, nIndex);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int GrTableManager::GetIndexInGlyphClass(int nClass, gid16 chwGlyphID)
-{
- return m_pgreng->GetIndexInGlyphClass(nClass, chwGlyphID);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-size_t GrTableManager::NumberOfGlyphsInClass(int nClass)
-{
- return m_pgreng->NumberOfGlyphsInClass(nClass);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-void GrTableManager::SetSlotAttrsFromGlyphAttrs(GrSlotState * pslot)
-{
- m_pgreng->SetSlotAttrsFromGlyphAttrs(pslot);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int GrTableManager::NumFeat()
-{
- return m_pgreng->NumFeat();
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int GrTableManager::DefaultForFeatureAt(int ifeat)
-{
- return m_pgreng->DefaultForFeatureAt(ifeat);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-void GrTableManager::DefaultsForLanguage(isocode lgcode,
- std::vector<featid> & vnFeats, std::vector<int> & vnValues)
-{
- return m_pgreng->DefaultsForLanguage(lgcode, vnFeats, vnValues);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-GrFeature * GrTableManager::FeatureWithID(featid nID, int * pifeat)
-{
- return m_pgreng->FeatureWithID(nID, pifeat);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-GrFeature * GrTableManager::Feature(int ifeat)
-{
- return m_pgreng->Feature(ifeat);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-bool GrTableManager::RightToLeft()
-{
- if (m_engst.WhiteSpaceOnly())
- return m_engst.m_fParaRtl;
- else
- return m_pgreng->RightToLeft();
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int GrTableManager::TopDirectionLevel()
-{
- return m_pgreng->TopDirectionLevel();
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-float GrTableManager::VerticalOffset()
-{
- return m_pgreng->VerticalOffset();
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int GrTableManager::NumUserDefn()
-{
- return m_pgreng->NumUserDefn();
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int GrTableManager::NumCompPerLig()
-{
- return m_pgreng->NumCompPerLig();
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int GrTableManager::ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID)
-{
- return m_pgreng->ComponentIndexForGlyph(chwGlyphID, nCompID);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int GrTableManager::GlyphAttrValue(gid16 chwGlyphID, int nAttrID)
-{
- return m_pgreng->GlyphAttrValue(chwGlyphID, nAttrID);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-bool GrTableManager::LoggingTransduction()
-{
- return m_fLogging;
- //return m_pgreng->LoggingTransduction();
-}
-
-/*----------------------------------------------------------------------------------------------
- Calculate the positions of the glyphs up to the given slot, within the output of the given
- pass. If the slot is NULL, go all the way to the end of what has been generated.
-
- @param ipass - index of pass needing positioning; normally this will be the
- final pass, but it could be another if positions are
- requested by the rules themselves
- @param pslotLast - last slot that needs to be positioned, or NULL
- @param pxsWidth - return the total width used so far
- @param psxVisibleWidth - return the visible width so far
-
- MOVE to EngineState
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::CalcPositionsUpTo(int ipass, GrSlotState * pslotLast,
- float * pxsWidth, float * pxsVisibleWidth)
-{
- Assert(ipass >= m_ipassPos1 - 1);
-
- int isstrm = ipass;
- GrSlotStream * psstrm = OutputStream(isstrm);
- Assert(psstrm->GotIndexOffset());
- if (psstrm->WritePos() <= psstrm->IndexOffset())
- {
- Assert(psstrm->WritePos() == 0);
- *pxsWidth = 0;
- *pxsVisibleWidth = 0;
- return;
- }
- if (!pslotLast)
- {
- pslotLast = psstrm->SlotAt(psstrm->WritePos() - 1);
- }
- Assert(pslotLast);
-
- // First set positions of all base slots.
-
- int islot = psstrm->IndexOffset();
- GrSlotState * pslot;
- float xs = 0;
- float ys = VerticalOffset();
- *pxsWidth = 0;
- *pxsVisibleWidth = 0;
-
- bool fLast = false;
- bool fLastBase = false;
-
- bool fFakeItalic = m_pgreng->FakeItalic();
- float fakeItalicRatio = 0;
- if (fFakeItalic)
- fakeItalicRatio = State()->GetFont()->fakeItalicRatio();
- bool fBasicJust = m_pgreng->BasicJustification();
-
- // Figure out how to know when to stop.
- // We need to calculate up to the base of the last leaf slot, if it happens
- // to be later in the stream than the last actual slot passed in.
- if (!psstrm->HasSlotAtPosPassIndex(pslotLast->AttachRootPosPassIndex()))
- return;
- GrSlotState * pslotLastBase = pslotLast->Base(psstrm);
-
- if (ipass == m_cpass - 1 && m_engst.m_islotPosNext > -1)
- {
- // For final pass, initialize from cache of previous calculations.
- islot = m_engst.m_islotPosNext;
- xs = m_engst.m_xsPosXNext;
- ys = m_engst.m_ysPosYNext;
- *pxsWidth = m_engst.m_dxsTotWidthSoFar;
- *pxsVisibleWidth = m_engst.m_dxsVisWidthSoFar;
-
- if (psstrm->SlotsPresent() <= islot)
- return;
-
- if (pslotLastBase->PosPassIndex() == GrSlotAbstract::kNotYetSet)
- {
- Assert(false); // I think this case is handled above
- return; // can't position this slot yet; its base has not been processed
- }
-
- if (pslotLastBase->PosPassIndex() + psstrm->IndexOffset() < islot)
- {
- fLastBase = true;
- if (pslotLast == pslotLastBase)
- fLast = true;
- }
- }
-
- std::vector<GrSlotState *> vpslotAttached;
-
- bool fRtl = RightToLeft();
-
- while (!fLast || !fLastBase)
- {
- Assert(islot < psstrm->SlotsPresent());
-
- pslot = (isstrm == ipass) ? psstrm->SlotAt(islot) : psstrm->OutputSlotAt(islot);
-
- if (!pslot->IsBase())
- {
- // This slot is attached to another; it will be positioned strictly
- // relative to that one. This happens in the loop below.
- vpslotAttached.push_back(pslot);
- }
- else
- {
- // Base character.
-
- bool fLB = pslot->IsLineBreak(LBGlyphID());
- if (InternalJustificationMode() == kjmodiJustify && fBasicJust
- && ipass == m_cpass - 1 && !fLB)
- {
- m_engst.AddJWidthToAdvance(psstrm, &pslot, islot, &pslotLast, &pslotLastBase);
- }
-
- // Make sure the metrics are the complete ones.
- pslot->CalcCompositeMetrics(this, psstrm, kPosInfinity, true);
-
- float xsInc = pslot->GlyphXOffset(psstrm, fakeItalicRatio);
- float ysInc = pslot->GlyphYOffset(psstrm);
- float xsAdvX = pslot->ClusterAdvWidth(psstrm);
- float ysAdvY = (fLB) ?
- 0 :
- EmToLogUnits(pslot->AdvanceY(this));
-
- if (fRtl)
- {
- xs -= xsAdvX;
- ys -= ysAdvY;
- pslot->SetXPos(xs + xsInc);
- pslot->SetYPos(ys + ysInc);
- }
- else
- {
- pslot->SetXPos(xs + xsInc);
- pslot->SetYPos(ys + ysInc);
- xs += xsAdvX;
- ys += ysAdvY;
- }
-
- *pxsWidth = max(*pxsWidth, fabsf(xs));
- if (!IsWhiteSpace(pslot))
- *pxsVisibleWidth = *pxsWidth;
-
- if (isstrm == m_cpass - 1)
- {
- // For the final output pass, cache the results of the calculation so far.
- // Only do this for slots that have actually been processed by the final
- // pass, because others may have intermediate values that may be changed
- // later.
- m_engst.m_islotPosNext = pslot->PosPassIndex() + psstrm->IndexOffset() + 1;
- m_engst.m_xsPosXNext = xs;
- m_engst.m_ysPosYNext = ys;
- m_engst.m_dxsTotWidthSoFar = *pxsWidth;
- m_engst.m_dxsVisWidthSoFar = *pxsVisibleWidth;
- }
- }
-
- // Need to have calculated both the last leaf and the last base (if they happen to
- // be different); if so, we're done.
- if (pslot == pslotLast)
- fLast = true;
- if (pslot == pslotLastBase)
- fLastBase = true;
-
- islot++;
- }
-
- Assert(fLast);
- Assert(fLastBase);
-
- // Now set positions of non-base slots, relative to their bases.
-
- for (size_t ipslot = 0; ipslot < vpslotAttached.size(); ipslot++)
- {
- GrSlotState * pslot = vpslotAttached[ipslot];
- GrSlotState * pslotBase = pslot->Base(psstrm);
- if (pslotBase->XPosition() == kNegInfinity || pslotBase->YPosition() == kNegInfinity)
- {
- Assert(false);
- continue;
- }
- float xsCluster = pslotBase->XPosition() - pslotBase->GlyphXOffset(psstrm, fakeItalicRatio);
- float ysCluster = pslotBase->YPosition() - pslotBase->GlyphYOffset(psstrm);
- float xsInc = pslot->GlyphXOffset(psstrm, fakeItalicRatio);
- float ysInc = pslot->GlyphYOffset(psstrm);
- pslot->SetXPos(xsCluster + xsInc);
- pslot->SetYPos(ysCluster + ysInc);
-
- // My theory is that we don't need to adjust *pxsWidth here, because the width of
- // any non-base slots should be factored into the advance width of their cluster
- // base, which was handled above.
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if the given slot is white space.
-----------------------------------------------------------------------------------------------*/
-bool GrTableManager::IsWhiteSpace(GrSlotState * pslot)
-{
- if (pslot->IsLineBreak(LBGlyphID()))
- return true;
- return pslot->IsSpace(this);
-}
-
-/*----------------------------------------------------------------------------------------------
- When doing basic justification, apply the value of justify.width to the advance width.
- This happens during the final positioning routine.
-----------------------------------------------------------------------------------------------*/
-void EngineState::AddJWidthToAdvance(GrSlotStream * psstrm, GrSlotState ** ppslot, int islot,
- GrSlotState ** ppslotLast, GrSlotState ** ppslotLastBase)
-{
- Assert(psstrm->OutputOfPass() == m_cpass - 1); // only used for final stream
- if ((*ppslot)->JWidth() > 0)
- {
- if ((*ppslot)->PassModified() != m_cpass - 1)
- {
- // Replace the slot with a new slot, so it gets marked properly with the
- // pass in which it was modified. (Otherwise the debug log gets screwed up.)
- GrSlotState * pslotNew;
- NewSlotCopy((*ppslot), m_cpass - 1, &pslotNew);
- psstrm->PutSlotAt(pslotNew, islot);
- if (*ppslot == *ppslotLast)
- *ppslotLast = pslotNew;
- if (*ppslot == *ppslotLastBase)
- *ppslotLastBase = pslotNew;
- *ppslot = pslotNew;
- }
- (*ppslot)->AddJWidthToAdvance(TableManager());
- }
-}
-
-
-//:>********************************************************************************************
-//:> Debuggers and utilities
-//:>********************************************************************************************
-
-//:Ignore
-#if 0
-void GrTableManager::TempDebug()
-{
- for (int ipass = 0; ipass < m_cpass; ++ipass)
- {
- int wpos = OutputStream(ipass)->WritePos();
- int rpos = OutputStream(ipass)->ReadPos();
- GrSlotState * wslot = OutputStream(ipass)->LastSlotWritten();
- GrSlotState * rslot = OutputStream(ipass)->LastSlotRead();
-
- }
-}
-#endif
-/*----------------------------------------------------------------------------------------------
- Given a character index in the original string, locate the corresponding line-break slot
- in the final surface stream. The character index must be one before which there is a
- line-break (seg lim), or the beginning or the end of the string.
- TODO SharonC: fix the bugs
-----------------------------------------------------------------------------------------------*/
-int GrTableManager::SurfaceLineBreakSlot(int ichw, GrCharStream * pchstrm, bool fInitial)
-{
- if (ichw == 0)
- {
- Assert(fInitial);
- return -1; // no initial line break
- }
- if (ichw == pchstrm->Lim())
- {
- Assert(!fInitial);
- return -1; // no terminating line break
- }
-
- int islotIn = pchstrm->SegOffset(ichw);
- Assert(islotIn >= 0);
- islotIn += (fInitial? m_engst.m_cslotPreSeg - 1: m_engst.m_cslotPreSeg);
-
- gid16 chwLBGlyphID = LBGlyphID();
-
- // Now islotIn is the position in stream 0;
-
- for (int ipass = 1; ipass < m_cpass; ++ipass)
- {
- int islotChunkMin;
- int islotChunkLim;
- GrSlotStream * psstrmOut = OutputStream(ipass);
-
- GrSlotStream * psstrmIn = InputStream(ipass);
- if (fInitial)
- islotIn = max(islotIn, psstrmIn->PreChunk());
- int islotT = psstrmIn->ChunkInNextMin(islotIn);
- islotChunkMin = psstrmIn->ChunkInNext(islotT);
- islotChunkMin = (islotChunkMin == -1)? 0: islotChunkMin;
-
- islotT = psstrmIn->ChunkInNextLim(islotIn);
- Assert(islotT <= psstrmIn->ReadPos());
- if (islotT == psstrmIn->ReadPos())
- islotChunkLim = psstrmOut->WritePos();
- else
- islotChunkLim = psstrmIn->ChunkInNext(islotT);
-
- int islotOut;
- for (islotOut = islotChunkMin; islotOut < islotChunkLim; ++islotOut)
- {
- gid16 chw = psstrmOut->GlyphIDAt(islotOut);
- if (chw == chwLBGlyphID)
- break;
- }
- Assert(psstrmOut->GlyphIDAt(islotOut) == chwLBGlyphID);
-
- islotIn = islotOut;
- }
- return islotIn;
-}
-
-/*----------------------------------------------------------------------------------------------
- Generate a debugger string showing the chunk boundaries for the given stream.
-----------------------------------------------------------------------------------------------*/
-std::wstring GrTableManager::ChunkDebugString(int ipass)
-{
- GrSlotStream * psstrm = OutputStream(ipass);
- std::wstring stuRet;
- //utf16 chwN = '\\';
- //utf16 chwR = '^';
-
- gid16 chwLBGlyphID = LBGlyphID();
-
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- if (psstrm->ChunkInPrev(islot) != -1)
- {
- if (psstrm->ChunkInNext(islot) != -1)
- stuRet.append(L">");
- else
- stuRet.append(L"\\");
- }
- else if (psstrm->ChunkInNext(islot) != -1)
- stuRet.append(L"/");
- else
- stuRet.append(L" ");
-
-// if (islot == psstrm->ReadPos())
-// stuRet.Append(&chwR, 1);
-
- wchar_t chw = psstrm->SlotAt(islot)->GlyphID();
- if (chw == chwLBGlyphID)
- stuRet.append(L"#");
- else
- stuRet.append(&chw, 1);
- }
- return stuRet;
-}
-
-} // namespace gr
-
-//:End Ignore
diff --git a/Build/source/libs/graphite-engine/src/segment/GrTableManager.h b/Build/source/libs/graphite-engine/src/segment/GrTableManager.h
deleted file mode 100644
index e0306c832c7..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/GrTableManager.h
+++ /dev/null
@@ -1,583 +0,0 @@
-/*--------------------------------------------------------------------*//*:Ignore this sentence.
-Copyright (C) 1999 - 2008 SIL International. All rights reserved.
-
-Distributable under the terms of either the Common Public License or the
-GNU Lesser General Public License, as specified in the LICENSING.txt file.
-
-File: GrTableManager.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- The GrTableManager class.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef GR_TABLEMAN_INCLUDED
-#define GR_TABLEMAN_INCLUDED
-
-#include <cassert>
-//:End Ignore
-
-namespace gr
-{
-
-class Font;
-
-/*----------------------------------------------------------------------------------------------
- There is a single instance of Engine State that keeps track of the state of the processing
- for a single segment generation.
-
- Hungarian: engst
-----------------------------------------------------------------------------------------------*/
-class EngineState
-{
- friend class GrTableManager;
- friend class FontMemoryUsage;
-
-public:
- EngineState();
- void Initialize(GrEngine *, GrTableManager *);
-
- ~EngineState();
- void DestroySlotBlocks();
-
- void InitForNewSegment(GrTableManager * ptman);
-
- void CreateEmpty();
-
- GrEngine * Engine();
- GrTableManager * TableManager();
-
- void CreateSlotStreams();
-
- GrSlotStream * InputStream(int ipass)
- {
- Assert(ipass > 0); // the char stream serves as input to the zeroth pass
- return m_prgpsstrm[ipass - 1];
- }
-
- // Return the stream that serves as output to the given pass.
- GrSlotStream * OutputStream(int ipass)
- {
- Assert(ipass < m_cpass);
- return m_prgpsstrm[ipass];
- }
-
- GrSlotState * AnAdjacentSlot(int ipassArg, int islotArg);
-
- GrResult GetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel, float * pxysValueRet);
- GrResult GetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel, int * pxysValueRet);
- GrResult SetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel, float xysValue);
- GrResult SetGlyphAttrForJustification(int iGlyph, int jgat, int nLevel, int xysValue);
-
- enum { kSlotBlockSize = 50 }; // number of slots to allocate in a block
-
- void InitPosCache()
- {
- m_islotPosNext = -1;
- m_xsPosXNext = 0;
- m_ysPosYNext = 0;
- m_dxsTotWidthSoFar = 0;
- m_dxsVisWidthSoFar = 0;
- }
-
- void SetFont(Font * pfont)
- {
- m_pfont = pfont;
- }
- Font * GetFont()
- {
- return m_pfont;
- }
-
- bool StartLineContext()
- {
- return m_fStartLineContext;
- }
- bool EndLineContext()
- {
- return m_fEndLineContext;
- }
- void SetStartLineContext(bool f)
- {
- m_fStartLineContext = f;
- }
- void SetEndLineContext(bool f)
- {
- m_fEndLineContext = f;
- }
-
- void SetInitialLB(bool f = true)
- {
- m_fInitialLB = f;
- }
-
- void SetFinalLB(bool f = true)
- {
- m_fFinalLB = f;
- }
-
- void SetInsertedLB(bool f = true)
- {
- m_fInsertedLB = f;
- }
-
- bool HasInitialLB()
- {
- return m_fInitialLB;
- }
- bool HasInsertedLB()
- {
- return m_fInsertedLB;
- }
- bool HasFinalLB()
- {
- return m_fFinalLB;
- }
-
- void SetExceededSpace(bool f = true)
- {
- m_fExceededSpace = f;
- }
-
- bool ExceededSpace()
- {
- return m_fExceededSpace;
- }
-
- void SetHitHardBreak(bool f = true)
- {
- m_fHitHardBreak = f;
- }
-
- bool HitHardBreak()
- {
- return m_fHitHardBreak;
- }
-
- void SetRemovedTrWhiteSpace(bool f = true)
- {
- m_fRemovedWhtsp = f;
- }
-
- bool RemovedTrWhiteSpace()
- {
- return m_fRemovedWhtsp;
- }
-
- bool WhiteSpaceOnly()
- {
- return (m_twsh == ktwshOnlyWs);
- }
-
- bool ParaRightToLeft()
- {
- return m_fParaRtl;
- }
-
- //int PrevPassMaxBackup(int ipass)
- //{
- // if (ipass == 0)
- // return 0;
- // return Pass(ipass - 1)->MaxBackup();
- //}
-
- DirCode InitialStrongDir()
- {
- return m_dircInitialStrongDir;
- }
- DirCode InitialTermDir()
- {
- return m_dircInitialTermDir;
- }
-
- void InitializeStreams(GrTableManager * ptman, GrCharStream * pchstrm,
- int cbPrev, byte * pbPrevSegDat, bool fNeedFinalBreak, int * pislotFinalBreak);
- int LbSlotToSegLim(int islot, GrCharStream * pchstrm, int cpassLB);
- int TraceStreamZeroPos(int islotFinal, int nTopDir);
-
- float EmToLogUnits(int m);
- int LogToEmUnits(float xys);
- bool GPointToXY(gid16 chwGlyphID, int nGPoint, float * xs, float * ys);
-
- void AddJWidthToAdvance(GrSlotStream * psstrm, GrSlotState ** ppslot, int islot,
- GrSlotState ** ppslotLast, GrSlotState ** ppslotLastBase);
-
- // Memory management for slots:
- void NewSlot(gid16 gID, GrFeatureValues fval, int ipass, int ichwSegOffset, int nUnicode,
- GrSlotState **);
- void NewSlot(gid16 gID, GrSlotState * pslotFeat, int ipass, int ichwSegOffset,
- GrSlotState **);
- void NewSlot(gid16 gID, GrSlotState * pslotFeat, int ipass, GrSlotState **);
- void NewSlotCopy(GrSlotState * pslotCopyFrom, int ipass,
- GrSlotState ** pslotRet);
-protected:
- void NextSlot(GrSlotState ** ppslot);
-
-protected:
- GrTableManager * m_ptman;
-
- int m_cFeat;
- int m_cCompPerLig;
- int m_cUserDefn;
-
- int m_jmodi; // justification mode
- int m_ipassJustCalled; // pass after which justification routine was called;
- // -1 if we are not in the midst of interacting with the
- // GrJustifier
-
- // Pointer to font
- Font * m_pfont;
-
- bool m_fStartLineContext; // true if there was a rule that ran over the initial LB
- bool m_fEndLineContext; // true if there was a rule that ran over the final LB
-
- // the number of slots inserted in the first stream before the official beginning
- // of the segment, including any initial line break
- int m_cslotPreSeg;
-
- // List of allocated GrSlotStates; hungarian slotblk = prgslot
- std::vector<GrSlotState *> m_vslotblk;
- std::vector<u_intslot *> m_vprgnSlotVarLenBufs; // corresponding var-length blocks
- int m_islotblkCurr;
- int m_islotNext;
-
- // Directionality codes from previous segment; these are used by the bidi algorithm
- // at the initial line-break character.
- DirCode m_dircInitialStrongDir;
- DirCode m_dircInitialTermDir;
-
- LineBrk m_lbPrevEnd;
-
- // All of the following 3 are true only when there is an actual LB glyph in the stream
- bool m_fInitialLB; // is there is an initial LB (an actual LB glyph--in all streams)
- bool m_fFinalLB; // is there is a final LB (in all streams--true when we've hit
- // the end of the input and end-of-line is true)
- bool m_fInsertedLB; // is there is a final LB inserted in the output of LB pass
- // (true when we've backtracked)
-
- bool m_fExceededSpace; // true if we backtracked due to exceeding space; false if we
- // haven't backtracked, or we did so for some other reason
- // (eg, omitting trailing whitespace)
-
- bool m_fHitHardBreak; // true if we encountered a hard-break in the input stream
- // (before the natural end of the segment)
-
- bool m_fRemovedWhtsp; // true if we've hit trailing whitespace characters that we've
- // removed
-
- TrWsHandling m_twsh; // white-space handling
- bool m_fParaRtl; // paragraph direction
-
- float m_dxsShrinkPossible;
-
- // The final positioning pass is where we are going to do most of the positioning.
- // Cache the intermediate results so we don't have to calculate from the beginning of
- // the segment every time.
- int m_islotPosNext; // where to continue calculating positions in final output stream
- // (one past the last base that was calculated)
- float m_xsPosXNext;
- float m_ysPosYNext;
- float m_dxsTotWidthSoFar;
- float m_dxsVisWidthSoFar;
-
- int m_cpass; // number of passes
-
- // array of pass-state objects
- PassState * m_prgzpst;
-
- // array of slot streams which are output of passes (input of zeroth
- // pass is the character stream, not a slot stream):
- GrSlotStream ** m_prgpsstrm;
- // For instance, a simple set of passes might look like this:
- // CharStream
- // GlyphGenPass pass 0
- // SlotStream stream 0
- // SubPass pass 1
- // SlotStream stream 1
- // PosPass pass 2
- // SlotStream stream 2
- //
- // m_cpass = 3
-
-}; // end of class EngineState
-
-/*----------------------------------------------------------------------------------------------
- There is a single instance of GrTableManager that handle the interactions between
- passes, including the demand-pull mechanism.
-
- Hungarian: tman
-----------------------------------------------------------------------------------------------*/
-
-class GrTableManager {
- friend class FontMemoryUsage;
-
-public:
- // Constructor & destructor:
- GrTableManager(GrEngine * pgreng)
- : m_cpass(0),
- m_fBidi(false),
- m_prgppass(NULL),
- m_pgreng(pgreng)
- {
- Assert(pgreng);
- }
-
- ~GrTableManager();
-
- bool CreateAndReadPasses(GrIStream & grstrm, int fxdSilfVersion, int fxdRuleVersion,
- int cpassFont, long lSubTableStart, int * rgnPassOffsets,
- int ipassSub1Font, int ipassPos1Font, int ipassJust1Font, byte ipassPostBidiFont);
-
- void CreateEmpty();
-
- GrEngine * Engine();
- EngineState * State();
-
- void Run(Segment * psegNew, Font * pfont, GrCharStream * pchstrm,
- IGrJustifier * pgjus, int jmodi,
- LayoutEnvironment & layout,
- int ichStop, float dxWidth, float dxUnjustified,
- bool fNeedFinalBreak, bool fMoreText, int ichFontLim,
- bool fInfiniteWidth, bool fWidthIsCharCount,
- int ichwCallerBtLim,
- int nDirDepth, SegEnd estJ);
-
- GrPass* Pass(int ipass)
- {
- Assert(ipass >= 0);
- return m_prgppass[ipass];
- }
-
- int NumberOfPasses()
- {
- return m_cpass;
- }
-
- int NumberOfLbPasses()
- {
- return m_cpassLB;
- }
-
- bool HasBidiPass()
- {
- return m_fBidi;
- }
-
- int FirstPosPass()
- {
- return m_ipassPos1;
- }
-
- void StorePassStates(PassState * rgzpst);
-
- // Return the stream that serves as input to the given pass.
- GrSlotStream * InputStream(int ipass)
- {
- return m_engst.InputStream(ipass);
- }
- GrSlotStream * OutputStream(int ipass)
- {
- return m_engst.OutputStream(ipass);
- }
-
- void UnwindAndReinit(int islotNewBreak);
-
-public:
- int InternalJustificationMode()
- {
- return m_engst.m_jmodi;
- }
-
- bool ShouldLogJustification()
- {
- return (m_engst.m_jmodi != kjmodiNormal);
- }
-
- int PrevPassMaxBackup(int ipass)
- {
- if (ipass == 0)
- return 0;
- return Pass(ipass - 1)->MaxBackup();
- }
-
- // Forward to the engine itself
- gid16 GetGlyphIDFromUnicode(int nUnicode);
- gid16 ActualGlyphForOutput(utf16 chwGlyphID);
- GrGlyphTable * GlyphTable();
-
- gid16 LBGlyphID();
-
- gid16 GetClassGlyphIDAt(int nClass, int nIndex);
- int GetIndexInGlyphClass(int nClass, gid16 chwGlyphID);
- size_t NumberOfGlyphsInClass(int nClass);
-
- void SetSlotAttrsFromGlyphAttrs(GrSlotState * pslot);
-
- int NumFeat();
- int DefaultForFeatureAt(int ifeat);
- GrFeature * FeatureWithID(featid nID, int * pifeat);
- GrFeature * Feature(int ifeat);
- void DefaultsForLanguage(isocode lgcode,
- std::vector<featid> & vnFeats, std::vector<int> & vnValues);
-
- bool RightToLeft();
- int TopDirectionLevel();
-
- float VerticalOffset();
-
- int NumUserDefn();
- int NumCompPerLig();
-
- int ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID);
- int GlyphAttrValue(gid16 chwGlyphID, int nAttrID);
-
- // ---
-
- bool LoggingTransduction();
-
- float EmToLogUnits(int m);
- int LogToEmUnits(float xys);
- bool GPointToXY(gid16 chwGlyphID, int nGPoint, float * xs, float * ys);
-
- void CalcPositionsUpTo(int ipass, GrSlotState * pslotLast,
- float * pxsWidth, float * pxsVisibleWidth);
-
- void InitPosCache()
- {
- m_engst.InitPosCache();
- }
-
- bool IsWhiteSpace(GrSlotState * pslot);
-
- // For transduction logging:
- bool WriteTransductionLog(std::ostream * pstrmLog,
- GrCharStream * pchstrm, Segment * psegRet, int cbPrevSetDat, byte * pbPrevSegDat);
- bool WriteAssociationLog(std::ostream * pstrmLog,
- GrCharStream * pchstrm, Segment * psegRet);
- bool WriteXmlLog(std::ostream * pstrmLog,
- GrCharStream * pchstrm, Segment * psegRet, int cbPrevSegDat, byte * pbPrevSegDat);
- bool WriteXmlAssocLog(std::ostream * pstrmLog,
- GrCharStream * pchstrm, Segment * psegRet);
-
-#ifdef TRACING
- void WriteXductnLog(std::ostream & strmOut, GrCharStream * pchstrm, Segment * psegRet,
- int cbPrevSegDat, byte * pbPrevSegDat);
- //bool LogFileName(std::string & staFile);
- void LogUnderlying(std::ostream & strmOut, GrCharStream * pchstrm, int cchwBackup);
- void LogPass1Input(std::ostream & strmOut);
- void LogPassOutput(std::ostream & strmOut, int ipass, int cslotSkipped);
- void LogAttributes(std::ostream & strmOut, int ipass, bool fJustWidths = false);
- void LogFinalPositions(std::ostream & strmOut);
- void LogUnderlyingHeader(std::ostream & strmOut, int ichwMin,
- int ichwLim, int cchwBackup, int * prgichw16bit);
- void LogSlotHeader(std::ostream & strmOut, int cslot,
- int cspPerSlot, int cspLeading, int islotMin = 0);
- void LogSlotGlyphs(std::ostream & strmOut, GrSlotStream * psstrm);
- void SlotAttrsModified(int ipass, bool * rgfMods, bool fPreJust, int * pccomp, int *pcassoc);
- void LogInTable(std::ostream & strmOut, int n);
- void LogInTable(std::ostream & strmOut, float n);
- void LogHexInTable(std::ostream & strmOut, gid16 chw, bool fPlus = false);
- void LogDirCodeInTable(std::ostream & strmOut, int dirc);
- void LogBreakWeightInTable(std::ostream & strmOut, int lb);
-
- void WriteXmlLogAux(std::ostream & strmOut,
- GrCharStream * pchstrm, Segment * psegRet, int cbPrevSegDat, byte * pbPrevSegDat);
- void LogXmlUnderlying(std::ostream & strmOut, GrCharStream * pchstrm, int cchwBackup, size_t nIndent);
- void LogXmlUnderlyingAux(std::ostream & strmOut, GrCharStream * pchstrm,
- int cch32Backup, int cch32Lim, size_t nIndent,
- bool fLogText, bool fLogFeatures, bool fLogColor, bool fLogStrOff, bool fLogLig, bool fLogGlyphs);
- void LogXmlPass(std::ostream & strmOut, int ipass, int cslotSkipped, int nIndent);
-
- void LogXmlTagOpen(std::ostream & strmOut, std::string strTag, size_t nIndent, bool fContent);
- void LogXmlTagPostAttrs(std::ostream & strmOut, bool fContent);
- void LogXmlTagClose(std::ostream & strmOut, std::string strTag, size_t nIndent, bool fContent);
- void LogXmlTagAttr(std::ostream & strmOut, std::string strAttr, int nValue, size_t nIndent = 0);
- void LogXmlTagAttr(std::ostream & strmOut, std::string strAttr, const char * szValue, size_t nIndent = 0);
- void LogXmlTagAttrHex(std::ostream & strmOut, std::string strAttr, int nValue, size_t nIndent = 0);
- std::string HexString(int n1, int n2, int n3, int n4, int n5, int n6);
- std::string HexString(std::vector<int>);
- void LogXmlTagColor(std::ostream & strmOut, std::string strAttr, int clrValue, bool fBack,
- size_t nIndent = 0);
- void LogXmlDirCode(std::ostream & strmOut, std::string strAttr, int dircValue, size_t nIndent = 0);
- void LogXmlBreakWeight(std::ostream & strmOut, std::string strAttr, int dircValue,
- size_t nIndent = 0);
- void LogXmlComment(std::ostream & strmOut, std::string strComment, size_t nIndent = 0);
-
-#endif // TRACING
-
-protected:
- void InitNewSegment(Segment * psegNew, Font * pfont, GrCharStream * pchstrm, IGrJustifier * pgjus,
- int islotStream0Break, int islotSurfaceBreak, bool fStartLine, bool fEndLine, int ichFontLim,
- LineBrk lbEnd, SegEnd est, int * dichSegLen);
-
- void InitSegmentAsEmpty(Segment * psegNew, Font * pfont, GrCharStream * pchstrm,
- bool fStartLine, bool fEndLine);
-
- void InitSegmentToDelete(Segment * psegNew, Font * pfont, GrCharStream * pchstrm);
-
- int ChunkInPrev(int ipass, int islot, GrCharStream * pchstrm);
-
- bool Backtrack(int * islotPrevLB,
- LineBrk * plbPref, LineBrk lbMax, TrWsHandling, bool fMoreText,
- int ichwCallerBtLim, LineBrk * plbFound);
-
- LineBrk IncLineBreak(LineBrk lb);
-
- void InitializeForNextSeg(Segment* pseg,
- int islotStream0Break, int islotSurfaceBreak, LineBrk lbEnd,
- bool fNextSegNeedsContext, GrCharStream * pchstrm);
-
- void SetFinalPositions(Segment * pseg, bool fWidthIsCharCount);
- void RecordAssocsAndOutput(Font * pfont, Segment * pseg,
- TrWsHandling twsh, bool fParaRtl, int nDirDepth);
-
- void CalculateAssociations(Segment * pseg, int csloutSurface);
- void AdjustAssocsForOverlaps(Segment * pseg);
-
- void UnstretchTrailingWs(GrSlotStream * psstrm, int iGlyphLim);
- void CallJustifier(IGrJustifier * pgjus, int ipassCurr, float dxUnjustified, float dxJustified,
- bool fEndLine);
-
- void DetermineShrink(IGrJustifier * pgjus, int ipass);
-
-protected:
- // Instance variables:
-
- int m_cpass; // number of passes; zero-th pass is Unicode character -> glyph ID mapping;
- // Note thatwe always have one positioning pass to measure things even
- // if there are no tables to run.
-
- int m_cpassLB; // number of line-break passes
- int m_ipassPos1; // first positioning pass
- int m_ipassJust1; // first justification pass (== m_ipassPos1 if none)
-
- bool m_fBidi; // is there a bidi pass?
-
- // array of passes:
- GrPass ** m_prgppass;
-
- // Pointer back to Graphite engine, to give access to global constants and tables.
- GrEngine * m_pgreng;
-
- // State of processing.
- EngineState m_engst;
-
- bool m_fLogging;
-
-public:
- // For test procedures:
- void SetUpTest(std::wstring);
-
-protected:
- void TempDebug();
- int SurfaceLineBreakSlot(int ichw, GrCharStream * pchstrm, bool fInitial);
- std::wstring ChunkDebugString(int ipass);
-}; // end of class GrTableManager
-
-} // namespace gr
-
-
-#endif // !GR_TABLEMAN_INCLUDED
diff --git a/Build/source/libs/graphite-engine/src/segment/Main.h b/Build/source/libs/graphite-engine/src/segment/Main.h
deleted file mode 100644
index da95af09ce8..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/Main.h
+++ /dev/null
@@ -1,181 +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: Main.h
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Main.header file for the Graphite engine.
-----------------------------------------------------------------------------------------------*/
-#ifdef _MSC_VER
-#pragma once
-#endif
-#ifndef GRAPHITE_H
-#define GRAPHITE_H 1
-
-//:End Ignore
-
-#define NO_EXCEPTIONS 1
-
-// It's okay to use functions that were declared deprecated by VS 2005:
-#ifdef _MSC_VER
-#define _CRT_SECURE_NO_DEPRECATE
-#pragma warning(disable: 4996) // warning: function was declared deprecated
-#pragma warning(disable: 4702) // unreachable code
-#endif
-
-#include "GrCommon.h"
-
-//:>********************************************************************************************
-//:> Interfaces.
-//:>********************************************************************************************
-#include "GrData.h"
-
-//:>********************************************************************************************
-//:> Implementations.
-//:>********************************************************************************************
-
-#ifndef _WIN32
-#include "GrMstypes.h"
-#ifndef HAVE_FABSF
-float fabsf(float x);
-#endif
-#endif
-#include "GrDebug.h"
-
-// For reading the font (FieldWorks's approach) and transduction logging:
-#include <fstream>
-#include <iostream>
-
-#include <vector>
-////#include <algorithm>
-#include <string>
-
-// gAssert should be used for any kind of assertions that can be caused by a corrupted font,
-// particularly those that won't be caught when loading the tables.
-#define gAssert(x) Assert(x)
-// When testing the error mechanism (because the process of bringing up the assertion dialog
-// interferes with FW repainting the invalid window:
-////#define gAssert(x) if (!(x)) Warn("corrupted font?")
-
-// Internal headers.
-#include "FileInput.h"
-
-// Public headers.
-#include "GrResult.h"
-//////#include "IGrGraphics.h"
-#include "ITextSource.h"
-#include "IGrJustifier.h"
-#include "IGrEngine.h"
-#include "GrConstants.h"
-#include "GrFeature.h"
-
-// External helper classes.
-#include "GrExt.h"
-
-
-// Forward declarations.
-namespace gr
-{
- class GrTableManager;
- class Segment;
- class GrEngine;
-}
-
-// Define after GrExt.h to avoid conflict with FW Rect class.
-namespace gr
-{
-/*
-struct Point
-{
- float x;
- float y;
-
- Point()
- {
- x = y = 0;
- }
-
- Point(POINT & p)
- {
- x = (float)p.x;
- y = (float)p.y;
- }
-};
-
-
-struct Rect
-{
- float top;
- float bottom;
- float left;
- float right;
-
- Rect()
- {
- top = bottom = left = right = 0;
- };
-
- Rect(RECT & r)
- {
- top = (float)r.top;
- bottom = (float)r.bottom;
- left = (float)r.left;
- right = (float)r.right;
- };
-};
-*/
-}; // namespace gr
-
-#include "GrFeatureValues.h"
-#include "GrSlotState.h"
-
-#include "SegmentAux.h"
-
-// Internal headers
-#include "GrCharStream.h"
-#include "GrGlyphTable.h"
-#include "GrClassTable.h"
-#include "GrPseudoMap.h"
-#include "GrSlotStream.h"
-#include "GrFSM.h"
-#include "GrPass.h"
-#include "GrTableManager.h"
-#include "FontCache.h"
-
-
-// Public headers
-#include "Font.h"
-#include "GraphiteProcess.h"
-#include "GrEngine.h"
-#include "FontFace.h"
-#include "Segment.h"
-#include "SegmentPainter.h"
-
-//#ifdef _WIN32
-//#include <hash_map>
-//#include "WinFont.h"
-//#include "WinSegmentPainter.h"
-//#endif
-
-// Internal headers
-#include "TtfUtil.h"
-//#include "GrUtil.h"
-
-#include "GrWrappers.h"
-
-//#include "IGrDebug.h"
-//#include "GrSegmentDebug.h"
-//#include "GrEngineDebug.h"
-
-/////<<<<<<< .mine
-// clashes with non gr stuff
-// using namespace gr;
-///////>>>>>>> .r98
-
-#endif // GRAPHITE_H
-
diff --git a/Build/source/libs/graphite-engine/src/segment/Makefile.am b/Build/source/libs/graphite-engine/src/segment/Makefile.am
deleted file mode 100644
index 59113aa924b..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-segmentdir = $(top_srcdir)/src/segment
-
-libgraphite_la_SOURCES += $(segmentdir)/FileInput.cpp
-libgraphite_la_SOURCES += $(segmentdir)/FontCache.cpp
-libgraphite_la_SOURCES += $(segmentdir)/FontFace.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrCharStream.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrClassTable.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrEngine.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrFeature.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrFSM.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrGlyphTable.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrPassActionCode.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrPass.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrSlotState.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrSlotStream.cpp
-libgraphite_la_SOURCES += $(segmentdir)/GrTableManager.cpp
-libgraphite_la_SOURCES += $(segmentdir)/MemoryUsage.cpp
-libgraphite_la_SOURCES += $(segmentdir)/Platform.cpp
-libgraphite_la_SOURCES += $(segmentdir)/SegmentAux.cpp
-libgraphite_la_SOURCES += $(segmentdir)/Segment.cpp
-libgraphite_la_SOURCES += $(segmentdir)/TestFSM.cpp
-libgraphite_la_SOURCES += $(segmentdir)/TestPasses.cpp
-libgraphite_la_SOURCES += $(segmentdir)/TransductionLog.cpp
-
-EXTRA_DIST += $(segmentdir)/*.h
-
diff --git a/Build/source/libs/graphite-engine/src/segment/MemoryUsage.cpp b/Build/source/libs/graphite-engine/src/segment/MemoryUsage.cpp
deleted file mode 100644
index 1fb3fc25282..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/MemoryUsage.cpp
+++ /dev/null
@@ -1,781 +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: MemoryUsage.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Calculates memory usage for the engine and segments.
-----------------------------------------------------------------------------------------------*/
-
-#pragma warning(disable: 4244) // conversion from wchar_t to char
-#pragma warning(disable: 4702) // unreachable code
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-
-#include "GrCommon.h"
-#include "GrData.h"
-#ifndef _WIN32
-#include "GrMstypes.h"
-#endif
-#include "GrDebug.h"
-//#include <fstream>
-#include <iostream>
-#include <cstring>
-//#include <string>
-// Forward declarations.
-
-#include "Main.h"
-
-//namespace gr
-//{
-// class GrTableManager;
-// class Segment;
-// class GrEngine;
-//}
-//
-//#include "GrTableManager.h"
-//#include "GrFeatureValues.h"
-//#include "GrSlotState.h"
-//#include "SegmentAux.h"
-//#include "Segment.h"
-#include "MemoryUsage.h"
-
-//#ifndef _MSC_VER
-//#include "config.h"
-//#endif
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-const int stringOverhead = (3 * sizeof(int)) + (sizeof(void *)) + (8 * sizeof(short));
-const int vectorOverhead = 3 * sizeof(void *);
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Font/engine
-//:>********************************************************************************************
-
-void FontMemoryUsage::initialize()
-{
- font = 0;
- fontCache = 0;
- fontFace = 0;
-
- eng_count = 0;
- eng_overhead = 0;
- eng_scalars = 0;
- eng_strings = 0;
- eng_pointers = 0;
- eng_cmap = 0;
- eng_nameTable = 0;
-
- pseudoMap = 0;
-
- clstbl_counters = 0;
- clstbl_offsets = 0;
- clstbl_glyphList = 0;
-
- glftbl_general = 0;
- glftbl_compDefns = 0;
- glftbl_attrTable = 0;
- glftbl_attrOffsets = 0;
-
- lngtbl_general = 0;
- lngtbl_entries = 0;
- lngtbl_featureSets = 0;
-
- tman_general = 0;
-
- pass_count = 0;
- pass_general = 0;
- pass_fsm = 0;
- pass_ruleExtras = 0;
- pass_constraintOffsets = 0;
- pass_constraintCode = 0;
- pass_actionOffsets = 0;
- pass_actionCode = 0;
-
- engst_general = 0;
- engst_passState = 0;
-
- sstrm_count = 0;
- sstrm_general = 0;
- sstrm_chunkMapsUsed = 0;
- sstrm_chunkMapsAlloc = 0;
- sstrm_reprocBuf = 0;
-
- slot_count = 0;
- slot_general = 0;
- slot_abstract = 0;
- slot_varLenBuf = 0;
- slot_assocsUsed = 0;
- slot_assocsAlloc = 0;
- slot_attachUsed = 0;
- slot_attachAlloc = 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the total byte count.
-----------------------------------------------------------------------------------------------*/
-int FontMemoryUsage::total()
-{
- int grandTotal = 0;
- grandTotal += font + fontCache + fontFace;
- grandTotal += eng_overhead + eng_scalars + eng_strings + eng_pointers + eng_cmap + eng_nameTable;
- grandTotal += pseudoMap;
- grandTotal += clstbl_counters + clstbl_offsets + clstbl_glyphList;
- grandTotal += glftbl_general + glftbl_compDefns + glftbl_attrTable + glftbl_attrOffsets;
- grandTotal += lngtbl_general + lngtbl_entries + lngtbl_featureSets;
- grandTotal += tman_general;
- grandTotal += pass_general + pass_fsm + pass_ruleExtras
- + pass_constraintOffsets + pass_constraintCode + pass_actionOffsets + pass_actionCode;
- grandTotal += engst_general + engst_passState;
- grandTotal += sstrm_general + sstrm_chunkMapsAlloc + sstrm_reprocBuf;
- grandTotal += slot_general + slot_abstract + slot_varLenBuf + slot_assocsAlloc + slot_attachAlloc;
-
- return grandTotal;
-}
-
-/*----------------------------------------------------------------------------------------------
- Add the results of two runs together.
-----------------------------------------------------------------------------------------------*/
-void FontMemoryUsage::add(FontMemoryUsage & fmu)
-{
- font += fmu.font;
- fontCache += fmu.fontCache;
- fontFace += fmu.fontFace;
-
- eng_count += fmu.eng_count;
- eng_overhead += fmu.eng_overhead;
- eng_scalars += fmu.eng_scalars;
- eng_strings += fmu.eng_strings;
- eng_pointers += fmu.eng_pointers;
- eng_cmap += fmu.eng_cmap;
- eng_nameTable += fmu.eng_nameTable;
-
- pseudoMap += fmu.pseudoMap;
-
- clstbl_counters += fmu.clstbl_counters;
- clstbl_offsets += fmu.clstbl_offsets;
- clstbl_glyphList += fmu.clstbl_glyphList;
-
- glftbl_general += fmu.glftbl_general;
- glftbl_compDefns += fmu.glftbl_compDefns;
- glftbl_attrTable += fmu.glftbl_attrTable;
- glftbl_attrOffsets += fmu.glftbl_attrOffsets;
-
- lngtbl_general += fmu.lngtbl_general;
- lngtbl_entries += fmu.lngtbl_entries;
- lngtbl_featureSets += fmu.lngtbl_featureSets;
-
- tman_general += fmu.tman_general;
-
- pass_count += fmu.pass_count;
- pass_general += fmu.pass_general;
- pass_fsm += fmu.pass_fsm;
- pass_ruleExtras += fmu.pass_ruleExtras;
- pass_constraintOffsets += fmu.pass_constraintOffsets;
- pass_constraintCode += fmu.pass_constraintCode;
- pass_actionOffsets += fmu.pass_actionOffsets;
- pass_actionCode += fmu.pass_actionCode;
-
- engst_general += fmu.engst_general;
- engst_passState += fmu.engst_passState;
-
- sstrm_count += fmu.sstrm_count;
- sstrm_general += fmu.sstrm_general;
- sstrm_chunkMapsUsed += fmu.sstrm_chunkMapsUsed;
- sstrm_chunkMapsAlloc += fmu.sstrm_chunkMapsAlloc;
- sstrm_reprocBuf += fmu.sstrm_reprocBuf;
-
- slot_count += fmu.slot_count;
- slot_general += fmu.slot_general;
- slot_abstract += fmu.slot_abstract;
- slot_varLenBuf += fmu.slot_varLenBuf;
- slot_assocsUsed += fmu.slot_assocsUsed;
- slot_assocsAlloc += fmu.slot_assocsAlloc;
- slot_attachUsed += fmu.slot_attachUsed;
- slot_attachAlloc += fmu.slot_attachAlloc;
-}
-
-/*----------------------------------------------------------------------------------------------
- Add up the memory used by all the engines in the cache.
-----------------------------------------------------------------------------------------------*/
-FontMemoryUsage Font::calculateMemoryUsage()
-{
- FontMemoryUsage fmu;
- FontFace::calculateAllMemoryUsage(fmu);
- return fmu;
-}
-
-void FontFace::calculateAllMemoryUsage(FontMemoryUsage & fmu)
-{
- s_pFontCache->calculateMemoryUsage(fmu);
-}
-
-void FontCache::calculateMemoryUsage(FontMemoryUsage & fmuTotal)
-{
- fmuTotal.fontCache += sizeof(int) * 4; // m_cfci, m_cfciMax, m_cfface, m_flush
- fmuTotal.fontCache += sizeof(void*); // m_prgfci;
-
- // Iterate through all the font faces in the cache.
- for (int ifci = 0; ifci < m_cfci; ifci++)
- {
- CacheItem * pfci = m_prgfci + ifci;
- char rgchFontName[32];
- memset(rgchFontName, 0, 32 * sizeof(char));
- std::copy(pfci->szFaceName, pfci->szFaceName + 32, rgchFontName);
- std::string strFontName(rgchFontName);
- fmuTotal.vstrFontNames.push_back(strFontName);
- int cface = 0;
- if (pfci->pffaceRegular)
- {
- FontMemoryUsage fmu;
- pfci->pffaceRegular->calculateMemoryUsage(fmu);
- fmuTotal.add(fmu);
- fmuTotal.vFontTotalsReg.push_back(fmu.total());
- cface++;
- }
- else
- fmuTotal.vFontTotalsReg.push_back(0);
-
- if (pfci->pffaceBold)
- {
- FontMemoryUsage fmu;
- pfci->pffaceBold->calculateMemoryUsage(fmu);
- fmuTotal.add(fmu);
- fmuTotal.vFontTotalsBold.push_back(fmu.total());
- cface++;
- }
- else
- fmuTotal.vFontTotalsBold.push_back(0);
-
- if (pfci->pffaceItalic)
- {
- FontMemoryUsage fmu;
- pfci->pffaceItalic->calculateMemoryUsage(fmu);
- fmuTotal.add(fmu);
- fmuTotal.vFontTotalsItalic.push_back(fmu.total());
- cface++;
- }
- else
- fmuTotal.vFontTotalsItalic.push_back(0);
-
- if (pfci->pffaceBI)
- {
- FontMemoryUsage fmu;
- pfci->pffaceBI->calculateMemoryUsage(fmu);
- fmuTotal.add(fmu);
- fmuTotal.vFontTotalsBI.push_back(fmu.total());
- cface++;
- }
- else
- fmuTotal.vFontTotalsBI.push_back(0);
-
- fmuTotal.vFaceCount.push_back(cface);
- }
-}
-
-void FontFace::calculateMemoryUsage(FontMemoryUsage & fmu)
-{
- fmu.fontFace += sizeof(int); // m_cfonts
- fmu.fontFace += sizeof(void *) * 2; // s_pFontCache, m_pgreng
-
- fmu.font += m_cfonts * sizeof(void*); // m_pfface
-
- fmu.addEngine(m_pgreng);
-}
-
-void FontMemoryUsage::addEngine(GrEngine * pgreng)
-{
- eng_count++;
-
- eng_overhead += sizeof(long); // m_cref
- eng_scalars += sizeof(bool) * 6; // m_fBold, m_fItalic, m_fSmart...
- eng_scalars += sizeof(bool) * 2; // m_fFakeItalicCache, m_fFakeBICache;
- eng_strings += stringOverhead * 4; // m_strCtrlFileReg/Bold/Italic/BI
- eng_strings += sizeof(wchar_t) * pgreng->m_strCtrlFileReg.length();
- eng_strings += sizeof(wchar_t) * pgreng->m_strCtrlFileBold.length();
- eng_strings += sizeof(wchar_t) * pgreng->m_strCtrlFileItalic.length();
- eng_strings += sizeof(wchar_t) * pgreng->m_strCtrlFileBI.length();
- eng_scalars += sizeof(bool);
- eng_strings += stringOverhead * 6; // m_stuCtrlFile etc.
- eng_strings += sizeof(wchar_t) * pgreng->m_stuCtrlFile.length();
- eng_strings += sizeof(wchar_t) * pgreng->m_stuInitError.length();
- eng_strings += sizeof(wchar_t) * pgreng->m_stuFaceName.length();
- eng_strings += sizeof(wchar_t) * pgreng->m_stuFeatures.length();
- eng_strings += sizeof(wchar_t) * pgreng->m_stuBaseFaceName.length();
- eng_scalars += sizeof(bool); // m_fUseSepBase
- eng_scalars += sizeof(GrResult) * 2; // m_resFontRead, m_resFontValid
- eng_scalars += sizeof(FontErrorCode);
- eng_scalars += sizeof(int) * 3; // m_fxdBadVersion, m_nFontCheckSum, m_nScriptTag, m_grfsdc
- eng_scalars += sizeof(bool); // m_fRightToLeft
- eng_scalars += sizeof(int) * 2; // m_mXAscent, m_mXDescent
- eng_scalars += sizeof(float); // m_dysOffset
- eng_scalars += sizeof(bool); // m_fBasicJust
- eng_scalars += sizeof(int); // m_cJLevels
- eng_pointers += sizeof(void*) * 4; // m_ptman, m_pctbl, m_pgtbl, m_pfface
- eng_scalars += sizeof(GrFeature) * kMaxFeatures;
- eng_scalars += sizeof(int); // m_cfeat
- eng_scalars += sizeof(size_t); // m_clcidFeatLabelLangs
- eng_scalars += sizeof(short) * pgreng->m_clcidFeatLabelLangs;
- // m_langtbl
- eng_scalars += sizeof(bool); // m_fLineBreak
- eng_scalars += sizeof(int) * 2; // m_cchwPreXlbContext, m_cchwPostXlbContext
- eng_scalars += sizeof(data16) * 7; // m_chwPseudoAttr, etc.
- eng_scalars += sizeof(gid16); // m_chwLBGlyphID
- eng_scalars += sizeof(int) * 4; // m_cComponents, m_cnUserDefn, m_cnCompPerLig, m_mFontEmUnits
-
- pseudoMap += sizeof(int) * 3;
- pseudoMap += sizeof(GrPseudoMap) * pgreng->m_cpsd;
-
- eng_cmap += sizeof(void*) * 2;
- eng_cmap += sizeof(byte*);
- eng_cmap += sizeof(bool);
- if (pgreng->m_fCmapTblCopy)
- eng_cmap += pgreng->m_cbCmapTbl;
-
- eng_nameTable += sizeof(byte *);
- eng_nameTable += sizeof(bool);
- if (pgreng->m_fNameTblCopy)
- eng_nameTable += pgreng->m_cbNameTbl;
-
- eng_scalars += sizeof(bool) * 2; // m_fLogXductn, m_fInErrorState
-
- clstbl_counters += sizeof(int) * 2; // m_ccls, m_cclsLinear
- clstbl_offsets += sizeof(data16) * (pgreng->m_pctbl->m_ccls + 1);
- clstbl_glyphList += sizeof(data16) * (pgreng->m_pctbl->m_prgichwOffsets[pgreng->m_pctbl->m_ccls]);
-
- glftbl_general += sizeof(int) * 3; // m_cglf, m_cComponents, m_cgstbl
- glftbl_general += vectorOverhead; // m_vpgstbl
- GrGlyphSubTable * pgstbl = pgreng->m_pgtbl->m_vpgstbl[0];
- glftbl_general += sizeof(int) * 4; // m_fxdSilfVersion, m_nAttrIDLim, m_cComponents, m_cnCompPerLig
- glftbl_general += sizeof(bool) * 2; // m_fHasDebugStrings, m_fGlocShort
- glftbl_general += sizeof(data16) * 3; // m_chw...Attr
- glftbl_compDefns += sizeof(int) * (pgstbl->m_cnCompPerLig + 1) * pgreng->m_pgtbl->m_cglf;
- glftbl_attrTable += sizeof(int) * 2; // m_fxdSilfVersion, m_cbEntryBufLen
- glftbl_attrTable += sizeof(byte) * pgstbl->m_pgatbl->m_cbEntryBufLen;
- glftbl_attrOffsets +=
- (pgreng->m_pgtbl->m_cglf + 1) * ((pgstbl->m_fGlocShort) ? sizeof(data16) : sizeof(data32));
-
- lngtbl_general += sizeof(size_t); // m_clang
- lngtbl_general += sizeof(data16) * 3; // m_dilangInit, m_cLoop, m_ilangStart
- lngtbl_general += sizeof(void*) * 2; // m_prglang, m_prgfset
- lngtbl_general += sizeof(int); // m_cbOffset0
- lngtbl_entries += sizeof(GrLangTable::LangEntry) * pgreng->m_langtbl.m_clang;
- lngtbl_featureSets += sizeof(GrLangTable::FeatSet) * pgreng->m_langtbl.m_cfset;
-
- GrTableManager * ptman = pgreng->m_ptman;
- tman_general += sizeof(int) * 4; // m_cpass, m_cpassLB, m_ipassPos1, m_ipassJust1
- tman_general += sizeof(bool); // m_fBidi
- tman_general += sizeof(void*) * 2; // m_prgppass, m_pgreng
- tman_general += sizeof(void*) * ptman->m_cpass; // m_prgppass
- tman_general += sizeof(bool); // m_fLogging
-
- pass_count += ptman->m_cpass;
- for (int ipass = 0; ipass < ptman->m_cpass; ipass++)
- {
- GrPass * ppass = ptman->m_prgppass[ipass];
- pass_general = sizeof(GrPass);
-
- GrFSM * pfsm = ppass->m_pfsm;
- if (pfsm)
- {
- pass_fsm += sizeof(int) * 5; // m_crow, m_crowFinal, m_rowFinalMin, m_crowNonAcpt, m_ccol
- pass_fsm += sizeof(void*) * 3; // m_prgirulnMin, m_prgrulnMatched, m_prgrowTransitions
- int crowSuccess = pfsm->m_crow - pfsm->m_crowNonAcpt;
- pass_fsm += sizeof(data16) * (crowSuccess + 1); // m_prgirulnMin
- pass_fsm += sizeof(data16) * (pfsm->m_crulnMatched); // m_prgrulnMatched
- pass_fsm += sizeof(short) * ((pfsm->m_crow - pfsm->m_crowFinal) * pfsm->m_ccol);
- pass_fsm += sizeof(data16); // m_dimcrInit, m_cLoop, m_imcrStart
- pass_fsm += sizeof(int); // m_cmcr
- pass_fsm += sizeof(void*); // m_prgmcr
- pass_fsm += sizeof(GrFSMClassRange) * pfsm->m_cmcr;
- pass_fsm += sizeof(int) * 2; // m_critMinRulePreContext, m_critMaxRulePreContext
- pass_fsm += sizeof(void*); // m_prgrowStartStates
- pass_fsm += sizeof(short) * (pfsm->m_critMaxRulePreContext - pfsm->m_critMinRulePreContext + 1);
- }
-
- pass_ruleExtras = sizeof(data16) * ppass->m_crul; // m_prgchwRuleSortKeys
- pass_ruleExtras = sizeof(byte*) * ppass->m_crul; // m_prgcritRulePreModContext
-
- pass_constraintOffsets += sizeof(data16) * (ppass->m_crul + 1);
- pass_actionOffsets =+ sizeof(data16) * (ppass->m_crul + 1);
-
- pass_constraintCode += sizeof(byte) * ppass->m_cbConstraints;
- pass_actionCode += sizeof(byte) * ppass->m_cbActions;
-
- pass_general += sizeof(bool) * ppass->m_crul; // m_prgfRuleOkay
- pass_general += vectorOverhead; // m_vnStack
- pass_general += sizeof(int) * ppass->m_vnStack.capacity();
- }
-
- engst_general += sizeof(EngineState);
- engst_general += sizeof(void *) * ptman->m_engst.m_vslotblk.capacity();
- engst_general += sizeof(void *) * ptman->m_engst.m_vprgnSlotVarLenBufs.capacity();
- engst_general += sizeof(void *) * ptman->m_engst.m_cpass; // m_prgpsstrm
-
- engst_passState += sizeof(PassState) * ptman->m_engst.m_cpass;
-
- for (int isstrm = 0; isstrm < ptman->m_engst.m_cpass; isstrm++)
- {
- sstrm_count++;
- GrSlotStream * psstrm = ptman->m_engst.m_prgpsstrm[isstrm];
- sstrm_general += sizeof(GrSlotStream);
- sstrm_chunkMapsUsed += psstrm->m_vislotPrevChunkMap.size();
- sstrm_chunkMapsUsed += psstrm->m_vislotPrevChunkMap.size();
- sstrm_chunkMapsAlloc += psstrm->m_vislotPrevChunkMap.capacity();
- sstrm_chunkMapsAlloc += psstrm->m_vislotNextChunkMap.capacity();
- sstrm_reprocBuf += psstrm->m_vpslotReproc.capacity();
- sstrm_reprocBuf += sizeof(int) * 2;
- sstrm_general -= sizeof(int) * 2;
- }
-
- slot_general += ptman->m_engst.m_vslotblk.size() * EngineState::kSlotBlockSize
- * (sizeof(GrSlotState) - sizeof(GrSlotAbstract));
- slot_abstract += ptman->m_engst.m_vslotblk.size() * EngineState::kSlotBlockSize
- * sizeof(GrSlotAbstract);
- int cnExtraPerSlot = ptman->m_engst.m_cUserDefn + (ptman->m_engst.m_cCompPerLig * 2)
- + ptman->m_engst.m_cFeat;
- slot_varLenBuf += EngineState::kSlotBlockSize * cnExtraPerSlot * sizeof(u_intslot);
- for (size_t islotblk = 0; islotblk < ptman->m_engst.m_vslotblk.size(); islotblk++)
- {
- for (int islot = 0; islot < EngineState::kSlotBlockSize; islot++)
- {
- slot_count++;
- GrSlotState * pslot = ptman->m_engst.m_vslotblk[islotblk] + islot;
- slot_assocsUsed += pslot->m_vpslotAssoc.size();
- slot_assocsAlloc += pslot->m_vpslotAssoc.capacity();
- slot_attachUsed += pslot->m_vdislotAttLeaves.size();
- slot_attachAlloc += pslot->m_vdislotAttLeaves.capacity();
- }
- }
-
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out the memory usage onto a stream.
-----------------------------------------------------------------------------------------------*/
-void FontMemoryUsage::prettyPrint(std::ostream & strm)
-{
- int totalBytes = total();
-
- strm << "Number of engines: " << eng_count << "\n";
- strm << "Number of passes: " << pass_count << "\n\n";
-
- strm << "Number of slot streams: " << sstrm_count << "\n";
- strm << "Number of slots: " << slot_count << "\n\n";
-
- int classTableTotal = clstbl_counters + clstbl_offsets + clstbl_glyphList;
- int glyphTableTotal = glftbl_general + glftbl_compDefns + glftbl_attrTable + glftbl_attrOffsets;
- int langTableTotal = lngtbl_general + lngtbl_entries + lngtbl_featureSets;
- int passTotal = pass_general + pass_fsm + pass_ruleExtras + pass_constraintOffsets + pass_constraintCode
- + pass_actionOffsets + pass_actionCode;
- int engineTotal = eng_overhead + eng_scalars + eng_strings + eng_pointers + eng_cmap + eng_nameTable
- + pseudoMap + classTableTotal + glyphTableTotal + langTableTotal + tman_general
- + passTotal;
-
- strm << "BYTE COUNT TOTALS\n";
- strm << "Font: " << font << "\n";
- strm << "Font cache: " << fontCache << "\n";
- strm << "Font face: " << fontFace << "\n";
- strm << "Engine " << engineTotal << "\n";
- strm << " Overhead: " << eng_overhead << "\n";
- strm << " Scalars: " << eng_scalars << "\n";
- strm << " Strings: " << eng_strings << "\n";
- strm << " Pointers: " << eng_pointers << "\n";
- strm << " Cmap table: " << eng_cmap << "\n";
- strm << " Name table: " << eng_nameTable << "\n";
- strm << " Pseudo map: " << pseudoMap << "\n";
- strm << " Class table: " << classTableTotal << "\n";
- strm << " Counters: " << clstbl_counters << "\n";
- strm << " Offsets: " << clstbl_offsets << "\n";
- strm << " Glyph list: " << clstbl_glyphList << "\n";
- strm << " Glyph table: " << glyphTableTotal << "\n";
- strm << " General: " << glftbl_general << "\n";
- strm << " Component defns: " << glftbl_compDefns << "\n";
- strm << " Attr table: " << glftbl_attrTable << "\n";
- strm << " Attr offsets: " << glftbl_attrOffsets << "\n";
- strm << " Language table: " << langTableTotal << "\n";
- strm << " General: " << lngtbl_general << "\n";
- strm << " Entries: " << lngtbl_entries << "\n";
- strm << " Feature sets: " << lngtbl_featureSets << "\n";
- strm << " Table manager: " << tman_general << "\n";
- strm << " Passes: " << passTotal << "\n";
- strm << " General: " << pass_general << "\n";
- strm << " FSM: " << pass_fsm << "\n";
- strm << " Rule extras: " << pass_ruleExtras << "\n";
- strm << " Constraint offsets: " << pass_constraintOffsets << "\n\n";
- strm << " Constraint code: " << pass_constraintCode << "\n";
- strm << " Action offsets: " << pass_actionOffsets << "\n";
- strm << " Action code: " << pass_actionCode << "\n\n";
-
- int slotTotal = slot_general + slot_abstract + slot_varLenBuf + slot_assocsAlloc + slot_attachAlloc;
- int streamTotal = sstrm_general + sstrm_chunkMapsAlloc + sstrm_reprocBuf + slotTotal;
- int engineStateTotal = engst_general + engst_passState + streamTotal;
-
- strm << " Engine State: " << engineStateTotal << "\n";
- strm << " General: " << engst_general << "\n";
- strm << " Pass states: " << engst_passState << "\n";
- strm << " Slot streams: " << streamTotal << "\n";
- strm << " General: " << sstrm_general << "\n";
- strm << " Chunk maps: " << sstrm_chunkMapsAlloc << " (" << sstrm_chunkMapsUsed << " used)\n";
- strm << " Reprocess buffer: " << sstrm_reprocBuf << "\n";
- strm << " Slots: " << slotTotal << "\n";
- strm << " General: " << slot_general << "\n";
- strm << " Abstract: " << slot_abstract << "\n";
- strm << " Var-length buf: " << slot_varLenBuf << "\n";
- strm << " Associations: " << slot_assocsAlloc << " (" << slot_assocsUsed << " used)\n";
- strm << " Attachments: " << slot_attachAlloc << " (" << slot_attachUsed << " used)\n\n";
-
- strm << "Total bytes used: " << totalBytes << "\n\n";
-
- strm << "TOTALS PER FONT\n";
- for (size_t ifont = 0; ifont < vstrFontNames.size(); ifont++)
- {
- strm << vstrFontNames[ifont].c_str() << "\n";
- strm << " Regular: " << vFontTotalsReg[ifont] << "\n";
- strm << " Bold: " << vFontTotalsBold[ifont] << "\n";
- strm << " Italic: " << vFontTotalsItalic[ifont] << "\n";
- strm << " Bold-italic: " << vFontTotalsBI[ifont] << "\n\n";
- }
-}
-
-
-//:>********************************************************************************************
-//:> Segment
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Initialize the data structure.
-----------------------------------------------------------------------------------------------*/
-void SegmentMemoryUsage::initialize()
-{
- seg_count = 0;
- overhead = 0;
- pointers = 0;
- scalars = 0;
- strings = 0;
- metrics = 0;
- associations = 0;
- init = 0;
- obsolete = 0;
-
- slot_count = 0;
- slot_abstract = 0;
- slot_varLenBuf = 0;
- slot_scalars = 0;
- slot_clusterMembers = 0;
-
- glyphInfo_count = 0;
- glyphInfo = 0;
-
- wastedVector = 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Add the memory for the segemtn to the SegmentMemoryUsage data structure.
-----------------------------------------------------------------------------------------------*/
-void Segment::calculateMemoryUsage(SegmentMemoryUsage & smu)
-{
- smu.addSegment(*this);
-}
-
-
-void SegmentMemoryUsage::addSegment(Segment & seg)
-{
- seg_count++;
-
- overhead += sizeof(long); // m_cref
- pointers += sizeof(void*); // m_pgts
- scalars += sizeof(int); // m_dichwLim
- scalars += sizeof(int); // m_ichwMin
- pointers += sizeof(void*); // m_pfont
- pointers += sizeof(void*); // m_preneng
- scalars += sizeof(bool); // m_fErroneous
- pointers += sizeof(void*); // m_pgjus
- scalars += sizeof(LayoutEnvironment);
- scalars += sizeof(bool); // m_fWsRtl
- scalars += sizeof(bool); // m_fParaRtl
- scalars += sizeof(TrWsHandling);
- scalars += sizeof(int); // m_nDirDepth
- init += sizeof(byte*); // m_prgbNextSegDat
- init += sizeof(int); // m_cbNextSegDat
- init += sizeof(byte) * seg.m_cbNextSegDat;
- init += sizeof(byte*); // m_prgInitDat
- init += sizeof(int); // m_cbInitDat
- init += sizeof(byte) * seg.m_cbInitDat;
- init += sizeof(int); // m_dichPreContext
-// obsolete += sizeof(void *); // m_psegPrev
-// obsolete += sizeof(void *); // m_psegNext
-// strings += stringOverhead * 2;
-// strings += sizeof(wchar_t) * seg.m_stuFaceName.length();
-// strings += sizeof(wchar_t) * seg.m_stuBaseFaceName.length();
-// scalars += sizeof(bool); // m_fUseSepBase;
-// scalars += sizeof(float); // m_pixHeight
-// scalars += sizeof(bool); // m_fBold
-// scalars += sizeof(bool); // m_fItalic
- scalars += sizeof(LineBrk); // m_lbStart
- scalars += sizeof(LineBrk); // m_lbEnd
- scalars += sizeof(bool); // m_fStartLine
- scalars += sizeof(bool); // m_fEndLine
- scalars += sizeof(SegEnd); // m_est
- metrics += sizeof(int); // m_mFontEmUnits
- metrics += sizeof(float) * 17; // was 19, removed m_x/ysDPI
- associations += sizeof(int); // m_ichwAssocsMin
- associations += sizeof(int); // m_ichwAssocsLim
- int dichw = seg.m_ichwAssocsLim - seg.m_ichwAssocsMin;
- associations += sizeof(int*); // m_prgisloutBefore
- associations += sizeof(int) * dichw;
- associations += sizeof(int*); // m_prgisloutAfter
- associations += sizeof(int) * dichw;
- associations += sizeof(void*); // m_prgpvisloutAssocs
- associations += sizeof(void*) * dichw;
- for (int idichw = 0; idichw < dichw; idichw++)
- {
- std::vector<int> * pvisloutAssocs = seg.m_prgpvisloutAssocs[idichw];
- if (pvisloutAssocs)
- {
- associations += vectorOverhead;
- associations += sizeof(int) * pvisloutAssocs->capacity();
- wastedVector += sizeof(int) * (pvisloutAssocs->capacity() - pvisloutAssocs->size());
- }
- }
- associations += sizeof(int*); // m_prgisloutLigature
- associations += sizeof(int) * dichw;
- associations += sizeof(sdata8*); // m_prgiComponent
- associations += sizeof(sdata8) * dichw;
-// obsolete += sizeof(void*); // m_psstrm
- scalars += sizeof(int); // m_cslout
- slot_count += seg.m_cslout;
- for (int islout = 0; islout < seg.m_cslout; islout++)
- {
- GrSlotOutput * pslout = seg.m_prgslout + islout;
- slot_abstract += sizeof(gid16) * 2; // m_chwGlyphID, m_chwActual
- slot_abstract += sizeof(sdata8) * 4; // m_spsl, m_dirc, m_lb, m_nDirLevel
-// slot_abstract += sizeof(float) * 8; // font/glyph metrics
- slot_abstract += sizeof(short) * 5; // slot attributes - was 21
- slot_abstract += sizeof(int); // m_mJWidth0;
- slot_abstract += sizeof(byte); // m_nJWeight0;
- slot_abstract += sizeof(bool); // m_fInsertBefore
- slot_abstract += sizeof(sdata8); // m_bIsSpace
- slot_abstract += sizeof(byte); // m_cnCompPerLig
- slot_abstract += sizeof(void*); // m_prgnVarLenBuf
- slot_varLenBuf += pslout->CExtraSpaceSlout() * sizeof(u_intslot);
- slot_abstract += sizeof(float); // m_xsPositionX, m_ysPositionY
-// slot_abstract += sizeof(bool); // m_fAdvXSet, m_fAdvYSet
- slot_scalars += sizeof(int) * 2; // m_ichwBefore/AfterAssoc
- slot_scalars += sizeof(sdata8); // m_cComponents
- slot_scalars += sizeof(int); // m_isloutClusterBase
- slot_scalars += sizeof(sdata8); // m_disloutCluster
- slot_scalars += sizeof(float) * 3; // m_xsClusterXOffset, m_xsClusterAdvance, m_xsAdvanceX
- slot_scalars += sizeof(int); // m_igbb
-// slot_scalars += sizeof(Rect); // m_rectBB
- }
- scalars += sizeof(int); // m_cnUserDefn
- scalars += sizeof(int); // m_cnCompPerLig
- scalars += sizeof(int); // m_cnFeat
- glyphInfo_count += seg.m_cginf;
- scalars += sizeof(int); // m_cginf;
- scalars += sizeof(int); // m_isloutGinf0
- for (int iginf = 0; iginf < seg.m_cginf; iginf++)
- {
- ///GlyphInfo * pginf = seg.m_prgginf + iginf;
- glyphInfo += sizeof(void *); // m_pseg
- glyphInfo += sizeof(void *); // m_pslout
- glyphInfo += sizeof(int); // m_islout
- }
- init += sizeof(int); // m_cslotRestartBackup
- init += vectorOverhead;
- init += sizeof(sdata8) * seg.m_vnSkipOffsets.capacity();
- wastedVector += sizeof(sdata8) * (seg.m_vnSkipOffsets.capacity() - seg.m_vnSkipOffsets.size());
- init += sizeof(DirCode); // m_dircPrevStrong
- init += sizeof(DirCode); // m_dircPrevTerm
-
- //int grandTotal;
- //grandTotal = overhead + pointers + scalars + strings + metrics + associations
- // + init + obsolete + slot_count + slot_abstract + slot_varLenBuf + slot_scalars
- // + slot_clusterMembers + glyphInfo_count + glyphInfo;
-
- //int totalPerSeg = grandTotal / seg_count;
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out the memory usage onto a stream.
-----------------------------------------------------------------------------------------------*/
-void SegmentMemoryUsage::prettyPrint(std::ostream & strm)
-{
- int totalBytes = overhead + pointers + scalars + strings + metrics + associations
- + init + obsolete + slot_count + slot_abstract + slot_varLenBuf + slot_scalars
- + slot_clusterMembers + glyphInfo_count + glyphInfo;
-
- int slotTotal = slot_abstract + slot_varLenBuf + slot_scalars + slot_clusterMembers;
-
- strm << "Number of segments: " << seg_count << "\n\n";
-
- strm << "TOTALS\n";
- strm << "Overhead: " << overhead << "\n";
- strm << "Pointers: " << pointers << "\n";
- strm << "Scalars: " << scalars << "\n";
- strm << "Strings: " << strings << "\n";
- strm << "Metrics: " << metrics << "\n";
- strm << "Associations: " << associations << "\n";
- strm << "Obsolete: " << obsolete << "\n";
- strm << "Slot data: " << slotTotal << "\n";
- strm << " Abstract: " << slot_abstract << "\n";
- strm << " Var-length buffer: " << slot_varLenBuf << "\n";
- strm << " Scalars: " << slot_scalars << "\n";
- strm << " Cluster members: " << slot_clusterMembers << "\n";
- strm << "Glyph info: " << glyphInfo << "\n\n";
-
- strm << "Wasted in vectors: " << wastedVector << "\n\n";
-
- strm << "Total bytes used: " << totalBytes << "\n\n";
-
- if (seg_count > 0)
- {
- strm << "AVERAGES\n";
- strm << "Overhead: " << overhead/seg_count << "\n";
- strm << "Pointers: " << pointers/seg_count << "\n";
- strm << "Scalars: " << scalars/seg_count << "\n";
- strm << "Strings: " << strings/seg_count << "\n";
- strm << "Metrics: " << metrics/seg_count << "\n";
- strm << "Associations: " << associations/seg_count << "\n";
- strm << "Obsolete: " << obsolete/seg_count << "\n";
- strm << "Slot data: " << slotTotal/seg_count << "\n";
- strm << " Abstract: " << slot_abstract/seg_count << "\n";
- strm << " Var-length buffer: " << slot_varLenBuf/seg_count << "\n";
- strm << " Scalars: " << slot_scalars/seg_count << "\n";
- strm << " Cluster members: " << slot_clusterMembers/seg_count << "\n";
- strm << "Glyph info: " << glyphInfo/seg_count << "\n\n";
-
- strm << "Avg. bytes per segment: " << totalBytes / seg_count << "\n\n";
-
- strm << "Avg. # of slots per segment: " << slot_count / seg_count << "\n\n";
- }
-}
-
-} //namespace gr
-
diff --git a/Build/source/libs/graphite-engine/src/segment/Platform.cpp b/Build/source/libs/graphite-engine/src/segment/Platform.cpp
deleted file mode 100644
index 30ec3f4bf1f..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/Platform.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-#include "GrPlatform.h"
-
-#ifdef _WIN32
-#include "windows.h"
-
-namespace gr
-{
-
-size_t Platform_UnicodeToANSI(const utf16 * prgchwSrc, size_t cchwSrc, char * prgchsDst, size_t cchsDst)
-{
- return ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)prgchwSrc, cchwSrc, prgchsDst, cchsDst, NULL, NULL);
-}
-
-size_t Platform_AnsiToUnicode(const char * prgchsSrc, size_t cchsSrc, utf16 * prgchwDst, size_t cchwDst)
-{
- return ::MultiByteToWideChar(CP_ACP, 0, prgchsSrc, cchsSrc, (LPWSTR)prgchwDst, cchwDst);
-}
-
-size_t Platform_8bitToUnicode(int nCodePage, const char * prgchsSrc, int cchsSrc,
- utf16 * prgchwDst, int cchwDst)
-{
- return ::MultiByteToWideChar(nCodePage, 0, prgchsSrc, cchsSrc, (LPWSTR)prgchwDst, cchwDst);
-}
-
-size_t utf8len(const char *s)
-{
- return mbstowcs(NULL,s,0);
-}
-
-utf16 *utf16cpy(utf16 *dest, const utf16 *src)
-{
- return (utf16*)wcscpy((wchar_t*)dest, (const wchar_t*)src);
-}
-
-utf16 *utf16ncpy(utf16 *dest, const utf16 *src, size_t n)
-{
- return (utf16*)wcsncpy((wchar_t*)dest, (const wchar_t*)src, n);
-}
-
-utf16 *utf16ncpy(utf16 *dest, const char *src, size_t n)
-{
- #ifdef UTF16DEBUG
- std::cerr << "utf16ncpy8: " << src << std::endl;
- #endif
- Platform_AnsiToUnicode(src, strlen(src), dest, n);
- return dest;
-}
-
-
-size_t utf16len(const utf16 *s)
-{
- return wcslen((const wchar_t*)s);
-}
-
-int utf16cmp(const utf16 *s1, const utf16 *s2)
-{
-return wcscmp((const wchar_t*)s1, (const wchar_t*)s2);
-}
-
-int utf16ncmp(const utf16 *s1, const utf16 *s2, size_t n)
-{
- return wcsncmp((const wchar_t*)s1, (const wchar_t*)s2, n);
-}
-
-int utf16cmp(const utf16 *s1, const char *s2)
-{
- while (*s1 && s2)
- {
- if (*s1 < *s2)
- {
- return -1;
- }
- if (*s1 > *s2)
- {
- return 1;
- }
- *s1++;
- *s2++;
- }
- if (*s1) return -1;
- else if (*s2) return 1;
- return 0;
-}
-
-}
-#else // not _WIN32
-
-#include <iostream>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef HAVE_FABSF
-float fabsf(float x)
-{
- return (x < 0.0f) ? -x : x;
-}
-#endif
-
-namespace gr
-{
-
-size_t utf16len(const utf16 *s)
-{
- // assumes NULL terminated strings
- const utf16 *start = s;
- for (; *s; ++s);
-
- return s - start;
-}
-
-} // namespace gr
-#endif // _WIN32
-
diff --git a/Build/source/libs/graphite-engine/src/segment/Segment.cpp b/Build/source/libs/graphite-engine/src/segment/Segment.cpp
deleted file mode 100644
index b936b037a64..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/Segment.cpp
+++ /dev/null
@@ -1,3547 +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: Segment.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Implements a Graphite segment--a range of rendered text in one writing system, that can be
- rendered with a single font, and that fits on a single line.
--------------------------------------------------------------------------------*//*:End Ignore*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-// any other headers (not precompiled)
-#include <math.h>
-#ifndef _WIN32
-#include <stdlib.h>
-#endif
-
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-#if 0 // TODO remove
-namespace
-{
-
-static bool g_fDrawing;
-
-} // namespace
-#endif
-
-
-static int g_csegTotal = 0;
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Segment methods
-//:>********************************************************************************************
-
-
-int Segment::GetSegmentCount() /// TEMP
-{
- return g_csegTotal;
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Constructor: basic initialization.
-----------------------------------------------------------------------------------------------*/
-Segment::Segment() :
- m_pgts(NULL),
- m_pfont(NULL),
- m_preneng(NULL),
- m_fErroneous(false),
- m_pgjus(NULL),
- m_prgbNextSegDat(NULL),
- m_cbNextSegDat(0),
- m_prgInitDat(NULL),
- m_cbInitDat(0),
-// m_fUseSepBase(0),
- //m_psegAltEndLine(NULL),
- m_prgisloutBefore(NULL),
- m_prgisloutAfter(NULL),
- m_prgpvisloutAssocs(NULL),
- m_prgisloutLigature(NULL),
- m_prgiComponent(NULL),
-// m_psstrm(NULL),
- m_cslout(0),
- m_prgslout(NULL),
- m_prgnSlotVarLenBuf(NULL),
-// m_cnUserDefn(0),
- m_cnCompPerLig(0),
-// m_cnFeat(0),
- m_cginf(0),
- m_prgginf(NULL)
-{
- m_cref = 1;
-
- g_csegTotal++;
-
-// m_stuFaceName.erase();
-// m_stuBaseFaceName.erase();
- m_vnSkipOffsets.clear();
-}
-
-/*----------------------------------------------------------------------------------------------
- Reference counting.
-----------------------------------------------------------------------------------------------*/
-
-long Segment::IncRefCount(void)
-{
- AssertPtr(this);
- return InterlockedIncrement(&m_cref);
-}
-
-long Segment::DecRefCount(void)
-{
- AssertPtr(this);
- long cref = InterlockedDecrement(&m_cref);
- if (cref == 0) {
- m_cref = 1;
- delete this;
- }
- return cref;
-}
-
-/*----------------------------------------------------------------------------------------------
- Constructor to fit as much of the text on the line as possible,
- finding a reasonable break point if necessary.
-----------------------------------------------------------------------------------------------*/
-LineFillSegment::LineFillSegment(
- Font * pfont,
- ITextSource * pts,
- LayoutEnvironment * playoutArg,
- toffset ichStart,
- toffset ichStop,
- float xsMaxWidth,
- bool fBacktracking)
- : Segment()
-{
- if (!pfont)
- throw;
- if (!pts)
- throw;
-
- LayoutEnvironment layoutDefault;
- LayoutEnvironment * playout = (!playoutArg) ? &layoutDefault : playoutArg;
-
- pfont->RenderLineFillSegment(this, pts, *playout, ichStart, ichStop, xsMaxWidth,
- fBacktracking);
-}
-
-/*----------------------------------------------------------------------------------------------
- Constructor to create a segment representing the given range of characters.
-----------------------------------------------------------------------------------------------*/
-RangeSegment::RangeSegment(
- Font * pfont,
- ITextSource * pts,
- LayoutEnvironment * playoutArg,
- toffset ichStart,
- toffset ichStop,
- Segment * psegInitLike)
- : Segment()
-{
- if (!pfont)
- throw;
- if (!pts)
- throw;
-
- LayoutEnvironment layoutDefault;
- LayoutEnvironment * playout = (!playoutArg) ? &layoutDefault : playoutArg;
- playout->setSegmentForInit(psegInitLike);
-
- pfont->RenderRangeSegment(this, pts, *playout, ichStart, ichStop);
-
- playout->setSegmentForInit(NULL);
-}
-
-/*----------------------------------------------------------------------------------------------
- Constructor to create a justified segment. Private.
-----------------------------------------------------------------------------------------------*/
-JustSegmentAux::JustSegmentAux(
- Font * pfont,
- ITextSource * pts,
- LayoutEnvironment * playoutArg,
- toffset ichStart,
- toffset ichStop,
- float xsNaturalWidth,
- float xsJustifiedWidth,
- Segment * psegInitLike)
- : Segment()
-{
- if (!pfont)
- throw;
- if (!pts)
- throw;
-
- LayoutEnvironment layoutDefault;
- LayoutEnvironment * playout = (!playoutArg) ? &layoutDefault : playoutArg;
- playout->setSegmentForInit(psegInitLike);
-
- pfont->RenderJustifiedSegment(this, pts, *playout, ichStart, ichStop,
- xsNaturalWidth, xsJustifiedWidth);
-
- playout->setSegmentForInit(NULL);
-}
-
-//Segment::Segment(ITextSource * pgts, int ichwMin, int ichwLim,
-// LineBrk lbStart, LineBrk lbEnd,
-// bool fStartLine, bool fEndLine, bool fWsRtl)
-//{
-// m_cref = 1;
-// Initialize(pgts, ichwMin, ichwLim, lbStart, lbEnd, fStartLine, fEndLine, fWsRtl);
-//}
-
-void Segment::Initialize(ITextSource * pgts, int ichwMin, int ichwLim,
- LineBrk lbStart, LineBrk lbEnd, SegEnd est,
- bool fStartLine, bool fEndLine, bool fWsRtl)
-{
- AssertPtrN(pgts);
- Assert(ichwMin >= 0);
- Assert(ichwLim >= 0);
- Assert(ichwMin <= ichwLim);
-
- //pgts->TextSrcObject(&m_pgts); // create a permanent wrapper, if necessary
- // m_pgts->AddRef(); no, smart pointer
- m_pgts = pgts;
-
- m_ichwMin = ichwMin;
- m_dichwLim = ichwLim - ichwMin;
- m_lbStart = lbStart;
- m_lbEnd = lbEnd;
- m_est = est;
- m_dxsStretch = 0;
- m_dxsWidth = -1;
- m_dysAscent = -1; // to properly init, ComputeDimensions must be called
- m_dysHeight = -1;
- m_dysXAscent = -1;
- m_dysXDescent = -1;
- m_dysAscentOverhang = -1;
- m_dysDescentOverhang = -1;
- m_dxsLeftOverhang = -1;
- m_dxsRightOverhang = -1;
- m_dysOffset = 0;
- m_fStartLine = fStartLine;
- m_fEndLine = fEndLine;
- m_fWsRtl = fWsRtl;
-
- m_dxsVisibleWidth = -1;
- m_dxsTotalWidth = -1;
-
-// m_psstrm = NULL;
- m_prgslout = NULL;
- m_prgnSlotVarLenBuf = NULL;
- m_prgisloutBefore = NULL;
- m_prgisloutAfter = NULL;
- m_prgpvisloutAssocs = NULL;
- m_prgisloutLigature = NULL;
- m_prgiComponent = NULL;
-
- m_prgbNextSegDat = NULL;
- m_cbNextSegDat = 0;
-
- //m_psegAltEndLine = NULL;
-
-// m_stuFaceName.erase();
-// m_stuBaseFaceName.erase();
-// m_fUseSepBase = false;
-
-// m_psegPrev = NULL; // obsolete
-// m_psegNext = NULL;
-
- //InitializePlatform();
-}
-
-/*----------------------------------------------------------------------------------------------
- Destructor.
-----------------------------------------------------------------------------------------------*/
-Segment::~Segment()
-{
- g_csegTotal--;
-
- DestroyContents();
-}
-
-void Segment::DestroyContents()
-{
- delete m_pfont;
- m_pfont = NULL;
-
- //if (m_pgts)
- // // A specially-created wrapper object has to be deleted.
- // m_pgts->DeleteTextSrcPtr();
- m_pgts = NULL;
-
- //if (m_pgjus)
- // // A specially-created wrapper object has to be deleted.
- // m_pgjus->DeleteJustifierPtr();
- m_pgjus = NULL;
-
- //if (m_psegAltEndLine)
- //{
- // if (m_psegAltEndLine->m_psegAltEndLine == this)
- // m_psegAltEndLine->m_psegAltEndLine = NULL;
- // delete m_psegAltEndLine;
- //}
-
- //for (int iginf = 0; iginf < m_cginf; iginf++) // DELETE
- // delete m_prgginf[iginf].components;
-
- Assert((m_prgslout && m_prgnSlotVarLenBuf) || (!m_prgslout && !m_prgnSlotVarLenBuf));
- delete[] m_prgslout;
- delete[] m_prgnSlotVarLenBuf;
- delete[] m_prgisloutBefore;
- delete[] m_prgisloutAfter;
- for (int ichw = 0; ichw < m_ichwAssocsLim - m_ichwAssocsMin; ichw++)
- {
- if (m_prgpvisloutAssocs && m_prgpvisloutAssocs[ichw])
- delete m_prgpvisloutAssocs[ichw];
- }
- delete[] m_prgpvisloutAssocs;
- delete[] m_prgisloutLigature;
- delete[] m_prgiComponent;
- delete[] m_prgbNextSegDat;
- delete[] m_prgInitDat;
- delete[] m_prgginf;
- m_cginf = 0;
-
- //DestroyContentsPlatform();
-
- // ReleaseObj(m_pgts); automatic because smart pointer
-}
-
-/*----------------------------------------------------------------------------------------------
- Factory method to create a new version of an existing segment with different
- line-boundary flags.
-----------------------------------------------------------------------------------------------*/
-Segment * Segment::LineContextSegment(Segment & seg, bool fStartLine, bool fEndLine)
-{
- if (!seg.hasLineBoundaryContext())
- {
- // Make an identical segment and just change the flags.
- Segment * psegNew = new Segment(seg);
- psegNew->InitLineContextSegment(fStartLine, fEndLine);
- return psegNew;
- }
- else
- {
- // Rerun the processing.
- LayoutEnvironment layout = seg.Layout();
- layout.setStartOfLine(fStartLine);
- layout.setEndOfLine(fEndLine);
- ITextSource & gts = seg.getText();
- Font & font = seg.getFont();
- return new RangeSegment(&font, &gts, &layout,
- seg.startCharacter(), seg.stopCharacter(), &seg);
- }
-}
-
-void Segment::InitLineContextSegment(bool fStartLine, bool fEndLine)
-{
- // For RTL end-of-line segments, trailing white space hangs off the left of
- // the origin of the segment. So when changing that flag
- // shift appropriately.
- bool fShift = ((m_nDirDepth % 2) && (m_fEndLine != fEndLine));
-
- m_fStartLine = fStartLine;
- m_fEndLine = fEndLine;
-
- m_layout.setStartOfLine(fStartLine);
- m_layout.setEndOfLine(fEndLine);
-
- if (fShift)
- {
- (m_fEndLine) ?
- ShiftGlyphs(m_dxsVisibleWidth - m_dxsTotalWidth) : // shift left
- ShiftGlyphs(m_dxsTotalWidth - m_dxsVisibleWidth); // shift right
- }
-
- m_dxsWidth = -1;
-}
-
-/*----------------------------------------------------------------------------------------------
- A factory method to create a justified version of an existing segment.
-----------------------------------------------------------------------------------------------*/
-Segment * Segment::JustifiedSegment(Segment & seg, float xsNewWidth)
-{
- LayoutEnvironment layout(seg.Layout());
- ITextSource & gts = seg.getText();
-
- // Why do we have to do this?
- layout.setJustifier(seg.Justifier());
- Font & font = seg.getFont();
- return new JustSegmentAux(&font, &gts, &layout,
- seg.startCharacter(), seg.stopCharacter(),
- seg.advanceWidth(), xsNewWidth, &seg);
-}
-
-/*----------------------------------------------------------------------------------------------
- A factory method to create a new version of an existing trailing white-space segment
- with a different direction.
-----------------------------------------------------------------------------------------------*/
-Segment * Segment::WhiteSpaceSegment(Segment & seg, int nNewDepth)
-{
- Segment * psegNew = new Segment(seg);
- psegNew->InitWhiteSpaceSegment(nNewDepth);
- return psegNew;
-}
-
-void Segment::InitWhiteSpaceSegment(int nNewDepth)
-{
- if (nNewDepth == m_nDirDepth)
- {
- return;
- }
- else if ((nNewDepth % 2) == (m_nDirDepth % 2))
- {
- // Same direction, not much to change.
- m_nDirDepth = nNewDepth;
- return;
- }
- else if (m_twsh != ktwshOnlyWs)
- return; // couldn't change it, oh, well
-
- // Otherwise, do the hard stuff: reverse the positions of the glyphs.
- for (int islout = 0; islout < m_cslout; islout++)
- {
- OutputSlot(islout)->ShiftForDirDepthChange(m_dxsTotalWidth);
- }
- m_nDirDepth = nNewDepth;
-
- //SetDirectionDepthPlatform(nNewDepth);
-}
-
-/*----------------------------------------------------------------------------------------------
- Basic copy method.
-----------------------------------------------------------------------------------------------*/
-Segment::Segment(Segment & seg)
-{
- int islout;
-
- m_pgts = seg.m_pgts;
- m_dichwLim = seg.m_dichwLim;
- m_ichwMin = seg.m_ichwMin;
- m_pfont = seg.m_pfont->copyThis();
- m_preneng = seg.m_preneng;
- m_fErroneous = seg.m_fErroneous;
- m_pgjus = seg.m_pgjus;
- m_fWsRtl = seg.m_fWsRtl;
- m_fParaRtl = seg.m_fParaRtl;
- m_twsh = seg.m_twsh;
- m_nDirDepth = seg.m_nDirDepth;
- m_cbNextSegDat = seg.m_cbNextSegDat;
- m_prgbNextSegDat = new byte[m_cbNextSegDat];
- std::copy(seg.m_prgbNextSegDat, seg.m_prgbNextSegDat + m_cbNextSegDat, m_prgbNextSegDat);
-// m_psegPrev = seg.m_psegPrev;
-// m_psegNext = seg.m_psegNext;
-// m_stuFaceName = seg.m_stuFaceName;
-// m_stuBaseFaceName = seg.m_stuBaseFaceName;
-// m_fUseSepBase = seg.m_fUseSepBase;
-// m_pixHeight = seg.m_pixHeight;
-// m_fBold = seg.m_fBold;
-// m_fItalic = seg.m_fItalic;
- m_lbStart = seg.m_lbStart;
- m_lbEnd = seg.m_lbEnd;
- m_fStartLine = seg.m_fStartLine;
- m_fEndLine = seg.m_fEndLine;
- m_est = seg.m_est;
- m_mFontEmUnits = seg.m_mFontEmUnits;
- m_dysFontAscent = seg.m_dysFontAscent;
- m_dysFontDescent = seg.m_dysFontDescent;
- m_xysEmSquare = seg.m_xysEmSquare;
-// m_xsDPI = seg.m_xsDPI;
-// m_ysDPI = seg.m_ysDPI;
- m_dxsStretch = seg.m_dxsStretch;
- m_dxsWidth = seg.m_dxsWidth;
- m_dysHeight = seg.m_dysHeight;
- m_dysAscent = seg.m_dysAscent;
- m_dysXAscent = seg.m_dysXAscent;
- m_dysXDescent = seg.m_dysXDescent;
- m_dysAscentOverhang = seg.m_dysAscentOverhang;
- m_dysDescentOverhang = seg.m_dysDescentOverhang;
- m_dxsLeftOverhang = seg.m_dxsLeftOverhang;
- m_dxsRightOverhang = seg.m_dxsRightOverhang;
- m_dxsVisibleWidth = seg.m_dxsVisibleWidth;
- m_dxsTotalWidth = seg.m_dxsTotalWidth;
- m_isloutVisLim = seg.m_isloutVisLim;
- m_dysOffset = seg.m_dysOffset;
-
- m_ichwAssocsMin = seg.m_ichwAssocsMin;
- m_ichwAssocsLim = seg.m_ichwAssocsLim;
-
- int dichw = m_ichwAssocsLim - m_ichwAssocsMin;
- m_prgisloutBefore = new int[dichw];
- std::copy(seg.m_prgisloutBefore, seg.m_prgisloutBefore + dichw, m_prgisloutBefore);
- m_prgisloutAfter = new int[dichw];
- std::copy(seg.m_prgisloutAfter, seg.m_prgisloutAfter + dichw, m_prgisloutAfter);
- m_prgpvisloutAssocs = new std::vector<int> * [dichw];
- for (int ivislout = 0; ivislout < dichw; ivislout++)
- {
- std::vector<int> * pvislout = seg.m_prgpvisloutAssocs[ivislout];
- if (pvislout)
- {
- std::vector<int> * pvisloutNew = new std::vector<int>;
- m_prgpvisloutAssocs[ivislout] = pvisloutNew;
- *pvisloutNew = *pvislout; // copy the vector
- }
- }
- m_prgisloutLigature = new int[dichw];
- std::copy(seg.m_prgisloutLigature, seg.m_prgisloutLigature + dichw, m_prgisloutLigature);
- m_prgiComponent = new sdata8[dichw];
- std::copy(seg.m_prgiComponent, seg.m_prgiComponent + dichw, m_prgiComponent);
-
- m_cslout = seg.m_cslout;
- int cnExtraPerSlot = (m_cslout > 0) ? seg.m_prgslout[0].CExtraSpaceSlout() : 0;
- m_prgnSlotVarLenBuf = new u_intslot[m_cslout * cnExtraPerSlot];
- m_prgslout = new GrSlotOutput[m_cslout];
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutOrig = seg.m_prgslout + islout;
- GrSlotOutput * psloutThis = m_prgslout + islout;
- psloutThis->ExactCopyFrom(psloutOrig,
- m_prgnSlotVarLenBuf + (islout * cnExtraPerSlot), // var-length buffer location
- cnExtraPerSlot);
- }
-
-// m_cnUserDefn = seg.m_cnUserDefn;
- m_cnCompPerLig = seg.m_cnCompPerLig;
-// m_cnFeat = seg.m_cnFeat;
- m_cslotRestartBackup = seg.m_cslotRestartBackup;
- std::copy(seg.m_prgnSlotVarLenBuf, seg.m_prgnSlotVarLenBuf +
- (m_cslout * cnExtraPerSlot), m_prgnSlotVarLenBuf);
-
- m_cginf = seg.m_cginf;
- m_isloutGinf0 = seg.m_isloutGinf0;
- m_prgginf = new GlyphInfo[m_cginf];
- std::copy(seg.m_prgginf, seg.m_prgginf + m_cginf, m_prgginf);
- for (int iginf = 0; iginf < m_cginf; iginf++)
- {
- m_prgginf[iginf].m_pseg = this;
- m_prgginf[iginf].m_pslout = m_prgslout + m_prgginf[iginf].m_islout;
- }
-
- // Platform-specific; remove eventually:
- //m_cgstrm = seg.m_cgstrm;
- //m_prggstrm = new GlyphStrm[m_cgstrm];
- //for (int igstrm = 0; igstrm < m_cgstrm; igstrm++)
- //{
- // m_prggstrm[igstrm].gsk.ys = seg.m_prggstrm[igstrm].gsk.ys;
- // m_prggstrm[igstrm].gsk.clrFore = seg.m_prggstrm[igstrm].gsk.clrFore;
- // m_prggstrm[igstrm].gsk.clrBack = seg.m_prggstrm[igstrm].gsk.clrBack;
- // m_prggstrm[igstrm].vchwGlyphId = seg.m_prggstrm[igstrm].vchwGlyphId;
- // m_prggstrm[igstrm].vdxs = seg.m_prggstrm[igstrm].vdxs;
- // m_prggstrm[igstrm].vigbb = seg.m_prggstrm[igstrm].vigbb;
- // m_prggstrm[igstrm].xsStart = seg.m_prggstrm[igstrm].xsStart;
- // m_prggstrm[igstrm].xsStartInt = seg.m_prggstrm[igstrm].xsStartInt;
- //}
- //m_cgbb = seg.m_cgbb;
- //m_prggbb = new GlyphBb[m_cgbb];
- //memcpy(m_prggbb, seg.m_prggbb, m_cgbb * sizeof(GlyphBb));
- //-------------------------------------
-
- m_vnSkipOffsets = seg.m_vnSkipOffsets;
- m_dircPrevStrong = seg.m_dircPrevStrong;
- m_dircPrevTerm = seg.m_dircPrevTerm;
- m_cbInitDat = seg.m_cbInitDat;
- m_prgInitDat = new byte[m_cbInitDat];
- std::copy(seg.m_prgInitDat, seg.m_prgInitDat + m_cbInitDat, m_prgInitDat);
-}
-
-/*----------------------------------------------------------------------------------------------
- Swap the guts of the two segments.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-void Segment::SwapWith(Segment * pgrseg)
-{
- int crefThis = m_cref;
- int crefOther = pgrseg->m_cref;
-
- std::swap(*this, *pgrseg);
-
- m_cref = crefThis;
- pgrseg->m_cref = crefOther;
-}
-
-/*----------------------------------------------------------------------------------------------
- Delete the pointer to the alternate-end-of-line segment.
-----------------------------------------------------------------------------------------------*/
-void Segment::ClearAltEndLineSeg()
-{
- //if (m_psegAltEndLine)
- //{
- // if (m_psegAltEndLine->m_psegAltEndLine == this)
- // m_psegAltEndLine->m_psegAltEndLine = NULL; // so we don't get into a loop
- // delete m_psegAltEndLine;
- // m_psegAltEndLine = NULL;
- //}
-}
-
-
-//:>********************************************************************************************
-//:> Interface methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Return the font that was used to create this segment.
- Note that in some implementations, the font may be invalid; eg, on Windows the font
- may not contain a valid device context.
-----------------------------------------------------------------------------------------------*/
-Font & Segment::getFont()
-{
- return *m_pfont;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the text-source that the segment is representing.
-----------------------------------------------------------------------------------------------*/
-ITextSource & Segment::getText()
-{
- return *m_pgts;
-}
-
-/*----------------------------------------------------------------------------------------------
- The distance the drawing point should advance after drawing this segment.
- Always positive, even for RtoL segments.
-----------------------------------------------------------------------------------------------*/
-float Segment::advanceWidth()
-{
- if (m_dxsWidth < 0)
- {
- ////SetUpGraphics(ichwBase, pgg, true);
- ComputeDimensions();
- }
- return m_dxsWidth;
-}
-
-/*----------------------------------------------------------------------------------------------
- Compute the rectangle in destination coords which contains all the pixels drawn by
- this segment. This should be a sufficient rectangle to invalidate if the segment is
- about to be discarded.
-----------------------------------------------------------------------------------------------*/
-Rect Segment::boundingRect()
-{
- if (m_dxsWidth < 0)
- {
- ////SetUpGraphics(ichwBase, pgg, true);
- ComputeDimensions();
- }
-
- Rect rectRet;
- rectRet.top = m_dysAscent + m_dysAscentOverhang;
- rectRet.bottom = (m_dysAscent - m_dysHeight) - m_dysDescentOverhang;
- rectRet.left = m_dxsLeftOverhang;
- rectRet.right = m_dxsVisibleWidth + m_dxsRightOverhang;
-
- return rectRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Answer whether the primary direction of the segment is right-to-left. This is based
- on the direction of the writing system, except for white-space-only segments, in
- which case it is based on the main paragraph direction.
-----------------------------------------------------------------------------------------------*/
-bool Segment::rightToLeft()
-{
- if (m_twsh == ktwshOnlyWs)
- {
- // White-space-only segment: use main paragraph direction.
- return (m_nDirDepth % 2);
- }
-
- GrEngine * pgreng = EngineImpl();
- if (pgreng)
- {
- return pgreng->RightToLeft();
- }
- return (m_pgts->getRightToLeft(m_ichwMin));
-}
-
-/*----------------------------------------------------------------------------------------------
- Get the depth of direction embedding used by this segment. It is presumably the same
- for all runs of the segment, otherwise, some of them would use a different writing
- system and therefore be part of a different segment. So just use the first.
-----------------------------------------------------------------------------------------------*/
-int Segment::directionDepth(bool * pfWeak)
-{
- if (pfWeak)
- *pfWeak = (m_twsh == ktwshOnlyWs);
-
-// *pnDepth = m_pgts->getDirectionDepth(m_ichwLim);
-// Assert(*pnDepth == m_nDirDepth);
-
- return m_nDirDepth;
-}
-
-/*----------------------------------------------------------------------------------------------
- Change the direction of the segment. This is needed specifically for white-space-only
- segments, which are initially created to be in the direction of the paragraph, but then
- later are discovered to not be line-end after all, and need to be changed to use the
- directionality of the writing system.
-
- @return kresFail for segments that do not have weak directionality and therefore
- cannot be changed.
-----------------------------------------------------------------------------------------------*/
-bool Segment::setDirectionDepth(int nNewDepth)
-{
- Assert(false);
-
- if (nNewDepth == m_nDirDepth)
- {
- return true;
- }
- else if ((nNewDepth % 2) == (m_nDirDepth % 2))
- {
- // Same direction, not much to change.
- m_nDirDepth = nNewDepth;
- return true;
- }
- else if (m_twsh != ktwshOnlyWs)
- return false;
-
- // Otherwise, do the hard stuff: reverse the positions of the glyphs.
- for (int islout = 0; islout < m_cslout; islout++)
- {
- OutputSlot(islout)->ShiftForDirDepthChange(m_dxsTotalWidth);
- }
-
- //SetDirectionDepthPlatform(nNewDepth);
-
- return true;
-
-}
-
-/*----------------------------------------------------------------------------------------------
- The logical range of characters covered by the segment, relative to the beginning of
- the segment. The stop character is the index of the first character beyond the end
- of the segment.
-
- These values should be exact at a writing system or string boundary,
- but may be somewhat fuzzy at a line-break, since characters may be re-ordered
- across such boundaries. The renderer is free to apply any definition it likes of
- where a line-break occurs. This should always be the same value obtained from the
- renderer as pdichLimSeg.
-----------------------------------------------------------------------------------------------*/
-int Segment::startCharacter()
-{
- return m_ichwMin;
-}
-
-int Segment::stopCharacter()
-{
- return m_ichwMin + m_dichwLim;
-}
-
-/*----------------------------------------------------------------------------------------------
- Returns an indication of why the segment ended.
-----------------------------------------------------------------------------------------------*/
-bool Segment::startOfLine()
-{
- return m_fStartLine;
-}
-
-/*----------------------------------------------------------------------------------------------
- Returns an indication of why the segment ended.
-----------------------------------------------------------------------------------------------*/
-bool Segment::endOfLine()
-{
- return m_fEndLine;
-}
-
-/*----------------------------------------------------------------------------------------------
- Returns true if this segment has something special happening at line boundaries.
-----------------------------------------------------------------------------------------------*/
-bool Segment::hasLineBoundaryContext()
-{
- return (EngineImpl()->LineBreakFlag());
-}
-
-/*----------------------------------------------------------------------------------------------
- Returns an indication of why the segment ended.
-----------------------------------------------------------------------------------------------*/
-SegEnd Segment::segmentTermination()
-{
- return m_est;
-}
-
-/*----------------------------------------------------------------------------------------------
- Indicates the last character of interest to the segment, relative to the beginning
- of the segment. The meaning of this is that no behavior of this segment will be
- affected if characters beyond that change. This does not necessarily mean that
- a different line break could not have been obtained by the renderer if characters
- beyond that change, just that a segment with the boundaries of this one would
- not behave differently.
-----------------------------------------------------------------------------------------------*/
-//GrResult Segment::get_LimInterest(int ichwBase, int * pdichw)
-//{
-// ChkGrOutPtr(pdichw);
-//
-// GrEngine * pgreng = EngineImpl();
-// Assert(pgreng);
-// *pdichw = m_dichwLim + pgreng->PostXlbContext();
-// ReturnResult(kresOk);
-//}
-
-/*----------------------------------------------------------------------------------------------
- Changes the end-of-line status of the segment. This is used after making the last segment
- of a string if we want to attempt to put some more text after it (e.g., in another
- writing system), or if we have reordered due to bidirectionality.
-
- ENHANCE: the current version handles switching back and forth when we are trying to
- decide whether we can put more stuff on a line. So it assumes we are at the end of
- the contextual run (ie, the next batch of stuff will be in a different ows).
- This will not correctly handle the way this function could or possibly
- should be used for bidirectional reordering.
-----------------------------------------------------------------------------------------------*/
-/*
-GrResult Segment::changeLineEnds(bool fNewStart, bool fNewEnd)
-{
- if (m_fStartLine != fNewStart || m_fEndLine != fNewEnd)
- {
- if (EngineImpl()->LineBreakFlag())
- {
- if (!m_psegAltEndLine)
- {
- int dichwLimSeg, dichwContext;
- float dxWidth;
- SegEnd est;
- int cbNextSegDat;
- byte rgbNextSegDat[256];
- OLECHAR rgchErrMsg[256];
- Segment * pseg;
-
- EngineImpl()->FindBreakPointAux(m_pfont, m_pgts, m_pgjus,
- m_ichwMin, m_ichwMin + m_dichwLim, m_ichwMin + m_dichwLim,
- false, fNewStart, fNewEnd, kPosInfFloat, false,
- klbNoBreak, klbNoBreak, m_twsh, m_fParaRtl,
- &pseg,
- &dichwLimSeg, &dxWidth, &est,
- m_cbInitDat, m_prgInitDat, 256, rgbNextSegDat, &cbNextSegDat,
- &dichwContext,
- NULL,
- rgchErrMsg, 256);
- // TODO: do something with the error message. This shouldn't really happen,
- // since to get here we already created a segment with this font.
- if (!pseg)
- {
- // Because we provide INT_MAX as the amount of space, there should
- // always be enough room to generate the alternate segment.
- Assert(false);
- THROW(kresUnexpected);
- }
- Assert(cbNextSegDat == 0);
- m_psegAltEndLine = pseg;
- }
- Assert(m_psegAltEndLine->m_fEndLine == fNewEnd);
- Segment * pseg = m_psegAltEndLine; // save the value
- SwapWith(m_psegAltEndLine);
- m_psegAltEndLine = pseg; // reset it after swap
- pseg->m_psegAltEndLine = this;
- }
- else
- {
- bool fShift = ((m_nDirDepth % 2) && (m_fEndLine != fNewEnd));
- m_fStartLine = fNewStart;
- m_fEndLine = fNewEnd;
- if (fShift)
- {
- (m_fEndLine) ?
- ShiftGlyphs(m_dxsVisibleWidth - m_dxsTotalWidth) : // shift left
- ShiftGlyphs(m_dxsTotalWidth - m_dxsVisibleWidth); // shift right
- }
- m_dxsWidth = -1;
- }
- }
-
- ReturnResult(kresOk);
-}
-*/
-
-/*----------------------------------------------------------------------------------------------
- Get the type of break that occurs at the logical start of the segment.
-----------------------------------------------------------------------------------------------*/
-LineBrk Segment::startBreakWeight()
-{
- return m_lbStart;
-}
-
-/*----------------------------------------------------------------------------------------------
- Get the type of break that occurs at the logical end of the segment.
-----------------------------------------------------------------------------------------------*/
-LineBrk Segment::endBreakWeight()
-{
- return m_lbEnd;
-}
-
-/*----------------------------------------------------------------------------------------------
- Read the amount of stretch, that is, the difference between the actual and natural width.
- If the segment has been shrunk, returns a negative number.
- TODO: implement properly.
-----------------------------------------------------------------------------------------------*/
-float Segment::stretch()
-{
- return (float)m_dxsStretch;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the maximum stretch possible.
- TODO: implement properly.
-----------------------------------------------------------------------------------------------*/
-float Segment::maxStretch()
-{
- return 1000;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the maximum shrink possible.
- TODO: implement properly.
-----------------------------------------------------------------------------------------------*/
-float Segment::maxShrink()
-{
- return 0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return iterators representing the complete range of glyphs in the segment.
-----------------------------------------------------------------------------------------------*/
-std::pair<GlyphIterator, GlyphIterator> Segment::glyphs()
-{
- return std::make_pair(GlyphIterator(*this, 0), GlyphIterator(*this, m_cginf));
-}
-
-/*----------------------------------------------------------------------------------------------
- Return iterators representing the set of glyphs for the given character.
-----------------------------------------------------------------------------------------------*/
-std::pair<GlyphSetIterator, GlyphSetIterator> Segment::charToGlyphs(toffset ich)
-{
- std::vector<int> vislout = UnderlyingToLogicalAssocs(ich);
-
- if (vislout.size() == 0)
- return std::make_pair(GlyphSetIterator(), GlyphSetIterator());
- else
- {
- // Note that BOTH instances of GlyphSetIterator must use the same underlying vector,
- // so that comparisons make sense.
- RcVector * qvislout = new RcVector(vislout);
- return std::make_pair(
- GlyphSetIterator(*this, 0, qvislout),
- GlyphSetIterator(*this, vislout.size(), qvislout));
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the rendered glyphs and their x- and y-coordinates, in the order generated by
- the final positioning pass, relative to the top-left of the segment. They are always
- returned in (roughly) left-to-right order. Note: any of the arrays may be null.
-----------------------------------------------------------------------------------------------*/
-/*
-GrResult Segment::GetGlyphsAndPositions(
- Rect rs, Rect rd, int cchMax, int * pcchRet,
- utf16 * prgchGlyphs, float * prgxd, float * prgyd, float * prgdxdAdv)
-{
- ChkGrOutPtr(pcchRet);
- if (prgchGlyphs)
- ChkGrArrayArg(prgchGlyphs, cchMax);
- if (prgxd)
- ChkGrArrayArg(prgxd, cchMax);
- if (prgyd)
- ChkGrArrayArg(prgyd, cchMax);
- if (prgdxdAdv)
- ChkGrArrayArg(prgdxdAdv, cchMax);
-
- GrResult res;
-
- //SetUpGraphics(ichwBase, pgg, true);
-
- Assert(m_dxsWidth >= 0);
- Assert(m_dysAscent >= 0);
-
- *pcchRet = m_cginf;
- if (cchMax < m_cginf)
- {
- res = (cchMax == 0) ? kresFalse : kresInvalidArg;
- //RestoreFont(pgg);
- ReturnResult(res);
- }
-
- if (m_dxsWidth < 0)
- ComputeDimensions();
-
- float dysFontAscent = m_dysFontAscent;
- //////res = GetFontAscentSourceUnits(pgg, &dysFontAscent);
- //////if (ResultFailed(res))
- //////{
- ////// RestoreFont(pgg);
- ////// ReturnResult(res);
- //////}
-
- float xs = 0;
- // Top of text that sits on the baseline, relative to top of segment:
- float ys = m_dysAscent - dysFontAscent;
-
- float * prgxdLocal;
- if (prgxd == NULL)
- prgxdLocal = new float[cchMax];
- else
- prgxdLocal = prgxd;
-
- res = GetGlyphsAndPositionsPlatform(xs, ys, rs, rd,
- prgchGlyphs, prgxdLocal, prgyd, prgdxdAdv);
-
- if (!prgxd)
- delete[] prgxdLocal;
-
- //RestoreFont(pgg);
-
- ReturnResult(res);
-}
-*/
-
-/*----------------------------------------------------------------------------------------------
- For debugging. Return the characters in this segment.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-GrResult Segment::GetCharData(int cchMax, utf16 * prgch, int * pcchRet)
-{
- ChkGrArgPtr(prgch);
- ChkGrOutPtr(pcchRet);
-
- int ichLimTmp = m_ichwMin + min(m_dichwLim, cchMax);
- m_pgts->fetch(m_ichwMin, ichLimTmp - m_ichwMin, prgch);
- *pcchRet = ichLimTmp - m_ichwMin;
- ReturnResult(kresOk);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return either the first or last character that the the glyph corresponds to. The
- index of the glyph matches what was returned by GetGlyphsAndPositions.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-GrResult Segment::GlyphToChar(int iginf, bool fFirst, int * pich)
-{
- Assert(m_dxsWidth >= 0);
- Assert(m_dysAscent >= 0);
-
- *pich = PhysicalSurfaceToUnderlying(iginf, fFirst);
- ReturnResult(kresOk);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return all the characters that the glyph corresponds to. Most commonly this will
- be only one char, but ligatures, for instance, will have several. The index of the
- glyph matches what was returned by GetGlyphsAndPositions.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-GrResult Segment::GlyphToAllChars(int iginf,
- int cichMax, int * prgich, int * pcichRet)
-{
- Assert(m_dxsWidth >= 0);
- Assert(m_dysAscent >= 0);
-
- std::vector<int> vich;
- int ichFirst = PhysicalSurfaceToUnderlying(iginf, true);
- int ichLast = PhysicalSurfaceToUnderlying(iginf, false);
- Assert(ichFirst <= ichLast);
-
- if (ichFirst < ichLast)
- {
- // Loop over the range of characters that might be associated with this glyph
- // and add any that actually are.
- // TODO: we should probably use a method that gets us all the physical associations,
- // but this should get us 99.5% of the way there for now.
- for (int ich = ichFirst; ich <= ichLast; ich++)
- {
- int iginfFirst = UnderlyingToPhysicalSurface(ich, true);
- int iginfLast = UnderlyingToPhysicalSurface(ich, false);
- if (iginfFirst == iginf || iginfLast == iginf)
- vich.push_back(ich);
- }
- }
- else
- vich.push_back(ichFirst);
-
- *pcichRet = vich.size();
- if (cichMax < signed(vich.size()))
- {
- GrResult res = (cichMax == 0 ? kresFalse : kresInvalidArg);
- ReturnResult(res);
- }
- int * pi = prgich;
- for (size_t i = 0; i < vich.size(); i++)
- *pi++ = vich[i];
-
- ReturnResult(kresOk);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return either the first or last glyph that corresponds to the character. The
- index of the glyph matches what was returned by GetGlyphsAndPositions.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-GrResult Segment::CharToGlyph(int ich, bool fFirst, int * pigbb)
-{
- Assert(m_dxsWidth >= 0);
- Assert(m_dysAscent >= 0);
-
- *pigbb = UnderlyingToPhysicalSurface(ich, fFirst);
- ReturnResult(kresOk);
-}
-
-
-//:>********************************************************************************************
-//:> Non-FieldWorks interface methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Return the breakweight for the given character. Returns the best value if the character is
- mapped to glyphs with different values.
-----------------------------------------------------------------------------------------------*/
-LineBrk Segment::getBreakWeight(int ich, bool fBreakBefore)
-{
- LineBrk lbFirst, lbLast;
-
- int isloutFirst = UnderlyingToLogicalSurface(ich, true);
- if (isloutFirst == kPosInfinity || isloutFirst == kNegInfinity)
- return klbClipBreak;
- GrSlotOutput * psloutFirst = m_prgslout + isloutFirst;
- bool fNotFirst = false;
- if ((psloutFirst->NumberOfComponents() > 0)
- && psloutFirst->UnderlyingComponent(0) != ich)
- {
- // Not the first component of a ligature.
- lbFirst = (LineBrk) ((int)klbClipBreak * -1);
- fNotFirst = true;
- }
- else
- {
- lbFirst = (LineBrk) psloutFirst->BreakWeight();
- }
-
- int isloutLast = UnderlyingToLogicalSurface(ich, false);
- if (isloutLast == kPosInfinity || isloutLast == kNegInfinity)
- return klbClipBreak;
- GrSlotOutput * psloutLast = m_prgslout + isloutLast;
- bool fNotLast = false;
- if ((psloutLast->NumberOfComponents() > 0)
- && psloutLast->UnderlyingComponent(psloutLast->NumberOfComponents() - 1) != ich)
- {
- // Not the last component of a ligature.
- lbLast = klbClipBreak;
- fNotLast = true;
- }
- else
- {
- lbLast = (LineBrk) psloutLast->BreakWeight();
- }
-
- LineBrk lbRet;
- if (fNotLast && fNotFirst)
- // middle of a ligature
- lbRet = klbClipBreak;
- else if (fNotLast)
- lbRet = (fBreakBefore) ? lbFirst : klbClipBreak;
- else if (fNotFirst)
- lbRet = (fBreakBefore) ? klbClipBreak : lbLast;
- else
- lbRet = (fBreakBefore) ? lbFirst : lbLast;
-
- return lbRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the width of the range of characters. Line-boundary contextualization is handled
- by the measure attributes on the glyphs. The width returned is equivalent to the sum of
- the widths of any line-segments that would be needed to underline all the characters.
-
- Since this method is intended to be used on "measured" segments that include the entire
- paragraph, it is not very smart about handling cross-line-boundary contextualization.
- It basically ignores any glyphs that are rendered by this segment but not officially
- part of the segment.
-----------------------------------------------------------------------------------------------*/
-float Segment::getRangeWidth(int ichMin, int ichLim,
- bool fStartLine, bool fEndLine, bool fSkipSpace)
-{
- if (m_dxsWidth < 0)
- {
- ////SetUpGraphics(ichwBase, pgg, true);
- ComputeDimensions();
- }
-
- Assert(m_dxsWidth >= 0);
- Assert(m_dysAscent >= 0);
-
- //float xsSegRight = m_dxsTotalWidth;
-
- int ichMinRange = min(ichMin, ichLim);
- int ichLimRange = max(ichMin, ichLim);
-
- //int ichMinSeg = max(ichMinRange, m_ichwMin + m_ichwAssocsMin);
- //int ichLimSeg = min(ichLimRange, m_ichwMin + m_ichwAssocsLim);
- int ichMinSeg = max(ichMinRange, m_ichwMin);
- int ichLimSeg = min(ichLimRange, m_ichwMin + m_dichwLim);
-
- if (ichLimSeg < m_ichwMin) // not + m_ichwAssocsMin
- return 0;
- if (ichMinSeg >= m_ichwMin + m_dichwLim) // not m_ichwAssocsLim
- return 0;
-
- if (fSkipSpace)
- {
- int islout = UnderlyingToLogicalSurface(ichLimSeg - 1, true);
- GrSlotOutput * pslout = (islout == kNegInfinity || islout == kPosInfinity) ?
- NULL :
- OutputSlot(islout);
- while (pslout && pslout->IsSpace())
- {
- ichLimSeg--;
- islout = UnderlyingToLogicalSurface(ichLimSeg - 1, true);
-// pslout = OutputSlot(islout);
- pslout = (islout == kNegInfinity || islout == kPosInfinity) ?
- NULL : OutputSlot(islout);
- }
- }
-
- float xsWidth = 0;
- SegmentNonPainter segp(this); // doesn't really need to paint
- float rgxdLefts[100];
- float rgxdRights[100];
- size_t cxd = 0;
- if (ichMinRange < ichLimRange)
- cxd = segp.getUnderlinePlacement(ichMinSeg, ichLimSeg, fSkipSpace,
- 100, rgxdLefts, rgxdRights, NULL);
- for (size_t i = 0; i < cxd; i++)
- xsWidth += rgxdRights[i] - rgxdLefts[i];
-
- // Add in the line-boundary contextualization.
- int isloutFirst = UnderlyingToLogicalSurface(ichMin, true);
- int isloutLast = UnderlyingToLogicalSurface(ichLim - 1, false);
- int mSol = 0;
- int mEol = 0;
- if (0 <= isloutFirst && isloutFirst < m_cslout)
- mSol = m_prgslout[isloutFirst].MeasureSol();
- if (0 <= isloutLast && isloutLast < m_cslout)
- mEol = m_prgslout[isloutLast].MeasureEol();
- float dxsSol = GrEngine::GrIFIMulDiv(mSol, m_xysEmSquare, m_mFontEmUnits);
- float dxsEol = GrEngine::GrIFIMulDiv(mEol, m_xysEmSquare, m_mFontEmUnits);
- xsWidth += dxsSol;
- xsWidth += dxsEol;
-
- //RestoreFont(pgg);
-
- return xsWidth;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the next reasonable breakpoint after ichStart resulting in range that fits in
- the specified width.
-----------------------------------------------------------------------------------------------*/
-int Segment::findNextBreakPoint(int ichStart,
- LineBrk lbPref, LineBrk lbWorst, float dxMaxWidth,
- float * pdxBreakWidth, bool fStartLine, bool fEndLine)
-{
- ChkGrOutPtr(pdxBreakWidth);
-
- int ichBreak;
-
- // First make a rough estimation of how much will fit, using a binary chop approach.
- int iginfStart = UnderlyingToPhysicalSurface(ichStart, !m_fWsRtl);
- int iginfEnd = UnderlyingToPhysicalSurface(m_ichwMin + m_dichwLim - 1, m_fWsRtl);
- int iginfLeft = min(iginfStart, iginfEnd);
- int iginfRight= max(iginfStart, iginfEnd);
-
- int iginfMin = iginfLeft;
- int iginfLim = iginfRight;
- int ichFit;
- if (m_fWsRtl) // right-to-left
- {
- float xRight = GlyphLeftEdge(iginfRight + 1);
- float xLeftMost = xRight - dxMaxWidth;
- while (GlyphLeftEdge(iginfLim) < xLeftMost)
- {
- if (iginfLim - iginfMin <= 1)
- break;
- int iginfMid = (iginfLim + iginfMin) >> 1; // divide by 2
- if (GlyphLeftEdge(iginfMid) < xLeftMost)
- iginfLim = iginfMid;
- else
- iginfMin = iginfMid;
- }
- ichFit = PhysicalSurfaceToUnderlying(iginfLim, false);
- }
- else // left-to-right
- {
- float xLeft = GlyphLeftEdge(iginfLeft);
- float xRightMost = dxMaxWidth - xLeft; // QUESTION: shouldn't this be +, not -?
- iginfLim++;
- while (GlyphLeftEdge(iginfLim) > xRightMost)
- {
- if (iginfLim - iginfMin <= 1)
- break;
- int iginfMid = (iginfLim + iginfMin) >> 1; // divide by 2
- if (GlyphLeftEdge(iginfMid) > xRightMost)
- iginfLim = iginfMid;
- else
- iginfMin = iginfMid;
- }
- Assert(iginfLim <= m_cginf);
- if (iginfLim >= m_cginf) iginfLim = m_cginf - 1;
- ichFit = PhysicalSurfaceToUnderlying(iginfLim, false);
- }
-
- // Breaking after ichFit should pretty much fit in the space. But make sure.
- float dxWidthFit;
- while (ichFit > ichStart)
- {
- dxWidthFit = getRangeWidth(ichStart, ichFit, fStartLine, fEndLine);
- if (dxWidthFit <= dxMaxWidth)
- break;
- ichFit--;
- }
-
- if (ichFit <= ichStart)
- {
- // Nothing will fit.
- return ichStart - 1;
- }
-
- // Now look for a good break. First look forward until the range doesn't fit anymore.
- int ichTry = ichFit;
- int nExtra = 2;
- LineBrk lbBest = klbClipBreak;
- int ichBestBreak = -1;
- while (nExtra > 0 && ichTry < m_ichwMin + m_dichwLim)
- {
- float dxWTmp;
- dxWTmp = getRangeWidth(ichStart, ichTry, fStartLine, fEndLine);
- if (dxWTmp <= dxMaxWidth)
- {
- LineBrk lbTmp;
- lbTmp = getBreakWeight(ichTry - 1, false);
- if (lbTmp > 0 && lbTmp < lbWorst && max(lbTmp, lbPref) <= lbBest)
- {
- ichBestBreak = ichTry;
- lbBest = max(lbTmp, lbPref); // any value better than lbPref is insignificant
- }
- else
- {
- lbTmp = getBreakWeight(ichTry - 1, true);
- if (lbTmp < 0)
- {
- lbTmp = LineBrk(max(lbTmp * -1L, long(lbPref)));
- if (lbTmp < lbWorst && lbTmp <= lbBest)
- {
- ichBestBreak = ichTry - 1;
- lbBest = lbTmp;
- }
- }
- }
- }
- else
- {
- // Didn't fit. But it is theoretically possible that actually adding another
- // character will! Try a few more.
- nExtra--;
- }
- ichTry++;
- }
-
- if (ichTry >= m_ichwMin + m_dichwLim)
- {
- // Break at the end of the segment.
- ichBreak = m_ichwMin + m_dichwLim;
- *pdxBreakWidth = getRangeWidth(ichStart, m_dichwLim, fStartLine, fEndLine);
- return ichBreak;
- }
-
- if (ichBestBreak > -1 && lbBest <= lbPref)
- {
- // Found a reasonable break by looking forward; return it.
- ichBreak = ichBestBreak;// + m_ichwMin;
- *pdxBreakWidth = getRangeWidth(ichStart, ichBestBreak, fStartLine, fEndLine);
- return ichBreak;
- }
-
- // Didn't find a really good break point looking forward from our rough guess.
- // Now look backward.
-
- ichTry = ichFit;
- while (ichTry > ichStart)
- {
- LineBrk lbTmp;
- lbTmp = getBreakWeight(ichTry - 1, false);
- if (lbTmp > 0 && lbTmp < lbWorst && max(lbTmp, lbPref) < lbBest)
- {
- ichBestBreak = ichTry;
- lbBest = max(lbTmp, lbPref); // any value better than lbPref is insignificant
- }
- else
- {
- lbTmp = getBreakWeight(ichTry - 1, true);
- if (lbTmp < 0)
- {
- lbTmp = LineBrk(max(lbTmp * -1L, long(lbPref)));
- if (lbTmp < lbWorst && lbTmp < lbBest)
- {
- ichBestBreak = ichTry - 1;
- lbBest = lbTmp;
- }
- }
- }
- if (lbBest <= lbPref)
- break;
-
- ichTry--;
- }
-
- if (ichBestBreak > -1 && ichBestBreak > ichStart)
- {
- // Found a reasonable break by looking backward; return it.
- ichBreak = ichBestBreak;// + m_ichwMin;
- *pdxBreakWidth = getRangeWidth(ichStart, ichBestBreak, fStartLine, fEndLine);
- return ichBreak;
- }
-
- // No reasonable break.
- return ichStart - 1;
-}
-
-/*----------------------------------------------------------------------------------------------
- Private; used by findNextBreakPoint().
-----------------------------------------------------------------------------------------------*/
-float Segment::GlyphLeftEdge(int iginf)
-{
- if (iginf >= m_cginf)
- return m_prgginf[m_cginf - 1].origin() + m_prgginf[m_cginf - 1].advanceWidth();
-// return m_prgginf[m_cginf].origin() + m_prgginf[m_cginf].advanceWidth();
- else
- return m_prgginf[iginf].origin();
-}
-
-
-//:>********************************************************************************************
-//:> Other methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- Get the embedded string. For temporary use; AddRef is not automatically called.
- Do not release unless you AddRef.
-----------------------------------------------------------------------------------------------*/
-ITextSource * Segment::GetString()
-{
- return m_pgts;
-}
-
-/*----------------------------------------------------------------------------------------------
- Compute the ascent, height, width, and overhangs of the segment.
- The ascent is the ascent of the font (distance from the baseline to the top)
- plus any extra ascent height specified by the font.
- The descent is distance from the baseline to the bottom of font, plus any extra descent
- specified by the font (ExtraDescent).
- The ascent overhang is the distance from the top of the font to the top of the highest
- glyph, or zero if all the glyphs fit within the ascent.
- The descent overhang is the distance from the bottom of the font to the bottom of the lowest
- glyph, or zero if all the glyphs fit within the descent.
- The height is the sum of the ascent and descent.
-----------------------------------------------------------------------------------------------*/
-void Segment::ComputeDimensions()
-{
- if (m_fEndLine)
- m_dxsWidth = m_dxsVisibleWidth; // don't include trailing white space.
- else
- m_dxsWidth = m_dxsTotalWidth;
-
- if (m_dxsWidth == -1)
- {
- for (int iginf = 0; iginf < m_cginf; iginf++)
- {
- GlyphInfo * pginf = m_prgginf + iginf;
- if (pginf->isSpace())
- continue;
- m_dxsWidth = max(m_dxsWidth, (pginf->origin() + pginf->advanceWidth()));
- }
- }
-
- int dysNegFontDescent = (int)m_dysFontDescent * -1;
-
- // if there were no glyphs in the segment then there is sometimes no EngineImpl
- if (!EngineImpl())
- {
- Assert(m_cslout == 0);
- Assert(m_cginf == 0);
- m_dxsWidth = 0;
- m_dysAscent = 0; // max(0.0, m_dysFontAscent);
- m_dysHeight = 0; // max(0.0, m_dysAscent - dysNegFontDescent);
- m_dysAscentOverhang = 0;
- m_dysDescentOverhang = 0;
- m_dxsLeftOverhang = 0;
- m_dxsRightOverhang = 0;
- return;
- }
-
- // Calculate the extra ascent and descent.
- int mXAscent = EngineImpl()->ExtraAscent();
- int mXDescent = EngineImpl()->ExtraDescent();
-
- m_dysXAscent = GrEngine::GrIFIMulDiv(mXAscent, m_xysEmSquare, m_mFontEmUnits);
- m_dysXDescent = GrEngine::GrIFIMulDiv(mXDescent, m_xysEmSquare, m_mFontEmUnits);
-
- m_dysAscent = m_dysFontAscent + m_dysXAscent;
- float dysNegDescent = dysNegFontDescent - m_dysXDescent; // dysNegDescent < 0
- m_dysHeight = m_dysAscent - dysNegDescent;
-
- // Calculate the overhangs.
- float dysVisAscent = m_dysAscent;
- float dysNegVisDescent = dysNegDescent;
- float dxsVisLeft = 0;
- float dxsVisRight = m_dxsTotalWidth;
- ComputeOverhangs(&dysVisAscent, &dysNegVisDescent, &dxsVisLeft, &dxsVisRight);
- m_dysAscentOverhang = max(float(0), (dysVisAscent - m_dysAscent));
- m_dysDescentOverhang = max(float(0), (dysNegDescent - dysNegVisDescent));
- m_dxsLeftOverhang = min(float(0), dxsVisLeft);
- m_dxsRightOverhang = max(float(0), dxsVisRight - m_dxsTotalWidth);
-
- m_dysOffset = EngineImpl()->VerticalOffset();
-}
-
-/*----------------------------------------------------------------------------------------------
- Compute the visible ascent and descent, based on how much the bounding box of any
- glyph may extend beyond the ascent or descent of the font.
- Also compute the left- and right-overhangs.
-----------------------------------------------------------------------------------------------*/
-void Segment::ComputeOverhangs(float * pdysVisAscent, float * pdysNegVisDescent,
- float * pdxsVisLeft, float * pdxsVisRight)
-{
- for (int iginf = 0; iginf < m_cginf; iginf++)
- {
- *pdysVisAscent = max(*pdysVisAscent, m_prgginf[iginf].bb().top);
- *pdysNegVisDescent = min(*pdysNegVisDescent, m_prgginf[iginf].bb().bottom);
-
- *pdxsVisLeft = min(*pdxsVisLeft, m_prgginf[iginf].bb().left);
- *pdxsVisRight = max(*pdxsVisRight, m_prgginf[iginf].bb().right);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Create the arrays to store the final output and association information.
-----------------------------------------------------------------------------------------------*/
-void Segment::SetUpOutputArrays(Font * pfont, GrTableManager * ptman,
- GrSlotStream * psstrmFinal,
- int cchwInThisSeg, int csloutSurface, gid16 chwLB,
- TrWsHandling twsh, bool fParaRtl, int nDirDepth, bool fEmpty)
-{
- m_mFontEmUnits = EngineImpl()->GetFontEmUnits();
-
- pfont->getFontMetrics(&m_dysFontAscent, &m_dysFontDescent, &m_xysEmSquare);
-// m_xsDPI = (float)pfont->getDPIx();
-// m_ysDPI = (float)pfont->getDPIy();
-
- // Note that storing both of these values is redundant; they should be the same.
-// Assert(m_xysEmSquare == m_pixHeight);
-
- m_twsh = twsh;
- m_fParaRtl = fParaRtl;
- if (m_twsh == ktwshOnlyWs)
- m_nDirDepth = (int)fParaRtl;
- else if (fParaRtl && nDirDepth == 0)
- m_nDirDepth = 2;
- else
- m_nDirDepth = nDirDepth;
-
- // Create association mappings and set up final versions of slots.
-
- Assert((psstrmFinal == NULL) == fEmpty);
-
- m_ichwAssocsMin = 0;
- m_ichwAssocsLim = cchwInThisSeg;
-
- m_prgisloutBefore = new int[cchwInThisSeg];
-
- m_prgisloutAfter = new int[cchwInThisSeg];
-
- m_prgpvisloutAssocs = new std::vector<int> * [cchwInThisSeg];
-
- m_prgisloutLigature = new int[cchwInThisSeg];
-
- m_prgiComponent = new sdata8[cchwInThisSeg];
-
- int cslot = 0;
- //m_psstrm = psstrmFinal; // TODO: make a local variable
- if (psstrmFinal)
- cslot = psstrmFinal->FinalSegLim();
- else
- Assert(fEmpty);
-
- float xsMin = 0;
- int islot;
- int islotMin = (psstrmFinal) ? psstrmFinal->IndexOffset() : 0;
- for (islot = islotMin; islot < cslot; islot++)
- xsMin = min(xsMin, psstrmFinal->SlotAt(islot)->XPosition());
-
- // For right-to-left segments, the draw origin is at the left side of the visible
- // portion of the text. So if necessary, scoot everything left so that the invisible
- // trailing white-space is to the left of the draw position.
- Assert(m_dxsTotalWidth > -1);
- Assert(m_dxsVisibleWidth > -1);
- float dxsInvisible = (m_fEndLine) ? m_dxsTotalWidth - m_dxsVisibleWidth : 0;
- for (islot = islotMin; ((m_nDirDepth % 2) && (islot < cslot)); islot++)
- {
- GrSlotState * pslot = psstrmFinal->SlotAt(islot);
- // int islout = islot - islotMin;
- if (pslot->GlyphID() == chwLB)
- continue; // skip over linebreak markers
- if (m_nDirDepth % 2) // redundant test
- {
- // RTL will have descending neg values, adjust to be positive. Also make sure
- // invisible trailing white space is to the left of the draw origin.
- // Review: will changing this value have side affects?
- pslot->SetXPos(pslot->XPosition() - xsMin - dxsInvisible);
- }
- }
-
- Assert(kPosInfinity > 0);
- Assert(kNegInfinity < 0);
- for (int ichw = 0; ichw < cchwInThisSeg; ++ichw)
- {
- m_prgisloutBefore[ichw] = kPosInfinity;
- m_prgisloutAfter[ichw] = kNegInfinity;
- m_prgpvisloutAssocs[ichw] = new std::vector<int>;
- m_prgisloutLigature[ichw] = kNegInfinity;
- m_prgiComponent[ichw] = 0;
- }
-
- m_cslout = csloutSurface;
- if (ptman->NumUserDefn() > 0 && ptman->NumCompPerLig() > 0)
- {
- int x; x = 3;
- }
-
-// m_cnUserDefn = ptman->NumUserDefn();
- m_cnCompPerLig = ptman->NumCompPerLig();
-// m_cnFeat = ptman->NumFeat();
- // Normal buffers, plus underlying indices of ligature components, plus
- // map from used components to defined components.
-// int cnExtraPerSlot = m_cnUserDefn + (m_cnCompPerLig * 2) + m_cnFeat + (m_cnCompPerLig * 2);
-
- // We don't need to store the user-defined slot attributes or the features in the segment itself.
- // What we need is: (1) component.ref attr settings, (2) slot-attribute indices,
- // (3) underlying indicates of ligature components, and (4) map from used components
- // to defined components
- int cnExtraPerSlot = m_cnCompPerLig * 4;
- m_prgslout = new GrSlotOutput[m_cslout];
- m_prgnSlotVarLenBuf = new u_intslot[m_cslout * cnExtraPerSlot];
-
- m_isloutVisLim = 0;
- if (psstrmFinal)
- {
- for (islot = islotMin; islot < psstrmFinal->FinalSegLim(); ++islot)
- {
- int isloutRel = islot - islotMin;
-
- GrSlotState * pslot = psstrmFinal->SlotAt(islot);
- pslot->SetPosPassIndex(isloutRel, false);
- pslot->EnsureCacheForOutput(ptman);
- GrSlotOutput * pslout = OutputSlot(isloutRel);
- pslout->SetBufferPtr(m_prgnSlotVarLenBuf + (isloutRel * cnExtraPerSlot));
- pslout->InitializeOutputFrom(pslot);
- pslout->SetBeforeAssoc(pslot->BeforeAssoc());
- pslout->SetAfterAssoc(pslot->AfterAssoc());
- if (pslot->HasComponents())
- pslot->SetComponentRefsFor(pslout);
- Assert(pslot->HasComponents() == (pslout->NumberOfComponents() > 0));
- //if (pslot->HasClusterMembers())
- //{
- //Assert(pslot->HasClusterMembers() || pslot->ClusterRootOffset() == 0);
- pslout->SetClusterXOffset(pslot->ClusterRootOffset() * -1);
- pslout->SetClusterAdvance(pslot->ClusterAdvWidthFrom(0));
-
- //}
-
- if (!ptman->IsWhiteSpace(pslot))
- m_isloutVisLim = islot + 1;
- }
- }
-
- // Set up the clusters.
- for (islot = islotMin; islot < m_cslout; islot++)
- {
- GrSlotState * pslot = psstrmFinal->SlotAt(islot);
- int isloutAdj = islot - islotMin;
- int isloutBaseIndex = pslot->Base(psstrmFinal)->PosPassIndex();
- if (!pslot->IsBase())
- {
- OutputSlot(isloutBaseIndex)->AddClusterMember(isloutBaseIndex, pslot->PosPassIndex());
- OutputSlot(isloutAdj)->SetClusterBase(isloutBaseIndex);
- }
- else if (pslot->HasClusterMembers() && pslot->IsBase())
- {
- Assert(isloutBaseIndex == islot - islotMin);
- OutputSlot(isloutAdj)->SetClusterBase(isloutBaseIndex);
- }
- }
-
- ///AssertValidClusters(psstrmFinal);
-
-#ifdef OLD_TEST_STUFF
- if (ptman->GlyphTable() == NULL)
- return; // test procedures
-#endif // OLD_TEST_STUFF
-
- // CalcPositionsUpTo() called on final pass already from Table Mgr
-
- // Final output for draw routines.
-
- SetUpGlyphInfo(ptman, psstrmFinal, chwLB, nDirDepth, islotMin, cslot);
-
- //SetUpOutputArraysPlatform(ptman, chwLB, nDirDepth, islotMin, cslot);
-
-}
-
-/*----------------------------------------------------------------------------------------------
- Set up the data structures that represent the actual rendered glyphs for the new segment.
-----------------------------------------------------------------------------------------------*/
-void Segment::SetUpGlyphInfo(GrTableManager * ptman, GrSlotStream * psstrmFinal,
- gid16 chwLB, int nDirDepth, int islotMin, int cslot)
-{
- //int paraDirLevel = (ptman->State()->ParaRightToLeft()) ? 1 : 0;
-
- m_cginf = 0;
-
- int islot;
- for (islot = islotMin; islot < cslot; islot++)
- {
- if (psstrmFinal->SlotAt(islot)->GlyphID() != chwLB)
- {
- m_cginf++;
- }
- }
-
- // For right-to-left segments, the draw origin will be at the left side of the visible
- // portion of the text. So if necessary, scoot everything left so that the invisible
- // trailing white-space is to the left of the draw position.
- Assert(m_dxsTotalWidth > -1);
- Assert(m_dxsVisibleWidth > -1);
- //float dxsInvisible = (m_fEndLine) ? m_dxsTotalWidth - m_dxsVisibleWidth : 0;
-
- m_prgginf = new GlyphInfo [m_cginf];
-
- m_isloutGinf0 = -1;
- int iginf = 0;
- for (int islot = islotMin; islot < cslot; islot++)
- {
- GrSlotState * pslot = psstrmFinal->SlotAt(islot);
-
- if (pslot->GlyphID() == chwLB)
- {
- continue; // skip over linebreak markers
- }
-
- int islout = islot - islotMin;
- GrSlotOutput * pslout = OutputSlot(islout);
-
- if (m_isloutGinf0 == -1)
- m_isloutGinf0 = islout;
-
- m_prgginf[iginf].m_pslout = pslout;
- m_prgginf[iginf].m_islout = islout;
- m_prgginf[iginf].m_pseg = this;
-
- // Fill in stuff in the output slot that is needed by the GlyphInfo object.
- pslout->m_xsAdvanceX = pslot->GlyphMetricLogUnits(ptman, kgmetAdvWidth);
- //pslout->m_ysAdvanceY = pslot->GlyphMetricLogUnits(ptman, kgmetAdvHeight);
- //pslout->m_rectBB.top
- // = pslot->YPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetBbTop);
- //pslout->m_rectBB.bottom
- // = pslot->YPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetBbBottom);
- //pslout->m_rectBB.left
- // = pslot->XPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetBbLeft);
- //if (pslot->IsSpace(ptman))
- // pslout->m_rectBB.right
- // = pslot->XPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetAdvWidth);
- //else
- // pslout->m_rectBB.right
- // = pslot->XPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetBbRight);
-
- iginf++;
- }
-
- if (cslot - islotMin == 0)
- m_isloutGinf0 = 0;
- if (m_isloutGinf0 == -1)
- {
- Assert(m_cginf == 0);
- m_isloutGinf0 = ((OutputSlot(0)->IsInitialLineBreak()) ? 1 : 0);
- }
-
- Assert(m_isloutGinf0 == 0 || m_isloutGinf0 == 1);
-}
-
-/*
-// OLD VERSION
-void Segment::SetUpGlyphInfo(GrTableManager * ptman, GrSlotStream * psstrmFinal, gid16 chwLB, int nDirDepth,
- int islotMin, int cslot)
-{
- int paraDirLevel = (ptman->State()->ParaRightToLeft()) ? 1 : 0;
-
- m_cginf = 0;
- int islot;
- for (islot = islotMin; islot < cslot; islot++)
- {
- if (psstrmFinal->SlotAt(islot)->GlyphID() != chwLB)
- m_cginf++;
- }
-
- // For right-to-left segments, the draw origin will be at the left side of the visible
- // portion of the text. So if necessary, scoot everything left so that the invisible
- // trailing white-space is to the left of the draw position.
- Assert(m_dxsTotalWidth > -1);
- Assert(m_dxsVisibleWidth > -1);
- float dxsInvisible = (m_fEndLine) ? m_dxsTotalWidth - m_dxsVisibleWidth : 0;
-
- m_prgginf = new GlyphInfo [m_cginf];
-
- // Fill in glyph information structures.
- m_isloutGinf0 = -1;
- for (islot = islotMin; islot < cslot; islot++)
- {
- GrSlotState * pslot = psstrmFinal->SlotAt(islot);
-
- int islout = islot - islotMin;
- if (pslot->GlyphID() == chwLB)
- {
- continue; // skip over linebreak markers
- }
- if (m_isloutGinf0 == -1)
- m_isloutGinf0 = islout;
-
- GrSlotOutput * pslout = OutputSlot(islout);
-
- int iginf = islout - m_isloutGinf0;
- GlyphInfo & ginf = m_prgginf[iginf];
-
- ginf.glyphID = pslot->ActualGlyphForOutput(ptman);
- ginf.pseudoGlyphID = pslot->GlyphID();
- if (ginf.glyphID == ginf.pseudoGlyphID)
- ginf.pseudoGlyphID = 0;
-
- ginf.isSpace = pslot->IsSpace(ptman);
-
- ginf.origin = pslot->XPosition();
- ginf.yOffset = pslot->YPosition();
-
- ginf.bbLeft = pslot->XPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetBbLeft);
- ginf.bbTop = pslot->YPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetBbTop);
- if (ginf.isSpace)
- {
- ginf.bbRight = pslot->XPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetAdvWidth);
- }
- else
- {
- ginf.bbRight = pslot->XPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetBbRight);
- }
- ginf.bbBottom = pslot->YPosition() + pslot->GlyphMetricLogUnits(ptman, kgmetBbBottom);
-
- ginf.advanceWidth = pslot->GlyphMetricLogUnits(ptman, kgmetAdvWidth);
- ginf.advanceHeight = 0;
-
- if (pslot->AttachTo() == 0) // not attached
- ginf.attachedTo = -1;
- else
- ginf.attachedTo = pslot->AttachTo() + islot;
-
- ginf.directionality = byte(pslot->Directionality());
- if (pslot->DirLevel() == -1)
- ginf.directionLevel = paraDirLevel;
- else
- ginf.directionLevel = byte(pslot->DirLevel());
-
- //ginf.firstChar = LogicalSurfaceToUnderlying(islout, true);
- //ginf.lastChar = LogicalSurfaceToUnderlying(islout, false);
-
- if (pslot->HasComponents())
- {
- SetUpLigInfo(ptman, ginf, pslout);
- }
- else
- {
- ginf.numberOfComponents = 0;
- ginf.components = NULL;
- }
-
- ginf.insertBefore = pslot->InsertBefore();
-
- ginf.maxStretch[0] = ptman->EmToLogUnits(pslot->JStretch());
- ginf.maxShrink[0] = ptman->EmToLogUnits(pslot->JShrink());
- ginf.stretchStep[0]= ptman->EmToLogUnits(pslot->JStep());
- ginf.justWidth[0] = ptman->EmToLogUnits(pslot->JWidth());
- ginf.justWeight[0] = pslot->JWeight();
-
- ginf.measureStartOfLine = pslout->MeasureSolLogUnits();
- ginf.measureEndOfLine = pslout->MeasureEolLogUnits();
- }
-}
-*/
-
-/*----------------------------------------------------------------------------------------------
- Set up the data structures that represent the components of a ligature glyph.
-----------------------------------------------------------------------------------------------*/
-/*
-void Segment::SetUpLigInfo(GrTableManager * ptman, GlyphInfo & ginf, GrSlotOutput * pslout)
-{
- GrGlyphTable * pgtbl = ptman->GlyphTable();
-
- int ccomp = pslout->NumberOfComponents();
- ginf.numberOfComponents = ccomp;
- ginf.components = new ComponentBox[ccomp];
- for (int icomp = 0; icomp < ccomp; icomp++)
- {
- ComponentBox & cb = ginf.components[icomp];
-
- // TODO: Rework ComponentIndexForGlyph to take slati rather than iForGlyph.
- float xsLeft, xsRight, ysTop, ysBottom;
- int slati = pslout->ComponentId(icomp);
- int iForGlyph = pgtbl->ComponentIndexForGlyph(pslout->GlyphID(), slati);
- pgtbl->ComponentBoxLogUnits(m_xysEmSquare, pslout->GlyphID(), iForGlyph,
- m_mFontEmUnits, m_dysAscent,
- &xsLeft, &ysTop, &xsRight, &ysBottom, false);
-
- cb.firstChar = pslout->UnderlyingComponent(icomp);
- cb.lastChar = cb.firstChar; // TODO: is this supported?
- cb.left = xsLeft;
- cb.right = xsRight;
- cb.top = ysTop;
- cb.bottom = ysBottom;
- }
-}
-*/
-
-
-// --------- OBSOLETE - replaced by GrTableManager::AdjustAssocsForOverlaps() ---------------
-#if 0
-
-/*----------------------------------------------------------------------------------------------
- Now that this segment is finished and has its associations set, handle any overlaps in
- the associations between the previous segment and this one.
-
- Review: Think about whether we need to distinguish between before==kPosInfinity meaning
- that the glyph is in the next segment vs. there is no association at all.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-void Segment::AdjustForOverlapsWithPrevSeg()
-{
- if (m_psegPrev)
- {
- AdjustBeforeArrayFromPrevSeg();
- m_psegPrev->AdjustAfterArrayFromNextSeg();
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- For any characters that are officially in this segment but are rendered in
- the previous segment, initialize this segment's before array appropriately. Specifically,
- set this segment's before value to something invalid--negative infinity, which will
- never be overwritten.
- OBSOLETE - replaced by AdjustAfterArrayFromNextSeg
-----------------------------------------------------------------------------------------------*/
-void Segment::InitBeforeArrayFromPrevSeg()
-{
- Assert(m_psegPrev);
-
- int ichwPrevMin = m_psegPrev->m_ichwMin;
- int ichwPrevLim = m_psegPrev->m_ichwLim;
-// int ichwPrevContextLim =
-// m_psegPrev->m_ichwAssocsLim - m_psegPrev->m_ichwAssocsMin + m_psegPrev->m_ichwMin;
- int cchwPrevAssocsMin = m_psegPrev->m_ichwAssocsMin;
- int cchwPrevAssocsLim = m_psegPrev->m_ichwAssocsLim;
-
- // Loop over associations appended to the end of the previous segment;
- // ichwPrev and ichwThis are relative to the start of their respective segments.
- for (int ichwPrev = ichwPrevLim - ichwPrevMin; ichwPrev < cchwPrevAssocsLim; ++ichwPrev)
- {
- int ichwThis = ichwPrev - (ichwPrevLim - ichwPrevMin); // relative to start of this seg
- if (m_psegPrev->m_prgisloutBefore[ichwPrev - cchwPrevAssocsMin] < kPosInfinity)
- // The "before" value is in the previous segment, so make this segment's
- // before value invalid.
- m_prgisloutBefore[ichwThis - m_ichwAssocsMin] = kNegInfinity;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- For any associations that overlap between the previous segment and this, adjust
- this segment's before array appropriately. Specifically, for any characters that
- are rendered in both, set this segment's before value to something invalid.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-void Segment::AdjustBeforeArrayFromPrevSeg()
-{
- Assert(m_psegPrev);
-
- int ichwPrevMin = m_psegPrev->m_ichwMin;
- int ichwPrevLim = m_psegPrev->m_ichwLim;
- int ichwPrevAssocsMin = m_psegPrev->m_ichwAssocsMin;
- int ichwPrevAssocsLim = m_psegPrev->m_ichwAssocsLim;
-
- // Loop over associations appended to the end of the previous segment
- // (ie, rendered in the previous segment but officially in this one);
- // ichwPrev and ichwThis are relative to the start of their respective segments.
- for (int ichwPrev = ichwPrevLim - ichwPrevMin; ichwPrev < ichwPrevAssocsLim; ++ichwPrev)
- {
- int ichwThis = ichwPrev - (ichwPrevLim - ichwPrevMin); // relative to start of this seg
- if (m_psegPrev->m_prgisloutBefore[ichwPrev - ichwPrevAssocsMin] < kPosInfinity)
- // The "before" value is in the previous segment, so make this segment's
- // before value invalid.
- m_prgisloutBefore[ichwThis - m_ichwAssocsMin] = kNegInfinity;
- }
- // Loop over associations prepended to the start of this segment
- // (ie, rendered in this segment but officially in the previous one);
- // ichwPrev and ichwThis are relative to the start of their respective segments.
- for (int ichwThis = m_ichwAssocsMin; ichwThis < 0; ++ichwThis)
- {
- int ichwPrev = ichwThis + (ichwPrevLim - ichwPrevMin);
- if (m_psegPrev->m_prgisloutBefore[ichwPrev - ichwPrevAssocsMin] < kPosInfinity)
- // The "before" value is in the previous segment, so make this segment's
- // before value invalid.
- m_prgisloutBefore[ichwThis - m_ichwAssocsMin] = kNegInfinity;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- For any associations that overlap between this segment and the next, adjust
- this segment's after array appropriately. Specifically, for any characters that
- are rendered in both, set this segment's after value to something invalid.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-void Segment::AdjustAfterArrayFromNextSeg()
-{
- Assert(m_psegNext);
-
- int ichwNextMin = m_psegNext->m_ichwMin;
- int ichwNextContextMin = ichwNextMin + m_psegNext->m_ichwAssocsMin;
- int ichwNextAssocsMin = m_psegNext->m_ichwAssocsMin;
-
- // Loop over associations prepended to the beginning of the following segment
- // (ie, rendered in the next segment but officially in this one);
- // ichwThis and ichwNext are relative to the start of their respective segments.
- for (int ichwNext = cchwNextAssocsMin; ichwNext < 0; ++ichwNext)
- {
- int ichwThis = ichwNext + (m_ichwLim - m_ichwMin);
- if (m_psegNext->m_prgisloutAfter[ichwNext - ichwNextAssocsMin] > kNegInfinity)
- // The "after" value is in the next segment, so make this segment's
- // after value invalid.
- m_prgisloutAfter[ichwThis - m_ichwAssocsMin] = kPosInfinity;
- }
-
- // Loop over associations appended to the end of this segment
- // (ie, rendered in this segment but officially in the next one);
- // ichwThis and ichwNext are relative to the start of their respective segments.
- for (int ichwThis = m_ichwLim - m_ichwMin; ichwThis < m_cchwAssocsLim; ++ichwThis)
- {
- int ichwNext = ichwThis - (m_ichwLim - m_ichwMin);
- if (m_psegNext->m_prgisloutAfter[ichwNext - ichwNextAssocsMin] > kNegInfinity)
- // The "after" value is in the next segment, so make this segment's
- // after value invalid.
- m_prgisloutAfter[ichwThis - m_ichwAssocsMin] = kPosInfinity;
- }
-}
-
-#endif // -------------------------- END OF OBSOLETE CODE ----------------------------------
-
-
-/*----------------------------------------------------------------------------------------------
- Generate a list of all the glyphs that are attached to the base with the given index.
- Note that we want to generate glyph indices, not slot indices.
-
- @param disloutCluster - indicates how far on either side of the base to look.
-----------------------------------------------------------------------------------------------*/
-void Segment::ClusterMembersForGlyph(int isloutBase, int disloutCluster,
- std::vector<int> & visloutRet)
-{
- for (int islout = max(0, isloutBase - disloutCluster);
- islout < min(m_cslout, isloutBase + disloutCluster + 1);
- islout++)
- {
- if (islout == isloutBase)
- continue; // don't include the base itself
- GrSlotOutput * pslout = m_prgslout + islout;
- if (pslout->ClusterBase() == isloutBase)
- {
- visloutRet.push_back(islout);
- }
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Record an underlying-to-surface association mapping, based on the fact that there is
- a corresponding surface-to-underlying association in the streams.
-
- @param ichwUnder - character index relative to the official beginning of the segment
- @param islotSurface - surface glyph it maps to
-----------------------------------------------------------------------------------------------*/
-void Segment::RecordSurfaceAssoc(int ichwUnder, int islotSurface, int nDir)
-{
- // If we are recording an association across the line boundary, make sure there
- // is space for it.
- EnsureSpaceAtLineBoundaries(ichwUnder);
-
- // For left-to-right chars, the before-value is the minimum of the previous
- // and new values, and the after-value is the maximum.
- if (nDir % 2 == 0)
- {
- // left-to-right
- m_prgisloutBefore[ichwUnder - m_ichwAssocsMin] =
- min(m_prgisloutBefore[ichwUnder - m_ichwAssocsMin], islotSurface);
- m_prgisloutAfter[ ichwUnder - m_ichwAssocsMin] =
- max(m_prgisloutAfter[ ichwUnder - m_ichwAssocsMin], islotSurface);
- }
- else
- {
- // right-to-left: the before-value is the max and the after-value is the min
- m_prgisloutBefore[ichwUnder - m_ichwAssocsMin] =
- max(m_prgisloutBefore[ichwUnder - m_ichwAssocsMin], islotSurface);
- m_prgisloutAfter[ ichwUnder - m_ichwAssocsMin] =
- min(m_prgisloutAfter[ ichwUnder - m_ichwAssocsMin], islotSurface);
- }
-
- m_prgpvisloutAssocs[ichwUnder - m_ichwAssocsMin]->push_back(islotSurface);
-}
-
-/*----------------------------------------------------------------------------------------------
- Record an underlying-to-surface ligature mapping, based on the fact that there is
- a component.ref attribute in the surface stream. Note that if there was a previous
- ligature value there, it will be overwritten.
-
- @param ichwUnder - character index relative to the official beginning of the segment
- @param islotSurface - surface glyph it maps to
- @param iComponent - which component this glyph represents
-----------------------------------------------------------------------------------------------*/
-void Segment::RecordLigature(int ichwUnder, int islotSurface, int iComponent)
-{
- // If we are recording a mapping across the line boundary, make sure there
- // is space for it.
- EnsureSpaceAtLineBoundaries(ichwUnder);
-
- Assert(m_prgisloutLigature[ichwUnder - m_ichwAssocsMin] == kNegInfinity);
-
- m_prgisloutLigature[ichwUnder - m_ichwAssocsMin] = islotSurface;
- Assert(iComponent < kMaxComponentsPerGlyph);
- m_prgiComponent[ ichwUnder - m_ichwAssocsMin] = sdata8(iComponent);
-}
-
-/*----------------------------------------------------------------------------------------------
- The given slot is one that is rendered in the previous segment.
- If it is associated with a character officially in this segment, mark the
- before-association kNegInfinity.
-
- @param ichwUnder - character index relative to the official beginning of the segment
- @param islot - processed glyph it maps to
-----------------------------------------------------------------------------------------------*/
-void Segment::MarkSlotInPrevSeg(int ichwUnder, int islot)
-{
- if (ichwUnder >= m_ichwAssocsMin)
- m_prgisloutBefore[ichwUnder - m_ichwAssocsMin] = kNegInfinity;
-}
-
-/*----------------------------------------------------------------------------------------------
- The given slot is one that is rendered in the following segment.
- If it is associated with a character officially in this segment, mark the
- after-association kPosInfinity.
-
- @param ichwUnder - character index relative to the official beginning of the segment
- @param islot - processed glyph it maps to
-----------------------------------------------------------------------------------------------*/
-void Segment::MarkSlotInNextSeg(int ichwUnder, int islot)
-{
- if (ichwUnder < m_ichwAssocsLim)
- m_prgisloutAfter[ichwUnder - m_ichwAssocsMin] = kPosInfinity;
-}
-
-/*----------------------------------------------------------------------------------------------
- If we are recording an association across the line boundary (in either direction),
- make sure there is space for it. This involves adding space to the beginning or
- the end of the association arrays, and adjusting the min and lim indicators.
-----------------------------------------------------------------------------------------------*/
-void Segment::EnsureSpaceAtLineBoundaries(int ichwUnder)
-{
- int cchwNewMin = min(ichwUnder, m_ichwAssocsMin);
- int cchwNewLim = max(ichwUnder+1, m_ichwAssocsLim);
- if (cchwNewMin < m_ichwAssocsMin || cchwNewLim > m_ichwAssocsLim)
- {
- // Make space either at the beginning or the end of the arrays.
- int cchwPreAdd = m_ichwAssocsMin - cchwNewMin;
- int cchwPostAdd = cchwNewLim - m_ichwAssocsLim;
-
- int * prgisloutTmp = m_prgisloutBefore;
- m_prgisloutBefore = new int[cchwNewLim - cchwNewMin];
- std::copy(prgisloutTmp, prgisloutTmp + (m_ichwAssocsLim - m_ichwAssocsMin),
- m_prgisloutBefore + cchwPreAdd);
- delete[] prgisloutTmp;
-
- prgisloutTmp = m_prgisloutAfter;
- m_prgisloutAfter = new int[cchwNewLim - cchwNewMin];
- std::copy(prgisloutTmp, prgisloutTmp + (m_ichwAssocsLim - m_ichwAssocsMin),
- m_prgisloutAfter + cchwPreAdd);
- delete[] prgisloutTmp;
-
- std::vector<int> ** ppvisloutTmp = m_prgpvisloutAssocs;
- m_prgpvisloutAssocs = new std::vector<int> * [cchwNewLim - cchwNewMin];
- std::swap_ranges(m_prgpvisloutAssocs + cchwPreAdd,
- m_prgpvisloutAssocs + cchwPreAdd +
- (m_ichwAssocsLim - m_ichwAssocsMin), ppvisloutTmp);
- delete[] ppvisloutTmp;
-
- prgisloutTmp = m_prgisloutLigature;
- m_prgisloutLigature = new int[cchwNewLim - cchwNewMin];
- std::copy(prgisloutTmp, prgisloutTmp + (m_ichwAssocsLim - m_ichwAssocsMin),
- m_prgisloutLigature + cchwPreAdd);
- delete[] prgisloutTmp;
-
- sdata8 * prgiCompTmp = m_prgiComponent;
- m_prgiComponent = new sdata8[cchwNewLim - cchwNewMin];
- std::copy(prgiCompTmp, prgiCompTmp + (m_ichwAssocsLim - m_ichwAssocsMin),
- m_prgiComponent + cchwPreAdd);
- delete[] prgiCompTmp;
-
- // Initialize new slots.
- int i;
- for (i = 0; i < cchwPreAdd; ++i)
- {
- m_prgisloutBefore[i] = kPosInfinity;
- m_prgisloutAfter[i] = kNegInfinity;
- m_prgpvisloutAssocs[i] = new std::vector<int>;
- m_prgisloutLigature[i] = kNegInfinity;
- m_prgiComponent[i] = 0;
- }
- for (i = m_ichwAssocsLim - m_ichwAssocsMin + cchwPreAdd;
- i < m_ichwAssocsLim - m_ichwAssocsMin + cchwPreAdd + cchwPostAdd;
- ++i)
- {
- m_prgisloutBefore[i] = kPosInfinity;
- m_prgisloutAfter[i] = kNegInfinity;
- m_prgpvisloutAssocs[i] = new std::vector<int>;
- m_prgisloutLigature[i] = kNegInfinity;
- m_prgiComponent[i] = 0;
- }
- m_ichwAssocsMin = cchwNewMin;
- m_ichwAssocsLim = cchwNewLim;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the given output slot.
-----------------------------------------------------------------------------------------------*/
-GrSlotOutput * Segment::OutputSlot(int islout)
-{
- return m_prgslout + islout;
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the rendering engine to the current one.
-----------------------------------------------------------------------------------------------*/
-void Segment::SetEngine(GrEngine * pgreng)
-{
- //if (m_preneng)
- // m_preneng->DecRefCount();
- m_preneng = pgreng;
- //if (m_preneng)
- // m_preneng->IncRefCount();
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the font.
-----------------------------------------------------------------------------------------------*/
-void Segment::SetFont(Font * pfont)
-{
- m_pfont = pfont->copyThis();
-
-// m_fBold = pfont->bold();
-// m_fItalic = pfont->italic();
- // Note that we store the character height (which does not include the internal leading),
- // not the actual font height, ie, ascent + descent. This is what is used in the LOGFONT.
- pfont->getFontMetrics(NULL, NULL, &m_xysEmSquare); // m_xysEmSquare = m_pixHeight
-}
-
-/*----------------------------------------------------------------------------------------------
- Switch the font out.
- ??? Do we need to change the member variables too?
-----------------------------------------------------------------------------------------------*/
-void Segment::SwitchFont(Font * pfont)
-{
- m_pfont = pfont;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the engine implementation if it is a proper GrEngine, or NULL otherwise.
-----------------------------------------------------------------------------------------------*/
-GrEngine * Segment::EngineImpl()
-{
- return m_preneng;
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the justification agent, in case this segment will ever need to be stretched
- or shrunk.
-----------------------------------------------------------------------------------------------*/
-void Segment::SetJustifier(IGrJustifier * pgjus)
-{
- m_pgjus = pgjus;
- //if (pgjus)
- // pgjus->JustifierObject(&m_pgjus);
- //else
- // m_pgjus = NULL;
-}
-
-/*----------------------------------------------------------------------------------------------
- Set the graphics object to use the base font.
-----------------------------------------------------------------------------------------------*/
-//void Segment::SetToBaseFont(IGrGraphics * pgg)
-//{
-// if (m_fUseSepBase)
-// EngineImpl()->SwitchGraphicsFont(pgg, true);
-//}
-
-/*----------------------------------------------------------------------------------------------
- Restore the graphics object to use the font that it originally had when passed in to
- the interface method.
-----------------------------------------------------------------------------------------------*/
-//void Segment::RestoreFont(IGrGraphics * pgg)
-//{
-// if (m_fUseSepBase)
-// EngineImpl()->SwitchGraphicsFont(pgg, false);
-//}
-
-/*----------------------------------------------------------------------------------------------
- Given a logical surface location, return the underlying position (relative to the
- beginning of the string). NOTE that we are returning the index of the closest charater
- (plus an indication of which side the click was on), not a position between characters.
-
- @param islout - output slot
- @param xsOffset - x coordinate of physical click, relative to left of glyph;
- kPosInfinity means all the way to the right;
- kNegInfinity means all the way to the left
- @param ysOffset - y coordinate of physical click, relative to TOP of segment (NOT
- upwards from baseline); kPosInfinity means all the way at
- the top; kNegInfinity means all the way at the bottom
- @param dxsGlyphWidth - width of glyph clicked on, or 0 if irrelevant
- @param dysGlyphHeight - actually line height -- CURRENTLY NOT USED
- @param pfAfter - return true if they clicked on trailing side; possibly NULL
-----------------------------------------------------------------------------------------------*/
-int Segment::LogicalSurfaceToUnderlying(int islout, float xsOffset, float ysClick,
- float dxsGlyphWidth, float dysGlyphHeight, bool * pfAfter)
-{
- Assert(islout >= 0);
- Assert(islout < m_cslout);
-
- GrSlotOutput * pslout = OutputSlot(islout);
- bool fGlyphRtl = SlotIsRightToLeft(pslout);
-
- int dichw;
- bool fAfter, fRight;
-
- float ysForGlyph = pslout->YPosition();
-
- float dysFontAscent = m_dysFontAscent;
- ////GrResult res = GetFontAscentSourceUnits(pgg, &dysFontAscent);
- ////if (ResultFailed(res))
- //// THROW(WARN(res));
- dysFontAscent += m_dysXAscent;
-
- float dysOffset = ysClick - (m_dysAscent - dysFontAscent); // relative to top of 0-baseline text
-
- // If the slot has components, see if the offset falls within one of them.
-
- if (pslout->NumberOfComponents() > 0)
- {
- GrEngine * pgreng = EngineImpl();
- if (!pgreng)
- goto LNotLigature;
-
- GrGlyphTable * pgtbl = pgreng->GlyphTable();
-
- for (int icomp = 0; icomp < pslout->NumberOfComponents(); icomp++)
- {
- float xsLeft, xsRight, ysTop, ysBottom;
-
- // TODO: Rework ComponentIndexForGlyph to take slati rather than iForGlyph.
- int slati = pslout->ComponentId(icomp);
- int iForGlyph = pgtbl->ComponentIndexForGlyph(pslout->GlyphID(), slati);
- if (!pgtbl->ComponentBoxLogUnits(m_xysEmSquare, pslout->GlyphID(), iForGlyph,
- m_mFontEmUnits, m_dysAscent,
- &xsLeft, &ysTop, &xsRight, &ysBottom))
- {
- continue; // component not defined
- }
- Assert(xsLeft <= xsRight);
- Assert(ysTop <= ysBottom);
- if (xsOffset < xsLeft || xsOffset > xsRight)
- continue;
- if ((dysOffset - ysForGlyph) < ysTop || (dysOffset - ysForGlyph) > ysBottom)
- continue;
-
- // Click was within the component's box.
-
- dichw = pslout->UnderlyingComponent(icomp);
- Assert(m_ichwMin + dichw >= 0);
- Assert(dichw < m_dichwLim);
-
- fRight = (xsOffset - xsLeft > xsRight - xsOffset);
- fAfter = (fGlyphRtl) ? !fRight : fRight;
- if (pfAfter)
- *pfAfter = fAfter;
-
- Assert(GrCharStream::AtUnicodeCharBoundary(m_pgts, m_ichwMin + dichw));
-
- return m_ichwMin + dichw;
- }
- }
-
-LNotLigature:
-
- // No relevant ligature component.
- // If the x-offset is less than half way across,
- // answer the before-association; otherwise answer the after-association.
-
- if (xsOffset == kPosInfinity)
- fRight = true;
- else if (xsOffset == kNegInfinity)
- fRight = false;
- else
- fRight = (xsOffset > (dxsGlyphWidth / 2));
-
- fAfter = (fGlyphRtl) ? !fRight : fRight;
-
- int diCharAdj = 0;
- if (fAfter)
- {
- dichw = pslout->AfterAssoc();
- if (pfAfter)
- *pfAfter = true;
- // The following should not be necessary because of the way associations are set up:
- //while (!GrCharStream::AtUnicodeCharBoundary(m_pgts, ichwBase + dichw + diCharAdj))
- // diCharAdj++;
- }
- else
- {
- dichw = pslout->BeforeAssoc();
- if (pfAfter)
- *pfAfter = false;
- // The following should not be necessary because of the way associations are set up:
- //while (!GrCharStream::AtUnicodeCharBoundary(m_pgts, ichwBase + dichw + diCharAdj))
- // diCharAdj--;
- }
-
- if (dichw == kNegInfinity || dichw == kPosInfinity)
- return dichw;
-
- // This should be true because of the way the associations are set up:
- Assert(GrCharStream::AtUnicodeCharBoundary(m_pgts, m_ichwMin + dichw)); // + diCharAdj));
-
- return m_ichwMin + dichw + diCharAdj;
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int Segment::LogicalSurfaceToUnderlying(int islout, bool fBefore)
-{
- if (fBefore)
- return LogicalSurfaceToUnderlying(islout, kNegInfFloat, kNegInfFloat);
- else
- return LogicalSurfaceToUnderlying(islout, kPosInfFloat, kPosInfFloat);
-}
-
-/*----------------------------------------------------------------------------------------------
- Given a physical surface location (an index into the glyph boxes),
- return the underlying position, relative to the beginning of the string.
-
- @param igbb - index of glyph
- @param xsOffset - relative to left side of glyph
- @param ysOffset - downwards from top of segment (not upwards from baseline)
-----------------------------------------------------------------------------------------------*/
-int Segment::PhysicalSurfaceToUnderlying(
- int iginf, float xsOffset, float ysOffset,
- float dxsGlyphWidth, float dysGlyphHeight, bool * pfAfter)
-{
- int islout = iginf + m_isloutGinf0;
- return LogicalSurfaceToUnderlying(islout, xsOffset, ysOffset,
- dxsGlyphWidth, dysGlyphHeight, pfAfter);
-}
-
-/*--------------------------------------------------------------------------------------------*/
-
-int Segment::PhysicalSurfaceToUnderlying(int iginf, bool fBefore)
-{
- int islout = iginf + m_isloutGinf0;
- bool fGlyphRtl = SlotIsRightToLeft(OutputSlot(islout));
- if (fBefore == fGlyphRtl)
- return PhysicalSurfaceToUnderlying(iginf, kPosInfFloat, kPosInfFloat);
- else
- return PhysicalSurfaceToUnderlying(iginf, kNegInfFloat, kNegInfFloat);
-}
-
-/*----------------------------------------------------------------------------------------------
- Given an underlying position (relative to the beginning of the string),
- return the logical surface location (ignoring right-to-left).
- NOTE that ichw indicates a CHARACTER, not a location between characters. So ichw = 3,
- fBefore = false indicates a selection between characters 3 and 4.
- For surrogates, it indicates the FIRST of the pair of 16-bit chars.
-----------------------------------------------------------------------------------------------*/
-int Segment::UnderlyingToLogicalSurface(int ichw, bool fBefore)
-{
- int ichwSegOffset = ichw - m_ichwMin;
-
- if (ichwSegOffset < m_ichwAssocsMin)
- return kNegInfinity; // probably rendered in previous segment
-
-
- // if the buffers aren't even allocated, then it probably means there
- // wasn't room for any glyphs, so the following segment is most likely
-// else if (ichwSegOffset >= m_ichwAssocsLim)
- else if (ichwSegOffset >= m_ichwAssocsLim || !m_prgisloutBefore || !m_prgisloutAfter)
- return kPosInfinity; // probably rendered in following segment
-
- else if (fBefore)
- {
- int isloutRet;
- int ichw = ichwSegOffset;
- // If no association has been made, loop forward to the next slot
- // we are before. As a last resort, answer kPosInfinity, meaning we
- // aren't before anything.
- do
- {
- isloutRet = m_prgisloutBefore[ichw - m_ichwAssocsMin];
- do { ++ichw; }
- while (!GrCharStream::AtUnicodeCharBoundary(m_pgts, ichw));
- } while (isloutRet == kPosInfinity && ichw < m_ichwAssocsLim);
- return isloutRet;
- }
- else
- {
- int isloutRet;
- int ichw = ichwSegOffset;
- // If no association has been made, loop backward to the previous slot
- // we are after. As a last resort, answer kNegInfinity, meaning we
- // aren't after anything.
- do
- {
- isloutRet = m_prgisloutAfter[ichw - m_ichwAssocsMin];
- do { --ichw; }
- while (!GrCharStream::AtUnicodeCharBoundary(m_pgts, ichw));
- } while (isloutRet == kNegInfinity && ichw >= 0);
- return isloutRet;
- }
- Assert(false); // should never reach here
-}
-
-/*----------------------------------------------------------------------------------------------
- Given an underlying position (relative to the beginning of the string),
- return the physical surface location, the index into m_prgginf.
-----------------------------------------------------------------------------------------------*/
-int Segment::UnderlyingToPhysicalSurface(int ichw, bool fBefore)
-{
- int islout = UnderlyingToLogicalSurface(ichw, fBefore);
- return LogicalToPhysicalSurface(islout);
-}
-
-/*----------------------------------------------------------------------------------------------
- Given a logical position (index into output slots), return the physical position,
- the index into the list of glyphs (m_prgginf).
-----------------------------------------------------------------------------------------------*/
-int Segment::LogicalToPhysicalSurface(int islout)
-{
- if (islout == kNegInfinity || islout == kPosInfinity)
- return islout;
-
- Assert(m_prgginf[islout - m_isloutGinf0].logicalIndex() == (unsigned)(islout - m_isloutGinf0));
-
- return islout - m_isloutGinf0;
-}
-
-/*----------------------------------------------------------------------------------------------
- Given an underlying position (relative to the beginning of the string),
- return the physical surface locations of all the associated surface glyphs.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-#if 0
-void Segment::UnderlyingToPhysicalAssocs(int ichw, std::vector<int> & viginf)
-{
- int ichwSegOffset = ichw - m_ichwMin;
-
- if (ichwSegOffset < m_ichwAssocsMin)
- return; // possibly rendered in previous segment
-
- else if (ichwSegOffset >= m_ichwAssocsLim)
- return; // possibly rendered in following segment
-
- else
- {
- std::vector<int> * pvisloutTmp = &(m_prgvisloutAssocs[ichwSegOffset - m_ichwAssocsMin]);
-
- for (size_t i = 0; i < pvisloutTmp->size(); i++)
- {
- int islout = (*pvisloutTmp)[i];
- Assert(islout != kNegInfinity);
- Assert(islout != kPosInfinity);
- viginf.push_back(LogicalToPhysicalSurface(islout));
- }
- }
-}
-#endif
-
-/*----------------------------------------------------------------------------------------------
- Given an underlying character position (relative to the beginning of the string),
- return a pointer to the vector containing the logical surface locations of
- all the associated surface glyphs.
-
- Returns an empty vector (not something containing infinities) if the character is
- "invisible."
-----------------------------------------------------------------------------------------------*/
-std::vector<int> Segment::UnderlyingToLogicalAssocs(int ichw)
-{
- std::vector<int> vnEmpty;
- vnEmpty.clear();
- Assert(vnEmpty.size() == 0);
-
- int ichwSegOffset = ichw - m_ichwMin;
-
- if (ichwSegOffset < m_ichwAssocsMin)
- return vnEmpty; // probably rendered in previous segment
-
- else if (ichwSegOffset >= m_ichwAssocsLim)
- return vnEmpty; // probably rendered in following segment
-
- else if (m_prgpvisloutAssocs[ichwSegOffset - m_ichwAssocsMin] == NULL)
- {
- // Create a vector using the before and after values.
- std::vector<int> visloutRet;
- int isloutBefore = m_prgisloutBefore[ichwSegOffset - m_ichwAssocsMin];
- int isloutAfter = m_prgisloutAfter[ichwSegOffset - m_ichwAssocsMin];
- if (isloutBefore != kPosInfinity && isloutBefore != kNegInfinity)
- visloutRet.push_back(isloutBefore);
- if (isloutAfter != kPosInfinity && isloutAfter != kNegInfinity && isloutBefore != isloutAfter)
- {
- visloutRet.push_back(isloutAfter);
- }
- return visloutRet;
- }
- else
- {
- std::vector<int> * pvisloutRet = m_prgpvisloutAssocs[ichwSegOffset - m_ichwAssocsMin];
- return *pvisloutRet;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Given an underlying character position (relative to the beginning of the string),
- return an index of a slot in this segment that can used to test things like
- InsertBefore. Don't return kNegInfinity or kPosInfinity except as a last resort.
-----------------------------------------------------------------------------------------------*/
-int Segment::UnderlyingToLogicalInThisSeg(int ichw)
-{
- int isloutTest = kNegInfinity;
- std::vector<int> vislout = UnderlyingToLogicalAssocs(ichw);
- for (size_t iislout = 0; iislout < vislout.size(); iislout++)
- {
- isloutTest = vislout[iislout];
- if (isloutTest != kNegInfinity && isloutTest != kPosInfinity)
- return isloutTest;
- }
- return isloutTest;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return true if the two characters map to exactly the same set of glyphs.
-----------------------------------------------------------------------------------------------*/
-bool Segment::SameSurfaceGlyphs(int ichw1, int ichw2)
-{
- std::vector<int> vislout1 = UnderlyingToLogicalAssocs(ichw1);
- std::vector<int> vislout2 = UnderlyingToLogicalAssocs(ichw2);
-
- bool fRet = true;
- if (vislout1.size() == 0 || vislout2.size() == 0)
- fRet = false;
- else if (vislout1.size() != vislout2.size())
- fRet = false;
- else
- {
- for (size_t islout = 0; islout < vislout1.size(); islout++)
- {
- if (vislout1[islout] != vislout2[islout])
- {
- fRet = false;
- break;
- }
- }
- }
- return fRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the direction level of the given character.
-----------------------------------------------------------------------------------------------*/
-int Segment::DirLevelOfChar(int ichw, bool fBefore)
-{
- if (m_twsh == ktwshOnlyWs)
- return m_nDirDepth;
- int islot = UnderlyingToLogicalSurface(ichw, fBefore);
- if (islot == kNegInfinity || islot == kPosInfinity)
- return 0;
- int nDir = OutputSlot(islot)->DirLevel();
- if (nDir == -1)
- // Not calculated: assume to be the top direction level.
- nDir = TopDirLevel();
-
- return nDir;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return whether the given character is right-to-left.
-----------------------------------------------------------------------------------------------*/
-int Segment::CharIsRightToLeft(int ichw, bool fBefore)
-{
- int nDir = DirLevelOfChar(ichw, fBefore);
- return ((nDir % 2) != 0);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return whether the given slot is right-to-left.
-----------------------------------------------------------------------------------------------*/
-int Segment::SlotIsRightToLeft(GrSlotOutput * pslout)
-{
- if (m_twsh == ktwshOnlyWs)
- return (m_nDirDepth % 2);
- int nDir = pslout->DirLevel();
- if (nDir == -1)
- nDir = TopDirLevel();
- return (nDir % 2);
-}
-
-/*----------------------------------------------------------------------------------------------
- Check to make sure that the attachments are valid. Specifically, for every glyph that
- is part of a cluster, all glyphs between that glyph and its root must (ultimately) have
- that root glyph as one of its roots.
- OBSOLETE
-----------------------------------------------------------------------------------------------*/
-void Segment::AssertValidClusters(GrSlotStream * psstrm)
-{
-#ifdef _DEBUG
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslotThis = psstrm->SlotAt(islot);
- GrSlotState * pslotRoot = pslotThis->AttachRoot(psstrm);
- if (!pslotRoot)
- continue;
- Assert(pslotRoot != pslotThis);
-
- int inc = (pslotThis->PosPassIndex() > pslotRoot->PosPassIndex()) ? -1 : 1;
-
- for (int islot2 = pslotThis->PosPassIndex() + inc;
- islot2 != pslotRoot->PosPassIndex();
- islot2 += inc)
- {
- GrSlotState * pslotMid = psstrm->SlotAt(islot2);
- Assert(pslotMid->HasAsRoot(psstrm, pslotRoot));
- }
- }
-#endif // _DEBUG
-}
-
-/*----------------------------------------------------------------------------------------------
- Return information about (editing) clusters as appropriate for Uniscribe, ie, consistent
- with the ScriptShape funciton.
- A cluster includes all attachments, all clumps of characters created by insert = false,
- and clumps of reordered glyphs.
-
- prgiginfFirstOfCluster returns the first glyph of the cluster for each CHARACTER
- (glyph indices returned are zero-based and refer to physical order--left-to-right, etc.).
- pfClusterStart returns a flag for each GLYPH indicating whether it is the first (left-most)
- of a cluster.
- Both arrays are optional.
- CORRECTION: for now we use strictly logical order. It's not clear whether physical
- order is needed for right-to-left text or not. See note below.
-
- TODO: convert from GlyphInfo objects which are RTL.
-----------------------------------------------------------------------------------------------*/
-GrResult Segment::getUniscribeClusters(
- int * prgiginfFirstOfCluster, int cchMax, int * pcch,
- bool * pfClusterStart, int cfMax, int * pcf)
-{
- ChkGrOutPtr(pcch);
- if (prgiginfFirstOfCluster)
- ChkGrArrayArg(prgiginfFirstOfCluster, cchMax);
- ChkGrOutPtr(pcf);
- if (pfClusterStart)
- ChkGrArrayArg(pfClusterStart, cfMax);
-
- GrResult res = kresOk;
-
- //SetUpGraphics(ichwBase, pgg, true);
-
- if (m_dxsWidth == -1)
- ComputeDimensions();
-
- Assert(m_dxsWidth >= 0);
- Assert(m_dysAscent >= 0);
-
- if (pcch)
- *pcch = m_dichwLim;
- if (pcf)
- *pcf = m_cginf;
- if (cchMax < m_dichwLim)
- {
- if (cchMax == 0 && cfMax == 0)
- res = kresFalse; // just asking for size information
- else if (prgiginfFirstOfCluster || cchMax > 0)
- res = kresInvalidArg; // not enough space
- }
- if (cfMax < m_cginf)
- {
- if (cchMax == 0 && cfMax == 0)
- res = kresFalse;
- else if (pfClusterStart || cfMax > 0)
- res = kresInvalidArg;
- }
- if (res != kresOk)
- {
- //RestoreFont(pgg);
- ReturnResult(res);
- }
-
- // Generate a pair of arrays, indicating the first and last (logical) slots
- // of the cluster for each character. Initially clusters are based just on
- // character-to-glyph associations, but they expand as we process
- // insert=false settings, attachments, and reordering.
-
- std::vector<int> visloutBefore;
- std::vector<int> visloutAfter;
- visloutBefore.resize(m_dichwLim);
- visloutAfter.resize(m_dichwLim);
-
- int ich;
- for (ich = 0; ich < m_dichwLim; ich++)
- {
- visloutBefore[ich] = m_prgisloutBefore[ich - m_ichwAssocsMin];
- visloutAfter[ich] = m_prgisloutAfter[ich - m_ichwAssocsMin];
- }
-
- if (m_dichwLim == 1)
- {
- // Only one character, therefore only one cluster.
- visloutBefore[0] = m_isloutGinf0;
- visloutAfter[0] = max(m_cginf - 1, 0) + m_isloutGinf0;
- }
- else
- {
- // Make all glyphs attached to each other part of a cluster, or glyphs where
- // insertion is not allowed.
- for (ich = 0; ich < m_dichwLim; ich++)
- {
- std::vector<int> vislout = UnderlyingToLogicalAssocs(ich + m_ichwMin);
-
- if (vislout.size() == 0)
- {
- // No glyphs represent this character. Merge it with the previous
- // character.
- visloutBefore[ich] = (ich == 0) ? visloutBefore[ich + 1] : visloutBefore[ich - 1];
- visloutAfter[ich] = (ich == 0) ? visloutAfter[ich + 1] : visloutAfter[ich - 1];
- continue;
- }
-
- size_t iislout;
- for (iislout = 0; iislout < vislout.size(); iislout++)
- {
- int islout = vislout[iislout];
- if (!m_prgslout[islout].InsertBefore())
- {
- // This glyph does not allow insertion before it; make its character part
- // of the same cluster as the previous character.
- MergeUniscribeCluster(visloutBefore, visloutAfter, ich - 1, ich);
-/*
-+ // Keith Stribley's fix:
-+ // NOTE: this is NOT always the same as the previous character, so
-+ // check whether the next character actually has a glyph before this
-+ // one
-+ if ((ich == m_dichwLim - 1) ||
-+ (std::min(visloutBefore[ich + 1], visloutAfter[ich + 1]) >
-+ std::max(visloutBefore[ich], visloutAfter[ich])))
-+ {
-+ MergeUniscribeCluster(visloutBefore, visloutAfter, ich - 1, ich);
-+ }
-+ else
-+ MergeUniscribeCluster(visloutBefore, visloutAfter, ich, ich + 1);
-*/
- }
- else if (m_prgslout[islout].ClusterBase() != -1
- && m_prgslout[islout].ClusterBase() != islout)
- {
- // This glyph is attached to something; make them part of the same cluster.
- int isloutBase = m_prgslout[islout].ClusterBase();
- int ichBase = LogicalSurfaceToUnderlying(isloutBase, false) - m_ichwMin;
- MergeUniscribeCluster(visloutBefore, visloutAfter,
- ich, ichBase);
- int ichBase1 = LogicalSurfaceToUnderlying(isloutBase, false) - m_ichwMin;
- if (ichBase1 != ichBase)
- MergeUniscribeCluster(visloutBefore, visloutAfter,
- ich, ichBase1);
- }
- }
- }
-
- // Handle reordering. Whenever the islout values get out of order, we need to
- // merge into a single cluster.
- for (ich = 0; ich < m_dichwLim - 1; ich++)
- {
- Assert(visloutBefore[ich] <= visloutAfter[ich]);
- Assert(visloutBefore[ich] != kPosInfinity);
- Assert(visloutBefore[ich] != kNegInfinity);
- Assert(visloutAfter[ich] != kPosInfinity);
- Assert(visloutAfter[ich] != kNegInfinity);
- const int b1 = visloutBefore[ich];
- const int a1 = visloutAfter[ich];
- const int b2 = visloutBefore[ich + 1];
- const int a2 = visloutAfter[ich + 1];
- if (b1 == b2 && a1 == a2)
- continue; // already a cluster
-
- if (std::min(b2, a2) <= std::max(b1, a1))
- {
- MergeUniscribeCluster(visloutBefore, visloutAfter, ich, ich + 1);
- }
- }
- }
-
- if (pfClusterStart)
- {
- // Initialize.
- int iginf;
- for (iginf = 0; iginf < m_cginf; iginf++)
- pfClusterStart[iginf] = false;
- }
-
- // To skip line-break slots; remember that the number of output slots equals the
- // number of gbbs plus initial and/or final line-break slots if any.
- // In this case the beginning of the first cluster indicates the first real glyph.
- int isloutFirstReal = (m_dichwLim) ? ((m_fWsRtl)? visloutAfter[0] : visloutBefore[0]) : 0;
-
- // Kludge to make assertions below easier:
- if (m_dichwLim > 0)
- {
- visloutBefore.push_back(visloutAfter.back() + 1);
- visloutAfter.push_back(visloutAfter.back() + 1);
- }
-
- // Convert (logical) slots to actual glyphs.
- for (ich = 0; ich < m_dichwLim; ich++)
- {
- // NOTE: to treat the first of the cluster as the left-most, use visloutAfter for
- // right-to-left situations.
-
- if (prgiginfFirstOfCluster)
- prgiginfFirstOfCluster[ich]
- = LogicalToPhysicalSurface((m_fWsRtl) ? visloutAfter[ich] : visloutBefore[ich]);
- int clusterStartPos = ((m_fWsRtl) ? visloutAfter[ich] : visloutBefore[ich]) - isloutFirstReal;
- if (pfClusterStart)
- pfClusterStart[clusterStartPos] = true;
-
- Assert((visloutBefore[ich] == visloutBefore[ich + 1] &&
- visloutAfter[ich] == visloutAfter[ich + 1])
- || (visloutBefore[ich] <= visloutAfter[ich] &&
- visloutAfter[ich] < visloutBefore[ich + 1]));
- }
-
- //RestoreFont(pgg);
-
- return kresOk;
-}
-
-
-// suppress GCC 4.3 warning for optimized min()/max() when called with (ich, ich+1) or similar
-#pragma GCC diagnostic ignored "-Wstrict-overflow"
-
-/*----------------------------------------------------------------------------------------------
- Merge the given characters into the same Uniscribe cluster. This means merging any
- intervening characters as well.
-----------------------------------------------------------------------------------------------*/
-void Segment::MergeUniscribeCluster(
- std::vector<int> & visloutBefore, std::vector<int> & visloutAfter,
- int ich1, int ich2)
-{
- int ichStartOrig = min(ich1, ich2);
- int ichStopOrig = max(ich1, ich2);
-
- int isloutMin = visloutBefore[ichStopOrig];
- int isloutMax = visloutAfter[ichStartOrig];
-
- int ichStart = ichStopOrig;
- int ichStop = ichStartOrig;
- // Find the beginning of the cluster.
- while (ichStart > 0 &&
- (ichStart > ichStartOrig
- || visloutBefore[ichStart - 1] >= visloutBefore[ichStopOrig]
- || visloutBefore[ichStart - 1] == visloutBefore[ichStart]))
- {
- ichStart--;
- isloutMin = std::min(isloutMin, visloutBefore[ichStart]);
- isloutMax = std::max(isloutMax, visloutAfter[ichStart]);
- }
- // Find end of cluster.
- while (ichStop < m_dichwLim - 1 &&
- (ichStop < ichStopOrig
- || visloutAfter[ichStop + 1] <= visloutAfter[ichStartOrig]
- || visloutAfter[ichStop + 1] == visloutAfter[ichStop]))
- {
- ichStop++;
- isloutMin = std::min(isloutMin, visloutBefore[ichStop]);
- isloutMax = std::max(isloutMax, visloutAfter[ichStop]);
- }
-
- int ich;
- for (ich = ichStart; ich <= ichStop; ich++)
- {
- visloutBefore[ich] = isloutMin;
- visloutAfter[ich] = isloutMax;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Return information about the positioning of glyphs as appropriate for Uniscribe.
- The advance widths returned are the natural ones (what would be applied if no smart
- rendering were happening), and the x-offsets are the difference between the
- natural location of the glyph and what is produced by Graphite. The y-offset
- is the same as GetGlyphsAndPositions.
-
- This is an experimental method. Its behavior may change signficantly in the future.
-----------------------------------------------------------------------------------------------*/
-/*
-GrResult Segment::GetUniscribePositions(
- Rect rs, Rect rd, int cgidMax, int *pcgidRet,
- float * prgxd, float * prgyd, float * prgdxdAdv)
-{
- ChkGrOutPtr(pcgidRet);
- ChkGrArrayArg(prgxd, cgidMax);
- ChkGrArrayArg(prgyd, cgidMax);
- ChkGrArrayArg(prgdxdAdv, cgidMax);
-
- GrResult res;
-
- //SetUpGraphics(ichBase, pgg, true);
-
- Assert(m_dxsWidth >= 0);
- Assert(m_dysAscent >= 0);
-
- *pcgidRet = m_cginf;
- if (cgidMax < m_cginf)
- {
- res = (cgidMax == 0) ? kresFalse : kresInvalidArg;
- //RestoreFont(pgg);
- ReturnResult(res);
- }
-
- if (m_dxsWidth < 0)
- ComputeDimensions();
-
- float * rgxdTmp = new float[cgidMax];
- float * rgdxdAdvTmp = new float[cgidMax];
- res = GetGlyphsAndPositions(rs, rd, cgidMax, pcgidRet,
- NULL, rgxdTmp, prgyd, rgdxdAdvTmp);
- if (ResultFailed(res))
- {
- delete[] rgxdTmp;
- delete[] rgdxdAdvTmp;
- //RestoreFont(pgg);
- ReturnResult(res);
- }
-
- float xdLeft = SegmentPainter::ScaleX(0, rs, rd);
- float xdXPosNatural = xdLeft;
- for (int iginf = 0; iginf < *pcgidRet; iginf++)
- {
- int islout = iginf + m_isloutGinf0;
- GrSlotOutput * pslout = OutputSlot(islout);
- float dxsAdvNatural = pslout->AdvanceXMetric();
- float dxdAdvNatural = SegmentPainter::ScaleX(dxsAdvNatural, rs, rd) - xdLeft;
- prgdxdAdv[iginf] = dxdAdvNatural;
- prgxd[iginf] = rgxdTmp[iginf] - xdXPosNatural;
-
- xdXPosNatural += dxdAdvNatural;
- }
-
- delete[] rgxdTmp;
- delete[] rgdxdAdvTmp;
-
- //RestoreFont(pgg);
-
- ReturnResult(res);
-
-}
-*/
-
-/*----------------------------------------------------------------------------------------------
- Return information about the positioning of glyphs as appropriate for Uniscribe.
- The advance widths returned are the natural ones (what would be applied if no smart
- rendering were happening), and the x-offsets are the difference between the
- natural location of the glyph and what is produced by Graphite. The y-offset
- is the same as GetGlyphsAndPositions.
-
- This is an experimental method. Its behavior may change signficantly in the future.
-----------------------------------------------------------------------------------------------*/
-/*
-GrResult Segment::GetUniscribeGlyphsAndPositions(
- Rect rs, Rect rd, int cgidMax, int *pcgidRet, utf16 * prgchGlyphs,
- float * prgxd, float * prgyd, float * prgdxdAdv)
-{
- ChkGrOutPtr(pcgidRet);
- ChkGrArrayArg(prgxd, cgidMax);
- ChkGrArrayArg(prgyd, cgidMax);
- ChkGrArrayArg(prgdxdAdv, cgidMax);
-
- GrResult res;
-
- //SetUpGraphics(ichBase, pgg, true);
-
- Assert(m_dxsWidth >= 0);
- Assert(m_dysAscent >= 0);
-
- *pcgidRet = m_cginf;
- if (cgidMax < m_cginf)
- {
- res = (cgidMax == 0) ? kresFalse : kresInvalidArg;
- //RestoreFont(pgg);
- ReturnResult(res);
- }
-
- if (m_dxsWidth < 0)
- ComputeDimensions();
-
- float * rgxdTmp = new float[cgidMax];
- float * rgdxdAdvTmp = new float[cgidMax];
- res = GetGlyphsAndPositions(rs, rd, cgidMax, pcgidRet,
- prgchGlyphs, rgxdTmp, prgyd, rgdxdAdvTmp);
- if (ResultFailed(res))
- {
- delete[] rgxdTmp;
- delete[] rgdxdAdvTmp;
- //RestoreFont(pgg);
- ReturnResult(res);
- }
-
- float xdLeft = SegmentPainter::ScaleX(0, rs, rd);
- float xdXPosNatural = xdLeft;
- for (int iginf = 0; iginf < *pcgidRet; iginf++)
- {
- int islout = iginf + m_isloutGinf0;
- GrSlotOutput * pslout = OutputSlot(islout);
- float dxsAdvNatural = pslout->AdvanceXMetric();
- float dxdAdvNatural = SegmentPainter::ScaleX(dxsAdvNatural, rs, rd) - xdLeft;
- prgdxdAdv[iginf] = dxdAdvNatural;
- prgxd[iginf] = rgxdTmp[iginf] - xdXPosNatural;
-
- xdXPosNatural += dxdAdvNatural;
- }
-
- delete[] rgxdTmp;
- delete[] rgdxdAdvTmp;
-
- //RestoreFont(pgg);
-
- ReturnResult(res);
-}
-*/
-
-/*----------------------------------------------------------------------------------------------
- Return the visual box for the given ligature component. Return (0,0,0,0) if the component
- is not defined.
-----------------------------------------------------------------------------------------------*/
-Rect Segment::ComponentRect(GrSlotOutput * pslout, int icomp)
-{
- Rect rectRet;
- rectRet.top = rectRet.bottom = rectRet.left = rectRet.right = 0;
- if (icomp < 0 || icomp > pslout->NumberOfComponents())
- return rectRet;
-
- GrEngine * pgreng = EngineImpl();
- if (!pgreng)
- return rectRet;
- GrGlyphTable * pgtbl = pgreng->GlyphTable();
- if (!pgtbl)
- return rectRet;
-
- float xsLeft, xsRight, ysTop, ysBottom;
-
- // TODO: Rework ComponentIndexForGlyph to take slati rather than iForGlyph.
- int slati = pslout->ComponentId(icomp);
- int iForGlyph = pgtbl->ComponentIndexForGlyph(pslout->GlyphID(), slati);
- if (!pgtbl->ComponentBoxLogUnits(m_xysEmSquare, pslout->GlyphID(), iForGlyph,
- m_mFontEmUnits, m_dysAscent,
- &xsLeft, &ysTop, &xsRight, &ysBottom,
- false)) // origin is baseline
- {
- return rectRet;
- }
- rectRet.top = ysTop;
- rectRet.bottom = ysBottom;
- rectRet.left = xsLeft;
- rectRet.right = xsRight;
-
- return rectRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Shift the glyphs physically by the given amount. This happens when a right-to-left
- segment is changed from being end-of-line to not, so we have to account for the fact
- that the trailing white-space was previous invisible but is now visible.
-----------------------------------------------------------------------------------------------*/
-void Segment::ShiftGlyphs(float dxsShift)
-{
- for (int islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * pslout = OutputSlot(islout);
- pslout->AdjustPosXBy(dxsShift);
- }
-
- //ShiftGlyphsPlatform(dxsShift);
-}
-
-/*----------------------------------------------------------------------------------------------
- Find the glyph that best matches the given click location.
-
- @param xsClick - relative to start of segment
- @param ysClick - relative to segment baseline
-----------------------------------------------------------------------------------------------*/
-int Segment::GlyphHit(float xsClick, float ysClick)
-{
- float xsLeft = kPosInfFloat;
- float xsRight = kNegInfFloat;
-
- int iginf;
- for (iginf = 0; iginf < m_cginf; iginf++)
- {
- GlyphInfo * pginf = m_prgginf + iginf;
- xsLeft = min(xsLeft, pginf->origin());
- xsRight = max(xsRight, pginf->origin() + pginf->advanceWidth());
- }
-
- if (xsClick < xsLeft)
- return m_fWsRtl ? m_cginf - 1 : 0;
- else if (xsClick > xsRight)
- return m_fWsRtl ? 0 : m_cginf - 1;
-
- int iginfHit;
- std::vector<int> viginfNear;
- std::vector<int> viginfHit;
- std::vector<int> viginfInside;
-
- // Find glyph which might contain click point.
-
- for (iginfHit = m_cginf; iginfHit-- > 0; )
- {
- if (m_fWsRtl)
- {
- if (m_prgginf[iginfHit].bb().right >= xsClick)
- break;
- }
- else
- {
- if (m_prgginf[iginfHit].bb().left <= xsClick)
- break;
- }
- }
- if (iginfHit < 0) // click within lsb of first glyph
- {
- return 0;
- }
-
- // Find all BB that OVERLAP the click point (bb.left < XClick < bb.right).
- for (iginf = iginfHit; iginf >= 0; iginf--)
- {
- Rect rectBB = m_prgginf[iginf].bb();
- if (rectBB.left <= xsClick && xsClick <= rectBB.right)
- {
- viginfNear.push_back(iginf);
- }
- }
-
- // Find all BB that CONTAIN the click point (considering the click's Y coor too).
- int iiginf;
- for (iiginf = 0; iiginf < (int)viginfNear.size(); iiginf++)
- {
- Rect rectBB = m_prgginf[viginfNear[iiginf]].bb();
- if (rectBB.bottom <= ysClick && ysClick <= rectBB.top)
- {
- viginfHit.push_back(viginfNear[iiginf]);
- }
- }
-
- if (viginfNear.size() > 2 && viginfHit.size() == 0)
- {
- // No hit along y-axis; find the closest thing.
- float dy = float(10000000.0);
- for (int iiginf2 = 0; iiginf2 < (int)viginfNear.size(); iiginf2++)
- {
- Rect rectBB = m_prgginf[viginfNear[iiginf2]].bb();
- if (fabsf(rectBB.top - ysClick) < dy)
- {
- dy = fabsf(rectBB.top - ysClick);
- viginfHit.clear();
- viginfHit.push_back(viginfNear[iiginf2]);
- }
- if (fabsf(rectBB.bottom - ysClick) < dy)
- {
- dy = fabsf(rectBB.bottom - ysClick);
- viginfHit.clear();
- viginfHit.push_back(viginfNear[iiginf2]);
- }
- }
- }
-
- // Find all BB for which the click is within their advance width, if any.
- for (iiginf = 0; iiginf < (int)viginfHit.size(); iiginf++)
- {
- //Rect rectBB = m_prgginf[viginfHit[iiginf]].bb(); -- ?? this tests the bounding box again :-/
- //if (rectBB.left <= xsClick && xsClick <= rectBB.right)
- gr::GlyphInfo * pginf = m_prgginf + viginfHit[iiginf];
- if (pginf->advanceWidth() == 0 // advance width is irrelevant
- || (pginf->origin() < xsClick && xsClick <= pginf->origin() + pginf->advanceWidth()))
- {
- viginfInside.push_back(viginfHit[iiginf]);
- }
- }
-
- // If no BB coincides in any way with the click point, take the BB whose leading edge
- // is closest to the click point.
- // There could be more than one BB with the same leading x coor.
- if (viginfHit.size() == 0 && viginfNear.size() == 0 && viginfInside.size() == 0)
- {
- float xsLeading;
- if (iginfHit + 1 == m_cginf)
- {
- viginfNear.push_back(iginfHit);
- }
- else if (!m_fWsRtl)
- {
- // Left-to-right:
- xsLeading = m_prgginf[iginfHit + 1].bb().left;
- for (iginf = iginfHit + 1; iginf < m_cginf; iginf++)
- {
- if (m_prgginf[iginf].bb().left == xsLeading)
- viginfNear.push_back(iginf);
- }
- }
- else
- {
- // Right-to-left:
- xsLeading = m_prgginf[iginfHit].bb().right;
- for (iginf = iginfHit; iginf < m_cginf; iginf++)
- {
- if (m_prgginf[iginf].bb().right == xsLeading)
- viginfNear.push_back(iginf);
- }
- }
- }
-
- Assert(viginfNear.size());
-
- int iginfLoc;
-
- // Select the BB based on its leading edge, offset from baseline, position in final pass.
- if (viginfInside.size())
- iginfLoc = SelectBb(viginfInside, m_fWsRtl);
- else if (viginfHit.size())
- iginfLoc = SelectBb(viginfHit, m_fWsRtl);
- else
- iginfLoc = SelectBb(viginfNear, m_fWsRtl);
-
- return iginfLoc;
-}
-
-/*----------------------------------------------------------------------------------------------
- Select the bounding box we will use for a mouse hit.
- First select any glyph with a significantly smaller bounding box.
- Then, select the BB with the left-most (LTR) or right-most (RTL) edge.
- If more than one BB has same edge of interest, select the one that is closest to the
- the baseline.
- If that is a tie, select the one with the lowest islout.
-
- @param vigbb - list of indexes into m_prggbb
- @param fRTL - writing system direction
-----------------------------------------------------------------------------------------------*/
-int Segment::SelectBb(std::vector<int> & viginf, bool fRTL)
-{
- if (!viginf.size())
- {
- Assert(false);
- return -1;
- }
-
- if (viginf.size() == 1)
- return viginf[0];
-
- // Find a glyph that has a signficantly smaller bounding box.
- // The idea is that it is going to be harder to hit than the bigger glyph.
- float smallestArea = float(1000000000.0);
- float largestArea = 0.0;
- size_t iiginfSmallest = 0;
- size_t iiginf;
- for (iiginf = 0; iiginf < viginf.size(); iiginf++)
- {
- gr::GlyphInfo * pginf = m_prgginf + viginf[iiginf];
- Rect rectBB = pginf->bb();
- float thisArea = (rectBB.right - rectBB.left) * (rectBB.top - rectBB.bottom);
- if (smallestArea > thisArea)
- {
- smallestArea = thisArea;
- iiginfSmallest = iiginf;
- }
- largestArea = max(largestArea, thisArea);
- }
- if (smallestArea * 2.0 < largestArea)
- return viginf[iiginfSmallest];
-
- // Find appropriate x coor of leading edge.
- float xsLeading;
- if (!fRTL)
- xsLeading = m_prgginf[viginf[0]].bb().left;
- else
- xsLeading = m_prgginf[viginf[0]].bb().right;
-
- for (iiginf = 1; iiginf < viginf.size(); iiginf++)
- {
- Rect rectBB = m_prgginf[viginf[iiginf]].bb();
- if (!fRTL)
- xsLeading = min(xsLeading, rectBB.left);
- else
- xsLeading = max(xsLeading, rectBB.right);
- }
-
- // Find BBs with the leading edge.
- std::vector<int> viginfSameEdge;
- for (iiginf = 0; iiginf < viginf.size(); iiginf++)
- {
- Rect rectBB = m_prgginf[viginf[iiginf]].bb();
- if (!fRTL)
- {
- if (rectBB.left == xsLeading)
- viginfSameEdge.push_back(viginf[iiginf]);
- }
- else
- {
- if (rectBB.right == xsLeading)
- viginfSameEdge.push_back(viginf[iiginf]);
- }
- }
-
- if (viginfSameEdge.size() == 1)
- return viginfSameEdge[0];
-
- // Find minimum distance from baseline.
- float ysMin = fabsf(m_prgginf[viginfSameEdge[0]].yOffset());
- for (iiginf = 1; iiginf < viginfSameEdge.size(); iiginf++)
- {
- float ysThis = fabsf(m_prgginf[viginfSameEdge[iiginf]].yOffset());
- ysMin = min(ysMin, ysThis);
- }
-
- // Find BBs with minimum distance from baseline.
- std::vector<int> viginfSameY;
- for (iiginf = 0; iiginf < viginfSameEdge.size(); iiginf++)
- {
- if (fabsf(m_prgginf[viginfSameEdge[iiginf]].yOffset()) == ysMin)
- viginfSameY.push_back(viginfSameEdge[iiginf]);
- }
-
- if (viginfSameY.size() == 1)
- return viginfSameY[0];
-
- // Find minimum index of current candidates.
- int islout = m_prgginf[viginfSameY[0]].logicalIndex();
- for (iiginf = 1; iiginf < viginfSameY.size(); iiginf++)
- {
- int isloutThis = m_prgginf[viginfSameY[iiginf]].logicalIndex();
- islout = min(islout, isloutThis);
- }
-
- // Find BB with minimum islout - islout should be unique for all glyphs.
- for (iiginf = 0; iiginf < viginfSameY.size(); iiginf++)
- {
- if (m_prgginf[viginfSameY[iiginf]].logicalIndex() == (unsigned)islout)
- return viginfSameY[iiginf];
- }
-
- Assert(false);
- return -1; // needed to stop compiler warning
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the right-most glyph on the physical surface. If there are ties, it will
- prefer the one that is logically closest to the edge.
-----------------------------------------------------------------------------------------------*/
-int Segment::RightMostGlyph()
-{
- float xsRight = kNegInfFloat;
- int iginfRet = -1;
- for (int iginf = 0; iginf < m_cginf; iginf++)
- {
- float xsThis = m_prgginf[iginf].bb().right;
- // For RTL, we prefer the glyph that is logically first; for LTR we prefer logically last.
- if (xsThis > xsRight || (!m_fWsRtl && xsRight == xsThis))
- {
- xsRight = xsThis;
- iginfRet = iginf;
- }
- }
- return iginfRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the left-most glyph on the physical surface. If there are ties, it will
- prefer the one that is logically closest to the edge.
-----------------------------------------------------------------------------------------------*/
-int Segment::LeftMostGlyph()
-{
- float xsLeft = kPosInfFloat;
- int iginfRet = -1;
- for (int iginf = 0; iginf < m_cginf; iginf++)
- {
- float xsThis = m_prgginf[iginf].bb().left;
- // For RTL, we prefer the glyph that is logically last; for LTR we prefer logically first.
- if (xsThis < xsLeft || (m_fWsRtl && xsLeft == xsThis))
- {
- xsLeft = xsThis;
- iginfRet = iginf;
- }
- }
- return iginfRet;
-}
-
-/*----------------------------------------------------------------------------------------------
- Convert from em-units to logical units.
-----------------------------------------------------------------------------------------------*/
-float Segment::EmToLogUnits(int m)
-{
- return GrEngine::GrIFIMulDiv(m, m_xysEmSquare, m_mFontEmUnits);
-}
-
-/*----------------------------------------------------------------------------------------------
- Return the line-break pseudo glyph ID.
-----------------------------------------------------------------------------------------------*/
-gid16 Segment::LBGlyphID()
-{
- return m_preneng->LBGlyphID();
-}
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/SegmentAux.cpp b/Build/source/libs/graphite-engine/src/segment/SegmentAux.cpp
deleted file mode 100644
index 9191e8724d5..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/SegmentAux.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/*--------------------------------------------------------------------*//*:Ignore this sentence.
-Copyright (C) 2005 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: SegmentAux.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Implements auxiliary class that work with Segment:
- - GlyphInfo
- - GlyphIterator
- - LayoutEnvironment
--------------------------------------------------------------------------------*//*:End Ignore*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-// any other headers (not precompiled)
-#ifndef _WIN32
-#include <stdlib.h>
-#endif
-
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> GlyphInfo methods
-//:>********************************************************************************************
-
-gid16 GlyphInfo::glyphID()
-{
- return m_pslout->m_chwActual;
-}
-
-gid16 GlyphInfo::pseudoGlyphID()
-{
- if (m_pslout->m_chwActual == m_pslout->m_chwGlyphID)
- return 0; // not a pseudo-glyph
- return m_pslout->m_chwGlyphID;
-}
-
-bool GlyphInfo::isAttached() const throw()
-{
- return m_pslout->IsPartOfCluster();
-}
-
-gr::GlyphIterator GlyphInfo::attachedClusterBase() const throw()
-{
- const int islout = m_pslout->ClusterBase();
-
- // Since we are not passing an array, the constructor expects a ginf index, not a slout index.
- return GlyphIterator(*m_pseg, ((islout >= 0) ? islout : m_islout) - m_pseg->m_isloutGinf0);
-}
-
-float GlyphInfo::attachedClusterAdvance() const throw()
-{
- return m_pslout->ClusterAdvance();
-}
-
-std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> GlyphInfo::attachedClusterGlyphs() const
-{
- std::vector<int> visloutClusterMembers;
- m_pslout->ClusterMembers(m_pseg, m_islout, visloutClusterMembers);
- RcVector * qvislout = new RcVector(visloutClusterMembers);
- return std::make_pair(
- GlyphSetIterator(*m_pseg, 0, qvislout),
- GlyphSetIterator(*m_pseg, visloutClusterMembers.size(), qvislout));
-}
-
-size_t GlyphInfo::logicalIndex()
-{
- if (m_pseg->OutputSlot(0)->IsLineBreak())
- return m_islout - 1;
- else
- return m_islout;
-}
-
-float GlyphInfo::origin()
-{
- return m_pslout->XPosition();
-}
-
-float GlyphInfo::advanceWidth() // logical units
-{
- return m_pslout->m_xsAdvanceX;
-}
-
-float GlyphInfo::advanceHeight() // logical units; zero for horizontal fonts
-{
- Font & font = m_pseg->getFont();
- return m_pslout->GlyphMetricLogUnits(&font, kgmetAdvHeight);
-}
-
-float GlyphInfo::yOffset()
-{
- return m_pslout->YPosition();
-}
-
-Rect GlyphInfo::bb() // logical units
-{
- return m_pslout->BoundingBox(m_pseg->getFont());
-}
-
-bool GlyphInfo::isSpace()
-{
- return m_pslout->IsSpace();
-}
-
-// first char associated with this glyph, relative to start of the text-source
-toffset GlyphInfo::firstChar()
-{
- return m_pseg->LogicalSurfaceToUnderlying(m_islout, true);
-}
-
-// last char associated with this glyph, relative to start of the text-source
-toffset GlyphInfo::lastChar()
-{
- return m_pseg->LogicalSurfaceToUnderlying(m_islout, false);
-}
-
-unsigned int GlyphInfo::directionality()
-{
- return m_pslout->Directionality();
-}
-
-// Embedding depth
-unsigned int GlyphInfo::directionLevel()
-{
- return m_pslout->DirLevel();
-}
-
-bool GlyphInfo::insertBefore()
-{
- return m_pslout->InsertBefore();
-}
-
-int GlyphInfo::breakweight()
-{
- return m_pslout->BreakWeight();
-}
-
-float GlyphInfo::maxStretch(size_t level)
-{
- return m_pslout->MaxStretch(m_pseg, (int)level);
-}
-
-float GlyphInfo::maxShrink(size_t level)
-{
- return m_pslout->MaxShrink(m_pseg, (int)level);
-}
-
-float GlyphInfo::stretchStep(size_t level)
-{
- return m_pslout->StretchStep(m_pseg, (int)level);
-}
-
-byte GlyphInfo::justWeight(size_t level)
-{
- return byte(m_pslout->JustWeight((int)level));
-}
-
-float GlyphInfo::justWidth(size_t level)
-{
- return m_pslout->JustWidth(m_pseg, (int)level);
-}
-
-float GlyphInfo::measureStartOfLine()
-{
- return m_pslout->MeasureSolLogUnits(m_pseg);
-}
-
-float GlyphInfo::measureEndOfLine()
-{
- return m_pslout->MeasureEolLogUnits(m_pseg);
-}
-
-size_t GlyphInfo::numberOfComponents()
-{
- return m_pslout->NumberOfComponents();
-}
-
-Rect GlyphInfo::componentBox(size_t icomp)
-{
- return m_pseg->ComponentRect(m_pslout, icomp);
-}
-
-toffset GlyphInfo::componentFirstChar(size_t icomp)
-{
- Assert((int)icomp < m_pslout->NumberOfComponents());
- return m_pslout->UnderlyingComponent(icomp) + m_pseg->startCharacter();
-}
-toffset GlyphInfo::componentLastChar(size_t icomp)
-{
- Assert((int)icomp < m_pslout->NumberOfComponents());
- return m_pslout->UnderlyingComponent(icomp) + m_pseg->startCharacter();
-}
-
-bool GlyphInfo::erroneous()
-{
- return m_pseg->Erroneous();
-}
-
-
-//:>********************************************************************************************
-//:> GlyphIterator methods
-//:>********************************************************************************************
-
-// Constructor
-GlyphIterator::GlyphIterator(Segment & seg, size_t iginf)
-: m_pginf(seg.m_prgginf + iginf)
-{}
-
-// Copy constructor.
-// Check if the incoming iterator is null, as we cannot dereference
-// it to get the segment, and create a null GlyphIterator.
-// Technically this might better be an assert as converting a null
-// GlyphSetIterator into a null GlyphIterator is pointless and suggests
-// some kind of error.
-GlyphIterator::GlyphIterator(const GlyphSetIterator & sit)
-: m_pginf((sit == GlyphSetIterator())
- ? 0
- : sit->segment().m_prgginf + sit->logicalIndex())
-{}
-
-/*----------------------------------------------------------------------------------------------
- Dereference the iterator, returning a GlyphInfo object.
-----------------------------------------------------------------------------------------------*/
-
-GlyphSetIterator::reference GlyphSetIterator::operator*() const
-{
- assert(m_pseg != 0);
- assert(m_vit != std::vector<int>::const_iterator());
- // in the case of a non-contiguous list
- return m_pseg->m_prgginf[(*m_vit) - m_pseg->m_isloutGinf0];
-}
-
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/TestFSM.cpp b/Build/source/libs/graphite-engine/src/segment/TestFSM.cpp
deleted file mode 100644
index 6dad1dc9dc8..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/TestFSM.cpp
+++ /dev/null
@@ -1,3416 +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: TestFSM.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Hard-coded FSMs for test procedures.
--------------------------------------------------------------------------------*//*:End Ignore*/
-
-//:Ignore
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-#ifdef OLD_TEST_STUFF
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-#ifndef _DEBUG
-
-bool GrLineBreakPass::RunTestRules(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- return false;
-}
-
-bool GrSubPass::RunTestRules(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- return false;
-}
-
-bool GrPosPass::RunTestRules(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- return false;
-}
-#endif // !_DEBUG
-
-
-#ifdef _DEBUG
-
-/*----------------------------------------------------------------------------------------------
- Call the appropriate test function.
-----------------------------------------------------------------------------------------------*/
-
-bool GrLineBreakPass::RunTestRules(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- return false;
-}
-
-bool GrSubPass::RunTestRules(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- if (m_staBehavior == "SimpleFSM")
- return RunSimpleFSMTest(ptman, ruln, psstrmInput, psstrmOutput);
- else if (m_staBehavior == "RuleAction")
- return false;
- else if (m_staBehavior == "RuleAction2")
- return false;
- else if (m_staBehavior == "Assoc")
- return false;
- else
- return false;
-}
-
-bool GrPosPass::RunTestRules(GrTableManager * ptman, int ruln,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- return false;
-}
-
-
-/*----------------------------------------------------------------------------------------------
- A simple FSM.
-
- Rules:
- r1. clsCons clsVowel clsDiacrAcute
- r2. clsCons clsVowelAE clsDiacr
- r3. clsCons clsVowelI
- r4. clsCons clsVowelI clsDiacrGrave
- r5. clsCons clsVowelI clsDiacr
-
- Machine classes:
- mcCons: b,c,d / f,g,h / j,k,l,m,n / p,q,r,s,t / v,w,x,y,z
- mcVae: a 97/ e 101
- mcVi: i 105
- mcVou: o 111 / u 117
- mcDa: acute '/' 47
- mcDg: grave '\' 92
- mcDct: other diacritics-circumflex '^' 94 / tilde '~' 126
-
-
- FSM: (T=transition, F=final, A=accepting, NA=non-accepting)
-
- | mcCons mcVae mcVi mcVou mcDa mcDg mcDct
- ---------------------------------------------------------------------------
- T NA s0 | s1
- | - - - - - - -
- T NA s1 | s2 s4 s3
- | - - - - - - -
- T NA s2 | s5 s6 s6
- | - - - - - - -
- T NA s3 | s10
- | - - - - - - -
- T A s4 | s7 s8 s9
- | - - - - - - -
- F A s5 |
- | - - - - - - -
- F A s6 |
- | - - - - - - -
- F A s7 |
- | - - - - - - -
- F A s8 |
- | - - - - - - -
- F A s9 |
- | - - - - - - -
- F A s10 |
- | - - - - - - -
-
- Rules Matched:
- s4: r3
- s5: r1, r2
- s6: r2
- s7: r1, r5
- s8: r4, r5
- s9: r5
- s10: r1
-
-----------------------------------------------------------------------------------------------*/
-
-void GrSubPass::SetUpSimpleFSMTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 3;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "SimpleFSM";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpSimpleFSMTest();
-}
-
-void GrFSM::SetUpSimpleFSMTest()
-{
- // Create machine class ranges.
- m_cmcr = 14;
- m_prgmcr = new GrFSMClassRange[14];
- m_prgmcr[0].m_chwFirst = 47; // forward slash (acute): mcDa
- m_prgmcr[0].m_chwLast = 47;
- m_prgmcr[0].m_col = 4;
-
- m_prgmcr[1].m_chwFirst = 92; // backslash: mcDg
- m_prgmcr[1].m_chwLast = 92;
- m_prgmcr[1].m_col = 5;
-
- m_prgmcr[2].m_chwFirst = 94; // caret: mcDct
- m_prgmcr[2].m_chwLast = 94;
- m_prgmcr[2].m_col = 6;
-
- m_prgmcr[3].m_chwFirst = 97; // a: mcVae
- m_prgmcr[3].m_chwLast = 97;
- m_prgmcr[3].m_col = 1;
-
- m_prgmcr[4].m_chwFirst = 98; // b - d: mcCons
- m_prgmcr[4].m_chwLast = 100;
- m_prgmcr[4].m_col = 0;
-
- m_prgmcr[5].m_chwFirst = 101; // e: mcVae
- m_prgmcr[5].m_chwLast = 101;
- m_prgmcr[5].m_col = 1;
-
- m_prgmcr[6].m_chwFirst = 102; // f - h: mcCons
- m_prgmcr[6].m_chwLast = 104;
- m_prgmcr[6].m_col = 0;
-
- m_prgmcr[7].m_chwFirst = 105; // i: mcVi
- m_prgmcr[7].m_chwLast = 105;
- m_prgmcr[7].m_col = 2;
-
- m_prgmcr[8].m_chwFirst = 106; // j - n: mcCons
- m_prgmcr[8].m_chwLast = 110;
- m_prgmcr[8].m_col = 0;
-
- m_prgmcr[9].m_chwFirst = 111; // o: mcVou
- m_prgmcr[9].m_chwLast = 111;
- m_prgmcr[9].m_col = 3;
-
- m_prgmcr[10].m_chwFirst = 112; // p - t: mcCons
- m_prgmcr[10].m_chwLast = 116;
- m_prgmcr[10].m_col = 0;
-
- m_prgmcr[11].m_chwFirst = 117; // u: mcVou
- m_prgmcr[11].m_chwLast = 117;
- m_prgmcr[11].m_col = 3;
-
- m_prgmcr[12].m_chwFirst = 118; // v - z: mcCons
- m_prgmcr[12].m_chwLast = 122;
- m_prgmcr[12].m_col = 0;
-
- m_prgmcr[13].m_chwFirst = 126; // tilde: mcDct
- m_prgmcr[13].m_chwLast = 126;
- m_prgmcr[13].m_col = 6;
-
- m_dimcrInit = 8; // (max power of 2 <= m_cmcr);
- m_cLoop = 3; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 11;
- m_crowNonAcpt = 4;
- m_crowFinal = 6;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 7;
-
- // Set up transition table.
- m_prgrowTransitions = new short[35]; // 35 = (m_crow-m_crowFinal) * m_ccol
- short * psn = m_prgrowTransitions;
- *psn++ = 1; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 2; *psn++ = 4; *psn++ = 3; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 5; *psn++ = 6; *psn++ = 6;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =10; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 8; *psn++ = 9;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[10]; // 10 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[7+1]; // 7 = m_crow - m_crowNonAcpt
-
- m_prgirulnMin[0] = 0; // s4: r3
- m_prgrulnMatched[0] = 3;
-
- m_prgirulnMin[1] = 1; // s5: r1, r2
- m_prgrulnMatched[1] = 1;
- m_prgrulnMatched[2] = 2;
-
- m_prgirulnMin[2] = 3; // s6: r2
- m_prgrulnMatched[3] = 2;
-
- m_prgirulnMin[3] = 4; // s7: r1, r5
- m_prgrulnMatched[4] = 1;
- m_prgrulnMatched[5] = 5;
-
- m_prgirulnMin[4] = 6; // s8: r4, r5
- m_prgrulnMatched[6] = 4;
- m_prgrulnMatched[7] = 5;
-
- m_prgirulnMin[5] = 8; // s9: r5
- m_prgrulnMatched[8] = 5;
-
- m_prgirulnMin[6] = 9; // s10: r1
- m_prgrulnMatched[9] = 1;
-
- m_prgirulnMin[7] = 10;
-}
-
-
-/*----------------------------------------------------------------------------------------------
- The "rule" does something silly: just inserts *'s--the number equals the number of the
- rule.
-----------------------------------------------------------------------------------------------*/
-bool GrSubPass::RunSimpleFSMTest(GrTableManager * ptman, int ruln, GrSlotStream * psstrmInput,
- GrSlotStream * psstrmOutput)
-{
- int cslotMatched = (ruln == 3)? 2: 3;
-
- GrSlotState * pslot0 = psstrmInput->Peek(0);
-
- for (int islot = 0; islot < cslotMatched; islot++)
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
-
- for (islot = 0; islot < ruln; islot++)
- {
- GrSlotState * pslot;
- ptman->NewSlot('*', pslot0, NULL, m_ipass, &pslot);
- pslot->Associate(pslot0);
- psstrmOutput->NextPut(pslot);
- }
-
- return true;
-}
-
-
-/*----------------------------------------------------------------------------------------------
- A simple set of rules with actions.
-
- Rules:
- r0. clsDigit gSlash clsDigit _ > @3 _ @1 gTilde; // tilde = 126
- r1. _ clsDigit gBackSlash clsDigit > gDollar @4 _ @2; // dollar sign = 36
-
- Machine classes:
- mcDigit: '0' - '9' 48 - 57
- mcSlash: '/' 47
- mcBSlash: '\' 92
-
-
- FSM: (T=transition, F=final, A=accepting, NA=non-accepting)
-
- | clsDig mcSlash mcBSlash
- ------------------------------------------------------
- T NA s0 | s1
- | - - -
- T NA s1 | s2 s3
- | - - -
- T NA s2 | s4
- | - - -
- T NA s3 | s5
- | - - -
- F A s4 |
- | - - -
- F A s5 |
- | - - -
-
- Rules Matched:
- s4: r0
- s5: r1
-
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpRuleActionTest()
-{
- if (m_pctbl)
- delete m_pctbl;
-
- m_pctbl = new GrClassTable();
- m_pctbl->SetUpRuleActionTest();
-}
-
-void GrClassTable::SetUpRuleActionTest()
-{
- m_ccls = 2; // number of classes
- m_cclsLinear = 2; // number of classes in linear format
-
- m_prgchwBIGGlyphList = new data16[100];
-
- m_prgichwOffsets = new data16[2+1];
-
- gid16 * pchw = m_prgchwBIGGlyphList;
-
- // Output class 0: tilde
- m_prgichwOffsets[0] = 0;
- *pchw++ = msbf(data16(126)); // '~'
-
- // Output class 1: dollar
- m_prgichwOffsets[1] = 1;
- *pchw++ = msbf(data16(36)); // '$'
-
- m_prgichwOffsets[2] = 2;
-}
-
-void GrSubPass::SetUpRuleActionTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 3;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "RuleAction";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpRuleActionTest();
-
- m_crul = 2;
-
- // Set up constraint code--succeed trivially.
- m_prgbConstraintBlock = new byte[3];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopPushByte; *pb++ = 1; // Push true
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 0;
- m_prgibConstraintStart[1] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[30];
- pb = m_prgbActionBlock;
-
- // Rule 1: clsDigit gSlash clsDigit _ > @3 _ @1 gTilde;
-
- *pb++ = kopPutCopy; *pb++ = 2; // PutCopy 2
- *pb++ = kopNext; // Next
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopPutCopy; *pb++ = -2; // PutCopy -2
- *pb++ = kopNext; // Next
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutGlyph8bitObs; *pb++ = 0; // PutGlyph 0 ('~' = 126)
- *pb++ = kopNext; // Next
- *pb++ = kopPushByte; *pb++ = 0; // Push 0
- *pb++ = kopPopRet; // PopAndRet
-
- // Rule 2: _ clsDigit gBackSlash clsDigit > gDollar @4 _ @2;
-
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutGlyph8bitObs; *pb++ = 1; // PutGlyph 1 ('$' = 36)
- *pb++ = kopNext; // Next
- *pb++ = kopPutCopy; *pb++ = 2; // PutCopy 2
- *pb++ = kopNext; // Next
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopPutCopy; *pb++ = -2; // PutCopy -2
- *pb++ = kopNext; // Next
- *pb++ = kopPushByte; *pb++ = 0; // Push 0
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 15;
-}
-
-void GrFSM::SetUpRuleActionTest()
-{
- // Create machine class ranges.
- m_cmcr = 3;
- m_prgmcr = new GrFSMClassRange[3];
- m_prgmcr[0].m_chwFirst = 47; // forward slash: mcSlash
- m_prgmcr[0].m_chwLast = 47;
- m_prgmcr[0].m_col = 1;
-
- m_prgmcr[1].m_chwFirst = 48; // 0 - 9: mcDigit
- m_prgmcr[1].m_chwLast = 57;
- m_prgmcr[1].m_col = 0;
-
- m_prgmcr[2].m_chwFirst = 92; // backslash
- m_prgmcr[2].m_chwLast = 92;
- m_prgmcr[2].m_col = 2;
-
-
- m_dimcrInit = 2; // (max power of 2 <= m_cmcr);
- m_cLoop = 1; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 6;
- m_crowNonAcpt = 4;
- m_crowFinal = 2;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 3;
-
- // Set up transition table.
- m_prgrowTransitions = new short[12]; // 12 = (m_crow-m_crowFinal) * m_ccol
- short * psn = m_prgrowTransitions;
- *psn++ = 1; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 2; *psn++ = 3;
- *psn++ = 4; *psn++ = 0; *psn++ = 0;
- *psn++ = 5; *psn++ = 0; *psn++ = 0;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[2+1]; // 2 = m_crow - m_crowNonAcpt
-
- m_prgirulnMin[0] = 0; // s4: r0
- m_prgrulnMatched[0] = 0;
-
- m_prgirulnMin[1] = 1; // s5: r1
- m_prgrulnMatched[1] = 1;
-
- m_prgirulnMin[2] = 2;
-}
-
-/*----------------------------------------------------------------------------------------------
- A more complicated set of rules with actions.
-
- PASS 1:
- r0. clsDigit > @1 {dir = DIR_RIGHT} / ^ _ {dir == DIR_LEFT};
- r1. clsSpecial > @2 {dir = DIR_ARABNUMBER} / clsDigit {dir != DIR_LEFT} ^ _;
- r2. clsSpecial > @2 {dir = @1.dir} / clsSpecial ^ _;
-
- Pass 1 machine classes:
- mcDigit: '0' - '9' 48 - 57
- mcSpecial: '-', '_', '=', '~' 45, 95, 61, 126
-
- Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting)
-
- | mcDigit mcSpecial
- ------------------------------------------
- T NA s0 | s2 s1
- | - _
- T NA s1 | s4
- | - -
- T A s2 | s3
- | - -
- F A s3 |
- | - -
- F A s4 |
- | - -
-
- Rules Matched:
- s2: r0
- s3: r1
- s4: r2
-
- PASS 2:
- r0. clsVowel gCaret > clsCirumVowel _;
- r1. clsVowel gSlash > _ clsAcuteVowel$1;
-
- Pass 2 machine classes:
- mcVowel
- mcCaret: '^' 94
- mcSlash: '/' 47
-
-
- Pass 2 FSM:
- | mcVowel mcCaret mcSlash
- -----------------------------------------------------
- T NA s0 | s1
- | - _
- T NA s1 | s2 s3
- | - -
- F A s2 |
- | - -
- F A s3 |
- | - -
-
- Rules matched:
- s2: r0
- s3: r1
-
-
- PASS 3:
- r0. clsLeft > clsRight {dir = @1.dir} / _ clsDir {dir==DIR_RIGHT};
- r1. clsRight > clsLeft {dir = @1.dir} / clsDir {dir==DIR_RIGHT} _;
-
- Pass 3 machine classes:
- mcDir: (clsDigit, clsSpecial)
- mcLeft: '(', '[', '{' 40, 91, 123
- mcRight: ')', ']', '}' 41, 93, 125
-
- Pass 3 FSM:
- | mcDir mcLeft mcRight
- -----------------------------------------------------
- T NA s0 | s2 s1
- | - _
- T NA s1 | s3
- | - -
- T NA s2 | s4
- | - -
- F A s3 |
- | - -
- F A s4 |
- | - -
-
- Rules matched:
- s3: r0
- s4: r1
-
-
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpRuleAction2Test()
-{
- if (m_pctbl)
- delete m_pctbl;
-
- m_pctbl = new GrClassTable();
- m_pctbl->SetUpRuleAction2Test();
-}
-
-void GrClassTable::SetUpRuleAction2Test()
-{
- m_ccls = 7; // number of classes
- m_cclsLinear = 4; // number of classes in linear format
-
- m_prgchwBIGGlyphList = new data16[70];
-
- m_prgichwOffsets = new data16[7+1];
-
- data16 * pchw = m_prgchwBIGGlyphList;
-
- // Output class 0: clsCirumVowel
- m_prgichwOffsets[0] = 0;
- *pchw++ = msbf(data16(226)); // a
- *pchw++ = msbf(data16(234)); // e
- *pchw++ = msbf(data16(238)); // i
- *pchw++ = msbf(data16(244)); // o
- *pchw++ = msbf(data16(251)); // u
- *pchw++ = msbf(data16(194)); // A
- *pchw++ = msbf(data16(202)); // E
- *pchw++ = msbf(data16(206)); // I
- *pchw++ = msbf(data16(212)); // O
- *pchw++ = msbf(data16(219)); // U
-
- // Output class 1: clsAcuteVowel
- m_prgichwOffsets[1] = 10;
- *pchw++ = msbf(data16(225)); // a
- *pchw++ = msbf(data16(233)); // e
- *pchw++ = msbf(data16(237)); // i
- *pchw++ = msbf(data16(243)); // o
- *pchw++ = msbf(data16(250)); // u
- *pchw++ = msbf(data16(193)); // A
- *pchw++ = msbf(data16(201)); // E
- *pchw++ = msbf(data16(205)); // I
- *pchw++ = msbf(data16(211)); // O
- *pchw++ = msbf(data16(218)); // U
-
- // Output class 2: clsLeft
- m_prgichwOffsets[2] = 10 + 10;
- *pchw++ = msbf(data16(40)); // (
- *pchw++ = msbf(data16(91)); // [
- *pchw++ = msbf(data16(123)); // {
-
- // Output class 3: clsRight
- m_prgichwOffsets[3] = 20 + 3;
- *pchw++ = msbf(data16(41)); // )
- *pchw++ = msbf(data16(93)); // ]
- *pchw++ = msbf(data16(125)); // }
-
- // Input class 4: clsVowel
- m_prgichwOffsets[4] = 23 + 3; // 26
- *pchw++ = msbf(data16(10));
- *pchw++ = msbf(data16(8)); *pchw++ = msbf(data16(3)); *pchw++ = msbf(data16(10-8));
- *pchw++ = msbf(data16(65)); *pchw++ = msbf(data16(5)); // A
- *pchw++ = msbf(data16(69)); *pchw++ = msbf(data16(6)); // E
- *pchw++ = msbf(data16(73)); *pchw++ = msbf(data16(7)); // I
- *pchw++ = msbf(data16(79)); *pchw++ = msbf(data16(8)); // O
- *pchw++ = msbf(data16(85)); *pchw++ = msbf(data16(9)); // U
- *pchw++ = msbf(data16(97)); *pchw++ = msbf(data16(0)); // a
- *pchw++ = msbf(data16(101)); *pchw++ = msbf(data16(1)); // e
- *pchw++ = msbf(data16(105)); *pchw++ = msbf(data16(2)); // i
- *pchw++ = msbf(data16(111)); *pchw++ = msbf(data16(3)); // o
- *pchw++ = msbf(data16(117)); *pchw++ = msbf(data16(4)); // u
-
- // Input class 5: clsLeft
- m_prgichwOffsets[5] = 26 + 4 + 10*2; // 50
- *pchw++ = msbf(data16(3));
- *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2));
- *pchw++ = msbf(data16(40)); *pchw++ = msbf(data16(0)); // (
- *pchw++ = msbf(data16(91)); *pchw++ = msbf(data16(1)); // [
- *pchw++ = msbf(data16(123)); *pchw++ = msbf(data16(2)); // {
-
- // Input class 6: clsRight
- m_prgichwOffsets[6] = 50 + 4 + 3*2; // 60
- *pchw++ = msbf(data16(3));
- *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2));
- *pchw++ = msbf(data16(41)); *pchw++ = msbf(data16(0)); // )
- *pchw++ = msbf(data16(93)); *pchw++ = msbf(data16(1)); // ]
- *pchw++ = msbf(data16(125)); *pchw++ = msbf(data16(2)); // }
-
- m_prgichwOffsets[7] = 60 + 4 + 3*2; // 70
-}
-
-void GrSubPass::SetUpRuleAction2Test()
-{
- if (m_ipass == 1)
- {
- m_nMaxRuleContext = m_nMaxChunk = 2;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "RuleAction2";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpRuleAction2Test(m_ipass);
-
- m_crul = 3;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1 + 10 + 10];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- *pb++ = kopCntxtItem; *pb++ = 0; // ContextItem 0
- *pb++ = kopPushSlotAttr; *pb++= kslatDir; // PushSlotAttr dir 0
- *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = kdircL; // Push DIR_LEFT
- *pb++ = kopEqual; // Equal
- *pb++ = kopOr; // Or
- *pb++ = kopPopRet; // PopAndRet
-
- *pb++ = kopCntxtItem; *pb++ = 0; // ContextItem 0
- *pb++ = kopPushSlotAttr; *pb++= kslatDir; // PushSlotAttr dir 0
- *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = kdircL; // Push DIR_LEFT
- *pb++ = kopNotEq; // NotEqual
- *pb++ = kopOr; // Or
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 1;
- m_prgibConstraintStart[1] = 11;
- m_prgibConstraintStart[2] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[10 + 11 + 12];
- pb = m_prgbActionBlock;
-
- // Rule 0: clsDigit > @1 {dir = DIR_RIGHT} / ^ _ {dir == DIR_LEFT};
-
- *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0
- *pb++ = kopPushByte; *pb++ = kdircR; // PushByte DIR_RIGHT
- *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir
- *pb++ = kopNext; // Next
- *pb++ = kopPushByte; *pb++ = -1; // Push -1
- *pb++ = kopPopRet; // PopAndRet
-
- // Rule 1: clsSpecial > @2 {dir = DIR_ARABNUMBER} / clsDigit {dir != DIR_LEFT} ^ _;
-
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0
- *pb++ = kopPushByte; *pb++ = kdircArabNum; // Push DIR_ARABNUMBER
- *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir
- *pb++ = kopNext; // Next
- *pb++ = kopPushByte; *pb++ = -1; // Push -1
- *pb++ = kopPopRet; // PopAndRet
-
- // Rule 2: clsSpecial > @2 {dir = @1.dir} / clsSpecial ^ _;
-
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0
- *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir -1
- *pb++ = -1;
- *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir
- *pb++ = kopNext; // Next
- *pb++ = kopPushByte; *pb++ = -1; // Push -1
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 10;
- m_prgibActionStart[2] = 10 + 11;
- }
- else if (m_ipass == 2)
- {
- m_nMaxRuleContext = m_nMaxChunk = 2;
- m_nMaxRuleLoop = 3;
- m_staBehavior = "RuleAction2";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpRuleAction2Test(m_ipass);
-
- m_crul = 2;
-
- // Set up constraint code--succeed trivially.
- m_prgbConstraintBlock = new byte[1];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 0;
- m_prgibConstraintStart[1] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[16];
- pb = m_prgbActionBlock;
-
- // Rule 0: clsVowel gCaret > clsCirumVowel _;
-
- *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsVowel clsCircumVowel
- *pb++ = 4; *pb++ = 0;
- *pb++ = kopNext; // Next
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 1: clsVowel gSlash > _ clsAcuteVowel$1;
-
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopPutSubs8bitObs; *pb++ = -1; // PutSubs -1 clsVowel clsAcuteVowel
- *pb++ = 4; *pb++ = 1;
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 8;
- }
- else if (m_ipass == 3)
- {
- m_nMaxRuleContext = m_nMaxChunk = 2;
- m_nMaxRuleLoop = 3;
- m_staBehavior = "RuleAction2";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpRuleAction2Test(m_ipass);
-
- m_crul = 2;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1 + 10 + 10];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- *pb++ = kopCntxtItem; *pb++ = 1; // ContextItem 1
- *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir 0
- *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = kdircR; // Push DIR_RIGHT
- *pb++ = kopEqual; // Equal
- *pb++ = kopOr; // Or
- *pb++ = kopPopRet; // PopAndRet
-
- *pb++ = kopCntxtItem; *pb++ = 0; // ContextItem 0
- *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir 0
- *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = kdircR; // Push DIR_RIGHT
- *pb++ = kopEqual; // Equal
- *pb++ = kopOr; // Or
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 1;
- m_prgibConstraintStart[1] = 1 + 10;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[23];
- pb = m_prgbActionBlock;
-
- // Rule 0: clsLeft > clsRight {dir = @1.dir} / _ clsDir {dir == DIR_RIGHT};
-
- *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsLeft clsRight
- *pb++ = 5; *pb++ = 3;
- *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir 1
- *pb++ = 1;
- *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 1: clsRight > clsLeft {dir = @1.dir} / clsDir {dir == DIR_RIGHT} _;
-
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsRight clsLeft
- *pb++ = 6; *pb++ = 2;
- *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir -1
- *pb++ = -1;
- *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 11;
- }
-}
-
-
-void GrFSM::SetUpRuleAction2Test(int ipass)
-{
- if (ipass == 1)
- {
- // Create machine class ranges.
- m_cmcr = 5;
- m_prgmcr = new GrFSMClassRange[5];
- m_prgmcr[0].m_chwFirst = 45; // hyphen
- m_prgmcr[0].m_chwLast = 45;
- m_prgmcr[0].m_col = 1;
-
- m_prgmcr[1].m_chwFirst = 48; // 0 - 9: mcDigit
- m_prgmcr[1].m_chwLast = 57;
- m_prgmcr[1].m_col = 0;
-
- m_prgmcr[2].m_chwFirst = 61; // equals sign
- m_prgmcr[2].m_chwLast = 61;
- m_prgmcr[2].m_col = 1;
-
- m_prgmcr[3].m_chwFirst = 95; // underscore
- m_prgmcr[3].m_chwLast = 95;
- m_prgmcr[3].m_col = 1;
-
- m_prgmcr[4].m_chwFirst = 126; // tilde
- m_prgmcr[4].m_chwLast = 126;
- m_prgmcr[4].m_col = 1;
-
- m_dimcrInit = 4; // (max power of 2 <= m_cmcr);
- m_cLoop = 2; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 5;
- m_crowNonAcpt = 2;
- m_crowFinal = 2;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 2;
-
- // Set up transition table.
- m_prgrowTransitions = new short[6]; // 6 = (m_crow-m_crowFinal) * m_ccol
- short * psn = m_prgrowTransitions;
- *psn++ = 2; *psn++ = 1;
- *psn++ = 0; *psn++ = 4;
- *psn++ = 0; *psn++ = 3;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[3+1]; // 3 = m_crow - m_crowNonAcpt
-
- m_prgirulnMin[0] = 0; // s2: r0
- m_prgrulnMatched[0] = 0;
-
- m_prgirulnMin[1] = 1; // s3: r1
- m_prgrulnMatched[1] = 1;
-
- m_prgirulnMin[2] = 2; // s3: r2
- m_prgrulnMatched[2] = 2;
-
- m_prgirulnMin[3] = 3;
- }
- else if (ipass == 2)
- {
- // Create machine class ranges.
- m_cmcr = 12;
- m_prgmcr = new GrFSMClassRange[12];
- m_prgmcr[0].m_chwFirst = 47; // slash
- m_prgmcr[0].m_chwLast = 47;
- m_prgmcr[0].m_col = 2;
-
- m_prgmcr[1].m_chwFirst = 65; // A
- m_prgmcr[1].m_chwLast = 65;
- m_prgmcr[1].m_col = 0;
-
- m_prgmcr[2].m_chwFirst = 69; // E
- m_prgmcr[2].m_chwLast = 69;
- m_prgmcr[2].m_col = 0;
-
- m_prgmcr[3].m_chwFirst = 73; // I
- m_prgmcr[3].m_chwLast = 73;
- m_prgmcr[3].m_col = 0;
-
- m_prgmcr[4].m_chwFirst = 79; // O
- m_prgmcr[4].m_chwLast = 79;
- m_prgmcr[4].m_col = 0;
-
- m_prgmcr[5].m_chwFirst = 85; // U
- m_prgmcr[5].m_chwLast = 85;
- m_prgmcr[5].m_col = 0;
-
- m_prgmcr[6].m_chwFirst = 94; // caret
- m_prgmcr[6].m_chwLast = 94;
- m_prgmcr[6].m_col = 1;
-
- m_prgmcr[7].m_chwFirst = 97; // a
- m_prgmcr[7].m_chwLast = 97;
- m_prgmcr[7].m_col = 0;
-
- m_prgmcr[8].m_chwFirst = 101; // e
- m_prgmcr[8].m_chwLast = 101;
- m_prgmcr[8].m_col = 0;
-
- m_prgmcr[9].m_chwFirst = 105; // i
- m_prgmcr[9].m_chwLast = 105;
- m_prgmcr[9].m_col = 0;
-
- m_prgmcr[10].m_chwFirst = 111; // o
- m_prgmcr[10].m_chwLast = 111;
- m_prgmcr[10].m_col = 0;
-
- m_prgmcr[11].m_chwFirst = 117; // u
- m_prgmcr[11].m_chwLast = 117;
- m_prgmcr[11].m_col = 0;
-
- m_dimcrInit = 8; // (max power of 2 <= m_cmcr);
- m_cLoop = 3; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 4;
- m_crowNonAcpt = 2;
- m_crowFinal = 2;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 3;
-
- // Set up transition table.
- m_prgrowTransitions = new short[6]; // 6 = (m_crow-m_crowFinal) * m_ccol
- short * psn = m_prgrowTransitions;
- *psn++ = 1; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 2; *psn++ = 3;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[2+1]; // 2 = m_crow - m_crowNonAcpt
-
- m_prgirulnMin[0] = 0; // s1: r0
- m_prgrulnMatched[0] = 0;
-
- m_prgirulnMin[1] = 1; // s2: r1
- m_prgrulnMatched[1] = 1;
-
- m_prgirulnMin[2] = 2;
- }
- else if (ipass == 3)
- {
- // Create machine class ranges.
- m_cmcr = 11;
- m_prgmcr = new GrFSMClassRange[11];
- m_prgmcr[0].m_chwFirst = 40; // (
- m_prgmcr[0].m_chwLast = 40;
- m_prgmcr[0].m_col = 1;
-
- m_prgmcr[1].m_chwFirst = 41; // )
- m_prgmcr[1].m_chwLast = 41;
- m_prgmcr[1].m_col = 2;
-
- m_prgmcr[2].m_chwFirst = 45; // hyphen
- m_prgmcr[2].m_chwLast = 45;
- m_prgmcr[2].m_col = 0;
-
- m_prgmcr[3].m_chwFirst = 48; // 0 - 9: mcDigit
- m_prgmcr[3].m_chwLast = 57;
- m_prgmcr[3].m_col = 0;
-
- m_prgmcr[4].m_chwFirst = 61; // =
- m_prgmcr[4].m_chwLast = 61;
- m_prgmcr[4].m_col = 0;
-
- m_prgmcr[5].m_chwFirst = 91; // [
- m_prgmcr[5].m_chwLast = 91;
- m_prgmcr[5].m_col = 1;
-
- m_prgmcr[6].m_chwFirst = 93; // ]
- m_prgmcr[6].m_chwLast = 93;
- m_prgmcr[6].m_col = 2;
-
- m_prgmcr[7].m_chwFirst = 95; // underscore
- m_prgmcr[7].m_chwLast = 95;
- m_prgmcr[7].m_col = 0;
-
- m_prgmcr[8].m_chwFirst = 123; // {
- m_prgmcr[8].m_chwLast = 123;
- m_prgmcr[8].m_col = 1;
-
- m_prgmcr[9].m_chwFirst = 125; // }
- m_prgmcr[9].m_chwLast = 125;
- m_prgmcr[9].m_col = 2;
-
- m_prgmcr[10].m_chwFirst = 126; // tilde
- m_prgmcr[10].m_chwLast = 126;
- m_prgmcr[10].m_col = 0;
-
- m_dimcrInit = 8; // (max power of 2 <= m_cmcr);
- m_cLoop = 3; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 5;
- m_crowNonAcpt = 3;
- m_crowFinal = 2;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 3;
-
- // Set up transition table.
- m_prgrowTransitions = new short[9]; // 9 = (m_crow-m_crowFinal) * m_ccol
- short * psn = m_prgrowTransitions;
- *psn++ = 2; *psn++ = 1; *psn++ = 0;
- *psn++ = 3; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 4;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[2+1]; // 2 = m_crow - m_crowNonAcpt
-
- m_prgirulnMin[0] = 0; // s3: r0
- m_prgrulnMatched[0] = 0;
-
- m_prgirulnMin[1] = 1; // s4: r1
- m_prgrulnMatched[1] = 1;
-
- m_prgirulnMin[2] = 2;
- }
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Tests of various kinds of assocations.
-
- PASS 1 (line-break):
- r0. gX / # _ ^ ; // do nothing
- r1. gX {break = -2};
-
- Pass 1 machine classes:
- mcX: 'x' 120
- mcLB: 35
-
- Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting)
-
- | gX gLB
- --------------------------------
- T NA s0 | s2 s1
- |
- T NA s1 | s3
- |
- F A s2 |
- |
- F A s3 |
-
-
- Rules Matched:
- s2: r1
- s3: r0
-
-
-
- PASS 2:
- r0. clsOA clsE > clsELig:(1 2) _;
- r1. clsLC _ _ gX > @1 @5 @1 @5 / _ _ # {break==2} _ _ ;
- r2. _ clsFraction _ > clsNumerator:2 gSlash:2 clsDenom:2;
-
- Pass 2 machine classes:
- mcOA: O A 79 65
- mcOAlc: o a 111 97
- mcE E e 69 101
- mcFraction: 188 189 190
- mcX: x 120
- mcLCother
- mcLB: 35
-
-
- Pass 2 FSM: mcLC
- | mcOA mcOAlc mcE mcElc other mcX mcFractn mcLB
- -----------------------------------------------------------------------------------------
- T NA s0 | s1 s2 s4 s3 s3 s6
- | - - - - - - -
- T NA s1 | s7
- | - - - - - - -
- T NA s2 | s7 s5
- | - - - - - - -
- T NA s3 | s5
- | - - - - - - -
- T NA s4 | s5
- | - - - - - - -
- T NA s5 | s8
- | - - - - - - -
- F A s6 |
- | - - - - - -
- F A s7 |
- | - - - - - -
- F A s8 |
- | - - - - - -
-
- Rules matched:
- s6: r2
- s7: r0
- s8: r1
-
-
- PASS 3:
- r0. _ > gHyphen / _ # {break == 2} ^;
-
- Pass 3 machine classes:
- mcLB: 35
-
- Pass 3 FSM:
-
- | gLB
- --------------------------------
- T NA s0 | s1
- |
- F A s1 |
- |
-
- Rules Matched:
- s1: r0
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpAssocTest()
-{
- if (m_pctbl)
- delete m_pctbl;
-
- m_pctbl = new GrClassTable();
- m_pctbl->SetUpAssocTest();
-
- m_fLineBreak = true;
- m_cchwPreXlbContext = 1;
- m_cchwPostXlbContext = 1;
-}
-
-void GrClassTable::SetUpAssocTest()
-{
- m_ccls = 11; // number of classes
- m_cclsLinear = 5; // number of classes in linear format (output classes)
-
- m_prgchwBIGGlyphList = new data16[143];
-
- m_prgichwOffsets = new data16[m_ccls+1];
-
- data16 * pchw = m_prgchwBIGGlyphList;
-
- // Output class 0: clsELig
- m_prgichwOffsets[0] = 0;
- *pchw++ = msbf(data16(140)); // OE
- *pchw++ = msbf(data16(198)); // AE
- *pchw++ = msbf(data16(156)); // oe
- *pchw++ = msbf(data16(230)); // ae
-
- // Output class 1: clsNumerator
- m_prgichwOffsets[1] = 4;
- *pchw++ = msbf(data16(49)); // 1
- *pchw++ = msbf(data16(49)); // 1
- *pchw++ = msbf(data16(51)); // 3
-
- // Output class 2: clsDenom
- m_prgichwOffsets[2] = 4 + 3;
- *pchw++ = msbf(data16(52)); // 4
- *pchw++ = msbf(data16(50)); // 2
- *pchw++ = msbf(data16(52)); // 4
-
- // Output class 3: gSlash
- m_prgichwOffsets[3] = 7 + 3;
- *pchw++ = msbf(data16(47)); // '/'
-
- // Output class 4: gHyphen
- m_prgichwOffsets[4] = 10 + 1;
- *pchw++ = msbf(data16(45)); // '-'
-
- // Input class 5: clsOA
- m_prgichwOffsets[5] = 11 + 1;
- *pchw++ = msbf(data16(4));
- *pchw++ = msbf(data16(4)); *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(0));
- *pchw++ = msbf(data16(65)); *pchw++ = msbf(data16(1)); // A
- *pchw++ = msbf(data16(79)); *pchw++ = msbf(data16(0)); // O
- *pchw++ = msbf(data16(97)); *pchw++ = msbf(data16(3)); // a
- *pchw++ = msbf(data16(111)); *pchw++ = msbf(data16(2)); // o
-
- // Input class 6: clsE
- m_prgichwOffsets[6] = 12 + 4 + 4*2; // 24
- *pchw++ = msbf(data16(3));
- *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2));
- *pchw++ = msbf(data16(40)); *pchw++ = msbf(data16(0)); // E
- *pchw++ = msbf(data16(91)); *pchw++ = msbf(data16(1)); // e
-
- // Input class 7: clsLC
- m_prgichwOffsets[7] = 24 + 4 + 2*2; // 32
- *pchw++ = msbf(data16(26));
- *pchw++ = msbf(data16(16)); *pchw++ = msbf(data16(4)); *pchw++ = msbf(data16(26-16));
- for (int i = 0; i < 26; ++i)
- {
- *pchw++ = msbf(data16(97+i)); *pchw++ = msbf(data16(i));
- }
-
- // Input class 8: gX
- m_prgichwOffsets[8] = 32 + 4 + 26*2; // 88
- *pchw++ = msbf(data16(1));
- *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(0)); *pchw++ = msbf(data16(0));
- *pchw++ = msbf(data16(120)); *pchw++ = msbf(data16(0));
-
- // Input class 9: clsFraction
- m_prgichwOffsets[9] = 88 + 4 + 1*2; // 127
- *pchw++ = msbf(data16(3));
- *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2));
- *pchw++ = msbf(data16(188)); *pchw++ = msbf(data16(0)); // 1/4
- *pchw++ = msbf(data16(189)); *pchw++ = msbf(data16(1)); // 1/2
- *pchw++ = msbf(data16(190)); *pchw++ = msbf(data16(2)); // 3/4
-
- // Input class 10: #
- m_prgichwOffsets[10] = 127 + 4 + 3*2; // 137
- *pchw++ = msbf(data16(1));
- *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(0)); *pchw++ = msbf(data16(0));
- *pchw++ = msbf(data16(35)); *pchw++ = msbf(data16(0)); // 1/4
-
- m_prgichwOffsets[11] = 137 + 4 + 1*2; // 143
-}
-
-void GrLineBreakPass::SetUpAssocTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "Assoc";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpAssocTest(m_ipass);
-
- m_crul = 2;
-
- // Set up constraint code--succeed trivially.
- m_prgbConstraintBlock = new byte[1];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 0;
- m_prgibConstraintStart[1] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[7 + 8];
- pb = m_prgbActionBlock;
-
- // Rule 0: gX / # _ ^ ; // do nothing
-
- *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0
- *pb++ = kopNext; // Next
- *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 1: gX {break = -2};
-
- *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0
- *pb++ = kopPushByte; *pb++ = -2; // PushByte -2
- *pb++ = kopAttrSet; *pb++ = kslatBreak; // AttrSet breakweight
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 7;
-}
-
-void GrSubPass::SetUpAssocTest()
-{
- if (m_ipass == 2)
- {
- m_nMaxRuleContext = m_nMaxChunk = 3;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "Assoc";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpAssocTest(m_ipass);
-
- m_crul = 3;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1 + 10];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- *pb++ = kopCntxtItem; *pb++ = 1; // ContextItem 1
- *pb++ = kopPushSlotAttr;*pb++ = kslatBreak; // PushSlotAttr break 0
- *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = 2; // Push 2
- *pb++ = kopEqual; // Equal
- *pb++ = kopOr; // Or
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 0;
- m_prgibConstraintStart[1] = 1;
- m_prgibConstraintStart[2] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[12 + 12 + 22];
- pb = m_prgbActionBlock;
-
- // Rule 0: clsOA clsE > clsELig:(1 2) _ ;
-
- *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsOA clsELig
- *pb++ = 5; *pb++ = 0;
- *pb++ = kopAssoc; *pb++ = 2; // Assoc 2 0 1
- *pb++ = 0; *pb++ = 1;
- *pb++ = kopNext; // Next
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 1: clsLC _ _ gX > @1 @5 @1 @5 / _ _ # {break==2} _ _ ;
-
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutCopy; *pb++ = 2; // PutCopy 2
- *pb++ = kopNext; // Next
- *pb++ = kopCopyNext; // CopyNext - line break
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutCopy; *pb++ = -1; // PutCopy -1
- *pb++ = kopNext; // Next
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopRetZero; // RetZero
-
- // Rule 2: _ clsFraction _ > clsNumerator:2 gSlash:2 clsDenom:2;
-
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutSubs8bitObs; *pb++ = 1; // PutSubs 1 clsFraction clsNumerator
- *pb++ = 9; *pb++ = 1;
- *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 1
- *pb++ = 1;
- *pb++ = kopNext; // Next
- *pb++ = kopPutGlyph8bitObs; *pb++ = 3; // PutGlyph gSlash
- *pb++ = kopNext; // Next
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsFraction clsDenom
- *pb++ = 9; *pb++ = 2;
- *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 0
- *pb++ = 0;
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 12;
- m_prgibActionStart[2] = 12 + 12;
- }
- else if (m_ipass == 3)
- {
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 3;
- m_staBehavior = "Assoc";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpAssocTest(m_ipass);
-
- m_crul = 1;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1 + 10];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- *pb++ = kopCntxtItem; *pb++ = 0; // ContextItem 0
- *pb++ = kopPushSlotAttr;*pb++ = kslatBreak; // PushSlotAttr break 0
- *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = 2; // Push 2
- *pb++ = kopEqual; // Equal
- *pb++ = kopOr; // Or
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 1;
-
- m_prgbActionBlock = new byte[7];
- pb = m_prgbActionBlock;
-
- // Rule 0: _ > gHyphen / _ # {break == 2} ^;
-
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutGlyph8bitObs; *pb++ = 4; // PutGlyph 4 ('-' = 45)
- *pb++ = kopNext; // Next
- *pb++ = kopPushByte; *pb++ = 1; // Push 1
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- }
- else
- Assert(false);
-}
-
-
-void GrFSM::SetUpAssocTest(int ipass)
-{
- if (ipass == 1)
- {
- // Create machine class ranges.
- m_cmcr = 2;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 35; // #
- m_prgmcr[0].m_chwLast = 35;
- m_prgmcr[0].m_col = 1;
-
- m_prgmcr[1].m_chwFirst = 120; // x
- m_prgmcr[1].m_chwLast = 120;
- m_prgmcr[1].m_col = 0;
-
- m_dimcrInit = 2; // (max power of 2 <= m_cmcr);
- m_cLoop = 1; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 4;
- m_crowNonAcpt = 2;
- m_crowFinal = 2;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 2;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 4
- short * psn = m_prgrowTransitions;
- *psn++ = 2; *psn++ = 1;
- *psn++ = 3; *psn++ = 0;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1];
-
- m_prgirulnMin[0] = 0; // s2: r1
- m_prgrulnMatched[0] = 1;
-
- m_prgirulnMin[1] = 1; // s3: r0
- m_prgrulnMatched[1] = 0;
-
- m_prgirulnMin[2] = 2;
- }
- else if (ipass == 2)
- {
- // Create machine class ranges.
- m_cmcr = 13;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 35; // #
- m_prgmcr[0].m_chwLast = 35;
- m_prgmcr[0].m_col = 7;
-
- m_prgmcr[1].m_chwFirst = 65; // A
- m_prgmcr[1].m_chwLast = 65;
- m_prgmcr[1].m_col = 0;
-
- m_prgmcr[2].m_chwFirst = 69; // E
- m_prgmcr[2].m_chwLast = 69;
- m_prgmcr[2].m_col = 2;
-
- m_prgmcr[3].m_chwFirst = 79; // O
- m_prgmcr[3].m_chwLast = 79;
- m_prgmcr[3].m_col = 0;
-
- m_prgmcr[4].m_chwFirst = 97; // a
- m_prgmcr[4].m_chwLast = 97;
- m_prgmcr[4].m_col = 1;
-
- m_prgmcr[5].m_chwFirst = 98; // b - d
- m_prgmcr[5].m_chwLast = 100;
- m_prgmcr[5].m_col = 4;
-
- m_prgmcr[6].m_chwFirst = 101; // e
- m_prgmcr[6].m_chwLast = 101;
- m_prgmcr[6].m_col = 3;
-
- m_prgmcr[7].m_chwFirst = 102; // f - n
- m_prgmcr[7].m_chwLast = 110;
- m_prgmcr[7].m_col = 4;
-
- m_prgmcr[8].m_chwFirst = 111; // o
- m_prgmcr[8].m_chwLast = 111;
- m_prgmcr[8].m_col = 1;
-
- m_prgmcr[9].m_chwFirst = 112; // p - w
- m_prgmcr[9].m_chwLast = 119;
- m_prgmcr[9].m_col = 4;
-
- m_prgmcr[10].m_chwFirst = 120; // x
- m_prgmcr[10].m_chwLast = 120;
- m_prgmcr[10].m_col = 5;
-
- m_prgmcr[11].m_chwFirst = 121; // y - z
- m_prgmcr[11].m_chwLast = 122;
- m_prgmcr[11].m_col = 4;
-
- m_prgmcr[12].m_chwFirst = 188; // 1/4, 1/2, 3/4
- m_prgmcr[12].m_chwLast = 190;
- m_prgmcr[12].m_col = 6;
-
-
- m_dimcrInit = 8; // (max power of 2 <= m_cmcr);
- m_cLoop = 3; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 9;
- m_crowNonAcpt = 6;
- m_crowFinal = 3;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 8;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 48
- short * psn = m_prgrowTransitions;
- *psn++ = 1; *psn++ = 2; *psn++ = 0; *psn++ = 4; *psn++ = 3; *psn++ = 3; *psn++ = 6; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 5;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 5;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 5;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 8; *psn++ = 0; *psn++ = 0;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[3+1]; // 3 = m_crow - m_crowNonAcpt
-
- m_prgirulnMin[0] = 0; // s6: r2
- m_prgrulnMatched[0] = 2;
-
- m_prgirulnMin[1] = 1; // s7: r0
- m_prgrulnMatched[1] = 0;
-
- m_prgirulnMin[2] = 2; // s8: r1
- m_prgrulnMatched[2] = 1;
-
- m_prgirulnMin[3] = 3;
- }
- else if (ipass == 3)
- {
- // Create machine class ranges.
- m_cmcr = 1;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 35; // #
- m_prgmcr[0].m_chwLast = 35;
- m_prgmcr[0].m_col = 0;
-
- m_dimcrInit = 1; // (max power of 2 <= m_cmcr);
- m_cLoop = 0; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 2;
- m_crowNonAcpt = 1;
- m_crowFinal = 1;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 1;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 1
- short * psn = m_prgrowTransitions;
- *psn++ = 1;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[1]; // 1 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1];
-
- m_prgirulnMin[0] = 0; // s1: r0
- m_prgrulnMatched[0] = 0;
-
- m_prgirulnMin[1] = 1;
- }
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Second batch of association tests.
-
- PASS 1:
- r0. clsSymbol _ > _ @1 / _ gNumber gHyphen # gNumber _;
- r1. clsSymbol _ > _ @1 / _ gHyphen # _;
- r2. _ clsSymbol > @6 _ / _ gNumber gHyphen # gNumber _;
- r3. _ clsSymbol > @4 _ / _ gHyphen # _;
- r4. clsLeft _ > @1 clsRight$1:1 / _ clsLetter gHyphen # _ gSpace;
- r5. clsLeft _ > @1 clsRight$1:1 / _ clsLetter gHyphen # clsLetter _ gSpace;
- r6. clsLeft _ > @1 clsRight$1:1 / _ clsLetter _ gSpace;
- r7. clsLeft _ > @1 clsRight$1:1 / _ clsLetter clsLetter _ gSpace;
-
- Pass 1 machine classes:
- mcSym: @, $, %, & 64, 36, 37, 38
- mcNum: 48-57
- mcHyphen: 45
- mcSpace: 32
- mcLet: 97-122
- mcLeft: ( [ { 40, 91, 123
- mcRight: ) ] } 41, 93, 125
-
- Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting)
-
- | mcSym mcNum mcHyph mcSpace mcLet mcLeft mcLB
- ----------------------------------------------------------------------------------
- T NA s0 | s1 s2 s3 s4
- |
- T NA s1 | s5 s6
- |
- T NA s2 | s7
- |
- T NA s3 | s8
- |
- T NA s4 | s9
- |
- T NA s5 | s10
- |
- T NA s6 | s18
- |
- T NA s7 | s11
- |
- T NA s8 | s19
- |
- T NA s9 | s12 s20 s13
- |
- T NA s10 | s14
- |
- T NA s11 | s15
- |
- T NA s12 | s16
- |
- T NA s13 | s21
- |
- T NA s14 | s22
- |
- T NA s15 | s23
- |
- T NA s16 | s24 s17
- |
- T NA s17 | s25
- |
- F A s18 |
- |
- F A s19 |
- |
- F A s20 |
- |
- F A s21 |
- |
- F A s22 |
- |
- F A s23 |
- |
- F A s24 |
- |
- F A s25 |
-
-
- Rules Matched:
- s18: r1
- s19: r3
- s20: r6
- s21: r7
- s22: r0
- s23: r2
- s24: r4
- s25: r5
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpAssoc2Test()
-{
- if (m_pctbl)
- delete m_pctbl;
-
- m_pctbl = new GrClassTable();
- m_pctbl->SetUpAssoc2Test();
-
- m_fLineBreak = true;
- m_cchwPreXlbContext = 3;
- m_cchwPostXlbContext = 2;
-}
-
-void GrClassTable::SetUpAssoc2Test()
-{
- m_ccls = 2; // number of classes
- m_cclsLinear = 1; // number of classes in linear format (output classes)
-
- m_prgchwBIGGlyphList = new data16[13];
-
- m_prgichwOffsets = new data16[m_ccls+1];
-
- data16 * pchw = m_prgchwBIGGlyphList;
-
- // Output class 0: clsRight
- m_prgichwOffsets[0] = 0;
- *pchw++ = msbf(data16(41)); // )
- *pchw++ = msbf(data16(93)); // ]
- *pchw++ = msbf(data16(125)); // }
-
- // Input class 1: clsLeft
- m_prgichwOffsets[1] = 3;
- *pchw++ = msbf(data16(3));
- *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2));
- *pchw++ = msbf(data16(40)); *pchw++ = msbf(data16(0)); // (
- *pchw++ = msbf(data16(91)); *pchw++ = msbf(data16(1)); // [
- *pchw++ = msbf(data16(123)); *pchw++ = msbf(data16(2)); // {
-
- m_prgichwOffsets[2] = 3 + 4 + 3*2; // 13
-}
-
-void GrSubPass::SetUpAssoc2Test()
-{
- m_nMaxRuleContext = m_nMaxChunk = 6;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "Assoc2";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpAssoc2Test(m_ipass);
-
- m_crul = 8;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 0;
- m_prgibConstraintStart[1] = 0;
- m_prgibConstraintStart[2] = 0;
- m_prgibConstraintStart[3] = 0;
- m_prgibConstraintStart[4] = 0;
- m_prgibConstraintStart[5] = 0;
- m_prgibConstraintStart[6] = 0;
- m_prgibConstraintStart[7] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[11 + 9 + 11 + 9 + 14 + 15 + 12 + 13];
- pb = m_prgbActionBlock;
-
- // Rule 0: clsSymbol _ > _ @1 / _ gNumber gHyphen # gNumber _;
-
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutCopy; *pb++ = -4; // PutCopy -4
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 1: clsSymbol _ > _ @1 / _ gHyphen # _;
-
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutCopy; *pb++ = -2; // PutCopy -2
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 2: _ clsSymbol > @6 _ / _ gNumber gHyphen # gNumber _;
-
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutCopy; *pb++ = 5; // PutCopy 5
- *pb++ = kopNext; // Next
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 3: _ clsSymbol > @4 _ / _ gHyphen # _;
-
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutCopy; *pb++ = 3; // PutCopy 3
- *pb++ = kopNext; // Next
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 4: clsLeft _ > @1 clsRight$1 / _ clsLetter gHyphen # _ gSpace;
-
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutSubs8bitObs; *pb++ = -3; // PutSubs -3 1 0
- *pb++ = 1; *pb++ = 0;
- *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 -3
- *pb++ = -3;
- *pb++ = kopNext; // Next;
- *pb++ = kopRetZero; // RetZero
-
- // Rule 5: clsLeft _ > @1 clsRight$1 / _ clsLetter gHyphen # clsLetter _ gSpace;
-
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutSubs8bitObs; *pb++ = -4; // PutSubs -4 1 0
- *pb++ = 1; *pb++ = 0;
- *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 -4
- *pb++ = -4;
- *pb++ = kopNext; // Next;
- *pb++ = kopRetZero; // RetZero
-
- // Rule 6: clsLeft _ > @1 clsRight$1 / _ clsLetter _ gSpace;
-
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutSubs8bitObs; *pb++ = -1; // PutSubs -1 1 0
- *pb++ = 1; *pb++ = 0;
- *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 -1
- *pb++ = -1;
- *pb++ = kopNext; // Next;
- *pb++ = kopRetZero; // RetZero
-
- // Rule 7: clsLeft _ > @1 clsRight$1 / _ clsLetter clsLetter _ gSpace;
-
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutSubs8bitObs; *pb++ = -2; // PutSubs -2 1 0
- *pb++ = 1; *pb++ = 0;
- *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 -2
- *pb++ = -2;
- *pb++ = kopNext; // Next;
- *pb++ = kopRetZero; // RetZero
-
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 11;
- m_prgibActionStart[2] = 11 + 9;
- m_prgibActionStart[3] = 20 + 11;
- m_prgibActionStart[4] = 31 + 9;
- m_prgibActionStart[5] = 40 + 14;
- m_prgibActionStart[6] = 54 + 15;
- m_prgibActionStart[7] = 69 + 12;
-}
-
-
-void GrFSM::SetUpAssoc2Test(int ipass)
-{
- // Create machine class ranges.
- m_cmcr = 10;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 32; // space
- m_prgmcr[0].m_chwLast = 32;
- m_prgmcr[0].m_col = 3;
-
- m_prgmcr[1].m_chwFirst = 35; // #
- m_prgmcr[1].m_chwLast = 35;
- m_prgmcr[1].m_col = 6;
-
- m_prgmcr[2].m_chwFirst = 36; // $, %, &
- m_prgmcr[2].m_chwLast = 38;
- m_prgmcr[2].m_col = 0;
-
- m_prgmcr[3].m_chwFirst = 40; // (
- m_prgmcr[3].m_chwLast = 40;
- m_prgmcr[3].m_col = 5;
-
- m_prgmcr[4].m_chwFirst = 45; // -
- m_prgmcr[4].m_chwLast = 45;
- m_prgmcr[4].m_col = 2;
-
- m_prgmcr[5].m_chwFirst = 48; // 0 - 9
- m_prgmcr[5].m_chwLast = 57;
- m_prgmcr[5].m_col = 1;
-
- m_prgmcr[6].m_chwFirst = 64; // @
- m_prgmcr[6].m_chwLast = 64;
- m_prgmcr[6].m_col = 0;
-
- m_prgmcr[7].m_chwFirst = 91; // [
- m_prgmcr[7].m_chwLast = 91;
- m_prgmcr[7].m_col = 5;
-
- m_prgmcr[8].m_chwFirst = 97; // a - z
- m_prgmcr[8].m_chwLast = 122;
- m_prgmcr[8].m_col = 4;
-
- m_prgmcr[9].m_chwFirst = 123; // {
- m_prgmcr[9].m_chwLast = 123;
- m_prgmcr[9].m_col = 5;
-
-
- m_dimcrInit = 8; // (max power of 2 <= m_cmcr);
- m_cLoop = 3; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 26;
- m_crowNonAcpt = 18;
- m_crowFinal = 8;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 7;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 126
- short * psn = m_prgrowTransitions;
- *psn++ = 1; *psn++ = 2; *psn++ = 3; *psn++ = 0; *psn++ = 0; *psn++ = 4; *psn++ = 0;
- *psn++ = 0; *psn++ = 5; *psn++ = 6; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 8;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 9; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ =10; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =18;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =11;
- *psn++ =19; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ =12; *psn++ =20; *psn++ =13; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =14;
- *psn++ = 0; *psn++ =15; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =16;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =21; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ =22; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ =23; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =24; *psn++ =17; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =25; *psn++ = 0; *psn++ = 0; *psn++ = 0;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[8]; // 3 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1];
-
- m_prgirulnMin[0] = 0; // s18: r1
- m_prgrulnMatched[0] = 1;
-
- m_prgirulnMin[1] = 1; // s19: r3
- m_prgrulnMatched[1] = 3;
-
- m_prgirulnMin[2] = 2; // s20: r6
- m_prgrulnMatched[2] = 6;
-
- m_prgirulnMin[3] = 3; // s21: r7
- m_prgrulnMatched[3] = 7;
-
- m_prgirulnMin[4] = 4; // s22: r0
- m_prgrulnMatched[4] = 0;
-
- m_prgirulnMin[5] = 5; // s23: r2
- m_prgrulnMatched[5] = 2;
-
- m_prgirulnMin[6] = 6; // s24: r4
- m_prgrulnMatched[6] = 4;
-
- m_prgirulnMin[7] = 7; // s25: r5
- m_prgrulnMatched[7] = 5;
-
- m_prgirulnMin[8] = 8;
-}
-
-/*----------------------------------------------------------------------------------------------
- Test of default associations
-
- PASS 1:
- r0. gDollar _ > @1 gEquals;
- r1. gAtSign > _ ;
-
- Pass 1 machine classes:
- mcDollar: $ 36
- mcAt: @ 64
-
- Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting)
-
- | mcDollar mcAt
- --------------------------------------
- T NA s0 | s1 s2
- |
- F A s1 |
- |
- F A s2 |
-
-
- Rules Matched:
- s1: r0
- s2: r1
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpDefaultAssocTest()
-{
- if (m_pctbl)
- delete m_pctbl;
-
- m_pctbl = new GrClassTable();
- m_pctbl->SetUpDefaultAssocTest();
-}
-
-void GrClassTable::SetUpDefaultAssocTest()
-{
- m_ccls = 1; // number of classes
- m_cclsLinear = 1; // number of classes in linear format
-
- m_prgchwBIGGlyphList = new data16[1];
-
- m_prgichwOffsets = new data16[m_ccls+1];
-
- data16 * pchw = m_prgchwBIGGlyphList;
-
- // Output class 0: gEquals
- m_prgichwOffsets[0] = 0;
- *pchw++ = msbf(data16(61));
-
- m_prgichwOffsets[1] = 1;
-}
-
-void GrSubPass::SetUpDefaultAssocTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "DefaultAssoc";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpDefaultAssocTest();
-
- m_crul = 2;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue;
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 0;
- m_prgibConstraintStart[1] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[6 + 3];
- pb = m_prgbActionBlock;
-
- // Rule 0: gDollar _ > @1 gEquals;
-
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopInsert; // Insert
- *pb++ = kopPutGlyph8bitObs; *pb++ = 0; // PutGlyph 0
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 1: gAtSign > _ ;
-
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 6;
-}
-
-
-void GrFSM::SetUpDefaultAssocTest()
-{
- // Create machine class ranges.
- m_cmcr = 2;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 36; // $
- m_prgmcr[0].m_chwLast = 36;
- m_prgmcr[0].m_col = 0;
-
- m_prgmcr[1].m_chwFirst = 64; // @
- m_prgmcr[1].m_chwLast = 64;
- m_prgmcr[1].m_col = 1;
-
-
- m_dimcrInit = 2; // (max power of 2 <= m_cmcr);
- m_cLoop = 1; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 3;
- m_crowNonAcpt = 1;
- m_crowFinal = 2;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 2;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 2
- short * psn = m_prgrowTransitions;
- *psn++ = 1; *psn++ = 2;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1];
-
- m_prgirulnMin[0] = 0; // s1: r0
- m_prgrulnMatched[0] = 0;
-
- m_prgirulnMin[1] = 1; // s2: r1
- m_prgrulnMatched[1] = 1;
-
- m_prgirulnMin[2] = 2;
-}
-
-/*----------------------------------------------------------------------------------------------
- Test of features. The ID of "theFeature" == 234, its index is 0. The default value is 1.
-
- PASS 1:
- if (theFeature == 0) // * -> $
- r0. gAsterisk > gDollar ;
- else if (theFeature == 1) // * -> %
- r1. gAsterisk > gPercent ;
- else // * -> @
- r2. gAsterisk > gAt ;
-
- Pass 1 machine classes:
- mcAsterisk: * 42
-
- Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting)
-
- | mcAsterisk
- --------------------------------
- T NA s0 | s1
- |
- F A s1 |
-
-
- Rules Matched:
- s1: r0, r1, r2
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpFeatureTest()
-{
- AddFeature(234, 0, 1, 1);
-
- if (m_pctbl)
- delete m_pctbl;
-
- m_pctbl = new GrClassTable();
- m_pctbl->SetUpFeatureTest();
-}
-
-void GrClassTable::SetUpFeatureTest()
-{
- m_ccls = 4; // number of classes
- m_cclsLinear = 4; // number of classes in linear format
-
- m_prgchwBIGGlyphList = new data16[4];
-
- m_prgichwOffsets = new data16[m_ccls + 1];
-
- data16 * pchw = m_prgchwBIGGlyphList;
-
- m_prgichwOffsets[0] = 0;
- *pchw++ = msbf(data16(36)); // $
-
- m_prgichwOffsets[1] = 1;
- *pchw++ = msbf(data16(37)); // %
-
- m_prgichwOffsets[2] = 2;
- *pchw++ = msbf(data16(64)); // @
-
- m_prgichwOffsets[3] = 3;
- *pchw++ = msbf(data16(42)); // *
-
- m_prgichwOffsets[4] = 4;
-}
-
-void GrSubPass::SetUpFeatureTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "Feature";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpFeatureTest();
-
- m_crul = 3;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1 + 6 + 12 + 12];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue;
-
- // (theFeature == 0)
- *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0
- *pb++ = kopPushByte; *pb++ = 0; // PushByte 0
- *pb++ = kopEqual; // Equal
- *pb++ = kopPopRet; // PopAndRet
-
- // (theFeature != 0 && theFeature == 1)
- *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0
- *pb++ = kopPushByte; *pb++ = 0; // PushByte 0
- *pb++ = kopNotEq; // NotEq
- *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0
- *pb++ = kopPushByte; *pb++ = 1; // PushByte 1
- *pb++ = kopEqual; // Equal
- *pb++ = kopAnd; // And
- *pb++ = kopPopRet; // PopAndRet
-
- // (theFeature != 0 && theFeature != 1)
- *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0
- *pb++ = kopPushByte; *pb++ = 0; // PushByte 0
- *pb++ = kopNotEq; // NotEq
- *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0
- *pb++ = kopPushByte; *pb++ = 1; // PushByte 1
- *pb++ = kopNotEq; // NotEq
- *pb++ = kopAnd; // And
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 1;
- m_prgibConstraintStart[1] = 1 + 6;
- m_prgibConstraintStart[2] = 1 + 6 + 12;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[4 + 4 + 4];
- pb = m_prgbActionBlock;
-
- // Rule 0: gAsterisk > gDollar ;
-
- *pb++ = kopPutGlyph8bitObs; *pb++ = 0; // PutGlyph 0
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 1: gAsterisk > gPercent ;
-
- *pb++ = kopPutGlyph8bitObs; *pb++ = 1; // PutGlyph 1
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 2: gAsterisk > gAt ;
-
- *pb++ = kopPutGlyph8bitObs; *pb++ = 2; // PutGlyph 2
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 4;
- m_prgibActionStart[2] = 4 + 4;
-}
-
-
-void GrFSM::SetUpFeatureTest()
-{
- // Create machine class ranges.
- m_cmcr = 1;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 42; // *
- m_prgmcr[0].m_chwLast = 42;
- m_prgmcr[0].m_col = 0;
-
-
- m_dimcrInit = 1; // (max power of 2 <= m_cmcr);
- m_cLoop = 0; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 2;
- m_crowNonAcpt = 1;
- m_crowFinal = 1;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 1;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 1
- short * psn = m_prgrowTransitions;
- *psn++ = 1;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1];
-
- m_prgirulnMin[0] = 0; // s1: r0, r1, r2
- m_prgrulnMatched[0] = 0;
- m_prgrulnMatched[1] = 1;
- m_prgrulnMatched[2] = 2;
-
- m_prgirulnMin[1] = 3;
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Tests of ligatures and components.
-
- PASS 1 (line-break):
- r0. clsLetter { break = 2 }
-
- Pass 1 machine classes:
- mcLetter: a - z 97 - 122
-
- Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting)
-
- | clsLetter
- --------------------------------
- T NA s0 | s1
- |
- F A s1 |
-
-
- Rules Matched:
- s1: r0
-
-
- PASS 2 (substitution):
- r0. gX gY gZ > gCapX:(1 2 4) { comp {X.ref=@1; Y.ref=@2; Z.ref=@4 }} _ _
- / _ _ # {break==2} _;
- r1. gX gY gZ > _ _ gCapZ:(1 3 4) { comp {X.ref=@1; Y.ref=@3; Z.ref=@4 }}
- / _ # {break==2} _ _;
- r2. gX gY gZ > _ gCapY:(1 2 3) { comp {X.ref=@1; Y.ref=@2; Z.ref=@3 }} gPlus;
-
- Pass 2 machine classes:
- mcX: x 120
- mcY: y 121
- mcZ: z 122
- mcLB: 35
-
-
- Pass 2 FSM:
- | mcX mcY mcZ mcLB
- ----------------------------------------------------
- T NA s0 | s1
- | - - -
- T NA s1 | s2 s3
- | - - -
- T NA s2 | s6 s4
- | - - -
- T NA s3 | s5
- | - - -
- T NA s4 | s7
- | - - -
- T NA s5 | s8
- | - - -
- F A s6 |
- | - - -
- F A s7 |
- | - - -
- F A s8 |
- | - - -
-
- Rules matched:
- s6: r2
- s7: r0
- s8: r1
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpLigatureTest()
-{
- if (m_pctbl)
- delete m_pctbl;
-
- m_pctbl = new GrClassTable();
- m_pctbl->SetUpLigatureTest();
-
- m_pgtbl = new GrGlyphTable();
- m_pgtbl->SetUpLigatureTest();
-
- m_fLineBreak = true;
- m_cchwPreXlbContext = 2;
- m_cchwPostXlbContext = 2;
-}
-
-void GrClassTable::SetUpLigatureTest()
-{
- m_ccls = 7; // number of classes
- m_cclsLinear = 7; // number of classes in linear format (all classes are single-item)
-
- m_prgchwBIGGlyphList = new data16[7];
-
- m_prgichwOffsets = new data16[m_ccls+1];
-
- data16 * pchw = m_prgchwBIGGlyphList;
-
- // Class 0: gCapX
- m_prgichwOffsets[0] = 0;
- *pchw++ = msbf(data16(88)); // X
-
- // Class 1: gCapY
- m_prgichwOffsets[1] = 1;
- *pchw++ = msbf(data16(89)); // Y
-
- // Class 2: gCapZ
- m_prgichwOffsets[2] = 2;
- *pchw++ = msbf(data16(90)); // Z
-
- // Class 3: gPlus
- m_prgichwOffsets[3] = 3;
- *pchw++ = msbf(data16(43)); // +
-
- // Class 4: gX
- m_prgichwOffsets[4] = 4;
- *pchw++ = msbf(data16(120)); // x
-
- // Class 5: gY
- m_prgichwOffsets[5] = 5;
- *pchw++ = msbf(data16(121)); // y
-
- // Class 6: gZ
- m_prgichwOffsets[6] = 6;
- *pchw++ = msbf(data16(122)); // z
-
- m_prgichwOffsets[7] = 7;
-}
-
-void GrGlyphTable::SetUpLigatureTest()
-{
- SetNumberOfGlyphs(128);
- SetNumberOfStyles(1);
-
- GrGlyphSubTable * pgstbl = new GrGlyphSubTable();
- Assert(pgstbl);
-
- pgstbl->Initialize(1, 0, 128, 10, 4);
- SetSubTable(0, pgstbl);
-
- SetNumberOfComponents(4); // comp.w, comp.x, comp.y, comp.z
-
- pgstbl->SetUpLigatureTest();
-}
-
-/***********************************************************************************************
- TODO: This method is BROKEN because m_prgibBIGAttrValues has been changed. It is no
- longer a data16 *. The Gloc table can contain 16-bit or 32-bit entries and must be
- accessed accordingly.
-***********************************************************************************************/
-void GrGlyphSubTable::SetUpLigatureTest()
-{
- m_nAttrIDLim = 20;
-
- m_pgatbl = new GrGlyphAttrTable();
- m_pgatbl->Initialize(0, 102);
-
- for (int i = 0; i < 88; i++)
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(0));
-
- m_prgibBIGAttrValues[88] = (byte)msbf(data16(0));
- m_prgibBIGAttrValues[89] = (byte)msbf(data16(34));
- m_prgibBIGAttrValues[90] = (byte)msbf(data16(68));
-
- for (i = 91; i < 128; i++)
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(102));
-
- m_pgatbl->SetUpLigatureTest();
-}
-
-void GrGlyphAttrTable::SetUpLigatureTest()
-{
- // Glyph 88 'X' (2 runs; offset = 0):
- // 0 = 0 comp.w undefined
- // 1 = 8 comp.x: (0,0, 25,100)
- // 2 = 12 comp.y: (25,0, 75,100)
- // 3 = 16 comp.z: (75,0, 100,100)
- // 4-7 = 0 comp.w box corners
- // 8 = 100 comp.x. top
- // 9 = 0 bottom
- // 10= 0 left
- // 11= 25 right
- // 12= 100 comp.y. top
- // 13= 0 bottom
- // 14= 25 left
- // 15= 75 right
- // 16= 100 comp.z. top
- // 17= 0 bottom
- // 18= 75 left
- // 19= 100 right
- //
- // Glyph 89 (2 runs; offset = 34):
- // 0 = 0 comp.w undefined
- // 1 = 8 comp.x: (0,0, 33,100)
- // 2 = 12 comp.y: (33,0, 67,100)
- // 3 = 16 comp.z: (67,0, 100,100)
- // 4-7 = 0 comp.w box corners
- // 8 = 100 comp.x. top
- // 9 = 0 bottom
- // 10= 0 left
- // 11= 33 right
- // 12= 100 comp.y. top
- // 13= 0 bottom
- // 14= 33 left
- // 15= 67 right
- // 16= 100 comp.z. top
- // 17= 0 bottom
- // 18= 67 left
- // 19= 100 right
- //
- // Glyph 90 (2 runs; offset = 68):
- // 0 = 0 comp.w undefined
- // 1 = 8 comp.x: (0,0, 10,100)
- // 2 = 12 comp.y: (10,0, 90,100)
- // 3 = 16 comp.z: (90,0, 100,100)
- // 4-7 = 0 comp.w box corners
- // 8 = 100 comp.x. top
- // 9 = 0 bottom
- // 10= 0 left
- // 11= 10 right
- // 12= 100 comp.y. top
- // 13= 0 bottom
- // 14= 10 left
- // 15= 90 right
- // 16= 100 comp.z. top
- // 17= 0 bottom
- // 18= 90 left
- // 19= 100 right
-
- byte * pbBIG = m_prgbBIGEntries;
-
- GrGlyphAttrRun gatrun;
-
- // Glyph 88 'X'
- gatrun.m_bMinAttrID = 1;
- gatrun.m_cAttrs = 3;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(8));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(12));
- gatrun.m_rgchwBIGValues[2] = msbf(data16(16));
- memcpy(pbBIG, &gatrun, 8); // 8 = 3*2 + 2
- pbBIG += 8;
- gatrun.m_bMinAttrID = 8; // comp.x.top
- gatrun.m_cAttrs = 12;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[2] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[3] = msbf(data16(25));
- gatrun.m_rgchwBIGValues[4] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[5] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[6] = msbf(data16(25));
- gatrun.m_rgchwBIGValues[7] = msbf(data16(75));
- gatrun.m_rgchwBIGValues[8] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[9] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[10] = msbf(data16(75));
- gatrun.m_rgchwBIGValues[11] = msbf(data16(100));
- memcpy(pbBIG, &gatrun, 26); // 26 = 12*2 + 2
- pbBIG += 26;
-
- // Glyph 89 'Y'
- gatrun.m_bMinAttrID = 1;
- gatrun.m_cAttrs = 3;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(8));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(12));
- gatrun.m_rgchwBIGValues[2] = msbf(data16(16));
- memcpy(pbBIG, &gatrun, 8); // 8 = 3*2 + 2
- pbBIG += 8;
- gatrun.m_bMinAttrID = 8; // comp.x.top
- gatrun.m_cAttrs = 12;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[2] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[3] = msbf(data16(33));
- gatrun.m_rgchwBIGValues[4] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[5] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[6] = msbf(data16(33));
- gatrun.m_rgchwBIGValues[7] = msbf(data16(67));
- gatrun.m_rgchwBIGValues[8] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[9] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[10] = msbf(data16(67));
- gatrun.m_rgchwBIGValues[11] = msbf(data16(100));
- memcpy(pbBIG, &gatrun, 26); // 26 = 12*2 + 2
- pbBIG += 26;
-
- // Glyph 90 'Z'
- gatrun.m_bMinAttrID = 1;
- gatrun.m_cAttrs = 3;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(8));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(12));
- gatrun.m_rgchwBIGValues[2] = msbf(data16(16));
- memcpy(pbBIG, &gatrun, 8); // 8 = 3*2 + 2
- pbBIG += 8;
- gatrun.m_bMinAttrID = 8; // comp.x.top
- gatrun.m_cAttrs = 12;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[2] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[3] = msbf(data16(10));
- gatrun.m_rgchwBIGValues[4] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[5] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[6] = msbf(data16(10));
- gatrun.m_rgchwBIGValues[7] = msbf(data16(90));
- gatrun.m_rgchwBIGValues[8] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[9] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[10] = msbf(data16(90));
- gatrun.m_rgchwBIGValues[11] = msbf(data16(100));
- memcpy(pbBIG, &gatrun, 26); // 26 = 12*2 + 2
- pbBIG += 26;
-
- Assert(pbBIG == m_prgbBIGEntries + 102);
-}
-
-void GrLineBreakPass::SetUpLigatureTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "Ligatures";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpLigatureTest(m_ipass);
-
- m_crul = 1;
-
- // Set up constraint code--succeed trivially.
- m_prgbConstraintBlock = new byte[1];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[8];
- pb = m_prgbActionBlock;
-
- // Rule 0: clsLetter { break = 2 }
-
- *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0
- *pb++ = kopPushByte; *pb++ = 2; // PushByte 2
- *pb++ = kopAttrSet; *pb++ = kslatBreak; // AttrSet breakweight
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
-}
-
-void GrSubPass::SetUpLigatureTest()
-{
- if (m_ipass == 2)
- {
- m_nMaxRuleContext = m_nMaxChunk = 4;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "Ligatures";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpLigatureTest(m_ipass);
-
- m_crul = 3;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1 + 10 + 10];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- *pb++ = kopCntxtItem; *pb++ = 2; // ContextItem 2
- *pb++ = kopPushSlotAttr;*pb++ = kslatBreak; // PushSlotAttr break 0
- *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = 2; // Push 2
- *pb++ = kopEqual; // Equal
- *pb++ = kopOr; // Or
- *pb++ = kopPopRet; // PopAndRet
-
- *pb++ = kopCntxtItem; *pb++ = 1; // ContextItem 1
- *pb++ = kopPushSlotAttr;*pb++ = kslatBreak; // PushSlotAttr break 0
- *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = 2; // Push 2
- *pb++ = kopEqual; // Equal
- *pb++ = kopOr; // Or
- *pb++ = kopPopRet; // PopAndRet
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 1;
- m_prgibConstraintStart[1] = 11;
- m_prgibConstraintStart[2] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[29 + 29 + 29];
- pb = m_prgbActionBlock;
-
- // Rule 0: gX gY gZ > gCapX:(1 2 4) { comp {X.ref=@1; Y.ref=@2; Z.ref=@4 }} _ _
- // / _ _ # {break==2} _;
-
- *pb++ = kopPutGlyph8bitObs; *pb++ = 0; // PutGlyph 0 (gCapX)
- *pb++ = kopAssoc; *pb++ = 3; // Assoc 3 0 1 3
- *pb++ = 0; *pb++ = 1; *pb++ = 3;
- *pb++ = kopPushByte; *pb++ = 0; // Push 0
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref x
- *pb++ = kslatCompRef; *pb++ = 1;
- *pb++ = kopPushByte; *pb++ = 1; // Push 1
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref y
- *pb++ = kslatCompRef; *pb++ = 2;
- *pb++ = kopPushByte; *pb++ = 3; // Push 3
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref z
- *pb++ = kslatCompRef; *pb++ = 3;
- *pb++ = kopNext; // Next
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 1: gX gY gZ > _ _ gCapZ:(1 3 4) { comp {X.ref=@1; Y.ref=@3; Z.ref=@4 }}
- // / _ # {break==2} _ _;
-
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopCopyNext; // CopyNext
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopPutGlyph8bitObs; *pb++ = 2; // PutGlyph 2 (gCapZ)
- *pb++ = kopAssoc; *pb++ = 3; // Assoc 3 -3 -1 0
- *pb++ = -3; *pb++ = -1; *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = -3; // Push -3
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref x
- *pb++ = kslatCompRef; *pb++ = 1;
- *pb++ = kopPushByte; *pb++ = -1; // Push -1
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref y
- *pb++ = kslatCompRef; *pb++ = 2;
- *pb++ = kopPushByte; *pb++ = 0; // Push 0
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref z
- *pb++ = kslatCompRef; *pb++ = 3;
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 2: gX gY gZ > _ gCapY:(1 2 3) { comp {X.ref=@1; Y.ref=@2; Z.ref=@3 }} gPlus;
-
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopPutGlyph8bitObs; *pb++ = 1; // PutGlyph 1 (gCapY)
- *pb++ = kopAssoc; *pb++ = 3; // Assoc 3 -1 0 1
- *pb++ = -1; *pb++ = 0; *pb++ = 1;
- *pb++ = kopPushByte; *pb++ = -1; // Push -1
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref x
- *pb++ = kslatCompRef; *pb++ = 1;
- *pb++ = kopPushByte; *pb++ = 0; // Push 0
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref y
- *pb++ = kslatCompRef; *pb++ = 2;
- *pb++ = kopPushByte; *pb++ = 1; // Push 1
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref z
- *pb++ = kslatCompRef; *pb++ = 3;
- *pb++ = kopNext; // Next
- *pb++ = kopPutGlyph8bitObs; *pb++ = 3; // PutGlyph 3 (gPlus)
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 29;
- m_prgibActionStart[2] = 29 + 29;
- }
- else
- Assert(false);
-}
-
-
-void GrFSM::SetUpLigatureTest(int ipass)
-{
- if (ipass == 1)
- {
- // Create machine class ranges.
- m_cmcr = 1;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 97; // a - z
- m_prgmcr[0].m_chwLast = 122;
- m_prgmcr[0].m_col = 0;
-
- m_dimcrInit = 1; // (max power of 2 <= m_cmcr);
- m_cLoop = 0; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 2;
- m_crowNonAcpt = 1;
- m_crowFinal = 1;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 1;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 1
- short * psn = m_prgrowTransitions;
- *psn++ = 1;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[1]; // 1 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1];
-
- m_prgirulnMin[0] = 0; // s1: r0
- m_prgrulnMatched[0] = 0;
-
- m_prgirulnMin[1] = 1;
- }
- else if (ipass == 2)
- {
- // Create machine class ranges.
- m_cmcr = 4;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 35; // #
- m_prgmcr[0].m_chwLast = 35;
- m_prgmcr[0].m_col = 3;
-
- m_prgmcr[1].m_chwFirst = 120; // x
- m_prgmcr[1].m_chwLast = 120;
- m_prgmcr[1].m_col = 0;
-
- m_prgmcr[2].m_chwFirst = 121; // y
- m_prgmcr[2].m_chwLast = 121;
- m_prgmcr[2].m_col = 1;
-
- m_prgmcr[3].m_chwFirst = 122; // z
- m_prgmcr[3].m_chwLast = 123;
- m_prgmcr[3].m_col = 2;
-
-
- m_dimcrInit = 4; // (max power of 2 <= m_cmcr);
- m_cLoop = 2; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 9;
- m_crowNonAcpt = 6;
- m_crowFinal = 3;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 4;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 24
- short * psn = m_prgrowTransitions;
- *psn++ = 1; *psn++ = 0; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 2; *psn++ = 0; *psn++ = 3;
- *psn++ = 0; *psn++ = 0; *psn++ = 6; *psn++ = 4;
- *psn++ = 0; *psn++ = 5; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 8; *psn++ = 0;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[3+1]; // 3 = m_crow - m_crowNonAcpt
-
- m_prgirulnMin[0] = 0; // s6: r2
- m_prgrulnMatched[0] = 2;
-
- m_prgirulnMin[1] = 1; // s7: r0
- m_prgrulnMatched[1] = 0;
-
- m_prgirulnMin[2] = 2; // s8: r1
- m_prgrulnMatched[2] = 1;
-
- m_prgirulnMin[3] = 3;
- }
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Tests of ligatures and components where the components are modified glyphs.
-
- PASS 1:
- r0. gX gI > @2 @1;
- r1. clsPlainVowel gAcute > clsVowelAcute:(1 2) _;
- r2. clsPlainVowel gGrave > clsVowelGrave:(1 2) _;
-
- Pass 1 machine classes:
- mcX: x 120
- mcI: i 105
- mcPV: a e o u 97 101 111 117
- mcAcute: / 47
- mcGrave: \ 92
-
- Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting)
-
- | mcX mcPV mcI mcAcute mcGrave
- ---------------------------------------------------------------
- T NA s0 | s1 s2 s2
- | - - - -
- T NA s1 | s3
- | - - - -
- T NA s2 | s4 s5
- | - - - -
- F A s3 |
- | - - - -
- F A s4 |
- | - - - -
- F A s5 |
- | - - - -
-
-
- Rules Matched:
- s3: r0
- s4: r1
- s5: r2
-
-
- PASS 2:
- r0. clsVowel gI > clsCapVowel:(1 2) { comp {v.ref = @1; i.ref = @2}} _;
-
- Pass 2 machine classes:
- mcV: 97 101 111 117
- 224 225 232 233 236 237 242 243 249 250
- mcI: i 105
-
-
- Pass 2 FSM:
- | mcV mcI
- ----------------------------------------------------
- T NA s0 | s1 s1
- | -
- T NA s1 | s2
- | -
- F A s2 |
- | -
-
- Rules matched:
- s2: r0
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpLigature2Test()
-{
- if (m_pctbl)
- delete m_pctbl;
-
- m_pctbl = new GrClassTable();
- m_pctbl->SetUpLigature2Test();
-
- m_pgtbl = new GrGlyphTable();
- m_pgtbl->SetUpLigature2Test();
-}
-
-void GrClassTable::SetUpLigature2Test()
-{
- m_ccls = 5; // number of classes
- m_cclsLinear = 3; // number of classes in linear format
-
- m_prgchwBIGGlyphList = new data16[73];
-
- m_prgichwOffsets = new data16[m_ccls+1];
-
- data16 * pchw = m_prgchwBIGGlyphList;
-
- // Output class 0: clsVowelAcute
- m_prgichwOffsets[0] = 0;
- *pchw++ = msbf(data16(225)); // a-acute
- *pchw++ = msbf(data16(233)); // e-acute
- *pchw++ = msbf(data16(237)); // i-acute
- *pchw++ = msbf(data16(243)); // o-acute
- *pchw++ = msbf(data16(250)); // u-acute
-
- // Output class 1: clsVowelGrave
- m_prgichwOffsets[1] = 5;
- *pchw++ = msbf(data16(224)); // a-grave
- *pchw++ = msbf(data16(232)); // e-grave
- *pchw++ = msbf(data16(236)); // i-grave
- *pchw++ = msbf(data16(242)); // o-grave
- *pchw++ = msbf(data16(249)); // u-grave
-
- // Output class 2: clsCapVowel
- m_prgichwOffsets[2] = 5 + 5; // 10
- *pchw++ = msbf(data16(65)); // A
- *pchw++ = msbf(data16(69)); // E
- *pchw++ = msbf(data16(73)); // I
- *pchw++ = msbf(data16(79)); // O
- *pchw++ = msbf(data16(85)); // U
- *pchw++ = msbf(data16(193)); // A-acute
- *pchw++ = msbf(data16(201)); // E-acute
- *pchw++ = msbf(data16(205)); // I-acute
- *pchw++ = msbf(data16(211)); // O-acute
- *pchw++ = msbf(data16(218)); // U-acute
- *pchw++ = msbf(data16(192)); // A-grave
- *pchw++ = msbf(data16(200)); // E-grave
- *pchw++ = msbf(data16(204)); // I-grave
- *pchw++ = msbf(data16(210)); // O-grave
- *pchw++ = msbf(data16(217)); // U-grave
-
- // Input class 3: clsPlainVowel
- m_prgichwOffsets[3] = 10 + 15; // 25
- *pchw++ = msbf(data16(5));
- *pchw++ = msbf(data16(4)); *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(5-4));
- *pchw++ = msbf(data16(97)); *pchw++ = msbf(data16(0)); // a
- *pchw++ = msbf(data16(101)); *pchw++ = msbf(data16(1)); // e
- *pchw++ = msbf(data16(105)); *pchw++ = msbf(data16(2)); // i
- *pchw++ = msbf(data16(111)); *pchw++ = msbf(data16(3)); // o
- *pchw++ = msbf(data16(117)); *pchw++ = msbf(data16(4)); // u
-
- // Input class 4: clsVowel
- m_prgichwOffsets[4] = 25 + 4+(5*2); // 39
- *pchw++ = msbf(data16(15));
- *pchw++ = msbf(data16(8)); *pchw++ = msbf(data16(3)); *pchw++ = msbf(data16(15-8));
- *pchw++ = msbf(data16(97)); *pchw++ = msbf(data16(0)); // a
- *pchw++ = msbf(data16(101)); *pchw++ = msbf(data16(1)); // e
- *pchw++ = msbf(data16(105)); *pchw++ = msbf(data16(2)); // i
- *pchw++ = msbf(data16(111)); *pchw++ = msbf(data16(3)); // o
- *pchw++ = msbf(data16(117)); *pchw++ = msbf(data16(4)); // u
- *pchw++ = msbf(data16(224)); *pchw++ = msbf(data16(10)); // a-grave
- *pchw++ = msbf(data16(225)); *pchw++ = msbf(data16(5)); // a-acute
- *pchw++ = msbf(data16(232)); *pchw++ = msbf(data16(11)); // e-grave
- *pchw++ = msbf(data16(233)); *pchw++ = msbf(data16(6)); // e-acute
- *pchw++ = msbf(data16(236)); *pchw++ = msbf(data16(12)); // i-grave
- *pchw++ = msbf(data16(237)); *pchw++ = msbf(data16(7)); // i-acute
- *pchw++ = msbf(data16(242)); *pchw++ = msbf(data16(13)); // o-grave
- *pchw++ = msbf(data16(243)); *pchw++ = msbf(data16(8)); // o-acute
- *pchw++ = msbf(data16(249)); *pchw++ = msbf(data16(14)); // u-grave
- *pchw++ = msbf(data16(250)); *pchw++ = msbf(data16(9)); // u-acute
-
- m_prgichwOffsets[5] = 39 + 4+(15*2); // 73
-}
-
-void GrGlyphTable::SetUpLigature2Test()
-{
- SetNumberOfGlyphs(256);
- SetNumberOfStyles(1);
-
- GrGlyphSubTable * pgstbl = new GrGlyphSubTable();
- Assert(pgstbl);
-
- pgstbl->Initialize(1, 0, 256, 10, 4);
- SetSubTable(0, pgstbl);
-
- SetNumberOfComponents(2); // comp.base, comp.i
-
- pgstbl->SetUpLigature2Test();
-}
-
-/***********************************************************************************************
- TODO: This method is BROKEN because m_prgibBIGAttrValues has been changed. It is no
- longer a data16 *. The Gloc table can contain 16-bit or 32-bit entries and must be
- accessed accordingly.
-***********************************************************************************************/
-void GrGlyphSubTable::SetUpLigature2Test()
-{
- m_nAttrIDLim = 10;
-
- m_pgatbl = new GrGlyphAttrTable();
- m_pgatbl->Initialize(0, 330);
-
- for (int i = 0; i <= 65; i++) // A
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(0));
-
- for (i = 66; i <= 69; i++) // E
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(22));
-
- for (i = 70; i <= 73; i++) // I
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(44));
-
- for (i = 74; i <= 79; i++) // O
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(66));
-
- for (i = 80; i <= 85; i++) // U
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(88));
-
- for (i = 86; i <= 192; i++) // A-grave
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(110));
-
- m_prgibBIGAttrValues[193] = (byte)msbf(data16(132)); // A-acute
-
- for (i = 194; i <= 200; i++) // E-grave
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(154));
-
- m_prgibBIGAttrValues[201] = (byte)msbf(data16(176)); // E-acute
-
- for (i = 202; i <= 204; i++) // I-grave
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(198));
-
- m_prgibBIGAttrValues[205] = (byte)msbf(data16(220)); // I-acute
-
- for (i = 206; i <= 210; i++) // O-grave
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(242));
-
- m_prgibBIGAttrValues[211] = (byte)msbf(data16(264)); // O-acute
-
- for (i = 212; i <= 217; i++) // U-grave
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(286));
-
- m_prgibBIGAttrValues[218] = (byte)msbf(data16(308)); // O-acute
-
- for (i = 219; i < 256; i++)
- m_prgibBIGAttrValues[i] = (byte)msbf(data16(330));
-
- m_pgatbl->SetUpLigature2Test();
-}
-
-void GrGlyphAttrTable::SetUpLigature2Test()
-{
- // All ligatures have the following defined:
- //
- // 0 = 2 comp.base (0,30, 100,100)
- // 1 = 6 comp.i (0,0, 100,30)
- // 2= 100 comp.base.top
- // 3= 30 bottom
- // 4= 0 left
- // 5= 100 right
- // 6 = 30 comp.i.top
- // 7 = 0 bottom
- // 8= 0 left
- // 9= 100 right
-
- byte * pbBIG = m_prgbBIGEntries;
-
- GrGlyphAttrRun gatrun;
-
- for (int i = 0; i < 15; i++)
- {
- gatrun.m_bMinAttrID = 0;
- gatrun.m_cAttrs = 10;
- gatrun.m_rgchwBIGValues[0] = msbf(data16(2));
- gatrun.m_rgchwBIGValues[1] = msbf(data16(6));
- gatrun.m_rgchwBIGValues[2] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[3] = msbf(data16(30));
- gatrun.m_rgchwBIGValues[4] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[5] = msbf(data16(100));
- gatrun.m_rgchwBIGValues[6] = msbf(data16(30));
- gatrun.m_rgchwBIGValues[7] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[8] = msbf(data16(0));
- gatrun.m_rgchwBIGValues[9] = msbf(data16(100));
- memcpy(pbBIG, &gatrun, 22); // 22 = 10*2 + 2
- pbBIG += 22;
- }
-
- Assert(pbBIG == m_prgbBIGEntries + (22 * 15));
-}
-
-void GrSubPass::SetUpLigature2Test()
-{
- if (m_ipass == 1)
- {
- m_nMaxRuleContext = m_nMaxChunk = 2;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "Ligatures2";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpLigature2Test(m_ipass);
-
- m_crul = 3;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 0;
- m_prgibConstraintStart[1] = 0;
- m_prgibConstraintStart[2] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[7 + 12 + 12];
- pb = m_prgbActionBlock;
-
- // Rule 0: gX gI > @2 @1;
-
- *pb++ = kopPutCopy; *pb++ = 1; // PutCopy 1
- *pb++ = kopNext; // Next
- *pb++ = kopPutCopy; *pb++ = -1; // PutCopy -1
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 1: clsPlainVowel gAcute > clsVowelAcute:(1 2) _;
-
- *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 3 0
- *pb++ = 3; *pb++ = 0;
- *pb++ = kopAssoc; *pb++ = 2; // Assoc 2 0 1
- *pb++ = 0; *pb++ = 1;
- *pb++ = kopNext; // Next
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- // Rule 2: clsPlainVowel gGrave > clsVowelGrave:(1 2) _;
-
- *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 3 1
- *pb++ = 3; *pb++ = 1;
- *pb++ = kopAssoc; *pb++ = 2; // Assoc 2 0 1
- *pb++ = 0; *pb++ = 1;
- *pb++ = kopNext; // Next
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- m_prgibActionStart[1] = 7;
- m_prgibActionStart[2] = 7 + 12;
- }
- else if (m_ipass == 2)
- {
- m_nMaxRuleContext = m_nMaxChunk = 2;
- m_nMaxRuleLoop = 5;
- m_staBehavior = "Ligatures2";
-
- m_pfsm = new GrFSM();
- Assert(m_pfsm);
- m_pfsm->SetUpLigature2Test(m_ipass);
-
- m_crul = 1;
-
- // Set up constraint code.
- m_prgbConstraintBlock = new byte[1];
- byte * pb = m_prgbConstraintBlock;
- *pb++ = kopRetTrue; // RetTrue
-
- m_prgibConstraintStart = new data16[m_crul];
- m_prgibConstraintStart[0] = 0;
-
- // Set up rule action code.
- m_prgbActionBlock = new byte[7 + 12 + 12];
- pb = m_prgbActionBlock;
-
- // Rule 0: clsVowel gI > clsCapVowel:(1 2) { comp {v.ref = @1; i.ref = @2}} _;
-
- *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 4 2
- *pb++ = 4; *pb++ = 2;
- *pb++ = kopAssoc; *pb++ = 2; // Assoc 2 0 1
- *pb++ = 0; *pb++ = 1;
- *pb++ = kopPushByte; *pb++ = 0; // Push 0
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot compRef v
- *pb++ = kslatCompRef; *pb++ = 0;
- *pb++ = kopPushByte; *pb++ = 1; // Push 1
- *pb++ = kopIAttrSetSlot; // IAttrSetSlot compRef i
- *pb++ = kslatCompRef; *pb++ = 1;
- *pb++ = kopNext; // Next
- *pb++ = kopDelete; // Delete
- *pb++ = kopNext; // Next
- *pb++ = kopRetZero; // RetZero
-
- m_prgibActionStart = new data16[m_crul];
- m_prgibActionStart[0] = 0;
- }
- else
- Assert(false);
-}
-
-
-void GrFSM::SetUpLigature2Test(int ipass)
-{
- if (ipass == 1)
- {
- // Create machine class ranges.
- m_cmcr = 8;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 47; // acute
- m_prgmcr[0].m_chwLast = 47;
- m_prgmcr[0].m_col = 3;
-
- m_prgmcr[1].m_chwFirst = 92; // grave
- m_prgmcr[1].m_chwLast = 92;
- m_prgmcr[1].m_col = 4;
-
- m_prgmcr[2].m_chwFirst = 97; // a
- m_prgmcr[2].m_chwLast = 97;
- m_prgmcr[2].m_col = 1;
-
- m_prgmcr[3].m_chwFirst = 101; // e
- m_prgmcr[3].m_chwLast = 101;
- m_prgmcr[3].m_col = 1;
-
- m_prgmcr[4].m_chwFirst = 105; // i
- m_prgmcr[4].m_chwLast = 105;
- m_prgmcr[4].m_col = 2;
-
- m_prgmcr[5].m_chwFirst = 111; // o
- m_prgmcr[5].m_chwLast = 111;
- m_prgmcr[5].m_col = 1;
-
- m_prgmcr[6].m_chwFirst = 117; // u
- m_prgmcr[6].m_chwLast = 117;
- m_prgmcr[6].m_col = 1;
-
- m_prgmcr[7].m_chwFirst = 120; // x
- m_prgmcr[7].m_chwLast = 120;
- m_prgmcr[7].m_col = 0;
-
- m_dimcrInit = 8; // (max power of 2 <= m_cmcr);
- m_cLoop = 3; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 6;
- m_crowNonAcpt = 3;
- m_crowFinal = 3;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 5;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 15
- short * psn = m_prgrowTransitions;
- *psn++ = 1; *psn++ = 2; *psn++ = 2; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 3; *psn++ = 0; *psn++ = 0;
- *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 4; *psn++ = 5;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[3+1]; // 3 = m_crow - m_crowNonAcpt
-
- m_prgirulnMin[0] = 0; // s3: r0
- m_prgrulnMatched[0] = 0;
-
- m_prgirulnMin[1] = 1; // s4: r1
- m_prgrulnMatched[1] = 1;
-
- m_prgirulnMin[2] = 2; // s5: r2
- m_prgrulnMatched[2] = 2;
-
- m_prgirulnMin[3] = 3;
- }
- else if (ipass == 2)
- {
- // Create machine class ranges.
- m_cmcr = 10;
- m_prgmcr = new GrFSMClassRange[m_cmcr];
- m_prgmcr[0].m_chwFirst = 97; // a
- m_prgmcr[0].m_chwLast = 97;
- m_prgmcr[0].m_col = 0;
-
- m_prgmcr[1].m_chwFirst = 101; // e
- m_prgmcr[1].m_chwLast = 101;
- m_prgmcr[1].m_col = 0;
-
- m_prgmcr[2].m_chwFirst = 105; // i
- m_prgmcr[2].m_chwLast = 105;
- m_prgmcr[2].m_col = 1;
-
- m_prgmcr[3].m_chwFirst = 111; // o
- m_prgmcr[3].m_chwLast = 111;
- m_prgmcr[3].m_col = 0;
-
- m_prgmcr[4].m_chwFirst = 117; // u
- m_prgmcr[4].m_chwLast = 117;
- m_prgmcr[4].m_col = 0;
-
- m_prgmcr[5].m_chwFirst = 224; // a-grave, a-acute
- m_prgmcr[5].m_chwLast = 225;
- m_prgmcr[5].m_col = 0;
-
- m_prgmcr[6].m_chwFirst = 232; // e-grave, e-acute
- m_prgmcr[6].m_chwLast = 233;
- m_prgmcr[6].m_col = 0;
-
- m_prgmcr[7].m_chwFirst = 236; // i-grave, i-acute
- m_prgmcr[7].m_chwLast = 237;
- m_prgmcr[7].m_col = 0;
-
- m_prgmcr[8].m_chwFirst = 242; // o-grave, o-acute
- m_prgmcr[8].m_chwLast = 243;
- m_prgmcr[8].m_col = 0;
-
- m_prgmcr[9].m_chwFirst = 249; // u-grave, u-acute
- m_prgmcr[9].m_chwLast = 250;
- m_prgmcr[9].m_col = 0;
-
-
- m_dimcrInit = 8; // (max power of 2 <= m_cmcr);
- m_cLoop = 3; // log2(max power of 2 <= m_cmcr);
- m_imcrStart = m_cmcr - m_dimcrInit;
-
-
- m_crow = 3;
- m_crowNonAcpt = 2;
- m_crowFinal = 1;
- m_rowFinalMin = m_crow - m_crowFinal;
- m_ccol = 2;
-
- // Set up transition table.
- m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 4
- short * psn = m_prgrowTransitions;
- *psn++ = 1; *psn++ = 1;
- *psn++ = 0; *psn++ = 2;
-
- // Set up matched-rules tables.
- m_prgrulnMatched = new data16[1]; // 1 = sum of rules matched for each accepting state
- m_prgirulnMin = new data16[1+1]; // 1 = m_crow - m_crowNonAcpt
-
- m_prgirulnMin[0] = 0; // s2: r0
- m_prgrulnMatched[0] = 0;
-
- m_prgirulnMin[1] = 1;
- }
-}
-
-#endif // _DEBUG
-
-} // namespace gr
-
-#endif // OLD_TEST_STUFF
-
-//:End Ignore
diff --git a/Build/source/libs/graphite-engine/src/segment/TestPasses.cpp b/Build/source/libs/graphite-engine/src/segment/TestPasses.cpp
deleted file mode 100644
index a85e6c56207..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/TestPasses.cpp
+++ /dev/null
@@ -1,1005 +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: TestPasses.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Hard-coded passes for test procedures.
--------------------------------------------------------------------------------*//*:End Ignore*/
-
-//:Ignore
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-#ifdef OLD_TEST_STUFF
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-/*----------------------------------------------------------------------------------------------
- For release version.
-----------------------------------------------------------------------------------------------*/
-#ifndef _DEBUG
-
-bool GrLineBreakPass::RunTestRules(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- return false;
-}
-
-bool GrSubPass::RunTestRules(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- return false;
-}
-
-bool GrPosPass::RunTestRules(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- return false;
-}
-
-#endif // !_DEBUG
-
-
-#ifdef _DEBUG
-
-/*----------------------------------------------------------------------------------------------
- Set up a table manager for testing.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::SetUpTest(std::wstring stuRendBehavior)
-{
- if (stuRendBehavior == L"NoRules")
- {
- m_cpass = 2;
- m_cpassLB = 0;
- m_ipassPos1 = 1;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrPosPass(1);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpTestData();
- }
- else if (stuRendBehavior == L"JustReorder" || stuRendBehavior == "RightToLeftLayout")
- {
- m_cpass = 4;
- m_cpassLB = 0;
- m_ipassPos1 = 3;
- m_fBidi = true;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrBidiPass(2);
- m_prgppass[3] = new GrPosPass(3);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpReverseNumbersTest();
- m_prgppass[2]->SetUpTestData();
- m_prgppass[3]->SetUpTestData();
-
- m_prgppass[2]->SetTopDirLevel(TopDirectionLevel());
- }
- else if (stuRendBehavior == L"CrossLineContext")
- {
- m_cpass = 4;
- m_cpassLB = 1;
- m_ipassPos1 = 3;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrLineBreakPass(1);
- m_prgppass[2] = new GrSubPass(2);
- m_prgppass[3] = new GrPosPass(3);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpCrossLineContextTest();
- m_prgppass[2]->SetUpCrossLineContextTest();
- m_prgppass[3]->SetUpTestData();
- }
- else if (stuRendBehavior == L"Reprocess")
- {
- m_cpass = 6;
- m_cpassLB = 1;
- m_ipassPos1 = 5;
- m_fBidi = true;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrLineBreakPass(1);
- m_prgppass[2] = new GrSubPass(2);
- m_prgppass[3] = new GrSubPass(3);
- m_prgppass[4] = new GrBidiPass(4);
- m_prgppass[5] = new GrPosPass(5);
-
- m_prgppass[0]->SetUpTestData(); // glyph-gen pass
- m_prgppass[1]->SetUpReprocessTest(); // line-break pass
- m_prgppass[2]->SetUpReverseNumbersTest(); // sub pass 1
- m_prgppass[3]->SetUpReprocessTest(); // sub pass 2
- m_prgppass[4]->SetUpTestData(); // bidi pass
- m_prgppass[5]->SetUpTestData(); // pos pass
-
- m_prgppass[4]->SetTopDirLevel(TopDirectionLevel());
- }
- else if (stuRendBehavior == L"LineEdgeContext")
- {
- m_cpass = 4;
- m_cpassLB = 0;
- m_ipassPos1 = 3;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrSubPass(2);
- m_prgppass[3] = new GrPosPass(3);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpLineEdgeContextTest(1);
- m_prgppass[2]->SetUpLineEdgeContextTest(2);
- m_prgppass[3]->SetUpTestData();
- }
- else if (stuRendBehavior == L"BidiAlgorithm")
- {
- m_cpass = 4;
- m_cpassLB = 0;
- m_ipassPos1 = 3;
- m_fBidi = true;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrBidiPass(2);
- m_prgppass[3] = new GrPosPass(3);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpBidiAlgorithmTest();
- m_prgppass[2]->SetUpBidiAlgorithmTest();
- m_prgppass[3]->SetUpTestData();
-
- m_prgppass[2]->SetTopDirLevel(TopDirectionLevel());
- }
- else if (stuRendBehavior == L"PseudoGlyphs")
- {
- m_cpass = 3;
- m_cpassLB = 0;
- m_ipassPos1 = 2;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrPosPass(2);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpPseudoGlyphsTest();
- m_prgppass[2]->SetUpTestData();
- }
- else if (stuRendBehavior == L"SimpleFSM")
- {
- m_cpass = 3;
- m_cpassLB = 0;
- m_ipassPos1 = 2;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrPosPass(2);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpSimpleFSMTest();
- m_prgppass[2]->SetUpTestData();
- }
- else if (stuRendBehavior == L"RuleAction")
- {
- m_cpass = 3;
- m_cpassLB = 0;
- m_ipassPos1 = 2;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrPosPass(2);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpRuleActionTest();
- m_prgppass[2]->SetUpTestData();
- }
- else if (stuRendBehavior == L"RuleAction2")
- {
- m_cpass = 6;
- m_cpassLB = 0;
- m_ipassPos1 = 5;
- m_fBidi = true;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrSubPass(2);
- m_prgppass[3] = new GrSubPass(3);
- m_prgppass[4] = new GrBidiPass(4);
- m_prgppass[5] = new GrPosPass(5);
-
- m_prgppass[0]->SetUpTestData(); // glyph-gen pass
- m_prgppass[1]->SetUpRuleAction2Test(); // sub pass 1
- m_prgppass[2]->SetUpRuleAction2Test(); // sub pass 2
- m_prgppass[3]->SetUpRuleAction2Test(); // sub pass 3
- m_prgppass[4]->SetUpTestData(); // bidi pass
- m_prgppass[5]->SetUpTestData(); // pos pass
-
- m_prgppass[4]->SetTopDirLevel(TopDirectionLevel());
- }
- else if (stuRendBehavior == L"Assoc")
- {
- m_cpass = 5;
- m_cpassLB = 1;
- m_ipassPos1 = 4;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrLineBreakPass(1);
- m_prgppass[2] = new GrSubPass(2);
- m_prgppass[3] = new GrSubPass(3);
- m_prgppass[4] = new GrPosPass(4);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpAssocTest();
- m_prgppass[2]->SetUpAssocTest();
- m_prgppass[3]->SetUpAssocTest();
- m_prgppass[4]->SetUpTestData();
- }
- else if (stuRendBehavior == L"Assoc2")
- {
- m_cpass = 3;
- m_cpassLB = 0;
- m_ipassPos1 = 2;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrPosPass(2);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpAssoc2Test();
- m_prgppass[2]->SetUpTestData();
- }
- else if (stuRendBehavior == L"DefaultAssoc")
- {
- m_cpass = 3;
- m_cpassLB = 0;
- m_ipassPos1 = 2;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrPosPass(2);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpDefaultAssocTest();
- m_prgppass[2]->SetUpTestData();
- }
- else if (stuRendBehavior == L"BidiNumbers")
- {
- m_cpass = 4;
- m_cpassLB = 0;
- m_ipassPos1 = 3;
- m_fBidi = true;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrBidiPass(2);
- m_prgppass[3] = new GrPosPass(3);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpBidiNumbersTest();
- m_prgppass[2]->SetUpBidiNumbersTest();
- m_prgppass[3]->SetUpTestData();
-
- m_prgppass[2]->SetTopDirLevel(TopDirectionLevel());
- }
- else if (stuRendBehavior == L"Feature")
- {
- m_cpass = 3;
- m_cpassLB = 0;
- m_ipassPos1 = 2;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrPosPass(2);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpFeatureTest();
- m_prgppass[2]->SetUpTestData();
- }
- else if (stuRendBehavior == L"Ligatures")
- {
- m_cpass = 4;
- m_cpassLB = 1;
- m_ipassPos1 = 3;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrLineBreakPass(1);
- m_prgppass[2] = new GrSubPass(2);
- m_prgppass[3] = new GrPosPass(3);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpLigatureTest();
- m_prgppass[2]->SetUpLigatureTest();
- m_prgppass[3]->SetUpTestData();
- }
- else if (stuRendBehavior == L"Ligatures2")
- {
- m_cpass = 4;
- m_cpassLB = 1;
- m_ipassPos1 = 3;
- m_fBidi = false;
-
- m_prgppass = new GrPass*[m_cpass];
- m_prgppass[0] = new GrGlyphGenPass(0);
- m_prgppass[1] = new GrSubPass(1);
- m_prgppass[2] = new GrSubPass(2);
- m_prgppass[3] = new GrPosPass(3);
-
- m_prgppass[0]->SetUpTestData();
- m_prgppass[1]->SetUpLigature2Test();
- m_prgppass[2]->SetUpLigature2Test();
- m_prgppass[3]->SetUpTestData();
- }
- else
- Assert(false);
-
- m_engst.m_prgpsstrm = new GrSlotStream*[m_cpass];
- for (int ipass = 0; ipass < m_cpass; ++ipass)
- m_engst.m_prgpsstrm[ipass] = new GrSlotStream(ipass);
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Set the pass variables that normally will be read from the ECF.
-----------------------------------------------------------------------------------------------*/
-
-void GrPass::SetUpTestData()
-{
- m_nMaxRuleContext = m_nMaxChunk = 2;
- m_nMaxRuleLoop = 2;
-}
-
-//void GrBidiPass::SetUpTestData()
-//{
-// m_nMaxRuleContext = m_nMaxChunk = 1;
-// m_nMaxRuleLoop = 2;
-//}
-
-/*----------------------------------------------------------------------------------------------
- Call the appropriate test function.
-----------------------------------------------------------------------------------------------*/
-
-bool GrLineBreakPass::RunTestRules(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- if (m_staBehavior == "Reprocess")
- return RunReprocessTest(ptman, psstrmInput, psstrmOutput);
- else if (m_staBehavior == "CrossLineContext")
- return RunCrossLineContextTest(ptman, psstrmInput, psstrmOutput);
- else
- return false;
-}
-
-bool GrSubPass::RunTestRules(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- if (m_staBehavior == "ReverseNumbers")
- return RunReverseNumbersTest(ptman, psstrmInput, psstrmOutput);
- else if (m_staBehavior == "CrossLineContext")
- return RunCrossLineContextTest(ptman, psstrmInput, psstrmOutput);
- else if (m_staBehavior == "Reprocess")
- return RunReprocessTest(ptman, psstrmInput, psstrmOutput);
- else if (m_staBehavior == "LineEdgeContext")
- return RunLineEdgeContextTest(ptman, psstrmInput, psstrmOutput);
- else if (m_staBehavior == "BidiAlgorithm")
- return RunBidiAlgorithmTest(ptman, psstrmInput, psstrmOutput);
- else if (m_staBehavior == "PseudoGlyphs")
- return RunPseudoGlyphsTest(ptman, psstrmInput, psstrmOutput);
- else if (m_staBehavior == "BidiNumbers")
- return RunBidiNumbersTest(ptman, psstrmInput, psstrmOutput);
- else
- return false;
-}
-
-bool GrPosPass::RunTestRules(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- A substitution pass that causes numbers to be reversed. Used by both the JustReorder test
- and the Reprocess test.
-----------------------------------------------------------------------------------------------*/
-
-void GrSubPass::SetUpReverseNumbersTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "ReverseNumbers";
-}
-
-bool GrSubPass::RunReverseNumbersTest(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- data16 chw0;
-
- // clsDigit { dir = DIR_RIGHT };
- if (psstrmInput->SlotsPending() >= 1)
- {
- bool fRtl = ptman->RightToLeft();
- chw0 = psstrmInput->Peek(0)->GlyphID();
- if ((chw0 >= '0') && (chw0 <= '9'))
- {
- GrSlotState * pslot0 = psstrmInput->NextGet();
-// GrFeatureValues fval0;
-// pslot0->GetFeatureValues(&fval0);
-
- GrSlotState * pslotNew;
- ptman->NewSlotCopy(pslot0, m_ipass, &pslotNew);
- pslotNew->SetDirectionality(fRtl ? kdircArabNum : kdircR);
- pslotNew->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew);
-
- return true;
- }
- else
- {
- GrSlotState * pslot0 = psstrmInput->NextGet();
-// GrFeatureValues fval0;
-// pslot0->GetFeatureValues(&fval0);
-
- GrSlotState * pslotNew;
- ptman->NewSlotCopy(pslot0, m_ipass, &pslotNew);
- if (chw0 == 32)
- pslotNew->SetDirectionality(kdircWhiteSpace);
- else if (chw0 == '.')
- pslotNew->SetDirectionality(kdircComSep);
- else
- pslotNew->SetDirectionality(fRtl ? kdircR : kdircL);
- pslotNew->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew);
-
- return true;
- }
- }
- else
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- A substitution pass that will do some hard-coded actions resulting in cross-line-boundary
- contextuals.
-----------------------------------------------------------------------------------------------*/
-void GrEngine::SetUpCrossLineContextTest()
-{
- m_fLineBreak = true;
- m_cchwPreXlbContext = 2;
- m_cchwPostXlbContext = 0;
-}
-
-void GrLineBreakPass::SetUpCrossLineContextTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "CrossLineContext";
-}
-
-void GrSubPass::SetUpCrossLineContextTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 3;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "CrossLineContext";
-}
-
-bool GrLineBreakPass::RunCrossLineContextTest(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- // '=' { break = intra };
- if ((psstrmInput->SlotsPending() >= 1) &&
- (psstrmInput->Peek(0)->GlyphID() == 61))
- {
- GrSlotState * pslotNew0;
- ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew0);
- pslotNew0->SetBreakWeight(int(klbHyphenBreak));
- psstrmOutput->NextPut(pslotNew0);
-
- psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
-
- return true;
- }
- else
- return false;
-}
-
-bool GrSubPass::RunCrossLineContextTest(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- // any '=' _ _ > any '=' '=':2 any:1 / _ _ # _ _
- if ((psstrmInput->SlotsPending() >= 3) &&
- (psstrmInput->Peek(1)->GlyphID() == 61) &&
- (psstrmInput->Peek(2)->GlyphID() == ptman->LBGlyphID()))
- {
- GrSlotState * pslot0 = psstrmInput->Peek(0);
- GrSlotState * pslot1 = psstrmInput->Peek(1);
- gid16 chw0 = pslot0->GlyphID();
-// GrFeatureValues fval0;
-// pslot0->GetFeatureValues(&fval0);
-// GrFeatureValues fval1;
-// pslot1->GetFeatureValues(&fval1);
-
- // copy the first 3 slots
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
-
- // insert 2 more
- GrSlotState * pslot3;
- ptman->NewSlot(61, pslot1, NULL, m_ipass, &pslot3);
- pslot3->Associate(pslot1);
- psstrmOutput->NextPut(pslot3);
-
- GrSlotState * pslot4;
- ptman->NewSlot(chw0, pslot0, NULL, m_ipass, &pslot4);
- pslot4->Associate(pslot0);
- psstrmOutput->NextPut(pslot4);
-
- return true;
- }
- else
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- Line break and substitution passes that cause intra-pass reprocessing (ie, the ^ mechanism).
-----------------------------------------------------------------------------------------------*/
-
-void GrLineBreakPass::SetUpReprocessTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 2;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "Reprocess";
-}
-
-bool GrLineBreakPass::RunReprocessTest(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- gid16 chw;
-
- // '^' {lb=2} / _ lc
- if ((psstrmInput->SlotsPending() >=2) &&
- (psstrmInput->Peek(0)->GlyphID() == '^') &&
- (((chw = psstrmInput->Peek(1)->GlyphID()) >= 'a') &&
- (chw <= 'z')))
- {
- GrSlotState * pslotNew0;
- ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew0);
- pslotNew0->SetBreakWeight(int(klbHyphenBreak));
- psstrmOutput->NextPut(pslotNew0);
-
- psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
-
- return true;
- }
- else
- return false;
-}
-
-
-void GrSubPass::SetUpReprocessTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 3;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "Reprocess";
-}
-
-bool GrSubPass::RunReprocessTest(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- gid16 chw;
- gid16 chwLB = ptman->LBGlyphID();
-
- // symbol > @2 {dir = DIR_ARABNUMBER} / any {dir != DIR_LEFT} ^ _
- if ((psstrmInput->SlotsPending() >= 2) &&
- (psstrmInput->Peek(0)->Directionality() != kdircL) &&
- (((chw = psstrmInput->Peek(1)->GlyphID()) == '@') ||
- (chw == '@') || (chw == '$') || (chw == '%') ||
- (chw == '^') || (chw == '&') || (chw == '*')))
- {
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
- GrSlotState * pslotNew1;
- ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew1);
- pslotNew1->SetDirectionality(kdircArabNum);
- psstrmOutput->NextPut(pslotNew1);
-
- psstrmOutput->SetPosForNextRule(-1, psstrmInput, false);
-
- return true;
- }
-
- // '^' lc > @1 uc
- else if ((psstrmInput->SlotsPending() >= 2) &&
- (psstrmInput->Peek(0)->GlyphID() == '^') &&
- (((chw = psstrmInput->Peek(1)->GlyphID()) >= 'a') &&
- (chw <= 'z')))
- {
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
-
- gid16 chwNew = chw - 'a' + 'A';
- GrSlotState * pslotNew1;
- ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew1);
- pslotNew1->SetGlyphID(chwNew);
- psstrmOutput->NextPut(pslotNew1);
-
- psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
-
- return true;
- }
-
- // '^' lc > @1 uc / _ # _
- else if ((psstrmInput->SlotsPending() >= 3) &&
- (psstrmInput->Peek(0)->GlyphID() == '^') &&
- (psstrmInput->Peek(1)->IsLineBreak(chwLB)) &&
- (((chw = psstrmInput->Peek(2)->GlyphID()) >= 'a') &&
- (chw <= 'z')))
- {
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
-
- gid16 chwNew = chw - 'a' + 'A';
- GrSlotState * pslotNew1;
- ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew1);
- pslotNew1->SetGlyphID(chwNew);
- psstrmOutput->NextPut(pslotNew1);
-
- psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
-
- return true;
- }
-
- else
- return false;
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Substitution passes that create contextual forms at the line breaks; also a cross-line-
- boundary contextual.
-----------------------------------------------------------------------------------------------*/
-
-void GrSubPass::SetUpLineEdgeContextTest(int ipass)
-{
- m_nMaxRuleContext = (ipass == 2)? 5: 2;
- m_nMaxChunk = m_nMaxRuleContext;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "LineEdgeContext";
-}
-
-bool GrSubPass::RunLineEdgeContextTest(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- gid16 chwLB = ptman->LBGlyphID();
-
- // any _ _ > @1 '-' '-' / _ _ _ #
- if ((m_ipass == 1) &&
- (psstrmInput->SlotsPending() >= 2) &&
- (psstrmInput->Peek(1)->IsLineBreak(chwLB)))
- {
- GrSlotState * pslot0 = psstrmInput->Peek(0);
-// GrFeatureValues fval;
-// pslot0->GetFeatureValues(&fval);
-
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
-
- GrSlotState * pslotNew1;
- ptman->NewSlot('-', pslot0, NULL, m_ipass, &pslotNew1);
- pslotNew1->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew1);
-
- GrSlotState * pslotNew2;
- ptman->NewSlot('-', pslot0, NULL, m_ipass, &pslotNew2);
- pslotNew2->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew2);
-
- return true;
- }
-
- // _ _ any > '+' '+' @4 / # _ _ _
- else if ((m_ipass == 1) &&
- (psstrmInput->SlotsPending() >= 2) &&
- (psstrmInput->Peek(0)->IsLineBreak(chwLB)))
- {
- GrSlotState * pslot2 = psstrmInput->Peek(1);
-// GrFeatureValues fval;
-// pslot2->GetFeatureValues(&fval);
-
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
-
- GrSlotState * pslotNew0;
- ptman->NewSlot('+', pslot2, NULL, m_ipass, &pslotNew0);
- pslotNew0->Associate(pslot2);
- psstrmOutput->NextPut(pslotNew0);
-
- GrSlotState * pslotNew1;
- ptman->NewSlot('+', pslot2, NULL, m_ipass, &pslotNew1);
- pslotNew1->Associate(pslot2);
- psstrmOutput->NextPut(pslotNew1);
-
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
-
- return true;
- }
-
- // '-' '-' '+' '+' > @1 _ _ @4 / _ _ # _ _
- else if ((m_ipass == 2) &&
- (psstrmInput->SlotsPending() >= 5) &&
- (psstrmInput->Peek(0)->GlyphID() == '-') &&
- (psstrmInput->Peek(1)->GlyphID() == '-') &&
- (psstrmInput->Peek(2)->IsLineBreak(chwLB)) &&
- (psstrmInput->Peek(3)->GlyphID() == '+') &&
- (psstrmInput->Peek(4)->GlyphID() == '+'))
- {
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
- psstrmInput->Skip(1);
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
- psstrmInput->Skip(1);
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
-
- return true;
- }
-
- else
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- Substitution passes that do something special with pseudo glyphs.
-----------------------------------------------------------------------------------------------*/
-
-void GrSubPass::SetUpPseudoGlyphsTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 3;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "PseudoGlyphs";
-}
-
-bool GrSubPass::RunPseudoGlyphsTest(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- gid16 chwLB = ptman->LBGlyphID();
-
- // pseudo > uppercase / _ ' '
- if ((psstrmInput->SlotsPending() >= 2) &&
- (psstrmInput->Peek(0)->GlyphID() > 1000) && // pseudo
- (psstrmInput->Peek(1)->GlyphID() == 32))
- {
- GrSlotState * pslot0 = psstrmInput->NextGet();
-// GrFeatureValues fval;
-// pslot0->GetFeatureValues(&fval);
-
- GrSlotState * pslotNew;
- ptman->NewSlotCopy(pslot0, m_ipass, &pslotNew);
- pslotNew->SetGlyphID(pslot0->GlyphID() - 1000);
- pslotNew->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew);
-
- psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
-
- return true;
- }
-
- // pseudo > uppercase / _ |
- // pseudo > uppercase / _ #
- else if ((psstrmInput->SlotsPending() <= 2) &&
- (psstrmInput->Peek(0)->GlyphID() > 1000) && // pseudo
- (psstrmInput->SlotsPending() < 2 || psstrmInput->Peek(1)->GlyphID() == 35))
- {
- GrSlotState * pslot0 = psstrmInput->NextGet();
-// GrFeatureValues fval;
-// pslot0->GetFeatureValues(&fval);
-
- GrSlotState * pslotNew;
- ptman->NewSlotCopy(pslot0, m_ipass, &pslotNew);
- pslotNew->SetGlyphID(pslot0->GlyphID() - 1000);
- pslotNew->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew);
-
- psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
-
- return true;
- }
-
- // pseudo any _ > lowercase:1 @2 @1 / _ _ ^ _;
- else if ((psstrmInput->SlotsPending() >= 3) &&
- (psstrmInput->Peek(0)->GlyphID() > 1000)) // pseudo
- {
- GrSlotState * pslot0 = psstrmInput->NextGet();
-// GrFeatureValues fval;
-// pslot0->GetFeatureValues(&fval);
-
- GrSlotState * pslotNew0;
- ptman->NewSlot(pslot0->GlyphID()-1000-65+97, pslot0, NULL, m_ipass, &pslotNew0);
- pslotNew0->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew0);
-
- psstrmOutput->CopyOneSlotFrom(psstrmInput);
-
- GrSlotState * pslotNew2;
- ptman->NewSlot(pslot0->GlyphID(), pslot0, NULL, m_ipass, &pslotNew2);
- pslotNew2->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew2);
-
- psstrmOutput->SetPosForNextRule(-1, psstrmInput, false);
-
- return true;
- }
- else
- return false;
-}
-
-/*----------------------------------------------------------------------------------------------
- Substitution pass that tests reversing numbers.
-----------------------------------------------------------------------------------------------*/
-void GrSubPass::SetUpBidiNumbersTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "BidiNumbers";
-}
-
-bool GrSubPass::RunBidiNumbersTest(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- gid16 chw0;
-
- // clsDigit > clsDigit { dir = DIR_ARABNUMBER };
- if ((psstrmInput->SlotsPending() >= 1) &&
- (((chw0 = psstrmInput->Peek(0)->GlyphID()) >= '0' && chw0 <= '9') ||
- (chw0 >= 'A' && chw0 <= 'Z') || (chw0 >= 'a' && chw0 <= 'z')))
- {
- GrSlotState * pslot0 = psstrmInput->NextGet();
-// GrFeatureValues fval0;
-// pslot0->GetFeatureValues(&fval0);
-
- GrSlotState * pslotNew;
- ptman->NewSlot(chw0, pslot0, NULL, m_ipass, &pslotNew);
- if (chw0 >= '0' && chw0 <= '9')
- pslotNew->SetDirectionality(kdircArabNum);
- else // a-z and A-Z
- pslotNew->SetDirectionality(kdircR);
- pslotNew->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew);
-
- return true;
- }
- else
- return false;
-}
-
-void GrBidiPass::SetUpBidiNumbersTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 2;
- m_nTopDirection = 1;
-}
-
-/*----------------------------------------------------------------------------------------------
- Substitution pass that tests the bidi algorithm thoroughly.
-----------------------------------------------------------------------------------------------*/
-void GrSubPass::SetUpBidiAlgorithmTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 2;
- m_staBehavior = "BidiAlgorithm";
-}
-
-bool GrSubPass::RunBidiAlgorithmTest(GrTableManager * ptman,
- GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
-{
- gid16 chw0;
-
- if (psstrmInput->SlotsPending() >= 1)
- {
- chw0 = psstrmInput->Peek(0)->GlyphID();
-
- DirCode dircNew;
-
- if (chw0 >= '0' && chw0 <= '9')
- dircNew = kdircEuroNum;
- else if (chw0 >= 'a' && chw0 <= 'z')
- dircNew = kdircL;
- else if (chw0 >= 'A' && chw0 <= 'M')
- dircNew = kdircR;
- else if (chw0 >= 'N' && chw0 <= 'T')
- dircNew = kdircRArab;
- else if (chw0 >= 'U' && chw0 <= 'Z')
- dircNew = kdircArabNum;
- else if (chw0 == '$' || chw0 == '%')
- dircNew = kdircEuroTerm;
- else if (chw0 == '.' || chw0 == '*' || chw0 == '+')
- dircNew = kdircEuroSep;
- else if (chw0 == '@')
- dircNew = kdircComSep;
- else if (chw0 == '_' || chw0 == '=')
- dircNew = kdircNeutral;
- else if (chw0 == ':')
- dircNew = kdircNSM;
- else
- return false;
-
- GrSlotState * pslot0 = psstrmInput->NextGet();
-// GrFeatureValues fval0;
-// pslot0->GetFeatureValues(&fval0);
-
- GrSlotState * pslotNew;
- ptman->NewSlot(chw0, pslot0, NULL, m_ipass, &pslotNew);
- pslotNew->SetDirectionality(dircNew);
- pslotNew->Associate(pslot0);
- psstrmOutput->NextPut(pslotNew);
-
- return true;
- }
- else
- return false;
-}
-
-void GrBidiPass::SetUpBidiAlgorithmTest()
-{
- m_nMaxRuleContext = m_nMaxChunk = 1;
- m_nMaxRuleLoop = 2;
- m_nTopDirection = 0;
-}
-
-
-#endif // _DEBUG
-
-} // namespace gr
-
-#endif // OLD_TEST_STUFF
-
-//:End Ignore
diff --git a/Build/source/libs/graphite-engine/src/segment/TransductionLog.cpp b/Build/source/libs/graphite-engine/src/segment/TransductionLog.cpp
deleted file mode 100644
index 73273ae3feb..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/TransductionLog.cpp
+++ /dev/null
@@ -1,2091 +0,0 @@
-/*--------------------------------------------------------------------*//*:Ignore this sentence.
-Copyright (C) 2000 - 2008 SIL International. All rights reserved.
-
-Distributable under the terms of either the Common Public License or the
-GNU Lesser General Public License, as specified in the LICENSING.txt file.
-
-File: TransductionLog.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Contains the functions for writing a log of the transduction process.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-
-#include <math.h>
-
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-#define SP_PER_SLOT 7
-#define LEADING_SP 15
-#define MAX_SLOTS 128
-
-/*----------------------------------------------------------------------------------------------
- Output a file showing a log of the transduction process and the resulting segment.
-----------------------------------------------------------------------------------------------*/
-//bool GrTableManager::WriteTransductionLog(GrCharStream * pchstrm, Segment * psegRet,
-// int cbPrevSegDat, byte * pbPrevSegDat, byte * pbNextSegDat, int * pcbNextSegDat)
-//{
-//#ifdef TRACING
-// std::string staFile;
-// if (!LogFileName(staFile))
-// return false;
-//
-// std::ofstream strmOut;
-// if (cbPrevSegDat > 0)
-// strmOut.open(staFile.c_str(), std::ios::app); // append
-// else
-// strmOut.open(staFile.c_str());
-// if (strmOut.fail())
-// return false;
-//
-// WriteXductnLog(strmOut, pchstrm, psegRet, cbPrevSegDat, pbPrevSegDat);
-//
-// strmOut.close();
-// return true;
-//#else
-// return false;
-//#endif // TRACING
-//}
-
-bool GrTableManager::WriteTransductionLog(std::ostream * pstrmLog,
- GrCharStream * pchstrm, Segment * psegRet, int cbPrevSegDat, byte * pbPrevSegDat)
-{
-#ifdef TRACING
- if (!pstrmLog)
- return false;
- std::ostream & strmOut = *pstrmLog;
- WriteXductnLog(strmOut, pchstrm, psegRet, cbPrevSegDat, pbPrevSegDat);
- return true;
-#else
- return false;
-#endif // TRACING
-}
-
-/*----------------------------------------------------------------------------------------------
- Append to the file, showing the surface/underlying mappings. This must be done after
- figuring out all the associations.
-
- Also write the final glyph positions, since they are now determined.
-----------------------------------------------------------------------------------------------*/
-//bool GrTableManager::WriteAssociationLog(GrCharStream * pchstrm, Segment * psegRet)
-//{
-//#ifdef TRACING
-// std::string staFile;
-// if (!LogFileName(staFile))
-// return false;
-//
-// std::ofstream strmOut;
-// strmOut.open(staFile.c_str(), std::ios::app); // append
-// if (strmOut.fail())
-// return false;
-//
-// LogFinalPositions(strmOut);
-//
-// strmOut << "\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n";
-//
-// psegRet->LogUnderlyingToSurface(this, strmOut, pchstrm);
-// psegRet->LogSurfaceToUnderlying(this, strmOut);
-//
-// strmOut << "\n\n=======================================================================\n\n";
-//
-// strmOut.close();
-// return true;
-//#else
-// return false;
-//#endif // TRACING
-//}
-
-
-bool GrTableManager::WriteAssociationLog(std::ostream * pstrmLog,
- GrCharStream * pchstrm, Segment * psegRet)
-{
-#ifdef TRACING
- if (!pstrmLog)
- return false;
-
- std::ostream & strmOut = *pstrmLog;
-
- psegRet->LogUnderlyingToSurface(this, strmOut, pchstrm);
- psegRet->LogSurfaceToUnderlying(this, strmOut);
-
- strmOut << "\n\n=======================================================================\n\n";
-
- return true;
-#else
- return false;
-#endif // TRACING
-}
-
-#ifdef TRACING
-
-/*----------------------------------------------------------------------------------------------
- Generate the name of the file where the log will be written. It goes in the directory
- defined by either the TEMP or TMP environment variable.
-
- TODO: remove
-----------------------------------------------------------------------------------------------*/
-//bool GrTableManager::LogFileName(std::string & staFile)
-//{
-// char * pchTmpEnv = getenv("TEMP");
-// if (pchTmpEnv == 0)
-// pchTmpEnv = getenv("TMP");
-// if (pchTmpEnv == 0)
-// return false;
-//
-// staFile.assign(pchTmpEnv);
-// if (staFile[staFile.size() - 1] != '\\')
-// staFile.append("\\");
-// staFile.append("gr_xductn.log");
-//
-// return true;
-//}
-
-/*----------------------------------------------------------------------------------------------
- Output a file showing a log of the transduction process and the resulting segment.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::WriteXductnLog(std::ostream & strmOut,
- GrCharStream * pchstrm, Segment * psegRet,
- int cbPrevSegDat, byte * pbPrevSegDat)
-{
- if (cbPrevSegDat == 0)
- LogUnderlying(strmOut, pchstrm, 0);
- else
- {
- Assert(*(pbPrevSegDat + 4) == 0); // skip offset for first pass
- LogUnderlying(strmOut, pchstrm, *(pbPrevSegDat + 3));
- }
-
- LogPass1Input(strmOut);
-
- for (int ipass = 1; ipass < m_cpass; ipass++)
- {
- if (cbPrevSegDat == 0)
- LogPassOutput(strmOut, ipass, 0);
- else
- LogPassOutput(strmOut, ipass, *(pbPrevSegDat + 4 + ipass));
- }
-
- LogFinalPositions(strmOut);
-
- strmOut << "\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n";
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out a log of the underlying input.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogUnderlying(std::ostream & strmOut, GrCharStream * pchstrm,
- int cchwBackup)
-{
- strmOut << "UNDERLYING INPUT\n\n";
-
- int rgnChars[MAX_SLOTS];
- bool rgfNewRun[MAX_SLOTS];
- std::fill_n(rgfNewRun, MAX_SLOTS, false);
- GrFeatureValues rgfval[MAX_SLOTS];
- int cchwMaxRawChars;
-
- int cnUtf32 = pchstrm->GetLogData(this, rgnChars, rgfNewRun, rgfval,
- cchwBackup, &cchwMaxRawChars);
- cnUtf32 = min(cnUtf32, MAX_SLOTS);
-
- int ichw;
-
- // For UTF-8 and surrogate representation:
- utf16 rgchwChars2[MAX_SLOTS];
- utf16 rgchwChars3[MAX_SLOTS];
- utf16 rgchwChars4[MAX_SLOTS];
- utf16 rgchwChars5[MAX_SLOTS];
- utf16 rgchwChars6[MAX_SLOTS];
- int rgcchwRaw[MAX_SLOTS];
-
- if (cchwMaxRawChars > 1)
- {
- cchwMaxRawChars = min(cchwMaxRawChars, 6); // max of 6 raw (UTF-8 or UTF-16) chars per slot
- pchstrm->GetLogDataRaw(this, cnUtf32, cchwBackup, cchwMaxRawChars,
- rgnChars, rgchwChars2, rgchwChars3, rgchwChars4, rgchwChars5, rgchwChars6,
- rgcchwRaw);
- }
- else
- {
- for (ichw = 0; ichw < cnUtf32; ichw++)
- {
- rgcchwRaw[ichw] = 1;
- rgchwChars2[ichw] = 0;
- rgchwChars3[ichw] = 0;
- rgchwChars4[ichw] = 0;
- rgchwChars5[ichw] = 0;
- rgchwChars6[ichw] = 0;
- }
- }
-
- LogUnderlyingHeader(strmOut, pchstrm->Min(), (pchstrm->Min() + cnUtf32 - cchwBackup),
- cchwBackup, rgcchwRaw);
-
- // Text
- strmOut << "Text: "; // 15 spaces
- for (ichw = 0; ichw < cnUtf32; ichw++)
- {
- if (rgnChars[ichw] < 0x0100 && rgchwChars2[ichw] == 0) // ANSI
- strmOut << (char)rgnChars[ichw] << " "; // 6 spaces
- else if (rgnChars[ichw] == knLRM)
- strmOut << "<LRM> ";
- else if (rgnChars[ichw] == knRLM)
- strmOut << "<RLM> ";
- else if (rgnChars[ichw] == knLRO)
- strmOut << "<LRO> ";
- else if (rgnChars[ichw] == knRLO)
- strmOut << "<RLO> ";
- else if (rgnChars[ichw] == knLRE)
- strmOut << "<LRE> ";
- else if (rgnChars[ichw] == knRLE)
- strmOut << "<RLE> ";
- else if (rgnChars[ichw] == knPDF)
- strmOut << "<PDF> ";
- else
- strmOut << " ";
- }
- strmOut << "\n";
-
- // Unicode
- strmOut << "Unicode: ";
- for (ichw = 0; ichw < cnUtf32; ichw++)
- LogHexInTable(strmOut, utf16(rgnChars[ichw]));
- strmOut << "\n";
- for (int icchRaw = 2; icchRaw <= cchwMaxRawChars; icchRaw++)
- {
- strmOut << " ";
- for (ichw = 0; ichw < cnUtf32; ichw++)
- {
- utf16 chw;
- switch (icchRaw)
- {
- case 2: chw = rgchwChars2[ichw]; break;
- case 3: chw = rgchwChars3[ichw]; break;
- case 4: chw = rgchwChars4[ichw]; break;
- case 5: chw = rgchwChars5[ichw]; break;
- case 6: chw = rgchwChars6[ichw]; break;
- default: chw = 0;
- }
- if (chw == 0)
- strmOut << " ";
- else
- LogHexInTable(strmOut, chw);
- }
- strmOut << "\n";
- }
-
- // Runs
- strmOut << "Runs: ";
- int crun = 0;
- for (ichw = 0; ichw < cnUtf32; ichw++)
- {
- if (rgfNewRun[ichw])
- {
- crun++;
- strmOut << "|" << crun << ((crun < 10) ? " " : " ");
- }
- else
- strmOut << " ";
- }
- strmOut << "\n";
-
- // Features
- strmOut << "Features and character properties:\n";
- crun = 0;
- for (ichw = 0; ichw < cnUtf32; ichw++)
- {
- if (rgfNewRun[ichw])
- {
- crun++;
- strmOut << " Run " << crun << ": ";
- rgfval[ichw].WriteXductnLog(this, strmOut);
-
- }
- }
-}
-
-
-void GrFeatureValues::WriteXductnLog(GrTableManager * ptman, std::ostream & strmOut)
-{
- bool fFirst = true;
- for (int i = 0; i < kMaxFeatures; i++)
- {
- if (m_rgnFValues[i] != 0)
- {
- GrFeature * pfeat = ptman->Feature(i);
- if (!fFirst)
- strmOut << ",";
- strmOut << pfeat->ID() << "=" << m_rgnFValues[i];
- fFirst = false;
- }
- }
- if (fFirst)
- strmOut << "all features=0";
-
- strmOut << "\n\n";
-}
-
-/*----------------------------------------------------------------------------------------------
- Loop through the input stream of underlying characters, storing information in the
- arrays for the log.
- ENHANCE SharonC: do we need to show the underline properties?
-----------------------------------------------------------------------------------------------*/
-int GrCharStream::GetLogData(GrTableManager * ptman, int * rgchl, bool * rgfNewRun,
- GrFeatureValues * rgfval, int cchrBackup, int * pcchrMax)
-{
- Assert(cchrBackup <= m_cchrBackedUp);
-
- int ichrPosToStop = m_ichrPos;
- int ichrStart = m_ichrMin - max(cchrBackup, m_cchrBackedUp);
-
- *pcchrMax = 0;
-
- // Restart the stream.
- m_ichrPos = ichrStart;
- m_ichrRunMin = 0;
- m_ichrRunLim = 0;
- m_ichrRunOffset = kPosInfinity;
- m_vislotNextChunkMap.clear();
-
- int cchrSkipBackup = m_cchrBackedUp - cchrBackup;
-
- int c = 0;
- int cchr = 0;
-
- while (m_ichrPos < ichrPosToStop)
- {
- if ((c < MAX_SLOTS) && (m_ichrPos >= m_ichrRunLim))
- {
- rgfNewRun[c] = true;
- }
-
- GrFeatureValues fval;
- int ichrOffset, cchrThis;
- int chl = NextGet(ptman, &fval, &ichrOffset, &cchrThis);
- cchr += cchrThis;
- if (cchr <= cchrSkipBackup)
- {} // ignore - this is before the pre-segment stuff that we want to skip
- else if (c < MAX_SLOTS)
- {
- rgchl[c] = chl;
- *pcchrMax = max(*pcchrMax, cchrThis);
- if (rgfNewRun[c])
- {
- rgfval[c] = fval;
- }
- c++;
- }
- }
-
- ////return (m_ichwPos - (m_ichwMin - cchwBackup));
- return c;
-}
-
-/*----------------------------------------------------------------------------------------------
- If any of the characters are comprised of surrogates or UTF-8, fill in the arrays with
- the raw (UTF-16 or UTF-8) chars for display. To do this we get the raw characters
- directly from the text source.
-----------------------------------------------------------------------------------------------*/
-void GrCharStream::GetLogDataRaw(GrTableManager * ptman, int cchl, int cchrBackup,
- int cchrMaxRaw, int * prgchl,
- utf16 * prgchw2, utf16 * prgchw3, utf16 * prgchw4, utf16 * prgchw5, utf16 * prgchw6,
- int * prgcchr)
-{
- for (int i = 0; i < cchl; i++)
- {
- prgchw2[i] = 0;
- }
-
- int ichrLim = m_ichrPos;
- int ichrMin = m_ichrMin - cchrBackup;
-
- int cchrRange = ichrLim - ichrMin;
- int ichr;
- utf16 * prgchwRunText = new utf16[cchrRange];
- utf8 * prgchsRunText8 = NULL;
-
- UtfType utf = m_pgts->utfEncodingForm();
-
- switch (utf)
- {
- case kutf8:
- prgchsRunText8 = new utf8[cchrRange];
- m_pgts->fetch(ichrMin, cchrRange, prgchsRunText8);
- for (int ichr = 0; ichr < cchrRange; ichr++)
- prgchwRunText[ichr] = (utf16)prgchsRunText8[ichr]; // zero-extend into UTF-16 buffer
- break;
- case kutf16:
- m_pgts->fetch(ichrMin, cchrRange, prgchwRunText);
- break;
- default:
- case kutf32: // this method should never have been called
- Assert(false);
- for (int ichrLp = 0; ichrLp < cchrRange; ichrLp++)
- {
- prgcchr[ichrLp] = 1;
- prgchw2[ichrLp] = 0;
- prgchw3[ichrLp] = 0;
- prgchw4[ichrLp] = 0;
- prgchw5[ichrLp] = 0;
- prgchw6[ichrLp] = 0;
- }
- return;
- }
-
- ichr = ichrMin;
- int ichl = 0;
- while (ichr < ichrLim)
- {
- int cchrThis = 1;
- // Replace 32-bit char with (first) 16-bit or 8-bit char.
- prgchl[ichl] = (int)prgchwRunText[ichr - ichrMin];
- prgcchr[ichr] = cchrThis;
- ichr++;
-
- while (!AtUnicodeCharBoundary(prgchwRunText, cchrRange, ichr - ichrMin, utf))
- {
- cchrThis++;
- switch (cchrThis)
- {
- case 2: prgchw2[ichl] = prgchwRunText[ichr - ichrMin]; break;
- case 3: prgchw3[ichl] = prgchwRunText[ichr - ichrMin]; break;
- case 4: prgchw4[ichl] = prgchwRunText[ichr - ichrMin]; break;
- case 5: prgchw5[ichl] = prgchwRunText[ichr - ichrMin]; break;
- case 6: prgchw6[ichl] = prgchwRunText[ichr - ichrMin]; break;
- default:
- break;
- }
- prgcchr[ichr] = cchrThis;
- ichr++;
- }
- switch (cchrThis)
- {
- case 1:
- prgchw2[ichl] = 0;
- // fall through
- case 2:
- prgchw3[ichl] = 0;
- // fall through
- case 3:
- prgchw4[ichl] = 0;
- // fall through
- case 4:
- prgchw5[ichl] = 0;
- // fall through
- case 5:
- prgchw6[ichl] = 0;
- }
- ichl++;
- }
-
- delete[] prgchwRunText;
- delete[] prgchsRunText8;
-}
-
-/*----------------------------------------------------------------------------------------------
- Output the glyph IDs generated by the glyph generation pass (pass 0).
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogPass1Input(std::ostream & strmOut)
-{
- strmOut << "INPUT TO PASS 1\n\n";
-
- GrSlotStream * psstrm = OutputStream(0);
-
- LogSlotHeader(strmOut, psstrm->WritePos(), SP_PER_SLOT, LEADING_SP);
-
- LogSlotGlyphs(strmOut, psstrm);
-
- strmOut << "\n";
-}
-
-/*----------------------------------------------------------------------------------------------
- Output the the results of pass.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogPassOutput(std::ostream & strmOut, int ipass, int cslotSkipped)
-{
- strmOut << "\n";
-
- GrPass * ppass = Pass(ipass);
- GrSlotStream * psstrmIn = InputStream(ipass);
- GrSlotStream * psstrmOut = OutputStream(ipass);
-
- int islot;
- // Mark each slot with its index in the input and output streams.
- for (islot = 0; islot < psstrmIn->ReadPos(); islot++)
- psstrmIn->SlotAt(islot)->m_islotTmpIn = islot;
-
- for (islot = 0; islot < psstrmOut->WritePos(); islot++)
- psstrmOut->SlotAt(islot)->m_islotTmpOut = islot;
-
- if (!dynamic_cast<GrBidiPass *>(ppass))
- ppass->LogRulesFiredAndFailed(strmOut, psstrmIn);
-
- strmOut << "\nOUTPUT OF PASS " << ipass;
- if (dynamic_cast<GrBidiPass *>(ppass))
- strmOut << " (bidi)";
- else if (dynamic_cast<GrSubPass *>(ppass))
- {
- if (ipass >= m_ipassJust1)
- strmOut << " (justification)";
- else
- strmOut << " (substitution)";
- }
- else if (dynamic_cast<GrPosPass *>(ppass))
- strmOut << " (positioning)";
- else if (dynamic_cast<GrLineBreakPass *>(ppass))
- strmOut << " (linebreak)";
- strmOut << "\n";
-
- ppass->LogInsertionsAndDeletions(strmOut, psstrmOut);
-
- LogSlotHeader(strmOut, psstrmOut->WritePos(), SP_PER_SLOT, LEADING_SP);
-
- LogSlotGlyphs(strmOut, psstrmOut);
-
- bool fAnyPseudos = false;
- if (dynamic_cast<GrPosPass *>(ppass))
- {
- for (islot = 0; islot < psstrmOut->WritePos(); islot++)
- {
- GrSlotState * pslotTmp = psstrmOut->SlotAt(islot);
- if (pslotTmp->GlyphID() != pslotTmp->ActualGlyphForOutput(this))
- {
- fAnyPseudos = true;
- break;
- }
- }
- }
- if (fAnyPseudos)
- {
- strmOut << "Actual glyphs: ";
- for (islot = 0; islot < psstrmOut->WritePos(); islot++)
- {
- GrSlotState * pslotTmp = psstrmOut->SlotAt(islot);
- if (pslotTmp->GlyphID() != pslotTmp->ActualGlyphForOutput(this))
- LogHexInTable(strmOut, pslotTmp->ActualGlyphForOutput(this));
- else
- strmOut << " ";
- }
- strmOut << "\n";
- }
-
- LogAttributes(strmOut, ipass);
-
- // Do this later, after we're sure the positions have been set:
- //if (ipass == m_cpass - 1)
- // LogFinalPositions(strmOut);
-
- if (cslotSkipped > 0)
- {
- strmOut << "\n ";
- for (islot = 0; islot < cslotSkipped; islot++)
- strmOut << "SKIP ";
- strmOut << "\n";
- }
-
- // If this was the pass just before the justification routines get run, output a
- // special line that just shows the results, ie, the values of justify.width.
- // TODO: adjust this when measure mode get functioning.
- if (ipass == m_ipassJust1 - 1 && ShouldLogJustification()
- && m_engst.m_jmodi == kjmodiJustify)
- {
- strmOut << "\nJUSTIFICATION\n\n";
- LogSlotHeader(strmOut, psstrmOut->WritePos(), SP_PER_SLOT, LEADING_SP);
- LogSlotGlyphs(strmOut, psstrmOut);
- LogAttributes(strmOut, ipass, true);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Write the list of rules fired and failed for a given pass.
-----------------------------------------------------------------------------------------------*/
-void GrPass::LogRulesFiredAndFailed(std::ostream & strmOut, GrSlotStream * psstrmIn)
-{
- m_pzpst->LogRulesFiredAndFailed(strmOut, psstrmIn);
-}
-
-void PassState::LogRulesFiredAndFailed(std::ostream & strmOut, GrSlotStream * psstrmIn)
-{
-
- strmOut << "PASS " << m_ipass << "\n\n" << "Rules matched: ";
- if (m_crulrec == 0)
- strmOut << "none";
- strmOut << "\n";
-
- for (int irulrec = 0; irulrec < m_crulrec; irulrec++)
- {
- if (m_rgrulrec[irulrec].m_fFired)
- strmOut << " * ";
- else
- strmOut << " ";
-
- strmOut << m_rgrulrec[irulrec].m_islot << ". ";
-
- if (m_rgrulrec[irulrec].m_irul == PassState::kHitMaxRuleLoop)
- strmOut << "hit MaxRuleLoop\n";
- else if (m_rgrulrec[irulrec].m_irul == PassState::kHitMaxBackup)
- strmOut << "hit MaxBackup\n";
- else
- {
- strmOut << "rule " << m_ipass << "." << m_rgrulrec[irulrec].m_irul;
-
- if (m_rgrulrec[irulrec].m_fFired)
- strmOut << " FIRED\n";
- else
- strmOut << " failed\n";
- }
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out the marks on top of the slot table indicating insertions and deletions.
-----------------------------------------------------------------------------------------------*/
-void GrPass::LogInsertionsAndDeletions(std::ostream & strmOut, GrSlotStream * psstrmOut)
-{
- m_pzpst->LogInsertionsAndDeletions(strmOut, psstrmOut);
-}
-
-void PassState::LogInsertionsAndDeletions(std::ostream & strmOut, GrSlotStream * psstrmOut)
-{
- int cslotDel = m_rgcslotDeletions[0];
- bool fIns;
- if (cslotDel > 1)
- strmOut << "\n DEL-" << cslotDel;
- else if (cslotDel == 1)
- strmOut << "\n DEL ";
- else
- strmOut << "\n ";
-
- for (int islot = 0; islot < psstrmOut->WritePos(); islot++)
- {
- cslotDel = (islot + 1 >= MAX_SLOTS) ? 0 : m_rgcslotDeletions[islot + 1];
- fIns = (islot >= MAX_SLOTS) ? 0 : m_rgfInsertion[islot];
-
- if (fIns)
- {
- strmOut << "INS";
- if (cslotDel > 0)
- {
- if (cslotDel > 1)
- strmOut << "/D-" << cslotDel;
- else
- strmOut << "/DEL";
- }
- else
- strmOut << " ";
-
- }
- else if (cslotDel > 0)
- {
- if (cslotDel >= 10)
- strmOut << "DEL-" << cslotDel << " ";
- else if (cslotDel > 1)
- strmOut << " DEL-" << cslotDel << " ";
- else
- strmOut << " DEL ";
- }
- else
- strmOut << " ";
- }
-
- strmOut << "\n";
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out a line for each slot attribute that changed during the pass.
-
- @param fJustWidths - a special pass that writes out just the effects of the justification
- routines, ie, the values of justify.width
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogAttributes(std::ostream & strmOut, int ipass,
- bool fJustWidths)
-{
- // Figure out which slot attributes were modified for some slot during the pass.
- bool * prgfMods = new bool[kslatMax + NumUserDefn() - 1];
-
- bool fPreJust = (!fJustWidths && ipass == m_ipassJust1 - 1 && ShouldLogJustification());
- bool fPostJust = ((fJustWidths || ipass == m_ipassJust1) && ShouldLogJustification());
-
- int ccomp; // max number of components per slot
- int cassoc; // max number of associations per slot
- SlotAttrsModified(ipass, prgfMods, fPreJust, &ccomp, &cassoc);
-
- if (fPreJust)
- {
- // prgfMods[kslatJStretch] = true;
- // prgfMods[kslatJShrink] = true;
- // prgfMods[kslatJStep] = true;
- // prgfMods[kslatWeight] = true;
- prgfMods[kslatJWidth] = false; // output j.width in its own line (we call this
- // method with fJustWidths == true)
- }
- else if (fPostJust)
- prgfMods[kslatJWidth] = true;
-
- GrPass * ppass = Pass(ipass);
- GrPass * ppassNext = (ipass < m_cpass - 1) ? Pass(ipass + 1) : NULL;
- GrSlotStream * psstrm = OutputStream(ipass);
-
- if (fJustWidths)
- {}
- else if (dynamic_cast<GrBidiPass *>(ppass))
- {
- // Special stuff for Bidi pass:
- // Log value of directionality attribute.
- strmOut << "directionality ";
- int islot;
- for (islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- LogDirCodeInTable(strmOut, pslot->DirProcessed());
- }
- strmOut << "\n";
-
- // Log final direction level for bidi pass.
- strmOut << "dir level ";
- for (islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- LogInTable(strmOut, pslot->DirLevel());
- }
- strmOut << "\n";
- }
- else if (ppassNext && dynamic_cast<GrBidiPass *>(ppassNext))
- {
- // Next pass is Bidi: log input values of directionality attribute that are input for it.
- strmOut << "directionality ";
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- LogDirCodeInTable(strmOut, pslot->Directionality());
- }
- strmOut << "\n";
- }
-
- for (int slat = 0; slat < kslatMax + NumUserDefn() - 1; slat++)
- {
- int cIndexLim = 1;
- if (slat == kslatCompRef)
- cIndexLim = ccomp;
- else if (slat == kslatUserDefn)
- cIndexLim = 1; // kMaxUserDefinedSlotAttributes;
-
- if (fJustWidths && slat != kslatJWidth)
- continue;
-
- bool fValidAttr = true;
- for (int iIndex = 0; iIndex < cIndexLim; iIndex++)
- {
- if (prgfMods[slat])
- {
- switch(slat)
- {
- case kslatAdvX: strmOut << "advance.x "; break;
- case kslatAdvY: strmOut << "advance.y "; break;
- case kslatAttTo: strmOut << "att.to "; break;
- case kslatAttAtX: strmOut << "att.at.x "; break;
- case kslatAttAtY: strmOut << "att.at.y "; break;
- case kslatAttAtGpt: strmOut << "att.at.gpt "; break;
- case kslatAttAtXoff: strmOut << "att.at.xoff "; break;
- case kslatAttAtYoff: strmOut << "att.at.yoff "; break;
- case kslatAttWithX: strmOut << "att.with.x "; break;
- case kslatAttWithY: strmOut << "att.with.y "; break;
- case kslatAttWithGpt: strmOut << "att.with.gpt "; break;
- case kslatAttWithXoff: strmOut << "att.with.xoff "; break;
- case kslatAttWithYoff: strmOut << "att.with.yoff "; break;
- case kslatAttLevel: strmOut << "att.level "; break;
- case kslatBreak: strmOut << "breakweight "; break;
- case kslatCompRef: strmOut << "component " << iIndex + 1 // 1-based
- << " "; break;
- case kslatDir: strmOut << "dir "; break;
- case kslatInsert: strmOut << "insert "; break;
- case kslatMeasureSol: strmOut << "measure.sol "; break;
- case kslatMeasureEol: strmOut << "measure.eol "; break;
- case kslatJStretch: strmOut << "j.stretch "; break;
- case kslatJShrink: strmOut << "j.shrink "; break;
- case kslatJStep: strmOut << "j.step "; break;
- case kslatJWeight: strmOut << "j.weight "; break;
- case kslatJWidth: strmOut << "j.width "; break;
- case kslatPosX:
- case kslatPosY:
- Assert(false);
- break;
- case kslatShiftX: strmOut << "shift.x "; break;
- case kslatShiftY: strmOut << "shift.y "; break;
- default:
- if (kslatUserDefn <= slat &&
- slat < kslatUserDefn + NumUserDefn())
- {
- strmOut << "user" << (slat - kslatUserDefn + 1) // 1-based
- << ((iIndex >= 9) ? " " : " ");
- }
- else
- {
- // Invalid attribute:
- Warn("bad slot attribute");
- fValidAttr = false;
- break;
- }
- }
-
- if (!fValidAttr)
- break; // out of iIndex loop
-
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- pslot->LogSlotAttributeValue(this, strmOut, ipass, slat, iIndex,
- fPreJust, fPostJust);
- }
-
- strmOut << "\n";
- }
- }
- }
-
- if (fJustWidths)
- goto LDone;
-
- for (int iassoc = 0; iassoc < cassoc; iassoc++)
- {
- // Log associations. Put them on one line it that will work; otherwise use several.
- bool fBoth = (cassoc <= 2);
- bool fAfter = (iassoc == (cassoc - 1));
- if (fBoth)
- strmOut << "assocs ";
- else if (iassoc == 0)
- strmOut << "assocs-before ";
- else if (fAfter)
- strmOut << " -after ";
- else
- strmOut << " -other ";
-
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- pslot->LogAssociation(this, strmOut, ipass, iassoc, fBoth, fAfter);
- }
-
- strmOut << "\n";
-
- if (fBoth)
- break;
- }
-
- if (cassoc == 0 && dynamic_cast<GrBidiPass *>(ppass))
- {
- strmOut << "assocs ";
-
- // Log associations for all slots moved during the Bidi pass.
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- if (pslot->m_islotTmpIn != pslot->m_islotTmpOut)
- LogInTable(strmOut, pslot->m_islotTmpIn);
- else
- strmOut << " ";
- }
-
- strmOut << "\n";
- }
-
-LDone:
-
- delete[] prgfMods;
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out the final positions.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogFinalPositions(std::ostream & strmOut)
-{
- GrSlotStream * psstrm = OutputStream(m_cpass - 1);
-
- strmOut << "x position ";
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- if (pslot->IsLineBreak(LBGlyphID()))
- {
- strmOut << " ";
- continue;
- }
- LogInTable(strmOut, pslot->XPosition());
- }
- strmOut << "\n";
-
- strmOut << "y position ";
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- if (pslot->IsLineBreak(LBGlyphID()))
- {
- strmOut << " ";
- continue;
- }
- LogInTable(strmOut, pslot->YPosition());
- }
- strmOut << "\n";
-}
-#endif // TRACING
-
-/*----------------------------------------------------------------------------------------------
- Write out the final underlying-to-surface associations.
-----------------------------------------------------------------------------------------------*/
-void Segment::LogUnderlyingToSurface(GrTableManager * ptman, std::ostream & strmOut,
- GrCharStream * pchstrm)
-{
-#ifdef TRACING
- strmOut << "\n\nUNDERLYING TO SURFACE MAPPINGS\n\n";
-
- size_t cassocs = 0;
- int fLigs = false;
- int ichw;
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (m_prgpvisloutAssocs[ichw])
- cassocs = max(cassocs, m_prgpvisloutAssocs[ichw]->size());
- if (m_prgisloutLigature[ichw] != kNegInfinity)
- fLigs = true;
- }
-
-// ptman->LogSlotHeader(strmOut, m_ichwAssocsLim, SP_PER_SLOT, LEADING_SP, m_ichwAssocsMin);
- ptman->LogUnderlyingHeader(strmOut, pchstrm->Min(), (pchstrm->Min() + m_ichwAssocsLim),
- -m_ichwAssocsMin, NULL);
-
- int rgnChars[MAX_SLOTS];
- bool rgfNewRun[MAX_SLOTS];
- std::fill_n(rgfNewRun, MAX_SLOTS, false);
- GrFeatureValues rgfval[MAX_SLOTS];
- int cchwMaxRawChars;
-
- int cchw = pchstrm->GetLogData(ptman, rgnChars, rgfNewRun, rgfval,
- -m_ichwAssocsMin, &cchwMaxRawChars);
- cchw = min(cchw, MAX_SLOTS);
-
- utf16 rgchwChars2[MAX_SLOTS];
- utf16 rgchwChars3[MAX_SLOTS];
- utf16 rgchwChars4[MAX_SLOTS];
- utf16 rgchwChars5[MAX_SLOTS];
- utf16 rgchwChars6[MAX_SLOTS];
- int rgcchwRaw[MAX_SLOTS];
- if (cchwMaxRawChars > 1)
- {
- cchwMaxRawChars = min(cchwMaxRawChars, 6);
- pchstrm->GetLogDataRaw(ptman, cchw, -m_ichwAssocsMin, cchwMaxRawChars,
- rgnChars, rgchwChars2, rgchwChars3, rgchwChars4, rgchwChars5, rgchwChars6,
- rgcchwRaw);
- }
- else
- {
- for (ichw = 0 ; ichw <(m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- rgcchwRaw[ichw] = 1;
- rgchwChars2[ichw] = 0;
- rgchwChars3[ichw] = 0;
- rgchwChars4[ichw] = 0;
- rgchwChars5[ichw] = 0;
- rgchwChars6[ichw] = 0;
- }
- }
-
- // Text
- strmOut << "Text: "; // 15 spaces
- int inUtf32 = 0;
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- utf16 chw, chwNext;
- switch (rgcchwRaw[ichw])
- {
- default:
- case 1: chw = utf16(rgnChars[inUtf32]); chwNext = rgchwChars2[inUtf32]; break;
- case 2: chw = rgchwChars2[inUtf32]; chwNext = rgchwChars3[inUtf32]; break;
- case 3: chw = rgchwChars3[inUtf32]; chwNext = rgchwChars4[inUtf32]; break;
- case 4: chw = rgchwChars4[inUtf32]; chwNext = rgchwChars5[inUtf32]; break;
- case 5: chw = rgchwChars5[inUtf32]; chwNext = rgchwChars6[inUtf32]; break;
- case 6: chw = rgchwChars6[inUtf32]; chwNext = 0; break;
- }
- if (rgcchwRaw[ichw] == 1 && chwNext == 0 && chw < 0x0100) // ANSI
- strmOut << (char)chw << " "; // 6 spaces
- else
- strmOut << " "; // 7 spaces
- if (chwNext == 0)
- inUtf32++;
- }
- strmOut << "\n";
-
- // Unicode
- strmOut << "Unicode: ";
- inUtf32 = 0;
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- utf16 chw, chwNext;
- switch (rgcchwRaw[ichw])
- {
- default:
- case 1: chw = utf16(rgnChars[inUtf32]); chwNext = rgchwChars2[inUtf32]; break;
- case 2: chw = rgchwChars2[inUtf32]; chwNext = rgchwChars3[inUtf32]; break;
- case 3: chw = rgchwChars3[inUtf32]; chwNext = rgchwChars4[inUtf32]; break;
- case 4: chw = rgchwChars4[inUtf32]; chwNext = rgchwChars5[inUtf32]; break;
- case 5: chw = rgchwChars5[inUtf32]; chwNext = rgchwChars6[inUtf32]; break;
- case 6: chw = rgchwChars6[inUtf32]; chwNext = 0; break;
- }
- ptman->LogHexInTable(strmOut, chw, chwNext != 0);
- if (chwNext == 0)
- inUtf32++;
- }
- strmOut << "\n";
-
- strmOut << "before ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (rgcchwRaw[ichw] > 1)
- // continuation of Unicode codepoint
- strmOut << " ";
- else if (m_prgisloutBefore[ichw] == kNegInfinity)
- strmOut << "<-- ";
- else if (m_prgisloutBefore[ichw] == kPosInfinity)
- strmOut << "--> ";
- else
- ptman->LogInTable(strmOut, m_prgisloutBefore[ichw]);
- }
- strmOut <<"\n";
-
- for (int ix = 1; ix < signed(cassocs) - 1; ix++) //(cassocs > 2)
- {
- if (ix == 1)
- strmOut << "other ";
- else
- strmOut << " ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- std::vector<int> * pvislout = m_prgpvisloutAssocs[ichw];
- if (pvislout == NULL)
- strmOut << " ";
- else if (signed(pvislout->size()) <= ix)
- strmOut << " ";
- else if ((*pvislout)[ix] != m_prgisloutAfter[ichw])
- ptman->LogInTable(strmOut, (*pvislout)[ix]);
- else
- strmOut << " ";
- }
- strmOut << "\n";
- }
-
- strmOut << "after ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (rgcchwRaw[ichw] > 1)
- // continuation of Unicode codepoint
- strmOut << " ";
- else if (m_prgisloutAfter[ichw] == kNegInfinity)
- strmOut << "<-- ";
- else if (m_prgisloutAfter[ichw] == kPosInfinity)
- strmOut << "--> ";
- else
- ptman->LogInTable(strmOut, m_prgisloutAfter[ichw]);
- }
- strmOut <<"\n";
-
- if (fLigs)
- {
- strmOut << "ligature ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (rgcchwRaw[ichw] > 1)
- // continuation of Unicode codepoint
- strmOut << " ";
- else if (m_prgisloutLigature[ichw] != kNegInfinity)
- ptman->LogInTable(strmOut, m_prgisloutLigature[ichw]);
- else
- strmOut << " ";
- }
- strmOut << "\n";
-
- strmOut << "component ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (rgcchwRaw[ichw] > 1)
- // continuation of Unicode codepoint
- strmOut << " ";
- else if (m_prgisloutLigature[ichw] != kNegInfinity)
- ptman->LogInTable(strmOut, m_prgiComponent[ichw] + 1); // 1-based
- else
- strmOut << " ";
- }
- strmOut << "\n";
- }
-
- strmOut << "\n";
-#endif
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out the final surface-to-underlying associations.
-----------------------------------------------------------------------------------------------*/
-void Segment::LogSurfaceToUnderlying(GrTableManager * ptman, std::ostream & strmOut)
-{
-#ifdef TRACING
- strmOut << "\nSURFACE TO UNDERLYING MAPPINGS\n\n";
-
- ptman->LogSlotHeader(strmOut, m_cslout, SP_PER_SLOT, LEADING_SP);
-
- int ccomp = 0;
-
- strmOut << "Glyph IDs: ";
- int islout;
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->SpecialSlotFlag() == kspslLbInitial ||
- psloutTmp->SpecialSlotFlag() == kspslLbFinal)
- {
- strmOut << "# ";
- }
- else
- {
- ptman->LogHexInTable(strmOut, psloutTmp->GlyphID());
- ccomp = max(ccomp, psloutTmp->NumberOfComponents());
- }
- }
- strmOut << "\n";
-
- bool fAnyPseudos = false;
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->GlyphID() != psloutTmp->ActualGlyphForOutput(ptman))
- {
- fAnyPseudos = true;
- break;
- }
- }
- if (fAnyPseudos)
- {
- strmOut << "Actual glyphs: ";
- for (int islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->GlyphID() != psloutTmp->ActualGlyphForOutput(ptman))
- ptman->LogHexInTable(strmOut, psloutTmp->ActualGlyphForOutput(ptman));
- else
- strmOut << " ";
- }
- strmOut << "\n";
- }
-
- strmOut << "before ";
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->SpecialSlotFlag() == kspslLbInitial ||
- psloutTmp->SpecialSlotFlag() == kspslLbFinal)
- {
- strmOut << " ";
- }
- else
- ptman->LogInTable(strmOut, psloutTmp->BeforeAssoc());
- }
- strmOut << "\n";
-
- strmOut << "after ";
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->SpecialSlotFlag() == kspslLbInitial ||
- psloutTmp->SpecialSlotFlag() == kspslLbFinal)
- {
- strmOut << " ";
- }
- else
- ptman->LogInTable(strmOut, psloutTmp->AfterAssoc());
- }
- strmOut << "\n";
-
- for (int icomp = 0; icomp < ccomp; icomp++)
- {
- strmOut << "component " << icomp + 1 // 1=based
- << " ";
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->SpecialSlotFlag() == kspslLbInitial ||
- psloutTmp->SpecialSlotFlag() == kspslLbFinal)
- {
- strmOut << " ";
- }
- else if (icomp < psloutTmp->NumberOfComponents())
- ptman->LogInTable(strmOut, psloutTmp->UnderlyingComponent(icomp));
- else
- strmOut << " ";
- }
- strmOut << "\n";
- }
-#endif
-}
-
-#ifdef TRACING
-/*----------------------------------------------------------------------------------------------
- Write out the header lines for the underlying data.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogUnderlyingHeader(std::ostream & strmOut, int iMin,
- int iLim, int cBackup, int * prgichr)
-{
- strmOut << "string ";
- int i, iLabel;
- int * pichr = prgichr;
- for (i = iMin - cBackup, iLabel = i; i < iLim; i++, iLabel++, pichr++)
- {
- while (prgichr && *pichr > 1)
- {
- // continuation of upper-plane char
- iLabel++;
- pichr++;
- }
- LogInTable(strmOut, iLabel);
- }
- strmOut << "\n";
-
- strmOut << "segment ";
- pichr = prgichr;
- for (i = 0 - cBackup, iLabel = i; i < (iLim - iMin); i++, iLabel++, pichr++)
- {
- while (prgichr && *pichr > 1)
- {
- // continuation of upper-plane char
- iLabel++;
- pichr++;
- }
- LogInTable(strmOut, iLabel);
- }
- strmOut << "\n\n";
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out the header lines for the slot contents.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogSlotHeader(std::ostream & strmOut, int islotLim,
- int cspPerSlot, int cspLeading, int islotMin)
-{
- islotLim = min(islotLim, MAX_SLOTS);
-
- int isp, islot;
-
- for (isp = 0; isp < cspLeading; isp++)
- strmOut << " ";
-
- for (islot = islotMin; islot < islotLim; islot++)
- LogInTable(strmOut, islot);
- strmOut << "\n\n";
-
-/****
- if (cslot >= 100)
- {
- for (isp = 0; isp < cspLeading; isp++)
- strmOut << " ";
-
- for (islot = 0; islot < 100; islot++)
- {
- for (isp = 0; isp < cspPerSlot; isp++)
- strmOut << " ";
- }
-
- for (islot = 100; islot < cslot; islot++)
- {
- strmOut << "1";
- for (isp = 1; isp < cspPerSlot; isp++)
- strmOut << " ";
- }
- }
-
- if (cslot > 10)
- {
- for (isp = 0; isp < cspLeading; isp++)
- strmOut << " ";
-
- for (islot = 0; islot < 10; islot++)
- {
- for (isp = 0; isp < cspPerSlot; isp++)
- strmOut << " ";
- }
-
- for (islot = 10; islot < cslot; islot++)
- {
- if (true) // (islot % 10 == 0)
- {
- if (islot >= 100)
- strmOut << ((islot - 100) / 10);
- else
- strmOut << (islot / 10);
- }
- else
- strmOut << " ";
-
- for (isp = 1; isp < cspPerSlot; isp++)
- strmOut << " ";
- }
- strmOut << "\n";
- }
-
- for (isp = 0; isp < cspLeading; isp++)
- strmOut << " ";
-
- for (islot = 0; islot < cslot; islot++)
- {
- strmOut << (islot % 10);
- for (isp = 1; isp < cspPerSlot; isp++)
- strmOut << " ";
-
- }
- strmOut << "\n";
-****/
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out the glyph numbers for the given stream.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogSlotGlyphs(std::ostream & strmOut, GrSlotStream * psstrm)
-{
- strmOut << "Glyph IDs: ";
- int islot;
- for (islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslotTmp = psstrm->SlotAt(islot);
- if (pslotTmp->IsLineBreak(LBGlyphID()))
- strmOut << "# ";
- else
- LogHexInTable(strmOut, pslotTmp->GlyphID());
- }
- strmOut << "\n";
-}
-
-/*----------------------------------------------------------------------------------------------
- Return flags indicating which attributes were modified for some slot during the pass
- and therefore need a line in the log file.
-
- The 'pfMods' array has one flag per slot attribute; the final group are the user-
- definable attributes. 'pccomp' returns the maximum number of ligature components
- in this pass. Associations are assumed to have changed if anything else for the slot did.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::SlotAttrsModified(int ipass, bool * rgfMods, bool fPreJust,
- int * pccomp, int * pcassoc)
-{
- // Zero the flags
- std::fill_n(rgfMods, kslatMax + NumUserDefn() - 1, false);
- *pccomp = 0;
- *pcassoc = 0;
-
- //GrSlotStream * psstrmIn = InputStream(ipass);
- GrSlotStream * psstrmOut = OutputStream(ipass);
-
- for (int islot = 0; islot < psstrmOut->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrmOut->SlotAt(islot);
- Assert(pslot->PassModified() <= ipass);
- if (pslot->PassModified() < ipass && !fPreJust)
- continue; // not modified during this pass
-
- pslot->SlotAttrsModified(rgfMods, fPreJust, pccomp, pcassoc);
- }
-}
-
-void GrSlotState::SlotAttrsModified(bool * rgfMods, bool fPreJust, int * pccomp, int * pcassoc)
-{
- // To handle reprocessing, in which case there may be a chain of slots modified
- // in the same pass:
- GrSlotState * pslotPrev = m_pslotPrevState;
- while (pslotPrev && pslotPrev->PassModified() == PassModified())
- pslotPrev = pslotPrev->m_pslotPrevState;
-
- if (!pslotPrev)
- {
- // Inserted slot?
- if (m_fAdvXSet)
- rgfMods[kslatAdvX] = true;
- if (m_fAdvYSet)
- rgfMods[kslatAdvY] = true;
-
- if (m_srAttachTo != 0)
- rgfMods[kslatAttTo] = true;
-
- if (m_mAttachAtX != kNotYetSet || m_mAttachAtY != 0)
- { // always do these in pairs
- rgfMods[kslatAttAtX] = true;
- rgfMods[kslatAttAtY] = true;
- }
- if (m_nAttachAtGpoint != kNotYetSet)
- rgfMods[kslatAttAtGpt] = true;
- if (m_mAttachAtXOffset != 0 || m_mAttachAtYOffset != 0)
- { // always do these in pairs
- rgfMods[kslatAttAtXoff] = true;
- rgfMods[kslatAttAtYoff] = true;
- }
-
- if (m_mAttachWithX != kNotYetSet || m_mAttachWithY != 0)
- { // always do these in pairs
- rgfMods[kslatAttWithX] = true;
- rgfMods[kslatAttWithY] = true;
- }
- if (m_nAttachWithGpoint != kNotYetSet)
- rgfMods[kslatAttWithGpt] = true;
- if (m_mAttachWithXOffset != 0 || m_mAttachWithYOffset != 0)
- { // always do these in pairs
- rgfMods[kslatAttWithXoff] = true;
- rgfMods[kslatAttWithYoff] = true;
- }
-
- if (m_nAttachLevel != 0)
- rgfMods[kslatAttLevel] = true;
-
- if (m_lb != kNotYetSet8)
- rgfMods[kslatBreak] = true;
- if (m_dirc != kNotYetSet8)
- rgfMods[kslatDir] = true;
- if (m_fInsertBefore != true)
- rgfMods[kslatInsert] = true;
-
- if (m_mMeasureSol != kNotYetSet && m_mMeasureSol != 0)
- rgfMods[kslatMeasureSol] = true;
- if (m_mMeasureEol != kNotYetSet && m_mMeasureEol != 0)
- rgfMods[kslatMeasureEol] = true;
-
- if (m_mJStretch0 != kNotYetSet && m_mJStretch0 != 0)
- rgfMods[kslatJStretch] = true;
- if (m_mJShrink0 != kNotYetSet && m_mJShrink0 != 0)
- rgfMods[kslatJShrink] = true;
- if (m_mJStep0 != kNotYetSet && m_mJStep0 != 0)
- rgfMods[kslatJStep] = true;
- if (m_nJWeight0 != byte(kNotYetSet) &&
- m_nJWeight0 != 0 && m_nJWeight0 != 1)
- rgfMods[kslatJWeight] = true;
- if (m_mJWidth0 != kNotYetSet && m_mJWidth0 != 0)
- rgfMods[kslatJWidth] = true;
-
- if (m_mShiftX != 0)
- rgfMods[kslatShiftX] = true;
- if (m_mShiftY != 0)
- rgfMods[kslatShiftY] = true;
-
- int i;
- for (i = 0; i < m_cnCompPerLig; i++)
- {
- if (CompRef(i) != NULL)
- rgfMods[kslatCompRef] = true;
- if (CompRef(i))
- *pccomp = max(*pccomp, i + 1); // max number of ligatures in this pass
- }
-
- for (i = 0; i < m_cnUserDefn; i++)
- {
- if (UserDefn(i) != 0)
- rgfMods[kslatUserDefn + i] = true;
- }
- }
- else
- {
- if (m_fAdvXSet && m_mAdvanceX != pslotPrev->m_mAdvanceX)
- rgfMods[kslatAdvX] = true;
- if (m_fAdvYSet && m_mAdvanceY != pslotPrev->m_mAdvanceY)
- rgfMods[kslatAdvY] = true;
-
- if (m_srAttachTo != pslotPrev->m_srAttachTo)
- rgfMods[kslatAttTo] = true;
-
- if (m_mAttachAtX != pslotPrev->m_mAttachAtX || m_mAttachAtY != pslotPrev->m_mAttachAtY)
- {
- rgfMods[kslatAttAtX] = true;
- rgfMods[kslatAttAtY] = true;
- }
- if (m_nAttachAtGpoint != pslotPrev->m_nAttachAtGpoint)
- rgfMods[kslatAttAtGpt] = true;
- if (m_mAttachAtXOffset != pslotPrev->m_mAttachAtXOffset ||
- m_mAttachAtYOffset != pslotPrev->m_mAttachAtYOffset)
- {
- rgfMods[kslatAttAtXoff] = true;
- rgfMods[kslatAttAtYoff] = true;
- }
-
- if (m_mAttachWithX != pslotPrev->m_mAttachWithX ||
- m_mAttachWithY != pslotPrev->m_mAttachWithY)
- {
- rgfMods[kslatAttWithX] = true;
- rgfMods[kslatAttWithY] = true;
- }
- if (m_nAttachWithGpoint != pslotPrev->m_nAttachWithGpoint)
- rgfMods[kslatAttWithGpt] = true;
- if (m_mAttachWithXOffset != pslotPrev->m_mAttachWithXOffset ||
- m_mAttachWithYOffset != pslotPrev->m_mAttachWithYOffset)
- {
- rgfMods[kslatAttWithXoff] = true;
- rgfMods[kslatAttWithYoff] = true;
- }
-
- if (m_nAttachLevel != pslotPrev->m_nAttachLevel)
- rgfMods[kslatAttLevel] = true;
-
- if (m_lb != pslotPrev->m_lb)
- rgfMods[kslatBreak] = true;
- if (m_dirc != pslotPrev->m_dirc)
- rgfMods[kslatDir] = true;
- if (m_fInsertBefore != pslotPrev->m_fInsertBefore)
- rgfMods[kslatInsert] = true;
-
- if (m_mMeasureSol != pslotPrev->m_mMeasureSol)
- rgfMods[kslatMeasureSol] = true;
- if (m_mMeasureEol != pslotPrev->m_mMeasureEol)
- rgfMods[kslatMeasureEol] = true;
-
- if (m_mJStretch0 != pslotPrev->m_mJStretch0 || (fPreJust && m_mJStretch0 != 0))
- rgfMods[kslatJStretch] = true;
- if (m_mJShrink0 != pslotPrev->m_mJShrink0 || (fPreJust && m_mJShrink0 != 0))
- rgfMods[kslatJShrink] = true;
- if (m_mJStep0 != pslotPrev->m_mJStep0 || (fPreJust && m_mJStep0 != 0))
- rgfMods[kslatJStep] = true;
- if (m_nJWeight0 != pslotPrev->m_nJWeight0 || (fPreJust && m_nJWeight0 != 0))
- rgfMods[kslatJWeight] = true;
- if (m_mJWidth0 != pslotPrev->m_mJWidth0)
- rgfMods[kslatJWidth] = true;
-
- if (m_mShiftX != pslotPrev->m_mShiftX)
- rgfMods[kslatShiftX] = true;
- if (m_mShiftY != pslotPrev->m_mShiftY)
- rgfMods[kslatShiftY] = true;
-
- int i;
- for (i = 0; i < m_cnCompPerLig; i++)
- {
- if (CompRef(i) != pslotPrev->CompRef(i))
- rgfMods[kslatCompRef] = true;
- if (CompRef(i))
- *pccomp = max(*pccomp, i + 1); // max number of ligatures in this pass
- }
-
- for (i = 0; i < m_cnUserDefn; i++)
- {
- if (UserDefn(i) != pslotPrev->UserDefn(i))
- rgfMods[kslatUserDefn + i] = true;
- }
- }
-
- *pcassoc = max(*pcassoc, AssocsSize());
-}
-
-/*----------------------------------------------------------------------------------------------
- Log the value of the slot attribute for the given slot, if it changed.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::LogSlotAttributeValue(GrTableManager * ptman,
- std::ostream & strmOut, int ipass, int slat, int iIndex,
- bool fPreJust, bool fPostJust)
-{
- if (m_ipassModified != ipass && !fPreJust && !fPostJust)
- {
- strmOut << " ";
- return;
- }
-
- // To handle reprocessing, in which case there may be a chain of slots modified
- // in the same pass:
- GrSlotState * pslotPrev = m_pslotPrevState;
- while (pslotPrev && pslotPrev->PassModified() == PassModified())
- pslotPrev = pslotPrev->m_pslotPrevState;
-
- // General-purpose variables for em-unit attributes:
- int mThis = 0;
- int mPrev = 0;
- switch (slat)
- {
- case kslatShiftX:
- mThis = m_mShiftX;
- mPrev = (pslotPrev) ? pslotPrev->m_mShiftX : 0;
- break;
- case kslatShiftY:
- mThis = m_mShiftY;
- mPrev = (pslotPrev) ? pslotPrev->m_mShiftY : 0;
- break;
- case kslatMeasureSol:
- mThis = m_mMeasureSol;
- mPrev = (pslotPrev) ? pslotPrev->m_mMeasureSol : 0;
- break;
- case kslatMeasureEol:
- mThis = m_mMeasureEol;
- mPrev = (pslotPrev) ? pslotPrev->m_mMeasureEol : 0;
- break;
- case kslatJStretch:
- mThis = m_mJStretch0;
- mPrev = (pslotPrev) ? pslotPrev->m_mJStretch0 : 0;
- mPrev = (fPreJust && mThis > 0) ? -1 : mPrev; // log it even if it didn't change
- break;
- case kslatJShrink:
- mThis = m_mJShrink0;
- mPrev = (pslotPrev) ? pslotPrev->m_mJShrink0 : 0;
- mPrev = (fPreJust && mThis > 0) ? -1 : mPrev; // log it even if it didn't change
- break;
- case kslatJStep:
- mThis = m_mJStep0;
- mPrev = (pslotPrev) ? pslotPrev->m_mJStep0 : 0;
- mPrev = (fPreJust && mThis > 1) ? -1 : mPrev; // log it even if it didn't change
- break;
- case kslatJWeight:
- mThis = m_nJWeight0;
- mPrev = (pslotPrev) ? pslotPrev->m_nJWeight0 : 0;
- mPrev = (fPreJust && mThis > 1) ? -1 : mPrev; // log it even if it didn't change
- break;
- case kslatJWidth:
- mThis = m_mJWidth0;
- mPrev = (pslotPrev) ? pslotPrev->m_mJWidth0 : 0;
- mPrev = (fPostJust && mThis > 0) ? -1 : mPrev; // log it even if it didn't change
- break;
- default:
- // don't use these variables
- break;
- }
-
- switch (slat)
- {
- case kslatAdvX:
- if (m_fAdvXSet && (!pslotPrev || m_mAdvanceX != pslotPrev->m_mAdvanceX))
- {
- ptman->LogInTable(strmOut, m_mAdvanceX);
- return;
- }
- break;
- case kslatAdvY:
- if (m_fAdvYSet && (!pslotPrev || m_mAdvanceY != pslotPrev->m_mAdvanceY))
- {
- ptman->LogInTable(strmOut, m_mAdvanceY);
- return;
- }
- break;
-
- case kslatAttTo:
- if (m_srAttachTo != (pslotPrev ? pslotPrev->m_srAttachTo : 0))
- {
- ptman->LogInTable(strmOut, m_srAttachTo);
- return;
- }
- break;
-
- case kslatAttAtX: // always do these in pairs
- case kslatAttAtY:
- if (m_mAttachAtX != (pslotPrev ? pslotPrev->m_mAttachAtX : kNotYetSet) ||
- m_mAttachAtY != (pslotPrev ? pslotPrev->m_mAttachAtY : 0))
- {
- ptman->LogInTable(strmOut,
- ((slat == kslatAttAtX) ? m_mAttachAtX : m_mAttachAtY));
- return;
- }
- break;
- case kslatAttAtGpt:
- if (m_nAttachAtGpoint != (pslotPrev ? pslotPrev->m_nAttachAtGpoint : kNotYetSet))
- {
- ptman->LogInTable(strmOut,
- ((m_nAttachAtGpoint == kGpointZero) ? 0 : m_nAttachAtGpoint));
- return;
- }
- break;
- case kslatAttAtXoff: // always do these in pairs
- case kslatAttAtYoff:
- if (m_mAttachAtXOffset != (pslotPrev ? pslotPrev->m_mAttachAtXOffset : 0) ||
- m_mAttachAtYOffset != (pslotPrev ? pslotPrev->m_mAttachAtYOffset : 0))
- {
- ptman->LogInTable(strmOut,
- ((slat == kslatAttAtXoff) ? m_mAttachAtXOffset : m_mAttachAtYOffset));
- return;
- }
- break;
-
- case kslatAttWithX: // always do these in pairs
- case kslatAttWithY:
- if (m_mAttachWithX != (pslotPrev ? pslotPrev->m_mAttachWithX : kNotYetSet) ||
- m_mAttachWithY != (pslotPrev ? pslotPrev->m_mAttachWithY : 0))
- {
- ptman->LogInTable(strmOut,
- ((slat == kslatAttWithX) ? m_mAttachWithX : m_mAttachWithY));
- return;
- }
- break;
- case kslatAttWithGpt:
- if (m_nAttachWithGpoint != (pslotPrev ? pslotPrev->m_nAttachWithGpoint : kNotYetSet))
- {
- ptman->LogInTable(strmOut,
- ((m_nAttachWithGpoint == kGpointZero) ? 0 : m_nAttachWithGpoint));
- return;
- }
- break;
- case kslatAttWithXoff: // always do these in pairs
- case kslatAttWithYoff:
- if (m_mAttachWithXOffset != (pslotPrev ? pslotPrev->m_mAttachWithXOffset : 0) ||
- m_mAttachWithYOffset != (pslotPrev ? pslotPrev->m_mAttachWithYOffset : 0))
- {
- ptman->LogInTable(strmOut,
- ((slat == kslatAttWithXoff) ? m_mAttachWithXOffset : m_mAttachWithYOffset));
- return;
- }
- break;
-
- case kslatAttLevel:
- if (m_nAttachLevel != (pslotPrev ? pslotPrev->m_nAttachLevel : 0))
- {
- ptman->LogInTable(strmOut, m_nAttachLevel);
- return;
- }
- break;
-
- case kslatBreak:
- if (m_lb != (pslotPrev ? pslotPrev->m_lb : kNotYetSet8))
- {
- ptman->LogBreakWeightInTable(strmOut, m_lb);
- return;
- }
- break;
- case kslatDir:
- if (m_dirc != (pslotPrev ? pslotPrev->m_dirc : kNotYetSet8))
- {
- ptman->LogDirCodeInTable(strmOut, m_dirc);
- return;
- }
- break;
- case kslatInsert:
- if (m_fInsertBefore != (pslotPrev ? pslotPrev->m_fInsertBefore : true))
- {
- if (m_fInsertBefore)
- strmOut << "true ";
- else
- strmOut << "false ";
- return;
- }
- break;
-
- case kslatJWeight:
- if (m_mJStretch0 == 0 && m_mJShrink0 == 0)
- mPrev = mThis; // don't log; weight is irrelevant
- // fall through
- case kslatShiftX:
- case kslatShiftY:
- case kslatMeasureSol:
- case kslatMeasureEol:
- case kslatJStretch:
- case kslatJShrink:
- case kslatJStep:
- case kslatJWidth:
- if (mThis != mPrev)
- {
- ptman->LogInTable(strmOut, mThis);
- return;
- }
- break;
-
- case kslatCompRef:
- if (CompRef(iIndex) != (pslotPrev ? pslotPrev->CompRef(iIndex) : 0))
- {
- GrSlotState * pslotComp = reinterpret_cast<GrSlotState *>(CompRef(iIndex));
- ptman->LogInTable(strmOut, pslotComp->m_islotTmpIn);
- return;
- }
- break;
-
- default:
- if (kslatUserDefn <= slat && slat <= kslatUserDefn + m_cnUserDefn)
- {
- int iTmp = slat - kslatUserDefn;
- if (UserDefn(iTmp) != (pslotPrev ? pslotPrev->UserDefn(iTmp) : 0))
- {
- ptman->LogInTable(strmOut, UserDefn(iTmp));
- return;
- }
- }
- else
- gAssert(false);
- }
-
- strmOut << " ";
-}
-
-/*----------------------------------------------------------------------------------------------
- Log the value of the association, if the slot changed.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::LogAssociation(GrTableManager * ptman,
- std::ostream & strmOut, int ipass, int iassoc, bool fBoth, bool fAfter)
-{
- if (m_ipassModified != ipass)
- {
- strmOut << " ";
- return;
- }
-
- if (fBoth)
- {
- GrSlotState * pslotBefore = AssocSlot(0);
- GrSlotState * pslotAfter = AssocSlot(m_vpslotAssoc.size() - 1);
-
- int nBefore, nAfter;
-
- int csp = 4;
- if (pslotBefore)
- {
- nBefore = pslotBefore->m_islotTmpIn;
- strmOut << nBefore;
- if (nBefore > 99) csp--;
- if (nBefore > 9) csp--;
- }
- else
- {
- strmOut << "??";
- csp--;
- }
- if (pslotAfter)
- {
- nAfter = pslotAfter->m_islotTmpIn;
- strmOut << "/" << nAfter;
- if (nAfter > 99) csp--;
- if (nAfter > 9) csp--;
- }
- else
- {
- if (pslotBefore)
- {
- strmOut << "/" << "??";
- csp--;
- }
- else
- csp = 5;
- }
-
- for (int isp = 0; isp < csp; isp++)
- strmOut << " ";
- }
-
- else if (fAfter)
- {
- Assert(m_vpslotAssoc.size());
- GrSlotState * pslotAfter = AssocSlot(m_vpslotAssoc.size() - 1);
-
- if (pslotAfter)
- {
- int nAfter = pslotAfter->m_islotTmpIn;
- ptman->LogInTable(strmOut, nAfter);
- }
- else
- strmOut << "?? ";
- }
- else if (iassoc < signed(m_vpslotAssoc.size() - 1))
- {
- GrSlotState * pslot = AssocSlot(iassoc);
-
- if (pslot)
- {
- int n = pslot->m_islotTmpIn;
- ptman->LogInTable(strmOut, n);
- }
- else
- strmOut << "?? ";
- }
- else
- strmOut << " ";
-}
-
-/*----------------------------------------------------------------------------------------------
- Write a hex value (a glyphID or Unicode codepoint) into the table.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogInTable(std::ostream & strmOut, int n)
-{
- if (n == kNegInfinity)
- {
- strmOut << "-inf ";
- return;
- }
- if (n == kPosInfinity)
- {
- strmOut << "+inf ";
- return;
- }
- if (n > 999999)
- {
- strmOut << "****** ";
- return;
- }
- if (n < -99999)
- {
- strmOut << "-***** ";
- return;
- }
-
- strmOut << n;
- int csp = SP_PER_SLOT - 1;
-
- if (abs(n) > 99999) csp--;
- if (abs(n) > 9999) csp--;
- if (abs(n) > 999) csp--;
- if (abs(n) > 99) csp--;
- if (abs(n) > 9) csp--;
-
- if (n < 0) csp--;
-
- for (int isp = 0; isp < csp; isp++)
- strmOut << " ";
-}
-
-void GrTableManager::LogInTable(std::ostream & strmOut, float n)
-{
- if (n == kNegInfFloat)
- {
- strmOut << "-inf ";
- return;
- }
- if (n == kPosInfFloat)
- {
- strmOut << "+inf ";
- return;
- }
- if (n > 9999)
- {
- strmOut << "****.* ";
- return;
- }
- if (n < -999)
- {
- strmOut << "-***.* ";
- return;
- }
-
- int csp = SP_PER_SLOT - 4;
-
- int nInt = (int)(fabsf(n));
- int nTenths = (int)fabsf((fabsf(n) - float(nInt) + 0.05f) * 10);
- if (nTenths >= 10)
- {
- nTenths = 0;
- nInt++;
- }
-
- if (nInt >= 1000) csp--;
- if (nInt >= 100) csp--;
- if (nInt >= 10) csp--;
-
- if (n < 0) csp--;
-
- for (int isp = 0; isp < csp; isp++)
- strmOut << " ";
- if (n < 0)
- strmOut << "-";
- strmOut << nInt << "." << nTenths << " ";
-}
-
-/*----------------------------------------------------------------------------------------------
- Write a hex value (a glyphID or Unicode codepoint) into the table.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogHexInTable(std::ostream & strmOut, utf16 chw, bool fPlus)
-{
- //char rgch[20];
- if (chw <= 0x0fff) strmOut << "0";
- if (chw <= 0x00ff) strmOut << "0";
- if (chw <= 0x000f) strmOut << "0";
-
- strmOut << std::hex << chw << std::dec;
-
- for (int i = 4; i < SP_PER_SLOT - 2; i++)
- strmOut << " ";
-
- if (fPlus)
- strmOut << "+ ";
- else
- strmOut << " ";
-}
-
-/*----------------------------------------------------------------------------------------------
- Write a directionality code to the table.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogDirCodeInTable(std::ostream & strmOut, int dirc)
-{
- switch (dirc)
- {
- case kdircUnknown: strmOut << "??? "; break;
- case kdircNeutral: strmOut << "ON "; break;
- case kdircL: strmOut << "L "; break;
- case kdircR: strmOut << "R "; break;
- case kdircRArab: strmOut << "AR "; break;
- case kdircEuroNum: strmOut << "EN "; break;
- case kdircEuroSep: strmOut << "ES "; break;
- case kdircEuroTerm: strmOut << "ET "; break;
- case kdircArabNum: strmOut << "AN "; break;
- case kdircComSep: strmOut << "CS "; break;
- case kdircWhiteSpace: strmOut << "WS "; break;
- case kdircBndNeutral: strmOut << "BN "; break;
- case kdircNSM: strmOut << "NSM "; break;
- case kdircLRO: strmOut << "LRO "; break;
- case kdircRLO: strmOut << "RLO "; break;
- case kdircLRE: strmOut << "LRE "; break;
- case kdircRLE: strmOut << "RLE "; break;
- case kdircPDF: strmOut << "PDF "; break;
- case kdircPdfL: strmOut << "PDF-L "; break;
- case kdircPdfR: strmOut << "PDF-R "; break;
- case kdircLlb: strmOut << "L "; break;
- case kdircRlb: strmOut << "R "; break;
- default: LogInTable(strmOut, dirc); break;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Write a breakweight code to the table.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogBreakWeightInTable(std::ostream & strmOut, int lb)
-{
- if (lb < 0)
- {
- lb = lb * -1;
- switch (lb)
- {
- case klbWsBreak: strmOut << "-ws "; break;
- case klbWordBreak: strmOut << "-word "; break;
- case klbHyphenBreak: strmOut << "-intra "; break;
- case klbLetterBreak: strmOut << "-lettr "; break;
- case klbClipBreak: strmOut << "-clip "; break;
- default: LogInTable(strmOut, lb*-1); break;
- }
- }
- else
- {
- switch (lb)
- {
- case klbNoBreak: strmOut << "none "; break;
- case klbWsBreak: strmOut << "ws "; break;
- case klbWordBreak: strmOut << "word "; break;
- case klbHyphenBreak: strmOut << "intra "; break;
- case klbLetterBreak: strmOut << "letter "; break;
- case klbClipBreak: strmOut << "clip "; break;
- default: LogInTable(strmOut, lb); break;
- }
- }
-}
-
-#endif // TRACING
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/XmlTransductionLog.cpp b/Build/source/libs/graphite-engine/src/segment/XmlTransductionLog.cpp
deleted file mode 100644
index d0dfcaafbe8..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/XmlTransductionLog.cpp
+++ /dev/null
@@ -1,1583 +0,0 @@
-/*--------------------------------------------------------------------*//*:Ignore this sentence.
-Copyright (C) 2008 SIL International. All rights reserved.
-
-Distributable under the terms of either the Common Public License or the
-GNU Lesser General Public License, as specified in the LICENSING.txt file.
-
-File: TransductionLog.cpp
-Responsibility: Sharon Correll
-Last reviewed: Not yet.
-
-Description:
- Contains the functions for writing a log of the transduction process using an XML format.
-----------------------------------------------------------------------------------------------*/
-
-//:>********************************************************************************************
-//:> Include files
-//:>********************************************************************************************
-#include "Main.h"
-
-#ifdef _MSC_VER
-#pragma hdrstop
-#endif
-
-#include <math.h>
-
-#undef THIS_FILE
-DEFINE_THIS_FILE
-
-//:End Ignore
-
-//:>********************************************************************************************
-//:> Forward declarations
-//:>********************************************************************************************
-
-//:>********************************************************************************************
-//:> Local Constants and static variables
-//:>********************************************************************************************
-
-namespace gr
-{
-
-//:>********************************************************************************************
-//:> Methods
-//:>********************************************************************************************
-
-#define SP_PER_SLOT 7
-#define LEADING_SP 15
-#define MAX_SLOTS 128
-
-/*----------------------------------------------------------------------------------------------
- Output a file showing a log of the transduction process and the resulting segment.
-----------------------------------------------------------------------------------------------*/
-bool GrTableManager::WriteXmlLog(std::ostream * pstrmLog,
- GrCharStream * pchstrm, Segment * psegRet, int cbPrevSegDat, byte * pbPrevSegDat)
-{
-#ifdef TRACING
- if (!pstrmLog)
- return false;
- std::ostream & strmOut = *pstrmLog;
- WriteXmlLogAux(strmOut, pchstrm, psegRet, cbPrevSegDat, pbPrevSegDat);
- return true;
-#else
- return false;
-#endif // TRACING
-}
-
-
-bool GrTableManager::WriteXmlAssocLog(std::ostream * pstrmLog,
- GrCharStream * pchstrm, Segment * psegRet)
-{
-#ifdef TRACING
- if (!pstrmLog)
- return false;
-
- std::ostream & strmOut = *pstrmLog;
- LogFinalPositions(strmOut);
-
- LogXmlTagOpen(strmOut, "Mappings", 1, true);
- LogXmlTagPostAttrs(strmOut, true);
-
- //psegRet->LogXmlUnderlyingToSurface(strmOut, this, pchstrm, 2);
- //psegRet->LogXmlSurfaceToUnderlying(strmOut, this, 2);
-
- LogXmlTagClose(strmOut, "Mappings", 1, true);
-
- strmOut << "\n";
- LogXmlTagClose(strmOut, "GraphiteTraceLog", 0, true);
-
- return true;
-#else
- return false;
-#endif // TRACING
-}
-
-#ifdef TRACING
-
-/*----------------------------------------------------------------------------------------------
- Output a file showing a log of the transduction process and the resulting segment.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::WriteXmlLogAux(std::ostream & strmOut,
- GrCharStream * pchstrm, Segment * psegRet,
- int cbPrevSegDat, byte * pbPrevSegDat)
-{
- strmOut
- << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<!DOCTYPE GraphiteTraceLog SYSTEM \"GraphiteTraceLog.dtd\">\n"
- << "\n";
-
- LogXmlTagOpen(strmOut, "GraphiteTraceLog", 0, true);
- LogXmlTagPostAttrs(strmOut, true);
- strmOut << "\n";
-
- LogXmlTagOpen(strmOut, "SegmentRun", 1, true);
- LogXmlTagAttr(strmOut, "stringOffset", pchstrm->Min(), 0);
- LogXmlTagPostAttrs(strmOut, true);
-
- if (cbPrevSegDat == 0)
- LogXmlUnderlying(strmOut, pchstrm, 0, 2);
- else
- {
- Assert(*(pbPrevSegDat + 4) == 0); // skip offset for first pass
- LogXmlUnderlying(strmOut, pchstrm, *(pbPrevSegDat + 3), 2);
- }
-
- //LogXmlPass1Input(strmOut);
-
- for (int ipass = 0; ipass < m_cpass; ipass++)
- {
- if (cbPrevSegDat == 0)
- LogXmlPass(strmOut, ipass, 0, 2);
- else
- LogXmlPass(strmOut, ipass, *(pbPrevSegDat + 4 + ipass), 2);
- }
-
- LogXmlTagClose(strmOut, "SegmentRun", 1, true);
- strmOut << "\n";
-
- // Don't do this until after we've logged the associations.
- //LogXmlTagClose(strmOut, "GraphiteTraceLog", 0, true);
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out a log of the underlying input.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlUnderlying(std::ostream & strmOut, GrCharStream * pchstrm,
- int cchwBackup, size_t nIndent)
-{
- LogXmlTagOpen(strmOut, "Input", nIndent, true);
- LogXmlTagPostAttrs(strmOut, true);
-
- LogXmlUnderlyingAux(strmOut, pchstrm, cchwBackup, -1, nIndent,
- true, // text
- true, // features
- true, // color
- false, // string offset
- false, // ligature components
- false); // glyph associations
-
- LogXmlTagClose(strmOut, "Input", nIndent, true);
-}
-
-void GrTableManager::LogXmlUnderlyingAux(std::ostream & strmOut, GrCharStream * pchstrm,
- int cch32Backup, int cch32Lim, size_t nIndent,
- bool fLogText, bool fLogFeatures, bool fLogColor, bool fLogStrOff, bool fLogLig, bool fLogGlyphs)
-{
- int rgnChars[MAX_SLOTS];
- bool rgfNewRun[MAX_SLOTS];
- std::fill_n(rgfNewRun, MAX_SLOTS, false);
- GrFeatureValues rgfval[MAX_SLOTS];
- int cchwMaxRawChars;
-
- int cch32 = pchstrm->GetLogData(this, rgnChars, rgfNewRun, rgfval,
- cch32Backup, &cchwMaxRawChars);
- cch32 = min(cch32, MAX_SLOTS);
- if (cch32Lim > -1)
- cch32 = min(cch32Lim, cch32);
-
- int ichw;
-
- // For UTF-8 and surrogate representation:
- int rgchwChars1[MAX_SLOTS];
- utf16 rgchwChars2[MAX_SLOTS];
- utf16 rgchwChars3[MAX_SLOTS];
- utf16 rgchwChars4[MAX_SLOTS];
- utf16 rgchwChars5[MAX_SLOTS];
- utf16 rgchwChars6[MAX_SLOTS];
- utf16 rgiRawString[MAX_SLOTS]; // indices from underlying slots to text-source chars (0-based)
-
- int rgichwRaw[MAX_SLOTS]; // index of input char with in the given UTF32, 1-based
-
- if (cchwMaxRawChars > 1)
- {
- cchwMaxRawChars = min(cchwMaxRawChars, 6); // max of 6 raw (UTF-8 or UTF-16) chars per slot
- pchstrm->GetLogDataRaw(this, cch32, cch32Backup, cchwMaxRawChars,
- rgchwChars1, rgchwChars2, rgchwChars3, rgchwChars4, rgchwChars5, rgchwChars6,
- rgichwRaw);
- }
- else
- {
- for (ichw = 0; ichw < cch32; ichw++)
- {
- rgichwRaw[ichw] = 1;
- rgchwChars1[ichw] = rgnChars[ichw];
- rgchwChars2[ichw] = 0;
- rgchwChars3[ichw] = 0;
- rgchwChars4[ichw] = 0;
- rgchwChars5[ichw] = 0;
- rgchwChars6[ichw] = 0;
- }
- }
-
- int ichUtf32 = 0;
- ichw = 0;
- while (ichUtf32 < cch32)
- {
- if (rgichwRaw[ichw] == 1)
- {
- rgiRawString[ichUtf32++] = (utf16)ichw;
- }
- ichw++;
- }
-
- int ichwFeat = 0;
- for (ichw = 0; ichw < cch32; ichw++)
- {
- if (rgfNewRun[ichw])
- ichwFeat = ichw; // because rgfval only saves features for first of run
-
- // See if there are any features.
- bool fFeatures = false;
- size_t ifeat;
- for (ifeat = 0; fLogFeatures && ifeat < kMaxFeatures; ifeat++)
- {
- if (rgfval[ichwFeat].FeatureValue(ifeat) != 0)
- {
- fFeatures = true;
- break;
- }
- }
-
- bool fContent = fFeatures;
-
- LogXmlTagOpen(strmOut, "Char", nIndent+1, fContent);
-
- LogXmlTagAttr(strmOut, "index", rgiRawString[ichw] - cch32Backup, 0);
- LogXmlTagAttrHex(strmOut, "usv", rgnChars[ichw], 0);
-
- if (fLogText)
- {
- char rgch[20];
- rgch[0] = (char)rgnChars[ichw];
- rgch[1] = 0;
- if (rgnChars[ichw] < 0x0100 && rgchwChars2[ichw] == 0) // ANSI
- LogXmlTagAttr(strmOut, "text", rgch);
- else if (rgnChars[ichw] == knLRM)
- LogXmlTagAttr(strmOut, "text", "<LRM>");
- else if (rgnChars[ichw] == knRLM)
- LogXmlTagAttr(strmOut, "text", "<RLM>");
- else if (rgnChars[ichw] == knLRO)
- LogXmlTagAttr(strmOut, "text", "<LRO>");
- else if (rgnChars[ichw] == knRLO)
- LogXmlTagAttr(strmOut, "text", "<RLO>");
- else if (rgnChars[ichw] == knLRE)
- LogXmlTagAttr(strmOut, "text", "<LRE>");
- else if (rgnChars[ichw] == knRLE)
- LogXmlTagAttr(strmOut, "text", "<RLE>");
- else if (rgnChars[ichw] == knPDF)
- LogXmlTagAttr(strmOut, "text", "<PDF>");
- }
-
- if (fLogStrOff)
- LogXmlTagAttr(strmOut, "stringOffset", pchstrm->Min() + rgiRawString[ichw] - cch32Backup, 0);
-
- if (rgchwChars2[ichw] != 0)
- {
- std::string strHex = HexString(rgchwChars1[ichw], rgchwChars2[ichw], rgchwChars3[ichw],
- rgchwChars4[ichw], rgchwChars5[ichw], rgchwChars6[ichw]);
- if (pchstrm->TextSrc()->utfEncodingForm() == kutf8)
- LogXmlTagAttr(strmOut, "textSourceUtf8", strHex.c_str());
- else
- LogXmlTagAttr(strmOut, "textSourceUtf16", strHex.c_str());
- }
-
- if (fLogColor)
- {
- IColorTextSource * tscolor = dynamic_cast<IColorTextSource *>(pchstrm->TextSrc());
- if (tscolor)
- {
- int clrFore, clrBack;
- tscolor->getColors(ichw, &clrFore, &clrBack);
- LogXmlTagColor(strmOut, "color", clrFore, false);
- LogXmlTagColor(strmOut, "background", clrBack, true);
- }
- }
-
- if (fLogLig)
- {
-
- }
-
-//if (fLogLig || fLogGlyphs)
-//{
-// size_t cassocs = 0;
-// int fLigs = false;
-// int ichw;
-// for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
-// {
-// if (m_prgpvisloutAssocs[ichw])
-// cassocs = max(cassocs, m_prgpvisloutAssocs[ichw]->size());
-// if (m_prgisloutLigature[ichw] != kNegInfinity)
-// fLigs = true;
-// }
-//}
-
- LogXmlTagPostAttrs(strmOut, fContent);
-
- if (fLogFeatures)
- {
- for (ifeat = 0; ifeat < kMaxFeatures; ifeat++)
- {
- if (rgfval[ichwFeat].FeatureValue(ifeat) != 0)
- {
- GrFeature * pfeat = Feature(ifeat);
-
- LogXmlTagOpen(strmOut, "Feature", nIndent+2, false);
- LogXmlTagAttr(strmOut, "id", pfeat->ID());
- LogXmlTagAttr(strmOut, "value", rgfval[ichwFeat].FeatureValue(ifeat));
- //LogXmlTagPostAttrs(strmOut, false);
- LogXmlTagClose(strmOut, "Feature", nIndent+1, false);
- }
- }
- }
-
- if (fLogGlyphs)
- {
- }
-
- LogXmlTagClose(strmOut, "Char", nIndent+1, fContent);
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Output the the results of pass.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlPass(std::ostream & strmOut, int ipass, int cslotSkipped, int nIndent)
-{
- strmOut << "\n";
-
- GrPass * ppass = Pass(ipass);
- GrSlotStream * psstrmIn = (ipass == 0) ? NULL : InputStream(ipass);
- GrSlotStream * psstrmOut = OutputStream(ipass);
-
- int islot;
- // Mark each slot with its index in the input and output streams.
- for (islot = 0; ipass > 0 && islot < psstrmIn->ReadPos(); islot++)
- psstrmIn->SlotAt(islot)->m_islotTmpIn = islot;
-
- for (islot = 0; islot < psstrmOut->WritePos(); islot++)
- psstrmOut->SlotAt(islot)->m_islotTmpOut = islot;
-
- LogXmlTagOpen(strmOut, "Pass", nIndent, true);
- LogXmlTagAttr(strmOut, "number", ipass);
-
- std::string strType;
- if (dynamic_cast<GrGlyphGenPass *>(ppass))
- strType = "glyphGeneration";
- else if (dynamic_cast<GrBidiPass *>(ppass))
- strType = "bidi";
- else if (dynamic_cast<GrSubPass *>(ppass))
- {
- if (ipass >= m_ipassJust1)
- strType = "justification";
- else
- strType = "substitution";
- }
- else if (dynamic_cast<GrPosPass *>(ppass))
- strType = "positioning";
- else if (dynamic_cast<GrLineBreakPass *>(ppass))
- strType = "linebreak";
- LogXmlTagAttr(strmOut, "type", strType.c_str());
-
- LogXmlTagPostAttrs(strmOut, true);
-
- if (!dynamic_cast<GrBidiPass *>(ppass) && !dynamic_cast<GrGlyphGenPass *>(ppass))
- {
- LogXmlTagOpen(strmOut, "RulesMatched", nIndent+1, true);
- LogXmlTagPostAttrs(strmOut, true);
- ppass->LogXmlRules(strmOut, this, psstrmIn, nIndent+2);
- LogXmlTagClose(strmOut, "RulesMatched", nIndent+1, true);
- }
-
- bool fJustWidths = false;
- if (ipass == m_ipassJust1 - 1 && ShouldLogJustification()
- && m_engst.m_jmodi == kjmodiJustify)
- {
- fJustWidths = true;
- }
-
- LogXmlTagOpen(strmOut, "Output", nIndent+1, true);
- LogXmlTagPostAttrs(strmOut, true);
- bool fPreJust = (!fJustWidths && ipass == m_ipassJust1 - 1 && ShouldLogJustification());
- bool fPostJust = (fJustWidths || ipass == m_ipassJust1 && ShouldLogJustification());
- ppass->LogXmlGlyphs(strmOut, this, psstrmOut, m_ipassJust1, fPreJust, fPostJust, cslotSkipped, nIndent+2);
- LogXmlTagClose(strmOut, "Output", nIndent+1, true);
-
- LogXmlTagClose(strmOut, "Pass", nIndent, true);
-
-#ifdef XMLOMIT
-
- // If this was the pass just before the justification routines get run, output a
- // special line that just shows the results, ie, the values of justify.width.
- // TODO: adjust this when measure mode get functioning.
- if (ipass == m_ipassJust1 - 1 && ShouldLogJustification()
- && m_engst.m_jmodi == kjmodiJustify)
- {
- strmOut << "\nJUSTIFICATION\n\n";
- LogSlotHeader(strmOut, psstrmOut->WritePos(), SP_PER_SLOT, LEADING_SP);
- LogSlotGlyphs(strmOut, psstrmOut);
- LogAttributes(strmOut, ipass, true);
- }
-
-#endif // XMLOMIT
-
-}
-
-/*----------------------------------------------------------------------------------------------
- Write the list of rules fired and failed for a given pass.
-----------------------------------------------------------------------------------------------*/
-void GrPass::LogXmlRules(std::ostream & strmOut, GrTableManager * ptman,
- GrSlotStream * psstrmIn, int nIndent)
-{
- m_pzpst->LogXmlRules(strmOut, ptman, psstrmIn, nIndent);
-}
-
-void PassState::LogXmlRules(std::ostream & strmOut, GrTableManager * ptman,
- GrSlotStream * psstrmIn, int nIndent)
-{
- if (m_crulrec == 0)
- {
- ptman->LogXmlComment(strmOut, "none", nIndent);
- return;
- }
-
- for (int irulrec = 0; irulrec < m_crulrec; irulrec++)
- {
- bool fSourceAvailable = false;
-
- ptman->LogXmlTagOpen(strmOut, "Rule", nIndent, fSourceAvailable);
-
- ptman->LogXmlTagAttr(strmOut, "slot", m_rgrulrec[irulrec].m_islot);
-
- if (m_rgrulrec[irulrec].m_irul == PassState::kHitMaxRuleLoop)
- ptman->LogXmlTagAttr(strmOut, "hitMaxRuleLoop", "true");
- else if (m_rgrulrec[irulrec].m_irul == PassState::kHitMaxBackup)
- ptman->LogXmlTagAttr(strmOut, "hitMaxBackup", "true");
- else
- {
- ptman->LogXmlTagAttr(strmOut, "debugNumber", m_rgrulrec[irulrec].m_irul);
- ptman->LogXmlTagAttr(strmOut, "fired", (m_rgrulrec[irulrec].m_fFired) ? "true" : "false");
- }
-
- ptman->LogXmlTagPostAttrs(strmOut, fSourceAvailable);
-
- // TODO: output Source
-
- ptman->LogXmlTagClose(strmOut, "Rule", nIndent, fSourceAvailable);
- }
-}
-
-void GrPass::LogXmlGlyphs(std::ostream & strmOut, GrTableManager * ptman, GrSlotStream * psstrmOut,
- int ipassJust1, bool fPreJust, bool fPostJust, int cslotSkipped, int nIndent)
-{
- GrBidiPass * ppassBidi = dynamic_cast<GrBidiPass *>(this);
- GrBidiPass * ppassBidiNext = (m_ipass + 1 >= ptman->NumberOfPasses()) ?
- NULL :
- dynamic_cast<GrBidiPass *>(ptman->Pass(m_ipass + 1));
- m_pzpst->LogXmlGlyphs(strmOut, ptman, psstrmOut, ipassJust1, fPreJust, fPostJust,
- (ppassBidi != NULL), (ppassBidiNext != NULL), cslotSkipped, nIndent);
-}
-
-void PassState::LogXmlGlyphs(std::ostream & strmOut, GrTableManager * ptman, GrSlotStream * psstrmOut,
- int ipassJust1, bool fPreJust, bool fPostJust, bool fBidi, bool fBidiNext, int cslotSkipped,
- int nIndent)
-{
- ptman->LogXmlTagOpen(strmOut, "Output", nIndent, true);
- ptman->LogXmlTagPostAttrs(strmOut, true);
-
- for (int islot = 0; islot < psstrmOut->WritePos() + 1; islot++) // +1 allows us to handle final deletion
- {
- if (islot > MAX_SLOTS)
- break;
-
- for (int islotDel = 0; islotDel < m_rgcslotDeletions[islot]; islotDel++)
- {
- ptman->LogXmlTagOpen(strmOut, "Glyph", nIndent+1, false);
- ptman->LogXmlTagAttr(strmOut, "slot", "deleted");
- ptman->LogXmlTagPostAttrs(strmOut, false);
- ptman->LogXmlTagClose(strmOut, "Glyph", nIndent+1, false);
- }
- if (islot >= psstrmOut->WritePos())
- break;
-
- GrSlotState * pslot = psstrmOut->SlotAt(islot);
-
- bool fMod = (pslot->PassModified() >= m_ipass && m_ipass > 0);
- if (fBidi || fBidiNext)
- fMod = true;
-
- ptman->LogXmlTagOpen(strmOut, "Glyph", nIndent+1, fMod);
-
- ptman->LogXmlTagAttr(strmOut, "slot", islot);
- if (pslot->GlyphID() == ptman->LBGlyphID())
- ptman->LogXmlTagAttr(strmOut, "gid", "linebreak");
- else
- ptman->LogXmlTagAttr(strmOut, "gid", pslot->GlyphID());
- if (pslot->GlyphID() != pslot->ActualGlyphForOutput(ptman))
- ptman->LogXmlTagAttr(strmOut, "actual", pslot->ActualGlyphForOutput(ptman));
- if (m_rgfInsertion[islot])
- ptman->LogXmlTagAttr(strmOut, "inserted", "true");
- if (islot < cslotSkipped)
- ptman->LogXmlTagAttr(strmOut, "nextPassSkips", "true");
-
- ptman->LogXmlTagPostAttrs(strmOut, fMod);
-
- if (fMod)
- {
- pslot->LogXmlAttributes(strmOut, ptman, psstrmOut, m_ipass, islot,
- fPreJust, fPostJust, fBidi, fBidiNext, nIndent+2);
- }
-
- ptman->LogXmlTagClose(strmOut, "Glyph", nIndent+1, fMod);
- }
-
- ptman->LogXmlTagClose(strmOut, "Output", nIndent, true);
-}
-
-/*----------------------------------------------------------------------------------------------
- Write out the attributes that have changes.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::LogXmlAttributes(std::ostream & strmOut, GrTableManager * ptman,
- GrSlotStream * psstrmOut, int ipass,
- int islot, bool fPreJust, bool fPostJust, bool fBidi, bool fBidiNext, int nIndent)
-{
- // To handle reprocessing, in which case there may be a chain of slots modified
- // in the same pass:
- GrSlotState * pslotPrev = PrevState();
- while (pslotPrev && pslotPrev->PassModified() == PassModified())
- pslotPrev = pslotPrev->m_pslotPrevState;
-
- bool * prgfMods = new bool[kslatMax + ptman->NumUserDefn() - 1];
- memset(prgfMods, 0, (kslatMax + ptman->NumUserDefn() - 1) * sizeof(bool));
- int ccomp;
- int cassoc;
- SlotAttrsModified(prgfMods, fPreJust, &ccomp, &cassoc); // just for this one slot
-
- if (fPreJust)
- prgfMods[kslatJWidth] = false;
- else if (fPostJust)
- prgfMods[kslatJWidth] = true;
-
- //if (fJustWidths)
- //{}
-
- bool fLogAssocs = false;
-
- for (int slat = 0; slat < kslatMax + ptman->NumUserDefn() - 1; slat++)
- {
- if (!prgfMods[slat] && (slat != kslatDir || (!fBidi && !fBidiNext)))
- continue;
-
- if (slat == kslatPosX)
- continue;
- if (slat == kslatPosY)
- continue;
-
- std::string strAttrName;
- switch (slat)
- {
- case kslatAdvX: strAttrName = "advance.x"; break;
- case kslatAdvY: strAttrName = "advance.y"; break;
- case kslatAttTo: strAttrName = "att.to"; break;
- case kslatAttAtX: strAttrName = "att.at.x"; break;
- case kslatAttAtY: strAttrName = "att.at.y"; break;
- case kslatAttAtGpt: strAttrName = "att.at.gpt"; break;
- case kslatAttAtXoff: strAttrName = "att.at.xoff"; break;
- case kslatAttAtYoff: strAttrName = "att.at.yoff"; break;
- case kslatAttWithX: strAttrName = "att.with.x"; break;
- case kslatAttWithY: strAttrName = "att.with.y"; break;
- case kslatAttWithGpt: strAttrName = "att.with.gpt"; break;
- case kslatAttWithXoff: strAttrName = "att.with.xoff"; break;
- case kslatAttWithYoff: strAttrName = "att.with.yoff"; break;
- case kslatAttLevel: strAttrName = "att.level"; break;
- case kslatBreak: strAttrName = "breakweight"; break;
- case kslatCompRef: strAttrName = "component"; break; // << iIndex + 1 - 1-based
- case kslatDir: strAttrName = "dir"; break;
- case kslatInsert: strAttrName = "insert"; break;
- case kslatMeasureSol: strAttrName = "measure.sol"; break;
- case kslatMeasureEol: strAttrName = "measure.eol"; break;
- case kslatJStretch: strAttrName = "just.stretch"; break;
- case kslatJShrink: strAttrName = "just.shrink"; break;
- case kslatJStep: strAttrName = "just.step"; break;
- case kslatJWeight: strAttrName = "just.weight"; break;
- case kslatJWidth: strAttrName = "just.width"; break;
- case kslatPosX:
- case kslatPosY:
- Assert(false);
- break;
- case kslatShiftX: strAttrName = "shift.x"; break;
- case kslatShiftY: strAttrName = "shift.y"; break;
- default:
- if (kslatUserDefn <= slat &&
- slat < kslatUserDefn + ptman->NumUserDefn())
- {
- strAttrName.assign("user");
- char rgch[20];
- itoa(slat - kslatUserDefn + 1, rgch, 10); // 1-based
- strAttrName.append(rgch);
- }
- else
- {
- // Invalid attribute:
- Warn("bad slot attribute");
- break;
- }
- }
-
- fLogAssocs = (fLogAssocs || prgfMods[slat]);
-
- if (slat == kslatCompRef)
- {
- for (int icomp = 0; icomp < ccomp; icomp++)
- {
- ptman->LogXmlTagOpen(strmOut, "Attribute", nIndent, false);
- ptman->LogXmlTagAttr(strmOut, "name", strAttrName.c_str());
- ptman->LogXmlTagAttr(strmOut, "index", icomp+1);
- int nValue = GetSlotAttrValue(strmOut, ptman, ipass, slat, icomp, fPreJust, fPostJust);
- ptman->LogXmlTagAttr(strmOut, "newValue", nValue);
- ptman->LogXmlTagPostAttrs(strmOut, false);
- ptman->LogXmlTagClose(strmOut, "Attribute", nIndent, false);
- }
- }
- else
- {
- std::string strValue = "newValue";
- if ((!prgfMods[slat] && fBidiNext) || fBidi)
- strValue = "value";
-
- ptman->LogXmlTagOpen(strmOut, "Attribute", nIndent, false);
- ptman->LogXmlTagAttr(strmOut, "name", strAttrName.c_str());
- int nValue = GetSlotAttrValue(strmOut, ptman, ipass, slat, 0, fPreJust, fPostJust);
- switch (slat)
- {
- case kslatDir: ptman->LogXmlDirCode(strmOut, strValue.c_str(), nValue);break;
- case kslatBreak: ptman->LogXmlBreakWeight(strmOut, "newValue", nValue); break;
- default: ptman->LogXmlTagAttr(strmOut, "newValue", nValue); break;
- }
- ptman->LogXmlTagPostAttrs(strmOut, false);
- ptman->LogXmlTagClose(strmOut, "Attribute", nIndent, false);
- }
- }
-
- if (fBidi)
- {
- // Output final directionality level
- ptman->LogXmlTagOpen(strmOut, "Attribute", nIndent, false);
- ptman->LogXmlTagAttr(strmOut, "name", "directionLevel");
- ptman->LogXmlTagAttr(strmOut, "value", DirLevel());
- ptman->LogXmlTagPostAttrs(strmOut, false);
- ptman->LogXmlTagClose(strmOut, "Attribute", nIndent, false);
- }
-
- if (m_vpslotAssoc.size() > 1)
- fLogAssocs = true; // multiple associations
- else if (m_vpslotAssoc.size() == 1)
- {
- // association change from previous stream
- GrSlotState * pslotAssoc = AssocSlot(0);
- if (pslotAssoc == NULL || pslotAssoc->m_islotTmpIn != islot)
- fLogAssocs = true;
- }
- if (fLogAssocs)
- {
- std::string strAssocs;
- char rgch[20];
- for (size_t iassoc = 0; iassoc < m_vpslotAssoc.size(); iassoc++)
- {
- GrSlotState * pslotAssoc = AssocSlot(iassoc);
- if (pslotAssoc)
- {
- int n = pslotAssoc->m_islotTmpIn;
- memset(rgch,0,20);
- itoa(n,rgch,10);
- if (iassoc > 0)
- strAssocs.append(" ");
- strAssocs.append(rgch);
- }
- }
- if (strAssocs.length() == 0)
- strAssocs.assign("??");
- ptman->LogXmlTagOpen(strmOut, "Associations", nIndent, false);
- ptman->LogXmlTagAttr(strmOut, "slots", strAssocs.c_str());
- //ptman->LogXmlTagPostAttrs(strmOut, false);
- ptman->LogXmlTagClose(strmOut, "Associations", nIndent, false);
- }
-
- delete prgfMods;
-}
-
-#if XMLOMIT
-/*----------------------------------------------------------------------------------------------
- Write out the final positions.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogFinalPositions(std::ostream & strmOut)
-{
- GrSlotStream * psstrm = OutputStream(m_cpass - 1);
-
- strmOut << "x position ";
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- if (pslot->IsLineBreak(LBGlyphID()))
- {
- strmOut << " ";
- continue;
- }
- LogInTable(strmOut, pslot->XPosition());
- }
- strmOut << "\n";
-
- strmOut << "y position ";
- for (int islot = 0; islot < psstrm->WritePos(); islot++)
- {
- GrSlotState * pslot = psstrm->SlotAt(islot);
- if (pslot->IsLineBreak(LBGlyphID()))
- {
- strmOut << " ";
- continue;
- }
- LogInTable(strmOut, pslot->YPosition());
- }
- strmOut << "\n";
-}
-
-#endif // XMLOMIT
-
-/*----------------------------------------------------------------------------------------------
- Log the value of the slot attribute for the given slot. Assume it has changed.
-----------------------------------------------------------------------------------------------*/
-int GrSlotState::GetSlotAttrValue(std::ostream & strmOut, GrTableManager * ptman,
- int ipass, int slat, int iIndex, bool fPreJust, bool fPostJust)
-{
- switch (slat)
- {
- case kslatAdvX:
- return int(m_mAdvanceX);
- case kslatAdvY:
- return int(m_mAdvanceY);
-
- case kslatAttTo:
- return m_srAttachTo;
-
- case kslatAttAtX: // always do these in pairs
- return m_mAttachAtX;
- case kslatAttAtY:
- return m_mAttachAtY;
- case kslatAttAtGpt:
- return m_nAttachAtGpoint;
-
- case kslatAttAtXoff: // always do these in pairs
- return m_mAttachAtXOffset;
- case kslatAttAtYoff:
- return m_mAttachAtYOffset;
-
- case kslatAttWithX: // always do these in pairs
- return m_mAttachWithX;
- case kslatAttWithY:
- return m_mAttachWithY;
-
- case kslatAttWithGpt:
- return m_nAttachWithGpoint;
-
- case kslatAttWithXoff: // always do these in pairs
- return m_mAttachWithXOffset;
- case kslatAttWithYoff:
- return m_mAttachWithYOffset;
-
- case kslatAttLevel:
- return m_nAttachLevel;
-
- case kslatBreak:
- return m_lb;
-
- case kslatDir:
- return m_dirc;
-
- case kslatInsert:
- return m_fInsertBefore;
-
- case kslatShiftX:
- return m_mShiftX;
- case kslatShiftY:
- return m_mShiftY;
- case kslatMeasureSol:
- return m_mMeasureSol;
- case kslatMeasureEol:
- return m_mMeasureEol;
- case kslatJStretch:
- return m_mJStretch0;
- case kslatJShrink:
- return m_mJShrink0;
- case kslatJStep:
- return m_mJStep0;
- case kslatJWeight:
- return m_nJWeight0;
- case kslatJWidth:
- return m_mJWidth0;
-
- case kslatCompRef:
- {
- GrSlotState * pslotComp = reinterpret_cast<GrSlotState *>(CompRef(iIndex));
- return pslotComp->m_islotTmpIn;
- }
-
- default:
- if (kslatUserDefn <= slat && slat <= kslatUserDefn + m_cnUserDefn)
- {
- int iTmp = slat - kslatUserDefn;
- return UserDefn(iTmp);
- }
- else
- gAssert(false);
- }
-
- return 0;
-}
-
-#endif // TRACING
-
-
-/*----------------------------------------------------------------------------------------------
- Write out the final underlying-to-surface associations.
-----------------------------------------------------------------------------------------------*/
-void Segment::LogXmlUnderlyingToSurface(std::ostream & strmOut, GrTableManager * ptman,
- GrCharStream * pchstrm, int nIndent)
-{
-#ifdef TRACING
-
- ptman->LogXmlTagOpen(strmOut, "UnderlyingToSurface", nIndent, true);
- ptman->LogXmlTagPostAttrs(strmOut, true);
-
- ptman->LogXmlUnderlyingAux(strmOut, pchstrm, -m_ichwAssocsMin, (m_ichwAssocsLim - m_ichwAssocsMin),
- nIndent+1,
- true, // text
- false, // features
- false, // color
- true, // string offset
- true, // ligature components
- true // glyph associations
- );
-
- ptman->LogXmlTagClose(strmOut, "UnderlyingToSurface", nIndent, true);
-
-
-#ifdef XMLOMIT
- ptman->LogXmlTagOpen(strmOut, "UnderlyingToSurface", nIndent, true);
-
- size_t cassocs = 0;
- int fLigs = false;
- int ichw;
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (m_prgpvisloutAssocs[ichw])
- cassocs = max(cassocs, m_prgpvisloutAssocs[ichw]->size());
- if (m_prgisloutLigature[ichw] != kNegInfinity)
- fLigs = true;
- }
-
- ptman->LogUnderlyingHeader(strmOut, pchstrm->Min(), (pchstrm->Min() + m_ichwAssocsLim),
- -m_ichwAssocsMin, NULL);
-
- int rgnChars[MAX_SLOTS];
- bool rgfNewRun[MAX_SLOTS];
- std::fill_n(rgfNewRun, MAX_SLOTS, false);
- GrFeatureValues rgfval[MAX_SLOTS];
- int cchwMaxRawChars;
-
- int cchw = pchstrm->GetLogData(ptman, rgnChars, rgfNewRun, rgfval,
- -m_ichwAssocsMin, &cchwMaxRawChars);
- cchw = min(cchw, MAX_SLOTS);
-
- utf16 rgchwChars2[MAX_SLOTS];
- utf16 rgchwChars3[MAX_SLOTS];
- utf16 rgchwChars4[MAX_SLOTS];
- utf16 rgchwChars5[MAX_SLOTS];
- utf16 rgchwChars6[MAX_SLOTS];
- int rgcchwRaw[MAX_SLOTS];
- if (cchwMaxRawChars > 1)
- {
- cchwMaxRawChars = min(cchwMaxRawChars, 6);
- pchstrm->GetLogDataRaw(ptman, cchw, -m_ichwAssocsMin, cchwMaxRawChars,
- rgnChars, rgchwChars2, rgchwChars3, rgchwChars4, rgchwChars5, rgchwChars6,
- rgcchwRaw);
- }
- else
- {
- for (ichw = 0 ; ichw <(m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- rgcchwRaw[ichw] = 1;
- rgchwChars2[ichw] = 0;
- rgchwChars3[ichw] = 0;
- rgchwChars4[ichw] = 0;
- rgchwChars5[ichw] = 0;
- rgchwChars6[ichw] = 0;
- }
- }
-
- // Text
- strmOut << "Text: "; // 15 spaces
- int inUtf32 = 0;
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- utf16 chw, chwNext;
- switch (rgcchwRaw[ichw])
- {
- default:
- case 1: chw = utf16(rgnChars[inUtf32]); chwNext = rgchwChars2[inUtf32]; break;
- case 2: chw = rgchwChars2[inUtf32]; chwNext = rgchwChars3[inUtf32]; break;
- case 3: chw = rgchwChars3[inUtf32]; chwNext = rgchwChars4[inUtf32]; break;
- case 4: chw = rgchwChars4[inUtf32]; chwNext = rgchwChars5[inUtf32]; break;
- case 5: chw = rgchwChars5[inUtf32]; chwNext = rgchwChars6[inUtf32]; break;
- case 6: chw = rgchwChars6[inUtf32]; chwNext = 0; break;
- }
- if (rgcchwRaw[ichw] == 1 && chwNext == 0 && chw < 0x0100) // ANSI
- strmOut << (char)chw << " "; // 6 spaces
- else
- strmOut << " "; // 7 spaces
- if (chwNext == 0)
- inUtf32++;
- }
- strmOut << "\n";
-
- // Unicode
- strmOut << "Unicode: ";
- inUtf32 = 0;
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- utf16 chw, chwNext;
- switch (rgcchwRaw[ichw])
- {
- default:
- case 1: chw = utf16(rgnChars[inUtf32]); chwNext = rgchwChars2[inUtf32]; break;
- case 2: chw = rgchwChars2[inUtf32]; chwNext = rgchwChars3[inUtf32]; break;
- case 3: chw = rgchwChars3[inUtf32]; chwNext = rgchwChars4[inUtf32]; break;
- case 4: chw = rgchwChars4[inUtf32]; chwNext = rgchwChars5[inUtf32]; break;
- case 5: chw = rgchwChars5[inUtf32]; chwNext = rgchwChars6[inUtf32]; break;
- case 6: chw = rgchwChars6[inUtf32]; chwNext = 0; break;
- }
- ptman->LogHexInTable(strmOut, chw, chwNext != 0);
- if (chwNext == 0)
- inUtf32++;
- }
- strmOut << "\n";
-
- strmOut << "before ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (rgcchwRaw[ichw] > 1)
- // continuation of Unicode codepoint
- strmOut << " ";
- else if (m_prgisloutBefore[ichw] == kNegInfinity)
- strmOut << "<-- ";
- else if (m_prgisloutBefore[ichw] == kPosInfinity)
- strmOut << "--> ";
- else
- ptman->LogInTable(strmOut, m_prgisloutBefore[ichw]);
- }
- strmOut <<"\n";
-
- for (int ix = 1; ix < signed(cassocs) - 1; ix++) //(cassocs > 2)
- {
- if (ix == 1)
- strmOut << "other ";
- else
- strmOut << " ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- std::vector<int> * pvislout = m_prgpvisloutAssocs[ichw];
- if (pvislout == NULL)
- strmOut << " ";
- else if (signed(pvislout->size()) <= ix)
- strmOut << " ";
- else if ((*pvislout)[ix] != m_prgisloutAfter[ichw])
- ptman->LogInTable(strmOut, (*pvislout)[ix]);
- else
- strmOut << " ";
- }
- strmOut << "\n";
- }
-
- strmOut << "after ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (rgcchwRaw[ichw] > 1)
- // continuation of Unicode codepoint
- strmOut << " ";
- else if (m_prgisloutAfter[ichw] == kNegInfinity)
- strmOut << "<-- ";
- else if (m_prgisloutAfter[ichw] == kPosInfinity)
- strmOut << "--> ";
- else
- ptman->LogInTable(strmOut, m_prgisloutAfter[ichw]);
- }
- strmOut <<"\n";
-
- if (fLigs)
- {
- strmOut << "ligature ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (rgcchwRaw[ichw] > 1)
- // continuation of Unicode codepoint
- strmOut << " ";
- else if (m_prgisloutLigature[ichw] != kNegInfinity)
- ptman->LogInTable(strmOut, m_prgisloutLigature[ichw]);
- else
- strmOut << " ";
- }
- strmOut << "\n";
-
- strmOut << "component ";
- for (ichw = 0; ichw < (m_ichwAssocsLim - m_ichwAssocsMin); ichw++)
- {
- if (rgcchwRaw[ichw] > 1)
- // continuation of Unicode codepoint
- strmOut << " ";
- else if (m_prgisloutLigature[ichw] != kNegInfinity)
- ptman->LogInTable(strmOut, m_prgiComponent[ichw] + 1); // 1-based
- else
- strmOut << " ";
- }
- strmOut << "\n";
- }
-
- strmOut << "\n";
-#endif // XMLOMIT
-#endif // TRACING
-
-}
-
-#ifdef XMLOMIT
-
-/*----------------------------------------------------------------------------------------------
- Write out the final surface-to-underlying associations.
-----------------------------------------------------------------------------------------------*/
-void Segment::LogSurfaceToUnderlying(GrTableManager * ptman, std::ostream & strmOut)
-{
-#ifdef TRACING
- strmOut << "\nSURFACE TO UNDERLYING MAPPINGS\n\n";
-
- ptman->LogSlotHeader(strmOut, m_cslout, SP_PER_SLOT, LEADING_SP);
-
- int ccomp = 0;
-
- strmOut << "Glyph IDs: ";
- int islout;
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->SpecialSlotFlag() == kspslLbInitial ||
- psloutTmp->SpecialSlotFlag() == kspslLbFinal)
- {
- strmOut << "# ";
- }
- else
- {
- ptman->LogHexInTable(strmOut, psloutTmp->GlyphID());
- ccomp = max(ccomp, psloutTmp->NumberOfComponents());
- }
- }
- strmOut << "\n";
-
- bool fAnyPseudos = false;
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->GlyphID() != psloutTmp->ActualGlyphForOutput(ptman))
- {
- fAnyPseudos = true;
- break;
- }
- }
- if (fAnyPseudos)
- {
- strmOut << "Actual glyphs: ";
- for (int islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->GlyphID() != psloutTmp->ActualGlyphForOutput(ptman))
- ptman->LogHexInTable(strmOut, psloutTmp->ActualGlyphForOutput(ptman));
- else
- strmOut << " ";
- }
- strmOut << "\n";
- }
-
- strmOut << "before ";
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->SpecialSlotFlag() == kspslLbInitial ||
- psloutTmp->SpecialSlotFlag() == kspslLbFinal)
- {
- strmOut << " ";
- }
- else
- ptman->LogInTable(strmOut, psloutTmp->BeforeAssoc());
- }
- strmOut << "\n";
-
- strmOut << "after ";
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->SpecialSlotFlag() == kspslLbInitial ||
- psloutTmp->SpecialSlotFlag() == kspslLbFinal)
- {
- strmOut << " ";
- }
- else
- ptman->LogInTable(strmOut, psloutTmp->AfterAssoc());
- }
- strmOut << "\n";
-
- for (int icomp = 0; icomp < ccomp; icomp++)
- {
- strmOut << "component " << icomp + 1 // 1=based
- << " ";
- for (islout = 0; islout < m_cslout; islout++)
- {
- GrSlotOutput * psloutTmp = m_prgslout + islout;
- if (psloutTmp->SpecialSlotFlag() == kspslLbInitial ||
- psloutTmp->SpecialSlotFlag() == kspslLbFinal)
- {
- strmOut << " ";
- }
- else if (icomp < psloutTmp->NumberOfComponents())
- ptman->LogInTable(strmOut, psloutTmp->UnderlyingComponent(icomp));
- else
- strmOut << " ";
- }
- strmOut << "\n";
- }
-#endif // TRACING
-}
-
-#ifdef TRACING
-/*----------------------------------------------------------------------------------------------
- Log the value of the association, if the slot changed.
-----------------------------------------------------------------------------------------------*/
-void GrSlotState::LogAssociation(GrTableManager * ptman,
- std::ostream & strmOut, int ipass, int iassoc, bool fBoth, bool fAfter)
-{
- if (m_ipassModified != ipass)
- {
- strmOut << " ";
- return;
- }
-
- if (fBoth)
- {
- GrSlotState * pslotBefore = (m_vpslotAssoc.size()) ? m_vpslotAssoc[0] : NULL;
- GrSlotState * pslotAfter = (m_vpslotAssoc.size()) ? m_vpslotAssoc.back() : NULL;
- // handle possible reprocessing
- while (pslotBefore && pslotBefore->PassModified() == m_ipassModified)
- pslotBefore = pslotBefore->m_pslotPrevState;
- while (pslotAfter && pslotAfter->PassModified() == m_ipassModified)
- pslotAfter = pslotAfter->m_pslotPrevState;
-
- int nBefore, nAfter;
-
-
- int csp = 4;
- if (pslotBefore)
- {
- nBefore = pslotBefore->m_islotTmpIn;
- strmOut << nBefore;
- if (nBefore > 99) csp--;
- if (nBefore > 9) csp--;
- }
- else
- {
- strmOut << "??";
- csp--;
- }
- if (pslotAfter)
- {
- nAfter = pslotAfter->m_islotTmpIn;
- strmOut << "/" << nAfter;
- if (nAfter > 99) csp--;
- if (nAfter > 9) csp--;
- }
- else
- {
- if (pslotBefore)
- {
- strmOut << "/" << "??";
- csp--;
- }
- else
- csp = 5;
- }
-
- for (int isp = 0; isp < csp; isp++)
- strmOut << " ";
- }
-
- else if (fAfter)
- {
- Assert(m_vpslotAssoc.size());
- GrSlotState * pslotAfter = m_vpslotAssoc.back();
- // handle possible reprocessing
- while (pslotAfter && pslotAfter->PassModified() == m_ipassModified)
- pslotAfter = pslotAfter->m_pslotPrevState;
-
- if (pslotAfter)
- {
- int nAfter = pslotAfter->m_islotTmpIn;
- ptman->LogInTable(strmOut, nAfter);
- }
- else
- strmOut << "?? ";
- }
- else if (iassoc < signed(m_vpslotAssoc.size()))
- {
- GrSlotState * pslot = m_vpslotAssoc[iassoc];
- // handle possible reprocessing
- while (pslot && pslot->PassModified() == m_ipassModified)
- pslot = pslot->m_pslotPrevState;
-
- if (pslot)
- {
- int n = pslot->m_islotTmpIn;
- ptman->LogInTable(strmOut, n);
- }
- else
- strmOut << "?? ";
- }
- else
- strmOut << " ";
-}
-
-
-/*----------------------------------------------------------------------------------------------
- Write a directionality code to the table.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogDirCodeInTable(std::ostream & strmOut, int dirc)
-{
- switch (dirc)
- {
- case kdircUnknown: strmOut << "??? "; break;
- case kdircNeutral: strmOut << "ON "; break;
- case kdircL: strmOut << "L "; break;
- case kdircR: strmOut << "R "; break;
- case kdircRArab: strmOut << "AR "; break;
- case kdircEuroNum: strmOut << "EN "; break;
- case kdircEuroSep: strmOut << "ES "; break;
- case kdircEuroTerm: strmOut << "ET "; break;
- case kdircArabNum: strmOut << "AN "; break;
- case kdircComSep: strmOut << "CS "; break;
- case kdircWhiteSpace: strmOut << "WS "; break;
- case kdircBndNeutral: strmOut << "BN "; break;
- case kdircNSM: strmOut << "NSM "; break;
- case kdircLRO: strmOut << "LRO "; break;
- case kdircRLO: strmOut << "RLO "; break;
- case kdircLRE: strmOut << "LRE "; break;
- case kdircRLE: strmOut << "RLE "; break;
- case kdircPDF: strmOut << "PDF "; break;
- case kdircPdfL: strmOut << "PDF-L "; break;
- case kdircPdfR: strmOut << "PDF-R "; break;
- case kdircLlb: strmOut << "L "; break;
- case kdircRlb: strmOut << "R "; break;
- default: LogInTable(strmOut, dirc); break;
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Write a breakweight code to the table.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogBreakWeightInTable(std::ostream & strmOut, int lb)
-{
- if (lb < 0)
- {
- lb = lb * -1;
- switch (lb)
- {
- case klbWsBreak: strmOut << "-ws "; break;
- case klbWordBreak: strmOut << "-word "; break;
- case klbHyphenBreak: strmOut << "-intra "; break;
- case klbLetterBreak: strmOut << "-lettr "; break;
- case klbClipBreak: strmOut << "-clip "; break;
- default: LogInTable(strmOut, lb); break;
- }
- }
- else
- {
- switch (lb)
- {
- case klbNoBreak: strmOut << "none "; break;
- case klbWsBreak: strmOut << "ws "; break;
- case klbWordBreak: strmOut << "word "; break;
- case klbHyphenBreak: strmOut << "intra "; break;
- case klbLetterBreak: strmOut << "letter "; break;
- case klbClipBreak: strmOut << "clip "; break;
- default: LogInTable(strmOut, lb); break;
- }
- }
-}
-
-#endif // TRACING
-
-#endif // XMLOMIT
-
-#ifdef TRACING
-/*----------------------------------------------------------------------------------------------
- Write an XML tag, leaving it open to possibly add attributes.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlTagOpen(std::ostream & strmOut, std::string strTag, size_t nIndent,
- bool fContent)
-{
- for (size_t i = 0; i < nIndent; i++)
- strmOut << " ";
-
- strmOut << "<" << strTag;
-}
-
-/*----------------------------------------------------------------------------------------------
- Write the termination of the opening XML tag.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlTagPostAttrs(std::ostream & strmOut,
- bool fContent)
-{
- if (fContent)
- strmOut << ">\n";
-}
-
-/*----------------------------------------------------------------------------------------------
- Write the closing form of the XML tag.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlTagClose(std::ostream & strmOut, std::string strTag, size_t nIndent,
- bool fContent)
-{
- if (fContent)
- {
- for (size_t i = 0; i < nIndent; i++)
- strmOut << " ";
- strmOut << "</" << strTag << ">\n";
- }
- else
- {
- strmOut << " />\n";
- }
-}
-
-/*----------------------------------------------------------------------------------------------
- Write an attribute/value pair inside of a tag.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlTagAttr(std::ostream & strmOut, std::string strAttr, int nValue,
- size_t nIndent)
-{
- char chBuf[20];
- itoa(nValue, chBuf, 10);
- LogXmlTagAttr(strmOut, strAttr, chBuf, nIndent);
-}
-
-void GrTableManager::LogXmlTagAttr(std::ostream & strmOut, std::string strAttr, const char * szValue,
- size_t nIndent)
-{
- if (nIndent > 0)
- {
- strmOut << "\n";
- for (size_t i = 0; i < nIndent + 2; i++)
- strmOut << " ";
- }
- else
- strmOut << " ";
-
- strmOut << strAttr << "=\"" << szValue << "\"";
-}
-
-void GrTableManager::LogXmlTagAttrHex(std::ostream & strmOut, std::string strAttr, int nValue,
- size_t nIndent)
-{
- char chBuf[20];
- chBuf[0] = chBuf[1] = chBuf[2] = '0';
- if (nValue < 0x10)
- itoa(nValue, chBuf+3, 16); // prepend 3 zeros
- else if (nValue < 0x100)
- itoa(nValue, chBuf+2, 16); // prepend 2 zeros
- else if (nValue < 0x1000)
- itoa(nValue, chBuf+1, 16); // prepend 1 zero
- else
- itoa(nValue, chBuf, 16);
- LogXmlTagAttr(strmOut, strAttr, chBuf, nIndent);
-}
-
-/*----------------------------------------------------------------------------------------------
- Concatenate the hex form of the given numbers into a string.
-----------------------------------------------------------------------------------------------*/
-std::string GrTableManager::HexString(std::vector<int> vn)
-{
- std::string strRet;
- for (size_t in = 0; in < vn.size(); in++)
- {
- char rgch[20];
- itoa(vn[in],rgch,16);
- strRet.append(rgch);
- if (in < vn.size() - 1)
- strRet.append(" ");
- }
- return strRet;
-}
-
-std::string GrTableManager::HexString(int n1, int n2, int n3, int n4, int n5, int n6)
-{
- std::vector<int> vn;
- if (n1 > 0)
- {
- vn.push_back(n1);
- if (n2 > 0)
- {
- vn.push_back(n2);
- if (n3 > 0)
- {
- vn.push_back(n3);
- if (n4 > 0)
- {
- vn.push_back(n4);
- if (n5 > 0)
- {
- vn.push_back(n5);
- if (n6 > 0)
- vn.push_back(n6);
- }
- }
- }
- }
- }
- return HexString(vn);
-}
-
-/*----------------------------------------------------------------------------------------------
- Write an attribute/value pair inside of a tag.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlTagColor(std::ostream & strmOut, std::string strAttr, int clrValue,
- bool fBack, size_t nIndent)
-{
- // Ignore black foreground and white background.
- if (!fBack && clrValue == kclrBlack)
- return;
- if (fBack && (clrValue == kclrWhite || clrValue == kclrTransparent))
- return;
-
- std::string strValue;
- char rgch[20];
- switch (clrValue)
- {
- case kclrBlack: strValue = "black"; break;
- case kclrWhite: strValue = "white"; break;
- case kclrRed: strValue = "red"; break;
- case kclrGreen: strValue = "green"; break;
- case kclrBlue: strValue = "blue"; break;
- case 0x00ffff: strValue = "yellow"; break;
- case 0xff00ff: strValue = "magenta"; break;
- case 0xffff00: strValue = "cyan"; break;
- default:
- rgch[0] = '#';
- itoa(clrValue, rgch+1, 16);
- strValue.assign(rgch);
- break;
- }
-
- LogXmlTagAttr(strmOut, strAttr, strValue.c_str(), nIndent);
-}
-
-/*----------------------------------------------------------------------------------------------
- Write a directionality code to the table.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlDirCode(std::ostream & strmOut, std::string strAttr, int dircValue,
- size_t nIndent)
-{
- std::string strValue;
- char rgch[20];
- switch (dircValue)
- {
- case kdircUnknown: strValue = "unknown"; break;
- case kdircNeutral: strValue = "ON"; break;
- case kdircL: strValue = "L"; break;
- case kdircR: strValue = "R"; break;
- case kdircRArab: strValue = "AR"; break;
- case kdircEuroNum: strValue = "EN"; break;
- case kdircEuroSep: strValue = "ES"; break;
- case kdircEuroTerm: strValue = "ET"; break;
- case kdircArabNum: strValue = "AN"; break;
- case kdircComSep: strValue = "CS"; break;
- case kdircWhiteSpace: strValue = "WS"; break;
- case kdircBndNeutral: strValue = "BN"; break;
- case kdircNSM: strValue = "NSM"; break;
- case kdircLRO: strValue = "LRO"; break;
- case kdircRLO: strValue = "RLO"; break;
- case kdircLRE: strValue = "LRE"; break;
- case kdircRLE: strValue = "RLE"; break;
- case kdircPDF: strValue = "PDF"; break;
- case kdircPdfL: strValue = "PDF-L"; break;
- case kdircPdfR: strValue = "PDF-R"; break;
- case kdircLlb: strValue = "L"; break;
- case kdircRlb: strValue = "R"; break;
- default:
- itoa(dircValue, rgch, 10);
- strValue.assign(rgch);
- break;
- }
- LogXmlTagAttr(strmOut, strAttr, strValue.c_str(), nIndent);
-}
-
-/*----------------------------------------------------------------------------------------------
- Write a breakweight code to the table.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlBreakWeight(std::ostream & strmOut, std::string strAttr, int lbValue,
- size_t nIndent)
-{
- std::string strValue;
- char rgch[20];
- if (lbValue < 0)
- {
- lbValue = lbValue * -1;
- switch (lbValue)
- {
- case klbWsBreak: strValue = "-ws"; break;
- case klbWordBreak: strValue = "-word"; break;
- case klbHyphenBreak: strValue = "-intra"; break;
- case klbLetterBreak: strValue = "-letter"; break;
- case klbClipBreak: strValue = "-clip"; break;
- default:
- itoa(lbValue * -1, rgch, 10);
- strValue.assign(rgch);
- break;
- }
- }
- else
- {
- switch (lbValue)
- {
- case klbNoBreak: strValue = "none"; break;
- case klbWsBreak: strValue = "ws"; break;
- case klbWordBreak: strValue = "word"; break;
- case klbHyphenBreak: strValue = "intra"; break;
- case klbLetterBreak: strValue = "letter"; break;
- case klbClipBreak: strValue = "clip"; break;
- default:
- itoa(lbValue, rgch, 10);
- strValue.assign(rgch);
- break;
- }
- }
- LogXmlTagAttr(strmOut, strAttr, strValue.c_str(), nIndent);
-}
-
-/*----------------------------------------------------------------------------------------------
- Add a comment to the log file.
-----------------------------------------------------------------------------------------------*/
-void GrTableManager::LogXmlComment(std::ostream & strmOut, std::string strComment,
- size_t nIndent)
-{
- for (size_t i = 0; i < nIndent; i++)
- strmOut << " ";
-
- strmOut << "<!-- " << strComment << " -->\n";
-}
-
-
-#endif // TRACING
-
-} // namespace gr
diff --git a/Build/source/libs/graphite-engine/src/segment/resource.h b/Build/source/libs/graphite-engine/src/segment/resource.h
deleted file mode 100644
index 775418f76bf..00000000000
--- a/Build/source/libs/graphite-engine/src/segment/resource.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by Graphite.rc
-//
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 101
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1000
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif