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 }