tor-browser

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

ftsdfcommon.c (3485B)


      1 /****************************************************************************
      2 *
      3 * ftsdfcommon.c
      4 *
      5 *   Auxiliary data for Signed Distance Field support (body).
      6 *
      7 * Copyright (C) 2020-2025 by
      8 * David Turner, Robert Wilhelm, and Werner Lemberg.
      9 *
     10 * Written by Anuj Verma.
     11 *
     12 * This file is part of the FreeType project, and may only be used,
     13 * modified, and distributed under the terms of the FreeType project
     14 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     15 * this file you indicate that you have read the license and
     16 * understand and accept it fully.
     17 *
     18 */
     19 
     20 
     21 #include "ftsdf.h"
     22 #include "ftsdfcommon.h"
     23 
     24 
     25  /**************************************************************************
     26   *
     27   * format and sign manipulating functions
     28   *
     29   */
     30 
     31  /*
     32   * Convert 16.16 fixed-point values to the desired output format.
     33   * In this case we reduce 16.16 fixed-point values to normalized
     34   * 8-bit values.
     35   *
     36   * The `max_value` in the parameter is the maximum value in the
     37   * distance field map and is equal to the spread.  We normalize
     38   * the distances using this value instead of computing the maximum
     39   * value for the entire bitmap.
     40   *
     41   * You can use this function to map the 16.16 signed values to any
     42   * format required.  Do note that the output buffer is 8-bit, so only
     43   * use an 8-bit format for `FT_SDFFormat`, or increase the buffer size in
     44   * `ftsdfrend.c`.
     45   */
     46  FT_LOCAL_DEF( FT_SDFFormat )
     47  map_fixed_to_sdf( FT_16D16  dist,
     48                    FT_16D16  max_value )
     49  {
     50    FT_SDFFormat  out;
     51    FT_16D16      udist;
     52 
     53 
     54    /* normalize the distance values */
     55    dist = FT_DivFix( dist, max_value );
     56 
     57    udist = dist < 0 ? -dist : dist;
     58 
     59    /* Reduce the distance values to 8 bits.                   */
     60    /*                                                         */
     61    /* Since +1/-1 in 16.16 takes the 16th bit, we right-shift */
     62    /* the number by 9 to make it fit into the 7-bit range.    */
     63    /*                                                         */
     64    /* One bit is reserved for the sign.                       */
     65    udist >>= 9;
     66 
     67    /* Since `char` can only store a maximum positive value    */
     68    /* of 127 we need to make sure it does not wrap around and */
     69    /* give a negative value.                                  */
     70    if ( dist > 0 && udist > 127 )
     71      udist = 127;
     72    if ( dist < 0 && udist > 128 )
     73      udist = 128;
     74 
     75    /* Output the data; negative values are from [0, 127] and positive    */
     76    /* from [128, 255].  One important thing is that negative values      */
     77    /* are inverted here, that means [0, 128] maps to [-128, 0] linearly. */
     78    /* More on that in `freetype.h` near the documentation of             */
     79    /* `FT_RENDER_MODE_SDF`.                                              */
     80    out = dist < 0 ? 128 - (FT_SDFFormat)udist
     81                   : (FT_SDFFormat)udist + 128;
     82 
     83    return out;
     84  }
     85 
     86 
     87  /*
     88   * Invert the signed distance packed into the corresponding format.
     89   * So if the values are negative they will become positive in the
     90   * chosen format.
     91   *
     92   * [Note]: This function should only be used after converting the
     93   *         16.16 signed distance values to `FT_SDFFormat`.  If that
     94   *         conversion has not been done, then simply invert the sign
     95   *         and use the above function to pack the values.
     96   */
     97  FT_LOCAL_DEF( FT_SDFFormat )
     98  invert_sign( FT_SDFFormat  dist )
     99  {
    100    return 255 - dist;
    101  }
    102 
    103 
    104 /* END */