1 /***************************************************************************/
5 /* The FreeType glyph rasterizer interface (body). */
7 /* Copyright 1996-2003, 2005, 2006, 2011, 2013 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_OBJECTS_H
30 /* initialize renderer -- init its raster */
32 ft_raster1_init( FT_Renderer render
)
34 FT_Library library
= FT_MODULE_LIBRARY( render
);
37 render
->clazz
->raster_class
->raster_reset( render
->raster
,
39 library
->raster_pool_size
);
45 /* set render-specific mode */
47 ft_raster1_set_mode( FT_Renderer render
,
51 /* we simply pass it to the raster */
52 return render
->clazz
->raster_class
->raster_set_mode( render
->raster
,
58 /* transform a given glyph image */
60 ft_raster1_transform( FT_Renderer render
,
62 const FT_Matrix
* matrix
,
63 const FT_Vector
* delta
)
65 FT_Error error
= FT_Err_Ok
;
68 if ( slot
->format
!= render
->glyph_format
)
70 error
= FT_THROW( Invalid_Argument
);
75 FT_Outline_Transform( &slot
->outline
, matrix
);
78 FT_Outline_Translate( &slot
->outline
, delta
->x
, delta
->y
);
85 /* return the glyph's control box */
87 ft_raster1_get_cbox( FT_Renderer render
,
91 FT_MEM_ZERO( cbox
, sizeof ( *cbox
) );
93 if ( slot
->format
== render
->glyph_format
)
94 FT_Outline_Get_CBox( &slot
->outline
, cbox
);
98 /* convert a slot's glyph image into a bitmap */
100 ft_raster1_render( FT_Renderer render
,
103 const FT_Vector
* origin
)
108 FT_UInt width
, height
, pitch
;
112 FT_Raster_Params params
;
115 /* check glyph image format */
116 if ( slot
->format
!= render
->glyph_format
)
118 error
= FT_THROW( Invalid_Argument
);
122 /* check rendering mode */
123 #ifndef FT_CONFIG_OPTION_PIC
124 if ( mode
!= FT_RENDER_MODE_MONO
)
126 /* raster1 is only capable of producing monochrome bitmaps */
127 if ( render
->clazz
== &ft_raster1_renderer_class
)
128 return FT_THROW( Cannot_Render_Glyph
);
132 /* raster5 is only capable of producing 5-gray-levels bitmaps */
133 if ( render
->clazz
== &ft_raster5_renderer_class
)
134 return FT_THROW( Cannot_Render_Glyph
);
136 #else /* FT_CONFIG_OPTION_PIC */
137 /* When PIC is enabled, we cannot get to the class object */
138 /* so instead we check the final character in the class name */
139 /* ("raster5" or "raster1"). Yes this is a hack. */
140 /* The "correct" thing to do is have different render function */
141 /* for each of the classes. */
142 if ( mode
!= FT_RENDER_MODE_MONO
)
144 /* raster1 is only capable of producing monochrome bitmaps */
145 if ( render
->clazz
->root
.module_name
[6] == '1' )
146 return FT_THROW( Cannot_Render_Glyph
);
150 /* raster5 is only capable of producing 5-gray-levels bitmaps */
151 if ( render
->clazz
->root
.module_name
[6] == '5' )
152 return FT_THROW( Cannot_Render_Glyph
);
154 #endif /* FT_CONFIG_OPTION_PIC */
156 outline
= &slot
->outline
;
158 /* translate the outline to the new origin if needed */
160 FT_Outline_Translate( outline
, origin
->x
, origin
->y
);
162 /* compute the control box, and grid fit it */
163 FT_Outline_Get_CBox( outline
, &cbox
);
165 /* undocumented but confirmed: bbox values get rounded */
167 cbox
.xMin
= FT_PIX_ROUND( cbox
.xMin
);
168 cbox
.yMin
= FT_PIX_ROUND( cbox
.yMin
);
169 cbox
.xMax
= FT_PIX_ROUND( cbox
.xMax
);
170 cbox
.yMax
= FT_PIX_ROUND( cbox
.yMax
);
172 cbox
.xMin
= FT_PIX_FLOOR( cbox
.xMin
);
173 cbox
.yMin
= FT_PIX_FLOOR( cbox
.yMin
);
174 cbox
.xMax
= FT_PIX_CEIL( cbox
.xMax
);
175 cbox
.yMax
= FT_PIX_CEIL( cbox
.yMax
);
178 width
= (FT_UInt
)( ( cbox
.xMax
- cbox
.xMin
) >> 6 );
179 height
= (FT_UInt
)( ( cbox
.yMax
- cbox
.yMin
) >> 6 );
181 if ( width
> FT_USHORT_MAX
|| height
> FT_USHORT_MAX
)
183 error
= FT_THROW( Invalid_Argument
);
187 bitmap
= &slot
->bitmap
;
188 memory
= render
->root
.memory
;
190 /* release old bitmap buffer */
191 if ( slot
->internal
->flags
& FT_GLYPH_OWN_BITMAP
)
193 FT_FREE( bitmap
->buffer
);
194 slot
->internal
->flags
&= ~FT_GLYPH_OWN_BITMAP
;
197 /* allocate new one, depends on pixel format */
198 if ( !( mode
& FT_RENDER_MODE_MONO
) )
200 /* we pad to 32 bits, only for backwards compatibility with FT 1.x */
201 pitch
= FT_PAD_CEIL( width
, 4 );
202 bitmap
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
203 bitmap
->num_grays
= 256;
207 pitch
= ( ( width
+ 15 ) >> 4 ) << 1;
208 bitmap
->pixel_mode
= FT_PIXEL_MODE_MONO
;
211 bitmap
->width
= width
;
212 bitmap
->rows
= height
;
213 bitmap
->pitch
= pitch
;
215 if ( FT_ALLOC_MULT( bitmap
->buffer
, pitch
, height
) )
218 slot
->internal
->flags
|= FT_GLYPH_OWN_BITMAP
;
220 /* translate outline to render it into the bitmap */
221 FT_Outline_Translate( outline
, -cbox
.xMin
, -cbox
.yMin
);
223 /* set up parameters */
224 params
.target
= bitmap
;
225 params
.source
= outline
;
228 if ( bitmap
->pixel_mode
== FT_PIXEL_MODE_GRAY
)
229 params
.flags
|= FT_RASTER_FLAG_AA
;
231 /* render outline into the bitmap */
232 error
= render
->raster_render( render
->raster
, ¶ms
);
234 FT_Outline_Translate( outline
, cbox
.xMin
, cbox
.yMin
);
239 slot
->format
= FT_GLYPH_FORMAT_BITMAP
;
240 slot
->bitmap_left
= (FT_Int
)( cbox
.xMin
>> 6 );
241 slot
->bitmap_top
= (FT_Int
)( cbox
.yMax
>> 6 );
248 FT_DEFINE_RENDERER( ft_raster1_renderer_class
,
251 sizeof ( FT_RendererRec
),
257 0, /* module specific interface */
259 (FT_Module_Constructor
)ft_raster1_init
,
260 (FT_Module_Destructor
) 0,
261 (FT_Module_Requester
) 0
264 FT_GLYPH_FORMAT_OUTLINE
,
266 (FT_Renderer_RenderFunc
) ft_raster1_render
,
267 (FT_Renderer_TransformFunc
)ft_raster1_transform
,
268 (FT_Renderer_GetCBoxFunc
) ft_raster1_get_cbox
,
269 (FT_Renderer_SetModeFunc
) ft_raster1_set_mode
,
271 (FT_Raster_Funcs
*) &FT_STANDARD_RASTER_GET
275 /* This renderer is _NOT_ part of the default modules; you will need */
276 /* to register it by hand in your application. It should only be */
277 /* used for backwards-compatibility with FT 1.x anyway. */
279 FT_DEFINE_RENDERER( ft_raster5_renderer_class
,
282 sizeof ( FT_RendererRec
),
288 0, /* module specific interface */
290 (FT_Module_Constructor
)ft_raster1_init
,
291 (FT_Module_Destructor
) 0,
292 (FT_Module_Requester
) 0
295 FT_GLYPH_FORMAT_OUTLINE
,
297 (FT_Renderer_RenderFunc
) ft_raster1_render
,
298 (FT_Renderer_TransformFunc
)ft_raster1_transform
,
299 (FT_Renderer_GetCBoxFunc
) ft_raster1_get_cbox
,
300 (FT_Renderer_SetModeFunc
) ft_raster1_set_mode
,
302 (FT_Raster_Funcs
*) &FT_STANDARD_RASTER_GET