PageRenderTime 58ms CodeModel.GetById 2ms app.highlight 49ms RepoModel.GetById 1ms app.codeStats 0ms

/src/compiler/android-ndk/jni/freetype/src/base/ftbitmap.c

http://ftk.googlecode.com/
C | 663 lines | 462 code | 158 blank | 43 comment | 82 complexity | 468562d0a3d1e0b562f0ecd7bddad70d MD5 | raw file
  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    if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
232         ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
233      return FT_Err_Invalid_Argument;
234       
235    xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
236    ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
237
238    if ( xstr == 0 && ystr == 0 )
239      return FT_Err_Ok;
240    else if ( xstr < 0 || ystr < 0 )
241      return FT_Err_Invalid_Argument;
242
243    switch ( bitmap->pixel_mode )
244    {
245    case FT_PIXEL_MODE_GRAY2:
246    case FT_PIXEL_MODE_GRAY4:
247      {
248        FT_Bitmap  tmp;
249        FT_Int     align;
250
251
252        if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
253          align = ( bitmap->width + xstr + 3 ) / 4;
254        else
255          align = ( bitmap->width + xstr + 1 ) / 2;
256
257        FT_Bitmap_New( &tmp );
258
259        error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
260        if ( error )
261          return error;
262
263        FT_Bitmap_Done( library, bitmap );
264        *bitmap = tmp;
265      }
266      break;
267
268    case FT_PIXEL_MODE_MONO:
269      if ( xstr > 8 )
270        xstr = 8;
271      break;
272
273    case FT_PIXEL_MODE_LCD:
274      xstr *= 3;
275      break;
276
277    case FT_PIXEL_MODE_LCD_V:
278      ystr *= 3;
279      break;
280    }
281
282    error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
283    if ( error )
284      return error;
285
286    pitch = bitmap->pitch;
287    if ( pitch > 0 )
288      p = bitmap->buffer + pitch * ystr;
289    else
290    {
291      pitch = -pitch;
292      p = bitmap->buffer + pitch * ( bitmap->rows - 1 );
293    }
294
295    /* for each row */
296    for ( y = 0; y < bitmap->rows ; y++ )
297    {
298      /*
299       * Horizontally:
300       *
301       * From the last pixel on, make each pixel or'ed with the
302       * `xstr' pixels before it.
303       */
304      for ( x = pitch - 1; x >= 0; x-- )
305      {
306        unsigned char tmp;
307
308
309        tmp = p[x];
310        for ( i = 1; i <= xstr; i++ )
311        {
312          if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
313          {
314            p[x] |= tmp >> i;
315
316            /* the maximum value of 8 for `xstr' comes from here */
317            if ( x > 0 )
318              p[x] |= p[x - 1] << ( 8 - i );
319
320#if 0
321            if ( p[x] == 0xff )
322              break;
323#endif
324          }
325          else
326          {
327            if ( x - i >= 0 )
328            {
329              if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
330              {
331                p[x] = (unsigned char)(bitmap->num_grays - 1);
332                break;
333              }
334              else
335              {
336                p[x] = (unsigned char)(p[x] + p[x-i]);
337                if ( p[x] == bitmap->num_grays - 1 )
338                  break;
339              }
340            }
341            else
342              break;
343          }
344        }
345      }
346
347      /*
348       * Vertically:
349       *
350       * Make the above `ystr' rows or'ed with it.
351       */
352      for ( x = 1; x <= ystr; x++ )
353      {
354        unsigned char*  q;
355
356
357        q = p - bitmap->pitch * x;
358        for ( i = 0; i < pitch; i++ )
359          q[i] |= p[i];
360      }
361
362      p += bitmap->pitch;
363    }
364
365    bitmap->width += xstr;
366    bitmap->rows += ystr;
367
368    return FT_Err_Ok;
369  }
370
371
372  /* documentation is in ftbitmap.h */
373
374  FT_EXPORT_DEF( FT_Error )
375  FT_Bitmap_Convert( FT_Library        library,
376                     const FT_Bitmap  *source,
377                     FT_Bitmap        *target,
378                     FT_Int            alignment )
379  {
380    FT_Error   error = FT_Err_Ok;
381    FT_Memory  memory;
382
383
384    if ( !library )
385      return FT_Err_Invalid_Library_Handle;
386
387    memory = library->memory;
388
389    switch ( source->pixel_mode )
390    {
391    case FT_PIXEL_MODE_MONO:
392    case FT_PIXEL_MODE_GRAY:
393    case FT_PIXEL_MODE_GRAY2:
394    case FT_PIXEL_MODE_GRAY4:
395    case FT_PIXEL_MODE_LCD:
396    case FT_PIXEL_MODE_LCD_V:
397      {
398        FT_Int   pad;
399        FT_Long  old_size;
400
401
402        old_size = target->rows * target->pitch;
403        if ( old_size < 0 )
404          old_size = -old_size;
405
406        target->pixel_mode = FT_PIXEL_MODE_GRAY;
407        target->rows       = source->rows;
408        target->width      = source->width;
409
410        pad = 0;
411        if ( alignment > 0 )
412        {
413          pad = source->width % alignment;
414          if ( pad != 0 )
415            pad = alignment - pad;
416        }
417
418        target->pitch = source->width + pad;
419
420        if ( target->rows * target->pitch > old_size             &&
421             FT_QREALLOC( target->buffer,
422                          old_size, target->rows * target->pitch ) )
423          return error;
424      }
425      break;
426
427    default:
428      error = FT_Err_Invalid_Argument;
429    }
430
431    switch ( source->pixel_mode )
432    {
433    case FT_PIXEL_MODE_MONO:
434      {
435        FT_Byte*  s = source->buffer;
436        FT_Byte*  t = target->buffer;
437        FT_Int    i;
438
439
440        target->num_grays = 2;
441
442        for ( i = source->rows; i > 0; i-- )
443        {
444          FT_Byte*  ss = s;
445          FT_Byte*  tt = t;
446          FT_Int    j;
447
448
449          /* get the full bytes */
450          for ( j = source->width >> 3; j > 0; j-- )
451          {
452            FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */
453
454
455            tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
456            tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
457            tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
458            tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
459            tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
460            tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
461            tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
462            tt[7] = (FT_Byte)(   val & 0x01 );
463
464            tt += 8;
465            ss += 1;
466          }
467
468          /* get remaining pixels (if any) */
469          j = source->width & 7;
470          if ( j > 0 )
471          {
472            FT_Int  val = *ss;
473
474
475            for ( ; j > 0; j-- )
476            {
477              tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
478              val <<= 1;
479              tt   += 1;
480            }
481          }
482
483          s += source->pitch;
484          t += target->pitch;
485        }
486      }
487      break;
488
489
490    case FT_PIXEL_MODE_GRAY:
491    case FT_PIXEL_MODE_LCD:
492    case FT_PIXEL_MODE_LCD_V:
493      {
494        FT_Int    width   = source->width;
495        FT_Byte*  s       = source->buffer;
496        FT_Byte*  t       = target->buffer;
497        FT_Int    s_pitch = source->pitch;
498        FT_Int    t_pitch = target->pitch;
499        FT_Int    i;
500
501
502        target->num_grays = 256;
503
504        for ( i = source->rows; i > 0; i-- )
505        {
506          FT_ARRAY_COPY( t, s, width );
507
508          s += s_pitch;
509          t += t_pitch;
510        }
511      }
512      break;
513
514
515    case FT_PIXEL_MODE_GRAY2:
516      {
517        FT_Byte*  s = source->buffer;
518        FT_Byte*  t = target->buffer;
519        FT_Int    i;
520
521
522        target->num_grays = 4;
523
524        for ( i = source->rows; i > 0; i-- )
525        {
526          FT_Byte*  ss = s;
527          FT_Byte*  tt = t;
528          FT_Int    j;
529
530
531          /* get the full bytes */
532          for ( j = source->width >> 2; j > 0; j-- )
533          {
534            FT_Int  val = ss[0];
535
536
537            tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
538            tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
539            tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
540            tt[3] = (FT_Byte)( ( val & 0x03 ) );
541
542            ss += 1;
543            tt += 4;
544          }
545
546          j = source->width & 3;
547          if ( j > 0 )
548          {
549            FT_Int  val = ss[0];
550
551
552            for ( ; j > 0; j-- )
553            {
554              tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );
555              val  <<= 2;
556              tt    += 1;
557            }
558          }
559
560          s += source->pitch;
561          t += target->pitch;
562        }
563      }
564      break;
565
566
567    case FT_PIXEL_MODE_GRAY4:
568      {
569        FT_Byte*  s = source->buffer;
570        FT_Byte*  t = target->buffer;
571        FT_Int    i;
572
573
574        target->num_grays = 16;
575
576        for ( i = source->rows; i > 0; i-- )
577        {
578          FT_Byte*  ss = s;
579          FT_Byte*  tt = t;
580          FT_Int    j;
581
582
583          /* get the full bytes */
584          for ( j = source->width >> 1; j > 0; j-- )
585          {
586            FT_Int  val = ss[0];
587
588
589            tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
590            tt[1] = (FT_Byte)( ( val & 0x0F ) );
591
592            ss += 1;
593            tt += 2;
594          }
595
596          if ( source->width & 1 )
597            tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
598
599          s += source->pitch;
600          t += target->pitch;
601        }
602      }
603      break;
604
605
606    default:
607      ;
608    }
609
610    return error;
611  }
612
613
614  /* documentation is in ftbitmap.h */
615
616  FT_EXPORT_DEF( FT_Error )
617  FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot )
618  {
619    if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP   &&
620         !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
621    {
622      FT_Bitmap  bitmap;
623      FT_Error   error;
624
625
626      FT_Bitmap_New( &bitmap );
627      error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
628      if ( error )
629        return error;
630
631      slot->bitmap = bitmap;
632      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
633    }
634
635    return FT_Err_Ok;
636  }
637
638
639  /* documentation is in ftbitmap.h */
640
641  FT_EXPORT_DEF( FT_Error )
642  FT_Bitmap_Done( FT_Library  library,
643                  FT_Bitmap  *bitmap )
644  {
645    FT_Memory  memory;
646
647
648    if ( !library )
649      return FT_Err_Invalid_Library_Handle;
650
651    if ( !bitmap )
652      return FT_Err_Invalid_Argument;
653
654    memory = library->memory;
655
656    FT_FREE( bitmap->buffer );
657    *bitmap = null_bitmap;
658
659    return FT_Err_Ok;
660  }
661
662
663/* END */