~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/freetype/src/base/ftsynth.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  ftsynth.c                                                              */
 
4
/*                                                                         */
 
5
/*    FreeType synthesizing code for emboldening and slanting (body).      */
 
6
/*                                                                         */
 
7
/*  Copyright 2000-2001, 2002, 2003 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 <ft2build.h>
 
20
#include FT_INTERNAL_OBJECTS_H
 
21
#include FT_INTERNAL_CALC_H
 
22
#include FT_OUTLINE_H
 
23
#include FT_TRIGONOMETRY_H
 
24
#include FT_SYNTHESIS_H
 
25
 
 
26
 
 
27
#define FT_BOLD_THRESHOLD  0x0100
 
28
 
 
29
 
 
30
  /*************************************************************************/
 
31
  /*************************************************************************/
 
32
  /****                                                                 ****/
 
33
  /****   EXPERIMENTAL OBLIQUING SUPPORT                                ****/
 
34
  /****                                                                 ****/
 
35
  /*************************************************************************/
 
36
  /*************************************************************************/
 
37
 
 
38
  FT_EXPORT_DEF( void )
 
39
  FT_GlyphSlot_Oblique( FT_GlyphSlot  slot )
 
40
  {
 
41
    FT_Matrix    transform;
 
42
    FT_Outline*  outline = &slot->outline;
 
43
 
 
44
 
 
45
    /* only oblique outline glyphs */
 
46
    if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
 
47
      return;
 
48
 
 
49
    /* we don't touch the advance width */
 
50
 
 
51
    /* For italic, simply apply a shear transform, with an angle */
 
52
    /* of about 12 degrees.                                      */
 
53
 
 
54
    transform.xx = 0x10000L;
 
55
    transform.yx = 0x00000L;
 
56
 
 
57
    transform.xy = 0x06000L;
 
58
    transform.yy = 0x10000L;
 
59
 
 
60
    FT_Outline_Transform( outline, &transform );
 
61
  }
 
62
 
 
63
 
 
64
  /*************************************************************************/
 
65
  /*************************************************************************/
 
66
  /****                                                                 ****/
 
67
  /****   EXPERIMENTAL EMBOLDENING/OUTLINING SUPPORT                    ****/
 
68
  /****                                                                 ****/
 
69
  /*************************************************************************/
 
70
  /*************************************************************************/
 
71
 
 
72
 
 
73
 
 
74
  static int
 
75
  ft_test_extrema( FT_Outline*  outline,
 
76
                   int          n )
 
77
  {
 
78
    FT_Vector  *prev, *cur, *next;
 
79
    FT_Pos      product;
 
80
    FT_Int      c, first, last;
 
81
 
 
82
 
 
83
    /* we need to compute the `previous' and `next' point */
 
84
    /* for these extrema.                                 */
 
85
    cur  = outline->points + n;
 
86
    prev = cur - 1;
 
87
    next = cur + 1;
 
88
 
 
89
    first = 0;
 
90
    for ( c = 0; c < outline->n_contours; c++ )
 
91
    {
 
92
      last = outline->contours[c];
 
93
 
 
94
      if ( n == first )
 
95
        prev = outline->points + last;
 
96
 
 
97
      if ( n == last )
 
98
        next = outline->points + first;
 
99
 
 
100
      first = last + 1;
 
101
    }
 
102
 
 
103
    product = FT_MulDiv( cur->x - prev->x,   /* in.x  */
 
104
                         next->y - cur->y,   /* out.y */
 
105
                         0x40 )
 
106
              -
 
107
              FT_MulDiv( cur->y - prev->y,   /* in.y  */
 
108
                         next->x - cur->x,   /* out.x */
 
109
                         0x40 );
 
110
 
 
111
    if ( product )
 
112
      product = product > 0 ? 1 : -1;
 
113
 
 
114
    return product;
 
115
  }
 
116
 
 
117
 
 
118
  /* Compute the orientation of path filling.  It differs between TrueType */
 
119
  /* and Type1 formats.  We could use the `FT_OUTLINE_REVERSE_FILL' flag,  */
 
120
  /* but it is better to re-compute it directly (it seems that this flag   */
 
121
  /* isn't correctly set for some weird composite glyphs currently).       */
 
122
  /*                                                                       */
 
123
  /* We do this by computing bounding box points, and computing their      */
 
124
  /* curvature.                                                            */
 
125
  /*                                                                       */
 
126
  /* The function returns either 1 or -1.                                  */
 
127
  /*                                                                       */
 
128
  static int
 
129
  ft_get_orientation( FT_Outline*  outline )
 
