LCOV - code coverage report
Current view: top level - gfx/graphite2/src - FeatureMap.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 142 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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           0 :     static int cmpNameAndFeatures(const void *ap, const void *bp)
      45             :     {
      46           0 :         const NameAndFeatureRef & a = *static_cast<const NameAndFeatureRef *>(ap),
      47           0 :                                 & b = *static_cast<const NameAndFeatureRef *>(bp);
      48           0 :         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           0 :     uint16 readFeatureSettings(const byte * p, FeatureSetting * s, size_t num_settings)
      59             :     {
      60           0 :         uint16 max_val = 0;
      61           0 :         for (FeatureSetting * const end = s + num_settings; s != end; ++s)
      62             :         {
      63           0 :             const int16 value = be::read<int16>(p);
      64           0 :             ::new (s) FeatureSetting(value, be::read<uint16>(p));
      65           0 :             if (uint16(value) > max_val)    max_val = value;
      66             :         }
      67             : 
      68           0 :         return max_val;
      69             :     }
      70             : }
      71             : 
      72           0 : FeatureRef::FeatureRef(const Face & face,
      73             :     unsigned short & bits_offset, uint32 max_val,
      74             :     uint32 name, uint16 uiName, uint16 flags,
      75           0 :     FeatureSetting *settings, uint16 num_set) throw()
      76             : : m_pFace(&face),
      77             :   m_nameValues(settings),
      78           0 :   m_mask(mask_over_val(max_val)),
      79             :   m_max(max_val),
      80             :   m_id(name),
      81             :   m_nameid(uiName),
      82             :   m_flags(flags),
      83           0 :   m_numSet(num_set)
      84             : {
      85           0 :     const uint8 need_bits = bit_set_count(m_mask);
      86           0 :     m_index = (bits_offset + need_bits) / SIZEOF_CHUNK;
      87           0 :     if (m_index > bits_offset / SIZEOF_CHUNK)
      88           0 :         bits_offset = m_index*SIZEOF_CHUNK;
      89           0 :     m_bits = bits_offset % SIZEOF_CHUNK;
      90           0 :     bits_offset += need_bits;
      91           0 :     m_mask <<= m_bits;
      92           0 : }
      93             : 
      94           0 : FeatureRef::~FeatureRef() throw()
      95             : {
      96           0 :     free(m_nameValues);
      97           0 : }
      98             : 
      99           0 : bool FeatureMap::readFeats(const Face & face)
     100             : {
     101           0 :     const Face::Table feat(face, TtfUtil::Tag::Feat);
     102           0 :     const byte * p = feat;
     103           0 :     if (!p) return true;
     104           0 :     if (feat.size() < FEAT_HEADER) return false;
     105             : 
     106           0 :     const byte *const feat_start = p,
     107           0 :                *const feat_end = p + feat.size();
     108             : 
     109           0 :     const uint32 version = be::read<uint32>(p);
     110           0 :     m_numFeats = be::read<uint16>(p);
     111           0 :     be::skip<uint16>(p);
     112           0 :     be::skip<uint32>(p);
     113             : 
     114             :     // Sanity checks
     115           0 :     if (m_numFeats == 0)    return true;
     116           0 :     if (version < 0x00010000 ||
     117           0 :         p + m_numFeats*FEATURE_SIZE > feat_end)
     118             :     {   //defensive
     119           0 :         m_numFeats = 0;
     120           0 :         return false;
     121             :     }
     122             : 
     123           0 :     m_feats = new FeatureRef [m_numFeats];
     124           0 :     uint16 * const  defVals = gralloc<uint16>(m_numFeats);
     125           0 :     if (!defVals || !m_feats) return false;
     126           0 :     unsigned short bits = 0;     //to cause overflow on first Feature
     127             : 
     128           0 :     for (int i = 0, ie = m_numFeats; i != ie; i++)
     129             :     {
     130           0 :         const uint32    label   = version < 0x00020000 ? be::read<uint16>(p) : be::read<uint32>(p);
     131           0 :         const uint16    num_settings = be::read<uint16>(p);
     132           0 :         if (version >= 0x00020000)
     133           0 :             be::skip<uint16>(p);
     134           0 :         const uint32    settings_offset = be::read<uint32>(p);
     135           0 :         const uint16    flags  = be::read<uint16>(p),
     136           0 :                         uiName = be::read<uint16>(p);
     137             : 
     138           0 :         if (settings_offset > size_t(feat_end - feat_start) 
     139           0 :             || settings_offset + num_settings * FEATURE_SETTING_SIZE > size_t(feat_end - feat_start))
     140             :         {
     141           0 :             free(defVals);
     142           0 :             return false;
     143             :         }
     144             : 
     145             :         FeatureSetting *uiSet;
     146             :         uint32 maxVal;
     147           0 :         if (num_settings != 0)
     148             :         {
     149           0 :             uiSet = gralloc<FeatureSetting>(num_settings);
     150           0 :             if (!uiSet)
     151             :             {
     152           0 :                 free(defVals);
     153           0 :                 return false;
     154             :             }
     155           0 :             maxVal = readFeatureSettings(feat_start + settings_offset, uiSet, num_settings);
     156           0 :             defVals[i] = uiSet[0].value();
     157             :         }
     158             :         else
     159             :         {
     160           0 :             uiSet = 0;
     161           0 :             maxVal = 0xffffffff;
     162           0 :             defVals[i] = 0;
     163             :         }
     164             : 
     165           0 :         ::new (m_feats + i) FeatureRef (face, bits, maxVal,
     166             :                                        label, uiName, flags,
     167           0 :                                        uiSet, num_settings);
     168             :     }
     169           0 :     new (&m_defaultFeatures) Features(bits/(sizeof(uint32)*8) + 1, *this);
     170           0 :     m_pNamedFeats = new NameAndFeatureRef[m_numFeats];
     171           0 :     if (!m_pNamedFeats)
     172             :     {
     173           0 :         free(defVals);
     174           0 :         return false;
     175             :     }
     176           0 :     for (int i = 0; i < m_numFeats; ++i)
     177             :     {
     178           0 :         m_feats[i].applyValToFeature(defVals[i], m_defaultFeatures);
     179           0 :         m_pNamedFeats[i] = m_feats+i;
     180             :     }
     181             :     
     182           0 :     free(defVals);
     183             : 
     184           0 :     qsort(m_pNamedFeats, m_numFeats, sizeof(NameAndFeatureRef), &cmpNameAndFeatures);
     185             : 
     186           0 :     return true;
     187             : }
     188             : 
     189           0 : bool SillMap::readFace(const Face & face)
     190             : {
     191           0 :     if (!m_FeatureMap.readFeats(face)) return false;
     192           0 :     if (!readSill(face)) return false;
     193           0 :     return true;
     194             : }
     195             : 
     196             : 
     197           0 : bool SillMap::readSill(const Face & face)
     198             : {
     199           0 :     const Face::Table sill(face, TtfUtil::Tag::Sill);
     200           0 :     const byte *p = sill;
     201             : 
     202           0 :     if (!p) return true;
     203           0 :     if (sill.size() < 12) return false;
     204           0 :     if (be::read<uint32>(p) != 0x00010000UL) return false;
     205           0 :     m_numLanguages = be::read<uint16>(p);
     206           0 :     m_langFeats = new LangFeaturePair[m_numLanguages];
     207           0 :     if (!m_langFeats || !m_FeatureMap.m_numFeats) { m_numLanguages = 0; return true; }        //defensive
     208             : 
     209           0 :     p += 6;     // skip the fast search
     210           0 :     if (sill.size() < m_numLanguages * 8U + 12) return false;
     211             : 
     212           0 :     for (int i = 0; i < m_numLanguages; i++)
     213             :     {
     214           0 :         uint32 langid = be::read<uint32>(p);
     215           0 :         uint16 numSettings = be::read<uint16>(p);
     216           0 :         uint16 offset = be::read<uint16>(p);
     217           0 :         if (offset + 8U * numSettings > sill.size() && numSettings > 0) return false;
     218           0 :         Features* feats = new Features(m_FeatureMap.m_defaultFeatures);
     219           0 :         if (!feats) return false;
     220           0 :         const byte *pLSet = sill + offset;
     221             : 
     222             :         // Apply langauge specific settings
     223           0 :         for (int j = 0; j < numSettings; j++)
     224             :         {
     225           0 :             uint32 name = be::read<uint32>(pLSet);
     226           0 :             uint16 val = be::read<uint16>(pLSet);
     227           0 :             pLSet += 2;
     228           0 :             const FeatureRef* pRef = m_FeatureMap.findFeatureRef(name);
     229           0 :             if (pRef)   pRef->applyValToFeature(val, *feats);
     230             :         }
     231             :         // Add the language id feature which is always feature id 1
     232           0 :         const FeatureRef* pRef = m_FeatureMap.findFeatureRef(1);
     233           0 :         if (pRef)   pRef->applyValToFeature(langid, *feats);
     234             : 
     235           0 :         m_langFeats[i].m_lang = langid;
     236           0 :         m_langFeats[i].m_pFeatures = feats;
     237             :     }
     238           0 :     return true;
     239             : }
     240             : 
     241             : 
     242           0 : Features* SillMap::cloneFeatures(uint32 langname/*0 means default*/) const
     243             : {
     244           0 :     if (langname)
     245             :     {
     246             :         // the number of languages in a font is usually small e.g. 8 in Doulos
     247             :         // so this loop is not very expensive
     248           0 :         for (uint16 i = 0; i < m_numLanguages; i++)
     249             :         {
     250           0 :             if (m_langFeats[i].m_lang == langname)
     251           0 :                 return new Features(*m_langFeats[i].m_pFeatures);
     252             :         }
     253             :     }
     254           0 :     return new Features (m_FeatureMap.m_defaultFeatures);
     255             : }
     256             : 
     257             : 
     258             : 
     259           0 : const FeatureRef *FeatureMap::findFeatureRef(uint32 name) const
     260             : {
     261             :     NameAndFeatureRef *it;
     262             :     
     263           0 :     for (it = m_pNamedFeats; it < m_pNamedFeats + m_numFeats; ++it)
     264           0 :         if (it->m_name == name)
     265           0 :             return it->m_pFRef;
     266           0 :     return NULL;
     267             : }
     268             : 
     269           0 : bool FeatureRef::applyValToFeature(uint32 val, Features & pDest) const
     270             : { 
     271           0 :     if (val>maxVal() || !m_pFace)
     272           0 :       return false;
     273           0 :     if (pDest.m_pMap==NULL)
     274           0 :       pDest.m_pMap = &m_pFace->theSill().theFeatureMap();
     275             :     else
     276           0 :       if (pDest.m_pMap!=&m_pFace->theSill().theFeatureMap())
     277           0 :         return false;       //incompatible
     278           0 :     if (m_index >= pDest.size())
     279           0 :         pDest.resize(m_index+1);
     280           0 :     pDest[m_index] &= ~m_mask;
     281           0 :     pDest[m_index] |= (uint32(val) << m_bits);
     282           0 :     return true;
     283             : }
     284             : 
     285           0 : uint32 FeatureRef::getFeatureVal(const Features& feats) const
     286             : { 
     287           0 :   if (m_index < feats.size() && &m_pFace->theSill().theFeatureMap()==feats.m_pMap) 
     288           0 :     return (feats[m_index] & m_mask) >> m_bits; 
     289             :   else
     290           0 :     return 0;
     291             : }
     292             : 
     293             : 

Generated by: LCOV version 1.13