tor-browser

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

ft-hb.c (4487B)


      1 /****************************************************************************
      2 *
      3 * ft-hb.c
      4 *
      5 *   FreeType-HarfBuzz bridge (body).
      6 *
      7 * Copyright (C) 2025 by
      8 * Behdad Esfahbod.
      9 *
     10 * This file is part of the FreeType project, and may only be used,
     11 * modified, and distributed under the terms of the FreeType project
     12 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     13 * this file you indicate that you have read the license and
     14 * understand and accept it fully.
     15 *
     16 */
     17 
     18 
     19 #if !defined( _WIN32 ) && !defined( _GNU_SOURCE )
     20 #  define _GNU_SOURCE  1  /* for RTLD_DEFAULT */
     21 #endif
     22 
     23 #include <freetype/freetype.h>
     24 #include <freetype/internal/ftmemory.h>
     25 
     26 #include "afglobal.h"
     27 
     28 #include "ft-hb.h"
     29 
     30 
     31 #if defined( FT_CONFIG_OPTION_USE_HARFBUZZ )         && \
     32    defined( FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC )
     33 
     34 #ifndef FT_LIBHARFBUZZ
     35 #  ifdef _WIN32
     36 #    define FT_LIBHARFBUZZ "libharfbuzz-0.dll"
     37 #  else
     38 #    ifdef __APPLE__
     39 #      define FT_LIBHARFBUZZ "libharfbuzz.0.dylib"
     40 #    else
     41 #      define FT_LIBHARFBUZZ "libharfbuzz.so.0"
     42 #    endif
     43 #  endif
     44 #endif
     45 
     46 #ifdef _WIN32
     47 
     48 #  include <windows.h>
     49 
     50 #else /* !_WIN32 */
     51 
     52 #  include <dlfcn.h>
     53 
     54  /* The GCC pragma suppresses the warning "ISO C forbids     */
     55  /* assignment between function pointer and 'void *'", which */
     56  /* inevitably gets emitted with `-Wpedantic`; see the man   */
     57  /* page of function `dlsym` for more information.           */
     58 #  if defined( __GNUC__ )
     59 #    pragma GCC diagnostic push
     60 #    ifndef __cplusplus
     61 #      pragma GCC diagnostic ignored "-Wpedantic"
     62 #    endif
     63 #  endif
     64 
     65 #endif /* !_WIN32 */
     66 
     67 
     68  FT_LOCAL_DEF( void )
     69  ft_hb_funcs_init( struct AF_ModuleRec_  *af_module )
     70  {
     71    FT_Memory  memory = af_module->root.memory;
     72    FT_Error   error;
     73 
     74    ft_hb_funcs_t                *funcs           = NULL;
     75    ft_hb_version_atleast_func_t  version_atleast = NULL;
     76 
     77 #ifdef _WIN32
     78    HANDLE  lib;
     79 #  define DLSYM( lib, name ) \
     80            (ft_ ## name ## _func_t)GetProcAddress( lib, #name )
     81 #else
     82    void  *lib;
     83 #  define DLSYM( lib, name ) \
     84            (ft_ ## name ## _func_t)dlsym( lib, #name )
     85 #endif
     86 
     87 
     88    af_module->hb_funcs = NULL;
     89 
     90    if ( FT_NEW( funcs ) )
     91      return;
     92    FT_ZERO( funcs );
     93 
     94 #ifdef _WIN32
     95 
     96    lib = LoadLibraryA( FT_LIBHARFBUZZ );
     97    if ( !lib )
     98      goto Fail;
     99    version_atleast = DLSYM( lib, hb_version_atleast );
    100 
    101 #else /* !_WIN32 */
    102 
    103 #  ifdef RTLD_DEFAULT
    104 #    define FT_RTLD_FLAGS RTLD_LAZY | RTLD_GLOBAL
    105    lib             = RTLD_DEFAULT;
    106    version_atleast = DLSYM( lib, hb_version_atleast );
    107 #  else
    108 #    define FT_RTLD_FLAGS RTLD_LAZY
    109 #  endif
    110 
    111    if ( !version_atleast )
    112    {
    113      /* Load the HarfBuzz library.
    114       *
    115       * We never close the library, since we opened it with RTLD_GLOBAL.
    116       * This is important for the case where we are using HarfBuzz as a
    117       * shared library, and we want to use the symbols from the library in
    118       * other shared libraries or clients.  HarfBuzz holds onto global
    119       * variables, and closing the library will cause them to be
    120       * invalidated.
    121       */
    122      lib = dlopen( FT_LIBHARFBUZZ, FT_RTLD_FLAGS );
    123      if ( !lib )
    124        goto Fail;
    125      version_atleast = DLSYM( lib, hb_version_atleast );
    126    }
    127 
    128 #endif /* !_WIN32 */
    129 
    130    if ( !version_atleast )
    131      goto Fail;
    132 
    133    /* Load all symbols we use. */
    134 #define HB_EXTERN( ret, name, args )  \
    135  {                                   \
    136    funcs->name = DLSYM( lib, name ); \
    137    if ( !funcs->name )               \
    138      goto Fail;                      \
    139  }
    140 #include "ft-hb-decls.h"
    141 #undef HB_EXTERN
    142 
    143 #undef DLSYM
    144 
    145    af_module->hb_funcs = funcs;
    146    return;
    147 
    148  Fail:
    149    if ( funcs )
    150      FT_FREE( funcs );
    151  }
    152 
    153 
    154  FT_LOCAL_DEF( void )
    155  ft_hb_funcs_done( struct AF_ModuleRec_  *af_module )
    156  {
    157    FT_Memory  memory = af_module->root.memory;
    158 
    159 
    160    if ( af_module->hb_funcs )
    161    {
    162      FT_FREE( af_module->hb_funcs );
    163      af_module->hb_funcs = NULL;
    164    }
    165  }
    166 
    167 
    168  FT_LOCAL_DEF( FT_Bool )
    169  ft_hb_enabled( struct AF_FaceGlobalsRec_  *globals )
    170  {
    171    return globals->module->hb_funcs != NULL;
    172  }
    173 
    174 #ifndef _WIN32
    175 #  if defined( __GNUC__ )
    176 #    pragma GCC diagnostic pop
    177 #  endif
    178 #endif
    179 
    180 #else /* !FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC */
    181 
    182  FT_LOCAL_DEF( FT_Bool )
    183  ft_hb_enabled( struct AF_FaceGlobalsRec_  *globals )
    184  {
    185    FT_UNUSED( globals );
    186 
    187 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
    188    return TRUE;
    189 #else
    190    return FALSE;
    191 #endif
    192  }
    193 
    194 #endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC */
    195 
    196 
    197 /* END */