source: trunk/poppler/freetype2/src/base/ftbitmap.c @ 262

Last change on this file since 262 was 262, checked in by Eugene Romanenko, 12 years ago

PDF plugin: freetype library updated to version 2.3.8

File size: 15.5 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  ftbitmap.c                                                             */
4/*                                                                         */
5/*    FreeType utility functions for bitmaps (body).                       */
6/*                                                                         */
7/*  Copyright 2004, 2005, 2006, 2007, 2008, 2009 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_BITMAP_H
21#include FT_IMAGE_H
22#include FT_INTERNAL_OBJECTS_H
23
24
25  static
26  const FT_Bitmap  null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
27
28
29  /* documentation is in ftbitmap.h */
30
31  FT_EXPORT_DEF( void )
32  FT_Bitmap_New( FT_Bitmap  *abitmap )
33  {
34    *abitmap = null_bitmap;
35  }
36
37
38  /* documentation is in ftbitmap.h */
39
40  FT_EXPORT_DEF( FT_Error )
41  FT_Bitmap_Copy( FT_Library        library,
42                  const FT_Bitmap  *source,
43                  FT_Bitmap        *target)
44  {
45    FT_Memory  memory = library->memory;
46    FT_Error   error  = FT_Err_Ok;
47    FT_Int     pitch  = source->pitch;
48    FT_ULong   size;
49
50
51    if ( source == target )
52      return FT_Err_Ok;
53
54    if ( source->buffer == NULL )
55    {
56      *target = *source;
57
58      return FT_Err_Ok;
59    }
60
61    if ( pitch < 0 )
62      pitch = -pitch;
63    size = (FT_ULong)( pitch * source->rows );
64
65    if ( target->buffer )
66    {
67      FT_Int    target_pitch = target->pitch;
68      FT_ULong  target_size;
69
70
71      if ( target_pitch < 0  )
72        target_pitch = -target_pitch;
73      target_size = (FT_ULong)( target_pitch * target->rows );
74
75      if ( target_size != size )
76        (void)FT_QREALLOC( target->buffer, target_size, size );
77    }
78    else
79      (void)FT_QALLOC( target->buffer, size );
80
81    if ( !error )
82    {
83      unsigned char *p;
84
85
86      p = target->buffer;
87      *target = *source;
88      target->buffer = p;
89
90      FT_MEM_COPY( target->buffer, source->buffer, size );
91    }
92
93    return error;
94  }
95
96
97  static FT_Error
98  ft_bitmap_assure_buffer( FT_Memory   memory,
99                           FT_Bitmap*  bitmap,
100                           FT_UInt     xpixels,
101                           FT_UInt     ypixels )
102  {
103    FT_Error        error;
104    int             pitch;
105    int             new_pitch;
106    FT_UInt         bpp;
107    FT_Int          i, width, height;
108    unsigned char*  buffer;
109
110
111    width  = bitmap->width;
112    height = bitmap->rows;
113    pitch  = bitmap->pitch;
114    if ( pitch < 0 )
115      pitch = -pitch;
116
117    switch ( bitmap->pixel_mode )
118    {
119    case FT_PIXEL_MODE_MONO:
120      bpp       = 1;
121      new_pitch = ( width + xpixels + 7 ) >> 3;
122      break;
123    case FT_PIXEL_MODE_GRAY2:
124      bpp       = 2;
125      new_pitch = ( width + xpixels + 3 ) >> 2;
126      break;
127    case FT_PIXEL_MODE_GRAY4:
128      bpp       = 4;
129      new_pitch = ( width + xpixels + 1 ) >> 1;
130      break;
131    case FT_PIXEL_MODE_GRAY:
132    case FT_PIXEL_MODE_LCD:
133    case FT_PIXEL_MODE_LCD_V:
134      bpp       = 8;
135      new_pitch = ( width + xpixels );
136      break;
137    default:
138      return FT_Err_Invalid_Glyph_Format;
139    }
140
141    /* if no need to allocate memory */
142    if ( ypixels == 0 && new_pitch <= pitch )
143    {
144      /* zero the padding */
145      FT_Int  bit_width = pitch * 8;
146      FT_Int  bit_last  = ( width + xpixels ) * bpp;
147
148
149      if ( bit_last < bit_width )
150      {
151        FT_Byte*  line  = bitmap->buffer + ( bit_last >> 3 );
152        FT_Byte*  end   = bitmap->buffer + pitch;
153        FT_Int    shift = bit_last & 7;
154        FT_UInt   mask  = 0xFF00U >> shift;
155        FT_Int    count = height;
156
157
158        for ( ; count > 0; count--, line += pitch, end += pitch )
159        {
160          FT_Byte*  write = line;
161
162
163          if ( shift > 0 )
164          {
165            write[0] = (FT_Byte)( write[0] & mask );
166            write++;
167          }
168          if ( write < end )
169            FT_MEM_ZERO( write, end-write );
170        }
171      }
172
173      return FT_Err_Ok;
174    }
175
176    if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
177      return error;
178
179    if ( bitmap->pitch > 0 )
180    {
181      FT_Int  len = ( width * bpp + 7 ) >> 3;
182
183
184      for ( i = 0; i < bitmap->rows; i++ )
185        FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
186                     bitmap->buffer + pitch * i, len );
187    }
188    else
189    {
190      FT_Int  len = ( width * bpp + 7 ) >> 3;
191
192
193      for ( i = 0; i < bitmap->rows; i++ )
194        FT_MEM_COPY( buffer + new_pitch * i,
195                     bitmap->buffer + pitch * i, len );
196    }
197
198    FT_FREE( bitmap->buffer );
199    bitmap->buffer = buffer;
200
201    if ( bitmap->pitch < 0 )
202      new_pitch = -new_pitch;
203
204    /* set pitch only, width and height are left untouched */
205    bitmap->pitch = new_pitch;
206
207    return FT_Err_Ok;
208  }
209
210
211  /* documentation is in ftbitmap.h */
212
213  FT_EXPORT_DEF( FT_Error )
214  FT_Bitmap_Embolden( FT_Library  library,
215                      FT_Bitmap*  bitmap,
216                      FT_Pos      xStrength,
217                      FT_Pos      yStrength )
218  {
219    FT_Error        error;
220    unsigned char*  p;
221    FT_Int          i, x, y, pitch;
222    FT_Int          xstr, ystr;
223
224
225    if ( !library )
226      return FT_Err_Invalid_Library_Handle;
227
228    if ( !bitmap || !bitmap->buffer )
229      return FT_Err_Invalid_Argument;
230
231    xstr = FT_PIX_ROUND( xStrength ) >> 6;
232    ystr = FT_PIX_ROUND( yStrength ) >> 6;
233
234    if ( xstr == 0 && ystr == 0 )
235      return FT_Err_Ok;
236    else if ( xstr < 0 || ystr < 0 )
237      return FT_Err_Invalid_Argument;
238
239    switch ( bitmap->pixel_mode )
240    {
241    case FT_PIXEL_MODE_GRAY2:
242    case FT_PIXEL_MODE_GRAY4:
243      {
244        FT_Bitmap  tmp;
245        FT_Int     align;
246
247
248        if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
249          align = ( bitmap->width + xstr + 3 ) / 4;
250        else
251          align = ( bitmap->width + xstr + 1 ) / 2;
252
253        FT_Bitmap_New( &tmp );
254
255        error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
256        if ( error )
257          return error;
258
259        FT_Bitmap_Done( library, bitmap );
260        *bitmap = tmp;
261      }
262      break;
263
264    case FT_PIXEL_MODE_MONO:
265      if ( xstr > 8 )
266        xstr = 8;
267      break;
268
269    case FT_PIXEL_MODE_LCD:
270      xstr *= 3;
271      break;
272
273    case FT_PIXEL_MODE_LCD_V:
274      ystr *= 3;
275      break;
276    }
277
278    error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
279    if ( error )
280      return error;
281
282    pitch = bitmap->pitch;
283    if ( pitch > 0 )
284      p = bitmap->buffer + pitch * ystr;
285    else
286    {
287      pitch = -pitch;
288      p = bitmap->buffer + pitch * ( bitmap->rows - 1 );
289    }
290
291    /* for each row */
292    for ( y = 0; y < bitmap->rows ; y++ )
293    {
294      /*
295       * Horizontally:
296       *
297       * From the last pixel on, make each pixel or'ed with the
298       * `xstr' pixels before it.
299       */
300      for ( x = pitch - 1; x >= 0; x-- )
301      {
302        unsigned char tmp;
303
304
305        tmp = p[x];
306        for ( i = 1; i <= xstr; i++ )
307        {
308          if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
309          {
310            p[x] |= tmp >> i;
311
312            /* the maximum value of 8 for `xstr' comes from here */
313            if ( x > 0 )
314              p[x] |= p[x - 1] << ( 8 - i );
315
316#if 0
317            if ( p[x] == 0xff )
318              break;
319#endif
320          }
321          else
322          {
323            if ( x - i >= 0 )
324            {
325              if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
326              {
327                p[x] = (unsigned char)(bitmap->num_grays - 1);
328                break;
329              }
330              else
331              {
332                p[x] = (unsigned char)(p[x] + p[x-i]);
333                if ( p[x] == bitmap->num_grays - 1 )
334                  break;
335              }
336            }
337            else
338              break;
339          }
340        }
341      }
342
343      /*
344       * Vertically:
345       *
346       * Make the above `ystr' rows or'ed with it.
347       */
348      for ( x = 1; x <= ystr; x++ )
349      {
350        unsigned char*  q;
351
352
353        q = p - bitmap->pitch * x;
354        for ( i = 0; i < pitch; i++ )
355          q[i] |= p[i];
356      }
357
358      p += bitmap->pitch;
359    }
360
361    bitmap->width += xstr;
362    bitmap->rows += ystr;
363
364    return FT_Err_Ok;
365  }
366
367
368  /* documentation is in ftbitmap.h */
369
370  FT_EXPORT_DEF( FT_Error )
371  FT_Bitmap_Convert( FT_Library        library,
372                     const FT_Bitmap  *source,
373                     FT_Bitmap        *target,
374                     FT_Int            alignment )
375  {
376    FT_Error   error = FT_Err_Ok;
377    FT_Memory  memory;
378
379
380    if ( !library )
381      return FT_Err_Invalid_Library_Handle;
382
383    memory = library->memory;
384
385    switch ( source->pixel_mode )
386    {
387    case FT_PIXEL_MODE_MONO:
388    case FT_PIXEL_MODE_GRAY:
389    case FT_PIXEL_MODE_GRAY2:
390    case FT_PIXEL_MODE_GRAY4:
391    case FT_PIXEL_MODE_LCD:
392    case FT_PIXEL_MODE_LCD_V:
393      {
394        FT_Int   pad;
395        FT_Long  old_size;
396
397
398        old_size = target->rows * target->pitch;
399        if ( old_size < 0 )
400          old_size = -old_size;
401
402        target->pixel_mode = FT_PIXEL_MODE_GRAY;
403        target->rows       = source->rows;
404        target->width      = source->width;
405
406        pad = 0;
407        if ( alignment > 0 )
408        {
409          pad = source->width % alignment;
410          if ( pad != 0 )
411            pad = alignment - pad;
412        }
413
414        target->pitch = source->width + pad;
415
416        if ( target->rows * target->pitch > old_size             &&
417             FT_QREALLOC( target->buffer,
418                          old_size, target->rows * target->pitch ) )
419          return error;
420      }
421      break;
422
423    default:
424      error = FT_Err_Invalid_Argument;
425    }
426
427    switch ( source->pixel_mode )
428    {
429    case FT_PIXEL_MODE_MONO:
430      {
431        FT_Byte*  s = source->buffer;
432        FT_Byte*  t = target->buffer;
433        FT_Int    i;
434
435
436        target->num_grays = 2;
437
438        for ( i = source->rows; i > 0; i-- )
439        {
440          FT_Byte*  ss = s;
441          FT_Byte*  tt = t;
442          FT_Int    j;
443
444
445          /* get the full bytes */
446          for ( j = source->width >> 3; j > 0; j-- )
447          {
448            FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */
449
450
451            tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
452            tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
453            tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
454            tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
455            tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
456            tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
457            tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
458            tt[7] = (FT_Byte)(   val & 0x01 );
459
460            tt += 8;
461            ss += 1;
462          }
463
464          /* get remaining pixels (if any) */
465          j = source->width & 7;
466          if ( j > 0 )
467          {
468            FT_Int  val = *ss;
469
470
471            for ( ; j > 0; j-- )
472            {
473              tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
474              val <<= 1;
475              tt   += 1;
476            }
477          }
478
479          s += source->pitch;
480          t += target->pitch;
481        }
482      }
483      break;
484
485
486    case FT_PIXEL_MODE_GRAY:
487    case FT_PIXEL_MODE_LCD:
488    case FT_PIXEL_MODE_LCD_V:
489      {
490        FT_Int    width   = source->width;
491        FT_Byte*  s       = source->buffer;
492        FT_Byte*  t       = target->buffer;
493        FT_Int    s_pitch = source->pitch;
494        FT_Int    t_pitch = target->pitch;
495        FT_Int    i;
496
497
498        target->num_grays = 256;
499
500        for ( i = source->rows; i > 0; i-- )
501        {
502          FT_ARRAY_COPY( t, s, width );
503
504          s += s_pitch;
505          t += t_pitch;
506        }
507      }
508      break;
509
510
511    case FT_PIXEL_MODE_GRAY2:
512      {
513        FT_Byte*  s = source->buffer;
514        FT_Byte*  t = target->buffer;
515        FT_Int    i;
516
517
518        target->num_grays = 4;
519
520        for ( i = source->rows; i > 0; i-- )
521        {
522          FT_Byte*  ss = s;
523          FT_Byte*  tt = t;
524          FT_Int    j;
525
526
527          /* get the full bytes */
528          for ( j = source->width >> 2; j > 0; j-- )
529          {
530            FT_Int  val = ss[0];
531
532
533            tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
534            tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
535            tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
536            tt[3] = (FT_Byte)( ( val & 0x03 ) );
537
538            ss += 1;
539            tt += 4;
540          }
541
542          j = source->width & 3;
543          if ( j > 0 )
544          {
545            FT_Int  val = ss[0];
546
547
548            for ( ; j > 0; j-- )
549            {
550              tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );
551              val  <<= 2;
552              tt    += 1;
553            }
554          }
555
556          s += source->pitch;
557          t += target->pitch;
558        }
559      }
560      break;
561
562
563    case FT_PIXEL_MODE_GRAY4:
564      {
565        FT_Byte*  s = source->buffer;
566        FT_Byte*  t = target->buffer;
567        FT_Int    i;
568
569
570        target->num_grays = 16;
571
572        for ( i = source->rows; i > 0; i-- )
573        {
574          FT_Byte*  ss = s;
575          FT_Byte*  tt = t;
576          FT_Int    j;
577
578
579          /* get the full bytes */
580          for ( j = source->width >> 1; j > 0; j-- )
581          {
582            FT_Int  val = ss[0];
583
584
585            tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
586            tt[1] = (FT_Byte)( ( val & 0x0F ) );
587
588            ss += 1;
589            tt += 2;
590          }
591
592          if ( source->width & 1 )
593            tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
594
595          s += source->pitch;
596          t += target->pitch;
597        }
598      }
599      break;
600
601
602    default:
603      ;
604    }
605
606    return error;
607  }
608
609
610  /* documentation is in ftbitmap.h */
611
612  FT_EXPORT_DEF( FT_Error )
613  FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot )
614  {
615    if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP   &&
616         !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
617    {
618      FT_Bitmap  bitmap;
619      FT_Error   error;
620
621
622      FT_Bitmap_New( &bitmap );
623      error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
624      if ( error )
625        return error;
626
627      slot->bitmap = bitmap;
628      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
629    }
630
631    return FT_Err_Ok;
632  }
633
634
635  /* documentation is in ftbitmap.h */
636
637  FT_EXPORT_DEF( FT_Error )
638  FT_Bitmap_Done( FT_Library  library,
639                  FT_Bitmap  *bitmap )
640  {
641    FT_Memory  memory;
642
643
644    if ( !library )
645      return FT_Err_Invalid_Library_Handle;
646
647    if ( !bitmap )
648      return FT_Err_Invalid_Argument;
649
650    memory = library->memory;
651
652    FT_FREE( bitmap->buffer );
653    *bitmap = null_bitmap;
654
655    return FT_Err_Ok;
656  }
657
658
659/* END */
Note: See TracBrowser for help on using the repository browser.