Mercurial > public > algo-animator
comparison main.c @ 15:e2fcfcb43fee
fix vertical character alignment
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Sun, 25 Jun 2023 16:28:13 +0100 |
parents | d055228ca9a6 |
children | 2ded5f1f544a |
comparison
equal
deleted
inserted
replaced
14:d055228ca9a6 | 15:e2fcfcb43fee |
---|---|
104 } | 104 } |
105 | 105 |
106 | 106 |
107 /* Render functions */ | 107 /* Render functions */ |
108 | 108 |
109 unsigned char* flipBitmapVertically(unsigned char* bitmap, int width, int height) { | |
110 unsigned char* flippedBitmap = (unsigned char*)malloc(width * height); | |
111 | |
112 for (int row = 0; row < height; row++) { | |
113 unsigned char* srcRow = bitmap + (row * width); | |
114 unsigned char* destRow = flippedBitmap + ((height - row - 1) * width); | |
115 memcpy(destRow, srcRow, width); | |
116 } | |
117 | |
118 return flippedBitmap; | |
119 } | |
120 | |
121 | |
109 void render_text(int x, int y, char* text) { | 122 void render_text(int x, int y, char* text) { |
110 | 123 for (const char *c = text; *c; c++) { |
111 // Get glyph index from character code | 124 |
112 FT_UInt glyph_index = FT_Get_Char_Index(ft_face, 'A'); | 125 // Get glyph index from character code |
113 | 126 FT_UInt glyph_index = FT_Get_Char_Index(ft_face, *c); |
114 if (glyph_index == 0) { | 127 |
115 fprintf(stderr, "Given character code has no glyph image in the face\n"); | 128 if (glyph_index == 0) { |
116 exit(1); | 129 fprintf(stderr, "Given character code has no glyph image in the face\n"); |
117 } | 130 exit(1); |
118 | 131 } |
119 // Load glyph image | 132 |
120 if (FT_Load_Glyph(ft_face, glyph_index, FT_LOAD_DEFAULT)) { | 133 // Load glyph image |
121 fprintf(stderr, "Failed to load glyph.\n"); | 134 if (FT_Load_Glyph(ft_face, glyph_index, FT_LOAD_DEFAULT)) { |
122 exit(1); | 135 fprintf(stderr, "Failed to load glyph.\n"); |
123 } | 136 exit(1); |
124 | 137 } |
125 // Render glyph | 138 |
126 if (FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL)) { | 139 // Render glyph |
127 fprintf(stderr, "Failed to render glyph.\n"); | 140 if (FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL)) { |
128 exit(1); | 141 fprintf(stderr, "Failed to render glyph.\n"); |
129 } | 142 exit(1); |
130 | 143 } |
131 FT_GlyphSlot slot = ft_face->glyph; | 144 |
132 FT_Bitmap* glyph_bitmap = &slot->bitmap; | 145 FT_GlyphSlot slot = ft_face->glyph; |
133 | 146 FT_Bitmap* glyph_bitmap = &slot->bitmap; |
134 glRasterPos2f(x, y); | 147 |
135 glDrawPixels( | 148 // Flip the bitmap vertically |
136 glyph_bitmap->width, | 149 unsigned char* flipped_bitmap = (unsigned char*)malloc(glyph_bitmap->width * glyph_bitmap->rows); |
137 glyph_bitmap->rows, | 150 |
138 GL_LUMINANCE, | 151 for (int row = 0; row < glyph_bitmap->rows; row++) { |
139 GL_UNSIGNED_BYTE, | 152 unsigned char* src_row = glyph_bitmap->buffer + (row * glyph_bitmap->width); |
140 glyph_bitmap->buffer | 153 unsigned char* dest_row = flipped_bitmap + ((glyph_bitmap->rows - row - 1) * glyph_bitmap->width); |
141 ); | 154 memcpy(dest_row, src_row, glyph_bitmap->width); |
155 } | |
156 | |
157 glyph_bitmap->buffer = flipped_bitmap; | |
158 | |
159 // Calculate the adjusted y position based on the glyph's bearing | |
160 int adjusted_y = y + (slot->bitmap_top - glyph_bitmap->rows); | |
161 | |
162 glRasterPos2f(x, adjusted_y); | |
163 glDrawPixels(glyph_bitmap->width, glyph_bitmap->rows, GL_LUMINANCE, GL_UNSIGNED_BYTE, glyph_bitmap->buffer); | |
164 | |
165 x += 15; | |
166 } | |
142 } | 167 } |
143 | 168 |
144 | 169 |
145 void display() { | 170 void display() { |
146 glClear(GL_COLOR_BUFFER_BIT); | 171 glClear(GL_COLOR_BUFFER_BIT); |
172 | 197 |
173 sprintf(text, "Algorithm: %s", algos[selected_algo]); | 198 sprintf(text, "Algorithm: %s", algos[selected_algo]); |
174 render_text(20, WINDOW_HEIGHT - 50, text); | 199 render_text(20, WINDOW_HEIGHT - 50, text); |
175 | 200 |
176 sprintf(text, "Number of elements: %i", arr_size); | 201 sprintf(text, "Number of elements: %i", arr_size); |
177 render_text(20, WINDOW_HEIGHT - 75, text); | 202 render_text(20, WINDOW_HEIGHT - 80, text); |
178 | 203 |
179 sprintf(text, "Iterations: %i", iter_counter); | 204 sprintf(text, "Iterations: %i", iter_counter); |
180 render_text(20, WINDOW_HEIGHT - 100, text); | 205 render_text(20, WINDOW_HEIGHT - 110, text); |
181 | 206 |
182 render_text(20, OFFSET - 50, "Press 'a' or 's' to select an algorithm"); | 207 render_text(20, OFFSET - 50, "Press a or s to select an algorithm"); |
183 render_text(20, OFFSET - 75, "Press 'enter' to run the algorithm"); | 208 render_text(20, OFFSET - 80, "Press enter to run the algorithm"); |
184 render_text(20, OFFSET - 100, "Press 'r' to reset array"); | 209 render_text(20, OFFSET - 110, "Press r to reset array"); |
185 | 210 |
186 glutSwapBuffers(); | 211 glutSwapBuffers(); |
187 } | 212 } |
188 | 213 |
189 | 214 |
258 /* | 283 /* |
259 * Creates projection matrix | 284 * Creates projection matrix |
260 * x increases from left to right (0 to WINDOW_WIDTH) | 285 * x increases from left to right (0 to WINDOW_WIDTH) |
261 * y increases from bottom to top (0 to WINDOW_HEIGHT) | 286 * y increases from bottom to top (0 to WINDOW_HEIGHT) |
262 */ | 287 */ |
288 | |
263 gluOrtho2D(0, WINDOW_WIDTH, 0, WINDOW_HEIGHT); | 289 gluOrtho2D(0, WINDOW_WIDTH, 0, WINDOW_HEIGHT); |
264 | 290 |
265 /* | 291 /* |
266 * This fucking line... I spent a day rendering random symbols | 292 * This fucking line... I spent a day rendering weird symbols |
267 * because the padding that adds FreeType to each row of the bitmap | 293 * because the padding that adds FreeType to each row of the bitmap |
268 * does not match the padding expected by GL. | 294 * does not match the padding expected by GL. |
269 */ | 295 */ |
270 | 296 |
271 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | 297 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
313 glutIdleFunc(idle); | 339 glutIdleFunc(idle); |
314 glutMainLoop(); | 340 glutMainLoop(); |
315 | 341 |
316 free(arr); | 342 free(arr); |
317 | 343 |
344 FT_Done_Face(ft_face); | |
345 FT_Done_FreeType(ft_library); | |
346 | |
318 return 0; | 347 return 0; |
319 } | 348 } |