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

Last change on this file since 182 was 182, checked in by Eugene Romanenko, 15 years ago

freetype update to version 2.3.0

File size: 14.5 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  ftbitmap.c                                                             */
4/*                                                                         */
5/*    FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
6/*    bitmaps into 8bpp format (body).                                     */
7/*                                                                         */
8/*  Copyright 2004, 2005, 2006, 2007 by                                    */
9/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
10/*                                                                         */
11/*  This file is part of the FreeType project, and may only be used,       */
12/*  modified, and distributed under the terms of the FreeType project      */
13/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
14/*  this file you indicate that you have read the license and              */
15/*  understand and accept it fully.                                        */
16/*                                                                         */
17/***************************************************************************/
18
19
20#include <ft2build.h>
21#include FT_BITMAP_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         ppb;
107    FT_Int          i, width;
108    unsigned char*  buffer;
109
110
111    width = bitmap->width;
112    pitch = bitmap->pitch;
113    if ( pitch < 0 )
114      pitch = -pitch;
115
116    switch ( bitmap->pixel_mode )
117    {
118    case FT_PIXEL_MODE_MONO:
119      ppb = 8;
120      break;
121    case FT_PIXEL_MODE_GRAY2:
122      ppb = 4;
123      break;
124    case FT_PIXEL_MODE_GRAY4:
125      ppb = 2;
126      break;
127    case FT_PIXEL_MODE_GRAY:
128    case FT_PIXEL_MODE_LCD:
129    case FT_PIXEL_MODE_LCD_V:
130      ppb = 1;
131      break;
132    default:
133      return FT_Err_Invalid_Glyph_Format;
134    }
135
136    /* if no need to allocate memory */
137    if ( ypixels == 0 && pitch * ppb >= bitmap->width + xpixels )
138    {
139      /* zero the padding */
140      for ( i = 0; i < bitmap->rows; i++ )
141      {
142        unsigned char*  last_byte;
143        int             bits = xpixels * ( 8 / ppb );
144        int             mask = 0;
145
146
147        last_byte = bitmap->buffer + i * pitch + ( bitmap->width - 1 ) / ppb;
148
149        if ( bits >= 8 )
150        {
151          FT_MEM_ZERO( last_byte + 1, bits / 8 );
152          bits %= 8;
153        }
154
155        if ( bits > 0 )
156        {
157          while ( bits-- > 0 )
158            mask |= 1 << bits;
159
160          *last_byte &= ~mask;
161        }
162      }
163
164      return FT_Err_Ok;
165    }
166
167    new_pitch = ( bitmap->width + xpixels + ppb - 1 ) / ppb;
168
169    if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
170      return error;
171
172    if ( bitmap->pitch > 0 )
173    {
174      FT_Int  len = ( width + ppb - 1 ) / ppb;
175
176
177      for ( i = 0; i < bitmap->rows; i++ )
178        FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
179                     bitmap->buffer + pitch * i, len );
180    }
181    else
182    {
183      FT_Int  len = ( width + ppb - 1 ) / ppb;
184
185
186      for ( i = 0; i < bitmap->rows; i++ )
187        FT_MEM_COPY( buffer + new_pitch * i,
188                     bitmap->buffer + pitch * i, len );
189    }
190
191    FT_FREE( bitmap->buffer );
192    bitmap->buffer = buffer;
193
194    if ( bitmap->pitch < 0 )
195      new_pitch = -new_pitch;
196
197    /* set pitch only */
198    bitmap->pitch = new_pitch;
199
200    return FT_Err_Ok;
201  }
202
203
204  /* documentation is in ftbitmap.h */
205
206  FT_EXPORT_DEF( FT_Error )
207  FT_Bitmap_Embolden( FT_Library  library,
208                      FT_Bitmap*  bitmap,
209                      FT_Pos      xStrength,
210                      FT_Pos      yStrength )
211  {
212    FT_Error        error;
213    unsigned char*  p;
214    FT_Int          i, x, y, pitch;
215    FT_Int          xstr, ystr;
216
217
218    if ( !library )
219      return FT_Err_Invalid_Library_Handle;
220
221    if ( !bitmap || !bitmap->buffer )
222      return FT_Err_Invalid_Argument;
223
224    xstr = FT_PIX_ROUND( xStrength ) >> 6;
225    ystr = FT_PIX_ROUND( yStrength ) >> 6;
226
227    if ( xstr == 0 && ystr == 0 )
228      return FT_Err_Ok;
229    else if ( xstr < 0 || ystr < 0 )
230      return FT_Err_Invalid_Argument;
231
232    switch ( bitmap->pixel_mode )
233    {
234    case FT_PIXEL_MODE_GRAY2:
235    case FT_PIXEL_MODE_GRAY4:
236      {
237        FT_Bitmap  tmp;
238        FT_Int     align;
239
240
241        if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
242          align = ( bitmap->width + xstr + 3 ) / 4;
243        else
244          align = ( bitmap->width + xstr + 1 ) / 2;
245
246        FT_Bitmap_New( &tmp );
247        error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
248
249        if ( error )
250          return error;
251
252        FT_Bitmap_Done( library, bitmap );
253        *bitmap = tmp;
254      }
255      break;
256
257    case FT_PIXEL_MODE_MONO:
258      if ( xstr > 8 )
259        xstr = 8;
260      break;
261
262    case FT_PIXEL_MODE_LCD:
263      xstr *= 3;
264      break;
265
266    case FT_PIXEL_MODE_LCD_V:
267      ystr *= 3;
268      break;
269    }
270
271    error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
272    if ( error )
273      return error;
274
275    pitch = bitmap->pitch;
276    if ( pitch > 0 )
277      p = bitmap->buffer + pitch * ystr;
278    else
279    {
280      pitch = -pitch;
281      p = bitmap->buffer + pitch * ( bitmap->rows - 1 );
282    }
283
284    /* for each row */
285    for ( y = 0; y < bitmap->rows ; y++ )
286    {
287      /*
288       * Horizontally:
289       *
290       * From the last pixel on, make each pixel or'ed with the
291       * `xstr' pixels before it.
292       */
293      for ( x = pitch - 1; x >= 0; x-- )
294      {
295        unsigned char tmp;
296
297
298        tmp = p[x];
299        for ( i = 1; i <= xstr; i++ )
300        {
301          if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
302          {
303            p[x] |= tmp >> i;
304
305            /* the maximum value of 8 for `xstr' comes from here */
306            if ( x > 0 )
307              p[x] |= p[x - 1] << ( 8 - i );
308
309#if 0
310            if ( p[x] == 0xff )
311              break;
312#endif
313          }
314          else
315          {
316            if ( x - i >= 0 )
317            {
318              if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
319              {
320                p[x] = (unsigned char)(bitmap->num_grays - 1);
321                break;
322              }
323              else
324              {
325                p[x] = (unsigned char)(p[x] + p[x-i]);
326                if ( p[x] == bitmap->num_grays - 1 )
327                  break;
328              }
329            }
330            else
331              break;
332          }
333        }
334      }
335
336      /*
337       * Vertically:
338       *
339       * Make the above `ystr' rows or'ed with it.
340       */
341      for ( x = 1; x <= ystr; x++ )
342      {
343        unsigned char*  q;
344
345
346        q = p - bitmap->pitch * x;
347        for ( i = 0; i < pitch; i++ )
348          q[i] |= p[i];
349      }
350
351      p += bitmap->pitch;
352    }
353
354    bitmap->width += xstr;
355    bitmap->rows += ystr;
356
357    return FT_Err_Ok;
358  }
359
360
361  /* documentation is in ftbitmap.h */
362
363  FT_EXPORT_DEF( FT_Error )
364  FT_Bitmap_Convert( FT_Library        library,
365                     const FT_Bitmap  *source,
366                     FT_Bitmap        *target,
367                     FT_Int            alignment )
368  {
369    FT_Error   error = FT_Err_Ok;
370    FT_Memory  memory;
371
372
373    if ( !library )
374      return FT_Err_Invalid_Library_Handle;
375
376    memory = library->memory;
377
378    switch ( source->pixel_mode )
379    {
380    case FT_PIXEL_MODE_MONO:
381    case FT_PIXEL_MODE_GRAY:
382    case FT_PIXEL_MODE_GRAY2:
383    case FT_PIXEL_MODE_GRAY4:
384      {
385        FT_Int   pad;
386        FT_Long  old_size;
387
388
389        old_size = target->rows * target->pitch;
390        if ( old_size < 0 )
391          old_size = -old_size;
392
393        target->pixel_mode = FT_PIXEL_MODE_GRAY;
394        target->rows       = source->rows;
395        target->width      = source->width;
396
397        pad = 0;
398        if ( alignment > 0 )
399        {
400          pad = source->width % alignment;
401          if ( pad != 0 )
402            pad = alignment - pad;
403        }
404
405        target->pitch = source->width + pad;
406
407        if ( target->rows * target->pitch > old_size             &&
408             FT_QREALLOC( target->buffer,
409                          old_size, target->rows * target->pitch ) )
410          return error;
411      }
412      break;
413
414    default:
415      error = FT_Err_Invalid_Argument;
416    }
417
418    switch ( source->pixel_mode )
419    {
420    case FT_PIXEL_MODE_MONO:
421      {
422        FT_Byte*  s = source->buffer;
423        FT_Byte*  t = target->buffer;
424        FT_Int    i;
425
426
427        target->num_grays = 2;
428
429        for ( i = source->rows; i > 0; i-- )
430        {
431          FT_Byte*  ss = s;
432          FT_Byte*  tt = t;
433          FT_Int    j;
434
435
436          /* get the full bytes */
437          for ( j = source->width >> 3; j > 0; j-- )
438          {
439            FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */
440
441
442            tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
443            tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
444            tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
445            tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
446            tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
447            tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
448            tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
449            tt[7] = (FT_Byte)(   val & 0x01 );
450
451            tt += 8;
452            ss += 1;
453          }
454
455          /* get remaining pixels (if any) */
456          j = source->width & 7;
457          if ( j > 0 )
458          {
459            FT_Int  val = *ss;
460
461
462            for ( ; j > 0; j-- )
463            {
464              tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
465              val <<= 1;
466              tt   += 1;
467            }
468          }
469
470          s += source->pitch;
471          t += target->pitch;
472        }
473      }
474      break;
475
476
477    case FT_PIXEL_MODE_GRAY:
478      {
479        FT_Int    width   = source->width;
480        FT_Byte*  s       = source->buffer;
481        FT_Byte*  t       = target->buffer;
482        FT_Int    s_pitch = source->pitch;
483        FT_Int    t_pitch = target->pitch;
484        FT_Int    i;
485
486
487        target->num_grays = 256;
488
489        for ( i = source->rows; i > 0; i-- )
490        {
491          FT_ARRAY_COPY( t, s, width );
492
493          s += s_pitch;
494          t += t_pitch;
495        }
496      }
497      break;
498
499
500    case FT_PIXEL_MODE_GRAY2:
501      {
502        FT_Byte*  s = source->buffer;
503        FT_Byte*  t = target->buffer;
504        FT_Int    i;
505
506
507        target->num_grays = 4;
508
509        for ( i = source->rows; i > 0; i-- )
510        {
511          FT_Byte*  ss = s;
512          FT_Byte*  tt = t;
513          FT_Int    j;
514
515
516          /* get the full bytes */
517          for ( j = source->width >> 2; j > 0; j-- )
518          {
519            FT_Int  val = ss[0];
520
521
522            tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
523            tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
524            tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
525            tt[3] = (FT_Byte)( ( val & 0x03 ) );
526
527            ss += 1;
528            tt += 4;
529          }
530
531          j = source->width & 3;
532          if ( j > 0 )
533          {
534            FT_Int  val = ss[0];
535
536
537            for ( ; j > 0; j-- )
538            {
539              tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );
540              val  <<= 2;
541              tt    += 1;
542            }
543          }
544
545          s += source->pitch;
546          t += target->pitch;
547        }
548      }
549      break;
550
551
552    case FT_PIXEL_MODE_GRAY4:
553      {
554        FT_Byte*  s = source->buffer;
555        FT_Byte*  t = target->buffer;
556        FT_Int    i;
557
558
559        target->num_grays = 16;
560
561        for ( i = source->rows; i > 0; i-- )
562        {
563          FT_Byte*  ss = s;
564          FT_Byte*  tt = t;
565          FT_Int    j;
566
567
568          /* get the full bytes */
569          for ( j = source->width >> 1; j > 0; j-- )
570          {
571            FT_Int  val = ss[0];
572
573
574            tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
575            tt[1] = (FT_Byte)( ( val & 0x0F ) );
576
577            ss += 1;
578            tt += 2;
579          }
580
581          if ( source->width & 1 )
582            tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
583
584          s += source->pitch;
585          t += target->pitch;
586        }
587      }
588      break;
589
590
591    default:
592      ;
593    }
594
595    return error;
596  }
597
598
599  /* documentation is in ftbitmap.h */
600
601  FT_EXPORT_DEF( FT_Error )
602  FT_Bitmap_Done( FT_Library  library,
603                  FT_Bitmap  *bitmap )
604  {
605    FT_Memory  memory;
606
607
608    if ( !library )
609      return FT_Err_Invalid_Library_Handle;
610
611    if ( !bitmap )
612      return FT_Err_Invalid_Argument;
613
614    memory = library->memory;
615
616    FT_FREE( bitmap->buffer );
617    *bitmap = null_bitmap;
618
619    return FT_Err_Ok;
620  }
621
622
623/* END */
Note: See TracBrowser for help on using the repository browser.