~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to components/aggpas/src/agg_font_freetype.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//----------------------------------------------------------------------------
2
 
// Anti-Grain Geometry - Version 2.4 (Public License)
3
 
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4
 
//
5
 
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6
 
// Pascal Port By: Milan Marusinec alias Milano
7
 
//                 milan@marusinec.sk
8
 
//                 http://www.aggpas.org
9
 
// Copyright (c) 2005-2007
10
 
//
11
 
// Permission to copy, use, modify, sell and distribute this software
12
 
// is granted provided this copyright notice appears in all copies.
13
 
// This software is provided "as is" without express or implied
14
 
// warranty, and with no claim as to its suitability for any purpose.
15
 
//
16
 
//----------------------------------------------------------------------------
17
 
// Contact: mcseem@antigrain.com
18
 
//          mcseemagg@yahoo.com
19
 
//          http://www.antigrain.com
20
 
//
21
 
// [Pascal Port History] -----------------------------------------------------
22
 
//
23
 
// 17.09.2007-Milano: Porting & Finished OK
24
 
// 16.09.2007-Milano: Unit port establishment
25
 
//
26
 
{ agg_font_freetype.pas }
27
 
unit
28
 
 agg_font_freetype ;
29
 
 
30
 
INTERFACE
31
 
 
32
 
{$I agg_mode.inc }
33
 
 
34
 
uses
35
 
 SysUtils ,Math ,
36
 
 agg_font_freetype_lib ,
37
 
 agg_basics ,
38
 
 agg_font_engine ,
39
 
 agg_font_cache_manager ,
40
 
 agg_trans_affine ,
41
 
 agg_vertex_source ,
42
 
 agg_path_storage_integer ,
43
 
 agg_conv_curve ,
44
 
 agg_scanline ,
45
 
 agg_scanline_u ,
46
 
 agg_scanline_bin ,
47
 
 agg_rasterizer_scanline_aa ,
48
 
 agg_renderer_scanline ,
49
 
 agg_render_scanlines ,
50
 
 agg_bitset_iterator ;
51
 
 
52
 
{ GLOBAL VARIABLES & CONSTANTS }
53
 
{ TYPES DEFINITION }
54
 
type
55
 
 face_name_ptr = ^face_name;
56
 
 face_name = record
57
 
   name : char_ptr; //PChar;
58
 
   size : unsigned;
59
 
 
60
 
  end;
61
 
 
62
 
//-----------------------------------------------font_engine_freetype_base
63
 
 font_engine_freetype_base = object(font_engine )
64
 
   m_flag32 : boolean;
65
 
 
66
 
   m_change_stamp ,
67
 
   m_last_error   : int;
68
 
 
69
 
   m_name       : PChar;
70
 
   m_name_len   ,
71
 
   m_face_index : unsigned;
72
 
   m_char_map   : FT_Encoding;
73
 
   m_signature  : face_name;
74
 
 
75
 
   m_height ,
76
 
   m_width  : unsigned;
77
 
 
78
 
   m_hinting             ,
79
 
   m_flip_y              ,
80
 
   m_library_initialized : boolean;
81
 
 
82
 
   m_library : FT_Library_ptr;    // handle to library
83
 
   m_faces   : FT_Face_ptr_ptr;   // A pool of font faces
84
 
 
85
 
   m_face_names : face_name_ptr;
86
 
   m_num_faces  ,
87
 
   m_max_faces  : unsigned;
88
 
   m_cur_face   : FT_Face_ptr;    // handle to the current face object
89
 
   m_resolution : int;
90
 
 
91
 
   m_glyph_rendering : glyph_rendering;
92
 
   m_glyph_index     ,
93
 
   m_data_size       ,
94
 
   m_data_type       : unsigned;
95
 
 
96
 
   m_bounds    : agg_basics.rect;
97
 
   m_advance_x ,
98
 
   m_advance_y : double;
99
 
   m_affine    : trans_affine;
100
 
 
101
 
   m_path16   : path_storage_int16;
102
 
   m_path32   : path_storage_int32;
103
 
   m_curves16 ,
104
 
   m_curves32 : conv_curve;
105
 
 
106
 
   m_scanline_aa   : scanline_u8;
107
 
   m_scanline_bin  : scanline_bin;
108
 
   m_scanlines_aa  : scanlines_aa_type;
109
 
   m_scanlines_bin : scanlines_bin_type;
110
 
   m_rasterizer    : rasterizer_scanline_aa;
111
 
 
112
 
   constructor Construct(flag32_ : boolean; max_faces : unsigned = 32 );
113
 
   destructor  Destruct;
114
 
 
115
 
  // Set font parameters
116
 
   procedure resolution_(dpi : unsigned );
117
 
 
118
 
   function  load_font(
119
 
              font_name : PChar; face_index : unsigned; ren_type : glyph_rendering;
120
 
              font_mem : PChar = NIL; font_mem_size : int = 0 ) : boolean;
121
 
 
122
 
   function  attach(file_name : PChar ) : boolean;
123
 
 
124
 
   function  char_map_ (map : FT_Encoding ) : boolean;
125
 
   function  height_   (h : double ) : boolean;
126
 
   function  width_    (w : double ) : boolean;
127
 
   procedure hinting_  (h : boolean );
128
 
   procedure flip_y_   (flip : boolean );
129
 
   procedure transform_(affine : trans_affine_ptr );
130
 
 
131
 
  // Set Gamma
132
 
   procedure gamma_(f : vertex_source_ptr );
133
 
 
134
 
  // Accessors
135
 
   function  _last_error : int;
136
 
   function  _resolution : unsigned;
137
 
   function  _name : PChar;
138
 
   function  _num_faces : unsigned;
139
 
   function  _char_map : FT_Encoding;
140
 
   function  _height : double;
141
 
   function  _width : double;
142
 
   function  _ascender : double;
143
 
   function  _descender : double;
144
 
   function  _hinting : boolean;
145
 
   function  _flip_y : boolean;
146
 
 
147
 
  // Interface mandatory to implement for font_cache_manager
148
 
   function  font_signature : PChar; virtual;
149
 
   function  change_stamp : int; virtual;
150
 
 
151
 
   function  prepare_glyph(glyph_code : unsigned ) : boolean; virtual;
152
 
 
153
 
   function  glyph_index : unsigned; virtual;
154
 
   function  data_size : unsigned; virtual;
155
 
   function  data_type : unsigned; virtual;
156
 
   function  bounds : rect_ptr; virtual;
157
 
   function  advance_x : double; virtual;
158
 
   function  advance_y : double; virtual;
159
 
 
160
 
   procedure write_glyph_to(data : int8u_ptr ); virtual;
161
 
   function  add_kerning   (first ,second : unsigned; x ,y : double_ptr ) : boolean; virtual;
162
 
 
163
 
   function  flag32 : boolean; virtual;
164
 
 
165
 
  // private
166
 
   procedure update_char_size;
167
 
   procedure update_signature;
168
 
 
169
 
   function  find_face(name : PChar ) : int;
170
 
 
171
 
  end;
172
 
 
173
 
//------------------------------------------------font_engine_freetype_int16
174
 
// This class uses values of type int16 (10.6 format) for the vector cache.
175
 
// The vector cache is compact, but when rendering glyphs of height
176
 
// more that 200 there integer overflow can occur.
177
 
 font_engine_freetype_int16 = object(font_engine_freetype_base )
178
 
   constructor Construct(max_faces : unsigned = 32 );
179
 
 
180
 
  end;
181
 
 
182
 
//------------------------------------------------font_engine_freetype_int32
183
 
// This class uses values of type int32 (26.6 format) for the vector cache.
184
 
// The vector cache is twice larger than in font_engine_freetype_int16,
185
 
// but it allows you to render glyphs of very large sizes.
186
 
 font_engine_freetype_int32 = object(font_engine_freetype_base )
187
 
   constructor Construct(max_faces : unsigned = 32 );
188
 
 
189
 
  end;
190
 
 
191
 
{ GLOBAL PROCEDURES }
192
 
 
193
 
 
194
 
IMPLEMENTATION
195
 
{ LOCAL VARIABLES & CONSTANTS }
196
 
//------------------------------------------------------------------------------
197
 
//
198
 
// This code implements the AUTODIN II polynomial
199
 
// The variable corresponding to the macro argument "crc" should
200
 
// be an unsigned long.
201
 
// Oroginal code  by Spencer Garrett <srg@quick.com>
202
 
//
203
 
// generated using the AUTODIN II polynomial
204
 
//   x^32 + x^26 + x^23 + x^22 + x^16 +
205
 
//   x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
206
 
//
207
 
//------------------------------------------------------------------------------
208
 
