xref: /aosp_15_r20/external/freetype/src/base/ftsynth.c (revision 63949dbd25bcc50c4e1178497ff9e9574d44fc5a)
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 )
FT_GlyphSlot_Oblique(FT_GlyphSlot slot)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 )
FT_GlyphSlot_Slant(FT_GlyphSlot slot,FT_Fixed xslant,FT_Fixed yslant)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 )
FT_GlyphSlot_Embolden(FT_GlyphSlot slot)99   FT_GlyphSlot_Embolden( FT_GlyphSlot  slot )
100   {
101     FT_GlyphSlot_AdjustWeight( slot, 0x0AAA, 0x0AAA );
102   }
103 
104 
105   FT_EXPORT_DEF( void )
FT_GlyphSlot_AdjustWeight(FT_GlyphSlot slot,FT_Fixed xdelta,FT_Fixed ydelta)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