OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ftrend1.c */ | 3 /* ftrend1.c */ |
4 /* */ | 4 /* */ |
5 /* The FreeType glyph rasterizer interface (body). */ | 5 /* The FreeType glyph rasterizer interface (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 1996-2003, 2005, 2006, 2011, 2013 by */ | 7 /* Copyright 1996-2015 by */ |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
9 /* */ | 9 /* */ |
10 /* This file is part of the FreeType project, and may only be used, */ | 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 */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
15 /* */ | 15 /* */ |
16 /***************************************************************************/ | 16 /***************************************************************************/ |
17 | 17 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 | 97 |
98 /* convert a slot's glyph image into a bitmap */ | 98 /* convert a slot's glyph image into a bitmap */ |
99 static FT_Error | 99 static FT_Error |
100 ft_raster1_render( FT_Renderer render, | 100 ft_raster1_render( FT_Renderer render, |
101 FT_GlyphSlot slot, | 101 FT_GlyphSlot slot, |
102 FT_Render_Mode mode, | 102 FT_Render_Mode mode, |
103 const FT_Vector* origin ) | 103 const FT_Vector* origin ) |
104 { | 104 { |
105 FT_Error error; | 105 FT_Error error; |
106 FT_Outline* outline; | 106 FT_Outline* outline; |
107 FT_BBox cbox; | 107 FT_BBox cbox, cbox0; |
108 FT_UInt width, height, pitch; | 108 FT_UInt width, height, pitch; |
109 FT_Bitmap* bitmap; | 109 FT_Bitmap* bitmap; |
110 FT_Memory memory; | 110 FT_Memory memory; |
111 | 111 |
112 FT_Raster_Params params; | 112 FT_Raster_Params params; |
113 | 113 |
114 | 114 |
115 /* check glyph image format */ | 115 /* check glyph image format */ |
116 if ( slot->format != render->glyph_format ) | 116 if ( slot->format != render->glyph_format ) |
117 { | 117 { |
118 error = FT_THROW( Invalid_Argument ); | 118 error = FT_THROW( Invalid_Argument ); |
119 goto Exit; | 119 goto Exit; |
120 } | 120 } |
121 | 121 |
122 /* check rendering mode */ | 122 /* check rendering mode */ |
123 #ifndef FT_CONFIG_OPTION_PIC | |
124 if ( mode != FT_RENDER_MODE_MONO ) | 123 if ( mode != FT_RENDER_MODE_MONO ) |
125 { | 124 { |
126 /* raster1 is only capable of producing monochrome bitmaps */ | 125 /* raster1 is only capable of producing monochrome bitmaps */ |
127 if ( render->clazz == &ft_raster1_renderer_class ) | 126 return FT_THROW( Cannot_Render_Glyph ); |
128 return FT_THROW( Cannot_Render_Glyph ); | |
129 } | 127 } |
130 else | |
131 { | |
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 ); | |
135 } | |
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 ) | |
143 { | |
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 ); | |
147 } | |
148 else | |
149 { | |
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 ); | |
153 } | |
154 #endif /* FT_CONFIG_OPTION_PIC */ | |
155 | 128 |
156 outline = &slot->outline; | 129 outline = &slot->outline; |
157 | 130 |
158 /* translate the outline to the new origin if needed */ | 131 /* translate the outline to the new origin if needed */ |
159 if ( origin ) | 132 if ( origin ) |
160 FT_Outline_Translate( outline, origin->x, origin->y ); | 133 FT_Outline_Translate( outline, origin->x, origin->y ); |
161 | 134 |
162 /* compute the control box, and grid fit it */ | 135 /* compute the control box, and grid fit it */ |
163 FT_Outline_Get_CBox( outline, &cbox ); | 136 FT_Outline_Get_CBox( outline, &cbox0 ); |
164 | 137 |
165 /* undocumented but confirmed: bbox values get rounded */ | 138 /* undocumented but confirmed: bbox values get rounded */ |
166 #if 1 | 139 #if 1 |
167 cbox.xMin = FT_PIX_ROUND( cbox.xMin ); | 140 cbox.xMin = FT_PIX_ROUND( cbox0.xMin ); |
168 cbox.yMin = FT_PIX_ROUND( cbox.yMin ); | 141 cbox.yMin = FT_PIX_ROUND( cbox0.yMin ); |
169 cbox.xMax = FT_PIX_ROUND( cbox.xMax ); | 142 cbox.xMax = FT_PIX_ROUND( cbox0.xMax ); |
170 cbox.yMax = FT_PIX_ROUND( cbox.yMax ); | 143 cbox.yMax = FT_PIX_ROUND( cbox0.yMax ); |
171 #else | 144 #else |
172 cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); | 145 cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); |
173 cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); | 146 cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); |
174 cbox.xMax = FT_PIX_CEIL( cbox.xMax ); | 147 cbox.xMax = FT_PIX_CEIL( cbox.xMax ); |
175 cbox.yMax = FT_PIX_CEIL( cbox.yMax ); | 148 cbox.yMax = FT_PIX_CEIL( cbox.yMax ); |
176 #endif | 149 #endif |
177 | 150 |
| 151 /* If either `width' or `height' round to 0, try */ |
| 152 /* explicitly rounding up/down. In the case of */ |
| 153 /* glyphs containing only one very narrow feature, */ |
| 154 /* this gives the drop-out compensation in the scan */ |
| 155 /* conversion code a chance to do its stuff. */ |
178 width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); | 156 width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); |
| 157 if ( width == 0 ) |
| 158 { |
| 159 cbox.xMin = FT_PIX_FLOOR( cbox0.xMin ); |
| 160 cbox.xMax = FT_PIX_CEIL( cbox0.xMax ); |
| 161 |
| 162 width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); |
| 163 } |
| 164 |
179 height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); | 165 height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); |
| 166 if ( height == 0 ) |
| 167 { |
| 168 cbox.yMin = FT_PIX_FLOOR( cbox0.yMin ); |
| 169 cbox.yMax = FT_PIX_CEIL( cbox0.yMax ); |
| 170 |
| 171 height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); |
| 172 } |
180 | 173 |
181 if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX ) | 174 if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX ) |
182 { | 175 { |
183 error = FT_THROW( Invalid_Argument ); | 176 error = FT_THROW( Invalid_Argument ); |
184 goto Exit; | 177 goto Exit; |
185 } | 178 } |
186 | 179 |
187 bitmap = &slot->bitmap; | 180 bitmap = &slot->bitmap; |
188 memory = render->root.memory; | 181 memory = render->root.memory; |
189 | 182 |
190 /* release old bitmap buffer */ | 183 /* release old bitmap buffer */ |
191 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) | 184 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) |
192 { | 185 { |
193 FT_FREE( bitmap->buffer ); | 186 FT_FREE( bitmap->buffer ); |
194 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; | 187 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; |
195 } | 188 } |
196 | 189 |
197 /* allocate new one, depends on pixel format */ | 190 pitch = ( ( width + 15 ) >> 4 ) << 1; |
198 if ( !( mode & FT_RENDER_MODE_MONO ) ) | 191 bitmap->pixel_mode = FT_PIXEL_MODE_MONO; |
199 { | |
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; | |
204 } | |
205 else | |
206 { | |
207 pitch = ( ( width + 15 ) >> 4 ) << 1; | |
208 bitmap->pixel_mode = FT_PIXEL_MODE_MONO; | |
209 } | |
210 | 192 |
211 bitmap->width = width; | 193 bitmap->width = width; |
212 bitmap->rows = height; | 194 bitmap->rows = height; |
213 bitmap->pitch = pitch; | 195 bitmap->pitch = (int)pitch; |
214 | 196 |
215 if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) | 197 if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) |
216 goto Exit; | 198 goto Exit; |
217 | 199 |
218 slot->internal->flags |= FT_GLYPH_OWN_BITMAP; | 200 slot->internal->flags |= FT_GLYPH_OWN_BITMAP; |
219 | 201 |
220 /* translate outline to render it into the bitmap */ | 202 /* translate outline to render it into the bitmap */ |
221 FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); | 203 FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); |
222 | 204 |
223 /* set up parameters */ | 205 /* set up parameters */ |
224 params.target = bitmap; | 206 params.target = bitmap; |
225 params.source = outline; | 207 params.source = outline; |
226 params.flags = 0; | 208 params.flags = 0; |
227 | 209 |
228 if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY ) | |
229 params.flags |= FT_RASTER_FLAG_AA; | |
230 | |
231 /* render outline into the bitmap */ | 210 /* render outline into the bitmap */ |
232 error = render->raster_render( render->raster, ¶ms ); | 211 error = render->raster_render( render->raster, ¶ms ); |
233 | 212 |
234 FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); | 213 FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); |
235 | 214 |
236 if ( error ) | 215 if ( error ) |
237 goto Exit; | 216 goto Exit; |
238 | 217 |
239 slot->format = FT_GLYPH_FORMAT_BITMAP; | 218 slot->format = FT_GLYPH_FORMAT_BITMAP; |
240 slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); | 219 slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); |
(...skipping 24 matching lines...) Expand all Loading... |
265 | 244 |
266 (FT_Renderer_RenderFunc) ft_raster1_render, | 245 (FT_Renderer_RenderFunc) ft_raster1_render, |
267 (FT_Renderer_TransformFunc)ft_raster1_transform, | 246 (FT_Renderer_TransformFunc)ft_raster1_transform, |
268 (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, | 247 (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, |
269 (FT_Renderer_SetModeFunc) ft_raster1_set_mode, | 248 (FT_Renderer_SetModeFunc) ft_raster1_set_mode, |
270 | 249 |
271 (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET | 250 (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET |
272 ) | 251 ) |
273 | 252 |
274 | 253 |
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. */ | |
278 /* */ | |
279 FT_DEFINE_RENDERER( ft_raster5_renderer_class, | |
280 | |
281 FT_MODULE_RENDERER, | |
282 sizeof ( FT_RendererRec ), | |
283 | |
284 "raster5", | |
285 0x10000L, | |
286 0x20000L, | |
287 | |
288 0, /* module specific interface */ | |
289 | |
290 (FT_Module_Constructor)ft_raster1_init, | |
291 (FT_Module_Destructor) 0, | |
292 (FT_Module_Requester) 0 | |
293 , | |
294 | |
295 FT_GLYPH_FORMAT_OUTLINE, | |
296 | |
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, | |
301 | |
302 (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET | |
303 ) | |
304 | |
305 | |
306 /* END */ | 254 /* END */ |
OLD | NEW |