~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/extras/freetype2/src/bdf/bdfdrivr.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  bdfdrivr.c
 
2
 
 
3
    FreeType font driver for bdf files
 
4
 
 
5
    Copyright (C) 2001-2002 by
 
6
    Francesco Zappa Nardelli
 
7
 
 
8
Permission is hereby granted, free of charge, to any person obtaining a copy
 
9
of this software and associated documentation files (the "Software"), to deal
 
10
in the Software without restriction, including without limitation the rights
 
11
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
12
copies of the Software, and to permit persons to whom the Software is
 
13
furnished to do so, subject to the following conditions:
 
14
 
 
15
The above copyright notice and this permission notice shall be included in
 
16
all copies or substantial portions of the Software.
 
17
 
 
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
20
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
21
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
22
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
23
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
24
THE SOFTWARE.
 
25
*/
 
26
 
 
27
#include <ft2build.h>
 
28
 
 
29
#include FT_INTERNAL_DEBUG_H
 
30
#include FT_INTERNAL_STREAM_H
 
31
#include FT_INTERNAL_OBJECTS_H
 
32
 
 
33
#include "bdf.h"
 
34
#include "bdfdrivr.h"
 
35
 
 
36
#include "bdferror.h"
 
37
 
 
38
 
 
39
  /*************************************************************************/
 
40
  /*                                                                       */
 
41
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
 
42
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
 
43
  /* messages during execution.                                            */
 
44
  /*                                                                       */
 
45
#undef  FT_COMPONENT
 
46
#define FT_COMPONENT  trace_bdfdriver
 
47
 
 
48
 
 
49
  FT_CALLBACK_DEF( FT_Error )
 
50
  BDF_Face_Done( BDF_Face  face )
 
51
  {
 
52
    FT_Memory  memory = FT_FACE_MEMORY( face );
 
53
 
 
54
 
 
55
    bdf_free_font( face->bdffont );
 
56
 
 
57
    FT_FREE( face->en_table );
 
58
 
 
59
    FT_FREE( face->charset_encoding );
 
60
    FT_FREE( face->charset_registry );
 
61
    FT_FREE( face->root.family_name );
 
62
 
 
63
    FT_FREE( face->root.available_sizes );
 
64
 
 
65
    FT_FREE( face->bdffont );
 
66
 
 
67
    FT_TRACE4(( "BDF_Face_Done: done face\n" ));
 
68
 
 
69
    return BDF_Err_Ok;
 
70
  }
 
71
 
 
72
 
 
73
  FT_CALLBACK_DEF( FT_Error )
 
74
  BDF_Face_Init( FT_Stream      stream,
 
75
                 BDF_Face       face,
 
76
                 FT_Int         face_index,
 
77
                 FT_Int         num_params,
 
78
                 FT_Parameter*  params )
 