const
209
 
 crc32tab : array[0..255 ] of unsigned = (
210
 
  $00000000, $77073096, $ee0e612c, $990951ba,
211
 
  $076dc419, $706af48f, $e963a535, $9e6495a3,
212
 
  $0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988,
213
 
  $09b64c2b, $7eb17cbd, $e7b82d07, $90bf1d91,
214
 
  $1db71064, $6ab020f2, $f3b97148, $84be41de,
215
 
  $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7,
216
 
  $136c9856, $646ba8c0, $fd62f97a, $8a65c9ec,
217
 
  $14015c4f, $63066cd9, $fa0f3d63, $8d080df5,
218
 
  $3b6e20c8, $4c69105e, $d56041e4, $a2677172,
219
 
  $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b,
220
 
  $35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940,
221
 
  $32d86ce3, $45df5c75, $dcd60dcf, $abd13d59,
222
 
  $26d930ac, $51de003a, $c8d75180, $bfd06116,
223
 
  $21b4f4b5, $56b3c423, $cfba9599, $b8bda50f,
224
 
  $2802b89e, $5f058808, $c60cd9b2, $b10be924,
225
 
  $2f6f7c87, $58684c11, $c1611dab, $b6662d3d,
226
 
  $76dc4190, $01db7106, $98d220bc, $efd5102a,
227
 
  $71b18589, $06b6b51f, $9fbfe4a5, $e8b8d433,
228
 
  $7807c9a2, $0f00f934, $9609a88e, $e10e9818,
229
 
  $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01,
230
 
  $6b6b51f4, $1c6c6162, $856530d8, $f262004e,
231
 
  $6c0695ed, $1b01a57b, $8208f4c1, $f50fc457,
232
 
  $65b0d9c6, $12b7e950, $8bbeb8ea, $fcb9887c,
233
 
  $62dd1ddf, $15da2d49, $8cd37cf3, $fbd44c65,
234
 
  $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2,
235
 
  $4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb,
236
 
  $4369e96a, $346ed9fc, $ad678846, $da60b8d0,
237
 
  $44042d73, $33031de5, $aa0a4c5f, $dd0d7cc9,
238
 
  $5005713c, $270241aa, $be0b1010, $c90c2086,
239
 
  $5768b525, $206f85b3, $b966d409, $ce61e49f,
240
 
  $5edef90e, $29d9c998, $b0d09822, $c7d7a8b4,
241
 
  $59b33d17, $2eb40d81, $b7bd5c3b, $c0ba6cad,
242
 
  $edb88320, $9abfb3b6, $03b6e20c, $74b1d29a,
243
 
  $ead54739, $9dd277af, $04db2615, $73dc1683,
244
 
  $e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8,
245
 
  $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1,
246
 
  $f00f9344, $8708a3d2, $1e01f268, $6906c2fe,
247
 
  $f762575d, $806567cb, $196c3671, $6e6b06e7,
248
 
  $fed41b76, $89d32be0, $10da7a5a, $67dd4acc,
249
 
  $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5,
250
 
  $d6d6a3e8, $a1d1937e, $38d8c2c4, $4fdff252,
251
 
  $d1bb67f1, $a6bc5767, $3fb506dd, $48b2364b,
252
 
  $d80d2bda, $af0a1b4c, $36034af6, $41047a60,
253
 
  $df60efc3, $a867df55, $316e8eef, $4669be79,
254
 
  $cb61b38c, $bc66831a, $256fd2a0, $5268e236,
255
 
  $cc0c7795, $bb0b4703, $220216b9, $5505262f,
256
 
  $c5ba3bbe, $b2bd0b28, $2bb45a92, $5cb36a04,
257
 
  $c2d7ffa7, $b5d0cf31, $2cd99e8b, $5bdeae1d,
258
 
  $9b64c2b0, $ec63f226, $756aa39c, $026d930a,
259
 
  $9c0906a9, $eb0e363f, $72076785, $05005713,
260
 
  $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38,
261
 
  $92d28e9b, $e5d5be0d, $7cdcefb7, $0bdbdf21,
262
 
  $86d3d2d4, $f1d4e242, $68ddb3f8, $1fda836e,
263
 
  $81be16cd, $f6b9265b, $6fb077e1, $18b74777,
264
 
  $88085ae6, $ff0f6a70, $66063bca, $11010b5c,
265
 
  $8f659eff, $f862ae69, $616bffd3, $166ccf45,
266
 
  $a00ae278, $d70dd2ee, $4e048354, $3903b3c2,
267
 
  $a7672661, $d06016f7, $4969474d, $3e6e77db,
268
 
  $aed16a4a, $d9d65adc, $40df0b66, $37d83bf0,
269
 
  $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9,
270
 
  $bdbdf21c, $cabac28a, $53b39330, $24b4a3a6,
271
 
  $bad03605, $cdd70693, $54de5729, $23d967bf,
272
 
  $b3667a2e, $c4614ab8, $5d681b02, $2a6f2b94,
273
 
  $b40bbe37, $c30c8ea1, $5a05df1b, $2d02ef8d );
274
 
 
275
 
{ UNIT IMPLEMENTATION }
276
 
{ calc_crc32 }
277
 
function calc_crc32(buf : int8u_ptr; size : unsigned ) : unsigned;
278
 
var
279
 
 crc ,len ,nr : unsigned;
280
 
 
281
 
 p : int8u_ptr;
282
 
 
283
 
begin
284
 
 crc:=unsigned(not 0 );
285
 
 len:=0;
286
 
 nr :=size;
287
 
 len:=len + nr;
288
 
 p  :=buf;
289
 
 
290
 
 while nr <> 0 do
291
 
  begin
292
 
   dec(nr );
293
 
 
294
 
   crc:=(crc shr 8 ) xor crc32tab[(crc xor p^ ) and $ff ];
295
 
 
296
 
   inc(ptrcomp(p ) ,sizeof(int8u ) );
297
 
 
298
 
  end;
299
 
 
300
 
 result:=not crc;
301
 
 
302
 
end;
303
 
 
304
 
{ dbl_to_plain_fx }
305
 
function dbl_to_plain_fx(d : double ) : int;
306
 
begin
307
 
 result:=Trunc(d * 65536.0 )
308
 
 
309
 
end;
310
 
 
311
 
{ int26p6_to_dbl }
312
 
function int26p6_to_dbl(p : int ) : double;
313
 
begin
314
 
 result:=p / 64.0;
315
 
 
316
 
end;
317
 
 
318
 
{ dbl_to_int26p6 }
319
 
function dbl_to_int26p6(p : double ) : int;
320
 
begin
321
 
 result:=Trunc(p * 64.0 + 0.5 );
322
 
 
323
 
end;
324
 
 
325
 
{ decompose_ft_outline }
326
 
function decompose_ft_outline(
327
 
          outline : FT_Outline_ptr;
328
 
          flip_y : boolean;
329
 
          mtx : trans_affine_ptr;
330
 
          path : path_storage_integer_ptr ) : boolean;
331
 
var
332
 
 v_last ,v_control ,v_start ,vec ,v_middle ,vec1 ,vec2 : FT_Vector;
333
 
 
334
 
 x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double;
335
 
 
336
 
 point ,limit : FT_Vector_ptr;
337
 
 
338
 
 tags : char_ptr;
339
 
 
340
 
 n     ,      // index of contour in outline
341
 
 first ,      // index of first point in contour
342
 
 last  : int; // index of last point in contour
343
 
 
344
 
 tag : char;  // current point's state
345
 
 
346
 
label
347
 
 Do_Conic ,Close ;
348
 
 
349
 
begin
350
 
 first:=0;
351
 
 n    :=0;
352
 
 
353
 
 while n < outline.n_contours do
354
 
  begin
355
 
   last :=FT_Short_ptr(ptrcomp(outline.contours ) + n * sizeof(FT_Short ) )^;
356
 
   limit:=FT_Vector_ptr(ptrcomp(outline.points ) + last * sizeof(FT_Vector ) );
357
 
 
358
 
   v_start:=FT_Vector_ptr(ptrcomp(outline.points ) + first * sizeof(FT_Vector) )^;
359
 
   v_last :=FT_Vector_ptr(ptrcomp(outline.points ) + last * sizeof(FT_Vector) )^;
360
 
 
361
 
   v_control:=v_start;
362
 
 
363
 
   point:=FT_Vector_ptr(ptrcomp(outline.points ) + first * sizeof(FT_Vector ) );
364
 
   tags :=char_ptr     (ptrcomp(outline.tags ) + first * sizeof(char ) );
365
 
   tag  :=FT_CURVE_TAG (tags^ );
366
 
 
367
 
  // A contour cannot start with a cubic control point!
368
 
   if tag = char(FT_CURVE_TAG_CUBIC ) then
369
 
    begin
370
 
     result:=false;
371
 
 
372
 
     exit;
373
 
 
374
 
    end;
375
 
 
376
 
  // check first point to determine origin
377
 
   if tag = char(FT_CURVE_TAG_CONIC ) then
378
 
    begin
379
 
    // first point is conic control. Yes, this happens.
380
 
     if FT_CURVE_TAG(char_ptr(ptrcomp(outline.tags ) + last )^ ) = char(FT_CURVE_TAG_ON ) then
381
 
      begin
382
 
      // start at last point if it is on the curve
383
 
       v_start:=v_last;
384
 
 
385
 
       dec(limit );
386
 
 
387
 
      end
388
 
     else
