diff options
Diffstat (limited to 'Build/source/libs/graphite/engine-2.4/src/font')
7 files changed, 0 insertions, 3963 deletions
diff --git a/Build/source/libs/graphite/engine-2.4/src/font/FileFont.cpp b/Build/source/libs/graphite/engine-2.4/src/font/FileFont.cpp deleted file mode 100644 index 422687eba73..00000000000 --- a/Build/source/libs/graphite/engine-2.4/src/font/FileFont.cpp +++ /dev/null @@ -1,429 +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: FileFont.cpp -Responsibility: Keith Stribley -Last reviewed: Not yet. - -Description: - A Font is an object that represents a font-family + bold + italic setting, that contains - Graphite tables. -----------------------------------------------------------------------------------------------*/ - -#include "Main.h" - -#include "FontTableCache.h" -#include "FileFont.h" -#ifndef _MSC_VER -#include <stdio.h> -#endif - -// TBD do this properly -#define FUDGE_FACTOR 72 -#define fix26_6(x) (x >> 6) + (x & 32 ? (x > 0 ? 1 : 0) : (x < 0 ? -1 : 0)) - -namespace gr -{ - - -FileFont::FileFont() - : Font(), - m_pfile(NULL), - m_pTableCache(NULL), - m_mAscent(0), - m_mDescent(0), - m_mEmSquare(0), - m_pointSize(0), - m_dpiX(FUDGE_FACTOR), - m_dpiY(FUDGE_FACTOR), - m_fIsValid(false), - m_pHeader(NULL), - m_pTableDir(NULL), - m_xScale(1.0f), - m_yScale(1.0f) -{ - m_fItalic = false; - m_fBold = false; - // colors are not used - m_clrFore = (unsigned long)kclrBlack; - m_clrBack = (unsigned long)kclrTransparent; -} - -FileFont::FileFont(FILE * pfile, float pointSize, - unsigned int dpiX, unsigned int dpiY) - : Font(), - m_pfile(pfile), - m_pTableCache(NULL), - m_mAscent(0), - m_mDescent(0), - m_mEmSquare(0), - m_pointSize(pointSize), - m_dpiX(dpiX), - m_dpiY(dpiY), - m_fIsValid(false), - m_pHeader(NULL), - m_pTableDir(NULL), - m_xScale(1.0f), - m_yScale(1.0f) -{ - Assert(m_pfile); // shouldn't be null - initializeFromFace(); - -} - -FileFont::FileFont(char * fileName, float pointSize, - unsigned int dpiX, unsigned int dpiY) - : Font(), - m_pfile(NULL), - m_pTableCache(NULL), - m_mAscent(0), - m_mDescent(0), - m_mEmSquare(0), - m_pointSize(pointSize), - m_dpiX(dpiX), - m_dpiY(dpiY), - m_fIsValid(false), - m_pHeader(NULL), - m_pTableDir(NULL), - m_xScale(1.0f), - m_yScale(1.0f) -{ - Assert(fileName); // shouldn't be null but we play safe anyway - m_pfile = fopen(fileName, "rb"); - - initializeFromFace(); -} - -FileFont::FileFont(std::string fileName, float pointSize, - unsigned int dpiX, unsigned int dpiY) - : Font(), - m_pfile(NULL), - m_pTableCache(NULL), - m_mAscent(0), - m_mDescent(0), - m_mEmSquare(0), - m_pointSize(pointSize), - m_dpiX(dpiX), - m_dpiY(dpiY), - m_fIsValid(false), - m_pHeader(NULL), - m_pTableDir(NULL), - m_xScale(1.0f), - m_yScale(1.0f) -{ - Assert(fileName.length()); // shouldn't be null but we play safe anyway - m_pfile = fopen(fileName.c_str(), "rb"); - - initializeFromFace(); -} - - -void -FileFont::initializeFromFace() -{ - if (m_dpiY == 0) m_dpiY = m_dpiX; - m_fItalic = false; - m_fBold = false; - // colors are not used - m_clrFore = (unsigned long)kclrBlack; - m_clrBack = (unsigned long)kclrTransparent; - - if (m_pfile) - { - size_t lOffset, lSize; - TtfUtil::GetHeaderInfo(lOffset, lSize); - m_pHeader = new byte [lSize]; - m_fIsValid = true; - if (!m_pHeader) - { - m_fIsValid = false; - return; - } - m_fIsValid = (fseek(m_pfile, lOffset, SEEK_SET) == 0); - size_t bytesRead = fread(m_pHeader, 1, lSize, m_pfile); - Assert(bytesRead == lSize); - m_fIsValid = TtfUtil::CheckHeader(m_pHeader); - - if (!m_fIsValid) return; - m_fIsValid = TtfUtil::GetTableDirInfo(m_pHeader, lOffset, lSize); - m_pTableDir = new byte[lSize]; - if (!m_pTableDir) - { - m_fIsValid = false; - return; - } - // if lOffset hasn't changed this isn't needed - fseek(m_pfile, lOffset, SEEK_SET); - bytesRead = fread(m_pTableDir, 1, lSize, m_pfile); - Assert(bytesRead == lSize); - - // now read head tables - m_fIsValid = TtfUtil::GetTableInfo(ktiOs2, m_pHeader, m_pTableDir, - lOffset, lSize); - if (!m_fIsValid) - { - return; - } - byte * pTable = readTable(ktiOs2, lSize); - // get ascent, descent, style while we have the OS2 table loaded - if (!m_fIsValid || !pTable) - { - return; - } - m_fIsValid = TtfUtil::FontOs2Style(pTable, m_fBold, m_fItalic); - m_mAscent = static_cast<float>(TtfUtil::FontAscent(pTable)); - m_mDescent = static_cast<float>(TtfUtil::FontDescent(pTable)); - - pTable = readTable(ktiName, lSize); - if (!m_fIsValid || !pTable) - { - return; - } - if (!TtfUtil::Get31EngFamilyInfo(pTable, lOffset, lSize)) - { - // not English name - m_fIsValid = false; - return; - } - Assert(lSize %2 == 0);// should be utf16 - utf16 rgchwFace[128]; - int cchw = (lSize / sizeof(utf16)) + 1; - cchw = min(cchw, 128); - utf16 * pTable16 = reinterpret_cast<utf16*>(pTable + lOffset); - std::copy(pTable16, pTable16 + cchw - 1, rgchwFace); - rgchwFace[cchw - 1] = 0; // zero terminate - TtfUtil::SwapWString(rgchwFace, cchw - 1); -// We could use something like "if (sizeof(std::wstring::value_type) == 4)" here, -// but a compile-time switch is preferable. -#if SIZEOF_WCHAR_T == 4 - for (int cch16 = 0; cch16 < cchw; ) - { - int cch16Used = 0; - utf32 ch32 = GrCharStream::Utf16ToUtf32(&(rgchwFace[cch16]), - cchw - cch16, &cch16Used); - m_stuFaceName.push_back(ch32); - cch16 += cch16Used; - } -// } -#else - // could utf16 and wchar_t ever have different endianness? - Assert(sizeof(utf16) == sizeof(wchar_t)); - m_stuFaceName.assign(reinterpret_cast<wchar_t*>(rgchwFace)); -#endif - pTable = readTable(ktiHead, lSize); - if (!m_fIsValid || !pTable) - { - return; - } - m_mEmSquare = static_cast<float>(TtfUtil::DesignUnits(pTable)); - // can now set the scale - m_xScale = scaleFromDpi(m_dpiX); - m_yScale = scaleFromDpi(m_dpiY); - } - else - { - m_fIsValid = false; - } -} - -byte * -FileFont::readTable(int /*TableId*/ tid, size_t & size) -{ - const TableId tableId = TableId(tid); - bool isTableValid = true; - size_t lOffset = 0, lSize = 0; - if (!m_pTableCache) - { - m_pTableCache = new FontTableCache(); - } - if (!m_pTableCache) return NULL; - - byte * pTable = m_pTableCache->getTable(tableId); - size = m_pTableCache->getTableSize(tableId); - // check whether it is already in the cache - if (pTable) return pTable; - isTableValid &= TtfUtil::GetTableInfo(tableId, m_pHeader, m_pTableDir, - lOffset, lSize); - if (!isTableValid) - return NULL; - fseek(m_pfile, lOffset, SEEK_SET); - // only allocate if needed - pTable = m_pTableCache->allocateTable(tableId, lSize); - - if (!pTable) - { - isTableValid = false; - return NULL; - } - size_t bytesRead = fread(pTable, 1, lSize, m_pfile); - isTableValid = bytesRead == lSize; - if (isTableValid) - { - isTableValid &= TtfUtil::CheckTable(tableId, pTable, lSize); - } - if (!isTableValid) - { - return 0; - } - size = lSize; - return pTable; -} - - -FileFont::~FileFont() -{ - - // if this is the last copy of the font sharing these tables - // delete them - if (m_pTableCache) - { - m_pTableCache->decrementFontCount(); - if (m_pTableCache->getFontCount() == 0) - { - delete [] m_pHeader; - delete [] m_pTableDir; - delete m_pTableCache; - m_pTableCache = NULL; - if (m_pfile) - fclose(m_pfile); - } - } - else - { - delete [] m_pHeader; - delete [] m_pTableDir; - if (m_pfile) - fclose(m_pfile); - } - // note the DecFontCount(); is done in the Font base class -} - -Font * FileFont::copyThis() -{ - FileFont * copy = new FileFont(*this); - return copy; -} - -/** -* A copy constructor that allows a change of point size or dpi -* The underlying table cache will be shared between the fonts, so -* this should have a low overhead. -*/ -FileFont::FileFont(const FileFont & font, float pointSize, - unsigned int dpiX, unsigned int dpiY) -: Font(font), - m_pfile(font.m_pfile), - m_mAscent(font.m_mAscent), - m_mDescent(font.m_mDescent), - m_mEmSquare(font.m_mEmSquare), - m_pointSize(font.m_pointSize), - m_dpiX(font.m_dpiX), - m_dpiY(font.m_dpiY), - m_fIsValid(font.m_fIsValid), - m_pHeader(font.m_pHeader), - m_pTableDir(font.m_pTableDir), - m_xScale(font.m_xScale), - m_yScale(font.m_yScale) -{ - if (pointSize > 0) - { - m_pointSize = pointSize; - if (dpiX > 0) - { - m_dpiX = dpiX; - if (dpiY > 0) m_dpiY = dpiY; - else dpiY = dpiX; - } - m_xScale = scaleFromDpi(m_dpiX); - m_yScale = scaleFromDpi(m_dpiY); - } - m_fItalic = font.m_fItalic; - m_fBold = font.m_fBold; - // colors are not used - m_clrFore = font.m_clrFore; - m_clrBack = font.m_clrBack; - m_stuFaceName.assign(font.m_stuFaceName); - - m_pTableCache = font.m_pTableCache; - // use the same table cache between instances - if (m_pTableCache) - m_pTableCache->incrementFontCount(); - - - // I dont' see why we need to reget the face, but WinFont does - //m_pfface = FontFace::GetFontFace(this, m_fpropDef.szFaceName, - // m_fpropDef.fBold, m_fpropDef.fItalic); -} - - - - //virtual FontErrorCode isValidForGraphite(int * pnVersion = NULL, int * pnSubVersion = NULL); - -/*---------------------------------------------------------------------------------------------- - Read a table from the font. -----------------------------------------------------------------------------------------------*/ -const void * -FileFont::getTable(fontTableId32 tableID, size_t * pcbSize) -{ - *pcbSize = 0; - // use a cache to reduce the number of times tables have to be reloaded - if (m_pTableCache == NULL) - { - // constructor automatically sets the font count to 1 - m_pTableCache = new FontTableCache(); - } - TableId tid = ktiCmap;// to prevent uninitialized warning - for (int i = 0; i<ktiLast; i++) - { - tid = static_cast<TableId>(i); - if (tableID == TtfUtil::TableIdTag(tid)) - { - if (m_pTableCache->getTable(tid)) - { - *pcbSize = m_pTableCache->getTableSize(tid); - return m_pTableCache->getTable(tid); - } - break; - } - } - Assert(tid < ktiLast); - size_t tableSize = 0; - void * pTable = readTable(tid, tableSize); - *pcbSize = static_cast<int>(tableSize); - return pTable; -} - - -void FileFont::getFontMetrics(float * pAscent, float * pDescent, - float * pEmSquare) -{ - if (pEmSquare) *pEmSquare = m_mEmSquare * m_xScale; - if (pAscent) *pAscent = m_mAscent * m_yScale; - if (pDescent) *pDescent = m_mDescent * m_yScale; -} - - -bool FileFont::FontHasGraphiteTables(FILE * file) -{ - FileFont testFont(file, 1.0f, FUDGE_FACTOR); - return testFont.fontHasGraphiteTables(); -} - -bool FileFont::FontHasGraphiteTables(char * fileName) -{ - FileFont testFont(fileName, 1.0f, FUDGE_FACTOR); - return testFont.fontHasGraphiteTables(); -} - -bool FileFont::fontHasGraphiteTables() -{ - size_t tableSize; - bool isGraphiteFont = m_fIsValid; - isGraphiteFont &= (readTable(ktiSilf, tableSize) != NULL); - return isGraphiteFont; -} - -} // namespace gr diff --git a/Build/source/libs/graphite/engine-2.4/src/font/Font.cpp b/Build/source/libs/graphite/engine-2.4/src/font/Font.cpp deleted file mode 100644 index b527769e0fb..00000000000 --- a/Build/source/libs/graphite/engine-2.4/src/font/Font.cpp +++ /dev/null @@ -1,944 +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: Font.cpp -Responsibility: Sharon Correll -Last reviewed: Not yet. - -Description: - A font is an object that knows how to read tables from a (platform-specific) font resource. -----------------------------------------------------------------------------------------------*/ - -//:>******************************************************************************************** -//:> Include files -//:>******************************************************************************************** -#include "Main.h" -#ifdef _MSC_VER -#pragma hdrstop -#endif -// any other headers (not precompiled) - -//:End Ignore - -//:>******************************************************************************************** -//:> Forward declarations -//:>******************************************************************************************** - -//:>******************************************************************************************** -//:> Local Constants and static variables -//:>******************************************************************************************** - - -namespace gr -{ - -//:>******************************************************************************************** -//:> Font methods -//:>******************************************************************************************** - -/*---------------------------------------------------------------------------------------------- - Constructor. -----------------------------------------------------------------------------------------------*/ -Font::Font(const Font & fontSrc) : m_pfface(fontSrc.m_pfface), m_fTablesCached(false) -{ - if (m_pfface) - m_pfface->IncFontCount(); -} - -/*---------------------------------------------------------------------------------------------- - Destructor. -----------------------------------------------------------------------------------------------*/ -Font::~Font() -{ - if (m_pfface) - m_pfface->DecFontCount(); -} - -/*---------------------------------------------------------------------------------------------- - Mark the font-cache as to whether it should be deleted when all the font instances go away. -----------------------------------------------------------------------------------------------*/ -void Font::SetFlushMode(int flush) -{ - FontFace::SetFlushMode(flush); -} - -/*---------------------------------------------------------------------------------------------- - Cache the common tables if necessary. -----------------------------------------------------------------------------------------------*/ -void Font::EnsureTablesCached() -{ - if (m_fTablesCached) - return; - - size_t cbBogus; - m_pHead = getTable(TtfUtil::TableIdTag(ktiHead), &cbBogus); - m_pHhea = getTable(TtfUtil::TableIdTag(ktiHhea), &cbBogus); - m_pHmtx = getTable(TtfUtil::TableIdTag(ktiHmtx), &m_cbHmtxSize); - m_pGlyf = getTable(TtfUtil::TableIdTag(ktiGlyf), &cbBogus); - m_pLoca = getTable(TtfUtil::TableIdTag(ktiLoca), &m_cbLocaSize); - - // getTable can return 0 for the lengths if it is hard to calculate them, but it should - // never do that for hmtx or loca. - Assert(m_cbHmtxSize > 0); - Assert(m_cbLocaSize > 0); - - m_fTablesCached = true; -} - -/*---------------------------------------------------------------------------------------------- - Return the flush mode of the font-cache. -----------------------------------------------------------------------------------------------*/ -int Font::GetFlushMode() -{ - return FontFace::GetFlushMode(); -} - -/*---------------------------------------------------------------------------------------------- - Return the internal object representing the font-face. This is the object that is stored - in Graphite's internal cache. -----------------------------------------------------------------------------------------------*/ -inline FontFace & Font::fontFace(bool fDumbFallback) -{ - if (m_pfface == 0) - initialiseFontFace(fDumbFallback); - return *m_pfface; -} - -void Font::initialiseFontFace(bool fDumbFallback) -{ - std::wstring stuFaceName; - bool fBold, fItalic; - - UniqueCacheInfo(stuFaceName, fBold, fItalic); - - m_pfface = FontFace::GetFontFace(this, stuFaceName, fBold, fItalic, fDumbFallback); - - Assert(m_pfface != 0); - - m_pfface->IncFontCount(); - - FontException fexptn; - fexptn.version = -1; - fexptn.subVersion = -1; - if (m_pfface->BadFont(&fexptn.errorCode) - || (!fDumbFallback && m_pfface->DumbFallback(&fexptn.errorCode))) - { - throw fexptn; - } -} - -/*---------------------------------------------------------------------------------------------- - Return uniquely identifying information that will be used as the key for this font - in the font cache. This includes the font face name and the bold and italic flags. -----------------------------------------------------------------------------------------------*/ -void Font::UniqueCacheInfo(std::wstring & stuFace, bool & fBold, bool & fItalic) -{ - size_t cbSize; - const byte * pNameTbl = static_cast<const byte *>(getTable(TtfUtil::TableIdTag(ktiName), &cbSize)); - size_t lOffset, lSize; - if (!TtfUtil::Get31EngFamilyInfo(pNameTbl, lOffset, lSize)) - { - // TODO: try to find any name in any arbitrary language. - Assert(false); - return; - } - - size_t cchw = long(lSize / sizeof(utf16)); - const byte *src_start = pNameTbl + lOffset; - for ( ; cchw > 0; cchw--, src_start += 2) // to handle situation where wchar_t is 4 bytes - stuFace.push_back((*src_start << 8) + src_start[1]); - - const void * pOs2Tbl = getTable(TtfUtil::TableIdTag(ktiOs2), &cbSize); - TtfUtil::FontOs2Style(pOs2Tbl, fBold, fItalic); - // Do we need to compare the results from the OS2 table with the italic flag in the - // head table? (There is no requirement that they be consistent!) -} - - -/*---------------------------------------------------------------------------------------------- - A default unhinted implmentation of getGlyphPoint(..) -----------------------------------------------------------------------------------------------*/ -void Font::getGlyphPoint(gid16 glyphID, unsigned int pointNum, Point & pointReturn) -{ - EnsureTablesCached(); - - // Default values - pointReturn.x = 0; - pointReturn.y = 0; - - if (m_pGlyf == 0) return; - if (m_pHead == 0) return; - if (m_pLoca == 0) return; - - size_t cContours; - size_t cEndPoints; - size_t cPoints; - - const size_t CONTOUR_BUF_SIZE = 16; - const size_t POINT_BUF_SIZE = 64; - // Fixed-size buffers that will be used in most cases: - bool rgfOnCurveFixedBuf[POINT_BUF_SIZE], *rgfOnCurveHeapBuf=0; - int rgnEndPtFixedBuf[CONTOUR_BUF_SIZE], *rgnEndPtHeapBuf=0, - rgnXFixedBuf[POINT_BUF_SIZE], *rgnXHeapBuf=0, - rgnYFixedBuf[POINT_BUF_SIZE], *rgnYHeapBuf=0; - - if (!TtfUtil::GlyfContourCount(glyphID, m_pGlyf, m_pLoca, m_cbLocaSize, m_pHead, cContours)) - return; // can't figure it out - - int * prgnEndPt = (cContours > CONTOUR_BUF_SIZE) ? - rgnEndPtHeapBuf = new int[cContours] : - rgnEndPtFixedBuf; - - cEndPoints = cContours; - if (!TtfUtil::GlyfContourEndPoints(glyphID, m_pGlyf, m_pLoca, m_cbLocaSize, m_pHead, - prgnEndPt, cEndPoints)) //cEndPonts will be zero on return - { - return; // should have been caught above - } - cPoints = prgnEndPt[cContours - 1] + 1; - - bool* prgfOnCurve = (cPoints > POINT_BUF_SIZE) ? rgfOnCurveHeapBuf= new bool[cPoints] : rgfOnCurveFixedBuf; - int * prgnX = (cPoints > POINT_BUF_SIZE) ? rgnXHeapBuf= new int[cPoints] : rgnXFixedBuf; - int * prgnY = (cPoints > POINT_BUF_SIZE) ? rgnYHeapBuf= new int[cPoints] : rgnYFixedBuf; - - if (TtfUtil::GlyfPoints(glyphID, m_pGlyf, m_pLoca, m_cbLocaSize, m_pHead, 0, 0, - prgnX, prgnY, prgfOnCurve, cPoints)) //cPoints will be zero on return - { - float nPixEmSquare; - getFontMetrics(0, 0, &nPixEmSquare); - - const float nDesignUnitsPerPixel = float(TtfUtil::DesignUnits(m_pHead)) / nPixEmSquare; - pointReturn.x = prgnX[pointNum] / nDesignUnitsPerPixel; - pointReturn.y = prgnY[pointNum] / nDesignUnitsPerPixel; - } - - delete[] rgnEndPtHeapBuf; - delete[] rgfOnCurveHeapBuf; - delete[] rgnXHeapBuf; - delete[] rgnYHeapBuf; -} - - -/*---------------------------------------------------------------------------------------------- - A default unhinted implmentation of getGlyphMetrics(..) -----------------------------------------------------------------------------------------------*/ -void Font::getGlyphMetrics(gid16 glyphID, gr::Rect & boundingBox, gr::Point & advances) -{ - EnsureTablesCached(); - - // Setup default return values in case of failiure. - boundingBox.left = 0; - boundingBox.right = 0; - boundingBox.bottom = 0; - boundingBox.top = 0; - advances.x = 0; - advances.y = 0; - - if (m_pHhea == 0) return; - - // Calculate the number of design units per pixel. - float pixelEmSquare; - getFontMetrics(0, 0, &pixelEmSquare); - const float pixelsPerDesignUnit = - pixelEmSquare / float(TtfUtil::DesignUnits(m_pHead)); - - // getTable can return 0 for the lengths if it is hard to calculate them, but it should - // never do that for hmtx or loca. - Assert(m_cbHmtxSize > 0); - - // Use the Hmtx and Head tables to find the glyph advances. - int lsb; - unsigned int advance = 0; - if (TtfUtil::HorMetrics(glyphID, m_pHmtx, m_cbHmtxSize, m_pHhea, - lsb, advance)) - { - advances.x = (advance * pixelsPerDesignUnit); - advances.y = 0.0f; - } - - if (m_pGlyf == 0) return; - if (m_pLoca == 0) return; - Assert(m_cbLocaSize > 0); - - // Fetch the glyph bounding box. GlyphBox may return false for a whitespace glyph. - // Note that using GlyfBox here allows attachment points (ie, points lying outside - // the glyph's outline) to affect the bounding box, which might not be what we want. - int xMin, xMax, yMin, yMax; - if (TtfUtil::GlyfBox(glyphID, m_pGlyf, m_pLoca, m_cbLocaSize, m_pHead, - xMin, yMin, xMax, yMax)) - { - boundingBox.left = (xMin * pixelsPerDesignUnit); - boundingBox.bottom = (yMin * pixelsPerDesignUnit); - boundingBox.right = (xMax * pixelsPerDesignUnit); - boundingBox.top = (yMax * pixelsPerDesignUnit); - } -} - - -/*---------------------------------------------------------------------------------------------- - Return a pair of iterators over a sequence of features defined for the font. -----------------------------------------------------------------------------------------------*/ -std::pair<FeatureIterator, FeatureIterator> Font::getFeatures() -{ - std::pair<FeatureIterator, FeatureIterator> pairRet; - pairRet.first = BeginFeature(); - pairRet.second = EndFeature(); - return pairRet; -} - -/*---------------------------------------------------------------------------------------------- - Returns an iterator indicating the feature with the given ID. If no such feature, - returns the end iterator. -----------------------------------------------------------------------------------------------*/ -FeatureIterator Font::featureWithID(featid id) -{ - FeatureIterator fit = BeginFeature(); - FeatureIterator fitEnd = EndFeature(); - for ( ; fit != fitEnd ; ++fit) - { - if (*fit == id) - return fit; - } - return fitEnd; // invalid -} - -/*---------------------------------------------------------------------------------------------- - Returns the UI label for the indicated feature. Return false if there is no label for the - language, or it is empty. -----------------------------------------------------------------------------------------------*/ -bool Font::getFeatureLabel(FeatureIterator fit, lgid nLanguage, utf16 * label) -{ - return GetFeatureLabel(fit.m_ifeat, nLanguage, label); -} - -/*---------------------------------------------------------------------------------------------- - Returns an iterator pointing at the default value for the feature. -----------------------------------------------------------------------------------------------*/ -FeatureSettingIterator Font::getDefaultFeatureValue(FeatureIterator fit) -{ - size_t ifset = GetFeatureDefault(fit.m_ifeat); - FeatureSettingIterator fsit = fit.BeginSetting(); - fsit += ifset; - return fsit; -} - -/*---------------------------------------------------------------------------------------------- - Returns a pair of iterators spanning the defined settings for the feature. -----------------------------------------------------------------------------------------------*/ -std::pair<FeatureSettingIterator, FeatureSettingIterator> - Font::getFeatureSettings(FeatureIterator fit) -{ - std::pair<FeatureSettingIterator, FeatureSettingIterator> pairRet; - pairRet.first = fit.BeginSetting(); - pairRet.second = fit.EndSetting(); - return pairRet; -} - -/*---------------------------------------------------------------------------------------------- - Returns the UI label for the indicated feature. Return false if there is no label for the - language, or it is empty. -----------------------------------------------------------------------------------------------*/ -bool Font::getFeatureSettingLabel(FeatureSettingIterator fsit, lgid nLanguage, utf16 * label) -{ - //FeatureIterator * pfit = static_cast<FeatureIterator *>(fsit.m_pfit); - return GetFeatureSettingLabel(fsit.m_fit.m_ifeat, fsit.m_ifset, nLanguage, label); -} - -/*---------------------------------------------------------------------------------------------- - Private methods for feature and language access. -----------------------------------------------------------------------------------------------*/ -size_t Font::NumberOfFeatures() -{ - try { - return fontFace().NumberOfFeatures(); - } - catch (...) { return 0; } -} -featid Font::FeatureID(size_t ifeat) -{ - try { - return fontFace().FeatureID(ifeat); - } - catch (...) { return 0; } -} -size_t Font::FeatureWithID(featid id) -{ - try { - return fontFace().FeatureWithID(id); - } - catch (...) { return 0; } -} -bool Font::GetFeatureLabel(size_t ifeat, lgid language, utf16 * label) -{ - try { - return fontFace().GetFeatureLabel(ifeat, language, label); - } - catch (...) - { - *label = 0; - return false; - } -} -int Font::GetFeatureDefault(size_t ifeat) // index of default setting -{ - try { - return fontFace().GetFeatureDefault(ifeat); - } - catch (...) { return 0; } -} -size_t Font::NumberOfSettings(size_t ifeat) -{ - try { - return fontFace().NumberOfSettings(ifeat); - } - catch (...) { return 0; } -} -int Font::GetFeatureSettingValue(size_t ifeat, size_t ifset) -{ - try { - return fontFace().GetFeatureSettingValue(ifeat, ifset); - } - catch (...) { return 0; } -} -bool Font::GetFeatureSettingLabel(size_t ifeat, size_t ifset, lgid language, utf16 * label) -{ - try { - return fontFace().GetFeatureSettingLabel(ifeat, ifset, language, label); - } - catch (...) - { - *label = 0; - return false; - } -} -size_t Font::NumberOfFeatLangs() -{ - try { - return fontFace().NumberOfFeatLangs(); - } - catch (...) { return 0; } -} -short Font::FeatLabelLang(size_t ilang) -{ - try { - return fontFace().FeatLabelLang(ilang); - } - catch (...) { return 0; } -} -size_t Font::NumberOfLanguages() -{ - try { - return fontFace().NumberOfLanguages(); - } - catch (...) { return 0; } -} -isocode Font::LanguageCode(size_t ilang) -{ - try { - return fontFace().LanguageCode(ilang); - } - catch (...) - { - isocode ret; - std::fill_n(ret.rgch, sizeof(ret.rgch), '\0'); - return ret; - } -} - -/*---------------------------------------------------------------------------------------------- - Return a pair of iterators over a sequence of feature-label languages for this font. -----------------------------------------------------------------------------------------------*/ -std::pair<FeatLabelLangIterator, FeatLabelLangIterator> Font::getFeatureLabelLanguages() -{ - std::pair<FeatLabelLangIterator, FeatLabelLangIterator> pairRet; - pairRet.first = BeginFeatLang(); - pairRet.second = EndFeatLang(); - return pairRet; -} - -/*---------------------------------------------------------------------------------------------- - Return a pair of iterators over a sequence of languages defined for the font, that is, - those that have features specified for them. -----------------------------------------------------------------------------------------------*/ -std::pair<LanguageIterator, LanguageIterator> Font::getSupportedLanguages() -{ - std::pair<LanguageIterator, LanguageIterator> pairRet; - pairRet.first = BeginLanguage(); - pairRet.second = EndLanguage(); - return pairRet; -} - -/*---------------------------------------------------------------------------------------------- - Return a bitmap indicating which directions are supported by the font. -----------------------------------------------------------------------------------------------*/ -ScriptDirCode Font::getSupportedScriptDirections() const throw() -{ - try { - Font * pfontThis = const_cast<Font *>(this); - FontFace & fface = pfontThis->fontFace(); - return fface.ScriptDirection(); - } - catch (...) { - return kfsdcHorizLtr; - } -} - -/*---------------------------------------------------------------------------------------------- - For segment creation. -----------------------------------------------------------------------------------------------*/ -void Font::RenderLineFillSegment(Segment * pseg, ITextSource * pts, LayoutEnvironment & layout, - toffset ichStart, toffset ichStop, float xsMaxWidth, bool fBacktracking) -{ - fontFace(layout.dumbFallback()).RenderLineFillSegment(pseg, this, pts, layout, - ichStart, ichStop, xsMaxWidth, fBacktracking); -} - -void Font::RenderRangeSegment(Segment * pseg, ITextSource * pts, LayoutEnvironment & layout, - toffset ichStart, toffset ichStop) -{ - fontFace(layout.dumbFallback()).RenderRangeSegment(pseg, this, pts, layout, ichStart, ichStop); -} - -void Font::RenderJustifiedSegment(Segment * pseg, ITextSource * pts, - LayoutEnvironment & layout, toffset ichStart, toffset ichStop, - float xsCurrentWidth, float xsDesiredWidth) -{ - fontFace(layout.dumbFallback()).RenderJustifiedSegment(pseg, this, pts, layout, - ichStart, ichStop, xsCurrentWidth, xsDesiredWidth); -} - -/*---------------------------------------------------------------------------------------------- - Feature iterators. -----------------------------------------------------------------------------------------------*/ -FeatureIterator Font::BeginFeature() -{ - FeatureIterator fit(this, 0, NumberOfFeatures()); - return fit; -} - -FeatureIterator Font::EndFeature() -{ - int cfeat = NumberOfFeatures(); - FeatureIterator fit (this, cfeat, cfeat); - return fit; -} - -/*---------------------------------------------------------------------------------------------- - Feature-label language iterators. -----------------------------------------------------------------------------------------------*/ -FeatLabelLangIterator Font::BeginFeatLang() -{ - FeatLabelLangIterator lgit(this, 0, NumberOfFeatLangs()); - return lgit; -} - -FeatLabelLangIterator Font::EndFeatLang() -{ - int clang = NumberOfFeatLangs(); - FeatLabelLangIterator lgit(this, clang, clang); - return lgit; -} - - -/*---------------------------------------------------------------------------------------------- - Language iterators. -----------------------------------------------------------------------------------------------*/ -LanguageIterator Font::BeginLanguage() -{ - LanguageIterator lgit(this, 0, NumberOfLanguages()); - return lgit; -} - -LanguageIterator Font::EndLanguage() -{ - int clang = NumberOfLanguages(); - LanguageIterator lgit(this, clang, clang); - return lgit; -} - - -/*---------------------------------------------------------------------------------------------- - Debugging. -----------------------------------------------------------------------------------------------*/ -//bool Font::DbgCheckFontCache() -//{ -// return FontFace::DbgCheckFontCache(); -//} - - -//:>******************************************************************************************** -//:> FeatureIterator methods -//:>******************************************************************************************** - -//FeatureIterator::FeatureIterator(FeatureIterator & fitToCopy) -//{ -// m_pfont = fitToCopy.m_pfont; -// m_ifeat = fitToCopy.m_ifeat; -// m_cfeat = fitToCopy.m_cfeat; -//} - -/*---------------------------------------------------------------------------------------------- - Dereference the iterator, returning a feature ID. -----------------------------------------------------------------------------------------------*/ -featid FeatureIterator::operator*() -{ - if (m_ifeat >= m_cfeat) - { - Assert(false); - return (unsigned int)kInvalid; - } - - return m_pfont->FeatureID(m_ifeat); -} - -/*---------------------------------------------------------------------------------------------- - Increment the iterator. -----------------------------------------------------------------------------------------------*/ -FeatureIterator FeatureIterator::operator++() -{ - if (m_ifeat >= m_cfeat) - { - // Can't increment. - Assert(false); - } - else - m_ifeat++; - - return *this; -} - -/*---------------------------------------------------------------------------------------------- - Increment the iterator by the given value. -----------------------------------------------------------------------------------------------*/ -FeatureIterator FeatureIterator::operator+=(int n) -{ - if (m_ifeat + n >= m_cfeat) - { - // Can't increment. - Assert(false); - m_ifeat = m_cfeat; - } - else if (static_cast<int>(m_ifeat) + n < 0) - { - // Can't decrement. - Assert(false); - m_ifeat = 0; - } - else - m_ifeat += n; - - return *this; -} - -/*---------------------------------------------------------------------------------------------- - Test whether the two iterators are equal. -----------------------------------------------------------------------------------------------*/ -bool FeatureIterator::operator==(FeatureIterator & fit) -{ - return (fit.m_ifeat == m_ifeat && fit.m_pfont == m_pfont); -} - -bool FeatureIterator::operator!=(FeatureIterator & fit) -{ - return (fit.m_ifeat != m_ifeat || fit.m_pfont != m_pfont); -} - -/*---------------------------------------------------------------------------------------------- - Return the number of items represented by the range of the two iterators. -----------------------------------------------------------------------------------------------*/ -int FeatureIterator::operator-(FeatureIterator & fit) -{ - if (m_pfont != fit.m_pfont) - { - throw; - } - return (m_ifeat - fit.m_ifeat); -} - - -/*---------------------------------------------------------------------------------------------- - Iterators. -----------------------------------------------------------------------------------------------*/ -FeatureSettingIterator FeatureIterator::BeginSetting() -{ - int cfset = m_pfont->NumberOfSettings(m_ifeat); - FeatureSettingIterator fsit(*this, 0, cfset); - return fsit; -} - -FeatureSettingIterator FeatureIterator::EndSetting() -{ - int cfset = m_pfont->NumberOfSettings(m_ifeat); - FeatureSettingIterator fsit(*this, cfset, cfset); - return fsit; -} - - -//:>******************************************************************************************** -//:> FeatureSettingIterator methods -//:>******************************************************************************************** - -/*---------------------------------------------------------------------------------------------- - Dereference the iterator, returning a feature value. -----------------------------------------------------------------------------------------------*/ -int FeatureSettingIterator::operator*() -{ - if (m_ifset >= m_cfset) - { - Assert(false); - return kInvalid; - } - - return m_fit.m_pfont->GetFeatureSettingValue(m_fit.m_ifeat, m_ifset); -} - -/*---------------------------------------------------------------------------------------------- - Increment the iterator. -----------------------------------------------------------------------------------------------*/ -FeatureSettingIterator FeatureSettingIterator::operator++() -{ - if (m_ifset >= m_cfset) - { - // Can't increment. - Assert(false); - } - else - m_ifset++; - - return *this; -} - -/*---------------------------------------------------------------------------------------------- - Increment the iterator by the given value. -----------------------------------------------------------------------------------------------*/ -FeatureSettingIterator FeatureSettingIterator::operator+=(int n) -{ - if (m_ifset + n >= m_cfset) - { - // Can't increment. - Assert(false); - m_ifset = m_cfset; - } - if (static_cast<int>(m_ifset) + n < 0) - { - // Can't decrement. - Assert(false); - m_ifset = 0; - } - else - m_ifset += n; - - return *this; -} - -/*---------------------------------------------------------------------------------------------- - Test whether the two iterators are equal. -----------------------------------------------------------------------------------------------*/ -bool FeatureSettingIterator::operator==(FeatureSettingIterator & fsit) -{ - //FeatureIterator * pfit = static_cast<FeatureIterator *>(m_pfit); - //FeatureIterator * pfitOther = static_cast<FeatureIterator *>(fsit.m_pfit); - //return (m_ifset == fsit.m_ifset && pfit == pfitOther); - return (m_ifset == fsit.m_ifset && m_fit == fsit.m_fit); -} - -bool FeatureSettingIterator::operator!=(FeatureSettingIterator & fsit) -{ - //FeatureIterator * pfit = static_cast<FeatureIterator *>(m_pfit); - //FeatureIterator * pfitOther = static_cast<FeatureIterator *>(fsit.m_pfit); - //return (m_ifset != fsit.m_ifset || pfit != pfitOther); - - return (m_ifset != fsit.m_ifset || m_fit != fsit.m_fit); -} - -/*---------------------------------------------------------------------------------------------- - Return the number of items represented by the range of the two iterators. -----------------------------------------------------------------------------------------------*/ -int FeatureSettingIterator::operator-(FeatureSettingIterator fsit) -{ - //FeatureIterator * pfit = static_cast<FeatureIterator *>(m_pfit); - //FeatureIterator * pfitOther = static_cast<FeatureIterator *>(fsit.m_pfit); - //if (pfit != pfitOther) - - if (m_fit != fsit.m_fit) - { - throw; - } - return (m_ifset - fsit.m_ifset); -} - -//:>******************************************************************************************** -//:> FeatLabelLangIterator methods -//:>******************************************************************************************** - -/*---------------------------------------------------------------------------------------------- - Dereference the iterator, returning a language LCID. -----------------------------------------------------------------------------------------------*/ -data16 FeatLabelLangIterator::operator*() -{ - if (m_ilang >= m_clang) - { - Assert(false); - return 0; - } - - return m_pfont->FeatLabelLang(m_ilang); -} - -/*---------------------------------------------------------------------------------------------- - Increment the iterator. -----------------------------------------------------------------------------------------------*/ -FeatLabelLangIterator FeatLabelLangIterator::operator++() -{ - if (m_ilang >= m_clang) - { - // Can't increment. - Assert(false); - } - else - m_ilang++; - - return *this; -} - -/*---------------------------------------------------------------------------------------------- - Increment the iterator by the given value. -----------------------------------------------------------------------------------------------*/ -FeatLabelLangIterator FeatLabelLangIterator::operator+=(int n) -{ - if (m_ilang + n >= m_clang) - { - // Can't increment. - Assert(false); - m_ilang = m_clang; - } - else if (static_cast<int>(m_ilang) + n < 0) - { - // Can't decrement. - Assert(false); - m_ilang = 0; - } - else - m_ilang += n; - - return *this; -} - -/*---------------------------------------------------------------------------------------------- - Test whether the two iterators are equal. -----------------------------------------------------------------------------------------------*/ -bool FeatLabelLangIterator::operator==(FeatLabelLangIterator & fllit) -{ - return (fllit.m_ilang == m_ilang && fllit.m_pfont == m_pfont); -} - -bool FeatLabelLangIterator::operator!=(FeatLabelLangIterator & fllit) -{ - return (fllit.m_ilang != m_ilang || fllit.m_pfont != m_pfont); -} - -/*---------------------------------------------------------------------------------------------- - Return the number of items represented by the range of the two iterators. -----------------------------------------------------------------------------------------------*/ -int FeatLabelLangIterator::operator-(FeatLabelLangIterator & fllit) -{ - if (m_pfont != fllit.m_pfont) - { - throw; - } - return (m_ilang - fllit.m_ilang); -} - - -//:>******************************************************************************************** -//:> LanguageIterator methods -//:>******************************************************************************************** - -/*---------------------------------------------------------------------------------------------- - Dereference the iterator, returning a language code. -----------------------------------------------------------------------------------------------*/ -isocode LanguageIterator::operator*() -{ - if (m_ilang >= m_clang) - { - Assert(false); - isocode codeRet; - codeRet.rgch[0] = '?'; codeRet.rgch[1] = '?'; - codeRet.rgch[2] = '?'; codeRet.rgch[3] = 0; - return codeRet; - } - - return m_pfont->LanguageCode(m_ilang); -} - -/*---------------------------------------------------------------------------------------------- - Increment the iterator. -----------------------------------------------------------------------------------------------*/ -LanguageIterator LanguageIterator::operator++() -{ - if (m_ilang >= m_clang) - { - // Can't increment. - Assert(false); - } - else - m_ilang++; - - return *this; -} - -/*---------------------------------------------------------------------------------------------- - Increment the iterator by the given value. -----------------------------------------------------------------------------------------------*/ -LanguageIterator LanguageIterator::operator+=(int n) -{ - if (m_ilang + n >= m_clang) - { - // Can't increment. - Assert(false); - m_ilang = m_clang; - } - else if (static_cast<int>(m_ilang) + n < 0) - { - // Can't decrement. - Assert(false); - m_ilang = 0; - } - else - m_ilang += n; - - return *this; -} - -/*---------------------------------------------------------------------------------------------- - Test whether the two iterators are equal. -----------------------------------------------------------------------------------------------*/ -bool LanguageIterator::operator==(LanguageIterator & lgit) -{ - return (lgit.m_ilang == m_ilang && lgit.m_pfont == m_pfont); -} - -bool LanguageIterator::operator!=(LanguageIterator & lgit) -{ - return (lgit.m_ilang != m_ilang || lgit.m_pfont != m_pfont); -} - -/*---------------------------------------------------------------------------------------------- - Return the number of items represented by the range of the two iterators. -----------------------------------------------------------------------------------------------*/ -int LanguageIterator::operator-(LanguageIterator & lgit) -{ - if (m_pfont != lgit.m_pfont) - { - throw; - } - return (m_ilang - lgit.m_ilang); -} - - -} // namespace gr - - diff --git a/Build/source/libs/graphite/engine-2.4/src/font/FontTableCache.h b/Build/source/libs/graphite/engine-2.4/src/font/FontTableCache.h deleted file mode 100644 index 461b00d745f..00000000000 --- a/Build/source/libs/graphite/engine-2.4/src/font/FontTableCache.h +++ /dev/null @@ -1,52 +0,0 @@ - -#include "TtfUtil.h" - -namespace gr -{ - - -// used to allow table sharing among font copies -// TBD: should this be a real class or is it acceptable to -// make the attributes public -class FontTableCache -{ -public: - FontTableCache() - : m_fontCount(1) - { - for (int i = 0; i<ktiLast; i++) - { - m_pTable[i] = NULL; - } - } - ~FontTableCache() - { - Assert(m_fontCount == 0); - for (int i = 0; i<ktiLast; i++) - { - if (m_pTable[i]) delete[] m_pTable[i]; - } - } - const int & getFontCount() { return m_fontCount; } - void incrementFontCount() { m_fontCount++; } - void decrementFontCount() { m_fontCount--; Assert(m_fontCount > -1); } - byte * getTable(TableId id) const { Assert(id < ktiLast); return m_pTable[id]; } - const long & getTableSize(TableId id) const - { - Assert(id < ktiLast); - return m_tableSize[id]; - } - byte * allocateTable(TableId id, long size) - { - m_pTable[id] = new byte[size]; - m_tableSize[id] = size; - return m_pTable[id]; - } - -private: - int m_fontCount; - byte * m_pTable[ktiLast]; - long m_tableSize[ktiLast]; -}; - -} diff --git a/Build/source/libs/graphite/engine-2.4/src/font/Makefile.am b/Build/source/libs/graphite/engine-2.4/src/font/Makefile.am deleted file mode 100644 index 461af621b49..00000000000 --- a/Build/source/libs/graphite/engine-2.4/src/font/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -fontdir = $(top_srcdir)/src/font - -libgraphite_la_SOURCES += $(fontdir)/Font.cpp -libgraphite_la_SOURCES += $(fontdir)/TtfUtil.cpp -libgraphite_la_SOURCES += $(fontdir)/FileFont.cpp - -EXTRA_DIST += $(fontdir)/*.h diff --git a/Build/source/libs/graphite/engine-2.4/src/font/TtfTypes.h b/Build/source/libs/graphite/engine-2.4/src/font/TtfTypes.h deleted file mode 100644 index da8d90f1f26..00000000000 --- a/Build/source/libs/graphite/engine-2.4/src/font/TtfTypes.h +++ /dev/null @@ -1,388 +0,0 @@ -/*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (C) 2007 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: TtfTypes.h -Responsibility: Tim Eves -Last reviewed: Not yet. - -Description: -Provides types required to represent the TTF basic types. --------------------------------------------------------------------------------*//*:End Ignore*/ - - -//********************************************************************************************** -// Include files -//********************************************************************************************** -#include "GrPlatform.h" - -namespace TtfUtil -{ -//********************************************************************************************** -// Forward declarations -//********************************************************************************************** - - -//********************************************************************************************** -// Type declarations -//********************************************************************************************** -typedef gr::data8 uint8; -typedef gr::sdata8 int8; -typedef gr::data16 uint16; -typedef gr::sdata16 int16; -typedef gr::data32 uint32; -typedef gr::sdata32 int32; - -typedef int16 short_frac; -typedef int32 fixed; -typedef int16 fword; -typedef uint16 ufword; -typedef int16 f2dot14; -typedef uint32 long_date_time[2]; - -//********************************************************************************************** -// Constants and enum types -//**********************************************************************************************/ -enum -{ - OneFix = 1<<16 -}; - -//********************************************************************************************** -// Table declarations -//********************************************************************************************** -namespace Sfnt -{ -#pragma pack(1) // We need this or the structure members aren't alligned - // correctly. Fortunately this form of pragma is supposed - // to be recongnised by VS C++ too (at least according to - // MSDN). - - struct OffsetSubTable - { - uint32 scaler_type; - uint16 num_tables, - search_range, - entry_selector, - range_shift; - struct Entry - { - uint32 tag, - checksum, - offset, - length; - } table_directory[1]; - - enum ScalerType - { - TrueTypeMac = 0x74727565U, - TrueTypeWin = 0x00010000U, - Type1 = 0x74797031U - }; - }; - - - - - struct CharacterCodeMap - { - uint16 version, - num_subtables; - struct - { - uint16 platform_id, - platform_specific_id; - uint32 offset; - } encoding[1]; - }; - - struct CmapSubTable - { - uint16 format, - length, - language; - }; - - struct CmapSubTableFormat4 : CmapSubTable - { - uint16 seg_count_x2, - search_range, - entry_selector, - range_shift, - end_code[1]; - // There are arrarys after this which need their - // start positions calculated since end_code is - // seg_count uint16s long. - }; - - struct CmapSubTableFormat12 - { - fixed format; - uint32 length, - language, - num_groups; - struct - { - uint32 start_char_code, - end_char_code, - start_glyph_id; - } group[1]; - }; - - - - struct FontHeader - { - fixed version, - font_revision; - uint32 check_sum_adjustment, - magic_number; - uint16 flags, - units_per_em; - long_date_time created, - modified; - fword x_min, - y_min, - x_max, - y_max; - uint16 mac_style, - lowest_rec_ppem; - int16 font_direction_hint, - index_to_loc_format, - glyph_data_format; - enum - { - MagicNumber = 0x5F0F3CF5, - GlypDataFormat = 0 - }; - enum {ShortIndexLocFormat, LongIndexLocFormat}; - }; - - - - - struct PostScriptGlyphName - { - fixed format, - italic_angle; - fword underline_position, - underline_thickness; - uint32 is_fixed_pitch, - min_mem_type42, - max_mem_type42, - min_mem_type1, - max_mem_type1; - enum - { - Format1 = 0x10000, - Format2 = 0x20000, - Format25 = 0x28000, - Format3 = 0x30000, - Format4 = 0x40000 - }; - }; - - struct PostScriptGlyphName2 : PostScriptGlyphName - { - uint16 number_of_glyphs, - glyph_name_index[1]; - }; - - struct PostScriptGlyphName25 : PostScriptGlyphName - { - uint16 number_of_glyphs; - int8 offset[1]; - }; - - struct PostScriptGlyphName3 : PostScriptGlyphName {}; - - struct PostScriptGlyphName4 : PostScriptGlyphName - { - uint16 glyph_to_char_map[1]; - }; - - - struct HorizontalHeader - { - fixed version; - fword ascent, - descent, - line_gap; - ufword advance_width_max; - fword min_left_side_bearing, - max_left_side_bearing, - x_max_element; - int16 caret_slope_rise, - caret_slope_run; - fword caret_offset; - int16 reserved[4], - metric_data_format; - uint16 num_long_hor_metrics; - }; - - struct MaximumProfile - { - fixed version; - uint16 num_glyphs, - max_points, - max_contours, - max_component_points, - max_component_contours, - max_zones, - max_twilight_points, - max_storage, - max_function_defs, - max_instruction_defs, - max_stack_elements, - max_size_of_instructions, - max_component_elements, - max_component_depth; - }; - - - typedef gr::byte Panose[10]; - - struct Compatibility0 - { - uint16 version; - int16 x_avg_char_width; - uint16 weight_class, - width_class; - int16 fs_type, - y_subscript_x_size, - y_subscript_y_size, - y_subscript_x_offset, - y_subscript_y_offset, - y_superscript_x_size, - y_superscript_y_size, - y_superscript_x_offset, - y_superscript_y_offset, - y_strikeout_size, - y_strikeout_position, - family_class; - Panose panose; - uint32 unicode_range[4]; - int8 ach_vend_id[4]; - uint16 fs_selection, - fs_first_char_index, - fs_last_char_index, // Acording to Apple's spec this is where v0 should end - typo_ascender, - typo_descender, - type_linegap, - win_ascent, - win_descent; - - enum - { - Italic =0x01, - Underscore=0x02, - Negative =0x04, - Outlined =0x08, - StrikeOut =0x10, - Bold =0x20 - }; - }; - - struct Compatibility1 : Compatibility0 - { - uint32 codepage_range[2]; - }; - - struct Compatibility2 : Compatibility1 - { - int16 x_height, - cap_height; - uint16 default_char, - break_char, - max_context; - }; - - struct Compatibility3 : Compatibility2 {}; - - typedef Compatibility3 Compatibility; - - - struct NameRecord - { - uint16 platform_id, - platform_specific_id, - language_id, - name_id, - length, - offset; - enum {Unicode, Mactintosh, Reserved, Microsoft}; - enum - { - Copyright, Family, Subfamily, UniqueSubfamily, - Fullname, Version, PostScript - }; - }; - - struct FontNames - { - uint16 format, - count, - string_offset; - NameRecord name_record[1]; - }; - - - struct HorizontalMetric - { - uint16 advance_width; - int16 left_side_bearing; - }; - - - struct Glyph - { - int16 number_of_contours; - fword x_min, - y_min, - x_max, - y_max; - }; - - struct SimpleGlyph : Glyph - { - uint16 end_pts_of_contours[1]; - enum - { - OnCurve = 0x01, - XShort = 0x02, - YShort = 0x04, - Repeat = 0x08, - XIsSame = 0x10, - XIsPos = 0x10, - YIsSame = 0x20, - YIsPos = 0x20 - }; - }; - - struct CompoundGlyph : Glyph - { - uint16 flags, - glyph_index; - enum - { - Arg1Arg2Words = 0x01, - ArgsAreXYValues = 0x02, - RoundXYToGrid = 0x04, - HaveScale = 0x08, - MoreComponents = 0x20, - HaveXAndYScale = 0x40, - HaveTwoByTwo = 0x80, - HaveInstructions = 0x100, - UseMyMetrics = 0x200, - OverlapCompund = 0x400, - ScaledOffset = 0x800, - UnscaledOffset = 0x1000 - }; - }; - -#pragma pack() -} // end of namespace Sfnt - -} // end of namespace TtfUtil diff --git a/Build/source/libs/graphite/engine-2.4/src/font/TtfUtil.cpp b/Build/source/libs/graphite/engine-2.4/src/font/TtfUtil.cpp deleted file mode 100644 index 20b498f20f2..00000000000 --- a/Build/source/libs/graphite/engine-2.4/src/font/TtfUtil.cpp +++ /dev/null @@ -1,1990 +0,0 @@ -/*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (C) 2000, 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: TtfUtil.cpp -Responsibility: Alan Ward -Last reviewed: Not yet. - -Description: - Implements the methods for TtfUtil class. This file should remain portable to any C++ - environment by only using standard C++ and the TTF structurs defined in Tt.h. - AW 2011-10-21: Add support for multi-level composite glyphs. Contribution by Alexey Kryukov. --------------------------------------------------------------------------------*//*:End Ignore*/ - - -/*********************************************************************************************** - Include files -***********************************************************************************************/ -// Language headers -#include <algorithm> -#include <cassert> -#include <cstddef> -#include <cstring> -#include <climits> -#include <stdexcept> -// Platform headers -// Module headers -#include "TtfUtil.h" -#include "TtfTypes.h" - -/*********************************************************************************************** - Forward declarations -***********************************************************************************************/ - -/*********************************************************************************************** - Local Constants and static variables -***********************************************************************************************/ -namespace -{ - // max number of components allowed in composite glyphs - const int kMaxGlyphComponents = 8; - - // These are basic byte order swapping functions - template<typename T> inline T rev16(const T d) { - T r = (d & 0xff) << 8; r |= (d & 0xff00) >> 8; - return r; - } - - template<typename T> inline T rev32(const T d) { - T r = (d & 0xff) << 24; r |= (d & 0xff00) << 8; - r |= (d & 0xff0000) >> 8; r |= (d & 0xff000000) >> 24; - return r; - } - - // This is the generic read function which does the swapping - template<typename T> inline T read(const T d) { - return d; - } - -#if !defined WORDS_BIGENDIAN || defined PC_OS - template<> inline TtfUtil::uint16 read(const TtfUtil::uint16 d) { - return rev16(d); - } - - template<> inline TtfUtil::int16 read(const TtfUtil::int16 d) { - return rev16(d); - } - - template<> inline TtfUtil::uint32 read(const TtfUtil::uint32 d) { - return rev32(d); - } - - template<> inline TtfUtil::int32 read(const TtfUtil::int32 d) { - return rev32(d); - } -#endif - - template <int R, typename T> - inline float fixed_to_float(const T f) { - return float(f)/float(2^R); - } - -#define MAKE_TAG(a,b,c,d) ((a << 24UL) + (b << 16UL) + (c << 8UL) + (d)) - const gr::fontTableId32 mapIdToTag[] = { - MAKE_TAG('c','m','a','p'), - MAKE_TAG('c','v','t',' '), - MAKE_TAG('c','r','y','p'), - MAKE_TAG('h','e','a','d'), - MAKE_TAG('f','p','g','m'), - MAKE_TAG('g','d','i','r'), - MAKE_TAG('g','l','y','f'), - MAKE_TAG('h','d','m','x'), - MAKE_TAG('h','h','e','a'), - MAKE_TAG('h','m','t','x'), - MAKE_TAG('l','o','c','a'), - MAKE_TAG('k','e','r','n'), - MAKE_TAG('L','T','S','H'), - MAKE_TAG('m','a','x','p'), - MAKE_TAG('n','a','m','e'), - MAKE_TAG('O','S','/','2'), - MAKE_TAG('p','o','s','t'), - MAKE_TAG('p','r','e','p'), - MAKE_TAG('F','e','a','t'), - MAKE_TAG('G','l','a','t'), - MAKE_TAG('G','l','o','c'), - MAKE_TAG('S','i','l','f'), - MAKE_TAG('S','i','l','e'), - MAKE_TAG('S','i','l','l') - }; - - -/*---------------------------------------------------------------------------------------------- - Table of standard Postscript glyph names. From Martin Hosken. Disagress with ttfdump.exe ----------------------------------------------------------------------------------------------*/ - const int kcPostNames = 258; - - const char * rgPostName[kcPostNames] = { - ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", - "dollar", "percent", "ampersand", "quotesingle", "parenleft", - "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", - "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", - "nine", "colon", "semicolon", "less", "equal", "greater", "question", - "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", - "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", - "bracketleft", "backslash", "bracketright", "asciicircum", - "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", - "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", - "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", - "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", - "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", - "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", - "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", - "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", - "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", - "section", "bullet", "paragraph", "germandbls", "registered", - "copyright", "trademark", "acute", "dieresis", "notequal", "AE", - "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", - "mu", "partialdiff", "summation", "product", "pi", "integral", - "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", - "exclamdown", "logicalnot", "radical", "florin", "approxequal", - "Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace", - "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", - "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", - "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", - "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", - "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", - "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", - "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", - "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", - "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", - "cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash", - "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", - "Yacute", "yacute", "Thorn", "thorn", "minus", "multiply", - "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", - "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla", - "scedilla", "Cacute", "cacute", "Ccaron", "ccaron", - "dcroat" }; - -} // end of namespace - -/*********************************************************************************************** - Methods -***********************************************************************************************/ - -/* Note on error processing: The code guards against bad glyph ids being used to look up data -in open ended tables (loca, hmtx). If the glyph id comes from a cmap this shouldn't happen -but it seems prudent to check for user errors here. The code does assume that data obtained -from the TTF file is valid otherwise (though the CheckTable method seeks to check for -obvious problems that might accompany a change in table versions). For example an invalid -offset in the loca table which could exceed the size of the glyf table is NOT trapped. -Likewise if numberOf_LongHorMetrics in the hhea table is wrong, this will NOT be trapped, -which could cause a lookup in the hmtx table to exceed the table length. Of course, TTF tables -that are completely corrupt will cause unpredictable results. */ - -/* Note on composite glyphs: It is unclear how to build composite glyphs in some cases, -so this code represents Alan's best guess until test cases can be found. See notes on -the high-level GlyfPoints method. */ - -namespace TtfUtil -{ - - -/*---------------------------------------------------------------------------------------------- - Get offset and size of the offset table needed to find table directory. - Return true if success, false otherwise. - lSize excludes any table directory entries. -----------------------------------------------------------------------------------------------*/ -bool GetHeaderInfo(size_t & lOffset, size_t & lSize) -{ - lOffset = 0; - lSize = offsetof(Sfnt::OffsetSubTable, table_directory); - assert(sizeof(uint32) + 4*sizeof (uint16) == lSize); - return true; -} - -/*---------------------------------------------------------------------------------------------- - Check the offset table for expected data. - Return true if success, false otherwise. -----------------------------------------------------------------------------------------------*/ -bool CheckHeader(const void * pHdr) -{ - const Sfnt::OffsetSubTable * pOffsetTable - = reinterpret_cast<const Sfnt::OffsetSubTable *>(pHdr); - - return read(pOffsetTable->scaler_type) == Sfnt::OffsetSubTable::TrueTypeWin; -} - -/*---------------------------------------------------------------------------------------------- - Get offset and size of the table directory. - Return true if successful, false otherwise. -----------------------------------------------------------------------------------------------*/ -bool GetTableDirInfo(const void * pHdr, size_t & lOffset, size_t & lSize) -{ - const Sfnt::OffsetSubTable * pOffsetTable - = reinterpret_cast<const Sfnt::OffsetSubTable *>(pHdr); - - lOffset = offsetof(Sfnt::OffsetSubTable, table_directory); - lSize = read(pOffsetTable->num_tables) - * sizeof(Sfnt::OffsetSubTable::Entry); - - return true; -} - - -/*---------------------------------------------------------------------------------------------- - Get offset and size of the specified table. - Return true if successful, false otherwise. On false, offset and size will be 0. -----------------------------------------------------------------------------------------------*/ -bool GetTableInfo(TableId ktiTableId, const void * pHdr, const void * pTableDir, - size_t & lOffset, size_t & lSize) -{ - gr::fontTableId32 lTableTag = TableIdTag(ktiTableId); - if (!lTableTag) - { - lOffset = 0; - lSize = 0; - return false; - } - - const Sfnt::OffsetSubTable * pOffsetTable - = reinterpret_cast<const Sfnt::OffsetSubTable *>(pHdr); - const Sfnt::OffsetSubTable::Entry - * entry_itr = reinterpret_cast<const Sfnt::OffsetSubTable::Entry *>( - pTableDir), - * const dir_end = entry_itr + read(pOffsetTable->num_tables); - - assert(read(pOffsetTable->num_tables) < 40); - if (read(pOffsetTable->num_tables) > 40) - return false; - - for (;entry_itr != dir_end; ++entry_itr) // 40 - safe guard - { - if (read(entry_itr->tag) == lTableTag) - { - lOffset = read(entry_itr->offset); - lSize = read(entry_itr->length); - return true; - } - } - - return false; -} - -/*---------------------------------------------------------------------------------------------- - Check the specified table. Tests depend on the table type. - Return true if successful, false otherwise. -----------------------------------------------------------------------------------------------*/ -bool CheckTable(TableId ktiTableId, const void * pTable, size_t lTableSize) -{ - using namespace Sfnt; - - switch(ktiTableId) - { - case ktiCmap: // cmap - { - const Sfnt::CharacterCodeMap * const pCmap - = reinterpret_cast<const Sfnt::CharacterCodeMap *>(pTable); - assert(read(pCmap->version) == 0); - return read(pCmap->version) == 0; - } - - case ktiHead: // head - { - const Sfnt::FontHeader * const pHead - = reinterpret_cast<const Sfnt::FontHeader *>(pTable); - bool r = read(pHead->version) == OneFix - && read(pHead->magic_number) == FontHeader::MagicNumber - && read(pHead->glyph_data_format) - == FontHeader::GlypDataFormat - && (read(pHead->index_to_loc_format) - == FontHeader::ShortIndexLocFormat - || read(pHead->index_to_loc_format) - == FontHeader::LongIndexLocFormat) - && sizeof(FontHeader) <= lTableSize; - assert(r); return r; - } - - case ktiPost: // post - { - const Sfnt::PostScriptGlyphName * const pPost - = reinterpret_cast<const Sfnt::PostScriptGlyphName *>(pTable); - const fixed format = read(pPost->format); - bool r = format == PostScriptGlyphName::Format1 - || format == PostScriptGlyphName::Format2 - || format == PostScriptGlyphName::Format3 - || format == PostScriptGlyphName::Format25; - assert(r); return r; - } - - case ktiHhea: // hhea - { - const Sfnt::HorizontalHeader * pHhea = - reinterpret_cast<const Sfnt::HorizontalHeader *>(pTable); - bool r = read(pHhea->version) == OneFix - && read(pHhea->metric_data_format) == 0 - && sizeof (Sfnt::HorizontalHeader) <= lTableSize; - assert(r); return r; - } - - case ktiMaxp: // maxp - { - const Sfnt::MaximumProfile * pMaxp = - reinterpret_cast<const Sfnt::MaximumProfile *>(pTable); - bool r = read(pMaxp->version) == OneFix - && sizeof(Sfnt::MaximumProfile) <= lTableSize; - assert(r); return r; - } - - case ktiOs2: // OS/2 - { - const Sfnt::Compatibility * pOs2 - = reinterpret_cast<const Sfnt::Compatibility *>(pTable); - if (read(pOs2->version) == 0) - { // OS/2 table version 1 size -// if (sizeof(Sfnt::Compatibility) -// - sizeof(uint32)*2 - sizeof(int16)*2 -// - sizeof(uint16)*3 <= lTableSize) - if (sizeof(Sfnt::Compatibility0) <= lTableSize) - return true; - } - else if (read(pOs2->version) == 1) - { // OS/2 table version 2 size -// if (sizeof(Sfnt::Compatibility) -// - sizeof(int16) *2 -// - sizeof(uint16)*3 <= lTableSize) - if (sizeof(Sfnt::Compatibility1) <= lTableSize) - return true; - } - else if (read(pOs2->version) == 2) - { // OS/2 table version 3 size - if (sizeof(Sfnt::Compatibility2) <= lTableSize) - return true; - } - else if (read(pOs2->version) == 3) - { // OS/2 table version 4 size - version 4 changed the meaning of some fields which we don't use - if (sizeof(Sfnt::Compatibility3) <= lTableSize) - return true; - } - else - return false; - } - - case ktiName: - { - const Sfnt::FontNames * pName - = reinterpret_cast<const Sfnt::FontNames *>(pTable); - assert(read(pName->format) == 0); - return read(pName->format) == 0; - } - - default: - break; - } - - return true; -} - -/*---------------------------------------------------------------------------------------------- - Return the number of glyphs in the font. Should never be less than zero. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -size_t GlyphCount(const void * pMaxp) -{ - const Sfnt::MaximumProfile * pTable = - reinterpret_cast<const Sfnt::MaximumProfile *>(pMaxp); - return read(pTable->num_glyphs); -} - -/*---------------------------------------------------------------------------------------------- - Return the maximum number of components for any composite glyph in the font. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -size_t MaxCompositeComponentCount(const void * pMaxp) -{ - const Sfnt::MaximumProfile * pTable = - reinterpret_cast<const Sfnt::MaximumProfile *>(pMaxp); - return read(pTable->max_component_elements); -} - -/*---------------------------------------------------------------------------------------------- - Composite glyphs can be composed of glyphs that are themselves composites. - This method returns the maximum number of levels like this for any glyph in the font. - A non-composite glyph has a level of 1. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -size_t MaxCompositeLevelCount(const void * pMaxp) -{ - const Sfnt::MaximumProfile * pTable = - reinterpret_cast<const Sfnt::MaximumProfile *>(pMaxp); - return read(pTable->max_component_depth); -} - -/*---------------------------------------------------------------------------------------------- - Return the number of glyphs in the font according to a differt source. - Should never be less than zero. Return -1 on failure. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -size_t LocaGlyphCount(size_t lLocaSize, const void * pHead) throw(std::domain_error) -{ - - const Sfnt::FontHeader * pTable - = reinterpret_cast<const Sfnt::FontHeader *>(pHead); - - if (read(pTable->index_to_loc_format) - == Sfnt::FontHeader::ShortIndexLocFormat) - // loca entries are two bytes and have been divided by two - return (lLocaSize >> 1) - 1; - - if (read(pTable->index_to_loc_format) - == Sfnt::FontHeader::LongIndexLocFormat) - // loca entries are four bytes - return (lLocaSize >> 2) - 1; - - //return -1; - throw std::domain_error("head table in inconsistent state. The font may be corrupted"); -} - -/*---------------------------------------------------------------------------------------------- - Return the design units the font is designed with -----------------------------------------------------------------------------------------------*/ -int DesignUnits(const void * pHead) -{ - const Sfnt::FontHeader * pTable = - reinterpret_cast<const Sfnt::FontHeader *>(pHead); - - return read(pTable->units_per_em); -} - -/*---------------------------------------------------------------------------------------------- - Return the checksum from the head table, which serves as a unique identifer for the font. -----------------------------------------------------------------------------------------------*/ -int HeadTableCheckSum(const void * pHead) -{ - const Sfnt::FontHeader * pTable = - reinterpret_cast<const Sfnt::FontHeader *>(pHead); - - return read(pTable->check_sum_adjustment); -} - -/*---------------------------------------------------------------------------------------------- - Return the create time from the head table. This consists of a 64-bit integer, which - we return here as two 32-bit integers. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -void HeadTableCreateTime(const void * pHead, - unsigned int * pnDateBC, unsigned int * pnDateAD) -{ - const Sfnt::FontHeader * pTable = - reinterpret_cast<const Sfnt::FontHeader *>(pHead); - - *pnDateBC = read(pTable->created[0]); - *pnDateAD = read(pTable->created[1]); -} - -/*---------------------------------------------------------------------------------------------- - Return the modify time from the head table.This consists of a 64-bit integer, which - we return here as two 32-bit integers. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -void HeadTableModifyTime(const void * pHead, - unsigned int * pnDateBC, unsigned int *pnDateAD) -{ - const Sfnt::FontHeader * pTable = - reinterpret_cast<const Sfnt::FontHeader *>(pHead); - - *pnDateBC = read(pTable->modified[0]); - *pnDateAD = read(pTable->modified[1]); -} - -/*---------------------------------------------------------------------------------------------- - Return true if the font is italic. -----------------------------------------------------------------------------------------------*/ -bool IsItalic(const void * pHead) -{ - const Sfnt::FontHeader * pTable = - reinterpret_cast<const Sfnt::FontHeader *>(pHead); - - return ((read(pTable->mac_style) & 0x00000002) != 0); -} - -/*---------------------------------------------------------------------------------------------- - Return the ascent for the font -----------------------------------------------------------------------------------------------*/ -int FontAscent(const void * pOs2) -{ - const Sfnt::Compatibility * pTable = reinterpret_cast<const Sfnt::Compatibility *>(pOs2); - - return read(pTable->win_ascent); -} - -/*---------------------------------------------------------------------------------------------- - Return the descent for the font -----------------------------------------------------------------------------------------------*/ -int FontDescent(const void * pOs2) -{ - const Sfnt::Compatibility * pTable = reinterpret_cast<const Sfnt::Compatibility *>(pOs2); - - return read(pTable->win_descent); -} - -/*---------------------------------------------------------------------------------------------- - Get the bold and italic style bits. - Return true if successful. false otherwise. - In addition to checking the OS/2 table, one could also check - the head table's macStyle field (overridden by the OS/2 table on Win) - the sub-family name in the name table (though this can contain oblique, dark, etc too) -----------------------------------------------------------------------------------------------*/ -bool FontOs2Style(const void *pOs2, bool & fBold, bool & fItalic) -{ - const Sfnt::Compatibility * pTable = reinterpret_cast<const Sfnt::Compatibility *>(pOs2); - - fBold = (read(pTable->fs_selection) & Sfnt::Compatibility::Bold) != 0; - fItalic = (read(pTable->fs_selection) & Sfnt::Compatibility::Italic) != 0; - - return true; -} - -/*---------------------------------------------------------------------------------------------- - Method for searching name table. -----------------------------------------------------------------------------------------------*/ -bool GetNameInfo(const void * pName, int nPlatformId, int nEncodingId, - int nLangId, int nNameId, size_t & lOffset, size_t & lSize) -{ - lOffset = 0; - lSize = 0; - - const Sfnt::FontNames * pTable = reinterpret_cast<const Sfnt::FontNames *>(pName); - uint16 cRecord = read(pTable->count); - uint16 nRecordOffset = read(pTable->string_offset); - const Sfnt::NameRecord * pRecord = reinterpret_cast<const Sfnt::NameRecord *>(pTable + 1); - - for (int i = 0; i < cRecord; ++i) - { - if (read(pRecord->platform_id) == nPlatformId && - read(pRecord->platform_specific_id) == nEncodingId && - read(pRecord->language_id) == nLangId && - read(pRecord->name_id) == nNameId) - { - lOffset = read(pRecord->offset) + nRecordOffset; - lSize = read(pRecord->length); - return true; - } - pRecord++; - } - - return false; -} - -/*---------------------------------------------------------------------------------------------- - Return all the lang-IDs that have data for the given name-IDs. Assume that there is room - in the return array (langIdList) for 128 items. The purpose of this method is to return - a list of all possible lang-IDs. -----------------------------------------------------------------------------------------------*/ -int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId, - int * nameIdList, int cNameIds, short * langIdList) -{ - const Sfnt::FontNames * pTable = reinterpret_cast<const Sfnt::FontNames *>(pName); - uint16 cRecord = read(pTable->count); - //uint16 nRecordOffset = swapw(pTable->stringOffset); - const Sfnt::NameRecord * pRecord = reinterpret_cast<const Sfnt::NameRecord *>(pTable + 1); - - int cLangIds = 0; - for (int i = 0; i < cRecord; ++i) - { - if (read(pRecord->platform_id) == nPlatformId && - read(pRecord->platform_specific_id) == nEncodingId) - { - bool fNameFound = false; - int nLangId = read(pRecord->language_id); - int nNameId = read(pRecord->name_id); - for (int j = 0; j < cNameIds; j++) - { - if (nNameId == nameIdList[j]) - { - fNameFound = true; - break; - } - } - if (fNameFound) - { - // Add it if it's not there. - int ilang; - for (ilang = 0; ilang < cLangIds; ilang++) - if (langIdList[ilang] == nLangId) - break; - if (ilang >= cLangIds) - { - langIdList[cLangIds] = short(nLangId); - cLangIds++; - } - if (cLangIds == 128) - return cLangIds; - } - } - pRecord++; - } - - return cLangIds; -} - -/*---------------------------------------------------------------------------------------------- - Get the offset and size of the font family name in English for the MS Platform with Unicode - writing system. The offset is within the pName data. The string is double byte with MSB - first. -----------------------------------------------------------------------------------------------*/ -bool Get31EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize) -{ - return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 1, 1033, - Sfnt::NameRecord::Family, lOffset, lSize); -} - -/*---------------------------------------------------------------------------------------------- - Get the offset and size of the full font name in English for the MS Platform with Unicode - writing system. The offset is within the pName data. The string is double byte with MSB - first. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize) -{ - return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 1, 1033, - Sfnt::NameRecord::Fullname, lOffset, lSize); -} - -/*---------------------------------------------------------------------------------------------- - Get the offset and size of the font family name in English for the MS Platform with Symbol - writing system. The offset is within the pName data. The string is double byte with MSB - first. -----------------------------------------------------------------------------------------------*/ -bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize) -{ - return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 0, 1033, - Sfnt::NameRecord::Family, lOffset, lSize); -} - -/*---------------------------------------------------------------------------------------------- - Get the offset and size of the full font name in English for the MS Platform with Symbol - writing system. The offset is within the pName data. The string is double byte with MSB - first. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize) -{ - return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 0, 1033, - Sfnt::NameRecord::Fullname, lOffset, lSize); -} - -/*---------------------------------------------------------------------------------------------- - Return the Glyph ID for a given Postscript name. This method finds the first glyph which - matches the requested Postscript name. Ideally every glyph should have a unique Postscript - name (except for special names such as .notdef), but this is not always true. - On failure return value less than zero. - -1 - table search failed - -2 - format 3 table (no Postscript glyph info) - -3 - other failures - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp, - const char * pPostName) -{ - using namespace Sfnt; - - const Sfnt::PostScriptGlyphName * pTable - = reinterpret_cast<const Sfnt::PostScriptGlyphName *>(pPost); - fixed format = read(pTable->format); - - if (format == PostScriptGlyphName::Format3) - { // format 3 - no Postscript glyph info in font - return -2; - } - - // search for given Postscript name among the standard names - int iPostName = -1; // index in standard names - for (int i = 0; i < kcPostNames; i++) - { - if (!strcmp(pPostName, rgPostName[i])) - { - iPostName = i; - break; - } - } - - if (format == PostScriptGlyphName::Format1) - { // format 1 - use standard Postscript names - return iPostName; - } - - if (format == PostScriptGlyphName::Format25) - { - if (iPostName == -1) - return -1; - - const PostScriptGlyphName25 * pTable25 - = static_cast<const PostScriptGlyphName25 *>(pTable); - int cnGlyphs = GlyphCount(pMaxp); - for (gr::gid16 nGlyphId = 0; nGlyphId < cnGlyphs && nGlyphId < kcPostNames; - nGlyphId++) - { // glyph_name_index25 contains bytes so no byte swapping needed - // search for first glyph id that uses the standard name - if (nGlyphId + pTable25->offset[nGlyphId] == iPostName) - return nGlyphId; - } - } - - if (format == PostScriptGlyphName::Format2) - { // format 2 - const PostScriptGlyphName2 * pTable2 - = static_cast<const PostScriptGlyphName2 *>(pTable); - - int cnGlyphs = read(pTable2->number_of_glyphs); - - if (iPostName != -1) - { // did match a standard name, look for first glyph id mapped to that name - for (gr::gid16 nGlyphId = 0; nGlyphId < cnGlyphs; nGlyphId++) - { - if (read(pTable2->glyph_name_index[nGlyphId]) == iPostName) - return nGlyphId; - } - return -1; // no glyph with this standard name - } - - else - { // did not match a standard name, search font specific names - size_t nStrSizeGoal = strlen(pPostName); - const char * pFirstGlyphName = reinterpret_cast<const char *>( - &pTable2->glyph_name_index[0] + cnGlyphs); - const char * pGlyphName = pFirstGlyphName; - int iInNames = 0; // index in font specific names - bool fFound = false; - const char * const endOfTable - = reinterpret_cast<const char *>(pTable2) + lPostSize; - while (pGlyphName < endOfTable && !fFound) - { // search Pascal strings for first matching name - size_t nStringSize = size_t(*pGlyphName); - if (nStrSizeGoal != nStringSize || - strncmp(pGlyphName + 1, pPostName, nStringSize)) - { // did not match - ++iInNames; - pGlyphName += nStringSize + 1; - } - else - { // did match - fFound = true; - } - } - if (!fFound) - return -1; // no font specific name matches request - - iInNames += kcPostNames; - for (gr::gid16 nGlyphId = 0; nGlyphId < cnGlyphs; nGlyphId++) - { // search for first glyph id that maps to the found string index - if (read(pTable2->glyph_name_index[nGlyphId]) == iInNames) - return nGlyphId; - } - return -1; // no glyph mapped to this index (very strange) - } - } - - return -3; -} - -/*---------------------------------------------------------------------------------------------- - Convert a Unicode character string from big endian (MSB first, Motorola) format to little - endian (LSB first, Intel) format. - nSize is the number of Unicode characters in the string. It should not include any - terminating null. If nSize is 0, it is assumed the string is null terminated. nSize - defaults to 0. - Return true if successful, false otherwise. -----------------------------------------------------------------------------------------------*/ -void SwapWString(void * pWStr, size_t nSize /* = 0 */) throw (std::invalid_argument) -{ - if (pWStr == 0) - throw std::invalid_argument("null pointer given"); - - uint16 * pStr = reinterpret_cast<uint16 *>(pWStr); - uint16 * const pStrEnd = pStr + (nSize == 0 ? gr::utf16len(pStr) : nSize); - -#ifndef USE_STDLIB_WORKAROUNDS - std::transform(pStr, pStrEnd, pStr, read<uint16>); -#else - for (int i = 0; i < nSize; i++) - { // swap the wide characters in the string - pStr[i] = gr::utf16(read(uint16(pStr[i]))); - } -#endif -} - -/*---------------------------------------------------------------------------------------------- - Get the left-side bearing and and advance width based on the given tables and Glyph ID - Return true if successful, false otherwise. On false, one or both value could be INT_MIN -----------------------------------------------------------------------------------------------*/ -bool HorMetrics(gr::gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize, const void * pHhea, - int & nLsb, unsigned int & nAdvWid) -{ - const Sfnt::HorizontalMetric * phmtx = - reinterpret_cast<const Sfnt::HorizontalMetric *>(pHmtx); - - const Sfnt::HorizontalHeader * phhea = - reinterpret_cast<const Sfnt::HorizontalHeader *>(pHhea); - - size_t cLongHorMetrics = read(phhea->num_long_hor_metrics); - if (nGlyphId < cLongHorMetrics) - { // glyph id is acceptable - nAdvWid = read(phmtx[nGlyphId].advance_width); - nLsb = read(phmtx[nGlyphId].left_side_bearing); - } - else - { - nAdvWid = read(phmtx[cLongHorMetrics - 1].advance_width); - - // guard against bad glyph id - size_t lLsbOffset = sizeof(Sfnt::HorizontalMetric) * cLongHorMetrics + - sizeof(int16) * (nGlyphId - cLongHorMetrics); // offset in bytes - if (lLsbOffset + 1 >= lHmtxSize) // + 1 because entries are two bytes wide - { - nLsb = 0; - return false; - } - const int16 * pLsb = reinterpret_cast<const int16 *>(phmtx) + - lLsbOffset / sizeof(int16); - nLsb = read(*pLsb); - } - - return true; -} - -/*---------------------------------------------------------------------------------------------- - Return a pointer to the requested cmap subtable. By default find the Microsoft Unicode - subtable. Pass nEncoding as -1 to find first table that matches only nPlatformId. - Return NULL if the subtable cannot be found. -----------------------------------------------------------------------------------------------*/ -void * FindCmapSubtable(const void * pCmap, - int nPlatformId, /* =3 */ - int nEncodingId) /* = 1 */ -{ - const Sfnt::CharacterCodeMap * pTable = - reinterpret_cast<const Sfnt::CharacterCodeMap *>(pCmap); - - uint16 csuPlatforms = read(pTable->num_subtables); - for (int i = 0; i < csuPlatforms; i++) - { - if (read(pTable->encoding[i].platform_id) == nPlatformId && - (nEncodingId == -1 || read(pTable->encoding[i].platform_specific_id) == nEncodingId)) - { - const void * pRtn = reinterpret_cast<const uint8 *>(pCmap) + - read(pTable->encoding[i].offset); - return const_cast<void *>(pRtn); - } - } - - return 0; -} - -/*---------------------------------------------------------------------------------------------- - Check the Microsoft Unicode subtable for expected values -----------------------------------------------------------------------------------------------*/ -bool CheckCmap31Subtable(const void * pCmap31) -{ - const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmap31); - // Bob H says ome freeware TT fonts have version 1 (eg, CALIGULA.TTF) - // so don't check subtable version. 21 Mar 2002 spec changes version to language. - - return read(pTable->format) == 4; -} - -/*---------------------------------------------------------------------------------------------- - Return the Glyph ID for the given Unicode ID in the Microsoft Unicode subtable. - (Actually this code only depends on subtable being format 4.) - Return 0 if the Unicode ID is not in the subtable. -----------------------------------------------------------------------------------------------*/ -gr::gid16 Cmap31Lookup(const void * pCmap31, int nUnicodeId) -{ - const Sfnt::CmapSubTableFormat4 * pTable = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmap31); - - uint16 nSeg = read(pTable->seg_count_x2) >> 1; - - uint16 n; - const uint16 * pLeft, * pMid; - uint16 cMid, chStart, chEnd; - - // Binary search of the endCode[] array - pLeft = &(pTable->end_code[0]); - n = nSeg; - while (n > 0) - { - cMid = n >> 1; // Pick an element in the middle - pMid = pLeft + cMid; - chEnd = read(*pMid); - if (nUnicodeId <= chEnd) - { - if (cMid == 0 || nUnicodeId > read(pMid[-1])) - break; // Must be this seg or none! - n = cMid; // Continue on left side, omitting mid point - } - else - { - pLeft = pMid + 1; // Continue on right side, omitting mid point - n -= (cMid + 1); - } - } - - if (!n) - return 0; - - // Ok, we're down to one segment and pMid points to the endCode element - // Either this is it or none is. - - chStart = read(*(pMid += nSeg + 1)); - if (chEnd >= nUnicodeId && nUnicodeId >= chStart) - { - // Found correct segment. Find Glyph Id - int16 idDelta = read(*(pMid += nSeg)); - uint16 idRangeOffset = read(*(pMid += nSeg)); - - if (idRangeOffset == 0) - return (uint16)(idDelta + nUnicodeId); // must use modulus 2^16 - - // Look up value in glyphIdArray - gr::gid16 nGlyphId = read(*(pMid + (nUnicodeId - chStart) + (idRangeOffset >> 1))); - // If this value is 0, return 0. Else add the idDelta - return nGlyphId ? nGlyphId + idDelta : 0; - } - - return 0; -} - -/*---------------------------------------------------------------------------------------------- - Return the next Unicode value in the cmap. Pass 0 to obtain the first item. - Returns 0xFFFF as the last item. - pRangeKey is an optional key that is used to optimize the search; its value is the range - in which the character is found. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -unsigned int Cmap31NextCodepoint(const void *pCmap31, unsigned int nUnicodeId, int * pRangeKey) -{ - const Sfnt::CmapSubTableFormat4 * pTable = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmap31); - - uint16 nRange = read(pTable->seg_count_x2) >> 1; - - uint32 nUnicodePrev = (uint32)nUnicodeId; - - const uint16 * pStartCode = &(pTable->end_code[0]) - + nRange // length of end code array - + 1; // reserved word - - if (nUnicodePrev == 0) - { - // return the first codepoint. - if (pRangeKey) - *pRangeKey = 0; - return read(pStartCode[0]); - } - else if (nUnicodePrev >= 0xFFFF) - { - if (pRangeKey) - *pRangeKey = nRange - 1; - return 0xFFFF; - } - - int iRange = (pRangeKey) ? *pRangeKey : 0; - // Just in case we have a bad key: - while (iRange > 0 && read(pStartCode[iRange]) > nUnicodePrev) - iRange--; - while (read(pTable->end_code[iRange]) < nUnicodePrev) - iRange++; - - // Now iRange is the range containing nUnicodePrev. - unsigned int nStartCode = read(pStartCode[iRange]); - unsigned int nEndCode = read(pTable->end_code[iRange]); - - if (nStartCode > nUnicodePrev) - // Oops, nUnicodePrev is not in the cmap! Adjust so we get a reasonable - // answer this time around. - nUnicodePrev = nStartCode - 1; - - if (nEndCode > nUnicodePrev) - { - // Next is in the same range; it is the next successive codepoint. - if (pRangeKey) - *pRangeKey = iRange; - return nUnicodePrev + 1; - } - - // Otherwise the next codepoint is the first one in the next range. - // There is guaranteed to be a next range because there must be one that - // ends with 0xFFFF. - if (pRangeKey) - *pRangeKey = iRange + 1; - return read(pStartCode[iRange + 1]); -} - -/*---------------------------------------------------------------------------------------------- - Check the Microsoft UCS-4 subtable for expected values. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -bool CheckCmap310Subtable(const void *pCmap310) -{ - const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmap310); - return read(pTable->format) == 12; -} - -/*---------------------------------------------------------------------------------------------- - Return the Glyph ID for the given Unicode ID in the Microsoft UCS-4 subtable. - (Actually this code only depends on subtable being format 12.) - Return 0 if the Unicode ID is not in the subtable. -----------------------------------------------------------------------------------------------*/ -gr::gid16 Cmap310Lookup(const void * pCmap310, unsigned int uUnicodeId) -{ - const Sfnt::CmapSubTableFormat12 * pTable = reinterpret_cast<const Sfnt::CmapSubTableFormat12 *>(pCmap310); - - //uint32 uLength = read(pTable->length); //could use to test for premature end of table - uint32 ucGroups = read(pTable->num_groups); - - for (unsigned int i = 0; i < ucGroups; i++) - { - uint32 uStartCode = read(pTable->group[i].start_char_code); - uint32 uEndCode = read(pTable->group[i].end_char_code); - if (uUnicodeId >= uStartCode && uUnicodeId <= uEndCode) - { - uint32 uDiff = uUnicodeId - uStartCode; - uint32 uStartGid = read(pTable->group[i].start_glyph_id); - return static_cast<gr::gid16>(uStartGid + uDiff); - } - } - - return 0; -} - -/*---------------------------------------------------------------------------------------------- - Return the next Unicode value in the cmap. Pass 0 to obtain the first item. - Returns 0x10FFFF as the last item. - pRangeKey is an optional key that is used to optimize the search; its value is the range - in which the character is found. - - Note: this method is not currently used by the Graphite engine. -----------------------------------------------------------------------------------------------*/ -unsigned int Cmap310NextCodepoint(const void *pCmap310, unsigned int nUnicodeId, int * pRangeKey) -{ - const Sfnt::CmapSubTableFormat12 * pTable = reinterpret_cast<const Sfnt::CmapSubTableFormat12 *>(pCmap310); - - int nRange = read(pTable->num_groups); - - uint32 nUnicodePrev = (uint32)nUnicodeId; - - if (nUnicodePrev == 0) - { - // return the first codepoint. - if (pRangeKey) - *pRangeKey = 0; - return read(pTable->group[0].start_char_code); - } - else if (nUnicodePrev >= 0x10FFFF) - { - if (pRangeKey) - *pRangeKey = nRange; - return 0x10FFFF; - } - - int iRange = (pRangeKey) ? *pRangeKey : 0; - // Just in case we have a bad key: - while (iRange > 0 && read(pTable->group[iRange].start_char_code) > nUnicodePrev) - iRange--; - while (read(pTable->group[iRange].end_char_code) < nUnicodePrev) - iRange++; - - // Now iRange is the range containing nUnicodePrev. - - unsigned int nStartCode = read(pTable->group[iRange].start_char_code); - unsigned int nEndCode = read(pTable->group[iRange].end_char_code); - - if (nStartCode > nUnicodePrev) - // Oops, nUnicodePrev is not in the cmap! Adjust so we get a reasonable - // answer this time around. - nUnicodePrev = nStartCode - 1; - - if (nEndCode > nUnicodePrev) - { - // Next is in the same range; it is the next successive codepoint. - if (pRangeKey) - *pRangeKey = iRange; - return nUnicodePrev + 1; - } - - // Otherwise the next codepoint is the first one in the next range, or 10FFFF if we're done. - if (pRangeKey) - *pRangeKey = iRange + 1; - return (iRange + 1 >= nRange) ? 0x10FFFF : read(pTable->group[iRange + 1].start_char_code); -} - -/*---------------------------------------------------------------------------------------------- - Return the offset stored in the loca table for the given Glyph ID. - (This offset is into the glyf table.) - Return -1 if the lookup failed. - Technically this method should return an unsigned long but it is unlikely the offset will - exceed 2^31. -----------------------------------------------------------------------------------------------*/ -size_t LocaLookup(gr::gid16 nGlyphId, - const void * pLoca, size_t lLocaSize, - const void * pHead) throw (std::out_of_range) -{ - const Sfnt::FontHeader * pTable = reinterpret_cast<const Sfnt::FontHeader *>(pHead); - - // CheckTable verifies the index_to_loc_format is valid - if (read(pTable->index_to_loc_format) == Sfnt::FontHeader::ShortIndexLocFormat) - { // loca entries are two bytes and have been divided by two - if (nGlyphId <= (lLocaSize >> 1) - 1) // allow sentinel value to be accessed - { - const uint16 * pShortTable = reinterpret_cast<const uint16 *>(pLoca); - return (read(pShortTable[nGlyphId]) << 1); - } - } - - if (read(pTable->index_to_loc_format) == Sfnt::FontHeader::LongIndexLocFormat) - { // loca entries are four bytes - if (nGlyphId <= (lLocaSize >> 2) - 1) - { - const uint32 * pLongTable = reinterpret_cast<const uint32 *>(pLoca); - return read(pLongTable[nGlyphId]); - } - } - - // only get here if glyph id was bad - //return -1; - throw std::out_of_range("glyph id out of range for font"); -} - -/*---------------------------------------------------------------------------------------------- - Return a pointer into the glyf table based on the given offset (from LocaLookup). - Return NULL on error. -----------------------------------------------------------------------------------------------*/ -void * GlyfLookup(const void * pGlyf, size_t nGlyfOffset) -{ - const uint8 * pByte = reinterpret_cast<const uint8 *>(pGlyf); - return const_cast<uint8 *>(pByte + nGlyfOffset); -} - -/*---------------------------------------------------------------------------------------------- - Get the bounding box coordinates for a simple glyf entry (non-composite). - Return true if successful, false otherwise. -----------------------------------------------------------------------------------------------*/ -bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin, - int & xMax, int & yMax) -{ - const Sfnt::Glyph * pGlyph = reinterpret_cast<const Sfnt::Glyph *>(pSimpleGlyf); - - xMin = read(pGlyph->x_min); - yMin = read(pGlyph->y_min); - xMax = read(pGlyph->x_max); - yMax = read(pGlyph->y_max); - - return true; -} - -/*---------------------------------------------------------------------------------------------- - Return the number of contours for a simple glyf entry (non-composite) - Returning -1 means this is a composite glyph -----------------------------------------------------------------------------------------------*/ -int GlyfContourCount(const void * pSimpleGlyf) -{ - const Sfnt::Glyph * pGlyph = reinterpret_cast<const Sfnt::Glyph *>(pSimpleGlyf); - return read(pGlyph->number_of_contours); // -1 means composite glyph -} - -/*---------------------------------------------------------------------------------------------- - Get the point numbers for the end points of the glyph contours for a simple - glyf entry (non-composite). - cnPointsTotal - count of contours from GlyfContourCount(); (same as number of end points) - prgnContourEndPoints - should point to a buffer large enough to hold cnPoints integers - cnPoints - count of points placed in above range - Return true if successful, false otherwise. - False could indicate a multi-level composite glyphs. -----------------------------------------------------------------------------------------------*/ -bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint, - int cnPointsTotal, int & cnPoints) -{ - const Sfnt::SimpleGlyph * pGlyph = reinterpret_cast<const Sfnt::SimpleGlyph *>(pSimpleGlyf); - - int cContours = read(pGlyph->number_of_contours); - if (cContours < 0) - return false; // this method isn't supposed handle composite glyphs - - for (int i = 0; i < cContours && i < cnPointsTotal; i++) - { - prgnContourEndPoint[i] = read(pGlyph->end_pts_of_contours[i]); - } - - cnPoints = cContours; - return true; -} - -/*---------------------------------------------------------------------------------------------- - Get the points for a simple glyf entry (non-composite) - cnPointsTotal - count of points from largest end point obtained from GlyfContourEndPoints - prgnX & prgnY - should point to buffers large enough to hold cnPointsTotal integers - The ranges are parallel so that coordinates for point(n) are found at offset n in both - ranges. This is raw point data with relative coordinates. - prgbFlag - should point to a buffer a large enough to hold cnPointsTotal bytes - This range is parallel to the prgnX & prgnY - cnPoints - count of points placed in above ranges - Return true if successful, false otherwise. - False could indicate a composite glyph -----------------------------------------------------------------------------------------------*/ -bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY, - char * prgbFlag, int cnPointsTotal, int & cnPoints) -{ - using namespace Sfnt; - - const Sfnt::SimpleGlyph * pGlyph = reinterpret_cast<const Sfnt::SimpleGlyph *>(pSimpleGlyf); - int cContours = read(pGlyph->number_of_contours); - // return false for composite glyph - if (cContours <= 0) - return false; - int cPts = read(pGlyph->end_pts_of_contours[cContours - 1]) + 1; - if (cPts > cnPointsTotal) - return false; - - // skip over bounding box data & point to byte count of instructions (hints) - const uint8 * pbGlyph = reinterpret_cast<const uint8 *> - (&pGlyph->end_pts_of_contours[cContours]); - - // skip over hints & point to first flag - int cbHints = read(*(const uint16 *)pbGlyph); - pbGlyph += sizeof(uint16); - pbGlyph += cbHints; - - // load flags & point to first x coordinate - int iFlag = 0; - while (iFlag < cPts) - { - if (!(*pbGlyph & SimpleGlyph::Repeat)) - { // flag isn't repeated - prgbFlag[iFlag] = (char)*pbGlyph; - pbGlyph++; - iFlag++; - } - else - { // flag is repeated; count specified by next byte - char chFlag = (char)*pbGlyph; - pbGlyph++; - int cFlags = (int)*pbGlyph; - pbGlyph++; - prgbFlag[iFlag] = chFlag; - iFlag++; - for (int i = 0; i < cFlags; i++) - { - prgbFlag[iFlag + i] = chFlag; - } - iFlag += cFlags; - } - } - if (iFlag != cPts) - return false; - - // load x coordinates - iFlag = 0; - while (iFlag < cPts) - { - if (prgbFlag[iFlag] & SimpleGlyph::XShort) - { - prgnX[iFlag] = *pbGlyph; - if (!(prgbFlag[iFlag] & SimpleGlyph::XIsPos)) - { - prgnX[iFlag] = -prgnX[iFlag]; - } - pbGlyph++; - } - else - { - if (prgbFlag[iFlag] & SimpleGlyph::XIsSame) - { - prgnX[iFlag] = 0; - // do NOT increment pbGlyph - } - else - { - prgnX[iFlag] = read(*(const int16 *)pbGlyph); - pbGlyph += sizeof(int16); - } - } - iFlag++; - } - - // load y coordinates - iFlag = 0; - while (iFlag < cPts) - { - if (prgbFlag[iFlag] & SimpleGlyph::YShort) - { - prgnY[iFlag] = *pbGlyph; - if (!(prgbFlag[iFlag] & SimpleGlyph::YIsPos)) - { - prgnY[iFlag] = -prgnY[iFlag]; - } - pbGlyph++; - } - else - { - if (prgbFlag[iFlag] & SimpleGlyph::YIsSame) - { - prgnY[iFlag] = 0; - // do NOT increment pbGlyph - } - else - { - prgnY[iFlag] = read(*(const int16 *)pbGlyph); - pbGlyph += sizeof(int16); - } - } - iFlag++; - } - - cnPoints = cPts; - return true; -} - -/*---------------------------------------------------------------------------------------------- - Fill prgnCompId with the component Glyph IDs from pSimpleGlyf. - Client must allocate space before calling. - pSimpleGlyf - assumed to point to a composite glyph - cCompIdTotal - the number of elements in prgnCompId - cCompId - the total number of Glyph IDs stored in prgnCompId - Return true if successful, false otherwise - False could indicate a non-composite glyph or the input array was not big enough -----------------------------------------------------------------------------------------------*/ -bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId, - size_t cnCompIdTotal, size_t & cnCompId) -{ - using namespace Sfnt; - - if (GlyfContourCount(pSimpleGlyf) >= 0) - return false; - - const Sfnt::SimpleGlyph * pGlyph = reinterpret_cast<const Sfnt::SimpleGlyph *>(pSimpleGlyf); - // for a composite glyph, the special data begins here - const uint8 * pbGlyph = reinterpret_cast<const uint8 *>(&pGlyph->end_pts_of_contours[0]); - - uint16 GlyphFlags; - size_t iCurrentComp = 0; - do - { - GlyphFlags = read(*((const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - prgnCompId[iCurrentComp++] = read(*((const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - if (iCurrentComp >= cnCompIdTotal) - return false; - int nOffset = 0; - nOffset += GlyphFlags & CompoundGlyph::Arg1Arg2Words ? 4 : 2; - nOffset += GlyphFlags & CompoundGlyph::HaveScale ? 2 : 0; - nOffset += GlyphFlags & CompoundGlyph::HaveXAndYScale ? 4 : 0; - nOffset += GlyphFlags & CompoundGlyph::HaveTwoByTwo ? 8 : 0; - pbGlyph += nOffset; - } while (GlyphFlags & CompoundGlyph::MoreComponents); - - cnCompId = iCurrentComp; - - return true; -} - -/*---------------------------------------------------------------------------------------------- - Return info on how a component glyph is to be placed - pSimpleGlyph - assumed to point to a composite glyph - nCompId - glyph id for component of interest - bOffset - if true, a & b are the x & y offsets for this component - if false, b is the point on this component that is attaching to point a on the - preceding glyph - Return true if successful, false otherwise - False could indicate a non-composite glyph or that component wasn't found -----------------------------------------------------------------------------------------------*/ -bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId, - bool fOffset, int & a, int & b) -{ - using namespace Sfnt; - - if (GlyfContourCount(pSimpleGlyf) >= 0) - return false; - - const Sfnt::SimpleGlyph * pGlyph = reinterpret_cast<const Sfnt::SimpleGlyph *>(pSimpleGlyf); - // for a composite glyph, the special data begins here - const uint8 * pbGlyph = reinterpret_cast<const uint8 *>(&pGlyph->end_pts_of_contours[0]); - - uint16 GlyphFlags; - do - { - GlyphFlags = read(*((const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - if (read(*((const uint16 *)pbGlyph)) == nCompId) - { - pbGlyph += sizeof(uint16); // skip over glyph id of component - fOffset = (GlyphFlags & CompoundGlyph::ArgsAreXYValues) == CompoundGlyph::ArgsAreXYValues; - - if (GlyphFlags & CompoundGlyph::Arg1Arg2Words ) - { - a = read(*(const int16 *)pbGlyph); - pbGlyph += sizeof(int16); - b = read(*(const int16 *)pbGlyph); - pbGlyph += sizeof(int16); - } - else - { // args are signed bytes - a = *pbGlyph++; - b = *pbGlyph++; - } - return true; - } - pbGlyph += sizeof(uint16); // skip over glyph id of component - int nOffset = 0; - nOffset += GlyphFlags & CompoundGlyph::Arg1Arg2Words ? 4 : 2; - nOffset += GlyphFlags & CompoundGlyph::HaveScale ? 2 : 0; - nOffset += GlyphFlags & CompoundGlyph::HaveXAndYScale ? 4 : 0; - nOffset += GlyphFlags & CompoundGlyph::HaveTwoByTwo ? 8 : 0; - pbGlyph += nOffset; - } while (GlyphFlags & CompoundGlyph::MoreComponents); - - // didn't find requested component - fOffset = true; - a = 0; - b = 0; - return false; -} - -/*---------------------------------------------------------------------------------------------- - Return info on how a component glyph is to be transformed - pSimpleGlyph - assumed to point to a composite glyph - nCompId - glyph id for component of interest - flt11, flt11, flt11, flt11 - a 2x2 matrix giving the transform - bTransOffset - whether to transform the offset from above method - The spec is unclear about the meaning of this flag - Currently - initialize to true for MS rasterizer and false for Mac rasterizer, then - on return it will indicate whether transform should apply to offset (MSDN CD 10/99) - Return true if successful, false otherwise - False could indicate a non-composite glyph or that component wasn't found -----------------------------------------------------------------------------------------------*/ -bool GetComponentTransform(const void * pSimpleGlyf, int nCompId, - float & flt11, float & flt12, float & flt21, float & flt22, - bool & fTransOffset) -{ - using namespace Sfnt; - - if (GlyfContourCount(pSimpleGlyf) >= 0) - return false; - - const Sfnt::SimpleGlyph * pGlyph = reinterpret_cast<const Sfnt::SimpleGlyph *>(pSimpleGlyf); - // for a composite glyph, the special data begins here - const uint8 * pbGlyph = reinterpret_cast<const uint8 *>(&pGlyph->end_pts_of_contours[0]); - - uint16 GlyphFlags; - do - { - GlyphFlags = read(*((const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - if (read(*((const uint16 *)pbGlyph)) == nCompId) - { - pbGlyph += sizeof(uint16); // skip over glyph id of component - pbGlyph += GlyphFlags & CompoundGlyph::Arg1Arg2Words ? 4 : 2; // skip over placement data - - if (fTransOffset) // MS rasterizer - fTransOffset = !(GlyphFlags & CompoundGlyph::UnscaledOffset); - else // Apple rasterizer - fTransOffset = (GlyphFlags & CompoundGlyph::ScaledOffset) != 0; - - if (GlyphFlags & CompoundGlyph::HaveScale) - { - flt11 = fixed_to_float<14>(read(*(const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - flt12 = 0; - flt21 = 0; - flt22 = flt11; - } - else if (GlyphFlags & CompoundGlyph::HaveXAndYScale) - { - flt11 = fixed_to_float<14>(read(*(const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - flt12 = 0; - flt21 = 0; - flt22 = fixed_to_float<14>(read(*(const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - } - else if (GlyphFlags & CompoundGlyph::HaveTwoByTwo) - { - flt11 = fixed_to_float<14>(read(*(const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - flt12 = fixed_to_float<14>(read(*(const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - flt21 = fixed_to_float<14>(read(*(const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - flt22 = fixed_to_float<14>(read(*(const uint16 *)pbGlyph)); - pbGlyph += sizeof(uint16); - } - else - { // identity transform - flt11 = 1.0; - flt12 = 0.0; - flt21 = 0.0; - flt22 = 1.0; - } - return true; - } - pbGlyph += sizeof(uint16); // skip over glyph id of component - int nOffset = 0; - nOffset += GlyphFlags & CompoundGlyph::Arg1Arg2Words ? 4 : 2; - nOffset += GlyphFlags & CompoundGlyph::HaveScale ? 2 : 0; - nOffset += GlyphFlags & CompoundGlyph::HaveXAndYScale ? 4 : 0; - nOffset += GlyphFlags & CompoundGlyph::HaveTwoByTwo ? 8 : 0; - pbGlyph += nOffset; - } while (GlyphFlags & CompoundGlyph::MoreComponents); - - // didn't find requested component - fTransOffset = false; - flt11 = 1; - flt12 = 0; - flt21 = 0; - flt22 = 1; - return false; -} - -/*---------------------------------------------------------------------------------------------- - Return a pointer into the glyf table based on the given tables and Glyph ID - Since this method doesn't check for spaces, it is good to call IsSpace before using it. - Return NULL on error. -----------------------------------------------------------------------------------------------*/ -void * GlyfLookup(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, - size_t lLocaSize, const void * pHead) -{ - // test for valid glyph id - // CheckTable verifies the index_to_loc_format is valid - - const Sfnt::FontHeader * pTable - = reinterpret_cast<const Sfnt::FontHeader *>(pHead); - - if (read(pTable->index_to_loc_format) == Sfnt::FontHeader::ShortIndexLocFormat) - { // loca entries are two bytes (and have been divided by two) - if (nGlyphId >= (lLocaSize >> 1) - 1) // don't allow nGlyphId to access sentinel - throw std::out_of_range("glyph id out of range for font"); - } - if (read(pTable->index_to_loc_format) == Sfnt::FontHeader::LongIndexLocFormat) - { // loca entries are four bytes - if (nGlyphId >= (lLocaSize >> 2) - 1) - throw std::out_of_range("glyph id out of range for font"); - } - - long lGlyfOffset = LocaLookup(nGlyphId, pLoca, lLocaSize, pHead); - void * pSimpleGlyf = GlyfLookup(pGlyf, lGlyfOffset); // invalid loca offset returns null - return pSimpleGlyf; -} - -/*---------------------------------------------------------------------------------------------- - Determine if a particular Glyph ID has any data in the glyf table. If it is white space, - there will be no glyf data, though there will be metric data in hmtx, etc. -----------------------------------------------------------------------------------------------*/ -bool IsSpace(gr::gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead) -{ - size_t lGlyfOffset = LocaLookup(nGlyphId, pLoca, lLocaSize, pHead); - - // the +1 should always work because there is a sentinel value at the end of the loca table - size_t lNextGlyfOffset = LocaLookup(nGlyphId + 1, pLoca, lLocaSize, pHead); - - return (lNextGlyfOffset - lGlyfOffset) == 0; -} - -/*---------------------------------------------------------------------------------------------- - Determine if a particular Glyph ID is a multi-level composite. - This is probably not needed since support for multi-level composites has been added. -----------------------------------------------------------------------------------------------*/ -bool IsDeepComposite(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, - long lLocaSize, const void * pHead) -{ - if (IsSpace(nGlyphId, pLoca, lLocaSize, pHead)) {return false;} - - void * pSimpleGlyf = GlyfLookup(nGlyphId, pGlyf, pLoca, lLocaSize, pHead); - if (pSimpleGlyf == NULL) - return false; // no way to really indicate an error occured here - - if (GlyfContourCount(pSimpleGlyf) >= 0) - return false; - - int rgnCompId[kMaxGlyphComponents]; // assumes only a limited number of glyph components - size_t cCompIdTotal = kMaxGlyphComponents; - size_t cCompId = 0; - - if (!GetComponentGlyphIds(pSimpleGlyf, rgnCompId, cCompIdTotal, cCompId)) - return false; - - for (size_t i = 0; i < cCompId; i++) - { - pSimpleGlyf = GlyfLookup(static_cast<gr::gid16>(rgnCompId[i]), - pGlyf, pLoca, lLocaSize, pHead); - if (pSimpleGlyf == NULL) {return false;} - - if (GlyfContourCount(pSimpleGlyf) < 0) - return true; - } - - return false; -} - -/*---------------------------------------------------------------------------------------------- - Get the bounding box coordinates based on the given tables and Glyph ID - Handles both simple and composite glyphs. - Return true if successful, false otherwise. On false, all point values will be INT_MIN - False may indicate a white space glyph -----------------------------------------------------------------------------------------------*/ -bool GlyfBox(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, - size_t lLocaSize, const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax) -{ - xMin = yMin = xMax = yMax = INT_MIN; - - if (IsSpace(nGlyphId, pLoca, lLocaSize, pHead)) {return false;} - - void * pSimpleGlyf = GlyfLookup(nGlyphId, pGlyf, pLoca, lLocaSize, pHead); - if (pSimpleGlyf == NULL) {return false;} - - return GlyfBox(pSimpleGlyf, xMin, yMin, xMax, yMax); -} - -/*---------------------------------------------------------------------------------------------- - Get the number of contours based on the given tables and Glyph ID. - Handles both simple and composite glyphs. - Return true if successful, false otherwise. On false, cnContours will be INT_MIN - False may indicate a white space glyph (or component). -----------------------------------------------------------------------------------------------*/ -bool GlyfContourCount(gr::gid16 nGlyphId, const void * pGlyf, - const void * pLoca, size_t lLocaSize, const void * pHead, size_t & cnContours) -{ - cnContours = static_cast<size_t>(INT_MIN); - - if (IsSpace(nGlyphId, pLoca, lLocaSize, pHead)) {return false;} - - void * pSimpleGlyf = GlyfLookup(nGlyphId, pGlyf, pLoca, lLocaSize, pHead); - if (pSimpleGlyf == NULL) {return false;} - - int cRtnContours = GlyfContourCount(pSimpleGlyf); - if (cRtnContours >= 0) - { - cnContours = size_t(cRtnContours); - return true; - } - - //handle composite glyphs - - int rgnCompId[kMaxGlyphComponents]; // assumes only a limted number of glyph components - size_t cCompIdTotal = kMaxGlyphComponents; - size_t cCompId = 0; - - if (!GetComponentGlyphIds(pSimpleGlyf, rgnCompId, cCompIdTotal, cCompId)) - return false; - - cRtnContours = 0; - int cTmp = 0; - for (size_t i = 0; i < cCompId; i++) - { - if (IsSpace(static_cast<gr::gid16>(rgnCompId[i]), pLoca, lLocaSize, pHead)) {return false;} - pSimpleGlyf = GlyfLookup(static_cast<gr::gid16>(rgnCompId[i]), pGlyf, - pLoca, lLocaSize, pHead); - if (pSimpleGlyf == 0) {return false;} - if ((cTmp = GlyfContourCount(pSimpleGlyf)) < 0) - { - size_t cNest = 0; - if (!GlyfContourCount(static_cast<gr::gid16>(rgnCompId[i]), pGlyf, pLoca, lLocaSize, - pHead, cNest)) - return false; - cTmp = (int) cNest; - } - cRtnContours += cTmp; - } - - cnContours = size_t(cRtnContours); - return true; -} - -/*---------------------------------------------------------------------------------------------- - Get the point numbers for the end points of the glyph contours based on the given tables - and Glyph ID. - Handles both simple and composite glyphs. - cnPoints - count of contours from GlyfContourCount (same as number of end points) - prgnContourEndPoints - should point to a buffer large enough to hold cnPoints integers - Return true if successful, false otherwise. On false, all end points are INT_MIN - False may indicate a white space glyph (or component). -----------------------------------------------------------------------------------------------*/ -bool GlyfContourEndPoints(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, - size_t lLocaSize, const void * pHead, - int * prgnContourEndPoint, size_t & cnPoints) -{ - std::fill_n(prgnContourEndPoint, cnPoints, INT_MIN); - - if (IsSpace(nGlyphId, pLoca, lLocaSize, pHead)) {return false;} - - void * pSimpleGlyf = GlyfLookup(nGlyphId, pGlyf, pLoca, lLocaSize, pHead); - if (pSimpleGlyf == NULL) {return false;} - - int cContours = GlyfContourCount(pSimpleGlyf); - int cActualPts = 0; - if (cContours > 0) - return GlyfContourEndPoints(pSimpleGlyf, prgnContourEndPoint, cnPoints, cActualPts); - - // handle composite glyphs - - int rgnCompId[kMaxGlyphComponents]; // assumes no glyph will be made of more than 8 components - size_t cCompIdTotal = kMaxGlyphComponents; - size_t cCompId = 0; - - if (!GetComponentGlyphIds(pSimpleGlyf, rgnCompId, cCompIdTotal, cCompId)) - return false; - - int * prgnCurrentEndPoint = prgnContourEndPoint; - int cCurrentPoints = cnPoints; - int nPrevPt = 0; - for (size_t i = 0; i < cCompId; i++) - { - if (IsSpace(static_cast<gr::gid16>(rgnCompId[i]), pLoca, lLocaSize, pHead)) {return false;} - pSimpleGlyf = GlyfLookup(static_cast<gr::gid16>(rgnCompId[i]), pGlyf, pLoca, lLocaSize, pHead); - if (pSimpleGlyf == NULL) {return false;} - - if (!GlyfContourEndPoints(pSimpleGlyf, prgnCurrentEndPoint, cCurrentPoints, cActualPts)) - { - size_t cNestedPts = ( size_t ) cCurrentPoints; - if (!GlyfContourEndPoints(static_cast<gr::gid16>(rgnCompId[i]), pGlyf, pLoca, lLocaSize, - pHead, prgnCurrentEndPoint, cNestedPts)) - return false; - cActualPts = cCurrentPoints - cNestedPts; - } - // points in composite are numbered sequentially as components are added - // must adjust end point numbers for new point numbers - for (int j = 0; j < cActualPts; j++) - prgnCurrentEndPoint[j] += nPrevPt; - nPrevPt = prgnCurrentEndPoint[cActualPts - 1] + 1; - - prgnCurrentEndPoint += cActualPts; - cCurrentPoints -= cActualPts; - } - - cnPoints = cCurrentPoints; - return true; -} - -/*---------------------------------------------------------------------------------------------- - Get the points for a glyph based on the given tables and Glyph ID - Handles both simple and composite glyphs. - cnPoints - count of points from largest end point obtained from GlyfContourEndPoints - prgnX & prgnY - should point to buffers large enough to hold cnPoints integers - The ranges are parallel so that coordinates for point(n) are found at offset n in - both ranges. These points are in absolute coordinates. - prgfOnCurve - should point to a buffer a large enough to hold cnPoints bytes (bool) - This range is parallel to the prgnX & prgnY - Return true if successful, false otherwise. On false, all points may be INT_MIN - False may indicate a white space glyph (or component), or a corrupt font - // TODO: doesn't support composite glyphs whose components are themselves components - It's not clear from the TTF spec when the transforms should be applied. Should the - transform be done before or after attachment point calcs? (current code - before) - Should the transform be applied to other offsets? (currently - no; however commented - out code is in place so that if CompoundGlyph::UnscaledOffset on the MS rasterizer is - clear (typical) then yes, and if CompoundGlyph::ScaledOffset on the Apple rasterizer is - clear (typical?) then no). See GetComponentTransform. - It's also unclear where point numbering with attachment poinst starts - (currently - first point number is relative to whole glyph, second point number is - relative to current glyph). -----------------------------------------------------------------------------------------------*/ -bool GlyfPoints(gr::gid16 nGlyphId, const void * pGlyf, - const void * pLoca, size_t lLocaSize, const void * pHead, - const int * prgnContourEndPoint, size_t cnEndPoints, - int * prgnX, int * prgnY, bool * prgfOnCurve, size_t & cnPoints) -{ - std::fill_n(prgnX, cnPoints, INT_MAX); - std::fill_n(prgnY, cnPoints, INT_MAX); - - if (IsSpace(nGlyphId, pLoca, lLocaSize, pHead)) - return false; - - void * pSimpleGlyf = GlyfLookup(nGlyphId, pGlyf, pLoca, lLocaSize, pHead); - if (pSimpleGlyf == NULL) - return false; - - int cContours = GlyfContourCount(pSimpleGlyf); - int cActualPts; - if (cContours > 0) - { - if (!GlyfPoints(pSimpleGlyf, prgnX, prgnY, (char *)prgfOnCurve, cnPoints, cActualPts)) - return false; - CalcAbsolutePoints(prgnX, prgnY, cnPoints); - SimplifyFlags((char *)prgfOnCurve, cnPoints); - return true; - } - - // handle composite glyphs - int rgnCompId[kMaxGlyphComponents]; // assumes no glyph will be made of more than 8 components - size_t cCompIdTotal = kMaxGlyphComponents; - size_t cCompId = 0; - - // this will fail if there are more components than there is room for - if (!GetComponentGlyphIds(pSimpleGlyf, rgnCompId, cCompIdTotal, cCompId)) - return false; - - int * prgnCurrentX = prgnX; - int * prgnCurrentY = prgnY; - char * prgbCurrentFlag = (char *)prgfOnCurve; // converting bool to char should be safe - int cCurrentPoints = cnPoints; - bool fOffset = true, fTransOff = true; - int a, b; - float flt11, flt12, flt21, flt22; - // int * prgnPrevX = prgnX; // in case first att pt number relative to preceding glyph - // int * prgnPrevY = prgnY; - for (size_t i = 0; i < cCompId; i++) - { - if (IsSpace(static_cast<gr::gid16>(rgnCompId[i]), pLoca, lLocaSize, pHead)) {return false;} - void * pCompGlyf = GlyfLookup(static_cast<gr::gid16>(rgnCompId[i]), pGlyf, - pLoca, lLocaSize, pHead); - if (pCompGlyf == NULL) {return false;} - - if (!GlyfPoints(pCompGlyf, prgnCurrentX, prgnCurrentY, prgbCurrentFlag, - cCurrentPoints, cActualPts)) - { - size_t cNestedPts = ( size_t ) cCurrentPoints; - if (!GlyfPoints(static_cast<gr::gid16>(rgnCompId[i]), pGlyf, pLoca, lLocaSize, pHead, - prgnContourEndPoint, cnEndPoints, prgnCurrentX, prgnCurrentY, (bool *)prgbCurrentFlag, - cNestedPts)) - { - return false; - } - cActualPts = cCurrentPoints - cNestedPts; - } - else - { - // convert points to absolute coordinates - // do before transform and attachment point placement are applied - CalcAbsolutePoints(prgnCurrentX, prgnCurrentY, cActualPts); - } - - if (!GetComponentPlacement(pSimpleGlyf, rgnCompId[i], fOffset, a, b)) - return false; - if (!GetComponentTransform(pSimpleGlyf, rgnCompId[i], - flt11, flt12, flt21, flt22, fTransOff)) - return false; - bool fIdTrans = flt11 == 1.0 && flt12 == 0.0 && flt21 == 0.0 && flt22 == 1.0; - - // apply transform - see main method note above - // do before attachment point calcs - if (!fIdTrans) - for (int j = 0; j < cActualPts; j++) - { - int x = prgnCurrentX[j]; // store before transform applied - int y = prgnCurrentY[j]; - prgnCurrentX[j] = (int)(x * flt11 + y * flt12); - prgnCurrentY[j] = (int)(x * flt21 + y * flt22); - } - - // apply placement - see main method note above - int nXOff, nYOff; - if (fOffset) // explicit x & y offsets - { - /* ignore fTransOff for now - if (fTransOff && !fIdTrans) - { // transform x & y offsets - nXOff = (int)(a * flt11 + b * flt12); - nYOff = (int)(a * flt21 + b * flt22); - } - else */ - { // don't transform offset - nXOff = a; - nYOff = b; - } - } - else // attachment points - { // in case first point is relative to preceding glyph and second relative to current - // nXOff = prgnPrevX[a] - prgnCurrentX[b]; - // nYOff = prgnPrevY[a] - prgnCurrentY[b]; - // first point number relative to whole composite, second relative to current glyph - nXOff = prgnX[a] - prgnCurrentX[b]; - nYOff = prgnY[a] - prgnCurrentY[b]; - } - for (int j = 0; j < cActualPts; j++) - { - prgnCurrentX[j] += nXOff; - prgnCurrentY[j] += nYOff; - } - - // prgnPrevX = prgnCurrentX; - // prgnPrevY = prgnCurrentY; - prgnCurrentX += cActualPts; - prgnCurrentY += cActualPts; - prgbCurrentFlag += cActualPts; - cCurrentPoints -= cActualPts; - } - - SimplifyFlags((char *)prgfOnCurve, cnPoints); - - cnPoints = cCurrentPoints; - return true; -} - -/*---------------------------------------------------------------------------------------------- - Simplify the meaning of flags to just indicate whether point is on-curve or off-curve. ----------------------------------------------------------------------------------------------*/ -bool SimplifyFlags(char * prgbFlags, int cnPoints) -{ - for (int i = 0; i < cnPoints; i++) - prgbFlags[i] = static_cast<char>(prgbFlags[i] & Sfnt::SimpleGlyph::OnCurve); - return true; -} - -/*---------------------------------------------------------------------------------------------- - Convert relative point coordinates to absolute coordinates - Points are stored in the font such that they are offsets from one another except for the - first point of a glyph. ----------------------------------------------------------------------------------------------*/ -bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints) -{ - int nX = prgnX[0]; - int nY = prgnY[0]; - for (int i = 1; i < cnPoints; i++) - { - prgnX[i] += nX; - nX = prgnX[i]; - prgnY[i] += nY; - nY = prgnY[i]; - } - - return true; -} - -/*---------------------------------------------------------------------------------------------- - Convert a numerical table ID to a string containing the actual name of the table. - Returns native order unsigned long. ----------------------------------------------------------------------------------------------*/ -gr::fontTableId32 TableIdTag(const TableId tid) -{ - assert(sizeof(mapIdToTag) == sizeof(gr::fontTableId32) * ktiLast); - assert(tid < ktiLast); - - return mapIdToTag[tid]; -} - -/*---------------------------------------------------------------------------------------------- - Return the length of the 'name' table in bytes. - Currently used. ----------------------------------------------------------------------------------------------*/ -#if 0 -size_t NameTableLength(const gr::byte * pTable) -{ - gr::byte * pb = (const_cast<gr::byte *>(pTable)) + 2; // skip format - size_t cRecords = *pb++ << 8; cRecords += *pb++; - int dbStringOffset0 = (*pb++) << 8; dbStringOffset0 += *pb++; - int dbMaxStringOffset = 0; - for (size_t irec = 0; irec < cRecords; irec++) - { - int nPlatform = (*pb++) << 8; nPlatform += *pb++; - int nEncoding = (*pb++) << 8; nEncoding += *pb++; - int nLanguage = (*pb++) << 8; nLanguage += *pb++; - int nName = (*pb++) << 8; nName += *pb++; - int cbStringLen = (*pb++) << 8; cbStringLen += *pb++; - int dbStringOffset = (*pb++) << 8; dbStringOffset += *pb++; - if (dbMaxStringOffset < dbStringOffset + cbStringLen) - dbMaxStringOffset = dbStringOffset + cbStringLen; - } - return dbStringOffset0 + dbMaxStringOffset; -} -#endif - -} // end of namespace TtfUtil diff --git a/Build/source/libs/graphite/engine-2.4/src/font/TtfUtil.h b/Build/source/libs/graphite/engine-2.4/src/font/TtfUtil.h deleted file mode 100644 index 5eb26a70db3..00000000000 --- a/Build/source/libs/graphite/engine-2.4/src/font/TtfUtil.h +++ /dev/null @@ -1,153 +0,0 @@ -/*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (C) 2000, 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: TtfUtil.h -Responsibility: Alan Ward -Last reviewed: Not yet. - -Description: - Utility class for handling TrueType font files. -----------------------------------------------------------------------------------------------*/ - -#ifdef _MSC_VER -#pragma once -#endif -#ifndef TTFUTIL_H -#define TTFUTIL_H - -// I don't know why I need to duplicate these there when they are in GrPlatform.h: -#ifdef _MSC_VER -#pragma warning(disable: 4127) // conditional expression is constant -#pragma warning(disable: 4290) // exception specification ignored. -#endif - -#include <cstddef> -#include <stdexcept> -#include "GrPlatform.h" - -// Enumeration used to specify a table in a TTF file -enum TableId -{ - ktiCmap, ktiCvt, ktiCryp, ktiHead, ktiFpgm, ktiGdir, ktiGlyf, - ktiHdmx, ktiHhea, ktiHmtx, ktiLoca, ktiKern, ktiLtsh, ktiMaxp, - ktiName, ktiOs2, ktiPost, ktiPrep, ktiFeat, ktiGlat, ktiGloc, - ktiSilf, ktiSile, ktiSill, - ktiLast /*This gives the enum length - it is not a real table*/ -}; - -/*---------------------------------------------------------------------------------------------- - Class providing utility methods to parse a TrueType font file (TTF). - Callling application handles all file input and memory allocation. - Assumes minimal knowledge of TTF file format. -----------------------------------------------------------------------------------------------*/ -namespace TtfUtil -{ - ////////////////////////////////// tools to find & check TTF tables - bool GetHeaderInfo(size_t & lOffset, size_t & lSize); - bool CheckHeader(const void * pHdr); - bool GetTableDirInfo(const void * pHdr, size_t & lOffset, size_t & lSize); - bool GetTableInfo(TableId ktiTableId, const void * pHdr, const void * pTableDir, - size_t & lOffset, size_t & lSize); - bool CheckTable(TableId ktiTableId, const void * pTable, size_t lTableSize); - - ////////////////////////////////// simple font wide info - size_t GlyphCount(const void * pMaxp); - size_t MaxCompositeComponentCount(const void * pMaxp); - size_t MaxCompositeLevelCount(const void * pMaxp); - size_t LocaGlyphCount(size_t lLocaSize, const void * pHead) throw (std::domain_error); - int DesignUnits(const void * pHead); - int HeadTableCheckSum(const void * pHead); - void HeadTableCreateTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD); - void HeadTableModifyTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD); - bool IsItalic(const void * pHead); - int FontAscent(const void * pOs2); - int FontDescent(const void * pOs2); - bool FontOs2Style(const void *pOs2, bool & fBold, bool & fItalic); - bool Get31EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize); - bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize); - bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize); - bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize); - int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp, - const char * pPostName); - - ////////////////////////////////// utility methods helpful for name table - bool GetNameInfo(const void * pName, int nPlatformId, int nEncodingId, - int nLangId, int nNameId, size_t & lOffset, size_t & lSize); - //size_t NameTableLength(const gr::byte * pTable); - int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId, - int *nameIdList, int cNameIds, short *langIdList); - void SwapWString(void * pWStr, size_t nSize = 0) throw (std::invalid_argument); - - ////////////////////////////////// cmap lookup tools - void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3, - int nEncodingId = 1); - bool CheckCmap31Subtable(const void * pCmap31); - gr::gid16 Cmap31Lookup(const void * pCmap31, int nUnicodeId); - unsigned int Cmap31NextCodepoint(const void *pCmap31, unsigned int nUnicodeId, - int * pRangeKey = 0); - bool CheckCmap310Subtable(const void *pCmap310); - gr::gid16 Cmap310Lookup(const void * pCmap310, unsigned int uUnicodeId); - unsigned int Cmap310NextCodepoint(const void *pCmap310, unsigned int nUnicodeId, - int * pRangeKey = 0); - - ///////////////////////////////// horizontal metric data for a glyph - bool HorMetrics(gr::gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize, - const void * pHhea, int & nLsb, unsigned int & nAdvWid); - - ///////////////////////////////// convert our TableId enum to standard TTF tags - gr::fontTableId32 TableIdTag(const TableId); - - ////////////////////////////////// primitives for loca and glyf lookup - size_t LocaLookup(gr::gid16 nGlyphId, const void * pLoca, size_t lLocaSize, - const void * pHead) throw (std::out_of_range); - void * GlyfLookup(const void * pGlyf, size_t lGlyfOffset); - - ////////////////////////////////// primitves for simple glyph data - bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin, - int & xMax, int & yMax); - - int GlyfContourCount(const void * pSimpleGlyf); - bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint, - int cnPointsTotal, size_t & cnPoints); - bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY, - char * prgbFlag, int cnPointsTotal, int & cnPoints); - - // primitive to find the glyph ids in a composite glyph - bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId, - size_t cnCompIdTotal, size_t & cnCompId); - // primitive to find the placement data for a component in a composite glyph - bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId, - bool fOffset, int & a, int & b); - // primitive to find the transform data for a component in a composite glyph - bool GetComponentTransform(const void * pSimpleGlyf, int nCompId, - float & flt11, float & flt12, float & flt21, float & flt22, bool & fTransOffset); - - ////////////////////////////////// operate on composite or simple glyph (auto glyf lookup) - void * GlyfLookup(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, - size_t lLocaSize, const void * pHead); // primitive used by below methods - - // below are primary user methods for handling glyf data - bool IsSpace(gr::gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead); - bool IsDeepComposite(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, - size_t lLocaSize, const void * pHead); - - bool GlyfBox(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, size_t lLocaSize, - const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax); - bool GlyfContourCount(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, - size_t lLocaSize, const void *pHead, size_t & cnContours); - bool GlyfContourEndPoints(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, - size_t lLocaSize, const void * pHead, int * prgnContourEndPoint, size_t & cnPoints); - bool GlyfPoints(gr::gid16 nGlyphId, const void * pGlyf, const void * pLoca, - size_t lLocaSize, const void * pHead, const int * prgnContourEndPoint, size_t cnEndPoints, - int * prgnX, int * prgnY, bool * prgfOnCurve, size_t & cnPoints); - - // utitily method used by high-level GlyfPoints - bool SimplifyFlags(char * prgbFlags, int cnPoints); - bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints); - -} // end of namespace TtfUtil - -#endif |