79
  {
 
80
    FT_Error       error  = BDF_Err_Ok;
 
81
    FT_Memory      memory = FT_FACE_MEMORY( face );
 
82
 
 
83
    bdf_font_t*    font;
 
84
    bdf_options_t  options;
 
85
 
 
86
    FT_UNUSED( num_params );
 
87
    FT_UNUSED( params );
 
88
    FT_UNUSED( face_index );
 
89
 
 
90
 
 
91
    if ( FT_STREAM_SEEK( 0 ) )
 
92
      goto Exit;
 
93
 
 
94
    options.correct_metrics = 1;   /* FZ XXX: options semantics */
 
95
    options.keep_unencoded  = 1;
 
96
    options.keep_comments   = 0;
 
97
    options.font_spacing    = BDF_PROPORTIONAL;
 
98
 
 
99
    error = bdf_load_font( stream, memory, &options, &font );
 
100
    if ( error == BDF_Err_Missing_Startfont_Field )
 
101
    {
 
102
      FT_TRACE2(( "[not a valid BDF file]\n" ));
 
103
      goto Fail;
 
104
    }
 
105
    else if ( error )
 
106
      goto Exit;
 
107
 
 
108
    /* we have a bdf font: let's construct the face object */
 
109
    face->bdffont = font;
 
110
    {
 
111
      FT_Face          root = FT_FACE( face );
 
112
      bdf_property_t*  prop = NULL;
 
113
 
 
114
 
 
115
      FT_TRACE4(( "number of glyphs: %d (%d)\n",
 
116
                  font->glyphs_size,
 
117
                  font->glyphs_used ));
 
118
      FT_TRACE4(( "number of unencoded glyphs: %d (%d)\n",
 
119
                  font->unencoded_size,
 
120
                  font->unencoded_used ));
 
121
 
 
122
      root->num_faces  = 1;
 
123
      root->face_index = 0;
 
124
      root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
 
125
                         FT_FACE_FLAG_HORIZONTAL  |
 
126
                         FT_FACE_FLAG_FAST_GLYPHS;
 
127
 
 
128
      prop = bdf_get_font_property( font, (char *)"SPACING" );
 
129
      if ( prop != NULL )
 
130
        if ( prop->format == BDF_ATOM )
 
131
          if ( prop->value.atom != NULL )
 
132
            if ( ( *(prop->value.atom) == 'M' ) ||
 
133
                 ( *(prop->value.atom) == 'C' ) )
 
134
              root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
 
135
 
 
136
      /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL   */
 
137
      /* FZ XXX: I need a font to implement this */
 
138
 
 
139
      root->style_flags = 0;
 
140
      prop = bdf_get_font_property( font, (char *)"SLANT" );
 
141
      if ( prop != NULL )
 
142
        if ( prop->format == BDF_ATOM )
 
143
          if ( prop->value.atom != NULL )
 
144
            if ( ( *(prop->value.atom) == 'O' ) ||
 
145
                 ( *(prop->value.atom) == 'I' ) )
 
146
              root->style_flags |= FT_STYLE_FLAG_ITALIC;
 
147
 
 
148
      prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" );
 
149
      if ( prop != NULL )
 
150
        if ( prop->format == BDF_ATOM )
 
151
          if ( prop->value.atom != NULL )
 
152
            if ( *(prop->value.atom) == 'B' )
 
153
              root->style_flags |= FT_STYLE_FLAG_BOLD;
 
154
 
 
155
      prop = bdf_get_font_property( font, (char *)"FAMILY_NAME" );
 
156
      if ( ( prop != NULL ) && ( prop->value.atom != NULL ) )
 
157
      {
 
158
        int  l = ft_strlen( prop->value.atom ) + 1;
 
159
 
 
160
 
 
161
        if ( FT_NEW_ARRAY( root->family_name, l ) )
 
162
          goto Exit;
 
163
        ft_strcpy( root->family_name, prop->value.atom );
 
164
      }
 
165
      else
 
166
        root->family_name = 0;
 
167
 
 
168
      root->style_name = (char *)"Regular";
 
169
      if ( root->style_flags & FT_STYLE_FLAG_BOLD )
 
170
      {
 
171
        if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
 
172
          root->style_name = (char *)"Bold Italic";
 
173
        else
 
174
          root->style_name = (char *)"Bold";
 
175
      }
 
176
      else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
 
177
        root->style_name = (char *)"Italic";
 
178
 
 
179
      root->num_glyphs = font->glyphs_size;     /* unencoded included */
 
180
 
 
181
      root->num_fixed_sizes = 1;
 
182
      if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
 
183
        goto Exit;
 
184
 
 
185
      prop = bdf_get_font_property( font, (char *)"PIXEL_SIZE" );
 
186
      if ( prop != NULL )
 
187
      {
 
188
        bdf_property_t  *xres = 0, *yres = 0;
 
189
 
 
190
 
 
191
        xres = bdf_get_font_property( font, (char *)"RESOLUTION_X" );
 
192
        yres = bdf_get_font_property( font, (char *)"RESOLUTION_Y" );
 
193
        if ( ( xres != NULL ) && ( yres != NULL ) )
 
194
        {
 
195
          FT_TRACE4(( "PIXEL_SIZE: %d  RESOLUTION_X: %d  RESOLUTION_Y: %d\n",
 
196
                      prop->value.int32,
 
197
                      xres->value.int32,
 
198
                      yres->value.int32 ));
 
199
          root->available_sizes->width =
 
200
            (FT_Short)( prop->value.int32 * 75 / xres->value.int32 );
 
201
             
 
202
          root->available_sizes->height =
 
203
            (FT_Short)( prop->value.int32 * 75 / yres->value.int32 );
 
204
        }
 
205
      }
 
206
      else
 
207
      {
 
208
        /* some fonts have broken SIZE declaration (jiskan24.bdf) */
 
209
        FT_ERROR(( "BDF_Face_Init: reading size\n" ));
 
210
        root->available_sizes->width  = (FT_Short)font->point_size ;
 
211
        root->available_sizes->height = (FT_Short)font->point_size ;
 
212
      }
 
213
 
 
214
      /* encoding table */
 
215
      {
 
216
        bdf_glyph_t*   cur = font->glyphs;
 
217
        unsigned long  n;
 
218
 
 
219
 
 
220
        if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) )
 
221
          goto Exit;
 
222
 
 
223
        for ( n = 0; n < font->glyphs_size; n++ )
 
224
        {
 
225
          (face->en_table[n]).enc = cur[n].encoding;
 
226
          FT_TRACE4(( "idx %d, val 0x%lX\n", n, cur[n].encoding ));
 
227
          (face->en_table[n]).glyph = (FT_Short)n;
 
228
        }
 
229
      }
 