389
 
      begin
390
 
      // if both first and last points are conic,
391
 
      // start at their middle and record its position
392
 
      // for closure
393
 
       v_start.x:=(v_start.x + v_last.x ) div 2;
394
 
       v_start.y:=(v_start.y + v_last.y ) div 2;
395
 
 
396
 
       v_last:=v_start;
397
 
 
398
 
      end;
399
 
 
400
 
     dec(ptrcomp(point ) ,sizeof(FT_Vector ) );
401
 
     dec(ptrcomp(tags ) );
402
 
 
403
 
    end;
404
 
 
405
 
   x1:=int26p6_to_dbl(v_start.x );
406
 
   y1:=int26p6_to_dbl(v_start.y );
407
 
 
408
 
   if flip_y then
409
 
    y1:=-y1;
410
 
 
411
 
   mtx.transform(mtx ,@x1 ,@y1 );
412
 
   path.move_to (dbl_to_int26p6(x1 ) ,dbl_to_int26p6(y1 ) );
413
 
 
414
 
   while ptrcomp(point ) < ptrcomp(limit ) do
415
 
    begin
416
 
     inc(ptrcomp(point ) ,sizeof(FT_Vector ) );
417
 
     inc(ptrcomp(tags ) );
418
 
 
419
 
     tag:=FT_CURVE_TAG(tags^ );
420
 
 
421
 
     case tag of
422
 
     // emit a single line_to
423
 
      char(FT_CURVE_TAG_ON ) :
424
 
       begin
425
 
        x1:=int26p6_to_dbl(point.x );
426
 
        y1:=int26p6_to_dbl(point.y );
427
 
 
428
 
        if flip_y then
429
 
         y1:=-y1;
430
 
 
431
 
        mtx.transform(mtx ,@x1 ,@y1 );
432
 
        path.line_to (dbl_to_int26p6(x1 ) ,dbl_to_int26p6(y1 ) );
433
 
 
434
 
        continue;
435
 
 
436
 
       end;
437
 
 
438
 
     // consume conic arcs
439
 
      char(FT_CURVE_TAG_CONIC ) :
440
 
       begin
441
 
        v_control.x:=point.x;
442
 
        v_control.y:=point.y;
443
 
 
444
 
       Do_Conic:
445
 
        if ptrcomp(point ) < ptrcomp(limit ) then
446
 
         begin
447
 
          inc(ptrcomp(point ) ,sizeof(FT_Vector ) );
448
 
          inc(ptrcomp(tags ) );
449
 
 
450
 
          tag:=FT_CURVE_TAG(tags^ );
451
 
 
452
 
          vec.x:=point.x;
453
 
          vec.y:=point.y;
454
 
 
455
 
          if tag = char(FT_CURVE_TAG_ON ) then
456
 
           begin
457
 
            x1:=int26p6_to_dbl(v_control.x );
458
 
            y1:=int26p6_to_dbl(v_control.y );
459
 
            x2:=int26p6_to_dbl(vec.x );
460
 
            y2:=int26p6_to_dbl(vec.y );
461
 
 
462
 
            if flip_y then
463
 
             begin
464
 
              y1:=-y1;
465
 
              y2:=-y2;
466
 
 
467
 
             end;
468
 
 
469
 
            mtx.transform(mtx ,@x1 ,@y1 );
470
 
            mtx.transform(mtx ,@x2 ,@y2 );
471
 
 
472
 
            path.curve3(
473
 
             dbl_to_int26p6(x1 ) ,
474
 
             dbl_to_int26p6(y1 ) ,
475
 
             dbl_to_int26p6(x2 ) ,
476
 
             dbl_to_int26p6(y2 ) );
477
 
 
478
 
            continue;
479
 
 
480
 
           end;
481
 
 
482
 
          if tag <> char(FT_CURVE_TAG_CONIC ) then
483
 
           begin
484
 
            result:=false;
485
 
 
486
 
            exit;
487
 
 
488
 
           end;
489
 
 
490
 
          v_middle.x:=(v_control.x + vec.x ) div 2;
491
 
          v_middle.y:=(v_control.y + vec.y ) div 2;
492
 
 
493
 
          x1:=int26p6_to_dbl(v_control.x );
494
 
          y1:=int26p6_to_dbl(v_control.y );
495
 
          x2:=int26p6_to_dbl(v_middle.x );
496
 
          y2:=int26p6_to_dbl(v_middle.y );
497
 
 
498
 
          if flip_y then
499
 
           begin
500
 
            y1:=-y1;
501
 
            y2:=-y2;
502
 
 
503
 
           end;
504
 
 
505
 
          mtx.transform(mtx ,@x1 ,@y1 );
506
 
          mtx.transform(mtx ,@x2 ,@y2 );
507
 
 
508
 
          path.curve3(
509
 
           dbl_to_int26p6(x1 ) ,
510
 
           dbl_to_int26p6(y1 ) ,
511
 
           dbl_to_int26p6(x2 ) ,
512
 
           dbl_to_int26p6(y2 ) );
513
 
 
514
 
          v_control:=vec;
515
 
 
516
 
          goto Do_Conic;
517
 
 
518
 
         end;
519
 
 
520
 
        x1:=int26p6_to_dbl(v_control.x );
521
 
        y1:=int26p6_to_dbl(v_control.y );
522
 
        x2:=int26p6_to_dbl(v_start.x );
523
 
        y2:=int26p6_to_dbl(v_start.y );
524
 
 
525
 
        if flip_y then
526
 
         begin
527
 
          y1:=-y1;
528
 
          y2:=-y2;
529
 
 
530
 
         end;
531
 
 
532
 
        mtx.transform(mtx ,@x1 ,@y1 );
533
 
        mtx.transform(mtx ,@x2 ,@y2 );
534
 
 
535
 
        path.curve3(
536
 
         dbl_to_int26p6(x1 ) ,
537
 
         dbl_to_int26p6(y1 ) ,
538
 
         dbl_to_int26p6(x2 ) ,
539
 
         dbl_to_int26p6(y2 ) );
540
 
 
541
 
        goto Close;
542
 
 
543
 
       end;
544
 
 
545
 
     // FT_CURVE_TAG_CUBIC
546
 
      else
547
 
       begin
548
 
        if (ptrcomp(point ) + sizeof(FT_Vector ) > ptrcomp(limit ) ) or
549
 
           (FT_CURVE_TAG(char_ptr(ptrcomp(tags ) + 1 )^ ) <> char(FT_CURVE_TAG_CUBIC ) ) then
550
 
         begin
551
 
          result:=false;
552
 
 
553
 
          exit;
554
 
 
555
 
         end;
556
 
 
557
 
        vec1.x:=point.x;
558
 
        vec1.y:=point.y;
559
 
        vec2.x:=FT_Vector_ptr(ptrcomp(point ) + sizeof(FT_Vector ) ).x;
560
 
        vec2.y:=FT_Vector_ptr(ptrcomp(point ) + sizeof(FT_Vector ) ).y;
561
 
 
562
 
        inc(ptrcomp(point ) ,2 * sizeof(FT_Vector ) );
563
 
        inc(ptrcomp(tags ) ,2 );
564
 
 
565
 
        if ptrcomp(point ) <= ptrcomp(limit ) then
566
 
         begin
567
 
          vec.x:=point.x;
568
 
          vec.y:=point.y;
569
 
 
570
 
          x1:=int26p6_to_dbl(vec1.x );
571
 
          y1:=int26p6_to_dbl(vec1.y );
572
 
          x2:=int26p6_to_dbl(vec2.x );
573
 
          y2:=int26p6_to_dbl(vec2.y );
574
 
          x3:=int26p6_to_dbl(vec.x );
575
 
          y3:=int26p6_to_dbl(vec.y );
576
 
 
577
 
          if flip_y then
578
 
           begin
579
 
            y1:=-y1;
580
 
            y2:=-y2;
581
 
            y3:=-y3;
582
 
 
583
 
           end;
584
 
 
585
 
          mtx.transform(mtx ,@x1 ,@y1 );
586
 
          mtx.transform(mtx ,@x2 ,@y2 );
587
 
          mtx.transform(mtx ,@x3 ,@y3 );
588
 
 
589
 
          path.curve4(
590
 
           dbl_to_int26p6(x1 ) ,
591
 
           dbl_to_int26p6(y1 ) ,
592
 
           dbl_to_int26p6(x2 ) ,
593
 
           dbl_to_int26p6(y2 ) ,
594
 
           dbl_to_int26p6(x3 ) ,
595
 
           dbl_to_int26p6(y3 ) );
596
 
 
597
 
          continue;
598
 
 
599
 
         end;
600
 
 
601
 
        x1:=int26p6_to_dbl(vec1.x );
602
 
        y1:=int26p6_to_dbl(vec1.y );
603
 
        x2:=int26p6_to_dbl(vec2.x );
604
 
        y2:=int26p6_to_dbl(vec2.y );
605
 
        x3:=int26p6_to_dbl(v_start.x );
606
 
        y3:=int26p6_to_dbl(v_start.y );
