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