LCOV - code coverage report
Current view: directory - gfx/graphite2/src - NameTable.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 110 0 0.0 %
Date: 2012-06-02 Functions: 4 0 0.0 %

       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 "inc/Main.h"
      28                 : #include "inc/Endian.h"
      29                 : 
      30                 : #include "inc/NameTable.h"
      31                 : #include "inc/UtfCodec.h"
      32                 : 
      33                 : using namespace graphite2;
      34                 : 
      35               0 : NameTable::NameTable(const void* data, size_t length, uint16 platformId, uint16 encodingID)
      36                 :     :
      37                 :     m_platformId(0), m_encodingId(0), m_languageCount(0),
      38                 :     m_platformOffset(0), m_platformLastRecord(0), m_nameDataLength(0),
      39               0 :     m_table(0), m_nameData(NULL)
      40                 : {
      41               0 :     void *pdata = malloc(length);
      42               0 :     if (!pdata) return;
      43               0 :     memcpy(pdata, data, length);
      44               0 :     m_table = reinterpret_cast<const TtfUtil::Sfnt::FontNames*>(pdata);
      45                 : 
      46               0 :     if ((length > sizeof(TtfUtil::Sfnt::FontNames)) &&
      47                 :         (length > sizeof(TtfUtil::Sfnt::FontNames) +
      48               0 :          sizeof(TtfUtil::Sfnt::NameRecord) * ( be::swap<uint16>(m_table->count) - 1)))
      49                 :     {
      50               0 :         uint16 offset = be::swap<uint16>(m_table->string_offset);
      51               0 :         m_nameData = reinterpret_cast<const uint8*>(pdata) + offset;
      52               0 :         setPlatformEncoding(platformId, encodingID);
      53               0 :         m_nameDataLength = length - offset;
      54                 :     }
      55                 :     else
      56                 :     {
      57               0 :         free(const_cast<TtfUtil::Sfnt::FontNames*>(m_table));
      58               0 :         m_table = NULL;
      59                 :     }
      60                 : }
      61                 : 
      62               0 : uint16 NameTable::setPlatformEncoding(uint16 platformId, uint16 encodingID)
      63                 : {
      64               0 :     if (!m_nameData) return 0;
      65               0 :     uint16 i = 0;
      66               0 :     uint16 count = be::swap<uint16>(m_table->count);
      67               0 :     for (; i < count; i++)
      68                 :     {
      69               0 :         if (be::swap<uint16>(m_table->name_record[i].platform_id) == platformId &&
      70               0 :             be::swap<uint16>(m_table->name_record[i].platform_specific_id) == encodingID)
      71                 :         {
      72               0 :             m_platformOffset = i;
      73               0 :             break;
      74                 :         }
      75                 :     }
      76               0 :     while ((++i < count) &&
      77               0 :            (be::swap<uint16>(m_table->name_record[i].platform_id) == platformId) &&
      78               0 :            (be::swap<uint16>(m_table->name_record[i].platform_specific_id) == encodingID))
      79                 :     {
      80               0 :         m_platformLastRecord = i;
      81                 :     }
      82               0 :     m_encodingId = encodingID;
      83               0 :     m_platformId = platformId;
      84               0 :     return 0;
      85                 : }
      86                 : 
      87               0 : void* NameTable::getName(uint16& languageId, uint16 nameId, gr_encform enc, uint32& length)
      88                 : {
      89               0 :     uint16 anyLang = 0;
      90               0 :     uint16 enUSLang = 0;
      91               0 :     uint16 bestLang = 0;
      92               0 :     if (!m_table)
      93                 :     {
      94               0 :         languageId = 0;
      95               0 :         length = 0;
      96               0 :         return NULL;
      97                 :     }
      98               0 :     for (uint16 i = m_platformOffset; i <= m_platformLastRecord; i++)
      99                 :     {
     100               0 :         if (be::swap<uint16>(m_table->name_record[i].name_id) == nameId)
     101                 :         {
     102               0 :             uint16 langId = be::swap<uint16>(m_table->name_record[i].language_id);
     103               0 :             if (langId == languageId)
     104                 :             {
     105               0 :                 bestLang = i;
     106               0 :                 break;
     107                 :             }
     108                 :             // MS language tags have the language in the lower byte, region in the higher
     109               0 :             else if ((langId & 0xFF) == (languageId & 0xFF))
     110                 :             {
     111               0 :                 bestLang = i;
     112                 :             }
     113               0 :             else if (langId == 0x409)
     114                 :             {
     115               0 :                 enUSLang = i;
     116                 :             }
     117                 :             else
     118                 :             {
     119               0 :                 anyLang = i;
     120                 :             }
     121                 :         }
     122                 :     }
     123               0 :     if (!bestLang)
     124                 :     {
     125               0 :         if (enUSLang) bestLang = enUSLang;
     126                 :         else
     127                 :         {
     128               0 :             bestLang = anyLang;
     129               0 :             if (!anyLang)
     130                 :             {
     131               0 :                 languageId = 0;
     132               0 :                 length = 0;
     133               0 :                 return NULL;
     134                 :             }
     135                 :         }
     136                 :     }
     137               0 :     const TtfUtil::Sfnt::NameRecord & nameRecord = m_table->name_record[bestLang];
     138               0 :     languageId = be::swap<uint16>(nameRecord.language_id);
     139               0 :     uint16 utf16Length = be::swap<uint16>(nameRecord.length);
     140               0 :     uint16 offset = be::swap<uint16>(nameRecord.offset);
     141               0 :     if(offset + utf16Length > m_nameDataLength)
     142                 :     {
     143               0 :         languageId = 0;
     144               0 :         length = 0;
     145               0 :         return NULL;
     146                 :     }
     147               0 :     utf16Length >>= 1; // in utf16 units
     148               0 :     utf16::codeunit_t * utf16Name = gralloc<utf16::codeunit_t>(utf16Length);
     149               0 :     const uint8* pName = m_nameData + offset;
     150               0 :     for (size_t i = 0; i < utf16Length; i++)
     151                 :     {
     152               0 :         utf16Name[i] = be::read<uint16>(pName);
     153                 :     }
     154               0 :     switch (enc)
     155                 :     {
     156                 :     case gr_utf8:
     157                 :     {
     158               0 :         utf8::codeunit_t* uniBuffer = gralloc<utf8::codeunit_t>(3 * utf16Length + 1);
     159               0 :         utf8::iterator d = uniBuffer;
     160               0 :         for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d)
     161               0 :                 *d = *s;
     162               0 :         length = d - uniBuffer;
     163               0 :         uniBuffer[length] = 0;
     164               0 :         return uniBuffer;
     165                 :     }
     166                 :     case gr_utf16:
     167               0 :         length = utf16Length;
     168               0 :         return utf16Name;
     169                 :     case gr_utf32:
     170                 :     {
     171               0 :         utf32::codeunit_t * uniBuffer = gralloc<utf32::codeunit_t>(utf16Length  + 1);
     172               0 :                 utf32::iterator d = uniBuffer;
     173               0 :                 for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d)
     174               0 :                         *d = *s;
     175               0 :                 length = d - uniBuffer;
     176               0 :                 uniBuffer[length] = 0;
     177               0 :                 return uniBuffer;
     178                 :     }
     179                 :     }
     180               0 :     length = 0;
     181               0 :     return NULL;
     182                 : }
     183                 : 
     184               0 : uint16 NameTable::getLanguageId(const char * bcp47Locale)
     185                 : {
     186               0 :     size_t localeLength = strlen(bcp47Locale);
     187               0 :     uint16 localeId = m_locale2Lang.getMsId(bcp47Locale);
     188               0 :     if (m_table && (be::swap<uint16>(m_table->format) == 1))
     189                 :     {
     190                 :         const uint8 * pLangEntries = reinterpret_cast<const uint8*>(m_table) +
     191                 :             sizeof(TtfUtil::Sfnt::FontNames)
     192               0 :             + sizeof(TtfUtil::Sfnt::NameRecord) * ( be::swap<uint16>(m_table->count) - 1);
     193               0 :         uint16 numLangEntries = be::read<uint16>(pLangEntries);
     194                 :         const TtfUtil::Sfnt::LangTagRecord * langTag =
     195               0 :             reinterpret_cast<const TtfUtil::Sfnt::LangTagRecord*>(pLangEntries);
     196               0 :         if (pLangEntries + numLangEntries * sizeof(TtfUtil::Sfnt::LangTagRecord) <= m_nameData)
     197                 :         {
     198               0 :             for (uint16 i = 0; i < numLangEntries; i++)
     199                 :             {
     200               0 :                 uint16 offset = be::swap<uint16>(langTag[i].offset);
     201               0 :                 uint16 length = be::swap<uint16>(langTag[i].length);
     202               0 :                 if ((offset + length <= m_nameDataLength) && (length == 2 * localeLength))
     203                 :                 {
     204               0 :                     const uint8* pName = m_nameData + offset;
     205               0 :                     bool match = true;
     206               0 :                     for (size_t j = 0; j < localeLength; j++)
     207                 :                     {
     208               0 :                         uint16 code = be::read<uint16>(pName);
     209               0 :                         if ((code > 0x7F) || (code != bcp47Locale[j]))
     210                 :                         {
     211               0 :                             match = false;
     212               0 :                             break;
     213                 :                         }
     214                 :                     }
     215               0 :                     if (match)
     216               0 :                         return 0x8000 + i;
     217                 :                 }
     218                 :             }
     219                 :         }
     220                 :     }
     221               0 :     return localeId;
     222                 : }
     223                 : 

Generated by: LCOV version 1.7