607
 
 
608
 
        if flip_y then
609
 
         begin
610
 
          y1:=-y1;
611
 
          y2:=-y2;
612
 
          y3:=-y3;
613
 
 
614
 
         end;
615
 
 
616
 
        mtx.transform(mtx ,@x1 ,@y1 );
617
 
        mtx.transform(mtx ,@x2 ,@y2 );
618
 
        mtx.transform(mtx ,@x3 ,@y3 );
619
 
 
620
 
        path.curve4(
621
 
         dbl_to_int26p6(x1) ,
622
 
         dbl_to_int26p6(y1) ,
623
 
         dbl_to_int26p6(x2) ,
624
 
         dbl_to_int26p6(y2) ,
625
 
         dbl_to_int26p6(x3) ,
626
 
         dbl_to_int26p6(y3) );
627
 
 
628
 
        goto Close;
629
 
 
630
 
       end;
631
 
 
632
 
     end;
633
 
 
634
 
    end;
635
 
 
636
 
   path.close_polygon;
637
 
 
638
 
  Close:
639
 
   first:=last + 1;
640
 
 
641
 
   inc(n );
642
 
 
643
 
  end;
644
 
 
645
 
 result:=true;
646
 
 
647
 
end;
648
 
 
649
 
{ decompose_ft_bitmap_mono }
650
 
procedure decompose_ft_bitmap_mono(
651
 
           bitmap : FT_Bitmap_ptr;
652
 
           x ,y : int;
653
 
           flip_y : boolean;
654
 
           sl : scanline_ptr;
655
 
           storage : renderer_scanline_ptr );
656
 
var
657
 
 i ,pitch ,j : int;
658
 
 
659
 
 buf  : int8u_ptr;
660
 
 bits : bitset_iterator;
661
 
 
662
 
begin
663
 
 buf  :=int8u_ptr(bitmap.buffer );
664
 
 pitch:=bitmap.pitch;
665
 
 
666
 
 sl.reset       (x ,x + bitmap.width );
667
 
 storage.prepare(bitmap.width + 2 );
668
 
 
669
 
 if flip_y then
670
 
  begin
671
 
   inc(ptrcomp(buf ) ,bitmap.pitch * (bitmap.rows - 1 ) );
672
 
   inc(y ,bitmap.rows );
673
 
 
674
 
   pitch:=-pitch;
675
 
 
676
 
  end;
677
 
 
678
 
 i:=0;
679
 
 
680
 
 while i < bitmap.rows do
681
 
  begin
682
 
   sl.reset_spans;
683
 
 
684
 
   bits.Construct(buf ,0 );
685
 
 
686
 
   j:=0;
687
 
 
688
 
   while j < bitmap.width do
689
 
    begin
690
 
     if bits.bit <> 0 then
691
 
      sl.add_cell(x + j ,cover_full );
692
 
 
693
 
     bits.inc_operator;
694
 
 
695
 
     inc(j );
696
 
 
697
 
    end;
698
 
 
699
 
   inc(ptrcomp(buf ) ,pitch * sizeof(int8u ) );
700
 
 
701
 
   if sl.num_spans <> 0 then
702
 
    begin
703
 
     sl.finalize   (y - i - 1 );
704
 
     storage.render(sl );
705
 
 
706
 
    end;
707
 
 
708
 
   inc(i );
709
 
 
710
 
  end;
711
 
 
712
 
end;
713
 
 
714
 
{ decompose_ft_bitmap_gray8 }
715
 
procedure decompose_ft_bitmap_gray8(
716
 
           bitmap : FT_Bitmap_ptr;
717
 
           x ,y : int;
718
 
           flip_y : boolean;
719
 
           ras : rasterizer_scanline_aa_ptr;
720
 
           sl : scanline_ptr;
721
 
           storage : renderer_scanline_ptr );
722
 
var
723
 
 i ,j ,pitch : int;
724
 
 
725
 
 buf ,p : int8u_ptr;
726
 
 
727
 
begin
728
 
 buf  :=int8u_ptr(bitmap.buffer );
729
 
 pitch:=bitmap.pitch;
730
 
 
731
 
 sl.reset       (x ,x + bitmap.width );
732
 
 storage.prepare(bitmap.width + 2 );
733
 
 
734
 
 if flip_y then
735
 
  begin
736
 
   inc(ptrcomp(buf ) ,bitmap.pitch * (bitmap.rows - 1 ) );
737
 
   inc(y ,bitmap.rows );
738
 
 
739
 
   pitch:=-pitch;
740
 
 
741
 
  end;
742
 
 
743
 
 i:=0;
744
 
 
745
 
 while i < bitmap.rows do
746
 
  begin
747
 
   sl.reset_spans;
748
 
 
749
 
   p:=buf;
750
 
   j:=0;
751
 
 
752
 
   while j < bitmap.width do
753
 
    begin
754
 
     if p^ <> 0 then
755
 
      sl.add_cell(x + j ,ras.apply_gamma(p^ ) );
756
 
 
757
 
     inc(ptrcomp(p ) ,sizeof(int8u ) );
758
 
     inc(j );
759
 
 
760
 
    end;
761
 
 
762
 
   inc(ptrcomp(buf ) ,pitch * sizeof(int8u ) );
763
 
 
764
 
   if sl.num_spans <> 0 then
765
 
    begin
766
 
     sl.finalize   (y - i - 1 );
767
 
     storage.render(sl );
768
 
 
769
 
    end;
770
 
 
771
 
   inc(i );
772
 
 
773
 
  end;
774
 
 
775
 
end;
776
 
 
777
 
{ CONSTRUCT }
778
 
constructor font_engine_freetype_base.Construct(flag32_ : boolean; max_faces : unsigned = 32 );
779
 
begin
780
 
 m_flag32:=flag32_;
781
 
 
782
 
 m_change_stamp:=0;
783
 
 m_last_error  :=0;
784
 
 
785
 
 m_name      :=NIL;
786
 
 m_name_len  :=256 - 16 - 1;
787
 
 m_face_index:=0;
788
 
 
789
 
 m_char_map:=FT_ENCODING_NONE;
790
 
 
791
 
 m_signature.size:=256 + 256 - 16;
792
 
 
793
 
 agg_getmem(pointer(m_signature.name ) ,m_signature.size );
794
 
 
795
 
 m_height :=0;
796
 
 m_width  :=0;
797
 
 m_hinting:=true;
798
 
 m_flip_y :=false;
799
 
 
800
 
 m_library_initialized:=false;
801
 
 
802
 
 m_library:=NIL;
803
 
 
804
 
 agg_getmem(pointer(m_faces ) ,max_faces * sizeof(FT_Face_ptr ) );
805
 
 agg_getmem(pointer(m_face_names ) ,max_faces * sizeof(face_name ) );
806
 
 
807
 
 m_num_faces :=0;
808
 
 m_max_faces :=max_faces;
809
 
 m_cur_face  :=NIL;
810
 
 m_resolution:=0;
811
 
 
812
 
 m_glyph_rendering:=glyph_ren_native_gray8;
813
 
 m_glyph_index    :=0;
814
 
 m_data_size      :=0;
815
 
 m_data_type      :=glyph_data_invalid;
816
 
 
817
 
 m_bounds.Construct(1 ,1 ,0 ,0 );
818
 
 
819
 
 m_advance_x:=0.0;
820
 
 m_advance_y:=0.0;
821
 
 
822
 
 m_affine.Construct;
823
 
 
824
 
 m_path16.Construct;
825
 
 m_path32.Construct;
826
 
 m_curves16.Construct(@m_path16 );
827
 
 m_curves32.Construct(@m_path32 );
828
 
 m_scanline_aa.Construct;
829
 
 m_scanline_bin.Construct;
830
 
 m_scanlines_aa.Construct;
831
 
 m_scanlines_bin.Construct;
832
 
 m_rasterizer.Construct;
833
 
 
834
 
 m_curves16.approximation_scale_(4.0 );
835
 
 m_curves32.approximation_scale_(4.0 );
836
 
 
837
 
 m_last_error:=FT_Init_FreeType(@m_library );
838
 
 
839
 
 if m_last_error = 0 then
840
 
  m_library_initialized:=true;
841
 
 
842
 
end;
843
 
 
844
 
{ DESTRUCT }
845
 
destructor font_engine_freetype_base.Destruct;
846
 
var
847
 
 i : unsigned;
848
 
 n : face_name_ptr;
849
 
 
850
 
begin
851
 
 i:=0;
852
 
 n:=m_face_names;
853
 
 
854
 
 while i < m_num_faces do
855
 
  begin
856
 
   agg_freemem (pointer(n.name ) ,n.size );
857
 
   FT_Done_Face(FT_Face_ptr_ptr(ptrcomp(m_faces ) + i * sizeof(FT_Face_ptr ) )^ );
858
 
 
859
 
   inc(ptrcomp(n ) ,sizeof(face_name ) );
860
 
   inc(i );
861
 
 
862
 
  end;
863
 
 
864
 
 agg_freemem(pointer(m_face_names ) ,m_max_faces * sizeof(face_name ) );
