sdk-world v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Loading...
Searching...
No Matches
ftsdfcommon.c
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 */