230
 
 
231
      /* charmaps */
 
232
      {
 
233
        bdf_property_t  *charset_registry = 0, *charset_encoding = 0;
 
234
 
 
235
 
 
236
        charset_registry =
 
237
          bdf_get_font_property( font, (char *)"CHARSET_REGISTRY" );
 
238
        charset_encoding =
 
239
          bdf_get_font_property( font, (char *)"CHARSET_ENCODING" );
 
240
        if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) )
 
241
        {
 
242
          if ( ( charset_registry->format == BDF_ATOM ) &&
 
243
               ( charset_encoding->format == BDF_ATOM ) &&
 
244
               ( charset_registry->value.atom != NULL ) &&
 
245
               ( charset_encoding->value.atom != NULL ) )
 
246
          {
 
247
            if ( FT_NEW_ARRAY( face->charset_encoding,
 
248
                               strlen( charset_encoding->value.atom ) + 1 ) )
 
249
              goto Exit;
 
250
            if (FT_NEW_ARRAY( face->charset_registry,
 
251
                              strlen( charset_registry->value.atom ) + 1 ) )
 
252
              goto Exit;
 
253
            ft_strcpy( face->charset_registry, charset_registry->value.atom );
 
254
            ft_strcpy( face->charset_encoding, charset_encoding->value.atom );
 
255
 
 
256
            face->charmap.encoding    = ft_encoding_none;
 
257
            face->charmap.platform_id = 0;
 
258
            face->charmap.encoding_id = 0;
 
259
            face->charmap.face        = root;
 
260
            face->charmap_handle      = &face->charmap;
 
261
 
 
262
            root->charmap = face->charmap_handle;
 
263
 
 
264
            goto Exit;
 
265
          }
 
266
        }
 
267
 
 
268
        /* otherwise assume adobe standard encoding */
 
269
        face->charmap.encoding    = ft_encoding_adobe_standard;
 
270
        face->charmap.platform_id = 7; /* taken from t1objs.c */
 
271
        face->charmap.encoding_id = 0;
 
272
        face->charmap.face        = root;
 
273
        face->charmap_handle      = &face->charmap;
 
274
 
 
275
        root->charmap = face->charmap_handle;
 
276
      }
 
277
    }
 
278
 
 
279
  Exit:
 
280
    return error;
 
281
 
 
282
  Fail:
 
283
    BDF_Face_Done( face );
 
284
    return BDF_Err_Unknown_File_Format;
 
285
  }
 
286
 
 
287
 
 
288
  static
 
289
  FT_Error  BDF_Set_Pixel_Size( FT_Size  size )
 
290
  {
 
291
    BDF_Face  face = (BDF_Face)FT_SIZE_FACE( size );
 
292
    FT_Face   root = FT_FACE( face );
 
293
 
 
294
 
 
295
    FT_TRACE4(( "rec %d - pres %d\n",
 
296
                size->metrics.y_ppem, root->available_sizes->height ));
 
297
 
 
298
    if ( size->metrics.y_ppem == root->available_sizes->height )
 
299
    {
 
300
      size->metrics.ascender  = face->bdffont->bbx.ascent << 6;
 
301
      size->metrics.descender = face->bdffont->bbx.descent * ( -64 );
 
302
      size->metrics.height    = face->bdffont->bbx.height << 6;
 
303
 
 
304
      return BDF_Err_Ok;
 
305
    }
 
306
    else
 
307
      return BDF_Err_Invalid_Pixel_Size;
 
308
  }
 
309
 
 
310
 
 
311
  static FT_Error
 
312
  BDF_Glyph_Load( FT_GlyphSlot  slot,
 
313
                  FT_Size       size,
 
314
                  FT_UInt       glyph_index,
 
315
                  FT_Int        load_flags )
 