865
 
 agg_freemem(pointer(m_faces ) ,m_max_faces * sizeof(FT_Face_ptr ) );
866
 
 agg_freemem(pointer(m_signature.name ) ,m_signature.size );
867
 
 
868
 
 if m_library_initialized then
869
 
  FT_Done_FreeType(m_library );
870
 
 
871
 
 m_path16.Destruct;
872
 
 m_path32.Destruct;
873
 
 m_curves16.Destruct;
874
 
 m_curves32.Destruct;
875
 
 m_scanline_aa.Destruct;
876
 
 m_scanline_bin.Destruct;
877
 
 m_scanlines_aa.Destruct;
878
 
 m_scanlines_bin.Destruct;
879
 
 m_rasterizer.Destruct;
880
 
 
881
 
end;
882
 
 
883
 
{ RESOLUTION_ }
884
 
procedure font_engine_freetype_base.resolution_(dpi : unsigned );
885
 
begin
886
 
 m_resolution:=dpi;
887
 
 
888
 
 update_char_size;
889
 
 
890
 
end;
891
 
 
892
 
{ LOAD_FONT }
893
 
function font_engine_freetype_base.load_font(
894
 
          font_name : PChar; face_index : unsigned; ren_type : glyph_rendering;
895
 
          font_mem : PChar = NIL; font_mem_size : int = 0 ) : boolean;
896
 
var
897
 
 idx : int;
898
 
 
899
 
begin
900
 
 result:=false;
901
 
 
902
 
 if m_library_initialized then
903
 
  begin
904
 
   m_last_error:=0;
905
 
 
906
 
   idx:=find_face(font_name );
907
 
 
908
 
   if idx >= 0 then
909
 
    begin
910
 
     m_cur_face:=FT_Face_ptr_ptr(ptrcomp(m_faces ) + idx * sizeof(FT_Face_ptr ) )^;
911
 
     m_name    :=PChar(face_name_ptr(ptrcomp(m_face_names ) + idx * sizeof(face_name ) ).name );
912
 
 
913
 
    end
914
 
   else
915
 
    begin
916
 
     if m_num_faces >= m_max_faces then
917
 
      begin
918
 
       agg_freemem (pointer(m_face_names.name ) ,m_face_names.size );
919
 
       FT_Done_Face(m_faces^ );
920
 
 
921
 
       move(
922
 
        FT_Face_ptr_ptr(ptrcomp(m_faces ) + sizeof(FT_Face_ptr ) )^ ,
923
 
        m_faces^ ,
924
 
        (m_max_faces - 1 ) * sizeof(FT_Face_ptr ) );
925
 
 
926
 
       move(
927
 
        face_name_ptr(ptrcomp(m_face_names ) + sizeof(face_name ) )^ ,
928
 
        m_face_names^ ,
929
 
        (m_max_faces - 1 ) * sizeof(face_name ) );
930
 
 
931
 
       dec(m_num_faces );
932
 
 
933
 
      end;
934
 
 
935
 
     if (font_mem <> NIL ) and
936
 
        (font_mem_size > 0 ) then
937
 
      m_last_error:=
938
 
       FT_New_Memory_Face(
939
 
        m_library ,
940
 
        FT_Byte_ptr(font_mem ) ,
941
 
        font_mem_size ,
942
 
        face_index ,
943
 
        FT_Face_ptr_ptr(ptrcomp(m_faces ) + m_num_faces * sizeof(FT_Face_ptr ) )^ )
944
 
     else
945
 
      m_last_error:=
946
 
       FT_New_Face(
947
 
        m_library ,
948
 
        font_name ,
949
 
        face_index ,
950
 
        FT_Face_ptr_ptr(ptrcomp(m_faces ) + m_num_faces * sizeof(FT_Face_ptr ) )^ );
951
 
 
952
 
     if m_last_error = 0 then
953
 
      begin
954
 
       face_name_ptr(ptrcomp(m_face_names ) + m_num_faces * sizeof(face_name ) ).size:=
955
 
        StrLen(font_name ) + 1;
956
 
 
957
 
       agg_getmem(
958
 
        pointer(face_name_ptr(ptrcomp(m_face_names ) + m_num_faces * sizeof(face_name ) ).name ) ,
959
 
        face_name_ptr(ptrcomp(m_face_names ) + m_num_faces * sizeof(face_name ) ).size );
960
 
 
961
 
       StrCopy(
962
 
        PChar(face_name_ptr(ptrcomp(m_face_names ) + m_num_faces * sizeof(face_name ) ).name ) ,
963
 
        font_name );
964
 
 
965
 
       m_cur_face:=FT_Face_ptr_ptr(ptrcomp(m_faces ) + m_num_faces * sizeof(FT_Face_ptr ) )^;
966
 
       m_name    :=PChar(face_name_ptr(ptrcomp(m_face_names ) + m_num_faces * sizeof(face_name ) ).name );
967
 
 
968
 
       inc(m_num_faces );
969
 
 
970
 
      end
971
 
     else
972
 
      begin
973
 
       PChar(face_name_ptr(ptrcomp(m_face_names ) + m_num_faces * sizeof(face_name ) ).name ):=NIL;
974
 
 
975
 
       m_cur_face:=NIL;
976
 
       m_name    :=NIL;
977
 
 
978
 
      end;
979
 
 
980
 
    end;
981
 
 
982
 
   if m_last_error = 0 then
983
 
    begin
984
 
     result:=true;
985
 
 
986
 
     case ren_type of
987
 
      glyph_ren_native_mono :
988
 
       m_glyph_rendering:=glyph_ren_native_mono;
989
 
 
990
 
      glyph_ren_native_gray8 :
991
 
       m_glyph_rendering:=glyph_ren_native_gray8;
992
 
 
993
 
      glyph_ren_outline :
994
 
       if FT_IS_SCALABLE(m_cur_face ) then
995
 
        m_glyph_rendering:=glyph_ren_outline
996
 
       else
997
 
        m_glyph_rendering:=glyph_ren_native_gray8;
998
 
 
999
 
      glyph_ren_agg_mono :
1000
 
       if FT_IS_SCALABLE(m_cur_face ) then
1001
 
        m_glyph_rendering:=glyph_ren_agg_mono
1002
 
       else
1003
 
        m_glyph_rendering:=glyph_ren_native_mono;
1004
 
 
1005
 
      glyph_ren_agg_gray8 :
1006
 
       if FT_IS_SCALABLE(m_cur_face ) then
1007
 
        m_glyph_rendering:=glyph_ren_agg_gray8
1008
 
       else
1009
 
        m_glyph_rendering:=glyph_ren_native_gray8;
1010
 
 
1011
 
     end;
1012
 
 
1013
 
     update_signature;
1014
 
 
1015
 
    end;
1016
 
 
1017
 
  end;
1018
 
 
1019
 
end;
1020
 
 
1021
 
{ ATTACH }
1022
 
function font_engine_freetype_base.attach(file_name : PChar ) : boolean;
1023
 
begin
1024
 
 result:=false;
1025
 
 
1026
 
 if m_cur_face <> NIL then
1027
 
  begin
1028
 
   m_last_error:=FT_Attach_File(m_cur_face ,file_name );
1029
 
 
1030
 
   result:=m_last_error = 0;
1031
 
 
1032
 
  end;
1033
 
 
1034
 
end;
1035
 
 
1036
 
{ CHAR_MAP_ }
1037
 
function font_engine_freetype_base.char_map_(map : FT_Encoding ) : boolean;
1038
 
begin
1039
 
 result:=false;
1040
 
 
1041
 
 if m_cur_face <> NIL then
1042
 
  begin
1043
 
   m_last_error:=FT_Select_Charmap(m_cur_face ,map );
1044
 
 
1045
 
   if m_last_error = 0 then
1046
 
    begin
1047
 
     m_char_map:=map;
1048
 
 
1049
 
     update_signature;
1050
 
 
1051
 
     result:=true;
1052
 
 
1053
 
    end;
1054
 
 
1055
 
  end;
1056
 
 
1057
 
end;
1058
 
 
1059
 
{ HEIGHT_ }
1060
 
function font_engine_freetype_base.height_(h : double ) : boolean;
1061
 
begin
1062
 
 result  :=false;
1063
 
 m_height:=Trunc(h * 64.0 );
1064
 
 
1065
 
 if m_cur_face <> NIL then
1066
 
  begin
1067
 
   update_char_size;
1068
 
 
1069
 
   result:=true;
1070
 
 
1071
 
  end;
1072
 
 
1073
 
end;
1074
 
 
1075
 
{ WIDTH_ }
1076
 
function font_engine_freetype_base.width_(w : double ) : boolean;
1077
 
begin
1078
 
 result :=false;
1079
 
 m_width:=Trunc(w * 64.0 );
1080
 
 
1081
 
 if m_cur_face <> NIL then
1082
 
  begin
1083
 
   update_char_size;
1084
 
 
1085
 
   result:=true;
1086
 
 
1087
 
  end;
1088
 
 
1089
 
end;
1090
 
 
1091
 
