1 /***************************************************************************/ 2 /* */ 3 /* ftrend1.c */ 4 /* */ 5 /* The FreeType glyph rasterizer interface (body). */ 6 /* */ 7 /* Copyright 1996-2018 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 10 /* This file is part of the FreeType project, and may only be used, */ 11 /* modified, and distributed under the terms of the FreeType project */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 /* this file you indicate that you have read the license and */ 14 /* understand and accept it fully. */ 15 /* */ 16 /***************************************************************************/ 17 18 19 #include <ft2build.h> 20 #include FT_INTERNAL_DEBUG_H 21 #include FT_INTERNAL_OBJECTS_H 22 #include FT_OUTLINE_H 23 #include "ftrend1.h" 24 #include "ftraster.h" 25 #include "rastpic.h" 26 27 #include "rasterrs.h" 28 29 30 /* initialize renderer -- init its raster */ 31 static FT_Error ft_raster1_init(FT_Renderer render)32 ft_raster1_init( FT_Renderer render ) 33 { 34 render->clazz->raster_class->raster_reset( render->raster, NULL, 0 ); 35 36 return FT_Err_Ok; 37 } 38 39 40 /* set render-specific mode */ 41 static FT_Error ft_raster1_set_mode(FT_Renderer render,FT_ULong mode_tag,FT_Pointer data)42 ft_raster1_set_mode( FT_Renderer render, 43 FT_ULong mode_tag, 44 FT_Pointer data ) 45 { 46 /* we simply pass it to the raster */ 47 return render->clazz->raster_class->raster_set_mode( render->raster, 48 mode_tag, 49 data ); 50 } 51 52 53 /* transform a given glyph image */ 54 static FT_Error ft_raster1_transform(FT_Renderer render,FT_GlyphSlot slot,const FT_Matrix * matrix,const FT_Vector * delta)55 ft_raster1_transform( FT_Renderer render, 56 FT_GlyphSlot slot, 57 const FT_Matrix* matrix, 58 const FT_Vector* delta ) 59 { 60 FT_Error error = FT_Err_Ok; 61 62 63 if ( slot->format != render->glyph_format ) 64 { 65 error = FT_THROW( Invalid_Argument ); 66 goto Exit; 67 } 68 69 if ( matrix ) 70 FT_Outline_Transform( &slot->outline, matrix ); 71 72 if ( delta ) 73 FT_Outline_Translate( &slot->outline, delta->x, delta->y ); 74 75 Exit: 76 return error; 77 } 78 79 80 /* return the glyph's control box */ 81 static void ft_raster1_get_cbox(FT_Renderer render,FT_GlyphSlot slot,FT_BBox * cbox)82 ft_raster1_get_cbox( FT_Renderer render, 83 FT_GlyphSlot slot, 84 FT_BBox* cbox ) 85 { 86 FT_ZERO( cbox ); 87 88 if ( slot->format == render->glyph_format ) 89 FT_Outline_Get_CBox( &slot->outline, cbox ); 90 } 91 92 93 /* convert a slot's glyph image into a bitmap */ 94 static FT_Error ft_raster1_render(FT_Renderer render,FT_GlyphSlot slot,FT_Render_Mode mode,const FT_Vector * origin)95 ft_raster1_render( FT_Renderer render, 96 FT_GlyphSlot slot, 97 FT_Render_Mode mode, 98 const FT_Vector* origin ) 99 { 100 FT_Error error = FT_Err_Ok; 101 FT_Outline* outline = &slot->outline; 102 FT_Bitmap* bitmap = &slot->bitmap; 103 FT_Memory memory = render->root.memory; 104 FT_Pos x_shift = 0; 105 FT_Pos y_shift = 0; 106 107 FT_Raster_Params params; 108 109 110 /* check glyph image format */ 111 if ( slot->format != render->glyph_format ) 112 { 113 error = FT_THROW( Invalid_Argument ); 114 goto Exit; 115 } 116 117 /* check rendering mode */ 118 if ( mode != FT_RENDER_MODE_MONO ) 119 { 120 /* raster1 is only capable of producing monochrome bitmaps */ 121 return FT_THROW( Cannot_Render_Glyph ); 122 } 123 124 /* release old bitmap buffer */ 125 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) 126 { 127 FT_FREE( bitmap->buffer ); 128 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; 129 } 130 131 ft_glyphslot_preset_bitmap( slot, mode, origin ); 132 133 /* allocate new one */ 134 if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) ) 135 goto Exit; 136 137 slot->internal->flags |= FT_GLYPH_OWN_BITMAP; 138 139 x_shift = -slot->bitmap_left * 64; 140 y_shift = ( (FT_Int)bitmap->rows - slot->bitmap_top ) * 64; 141 142 if ( origin ) 143 { 144 x_shift += origin->x; 145 y_shift += origin->y; 146 } 147 148 /* translate outline to render it into the bitmap */ 149 if ( x_shift || y_shift ) 150 FT_Outline_Translate( outline, x_shift, y_shift ); 151 152 /* set up parameters */ 153 params.target = bitmap; 154 params.source = outline; 155 params.flags = FT_RASTER_FLAG_DEFAULT; 156 157 /* render outline into the bitmap */ 158 error = render->raster_render( render->raster, ¶ms ); 159 160 Exit: 161 if ( !error ) 162 /* everything is fine; the glyph is now officially a bitmap */ 163 slot->format = FT_GLYPH_FORMAT_BITMAP; 164 else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) 165 { 166 FT_FREE( bitmap->buffer ); 167 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; 168 } 169 170 if ( x_shift || y_shift ) 171 FT_Outline_Translate( outline, -x_shift, -y_shift ); 172 173 return error; 174 } 175 176 177 FT_DEFINE_RENDERER( 178 ft_raster1_renderer_class, 179 180 FT_MODULE_RENDERER, 181 sizeof ( FT_RendererRec ), 182 183 "raster1", 184 0x10000L, 185 0x20000L, 186 187 NULL, /* module specific interface */ 188 189 (FT_Module_Constructor)ft_raster1_init, /* module_init */ 190 (FT_Module_Destructor) NULL, /* module_done */ 191 (FT_Module_Requester) NULL, /* get_interface */ 192 193 FT_GLYPH_FORMAT_OUTLINE, 194 195 (FT_Renderer_RenderFunc) ft_raster1_render, /* render_glyph */ 196 (FT_Renderer_TransformFunc)ft_raster1_transform, /* transform_glyph */ 197 (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, /* get_glyph_cbox */ 198 (FT_Renderer_SetModeFunc) ft_raster1_set_mode, /* set_mode */ 199 200 (FT_Raster_Funcs*)&FT_STANDARD_RASTER_GET /* raster_class */ 201 ) 202 203 204 /* END */ 205