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

Last change on this file since 251 was 251, checked in by Eugene Romanenko, 13 years ago

PDF plugin: freetype library updated to version 2.3.5

File size: 14.9 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         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      {
392        FT_Int   pad;
393        FT_Long  old_size;
394
395
396        old_size = target->rows * target->pitch;
397        if ( old_size < 0 )
398          old_size = -old_size;
399
400        target->pixel_mode = FT_PIXEL_MODE_GRAY;
401        target->rows       = source->rows;
402        target->width      = source->width;
403
404        pad = 0;
405        if ( alignment > 0 )
406        {
407          pad = source->width % alignment;
408          if ( pad != 0 )
409            pad = alignment - pad;
410        }
411
412        target->pitch = source->width + pad;
413
414        if ( target->rows * target->pitch > old_size             &&
415             FT_QREALLOC( target->buffer,
416                          old_size, target->rows * target->pitch ) )
417          return error;
418      }
419      break;
420
421    default:
422      error = FT_Err_Invalid_Argument;
423    }
424
425    switch ( source->pixel_mode )
426    {
427    case FT_PIXEL_MODE_MONO:
428      {
429        FT_Byte*  s = source->buffer;
430        FT_Byte*  t = target->buffer;
431        FT_Int    i;
432
433
434        target->num_grays = 2;
435
436        for ( i = source->rows; i > 0; i-- )
437        {
438          FT_Byte*  ss = s;
439          FT_Byte*  tt = t;
440          FT_Int    j;
441
442
443          /* get the full bytes */
444          for ( j = source->width >> 3; j > 0; j-- )
445          {
446            FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */
447
448
449            tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
450            tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
451            tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
452            tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
453            tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
454            tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
455            tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
456            tt[7] = (FT_Byte)(   val & 0x01 );
457
458            tt += 8;
459            ss += 1;
460          }
461
462          /* get remaining pixels (if any) */
463          j = source->width & 7;
464          if ( j > 0 )
465          {
466            FT_Int  val = *ss;
467
468
469            for ( ; j > 0; j-- )
470            {
471              tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
472              val <<= 1;
473              tt   += 1;
474            }
475          }
476
477          s += source->pitch;
478          t += target->pitch;
479        }
480      }
481      break;
482
483
484    case FT_PIXEL_MODE_GRAY:
485      {
486        FT_Int    width   = source->width;
487        FT_Byte*  s       = source->buffer;
488        FT_Byte*  t       = target->buffer;
489        FT_Int    s_pitch = source->pitch;
490        FT_Int    t_pitch = target->pitch;
491        FT_Int    i;
492
493
494        target->num_grays = 256;
495
496        for ( i = source->rows; i > 0; i-- )
497        {
498          FT_ARRAY_COPY( t, s, width );
499
500          s += s_pitch;
501          t += t_pitch;
502        }
503      }
504      break;
505
506
507    case FT_PIXEL_MODE_GRAY2:
508      {
509        FT_Byte*  s = source->buffer;
510        FT_Byte*  t = target->buffer;
511        FT_Int    i;
512
513
514        target->num_grays = 4;
515
516        for ( i = source->rows; i > 0; i-- )
517        {
518          FT_Byte*  ss = s;
519          FT_Byte*  tt = t;
520          FT_Int    j;
521
522
523          /* get the full bytes */
524          for ( j = source->width >> 2; j > 0; j-- )
525          {
526            FT_Int  val = ss[0];
527
528
529            tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
530            tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
531            tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
532            tt[3] = (FT_Byte)( ( val & 0x03 ) );
533
534            ss += 1;
535            tt += 4;
536          }
537
538          j = source->width & 3;
539          if ( j > 0 )
540          {
541            FT_Int  val = ss[0];
542
543
544            for ( ; j > 0; j-- )
545            {
546              tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );
547              val  <<= 2;
548              tt    += 1;
549            }
550          }
551
552          s += source->pitch;
553          t += target->pitch;
554        }
555      }
556      break;
557
558
559    case FT_PIXEL_MODE_GRAY4:
560      {
561        FT_Byte*  s = source->buffer;
562        FT_Byte*  t = target->buffer;
563        FT_Int    i;
564
565
566        target->num_grays = 16;
567
568        for ( i = source->rows; i > 0; i-- )
569        {
570          FT_Byte*  ss = s;
571          FT_Byte*  tt = t;
572          FT_Int    j;
573
574
575          /* get the full bytes */
576          for ( j = source->width >> 1; j > 0; j-- )
577          {
578            FT_Int  val = ss[0];
579
580
581            tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
582            tt[1] = (FT_Byte)( ( val & 0x0F ) );
583
584            ss += 1;
585            tt += 2;
586          }
587
588          if ( source->width & 1 )
589            tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
590
591          s += source->pitch;
592          t += target->pitch;
593        }
594      }
595      break;
596
597
598    default:
599      ;
600    }
601
602    return error;
603  }
604
605
606  /* documentation is in ftbitmap.h */
607
608  FT_EXPORT_DEF( FT_Error )
609  FT_Bitmap_Done( FT_Library  library,
610                  FT_Bitmap  *bitmap )
611  {
612    FT_Memory  memory;
613
614
615    if ( !library )
616      return FT_Err_Invalid_Library_Handle;
617
618    if ( !bitmap )
619      return FT_Err_Invalid_Argument;
620
621    memory = library->memory;
622
623    FT_FREE( bitmap->buffer );
624    *bitmap = null_bitmap;
625
626    return FT_Err_Ok;
627  }
628
629
630/* END */
Note: See TracBrowser for help on using the repository browser.