{ HINTING_ }
1092
 
procedure font_engine_freetype_base.hinting_(h : boolean );
1093
 
begin
1094
 
 m_hinting:=h;
1095
 
 
1096
 
 if m_cur_face <> NIL then
1097
 
  update_signature;
1098
 
 
1099
 
end;
1100
 
 
1101
 
{ FLIP_Y_ }
1102
 
procedure font_engine_freetype_base.flip_y_(flip : boolean );
1103
 
begin
1104
 
 m_flip_y:=flip;
1105
 
 
1106
 
 if m_cur_face <> NIL then
1107
 
  update_signature;
1108
 
 
1109
 
end;
1110
 
 
1111
 
{ TRANSFORM_ }
1112
 
procedure font_engine_freetype_base.transform_(affine : trans_affine_ptr );
1113
 
begin
1114
 
 m_affine.assign_all(affine );
1115
 
 
1116
 
 if m_cur_face <> NIL then
1117
 
  update_signature;
1118
 
 
1119
 
end;
1120
 
 
1121
 
{ GAMMA_ }
1122
 
procedure font_engine_freetype_base.gamma_(f : vertex_source_ptr );
1123
 
begin
1124
 
 m_rasterizer.gamma(f );
1125
 
 
1126
 
end;
1127
 
 
1128
 
{ LAST_ERROR_ }
1129
 
function font_engine_freetype_base._last_error : int;
1130
 
begin
1131
 
 result:=m_last_error;
1132
 
 
1133
 
end;
1134
 
 
1135
 
{ _RESOLUTION }
1136
 
function font_engine_freetype_base._resolution : unsigned;
1137
 
begin
1138
 
 result:=m_resolution;
1139
 
 
1140
 
end;
1141
 
 
1142
 
{ _NAME }
1143
 
function font_engine_freetype_base._name : PChar;
1144
 
begin
1145
 
 result:=m_name;
1146
 
 
1147
 
end;
1148
 
 
1149
 
{ _NUM_FACES }
1150
 
function font_engine_freetype_base._num_faces : unsigned;
1151
 
begin
1152
 
 if m_cur_face <> NIL then
1153
 
  result:=m_cur_face.num_faces
1154
 
 else
1155
 
  result:=0;
1156
 
 
1157
 
end;
1158
 
 
1159
 
{ _CHAR_MAP }
1160
 
function font_engine_freetype_base._char_map : FT_Encoding;
1161
 
begin
1162
 
 result:=m_char_map;
1163
 
 
1164
 
end;
1165
 
 
1166
 
{ _HEIGHT }
1167
 
function font_engine_freetype_base._height : double;
1168
 
begin
1169
 
 result:=m_height / 64.0;
1170
 
 
1171
 
end;
1172
 
 
1173
 
{ _WIDTH }
1174
 
function font_engine_freetype_base._width : double;
1175
 
begin
1176
 
 result:=m_width / 64.0;
1177
 
 
1178
 
end;
1179
 
 
1180
 
{ _ASCENDER }
1181
 
function font_engine_freetype_base._ascender : double;
1182
 
begin
1183
 
 if m_cur_face <> NIL then
1184
 
  result:=m_cur_face.ascender * _height / m_cur_face.height
1185
 
 else
1186
 
  result:=0.0;
1187
 
 
1188
 
end;
1189
 
 
1190
 
{ _DESCENDER }
1191
 
function font_engine_freetype_base._descender : double;
1192
 
begin
1193
 
 if m_cur_face <> NIL then
1194
 
  result:=m_cur_face.descender * _height / m_cur_face.height
1195
 
 else
1196
 
  result:=0.0;
1197
 
 
1198
 
end;
1199
 
 
1200
 
{ _HINTING }
1201
 
function font_engine_freetype_base._hinting : boolean;
1202
 
begin
1203
 
 result:=m_hinting;
1204
 
 
1205
 
end;
1206
 
 
1207
 
{ _FLIP_Y }
1208
 
function font_engine_freetype_base._flip_y : boolean;
1209
 
begin
1210
 
 result:=m_flip_y;
1211
 
 
1212
 
end;
1213
 
 
1214
 
{ FONT_SIGNATURE }
1215
 
function font_engine_freetype_base.font_signature : PChar;
1216
 
begin
1217
 
 result:=PChar(m_signature.name );
1218
 
 
1219
 
end;
1220
 
 
1221
 
{ CHANGE_STAMP }
1222
 
function font_engine_freetype_base.change_stamp : int;
1223
 
begin
1224
 
 result:=m_change_stamp;
1225
 
 
1226
 
end;
1227
 
 
1228
 
{ PREPARE_GLYPH }
1229
 
function font_engine_freetype_base.prepare_glyph(glyph_code : unsigned ) : boolean;
1230
 
var
1231
 
 fl : int;
1232
 
 
1233
 
 bnd : rect_d; 
1234
 
 
1235
 
begin
1236
 
 result:=false;
1237
 
 
1238
 
 m_glyph_index:=FT_Get_Char_Index(m_cur_face ,glyph_code );
1239
 
 
1240
 
 if m_hinting then