316
  {
 
317
    BDF_Face        face   = (BDF_Face)FT_SIZE_FACE( size );
 
318
    FT_Error        error  = BDF_Err_Ok;
 
319
    FT_Bitmap*      bitmap = &slot->bitmap;
 
320
    bdf_glyph_t     glyph;
 
321
    int             bpp    = face->bdffont->bpp;
 
322
    int             i, j, count;
 
323
    unsigned char   *p, *pp;
 
324
 
 
325
    FT_Memory       memory = face->bdffont->memory;
 
326
 
 
327
    FT_UNUSED( load_flags );
 
328
 
 
329
 
 
330
    if ( !face )
 
331
    {
 
332
      error = BDF_Err_Invalid_Argument;
 
333
      goto Exit;
 
334
    }
 
335
 
 
336
    /* slot, bitmap => freetype, glyph => bdflib */
 
337
    glyph = face->bdffont->glyphs[glyph_index];
 
338
 
 
339
    bitmap->rows      = glyph.bbx.height;
 
340
    bitmap->width     = glyph.bbx.width;
 
341
 
 
342
    if ( bpp == 1 )
 
343
    {
 
344
      bitmap->pixel_mode = ft_pixel_mode_mono;
 
345
      bitmap->pitch      = glyph.bpr;
 
346
 
 
347
      if ( FT_NEW_ARRAY( bitmap->buffer, glyph.bytes ) )
 
348
        goto Exit;
 
349
      FT_MEM_COPY( bitmap->buffer, glyph.bitmap, glyph.bytes );
 
350
    }
 
351
    else
 
352
    {
 
353
      /* blow up pixmap to have 8 bits per pixel */
 
354
      bitmap->pixel_mode = ft_pixel_mode_grays;
 
355
      bitmap->pitch      = bitmap->width;
 
356
 
 
357
      if ( FT_NEW_ARRAY( bitmap->buffer, bitmap->rows * bitmap->pitch ) )
 
358
        goto Exit;
 
359
 
 
360
      switch ( bpp )
 
361
      {
 
362
      case 2:
 
363
        bitmap->num_grays = 4;
 
364
 
 
365
        count = 0;
 
366
        p     = glyph.bitmap;
 
367
 
 
368
        for ( i = 0; i < bitmap->rows; i++ )
 
369
        {
 
370
          pp = p;
 
371
 
 
372
          /* get the full bytes */
 
373
          for ( j = 0; j < ( bitmap->width >> 2 ); j++ )
 
374
          {
 
375
            bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xC0 ) >> 6 );
 
376
            bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x30 ) >> 4 );
 
377
            bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x0C ) >> 2 );
 
378
            bitmap->buffer[count++] = (FT_Byte)(   *pp & 0x03 );
 
379
 
 
380
            pp++;
 
381
          }
 
382
 
 
383
          /* get remaining pixels (if any) */
 
384
          switch ( bitmap->width & 3 )
 
385
          {
 
386
          case 3:
 
387
            bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xC0 ) >> 6 );
 
388
            /* fall through */
 
389
          case 2:
 
390
            bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x30 ) >> 4 );
 
391
            /* fall through */
 
392
          case 1:
 
393
            bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x0C ) >> 2 );
 
394
            /* fall through */
 
395
          case 0:
 
396
            break;
 
397
          }
 
398
 
 
399
          p += glyph.bpr;
 
400
        }
 
401
        break;
 
402
 
 
403
      case 4:
 
404
        bitmap->num_grays = 16;
 
405
 
 
406
        count = 0;
 
407
        p     = glyph.bitmap;
 
408
 
 
409
        for ( i = 0; i < bitmap->rows; i++ )
 
410
        {
 
411
          pp = p;
 
412
 
 
413
          /* get the full bytes */
 
414
          for ( j = 0; j < ( bitmap->width >> 1 ); j++ )
 
415
          {
 
416
            bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xF0 ) >> 4 );
 
417
            bitmap->buffer[count++] = (FT_Byte)(   *pp & 0x0F );
 
418
 
 
419
            pp++;
 
420
          }
 
421
 
 
422
          /* get remaining pixel (if any) */
 
423
          switch ( bitmap->width & 1 )
 
424
          {
 
425
          case 1:
 
426
            bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xF0 ) >> 4 );
 
427
            /* fall through */
 
428
          case 0:
 
429
            break;
 
430
          }
 
431
 
 
432
          p += glyph.bpr;
 
433
        }
 
434
        break;
 
435
 
 
436
      case 8:
 
437
        bitmap->num_grays = 256;
 
438
 
 
439
        FT_MEM_COPY( bitmap->buffer, glyph.bitmap,
 
440
                     bitmap->rows * bitmap->pitch );
 
