tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FeatureMap.cpp (9431B)


      1 /*  GRAPHITE2 LICENSING
      2 
      3    Copyright 2010, SIL International
      4    All rights reserved.
      5 
      6    This library is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU Lesser General Public License as published
      8    by the Free Software Foundation; either version 2.1 of License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14    Lesser General Public License for more details.
     15 
     16    You should also have received a copy of the GNU Lesser General Public
     17    License along with this library in the file named "LICENSE".
     18    If not, write to the Free Software Foundation, 51 Franklin Street,
     19    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
     20    internet at http://www.fsf.org/licenses/lgpl.html.
     21 
     22 Alternatively, the contents of this file may be used under the terms of the
     23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
     24 License, as published by the Free Software Foundation, either version 2
     25 of the License or (at your option) any later version.
     26 */
     27 #include <cstring>
     28 
     29 #include "inc/Main.h"
     30 #include "inc/bits.h"
     31 #include "inc/Endian.h"
     32 #include "inc/FeatureMap.h"
     33 #include "inc/FeatureVal.h"
     34 #include "graphite2/Font.h"
     35 #include "inc/TtfUtil.h"
     36 #include <cstdlib>
     37 #include "inc/Face.h"
     38 
     39 
     40 using namespace graphite2;
     41 
     42 namespace
     43 {
     44    static int cmpNameAndFeatures(const void *ap, const void *bp)
     45    {
     46        const NameAndFeatureRef & a = *static_cast<const NameAndFeatureRef *>(ap),
     47                                & b = *static_cast<const NameAndFeatureRef *>(bp);
     48        return (a < b ? -1 : (b < a ? 1 : 0));
     49    }
     50 
     51    const size_t    FEAT_HEADER     = sizeof(uint32) + 2*sizeof(uint16) + sizeof(uint32),
     52                    FEATURE_SIZE    = sizeof(uint32)
     53                                    + 2*sizeof(uint16)
     54                                    + sizeof(uint32)
     55                                    + 2*sizeof(uint16),
     56                    FEATURE_SETTING_SIZE = sizeof(int16) + sizeof(uint16);
     57 
     58    uint16 readFeatureSettings(const byte * p, FeatureSetting * s, size_t num_settings)
     59    {
     60        uint16 max_val = 0;
     61        for (FeatureSetting * const end = s + num_settings; s != end; ++s)
     62        {
     63            const int16 value = be::read<int16>(p);
     64            ::new (s) FeatureSetting(value, be::read<uint16>(p));
     65            if (uint16(value) > max_val)    max_val = value;
     66        }
     67 
     68        return max_val;
     69    }
     70 }
     71 
     72 FeatureRef::FeatureRef(const Face & face,
     73    unsigned short & bits_offset, uint32 max_val,
     74    uint32 name, uint16 uiName, flags_t flags,
     75    FeatureSetting *settings, uint16 num_set) throw()
     76 : m_face(&face),
     77  m_nameValues(settings),
     78  m_mask(mask_over_val(max_val)),
     79  m_max(max_val),
     80  m_id(name),
     81  m_nameid(uiName),
     82  m_numSet(num_set),
     83  m_flags(flags)
     84 {
     85    const uint8 need_bits = bit_set_count(m_mask);
     86    m_index = (bits_offset + need_bits) / SIZEOF_CHUNK;
     87    if (m_index > bits_offset / SIZEOF_CHUNK)
     88        bits_offset = m_index*SIZEOF_CHUNK;
     89    m_bits = bits_offset % SIZEOF_CHUNK;
     90    bits_offset += need_bits;
     91    m_mask <<= m_bits;
     92 }
     93 
     94 FeatureRef::~FeatureRef() throw()
     95 {
     96    free(m_nameValues);
     97 }
     98 
     99 bool FeatureMap::readFeats(const Face & face)
    100 {
    101    const Face::Table feat(face, TtfUtil::Tag::Feat);
    102    const byte * p = feat;
    103    if (!p) return true;
    104    if (feat.size() < FEAT_HEADER) return false;
    105 
    106    const byte *const feat_start = p,
    107               *const feat_end = p + feat.size();
    108 
    109    const uint32 version = be::read<uint32>(p);
    110    m_numFeats = be::read<uint16>(p);
    111    be::skip<uint16>(p);
    112    be::skip<uint32>(p);
    113 
    114    // Sanity checks
    115    if (m_numFeats == 0)    return true;
    116    if (version < 0x00010000 ||
    117        p + m_numFeats*FEATURE_SIZE > feat_end)
    118    {   //defensive
    119        m_numFeats = 0;
    120        return false;
    121    }
    122 
    123    m_feats = new FeatureRef [m_numFeats];
    124    uint16 * const  defVals = gralloc<uint16>(m_numFeats);
    125    if (!defVals || !m_feats) return false;
    126    unsigned short bits = 0;     //to cause overflow on first Feature
    127 
    128    for (int i = 0, ie = m_numFeats; i != ie; i++)
    129    {
    130        const uint32    label   = version < 0x00020000 ? be::read<uint16>(p) : be::read<uint32>(p);
    131        const uint16    num_settings = be::read<uint16>(p);
    132        if (version >= 0x00020000)
    133            be::skip<uint16>(p);
    134        const uint32    settings_offset = be::read<uint32>(p);
    135        const uint16    flags  = be::read<uint16>(p),
    136                        uiName = be::read<uint16>(p);
    137 
    138        if (settings_offset > size_t(feat_end - feat_start)
    139            || settings_offset + num_settings * FEATURE_SETTING_SIZE > size_t(feat_end - feat_start))
    140        {
    141            free(defVals);
    142            return false;
    143        }
    144 
    145        FeatureSetting *uiSet;
    146        uint32 maxVal;
    147        if (num_settings != 0)
    148        {
    149            uiSet = gralloc<FeatureSetting>(num_settings);
    150            if (!uiSet)
    151            {
    152                free(defVals);
    153                return false;
    154            }
    155            maxVal = readFeatureSettings(feat_start + settings_offset, uiSet, num_settings);
    156            defVals[i] = uiSet[0].value();
    157        }
    158        else
    159        {
    160            uiSet = 0;
    161            maxVal = 0xffffffff;
    162            defVals[i] = 0;
    163        }
    164 
    165        ::new (m_feats + i) FeatureRef (face, bits, maxVal,
    166                                       label, uiName, 
    167                                       FeatureRef::flags_t(flags),
    168                                       uiSet, num_settings);
    169    }
    170    new (&m_defaultFeatures) Features(bits/(sizeof(uint32)*8) + 1, *this);
    171    m_pNamedFeats = new NameAndFeatureRef[m_numFeats];
    172    if (!m_pNamedFeats)
    173    {
    174        free(defVals);
    175        return false;
    176    }
    177    for (int i = 0; i < m_numFeats; ++i)
    178    {
    179        m_feats[i].applyValToFeature(defVals[i], m_defaultFeatures);
    180        m_pNamedFeats[i] = m_feats[i];
    181    }
    182 
    183    free(defVals);
    184 
    185    qsort(m_pNamedFeats, m_numFeats, sizeof(NameAndFeatureRef), &cmpNameAndFeatures);
    186 
    187    return true;
    188 }
    189 
    190 bool SillMap::readFace(const Face & face)
    191 {
    192    if (!m_FeatureMap.readFeats(face)) return false;
    193    if (!readSill(face)) return false;
    194    return true;
    195 }
    196 
    197 
    198 bool SillMap::readSill(const Face & face)
    199 {
    200    const Face::Table sill(face, TtfUtil::Tag::Sill);
    201    const byte *p = sill;
    202 
    203    if (!p) return true;
    204    if (sill.size() < 12) return false;
    205    if (be::read<uint32>(p) != 0x00010000UL) return false;
    206    m_numLanguages = be::read<uint16>(p);
    207    m_langFeats = new LangFeaturePair[m_numLanguages];
    208    if (!m_langFeats || !m_FeatureMap.m_numFeats) { m_numLanguages = 0; return true; }        //defensive
    209 
    210    p += 6;     // skip the fast search
    211    if (sill.size() < m_numLanguages * 8U + 12) return false;
    212 
    213    for (int i = 0; i < m_numLanguages; i++)
    214    {
    215        uint32 langid = be::read<uint32>(p);
    216        uint16 numSettings = be::read<uint16>(p);
    217        uint16 offset = be::read<uint16>(p);
    218        if (offset + 8U * numSettings > sill.size() && numSettings > 0) return false;
    219        Features* feats = new Features(m_FeatureMap.m_defaultFeatures);
    220        if (!feats) return false;
    221        const byte *pLSet = sill + offset;
    222 
    223        // Apply langauge specific settings
    224        for (int j = 0; j < numSettings; j++)
    225        {
    226            uint32 name = be::read<uint32>(pLSet);
    227            uint16 val = be::read<uint16>(pLSet);
    228            pLSet += 2;
    229            const FeatureRef* pRef = m_FeatureMap.findFeatureRef(name);
    230            if (pRef)   pRef->applyValToFeature(val, *feats);
    231        }
    232        // Add the language id feature which is always feature id 1
    233        const FeatureRef* pRef = m_FeatureMap.findFeatureRef(1);
    234        if (pRef)   pRef->applyValToFeature(langid, *feats);
    235 
    236        m_langFeats[i].m_lang = langid;
    237        m_langFeats[i].m_pFeatures = feats;
    238    }
    239    return true;
    240 }
    241 
    242 
    243 Features* SillMap::cloneFeatures(uint32 langname/*0 means default*/) const
    244 {
    245    if (langname)
    246    {
    247        // the number of languages in a font is usually small e.g. 8 in Doulos
    248        // so this loop is not very expensive
    249        for (uint16 i = 0; i < m_numLanguages; i++)
    250        {
    251            if (m_langFeats[i].m_lang == langname)
    252                return new Features(*m_langFeats[i].m_pFeatures);
    253        }
    254    }
    255    return new Features (m_FeatureMap.m_defaultFeatures);
    256 }
    257 
    258 
    259 
    260 const FeatureRef *FeatureMap::findFeatureRef(uint32 name) const
    261 {
    262    NameAndFeatureRef *it;
    263 
    264    for (it = m_pNamedFeats; it < m_pNamedFeats + m_numFeats; ++it)
    265        if (it->m_name == name)
    266            return it->m_pFRef;
    267    return NULL;
    268 }
    269 
    270 bool FeatureRef::applyValToFeature(uint32 val, Features & pDest) const
    271 {
    272    if (val>maxVal() || !m_face)
    273      return false;
    274    if (pDest.m_pMap==NULL)
    275      pDest.m_pMap = &m_face->theSill().theFeatureMap();
    276    else
    277      if (pDest.m_pMap!=&m_face->theSill().theFeatureMap())
    278        return false;       //incompatible
    279    if (m_index >= pDest.size())
    280        pDest.resize(m_index+1);
    281    pDest[m_index] &= ~m_mask;
    282    pDest[m_index] |= (uint32(val) << m_bits);
    283    return true;
    284 }
    285 
    286 uint32 FeatureRef::getFeatureVal(const Features& feats) const
    287 {
    288  if (m_index < feats.size() && m_face
    289      && &m_face->theSill().theFeatureMap()==feats.m_pMap)
    290    return (feats[m_index] & m_mask) >> m_bits;
    291  else
    292    return 0;
    293 }