1241
 
  m_last_error:=FT_Load_Glyph(m_cur_face ,m_glyph_index ,FT_LOAD_DEFAULT{} {FT_LOAD_FORCE_AUTOHINT{} )
1242
 
 else
1243
 
  m_last_error:=FT_Load_Glyph(m_cur_face ,m_glyph_index ,FT_LOAD_NO_HINTING );
1244
 
 
1245
 
 if m_last_error = 0 then
1246
 
  case m_glyph_rendering of
1247
 
   glyph_ren_native_mono :
1248
 
    begin
1249
 
     m_last_error:=FT_Render_Glyph(m_cur_face.glyph ,FT_RENDER_MODE_MONO );
1250
 
 
1251
 
     if m_last_error = 0 then
1252
 
      begin
1253
 
       if m_flip_y then
1254
 
        fl:=-m_cur_face.glyph.bitmap_top
1255
 
       else
1256
 
        fl:=m_cur_face.glyph.bitmap_top;
1257
 
 
1258
 
       decompose_ft_bitmap_mono(
1259
 
        @m_cur_face.glyph.bitmap ,
1260
 
        m_cur_face.glyph.bitmap_left ,
1261
 
        fl ,
1262
 
        m_flip_y ,
1263
 
        @m_scanline_bin ,
1264
 
        @m_scanlines_bin );
1265
 
 
1266
 
       m_bounds.x1:=m_scanlines_bin._min_x;
1267
 
       m_bounds.y1:=m_scanlines_bin._min_y;
1268
 
       m_bounds.x2:=m_scanlines_bin._max_x;
1269
 
       m_bounds.y2:=m_scanlines_bin._max_y;
1270
 
       m_data_size:=m_scanlines_bin.byte_size;
1271
 
       m_data_type:=glyph_data_mono;
1272
 
       m_advance_x:=int26p6_to_dbl(m_cur_face.glyph.advance.x );
1273
 
       m_advance_y:=int26p6_to_dbl(m_cur_face.glyph.advance.y );
1274
 
 
1275
 
       result:=true;
1276
 
 
1277
 
      end;
1278
 
 
1279
 
    end;
1280
 
 
1281
 
   glyph_ren_native_gray8 :
1282
 
    begin
1283
 
     m_last_error:=FT_Render_Glyph(m_cur_face.glyph ,FT_RENDER_MODE_NORMAL );
1284
 
 
1285
 
     if m_last_error = 0 then
1286
 
      begin
1287
 
       if m_flip_y then
1288
 
        fl:=-m_cur_face.glyph.bitmap_top
1289
 
       else
1290
 
        fl:=m_cur_face.glyph.bitmap_top;
1291
 
 
1292
 
       decompose_ft_bitmap_gray8(
1293
 
        @m_cur_face.glyph.bitmap ,
1294
 
        m_cur_face.glyph.bitmap_left ,
1295
 
        fl ,
1296
 
        m_flip_y ,
1297
 
        @m_rasterizer ,
1298
 
        @m_scanline_aa ,
1299
 
        @m_scanlines_aa );
1300
 
 
1301
 
       m_bounds.x1:=m_scanlines_aa._min_x;
1302
 
       m_bounds.y1:=m_scanlines_aa._min_y;
1303
 
       m_bounds.x2:=m_scanlines_aa._max_x;
1304
 
       m_bounds.y2:=m_scanlines_aa._max_y;
1305
 
       m_data_size:=m_scanlines_aa.byte_size;
1306
 
       m_data_type:=glyph_data_gray8;
1307
 
       m_advance_x:=int26p6_to_dbl(m_cur_face.glyph.advance.x );
1308
 
       m_advance_y:=int26p6_to_dbl(m_cur_face.glyph.advance.y );
1309
 
 
1310
 
       result:=true;
1311
 
 
1312
 
      end;
1313
 
 
1314
 
    end;
1315
 
 
1316
 
   glyph_ren_outline :
1317
 
    if m_last_error = 0 then
1318
 
     if m_flag32 then
1319
 
      begin
1320
 
       m_path32.remove_all;
1321
 
 
1322
 
       if decompose_ft_outline(
1323
 
           @m_cur_face.glyph.outline ,
1324
 
           m_flip_y ,
1325
 
           @m_affine ,
1326
 
           @m_path32 ) then
1327
 
        begin
1328
 
         bnd:=m_path32.bounding_rect;
1329
 
 
1330
 
         m_data_size:=m_path32.byte_size;
1331
 
         m_data_type:=glyph_data_outline;
1332
 
         m_bounds.x1:=Floor(bnd.x1 );
1333
 
         m_bounds.y1:=Floor(bnd.y1 );
1334
 
         m_bounds.x2:=Ceil(bnd.x2 );
1335
 
         m_bounds.y2:=Ceil(bnd.y2 );
1336
 
         m_advance_x:=int26p6_to_dbl(m_cur_face.glyph.advance.x );
1337
 
         m_advance_y:=int26p6_to_dbl(m_cur_face.glyph.advance.y );
1338
 
 
1339
 
         m_affine.transform(@m_affine ,@m_advance_x ,@m_advance_y );
1340
 
 
1341
 
         result:=true;
1342
 
 
1343
 
        end;
1344
 
 
1345
 
      end
1346
 
     else
1347
 
      begin
1348
 
       m_path16.remove_all;
1349
 
 
1350
 
       if decompose_ft_outline(
1351
 
           @m_cur_face.glyph.outline ,
1352
 
           m_flip_y ,
1353
 
           @m_affine ,
1354
 
           @m_path16 ) then
1355
 
        begin
1356
 
         bnd:=m_path16.bounding_rect;
1357
 
 
1358
 
         m_data_size:=m_path16.byte_size;
1359
 
         m_data_type:=glyph_data_outline;
1360
 
         m_bounds.x1:=Floor(bnd.x1 );
1361
 
         m_bounds.y1:=Floor(bnd.y1 );
1362
 
         m_bounds.x2:=Ceil(bnd.x2 );
1363
 
         m_bounds.y2:=Ceil(bnd.y2 );
1364
 
         m_advance_x:=int26p6_to_dbl(m_cur_face.glyph.advance.x );
1365
 
         m_advance_y:=int26p6_to_dbl(m_cur_face.glyph.advance.y );
1366
 
 
1367
 
         m_affine.transform(@m_affine ,@m_advance_x ,@m_advance_y );
1368
 
 
1369
 
         result:=true;
1370
 
 
1371
 
        end;
1372
 
 
1373
 
      end;
1374
 
 
1375
 
   glyph_ren_agg_mono :
1376
 
    if m_last_error = 0 then
1377
 
     begin
1378
 
      m_rasterizer.reset;
1379
 
 
1380
 
      if m_flag32 then
1381
 
       begin
1382
 
        m_path32.remove_all;
1383
 
 
1384
 
        decompose_ft_outline(
1385
 
         @m_cur_face.glyph.outline ,
1386
 
         m_flip_y ,
1387
 
         @m_affine ,
1388
 
         @m_path32 );
1389
 
 
1390
 
        m_rasterizer.add_path(@m_curves32 );
1391
 
 
1392
 
       end
1393
 
      else
1394
 
       begin
1395
 
        m_path16.remove_all;
1396
 
 
1397
 
        decompose_ft_outline(
1398
 
         @m_cur_face.glyph.outline ,
1399
 
         m_flip_y ,
1400
 
         @m_affine ,
1401
 
         @m_path16 );
1402
 
 
1403
 
        m_rasterizer.add_path(@m_curves16 );
1404
 
 
1405
 
       end;
1406
 
 
1407
 
      m_scanlines_bin.prepare(1 ); // Remove all
1408
 
 
1409
 
      render_scanlines(@m_rasterizer ,@m_scanline_bin ,@m_scanlines_bin );
1410
 
 
1411
 
      m_bounds.x1:=m_scanlines_bin._min_x;
1412
 
      m_bounds.y1:=m_scanlines_bin._min_y;
1413
 
      m_bounds.x2:=m_scanlines_bin._max_x;
1414
 
      m_bounds.y2:=m_scanlines_bin._max_y;
1415
 
      m_data_size:=m_scanlines_bin.byte_size;
1416
 
      m_data_type:=glyph_data_mono;
1417
 
      m_advance_x:=int26p6_to_dbl(m_cur_face.glyph.advance.x );
1418
 
      m_advance_y:=int26p6_to_dbl(m_cur_face.glyph.advance.y );
1419
 
 
1420
 
      m_affine.transform(@m_affine ,@m_advance_x ,@m_advance_y );
1421
 
 
1422
 
      result:=true;
1423
 
 
1424
 
     end;
1425
 
 
1426
 
   glyph_ren_agg_gray8 :
1427
 
    if m_last_error = 0 then
1428
 
     begin
1429
 
      m_rasterizer.reset;
1430
 
 
1431
 
      if m_flag32 then
1432
 
       begin
1433
 
        m_path32.remove_all;
1434
 
 
1435
 
        decompose_ft_outline(
1436
 
         @m_cur_face.glyph.outline ,
1437
 
         m_flip_y ,
1438
 
         @m_affine ,
1439
 
         @m_path32 );
1440
 
 
1441
 
        m_rasterizer.add_path(@m_curves32 );
1442
 
 
1443
 
       end
1444
 
      else
1445
 
       begin
1446
 
        m_path16.remove_all;
1447
 
 
1448
 
        decompose_ft_outline(
1449
 
         @m_cur_face.glyph.outline ,
1450
 
         m_flip_y ,
1451
 
         @m_affine ,
1452
 
         @m_path16 );
1453
 
 
1454
 
        m_rasterizer.add_path(@m_curves16 );
1455
 
 
1456
 
       end;
1457
 
 
1458
 
      m_scanlines_aa.prepare(1 ); // Remove all
1459
 
 
1460
 
      render_scanlines(@m_rasterizer ,@m_scanline_aa ,@m_scanlines_aa );
1461
 
 
1462
 
      m_bounds.x1:=m_scanlines_aa._min_x;
1463
 
      m_bounds.y1:=m_scanlines_aa._min_y;
1464
 
      m_bounds.x2:=m_scanlines_aa._max_x;
1465
 
      m_bounds.y2:=m_scanlines_aa._max_y;
1466
 
      m_data_size:=m_scanlines_aa.byte_size;
1467
 
      m_data_type:=glyph_data_gray8;
1468
 
      m_advance_x:=int26p6_to_dbl(m_cur_face.glyph.advance.x );
1469
 
      m_advance_y:=int26p6_to_dbl(m_cur_face.glyph.advance.y );
1470
 
 
1471
 
      m_affine.transform(@m_affine ,@m_advance_x ,@m_advance_y );
1472
 
 
1473
 
      result:=true;
1474
 
 
1475
 
     end;
1476
 
 
1477
 
  end;
1478
 
 
1479
 
end;
1480
 
 
1481
 
{ GLYPH_INDEX }
1482
 
function font_engine_freetype_base.glyph_index : unsigned;
1483
 
begin
1484
 
 result:=m_glyph_index;
1485
 
 
1486
 
end;
1487
 
 
1488
 
{ DATA_SIZE }
1489
 
function font_engine_freetype_base.data_size : unsigned;
1490
 
begin
1491
 
 result:=m_data_size;
1492
 
 
1493
 
end;
1494
 
 
1495
 
{ DATA_TYPE }
1496
 
function font_engine_freetype_base.data_type : unsigned;
1497
 
begin
1498
 
 result:=m_data_type;
1499
 
 
1500
 
end;
1501
 
 
1502
 
{ BOUNDS }
1503
 
function font_engine_freetype_base.bounds : rect_ptr;
1504
 
begin
1505
 
 result:=@m_bounds;
1506
 
 
1507
 
end;
1508
 
 
1509
 
{ ADVANCE_X }
1510
 
function font_engine_freetype_base.advance_x : double;
1511
 
begin
1512
 
 result:=m_advance_x;
1513
 
 
1514
 
end;
1515
 
 
1516
 
{ ADVANCE_Y }
1517
 
function font_engine_freetype_base.advance_y : double;
1518
 
begin
1519
 
 result:=m_advance_y;
1520
 
 
1521
 
end;
1522
 
 
1523
 
{ WRITE_GLYPH_TO }
1524
 
procedure font_engine_freetype_base.write_glyph_to(data : int8u_ptr );
1525
 
begin
1526
 
 if (data <> NIL ) and
1527
 
    (m_data_size <> 0 ) then
1528
 
  case m_data_type of
1529
 
   glyph_data_mono :
1530
 
    m_scanlines_bin.serialize(data );
1531
 
 
1532
 
   glyph_data_gray8 :
1533
 
    m_scanlines_aa.serialize(data );
1534
 
 
1535
 
   glyph_data_outline :
1536
 
    if m_flag32 then
1537
 
     m_path32.serialize(data )
1538
 
    else
1539
 
     m_path16.serialize(data );
1540
 
 
1541
 
  end;
1542
 
 
1543
 
end;
1544
 
 
1545
 
{ ADD_KERNING }
1546
 
function font_engine_freetype_base.add_kerning(first ,second : unsigned; x ,y : double_ptr ) : boolean;
1547
 
var
1548
 
 delta  : FT_Vector;
1549
 
 dx ,dy : double;
1550
 
 
1551
 
begin
1552
 
 if (m_cur_face <> NIL ) and
1553
 
    (first <> 0 ) and
1554
 
    (second <> 0 ) and
1555
 
    FT_HAS_KERNING(m_cur_face ) then
1556
 
  begin
1557
 
   FT_Get_Kerning(m_cur_face ,first ,second ,FT_KERNING_DEFAULT ,@delta );
1558
 
 
1559
 
   dx:=int26p6_to_dbl(delta.x );
1560
 
   dy:=int26p6_to_dbl(delta.y );
1561
 
 
1562
 
   if (m_glyph_rendering = glyph_ren_outline ) or
1563
 
      (m_glyph_rendering = glyph_ren_agg_mono ) or
1564
 
      (m_glyph_rendering = glyph_ren_agg_gray8 ) then
1565
 
    m_affine.transform_2x2(@m_affine ,@dx ,@dy );
1566
 
 
1567
 
   x^:=x^ + dx;
1568
 
   y^:=y^ + dy;
1569
 
 
1570
 
   result:=true;
1571
 
 
1572
 
  end
1573
 
 else
1574
 
  result:=false;
1575
 
 
1576
 
end;
1577
 
 
1578
 
{ FLAG32 }
1579
 
function font_engine_freetype_base.flag32;
1580
 
begin
1581
 
 result:=m_flag32;
1582
 
 
1583
 
end;
1584
 
 
1585
 
{ UPDATE_CHAR_SIZE }
1586
 
procedure font_engine_freetype_base.update_char_size;
1587
 
begin
1588
 
 if m_cur_face <> NIL then
1589
 
  begin
1590
 
   if m_resolution <> 0 then
1591
 
    FT_Set_Char_Size(
1592
 
     m_cur_face ,
1593
 
     m_width ,       // char_width in 1/64th of points
1594
 
     m_height ,      // char_height in 1/64th of points
1595
 
     m_resolution ,  // horizontal device resolution
1596
 
     m_resolution )  // vertical device resolution
1597
 
   else
1598
 
    FT_Set_Pixel_Sizes(
1599
 
     m_cur_face ,
1600
 
     m_width shr 6 ,    // pixel_width
1601
 
     m_height shr 6 );  // pixel_height
1602
 
 
1603
 
   update_signature;
1604
 
 
1605
 
  end;
1606
 
 
1607
 
end;
1608
 
 
1609
 
{ UPDATE_SIGNATURE }
1610
 
procedure font_engine_freetype_base.update_signature;
1611
 
var
1612
 
 name_len ,gamma_hash ,i : unsigned;
1613
 
 
1614
 
 gamma_table : array[0..aa_num - 1 ] of int8u;
1615
 
 
1616
 
 mtx : array[0..5 ] of double;
1617
 
 buf : array[0..99 ] of char;
1618
 
 str : char_ptr;
1619
 
 
1620
 
begin
1621
 
 if (m_cur_face <> NIL ) and
1622
 
    (m_name <> NIL ) then
1623
 
  begin
1624
 
   name_len:=StrLen(m_name );
1625
 
 
1626
 
   if name_len > m_name_len then
1627
 
    begin
1628
 
     agg_freemem(pointer(m_signature.name ) ,m_signature.size );
1629
 
 
1630
 
     m_signature.size:=name_len + 32 + 256;
1631
 
 
1632
 
     agg_getmem(pointer(m_signature.name ) ,m_signature.size );
1633
 
 
1634
 
     m_name_len:=name_len + 32 - 1;
1635
 
 
1636
 
    end;
1637
 
 
1638
 
   gamma_hash:=0;
1639
 
 
1640
 
   if (m_glyph_rendering = glyph_ren_native_gray8 ) or
1641
 
      (m_glyph_rendering = glyph_ren_agg_mono ) or
1642
 
      (m_glyph_rendering = glyph_ren_agg_gray8 ) then
1643
 
    begin
1644
 
     for i:=0 to aa_num - 1 do
1645
 
      gamma_table[i ]:=m_rasterizer.apply_gamma(i );
1646
 
 
1647
 
     gamma_hash:=calc_crc32(@gamma_table ,sizeof(gamma_table ) );
1648
 
 
1649
 
    end;
1650
 
 
1651
 
   str:=m_signature.name;
1652
 
 
1653
 
   sprintf(str                                             ,'%s,'  ,ptrcomp(m_name ) );
1654
 
   sprintf(char_ptr(ptrcomp(str ) + StrLen(PChar(str ) ) ) ,'%u,'  ,int(m_char_map ) );
1655
 
   sprintf(char_ptr(ptrcomp(str ) + StrLen(PChar(str ) ) ) ,'%d,'  ,m_face_index );
1656
 
   sprintf(char_ptr(ptrcomp(str ) + StrLen(PChar(str ) ) ) ,'%d,'  ,int(m_glyph_rendering ) );
1657
 
   sprintf(char_ptr(ptrcomp(str ) + StrLen(PChar(str ) ) ) ,'%d:'  ,m_resolution );
1658
 
   sprintf(char_ptr(ptrcomp(str ) + StrLen(PChar(str ) ) ) ,'%dx'  ,m_height );
1659
 
   sprintf(char_ptr(ptrcomp(str ) + StrLen(PChar(str ) ) ) ,'%d,'  ,m_width );
1660
 
   sprintf(char_ptr(ptrcomp(str ) + StrLen(PChar(str ) ) ) ,'%d,'  ,int(m_hinting ) );
1661
 
   sprintf(char_ptr(ptrcomp(str ) + StrLen(PChar(str ) ) ) ,'%d,'  ,int(m_flip_y ) );
1662
 
   sprintf(char_ptr(ptrcomp(str ) + StrLen(PChar(str ) ) ) ,'%08X' ,gamma_hash );
1663
 
 
1664
 
   if (m_glyph_rendering = glyph_ren_outline ) or
1665
 
      (m_glyph_rendering = glyph_ren_agg_mono ) or
1666
 
      (m_glyph_rendering = glyph_ren_agg_gray8 ) then
1667
 
    begin
1668
 
     m_affine.store_to(@mtx );
1669
 
 
1670
 
     sprintf(@buf[0 ]                 ,',%08X' ,dbl_to_plain_fx(mtx[0 ] ) );
1671
 
     sprintf(@buf[StrLen(@buf[0 ] ) ] ,'%08X'  ,dbl_to_plain_fx(mtx[1 ] ) );
1672
 
     sprintf(@buf[StrLen(@buf[0 ] ) ] ,'%08X'  ,dbl_to_plain_fx(mtx[2 ] ) );
1673
 
     sprintf(@buf[StrLen(@buf[0 ] ) ] ,'%08X'  ,dbl_to_plain_fx(mtx[3 ] ) );
1674
 
     sprintf(@buf[StrLen(@buf[0 ] ) ] ,'%08X'  ,dbl_to_plain_fx(mtx[4 ] ) );
1675
 
     sprintf(@buf[StrLen(@buf[0 ] ) ] ,'%08X'  ,dbl_to_plain_fx(mtx[5 ] ) );
1676
 
 
1677
 
     StrCat(PChar(m_signature.name ) ,buf );
1678
 
 
1679
 
    end;
1680
 
 
1681
 
   inc(m_change_stamp );
1682
 
 
1683
 
  end;
1684
 
 
1685
 
end;
1686
 
 
1687
 
{ FIND_FACE }
1688
 
function font_engine_freetype_base.find_face(name : PChar ) : int;
1689
 
var
1690
 
 i : unsigned;
1691
 
 n : face_name_ptr;
1692
 
 
1693
 
begin
1694
 
 result:=-1;
1695
 
 
1696
 
 n:=m_face_names;
1697
 
 i:=0;
1698
 
 
1699
 
 while i < m_num_faces do
1700
 
  begin
1701
 
   if StrComp(name ,PChar(n.name ) ) = 0 then
1702
 
    begin
1703
 
     result:=i;
1704
 
 
1705
 
     exit;
1706
 
 
1707
 
    end;
1708
 
 
1709
 
   inc(ptrcomp(n ) ,sizeof(face_name ) );
1710
 
   inc(i );
1711
 
 
1712
 
  end;
1713
 
 
1714
 
end;
1715
 
 
1716
 
{ CONSTRUCT }
1717
 
constructor font_engine_freetype_int16.Construct(max_faces : unsigned = 32 );
1718
 
begin
1719
 
 inherited Construct(false ,max_faces );
1720
 
 
1721
 
end;
1722
 
 
1723
 
{ CONSTRUCT }
1724
 
constructor font_engine_freetype_int32.Construct(max_faces : unsigned = 32 );
1725
 
begin
1726
 
 inherited Construct(true ,max_faces );
1727
 
 
1728
 
end;
1729
 
 
1730
 
END.
1731