1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ftbitmap.c                                                             */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
50a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*    FreeType utility functions for bitmaps (body).                       */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/*  Copyright 2004-2009, 2011, 2013 by                                     */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include FT_INTERNAL_DEBUG_H
21a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_BITMAP_H
230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include FT_IMAGE_H
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const FT_Bitmap  null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftbitmap.h */
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Bitmap_New( FT_Bitmap  *abitmap )
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *abitmap = null_bitmap;
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftbitmap.h */
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Bitmap_Copy( FT_Library        library,
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  const FT_Bitmap  *source,
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Bitmap        *target)
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error  = FT_Err_Ok;
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     pitch  = source->pitch;
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong   size;
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( source == target )
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Ok;
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( source->buffer == NULL )
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *target = *source;
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Ok;
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pitch < 0 )
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pitch = -pitch;
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    size = (FT_ULong)( pitch * source->rows );
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( target->buffer )
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int    target_pitch = target->pitch;
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong  target_size;
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( target_pitch < 0  )
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        target_pitch = -target_pitch;
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      target_size = (FT_ULong)( target_pitch * target->rows );
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( target_size != size )
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (void)FT_QREALLOC( target->buffer, target_size, size );
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (void)FT_QALLOC( target->buffer, size );
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      unsigned char *p;
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p = target->buffer;
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *target = *source;
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      target->buffer = p;
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_COPY( target->buffer, source->buffer, size );
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_bitmap_assure_buffer( FT_Memory   memory,
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Bitmap*  bitmap,
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_UInt     xpixels,
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_UInt     ypixels )
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int             pitch;
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int             new_pitch;
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt         bpp;
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int          i, width, height;
110c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner    unsigned char*  buffer = NULL;
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    width  = bitmap->width;
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    height = bitmap->rows;
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pitch  = bitmap->pitch;
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pitch < 0 )
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pitch = -pitch;
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( bitmap->pixel_mode )
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_MONO:
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bpp       = 1;
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      new_pitch = ( width + xpixels + 7 ) >> 3;
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY2:
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bpp       = 2;
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      new_pitch = ( width + xpixels + 3 ) >> 2;
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY4:
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bpp       = 4;
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      new_pitch = ( width + xpixels + 1 ) >> 1;
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY:
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_LCD:
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_LCD_V:
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bpp       = 8;
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      new_pitch = ( width + xpixels );
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
140a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Glyph_Format );
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if no need to allocate memory */
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ypixels == 0 && new_pitch <= pitch )
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* zero the padding */
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int  bit_width = pitch * 8;
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int  bit_last  = ( width + xpixels ) * bpp;
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( bit_last < bit_width )
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  line  = bitmap->buffer + ( bit_last >> 3 );
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  end   = bitmap->buffer + pitch;
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    shift = bit_last & 7;
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt   mask  = 0xFF00U >> shift;
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    count = height;
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; count > 0; count--, line += pitch, end += pitch )
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte*  write = line;
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( shift > 0 )
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            write[0] = (FT_Byte)( write[0] & mask );
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            write++;
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( write < end )
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_MEM_ZERO( write, end-write );
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Ok;
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( bitmap->pitch > 0 )
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int  len = ( width * bpp + 7 ) >> 3;
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < bitmap->rows; i++ )
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     bitmap->buffer + pitch * i, len );
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int  len = ( width * bpp + 7 ) >> 3;
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < bitmap->rows; i++ )
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MEM_COPY( buffer + new_pitch * i,
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     bitmap->buffer + pitch * i, len );
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( bitmap->buffer );
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bitmap->buffer = buffer;
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( bitmap->pitch < 0 )
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      new_pitch = -new_pitch;
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set pitch only, width and height are left untouched */
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bitmap->pitch = new_pitch;
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftbitmap.h */
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Bitmap_Embolden( FT_Library  library,
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Bitmap*  bitmap,
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Pos      xStrength,
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Pos      yStrength )
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned char*  p;
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int          i, x, y, pitch;
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int          xstr, ystr;
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
228a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Library_Handle );
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !bitmap || !bitmap->buffer )
231a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Argument );
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
233295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
234295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
235a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Argument );
236e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang
237295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
238295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( xstr == 0 && ystr == 0 )
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Ok;
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( xstr < 0 || ystr < 0 )
243a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Argument );
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( bitmap->pixel_mode )
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY2:
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY4:
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bitmap  tmp;
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int     align;
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          align = ( bitmap->width + xstr + 3 ) / 4;
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          align = ( bitmap->width + xstr + 1 ) / 2;
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bitmap_New( &tmp );
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return error;
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bitmap_Done( library, bitmap );
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *bitmap = tmp;
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_MONO:
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( xstr > 8 )
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        xstr = 8;
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_LCD:
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      xstr *= 3;
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_LCD_V:
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ystr *= 3;
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
282a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
283a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    case FT_PIXEL_MODE_BGRA:
284a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      /* We don't embolden color glyphs. */
285a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_Err_Ok;
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pitch = bitmap->pitch;
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pitch > 0 )
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p = bitmap->buffer + pitch * ystr;
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pitch = -pitch;
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p = bitmap->buffer + pitch * ( bitmap->rows - 1 );
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* for each row */
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( y = 0; y < bitmap->rows ; y++ )
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       * Horizontally:
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       *
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       * From the last pixel on, make each pixel or'ed with the
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       * `xstr' pixels before it.
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       */
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( x = pitch - 1; x >= 0; x-- )
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        unsigned char tmp;
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tmp = p[x];
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( i = 1; i <= xstr; i++ )
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            p[x] |= tmp >> i;
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* the maximum value of 8 for `xstr' comes from here */
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( x > 0 )
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              p[x] |= p[x - 1] << ( 8 - i );
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( p[x] == 0xff )
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( x - i >= 0 )
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              {
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                p[x] = (unsigned char)(bitmap->num_grays - 1);
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              }
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              else
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              {
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                p[x] = (unsigned char)(p[x] + p[x-i]);
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                if ( p[x] == bitmap->num_grays - 1 )
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  break;
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              }
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       * Vertically:
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       *
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       * Make the above `ystr' rows or'ed with it.
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       */
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( x = 1; x <= ystr; x++ )
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        unsigned char*  q;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        q = p - bitmap->pitch * x;
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( i = 0; i < pitch; i++ )
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          q[i] |= p[i];
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p += bitmap->pitch;
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bitmap->width += xstr;
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bitmap->rows += ystr;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
378a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  FT_Byte
379a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  ft_gray_for_premultiplied_srgb_bgra( const FT_Byte*  bgra )
380a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  {
381a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Long  a = bgra[3];
382a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Long  b = bgra[0];
383a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Long  g = bgra[1];
384a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Long  r = bgra[2];
385a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Long  l;
386a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
387a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
388a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    /*
389a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722
390a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * coefficients for RGB channels *on the linear colors*.
391a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * A gamma of 2.2 is fair to assume.  And then, we need to
392a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * undo the premultiplication too.
393a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     *
394a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * http://accessibility.kde.org/hsl-adjusted.php
395a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     *
396a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * We do the computation with integers only.
397a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     */
398a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
399a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    /* Undo premultification, get the number in a 16.16 form. */
400a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    b = FT_MulDiv( b, 65536, a );
401a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    g = FT_MulDiv( g, 65536, a );
402a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    r = FT_MulDiv( r, 65536, a );
403a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    a = a * 256;
404a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
405a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    /* Apply gamma of 2.0 instead of 2.2. */
406a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    b = FT_MulFix( b, b );
407a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    g = FT_MulFix( g, g );
408a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    r = FT_MulFix( r, r );
409a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
410a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    /* Apply coefficients. */
411a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    b = FT_MulFix( b,  4731 /* 0.0722 * 65536 */ );
412a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ );
413a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ );
414a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
415a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    l = r + g + b;
416a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
417a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    /*
418a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * Final transparency can be determined this way:
419a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     *
420a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * - If alpha is zero, we want 0.
421a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * - If alpha is zero and luminosity is zero, we want 255.
422a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * - If alpha is zero and luminosity is one, we want 0.
423a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     *
424a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     * So the formula is a * (1 - l).
425a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang     */
426a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
427a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 );
428a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  }
429a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
430a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftbitmap.h */
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Bitmap_Convert( FT_Library        library,
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     const FT_Bitmap  *source,
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Bitmap        *target,
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Int            alignment )
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error = FT_Err_Ok;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
444a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Library_Handle );
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( source->pixel_mode )
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_MONO:
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY:
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY2:
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY4:
4540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    case FT_PIXEL_MODE_LCD:
4550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    case FT_PIXEL_MODE_LCD_V:
456a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    case FT_PIXEL_MODE_BGRA:
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int   pad;
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Long  old_size;
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        old_size = target->rows * target->pitch;
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( old_size < 0 )
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          old_size = -old_size;
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        target->pixel_mode = FT_PIXEL_MODE_GRAY;
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        target->rows       = source->rows;
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        target->width      = source->width;
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pad = 0;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( alignment > 0 )
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pad = source->width % alignment;
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( pad != 0 )
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            pad = alignment - pad;
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        target->pitch = source->width + pad;
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
480e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang        if ( target->pitch > 0                                     &&
481e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang             (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch )
482a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          return FT_THROW( Invalid_Argument );
483e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( target->rows * target->pitch > old_size             &&
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_QREALLOC( target->buffer,
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          old_size, target->rows * target->pitch ) )
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return error;
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
492a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      error = FT_THROW( Invalid_Argument );
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( source->pixel_mode )
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_MONO:
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  s = source->buffer;
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  t = target->buffer;
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    i;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        target->num_grays = 2;
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( i = source->rows; i > 0; i-- )
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte*  ss = s;
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte*  tt = t;
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Int    j;
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* get the full bytes */
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = source->width >> 3; j > 0; j-- )
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[7] = (FT_Byte)(   val & 0x01 );
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt += 8;
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ss += 1;
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* get remaining pixels (if any) */
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          j = source->width & 7;
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( j > 0 )
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int  val = *ss;
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            for ( ; j > 0; j-- )
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              val <<= 1;
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              tt   += 1;
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          s += source->pitch;
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          t += target->pitch;
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY:
5550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    case FT_PIXEL_MODE_LCD:
5560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    case FT_PIXEL_MODE_LCD_V:
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    width   = source->width;
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  s       = source->buffer;
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  t       = target->buffer;
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    s_pitch = source->pitch;
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    t_pitch = target->pitch;
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    i;
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        target->num_grays = 256;
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( i = source->rows; i > 0; i-- )
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_ARRAY_COPY( t, s, width );
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          s += s_pitch;
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          t += t_pitch;
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY2:
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  s = source->buffer;
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  t = target->buffer;
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    i;
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        target->num_grays = 4;
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( i = source->rows; i > 0; i-- )
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte*  ss = s;
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte*  tt = t;
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Int    j;
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* get the full bytes */
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = source->width >> 2; j > 0; j-- )
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int  val = ss[0];
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[3] = (FT_Byte)( ( val & 0x03 ) );
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ss += 1;
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt += 4;
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          j = source->width & 3;
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( j > 0 )
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int  val = ss[0];
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            for ( ; j > 0; j-- )
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              val  <<= 2;
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              tt    += 1;
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          s += source->pitch;
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          t += target->pitch;
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_PIXEL_MODE_GRAY4:
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  s = source->buffer;
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  t = target->buffer;
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    i;
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        target->num_grays = 16;
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( i = source->rows; i > 0; i-- )
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte*  ss = s;
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte*  tt = t;
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Int    j;
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* get the full bytes */
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = source->width >> 1; j > 0; j-- )
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int  val = ss[0];
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[1] = (FT_Byte)( ( val & 0x0F ) );
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ss += 1;
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt += 2;
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( source->width & 1 )
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          s += source->pitch;
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          t += target->pitch;
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
669a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    case FT_PIXEL_MODE_BGRA:
670a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      {
671a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        FT_Byte*  s       = source->buffer;
672a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        FT_Byte*  t       = target->buffer;
673a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        FT_Int    s_pitch = source->pitch;
674a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        FT_Int    t_pitch = target->pitch;
675a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        FT_Int    i;
676a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
677a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
678a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        target->num_grays = 256;
679a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
680a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        for ( i = source->rows; i > 0; i-- )
681a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        {
682a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          FT_Byte*  ss = s;
683a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          FT_Byte*  tt = t;
684a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          FT_Int    j;
685a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
686a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
687a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          for ( j = source->width; j > 0; j-- )
688a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          {
689a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            tt[0] = ft_gray_for_premultiplied_srgb_bgra( ss );
690a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
691a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            ss += 4;
692a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            tt += 1;
693a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          }
694a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
695a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          s += s_pitch;
696a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          t += t_pitch;
697a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        }
698a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      }
699a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      break;
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ;
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftbitmap.h */
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
7120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot )
7130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  {
7140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP   &&
7150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project         !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
7160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
7170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_Bitmap  bitmap;
7180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_Error   error;
7190a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_Bitmap_New( &bitmap );
7220a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
7230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( error )
7240a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return error;
7250a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      slot->bitmap = bitmap;
7270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
7280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
7290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return FT_Err_Ok;
7310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  }
7320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* documentation is in ftbitmap.h */
7350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Bitmap_Done( FT_Library  library,
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Bitmap  *bitmap )
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
744a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Library_Handle );
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !bitmap )
747a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Argument );
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( bitmap->buffer );
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *bitmap = null_bitmap;
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
759