diff options
Diffstat (limited to 'Build/source/libs/graphite/src/segment/GrFeature.cpp')
-rw-r--r-- | Build/source/libs/graphite/src/segment/GrFeature.cpp | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/Build/source/libs/graphite/src/segment/GrFeature.cpp b/Build/source/libs/graphite/src/segment/GrFeature.cpp new file mode 100644 index 00000000000..61970d56949 --- /dev/null +++ b/Build/source/libs/graphite/src/segment/GrFeature.cpp @@ -0,0 +1,321 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 1999, 2001 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: GrFeature.cpp +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + Implements the GrFeature class. +-------------------------------------------------------------------------------*//*:End Ignore*/ + +//:>******************************************************************************************** +//:> Include files +//:>******************************************************************************************** +#include "Main.h" +#include <cstring> + +#ifdef _MSC_VER +#pragma hdrstop +#endif +#undef THIS_FILE +DEFINE_THIS_FILE + +//:>******************************************************************************************** +//:> Forward declarations +//:>******************************************************************************************** + +//:>******************************************************************************************** +//:> Local Constants and static variables +//:>******************************************************************************************** + +namespace gr +{ + +//:>******************************************************************************************** +//:> GrFeature Methods +//:>******************************************************************************************** + +/*---------------------------------------------------------------------------------------------- + Initialize the feature. +----------------------------------------------------------------------------------------------*/ +void GrFeature::Initialize(featid nID, int nNameId, int cfset, int nDefault) +{ + m_nID = nID; + m_nNameId = nNameId; + m_nDefault = nDefault; + + m_vnVal.resize(cfset); + for (unsigned int ifset = 0; ifset < m_vnVal.size(); ifset++) + m_vnVal[ifset] = INT_MAX; + m_vnNameId.resize(cfset); +} + +/*---------------------------------------------------------------------------------------------- + Return the feature settings. +----------------------------------------------------------------------------------------------*/ +int GrFeature::Settings(int cMax, int * prgnVal) +{ + int cRet = min(cMax, signed(m_vnVal.size())); + for (int ifset = 0; ifset < cRet; ifset++) + prgnVal[ifset] = m_vnVal[ifset]; + return cRet; +} + +/*---------------------------------------------------------------------------------------------- + Add a feature setting. +----------------------------------------------------------------------------------------------*/ +void GrFeature::AddSetting(int nVal, int nNameId) +{ + Assert(nVal != INT_MAX); + unsigned int ifset; + for (ifset = 0; ifset < m_vnVal.size(); ifset++) + { + if (m_vnVal[ifset] == nVal) + return; // already there + } + for (ifset = 0; ifset < m_vnVal.size(); ifset++) + { + if (m_vnVal[ifset] == INT_MAX) + { + m_vnVal[ifset] = nVal; + m_vnNameId[ifset] = nNameId; + return; + } + } + m_vnVal.push_back(nVal); + m_vnNameId.push_back(nNameId); +} + +/*---------------------------------------------------------------------------------------------- + Return true if the given setting is valid according to the font's feature table. +----------------------------------------------------------------------------------------------*/ +bool GrFeature::IsValidSetting(int nVal) +{ + for (unsigned int ifset = 0; ifset < m_vnVal.size(); ifset++) + { + if (m_vnVal[ifset] == nVal) + return true; + } + return false; +} + +/*---------------------------------------------------------------------------------------------- + Read the feature label from the name table. +----------------------------------------------------------------------------------------------*/ +std::wstring GrFeature::Label(GrEngine * pgreng, int nLang) +{ + std::wstring stu = pgreng->StringFromNameTable(nLang, m_nNameId); + if (stu == L"NoName") + stu.erase(); + return stu; +} + +/*---------------------------------------------------------------------------------------------- + Read the feature value label from the name table. +----------------------------------------------------------------------------------------------*/ +std::wstring GrFeature::SettingLabel(GrEngine * pgreng, int nVal, int nLang) +{ + for (unsigned int ifset = 0; ifset < m_vnVal.size(); ifset++) + { + if (m_vnVal[ifset] == nVal) + { + std::wstring stu = pgreng->StringFromNameTable(nLang, m_vnNameId[ifset]); + if (stu == L"NoName") + stu.erase(); + return stu; + } + } + Assert(false); // setting is not valid + return L""; +} + +/*---------------------------------------------------------------------------------------------- + Return the given setting value. +----------------------------------------------------------------------------------------------*/ +int GrFeature::NthSetting(int ifset) +{ + if (ifset >= (int)m_vnVal.size()) + return -1; + else + return m_vnVal[ifset]; +} + +/*---------------------------------------------------------------------------------------------- + Read the feature value label for the given index. +----------------------------------------------------------------------------------------------*/ +std::wstring GrFeature::NthSettingLabel(GrEngine * pgreng, int ifset, int nLang) +{ + std::wstring stu; + + if (ifset >= (int)m_vnVal.size()) + stu.erase(); + else + { + stu = pgreng->StringFromNameTable(nLang, m_vnNameId[ifset]); + if (stu == L"NoName") + stu.erase(); + } + return stu; +} + +/*---------------------------------------------------------------------------------------------- + Return the feature setting label. +----------------------------------------------------------------------------------------------*/ +// void GrFeature::SetSettingLabel(int nVal, std::wstring stuLabel, int nLang) +// { +// for (int ifset = 0; ifset < m_vfset.size(); ifset++) +// { +// if (m_vfset[ifset].m_nVal == nVal) +// { +// m_vfset[ifset].m_hmnstuLabels.Insert(nLang, stuLabel, true); +// return; +// } +// } +// Assert(false); // setting is not valid +// } + + +//:>******************************************************************************************** +//:> GrLangTable Methods +//:>******************************************************************************************** + +/*---------------------------------------------------------------------------------------------- + Read the languages from the font. +----------------------------------------------------------------------------------------------*/ +bool GrLangTable::ReadFromFont(GrIStream * pgrstrm, int fxdVersion) +{ + GrIStream & grstrm = *pgrstrm; + + // number of languages + m_clang = (size_t)grstrm.ReadUShortFromFont(); + + // search constants + m_dilangInit = grstrm.ReadUShortFromFont(); + m_cLoop = grstrm.ReadUShortFromFont(); + m_ilangStart = grstrm.ReadUShortFromFont(); + + // Slurp the data into the buffers. The "+1" represents a bogus ending entry that quickly + // gives us the size of the feature list. Note that the resulting data is all big-endian. + int cb = (m_clang + 1) * sizeof(LangEntry); + m_prglang = new LangEntry[m_clang + 1]; + grstrm.ReadBlockFromFont(m_prglang, cb); + + m_cbOffset0 = (lsbf)(m_prglang[0].cbOffsetBIG); + + Assert((lsbf)(m_prglang[m_clang].cFeaturesBIG) == 0); // bogus entry has no settings + cb = (lsbf)(m_prglang[m_clang].cbOffsetBIG) - m_cbOffset0; + Assert(cb % sizeof(FeatSet) == 0); // # of bytes fits nicely into FeatSet class + int cfset = cb / sizeof(FeatSet); + m_prgfset = new FeatSet[cfset]; + m_cfset = cfset; + grstrm.ReadBlockFromFont(m_prgfset, cb); + + return true; +} + +/*---------------------------------------------------------------------------------------------- + Create an empty language table to use for dumb rendering, or when there is no valid + Sill table. +----------------------------------------------------------------------------------------------*/ +void GrLangTable::CreateEmpty() +{ + m_prglang = NULL; + m_prgfset = NULL; + m_clang = 0; + m_dilangInit = 0; + m_cLoop = 0; + m_ilangStart = 0; +} + +/*---------------------------------------------------------------------------------------------- + Return information about the language with the given ID by filling in the given vectors + with the feature ids and values. Will wipe out any data in the vectors already. +----------------------------------------------------------------------------------------------*/ +void GrLangTable::LanguageFeatureSettings(isocode lgcode, + std::vector<featid> & vnFeatId, std::vector<int> & vnValues) +{ + vnFeatId.clear(); + vnValues.clear(); + + int ilang = FindIndex(lgcode); + if (ilang == -1) + return; // no such language: leave vectors empty + + LangEntry * plang = m_prglang + ilang; + int cbOffset = lsbf(plang->cbOffsetBIG) - m_cbOffset0; + Assert(cbOffset % sizeof(FeatSet) == 0); + byte * pbFeatSet = reinterpret_cast<byte*>(m_prgfset) + cbOffset; + FeatSet * pfset = reinterpret_cast<FeatSet*>(pbFeatSet); + for (int ifset = 0; ifset < lsbf(plang->cFeaturesBIG); ifset++) + { + vnFeatId.push_back(lsbf(pfset[ifset].featidBIG)); + vnValues.push_back(lsbf(pfset[ifset].valueBIG)); + } +} + +/*---------------------------------------------------------------------------------------------- + Return the code for the language at the given index. +----------------------------------------------------------------------------------------------*/ +isocode GrLangTable::LanguageCode(size_t ilang) +{ + isocode lgcodeRet; + if (ilang > m_clang) + { + std::fill_n(lgcodeRet.rgch, 4, '\0'); + return lgcodeRet; + } + LangEntry * plang = m_prglang + ilang; + std::copy(plang->rgchCode, plang->rgchCode + 4, lgcodeRet.rgch); + return lgcodeRet; +} + +/*---------------------------------------------------------------------------------------------- + Return the index of the language in the list. +----------------------------------------------------------------------------------------------*/ +int GrLangTable::FindIndex(isocode lgcode) +{ + if (m_clang == 0) + return -1; +#ifdef _DEBUG + int nPowerOf2 = 1; + while (nPowerOf2 <= signed(m_clang)) + nPowerOf2 <<= 1; + nPowerOf2 >>= 1; + // Now nPowerOf2 is the max power of 2 <= m_clang + gAssert((1 << m_cLoop) == nPowerOf2); // m_cLoop == log2(nPowerOf2) + gAssert(m_dilangInit == nPowerOf2); + gAssert(m_ilangStart == m_clang - m_dilangInit); +#endif // _DEBUG + + int dilangCurr = m_dilangInit; + + int ilangCurr = m_ilangStart; // may become < 0 + while (dilangCurr > 0) + { + int nTest; + if (ilangCurr < 0) + nTest = -1; + else + { + LangEntry * plangCurr = m_prglang + ilangCurr; + nTest = strcmp(plangCurr->rgchCode, lgcode.rgch); + } + + if (nTest == 0) + return ilangCurr; + + dilangCurr >>= 1; // divide by 2 + if (nTest < 0) + ilangCurr += dilangCurr; + else // (nTest > 0) + ilangCurr -= dilangCurr; + } + + return -1; +} + +} // namespace gr |