ftsmooth.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /***************************************************************************/
  2. /* */
  3. /* ftsmooth.c */
  4. /* */
  5. /* Anti-aliasing renderer interface (body). */
  6. /* */
  7. /* Copyright 2000-2001, 2002 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. #include <ft2build.h>
  18. #include FT_INTERNAL_OBJECTS_H
  19. #include FT_OUTLINE_H
  20. #include "ftsmooth.h"
  21. #include "ftgrays.h"
  22. #include "ftsmerrs.h"
  23. /* initialize renderer -- init its raster */
  24. static FT_Error
  25. ft_smooth_init( FT_Renderer render )
  26. {
  27. FT_Library library = FT_MODULE_LIBRARY( render );
  28. render->clazz->raster_class->raster_reset( render->raster,
  29. library->raster_pool,
  30. library->raster_pool_size );
  31. return 0;
  32. }
  33. /* sets render-specific mode */
  34. static FT_Error
  35. ft_smooth_set_mode( FT_Renderer render,
  36. FT_ULong mode_tag,
  37. FT_Pointer data )
  38. {
  39. /* we simply pass it to the raster */
  40. return render->clazz->raster_class->raster_set_mode( render->raster,
  41. mode_tag,
  42. data );
  43. }
  44. /* transform a given glyph image */
  45. static FT_Error
  46. ft_smooth_transform( FT_Renderer render,
  47. FT_GlyphSlot slot,
  48. FT_Matrix* matrix,
  49. FT_Vector* delta )
  50. {
  51. FT_Error error = Smooth_Err_Ok;
  52. if ( slot->format != render->glyph_format )
  53. {
  54. error = Smooth_Err_Invalid_Argument;
  55. goto Exit;
  56. }
  57. if ( matrix )
  58. FT_Outline_Transform( &slot->outline, matrix );
  59. if ( delta )
  60. FT_Outline_Translate( &slot->outline, delta->x, delta->y );
  61. Exit:
  62. return error;
  63. }
  64. /* return the glyph's control box */
  65. static void
  66. ft_smooth_get_cbox( FT_Renderer render,
  67. FT_GlyphSlot slot,
  68. FT_BBox* cbox )
  69. {
  70. FT_MEM_ZERO( cbox, sizeof ( *cbox ) );
  71. if ( slot->format == render->glyph_format )
  72. FT_Outline_Get_CBox( &slot->outline, cbox );
  73. }
  74. /* convert a slot's glyph image into a bitmap */
  75. static FT_Error
  76. ft_smooth_render_generic( FT_Renderer render,
  77. FT_GlyphSlot slot,
  78. FT_Render_Mode mode,
  79. FT_Vector* origin,
  80. FT_Render_Mode required_mode,
  81. FT_Int hmul,
  82. FT_Int vmul )
  83. {
  84. FT_Error error;
  85. FT_Outline* outline = NULL;
  86. FT_BBox cbox;
  87. FT_UInt width, height, pitch;
  88. FT_Bitmap* bitmap;
  89. FT_Memory memory;
  90. FT_Raster_Params params;
  91. /* check glyph image format */
  92. if ( slot->format != render->glyph_format )
  93. {
  94. error = Smooth_Err_Invalid_Argument;
  95. goto Exit;
  96. }
  97. /* check mode */
  98. if ( mode != required_mode )
  99. return Smooth_Err_Cannot_Render_Glyph;
  100. outline = &slot->outline;
  101. /* translate the outline to the new origin if needed */
  102. if ( origin )
  103. FT_Outline_Translate( outline, origin->x, origin->y );
  104. /* compute the control box, and grid fit it */
  105. FT_Outline_Get_CBox( outline, &cbox );
  106. cbox.xMin &= -64;
  107. cbox.yMin &= -64;
  108. cbox.xMax = ( cbox.xMax + 63 ) & -64;
  109. cbox.yMax = ( cbox.yMax + 63 ) & -64;
  110. width = ( cbox.xMax - cbox.xMin ) >> 6;
  111. height = ( cbox.yMax - cbox.yMin ) >> 6;
  112. bitmap = &slot->bitmap;
  113. memory = render->root.memory;
  114. /* release old bitmap buffer */
  115. if ( slot->flags & FT_GLYPH_OWN_BITMAP )
  116. {
  117. FT_FREE( bitmap->buffer );
  118. slot->flags &= ~FT_GLYPH_OWN_BITMAP;
  119. }
  120. /* allocate new one, depends on pixel format */
  121. pitch = width;
  122. if ( hmul )
  123. {
  124. width = width * hmul;
  125. pitch = ( width + 3 ) & -4;
  126. }
  127. if ( vmul )
  128. height *= vmul;
  129. bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
  130. bitmap->num_grays = 256;
  131. bitmap->width = width;
  132. bitmap->rows = height;
  133. bitmap->pitch = pitch;
  134. if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
  135. goto Exit;
  136. slot->flags |= FT_GLYPH_OWN_BITMAP;
  137. /* translate outline to render it into the bitmap */
  138. FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin );
  139. /* set up parameters */
  140. params.target = bitmap;
  141. params.source = outline;
  142. params.flags = FT_RASTER_FLAG_AA;
  143. /* implode outline if needed */
  144. {
  145. FT_Int n;
  146. FT_Vector* vec;
  147. if ( hmul )
  148. for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ )
  149. vec->x *= hmul;
  150. if ( vmul )
  151. for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ )
  152. vec->y *= vmul;
  153. }
  154. /* render outline into the bitmap */
  155. error = render->raster_render( render->raster, &params );
  156. /* deflate outline if needed */
  157. {
  158. FT_Int n;
  159. FT_Vector* vec;
  160. if ( hmul )
  161. for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ )
  162. vec->x /= hmul;
  163. if ( vmul )
  164. for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ )
  165. vec->y /= vmul;
  166. }
  167. FT_Outline_Translate( outline, cbox.xMin, cbox.yMin );
  168. if ( error )
  169. goto Exit;
  170. slot->format = FT_GLYPH_FORMAT_BITMAP;
  171. slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 );
  172. slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 );
  173. Exit:
  174. if ( outline && origin )
  175. FT_Outline_Translate( outline, -origin->x, -origin->y );
  176. return error;
  177. }
  178. /* convert a slot's glyph image into a bitmap */
  179. static FT_Error
  180. ft_smooth_render( FT_Renderer render,
  181. FT_GlyphSlot slot,
  182. FT_Render_Mode mode,
  183. FT_Vector* origin )
  184. {
  185. return ft_smooth_render_generic( render, slot, mode, origin,
  186. FT_RENDER_MODE_NORMAL,
  187. 0, 0 );
  188. }
  189. /* convert a slot's glyph image into a horizontal LCD bitmap */
  190. static FT_Error
  191. ft_smooth_render_lcd( FT_Renderer render,
  192. FT_GlyphSlot slot,
  193. FT_Render_Mode mode,
  194. FT_Vector* origin )
  195. {
  196. FT_Error error;
  197. error = ft_smooth_render_generic( render, slot, mode, origin,
  198. FT_RENDER_MODE_LCD,
  199. 3, 0 );
  200. if ( !error )
  201. slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD;
  202. return error;
  203. }
  204. /* convert a slot's glyph image into a vertical LCD bitmap */
  205. static FT_Error
  206. ft_smooth_render_lcd_v( FT_Renderer render,
  207. FT_GlyphSlot slot,
  208. FT_Render_Mode mode,
  209. FT_Vector* origin )
  210. {
  211. FT_Error error;
  212. error = ft_smooth_render_generic( render, slot, mode, origin,
  213. FT_RENDER_MODE_LCD_V,
  214. 0, 3 );
  215. if ( !error )
  216. slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V;
  217. return error;
  218. }
  219. FT_CALLBACK_TABLE_DEF
  220. const FT_Renderer_Class ft_smooth_renderer_class =
  221. {
  222. {
  223. ft_module_renderer,
  224. sizeof( FT_RendererRec ),
  225. "smooth",
  226. 0x10000L,
  227. 0x20000L,
  228. 0, /* module specific interface */
  229. (FT_Module_Constructor)ft_smooth_init,
  230. (FT_Module_Destructor) 0,
  231. (FT_Module_Requester) 0
  232. },
  233. FT_GLYPH_FORMAT_OUTLINE,
  234. (FT_Renderer_RenderFunc) ft_smooth_render,
  235. (FT_Renderer_TransformFunc)ft_smooth_transform,
  236. (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox,
  237. (FT_Renderer_SetModeFunc) ft_smooth_set_mode,
  238. (FT_Raster_Funcs*) &ft_grays_raster
  239. };
  240. FT_CALLBACK_TABLE_DEF
  241. const FT_Renderer_Class ft_smooth_lcd_renderer_class =
  242. {
  243. {
  244. ft_module_renderer,
  245. sizeof( FT_RendererRec ),
  246. "smooth-lcd",
  247. 0x10000L,
  248. 0x20000L,
  249. 0, /* module specific interface */
  250. (FT_Module_Constructor)ft_smooth_init,
  251. (FT_Module_Destructor) 0,
  252. (FT_Module_Requester) 0
  253. },
  254. FT_GLYPH_FORMAT_OUTLINE,
  255. (FT_Renderer_RenderFunc) ft_smooth_render_lcd,
  256. (FT_Renderer_TransformFunc)ft_smooth_transform,
  257. (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox,
  258. (FT_Renderer_SetModeFunc) ft_smooth_set_mode,
  259. (FT_Raster_Funcs*) &ft_grays_raster
  260. };
  261. FT_CALLBACK_TABLE_DEF
  262. const FT_Renderer_Class ft_smooth_lcdv_renderer_class =
  263. {
  264. {
  265. ft_module_renderer,
  266. sizeof( FT_RendererRec ),
  267. "smooth-lcdv",
  268. 0x10000L,
  269. 0x20000L,
  270. 0, /* module specific interface */
  271. (FT_Module_Constructor)ft_smooth_init,
  272. (FT_Module_Destructor) 0,
  273. (FT_Module_Requester) 0
  274. },
  275. FT_GLYPH_FORMAT_OUTLINE,
  276. (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v,
  277. (FT_Renderer_TransformFunc)ft_smooth_transform,
  278. (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox,
  279. (FT_Renderer_SetModeFunc) ft_smooth_set_mode,
  280. (FT_Raster_Funcs*) &ft_grays_raster
  281. };
  282. /* END */