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 |
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 |
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 |
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 |
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 |
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 | |