tor-browser

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

gr_face.cpp (7804B)


      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 "graphite2/Font.h"
     28 #include "inc/Face.h"
     29 #include "inc/FileFace.h"
     30 #include "inc/GlyphCache.h"
     31 #include "inc/CmapCache.h"
     32 #include "inc/Silf.h"
     33 #include "inc/json.h"
     34 
     35 using namespace graphite2;
     36 
     37 #if !defined GRAPHITE2_NTRACING
     38 extern json *global_log;
     39 #endif
     40 
     41 namespace
     42 {
     43    bool load_face(Face & face, unsigned int options)
     44    {
     45 #ifdef GRAPHITE2_TELEMETRY
     46        telemetry::category _misc_cat(face.tele.misc);
     47 #endif
     48        Face::Table silf(face, Tag::Silf, 0x00050000);
     49        if (!silf)
     50            return false;
     51 
     52        if (!face.readGlyphs(options))
     53            return false;
     54 
     55        if (silf)
     56        {
     57            if (!face.readFeatures() || !face.readGraphite(silf))
     58            {
     59 #if !defined GRAPHITE2_NTRACING
     60                if (global_log)
     61                {
     62                    *global_log << json::object
     63                        << "type" << "fontload"
     64                        << "failure" << face.error()
     65                        << "context" << face.error_context()
     66                    << json::close;
     67                }
     68 #endif
     69                return false;
     70            }
     71            else
     72                return true;
     73        }
     74        else
     75            return false;
     76    }
     77 
     78    inline
     79    uint32 zeropad(const uint32 x)
     80    {
     81        if (x == 0x20202020)                    return 0;
     82        if ((x & 0x00FFFFFF) == 0x00202020)     return x & 0xFF000000;
     83        if ((x & 0x0000FFFF) == 0x00002020)     return x & 0xFFFF0000;
     84        if ((x & 0x000000FF) == 0x00000020)     return x & 0xFFFFFF00;
     85        return x;
     86    }
     87 }
     88 
     89 extern "C" {
     90 
     91 gr_face* gr_make_face_with_ops(const void* appFaceHandle/*non-NULL*/, const gr_face_ops *ops, unsigned int faceOptions)
     92                  //the appFaceHandle must stay alive all the time when the gr_face is alive. When finished with the gr_face, call destroy_face
     93 {
     94    if (ops == 0)   return 0;
     95 
     96    Face *res = new Face(appFaceHandle, *ops);
     97    if (res && load_face(*res, faceOptions))
     98        return static_cast<gr_face *>(res);
     99 
    100    delete res;
    101    return 0;
    102 }
    103 
    104 gr_face* gr_make_face(const void* appFaceHandle/*non-NULL*/, gr_get_table_fn tablefn, unsigned int faceOptions)
    105 {
    106    const gr_face_ops ops = {sizeof(gr_face_ops), tablefn, NULL};
    107    return gr_make_face_with_ops(appFaceHandle, &ops, faceOptions);
    108 }
    109 
    110 
    111 gr_face* gr_make_face_with_seg_cache_and_ops(const void* appFaceHandle/*non-NULL*/, const gr_face_ops *ops, unsigned int , unsigned int faceOptions)
    112 {
    113  return gr_make_face_with_ops(appFaceHandle, ops, faceOptions);
    114 }
    115 
    116 gr_face* gr_make_face_with_seg_cache(const void* appFaceHandle/*non-NULL*/, gr_get_table_fn tablefn, unsigned int, unsigned int faceOptions)
    117 {
    118  const gr_face_ops ops = {sizeof(gr_face_ops), tablefn, NULL};
    119  return gr_make_face_with_ops(appFaceHandle, &ops, faceOptions);
    120 }
    121 
    122 gr_uint32 gr_str_to_tag(const char *str)
    123 {
    124    uint32 res = 0;
    125    switch(max(strlen(str),size_t(4)))
    126    {
    127        case 4: res |= str[3];       GR_FALLTHROUGH;
    128        case 3: res |= str[2] << 8;  GR_FALLTHROUGH;
    129        case 2: res |= str[1] << 16; GR_FALLTHROUGH;
    130        case 1: res |= str[0] << 24; GR_FALLTHROUGH;
    131        default:  break;
    132    }
    133    return res;
    134 }
    135 
    136 void gr_tag_to_str(gr_uint32 tag, char *str)
    137 {
    138    if (!str) return;
    139 
    140    *str++ = char(tag >> 24);
    141    *str++ = char(tag >> 16);
    142    *str++ = char(tag >> 8);
    143    *str++ = char(tag);
    144    *str = '\0';
    145 }
    146 
    147 gr_feature_val* gr_face_featureval_for_lang(const gr_face* pFace, gr_uint32 langname/*0 means clone default*/) //clones the features. if none for language, clones the default
    148 {
    149    assert(pFace);
    150    langname = zeropad(langname);
    151    return static_cast<gr_feature_val *>(pFace->theSill().cloneFeatures(langname));
    152 }
    153 
    154 
    155 const gr_feature_ref* gr_face_find_fref(const gr_face* pFace, gr_uint32 featId)  //When finished with the FeatureRef, call destroy_FeatureRef
    156 {
    157    assert(pFace);
    158    featId = zeropad(featId);
    159    const FeatureRef* pRef = pFace->featureById(featId);
    160    return static_cast<const gr_feature_ref*>(pRef);
    161 }
    162 
    163 unsigned short gr_face_n_fref(const gr_face* pFace)
    164 {
    165    assert(pFace);
    166    int res = 0;
    167    for (int i = 0; i < pFace->numFeatures(); ++i)
    168        if (!(pFace->feature(i)->getFlags() & FeatureRef::HIDDEN))
    169            ++res;
    170    return res;
    171 }
    172 
    173 const gr_feature_ref* gr_face_fref(const gr_face* pFace, gr_uint16 i) //When finished with the FeatureRef, call destroy_FeatureRef
    174 {
    175    assert(pFace);
    176    int count = 0;
    177    for (int j = 0; j < pFace->numFeatures(); ++j)
    178    {
    179        const FeatureRef* pRef = pFace->feature(j);
    180        if (!(pRef->getFlags() & FeatureRef::HIDDEN))
    181            if (count++ == i)
    182                return static_cast<const gr_feature_ref*>(pRef);
    183    }
    184    return 0;
    185 }
    186 
    187 unsigned short gr_face_n_languages(const gr_face* pFace)
    188 {
    189    assert(pFace);
    190    return pFace->theSill().numLanguages();
    191 }
    192 
    193 gr_uint32 gr_face_lang_by_index(const gr_face* pFace, gr_uint16 i)
    194 {
    195    assert(pFace);
    196    return pFace->theSill().getLangName(i);
    197 }
    198 
    199 
    200 void gr_face_destroy(gr_face *face)
    201 {
    202    delete static_cast<Face*>(face);
    203 }
    204 
    205 
    206 gr_uint16 gr_face_name_lang_for_locale(gr_face *face, const char * locale)
    207 {
    208    if (face)
    209    {
    210        return face->languageForLocale(locale);
    211    }
    212    return 0;
    213 }
    214 
    215 unsigned short gr_face_n_glyphs(const gr_face* pFace)
    216 {
    217    return pFace->glyphs().numGlyphs();
    218 }
    219 
    220 const gr_faceinfo *gr_face_info(const gr_face *pFace, gr_uint32 script)
    221 {
    222    if (!pFace) return 0;
    223    const Silf *silf = pFace->chooseSilf(script);
    224    if (silf) return silf->silfInfo();
    225    return 0;
    226 }
    227 
    228 int gr_face_is_char_supported(const gr_face* pFace, gr_uint32 usv, gr_uint32 script)
    229 {
    230    const Cmap & cmap = pFace->cmap();
    231    gr_uint16 gid = cmap[usv];
    232    if (!gid)
    233    {
    234        const Silf * silf = pFace->chooseSilf(script);
    235        gid = silf->findPseudo(usv);
    236    }
    237    return (gid != 0);
    238 }
    239 
    240 #ifndef GRAPHITE2_NFILEFACE
    241 gr_face* gr_make_file_face(const char *filename, unsigned int faceOptions)
    242 {
    243    FileFace* pFileFace = new FileFace(filename);
    244    if (*pFileFace)
    245    {
    246      gr_face* pRes = gr_make_face_with_ops(pFileFace, &FileFace::ops, faceOptions);
    247      if (pRes)
    248      {
    249        pRes->takeFileFace(pFileFace);        //takes ownership
    250        return pRes;
    251      }
    252    }
    253 
    254    //error when loading
    255 
    256    delete pFileFace;
    257    return NULL;
    258 }
    259 
    260 gr_face* gr_make_file_face_with_seg_cache(const char* filename, unsigned int, unsigned int faceOptions)   //returns NULL on failure. //TBD better error handling
    261                  //when finished with, call destroy_face
    262 {
    263    return gr_make_file_face(filename, faceOptions);
    264 }
    265 #endif      //!GRAPHITE2_NFILEFACE
    266 
    267 } // extern "C"