441
        break;
 
442
      }
 
443
    }
 
444
 
 
445
    slot->bitmap_left = 0;
 
446
    slot->bitmap_top  = glyph.bbx.ascent;
 
447
 
 
448
    /* FZ XXX: TODO: vertical metrics */
 
449
    slot->metrics.horiAdvance  = glyph.dwidth << 6;
 
450
    slot->metrics.horiBearingX = glyph.bbx.x_offset << 6;
 
451
    slot->metrics.horiBearingY = glyph.bbx.y_offset << 6;
 
452
    slot->metrics.width        = bitmap->width << 6;
 
453
    slot->metrics.height       = bitmap->rows << 6;
 
454
 
 
455
    slot->linearHoriAdvance = (FT_Fixed)glyph.dwidth << 16;
 
456
    slot->format            = ft_glyph_format_bitmap;
 
457
    slot->flags             = FT_GLYPH_OWN_BITMAP;
 
458
 
 
459
  Exit:
 
460
    return error;
 
461
  }
 
462
 
 
463
 
 
464
  static
 
465
  FT_UInt  BDF_Get_Char_Index( FT_CharMap  charmap,
 
466
                               FT_ULong    char_code )
 
467
  {
 
468
    BDF_Face          face     = (BDF_Face)charmap->face;
 
469
    BDF_encoding_el*  en_table = face->en_table;
 
470
    int               low, high, mid;
 
471
 
 
472
 
 
473
    FT_TRACE4(( "BDF_Get_Char_Index %ld\n", char_code ));
 
474
 
 
475
    low  = 0;
 
476
    high = face->bdffont->glyphs_used - 1;
 
477
 
 
478
    while ( low <= high )
 
479
    {
 
480
      mid = ( low + high ) / 2;
 
481
      if ( char_code < en_table[mid].enc )
 
482
        high = mid - 1;
 
483
      else if ( char_code > en_table[mid].enc )
 
484
        low = mid + 1;
 
485
      else
 
486
        return en_table[mid].glyph;
 
487
    }
 
488
 
 
489
    return face->bdffont->default_glyph;
 
490
  }
 
491
 
 
492
 
 
493
  FT_CALLBACK_TABLE_DEF
 
494
  const FT_Driver_ClassRec  bdf_driver_class =
 
495
  {
 
496
    {
 
497
      ft_module_font_driver,
 
498
      sizeof ( FT_DriverRec ),
 
499
 
 
500
      "bdf",
 
501
      0x10000L,
 
502
      0x20000L,
 
503
 
 
504
      0,
 
505
 
 
506
      (FT_Module_Constructor)0,
 
507
      (FT_Module_Destructor) 0,
 
508
      (FT_Module_Requester)  0
 
509
    },
 
510
 
 
511
    sizeof( BDF_FaceRec ),
 
512
    sizeof( FT_SizeRec ),
 
513
    sizeof( FT_GlyphSlotRec ),
 
514
 
 
515
    (FT_Face_InitFunc)        BDF_Face_Init,
 
516
    (FT_Face_DoneFunc)        BDF_Face_Done,
 
517
    (FT_Size_InitFunc)        0,
 
518
    (FT_Size_DoneFunc)        0,
 
519
    (FT_Slot_InitFunc)        0,
 
520
    (FT_Slot_DoneFunc)        0,
 
521
 
 
522
    (FT_Size_ResetPointsFunc) BDF_Set_Pixel_Size,
 
523
    (FT_Size_ResetPixelsFunc) BDF_Set_Pixel_Size,
 
524
 
 
525
    (FT_Slot_LoadFunc)        BDF_Glyph_Load,
 
526
 
 
527
#ifndef FT_CONFIG_OPTION_USE_CMAPS
 
528
    (FT_CharMap_CharIndexFunc)0,
 
529
#else
 
530
    (FT_CharMap_CharIndexFunc)BDF_Get_Char_Index,
 
531
#endif
 
532
 
 
533
    (FT_Face_GetKerningFunc)  0,
 
534
    (FT_Face_AttachFunc)      0,
 
535
    (FT_Face_GetAdvancesFunc) 0,
 
536
 
 
537
#ifndef FT_CONFIG_OPTION_USE_CMAPS
 
538
    (FT_CharMap_CharNextFunc) 0, /* BDF_Char_Get_Next,*/
 
539
#else
 
540
    (FT_CharMap_CharNextFunc) 0
 
541
#endif
 
542
  };
 
543
 
 
544
 
 
545
/* END */