freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Git][freetype/freetype][master] 2 commits: New function `FT_MulAddFix`


From: Werner Lemberg (@wl)
Subject: [Git][freetype/freetype][master] 2 commits: New function `FT_MulAddFix` to compute the sum of fixed-point products.
Date: Wed, 29 Jun 2022 18:27:45 +0000

Werner Lemberg pushed to branch master at FreeType / FreeType

Commits:

  • 15fef219
    by Dominik Röttsches at 2022-06-29T20:12:04+02:00
    New function `FT_MulAddFix` to compute the sum of fixed-point products.
    
    This function, based on the code of `FT_MulFix`, uses 64-bit precision
    internally for intermediate computations.
    
    * include/freetype/internal/ftcalc.h, base/ftcalc.c (FT_MulAddFix):
    Implement it.
    
  • dece9535
    by Dominik Röttsches at 2022-06-29T20:27:11+02:00
    [truetype] Perform variation store delta computation with 64-bit precision.
    
    * include/freetype/internal/ftmmtypes.h (FT_ItemVarDelta): Make type
    explicitly 32-bit.
    * include/freetype/internal/services/svmm.h
    (FT_Var_Get_Item_Delta_Func): Change return type to `FT_ItemVarDelta`
    * truetype/ttgxvar.h (tt_var_get_item_delta): Change return type to
    `FT_ItemVarDelta`.
    * truetype/ttgxvar.c (tt_var_get_item_delta): Store scalars and deltas
    to intermediate array, perform computation using new method
    `FT_MulAddFix`.
    

6 changed files:

