1 | /**************************************************************************** |
2 | * |
3 | * ftsynth.c |
4 | * |
5 | * FreeType synthesizing code for emboldening and slanting (body). |
6 | * |
7 | * Copyright (C) 2000-2023 by |
8 | * David Turner, Robert Wilhelm, and Werner Lemberg. |
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 | #include <freetype/ftsynth.h> |
20 | #include <freetype/internal/ftdebug.h> |
21 | #include <freetype/internal/ftobjs.h> |
22 | #include <freetype/ftoutln.h> |
23 | #include <freetype/ftbitmap.h> |
24 | |
25 | |
26 | /************************************************************************** |
27 | * |
28 | * The macro FT_COMPONENT is used in trace mode. It is an implicit |
29 | * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
30 | * messages during execution. |
31 | */ |
32 | #undef FT_COMPONENT |
33 | #define FT_COMPONENT synth |
34 | |
35 | |
36 | /*************************************************************************/ |
37 | /*************************************************************************/ |
38 | /**** ****/ |
39 | /**** EXPERIMENTAL OBLIQUING SUPPORT ****/ |
40 | /**** ****/ |
41 | /*************************************************************************/ |
42 | /*************************************************************************/ |
43 | |
44 | /* documentation is in ftsynth.h */ |
45 | |
46 | FT_EXPORT_DEF( void ) |
47 | FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) |
48 | { |
49 | /* Value '0x0366A' corresponds to a shear angle of about 12 degrees. */ |
50 | FT_GlyphSlot_Slant( slot, 0x0366A, 0 ); |
51 | } |
52 | |
53 | |
54 | /* documentation is in ftsynth.h */ |
55 | |
56 | FT_EXPORT_DEF( void ) |
57 | FT_GlyphSlot_Slant( FT_GlyphSlot slot, |
58 | FT_Fixed xslant, |
59 | FT_Fixed yslant ) |
60 | { |
61 | FT_Matrix transform; |
62 | FT_Outline* outline; |
63 | |
64 | |
65 | if ( !slot ) |
66 | return; |
67 | |
68 | outline = &slot->outline; |
69 | |
70 | /* only oblique outline glyphs */ |
71 | if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) |
72 | return; |
73 | |
74 | /* we don't touch the advance width */ |
75 | |
76 | /* For italic, simply apply a shear transform */ |
77 | transform.xx = 0x10000L; |
78 | transform.yx = -yslant; |
79 | |
80 | transform.xy = xslant; |
81 | transform.yy = 0x10000L; |
82 | |
83 | FT_Outline_Transform( outline, &transform ); |
84 | } |
85 | |
86 | |
87 | /*************************************************************************/ |
88 | /*************************************************************************/ |
89 | /**** ****/ |
90 | /**** EXPERIMENTAL EMBOLDENING SUPPORT ****/ |
91 | /**** ****/ |
92 | /*************************************************************************/ |
93 | /*************************************************************************/ |
94 | |
95 | |
96 | /* documentation is in ftsynth.h */ |
97 | |
98 | FT_EXPORT_DEF( void ) |
99 | FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) |
100 | { |
101 | FT_GlyphSlot_AdjustWeight( slot, 0x0AAA, 0x0AAA ); |
102 | } |
103 | |
104 | |
105 | FT_EXPORT_DEF( void ) |
106 | FT_GlyphSlot_AdjustWeight( FT_GlyphSlot slot, |
107 | FT_Fixed xdelta, |
108 | FT_Fixed ydelta ) |
109 | { |
110 | FT_Library library; |
111 | FT_Size size; |
112 | FT_Error error; |
113 | FT_Pos xstr, ystr; |
114 | |
115 | |
116 | if ( !slot ) |
117 | return; |
118 | |
119 | library = slot->library; |
120 | size = slot->face->size; |
121 | |
122 | if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && |
123 | slot->format != FT_GLYPH_FORMAT_BITMAP ) |
124 | return; |
125 | |
126 | /* express deltas in pixels in 26.6 format */ |
127 | xstr = (FT_Pos)size->metrics.x_ppem * xdelta / 1024; |
128 | ystr = (FT_Pos)size->metrics.y_ppem * ydelta / 1024; |
129 | |
130 | if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) |
131 | FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); |
132 | |
133 | else /* slot->format == FT_GLYPH_FORMAT_BITMAP */ |
134 | { |
135 | /* round to full pixels */ |
136 | xstr &= ~63; |
137 | if ( xstr == 0 ) |
138 | xstr = 1 << 6; |
139 | ystr &= ~63; |
140 | |
141 | /* |
142 | * XXX: overflow check for 16-bit system, for compatibility |
143 | * with FT_GlyphSlot_Embolden() since FreeType 2.1.10. |
144 | * unfortunately, this function return no informations |
145 | * about the cause of error. |
146 | */ |
147 | if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN ) |
148 | { |
149 | FT_TRACE1(( "FT_GlyphSlot_Embolden:" )); |
150 | FT_TRACE1(( "too strong emboldening parameter ystr=%ld\n" , ystr )); |
151 | return; |
152 | } |
153 | error = FT_GlyphSlot_Own_Bitmap( slot ); |
154 | if ( error ) |
155 | return; |
156 | |
157 | error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr ); |
158 | if ( error ) |
159 | return; |
160 | } |
161 | |
162 | if ( slot->advance.x ) |
163 | slot->advance.x += xstr; |
164 | |
165 | if ( slot->advance.y ) |
166 | slot->advance.y += ystr; |
167 | |
168 | slot->metrics.width += xstr; |
169 | slot->metrics.height += ystr; |
170 | slot->metrics.horiAdvance += xstr; |
171 | slot->metrics.vertAdvance += ystr; |
172 | slot->metrics.horiBearingY += ystr; |
173 | |
174 | /* XXX: 16-bit overflow case must be excluded before here */ |
175 | if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) |
176 | slot->bitmap_top += (FT_Int)( ystr >> 6 ); |
177 | } |
178 | |
179 | |
180 | /* END */ |
181 | |