4 #include <SDL2/SDL_ttf.h>
40 TTF_Font* font = TTF_OpenFont(fontFile, size);
55 int padding = size / 8;
59 glm::ivec4* glyphRectangles =
new glm::ivec4[
m_regLength];
67 const char str[2] = {c,
'\0'};
70 TTF_SizeText(font, str, &glyphRectangles[i].z, &glyphRectangles[i].w);
74 unsigned int bestWidth = 0, bestHeight = 0, bestRows = 0;
75 std::vector<int>* bestPartition =
nullptr;
80 unsigned int rows = 1;
86 height = rows * (padding +
m_height) + padding;
102 delete[] trialPartition;
108 if(area >= width * height)
113 delete[] bestPartition;
116 bestPartition = trialPartition;
120 area = bestWidth * bestHeight;
127 delete[] trialPartition;
148 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bestWidth, bestHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE,
nullptr);
152 SDL_Color foreground = {255, 255, 255, 255};
157 for(
unsigned int row = 0; row < bestRows; row++)
161 for(
unsigned int column = 0; column < bestPartition[row].size(); column++)
164 int glyph = bestPartition[row][column];
167 SDL_Surface* glyphSurface =
174 unsigned int glyph_width = glyphSurface->pitch /
sizeof(
unsigned int);
176 unsigned int glyph_height = glyphSurface->h;
178 unsigned char* pixel_data = (
unsigned char*)glyphSurface->pixels;
181 unsigned int num_pixel_data = glyph_width * glyph_height;
183 for(
unsigned int i = 0; i < num_pixel_data; i += 4)
185 float alpha = pixel_data[i + 3] / 255.0f;
187 float gray = (
unsigned char)((
float)pixel_data[i] * alpha);
189 pixel_data[i] = gray;
190 pixel_data[i + 1] = gray;
191 pixel_data[i + 2] = gray;
195 glTexSubImage2D(GL_TEXTURE_2D, 0, xOff, bestHeight - yOff - 1 - glyphSurface->h, glyph_width,
196 glyph_height, GL_BGRA, GL_UNSIGNED_BYTE, pixel_data);
199 glyphRectangles[glyph].x = xOff;
200 glyphRectangles[glyph].y = yOff;
201 glyphRectangles[glyph].z = glyphSurface->w;
202 glyphRectangles[glyph].w = glyphSurface->h;
205 SDL_FreeSurface(glyphSurface);
206 glyphSurface =
nullptr;
208 xOff += glyphRectangles[glyph].z + padding;
214 int zero_index = padding - 1;
215 int* pureWhiteSquare =
new int[zero_index * zero_index];
218 memset(pureWhiteSquare, 0xffffffff, zero_index * zero_index *
sizeof(
int));
221 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, zero_index, zero_index, GL_RGBA, GL_UNSIGNED_BYTE, pureWhiteSquare);
224 delete[] pureWhiteSquare;
225 pureWhiteSquare =
nullptr;
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
236 for(
unsigned int i = 0; (
unsigned int)i <
m_regLength; i++)
242 (
float)glyphRectangles[i].x / (
float)bestWidth, (
float)glyphRectangles[i].y / (
float)bestHeight,
243 (
float)glyphRectangles[i].z / (
float)bestWidth, (
float)glyphRectangles[i].w / (
float)bestHeight);
250 glm::vec4(0.0f, 0.0f, (
float)zero_index / (
float)bestWidth, (
float)zero_index / (
float)bestHeight);
255 delete[] glyphRectangles;
256 delete[] bestPartition;
284 float columnWidth = 0.0f;
287 for(
int charIndex = 0; s[charIndex] != 0; charIndex++)
289 char c = s[charIndex];
294 if(size.x < columnWidth)
296 size.x = columnWidth;
316 if(size.x < columnWidth)
317 size.x = columnWidth;
322 std::vector<int>*
Font::createRows(glm::ivec4* rectangles,
int rectanglesLength,
int rows,
int padding,
int& width)
325 std::vector<int>* ret =
new std::vector<int>[rows]();
328 int* columnWidths =
new int[rows]();
330 for(
int i = 0; i < rows; i++)
332 columnWidths[i] = padding;
336 for(
int i = 0; i < rectanglesLength; i++)
340 for(
int rowIndexTest = 0; rowIndexTest < rows; rowIndexTest++)
343 if(columnWidths[rowIndexTest] < columnWidths[rowIndex])
344 rowIndex = rowIndexTest;
348 columnWidths[rowIndex] += rectangles[i].z + padding;
351 ret[rowIndex].push_back(i);
356 for(
int i = 0; i < rows; i++)
358 if(columnWidths[i] > width)
359 width = columnWidths[i];
362 delete[] columnWidths;