130
  {
 
131
    FT_BBox  box;
 
132
    FT_BBox  indices;
 
133
    int      n, last;
 
134
 
 
135
 
 
136
    indices.xMin = -1;
 
137
    indices.yMin = -1;
 
138
    indices.xMax = -1;
 
139
    indices.yMax = -1;
 
140
 
 
141
    box.xMin = box.yMin =  32767;
 
142
    box.xMax = box.yMax = -32768;
 
143
 
 
144
    /* is it empty ? */
 
145
    if ( outline->n_contours < 1 )
 
146
      return 1;
 
147
 
 
148
    last = outline->contours[outline->n_contours - 1];
 
149
 
 
150
    for ( n = 0; n <= last; n++ )
 
151
    {
 
152
      FT_Pos  x, y;
 
153
 
 
154
 
 
155
      x = outline->points[n].x;
 
156
      if ( x < box.xMin )
 
157
      {
 
158
        box.xMin     = x;
 
159
        indices.xMin = n;
 
160
      }
 
161
      if ( x > box.xMax )
 
162
      {
 
163
        box.xMax     = x;
 
164
        indices.xMax = n;
 
165
      }
 
166
 
 
167
      y = outline->points[n].y;
 
168
      if ( y < box.yMin )
 
169
      {
 
170
        box.yMin     = y;
 
171
        indices.yMin = n;
 
172
      }
 
173
      if ( y > box.yMax )
 
174
      {
 
175
        box.yMax     = y;
 
176
        indices.yMax = n;
 
177
      }
 
178
    }
 
179
 
 
180
    /* test orientation of the xmin */
 
181
    n = ft_test_extrema( outline, indices.xMin );
 
182
    if ( n )
 
183
      goto Exit;
 
184
 
 
185
    n = ft_test_extrema( outline, indices.yMin );
 
186
    if ( n )
 
187
      goto Exit;
 
188
 
 
189
    n = ft_test_extrema( outline, indices.xMax );
 
190
    if ( n )
 
191
      goto Exit;
 
192
 
 
193
    n = ft_test_extrema( outline, indices.yMax );
 
194
    if ( !n )
 
195
      n = 1;
 
196
 
 
197
  Exit:
 
198
    return n;
 
199
  }
 
200
 
 
201
 
 
202
  FT_EXPORT_DEF( void )
 
203
  FT_GlyphSlot_Embolden( FT_GlyphSlot  slot )
 
204
  {
 
205
    FT_Vector*   points;
 
206
    FT_Vector    v_prev, v_first, v_next, v_cur;
 
207
    FT_Pos       distance;
 
208
    FT_Outline*  outline = &slot->outline;
 
209
    FT_Face      face = FT_SLOT_FACE( slot );
 
210
    FT_Angle     rotate, angle_in, angle_out;
 
211
    FT_Int       c, n, first, orientation;
 
212
 
 
213
 
 
214
    /* only embolden outline glyph images */
 
215
    if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
 
216
      return;
 
217
 
 
218
    /* compute control distance */
 
219
    distance = FT_MulFix( face->units_per_EM / 60,
 
220
                          face->size->metrics.y_scale );
 
221
 
 
222
    orientation = ft_get_orientation( outline );
 
223
    rotate      = FT_ANGLE_PI2*orientation;
 
224
 
 
225
    points = outline->points;
 
226
 
 
227
    first = 0;
 
228
    for ( c = 0; c < outline->n_contours; c++ )
 
229
    {
 
230
      int  last = outline->contours[c];
 
231
 
 
232
 
 
233
      v_first = points[first];
 
234
      v_prev  = points[last];
 
235
      v_cur   = v_first;
 
236
 
 
237
      for ( n = first; n <= last; n++ )
 
238
      {
 
239
        FT_Pos     d;
 
240
        FT_Vector  in, out;
 
241
        FT_Fixed   scale;
 
242
        FT_Angle   angle_diff;
 
243
 
 
244
 
 
245
        if ( n < last ) v_next = points[n + 1];
 
246
        else            v_next = v_first;
 
247
 
 
248
        /* compute the in and out vectors */
 
249
        in.x  = v_cur.x - v_prev.x;
 
250
        in.y  = v_cur.y - v_prev.y;
 
251
 
 
252
        out.x = v_next.x - v_cur.x;
 
253
        out.y = v_next.y - v_cur.y;
 
254
 
 
255
        angle_in   = FT_Atan2( in.x, in.y );
 
256
        angle_out  = FT_Atan2( out.x, out.y );
 
257
        angle_diff = FT_Angle_Diff( angle_in, angle_out );
 
258
        scale      = FT_Cos( angle_diff/2 );
 
259
 
 
260
        if ( scale < 0x400L && scale > -0x400L )
 
261
        {
 
262
          if ( scale >= 0 )
 
263
            scale = 0x400L;
 
264
          else
 
265
            scale = -0x400L;
 
266
        }
 
267
 
 
268
        d = FT_DivFix( distance, scale );
 
269
 
 
270
        FT_Vector_From_Polar( &in, d, angle_in + angle_diff/2 - rotate );
 
271
 
 
272
        outline->points[n].x = v_cur.x + distance + in.x;
 
273
        outline->points[n].y = v_cur.y + distance + in.y;
 
274
 
 
275
        v_prev = v_cur;
 
276
        v_cur  = v_next;
 
277
      }
 
278
 
 
279
      first = last + 1;
 
280
    }
 
281
 
 
282
    slot->metrics.horiAdvance =
 
283
      ( slot->metrics.horiAdvance + distance*4 ) & ~63;
 
284
  }
 
285
 
 
286
 
 
287
/* END */