Changes:

  • include/freetype/internal/ftcalc.h
    ... ... @@ -278,6 +278,40 @@ FT_BEGIN_HEADER
    278 278
                           FT_Long  c );
    
    279 279
     
    
    280 280
     
    
    281
    +  /**************************************************************************
    
    282
    +   *
    
    283
    +   * @function:
    
    284
    +   *   FT_MulAddFix
    
    285
    +   *
    
    286
    +   * @description:
    
    287
    +   *   Compute `(s[0] * f[0] + s[1] * f[1] + ...) / 0x10000`, where `s[n]` is
    
    288
    +   *   usually a 16.16 scalar.
    
    289
    +   *
    
    290
    +   * @input:
    
    291
    +   *   s ::
    
    292
    +   *     The array of scalars.
    
    293
    +   *   f ::
    
    294
    +   *     The array of factors.
    
    295
    +   *   count ::
    
    296
    +   *     The number of entries in the array.
    
    297
    +   *
    
    298
    +   * @return:
    
    299
    +   *   The result of `(s[0] * f[0] + s[1] * f[1] + ...) / 0x10000`.
    
    300
    +   *
    
    301
    +   * @note:
    
    302
    +   *   This function is currently used for the scaled delta computation of
    
    303
    +   *   variation stores.  It internally uses 64-bit data types when
    
    304
    +   *   available, otherwise it emulates 64-bit math by using 32-bit
    
    305
    +   *   operations, which produce a correct result but most likely at a slower
    
    306
    +   *   performance in comparison to the implementation base on `int64_t`.
    
    307
    +   *
    
    308
    +   */
    
    309
    +  FT_BASE( FT_Int32 )
    
    310
    +  FT_MulAddFix( FT_Fixed*  s,
    
    311
    +                FT_Int32*  f,
    
    312
    +                FT_UInt    count );
    
    313
    +
    
    314
    +
    
    281 315
       /*
    
    282 316
        * A variant of FT_Matrix_Multiply which scales its result afterwards.  The
    
    283 317
        * idea is that both `a' and `b' are scaled by factors of 10 so that the
    

  • include/freetype/internal/ftmmtypes.h
    ... ... @@ -24,7 +24,7 @@
    24 24
     FT_BEGIN_HEADER
    
    25 25
     
    
    26 26
     
    
    27
    -  typedef FT_Long FT_ItemVarDelta;
    
    27
    +  typedef FT_Int32  FT_ItemVarDelta;
    
    28 28
     
    
    29 29
       typedef struct  GX_ItemVarDataRec_
    
    30 30
       {
    

  • include/freetype/internal/services/svmm.h
    ... ... @@ -109,7 +109,7 @@ FT_BEGIN_HEADER
    109 109
                                           FT_ULong         offset,
    
    110 110
                                           GX_ItemVarStore  itemStore );
    
    111 111
     
    
    112
    -  typedef FT_Int
    
    112
    +  typedef FT_ItemVarDelta
    
    113 113
       (*FT_Var_Get_Item_Delta_Func)( FT_Face          face,
    
    114 114
                                      GX_ItemVarStore  itemStore,
    
    115 115
                                      FT_UInt          outerIndex,
    

  • src/base/ftcalc.c
    ... ... @@ -1085,4 +1085,64 @@
    1085 1085
       }
    
    1086 1086
     
    
    1087 1087
     
    
    1088
    +  FT_BASE_DEF( FT_Int32 )
    
    1089
    +  FT_MulAddFix( FT_Fixed*  s,
    
    1090
    +                FT_Int32*  f,
    
    1091
    +                FT_UInt    count )
    
    1092
    +  {
    
    1093
    +    FT_UInt   i;
    
    1094
    +    FT_Int64  temp;
    
    1095
    +
    
    1096
    +
    
    1097
    +#ifdef FT_INT64
    
    1098
    +
    
    1099
    +    for ( i = 0; i < count; ++i )
    
    1100
    +      temp += (FT_Int64)s[i] * f[i];
    
    1101
    +
    
    1102
    +    return temp >> 16;
    
    1103
    +
    
    1104
    +#else
    
    1105
    +
    
    1106
    +    temp.hi = 0;
    
    1107
    +    temp.lo = 0;
    
    1108
    +
    
    1109
    +    for ( i = 0; i < count; ++i )
    
    1110
    +    {
    
    1111
    +      FT_Int64  multResult;
    
    1112
    +
    
    1113
    +      FT_Int     sign  = 1;
    
    1114
    +      FT_UInt32  carry = 0;
    
    1115
    +
    
    1116
    +      FT_UInt32  scalar;
    
    1117
    +      FT_UInt32  factor;
    
    1118
    +
    
    1119
    +
    
    1120
    +      scalar = (FT_UInt32)s[i];
    
    1121
    +      factor = (FT_UInt32)f[i];
    
    1122
    +
    
    1123
    +      FT_MOVE_SIGN( s[i], scalar, sign );
    
    1124
    +      FT_MOVE_SIGN( f[i], factor, sign );
    
    1125
    +
    
    1126
    +      ft_multo64( scalar, factor, &multResult );
    
    1127
    +
    
    1128
    +      if ( sign < 0 )
    
    1129
    +      {
    
    1130
    +        /* Emulated `FT_Int64` negation. */
    
    1131
    +        carry = ( multResult.lo == 0 );
    
    1132
    +
    
    1133
    +        multResult.lo = ~multResult.lo + 1;
    
    1134
    +        multResult.hi = ~multResult.hi + carry;
    
    1135
    +      }
    
    1136
    +
    
    1137
    +      FT_Add64( &temp, &multResult, &temp );
    
    1138
    +    }
    
    1139
    +
    
    1140
    +    return (FT_Int32)( ( (FT_Int32)( temp.hi & 0xFFFF ) << 16 ) |
    
    1141
    +                                   ( temp.lo >> 16 )            );
    
    1142
    +
    
    1143
    +#endif /* !FT_INT64 */
    
    1144
    +
    
    1145
    +  }
    
    1146
    +
    
    1147
    +
    
    1088 1148
     /* END */

  • src/truetype/ttgxvar.c
    ... ... @@ -939,19 +939,23 @@
    939 939
       }
    
    940 940
     
    
    941 941
     
    
    942
    -  FT_LOCAL_DEF( FT_Int )
    
    942
    +  FT_LOCAL_DEF( FT_ItemVarDelta )
    
    943 943
       tt_var_get_item_delta( TT_Face          face,
    
    944 944
                              GX_ItemVarStore  itemStore,
    
    945 945
                              FT_UInt          outerIndex,
    
    946 946
                              FT_UInt          innerIndex )
    
    947 947
       {
    
    948
    +    FT_Stream  stream = FT_FACE_STREAM( face );
    
    949
    +    FT_Memory  memory = stream->memory;
    
    950
    +    FT_Error   error  = FT_Err_Ok;
    
    951
    +
    
    948 952
         GX_ItemVarData    varData;
    
    949 953
         FT_ItemVarDelta*  deltaSet;
    
    950 954
     
    
    951
    -    FT_UInt   master, j;
    
    952
    -    FT_Fixed  netAdjustment = 0;     /* accumulated adjustment */
    
    953
    -    FT_Fixed  scaledDelta;
    
    954
    -    FT_Fixed  delta;
    
    955
    +    FT_UInt           master, j;
    
    956
    +    FT_Fixed*         scalars;
    
    957
    +    FT_ItemVarDelta   returnValue;
    
    958
    +
    
    955 959
     
    
    956 960
         /* OpenType 1.8.4+: No variation data for this item
    
    957 961
          *  as indices have special value 0xFFFF. */
    
    ... ... @@ -964,6 +968,9 @@
    964 968
         varData  = &itemStore->varData[outerIndex];
    
    965 969
         deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex];
    
    966 970
     
    
    971
    +    if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
    
    972
    +      return 0;
    
    973
    +
    
    967 974
         /* outer loop steps through master designs to be blended */
    
    968 975
         for ( master = 0; master < varData->regionIdxCount; master++ )
    
    969 976
         {
    
    ... ... @@ -1013,18 +1020,33 @@
    1013 1020
                 FT_MulDiv( scalar,
    
    1014 1021
                            axis->endCoord - face->blend->normalizedcoords[j],
    
    1015 1022
                            axis->endCoord - axis->peakCoord );
    
    1016
    -      } /* per-axis loop */
    
    1017 1023
     
    
    1018
    -      /* get the scaled delta for this region */
    
    1019
    -      delta       = FT_intToFixed( deltaSet[master] );
    
    1020
    -      scaledDelta = FT_MulFix( scalar, delta );
    
    1024
    +      } /* per-axis loop */
    
    1021 1025
     
    
    1022
    -      /* accumulate the adjustments from each region */
    
    1023
    -      netAdjustment = netAdjustment + scaledDelta;
    
    1026
    +      scalars[master] = scalar;
    
    1024 1027
     
    
    1025 1028
         } /* per-region loop */
    
    1026 1029
     
    
    1027
    -    return FT_fixedToInt( netAdjustment );
    
    1030
    +
    
    1031
    +    /* Compute the scaled delta for this region.
    
    1032
    +     *
    
    1033
    +     * From: https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables:
    
    1034
    +     *
    
    1035
    +     *   `Fixed` is a 32-bit (16.16) type and, in the general case, requires
    
    1036
    +     *   32-bit deltas.  As described above, the `DeltaSet` record can
    
    1037
    +     *   accommodate deltas that are, logically, either 16-bit or 32-bit.
    
    1038
    +     *   When scaled deltas are applied to `Fixed` values, the `Fixed` value
    
    1039
    +     *   is treated like a 32-bit integer.
    
    1040
    +     *
    
    1041
    +     * `FT_MulAddFix` internally uses 64-bit precision; it thus can handle
    
    1042
    +     * deltas ranging from small 8-bit to large 32-bit values that are
    
    1043
    +     * applied to 16.16 `FT_Fixed` / OpenType `Fixed` values.
    
    1044
    +     */
    
    1045
    +    returnValue = FT_MulAddFix( scalars, deltaSet, varData->regionIdxCount );
    
    1046
    +
    
    1047
    +    FT_FREE( scalars );
    
    1048
    +
    
    1049
    +    return returnValue;
    
    1028 1050
       }
    
    1029 1051
     
    
    1030 1052
     
    

  • src/truetype/ttgxvar.h
    ... ... @@ -391,7 +391,7 @@ FT_BEGIN_HEADER
    391 391
                                            GX_ItemVarStore    itemStore,
    
    392 392
                                            FT_ULong           table_len );
    
    393 393
     
    
    394
    -  FT_LOCAL( FT_Int )
    
    394
    +  FT_LOCAL( FT_ItemVarDelta )
    
    395 395
       tt_var_get_item_delta( TT_Face          face,
    
    396 396
                              GX_ItemVarStore  itemStore,
    
    397 397
                              FT_UInt          outerIndex,
    


  • reply via email to

    [Prev in Thread] Current Thread [Next in Thread]