Imported Upstream version 2.13.2
[platform/upstream/freetype2.git] / src / base / ftsynth.c
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 */