Added Backend_PrepareToDrawGlyphs
This is to reduce OpenGL context changes, and help pave the way for glyph-batching
This commit is contained in:
parent
fa8ab56e93
commit
639039ce3a
6 changed files with 93 additions and 40 deletions
|
@ -28,6 +28,7 @@ void Backend_ColourFill(Backend_Surface *surface, const RECT *rect, unsigned cha
|
||||||
BOOL Backend_SupportsSubpixelGlyphs(void);
|
BOOL Backend_SupportsSubpixelGlyphs(void);
|
||||||
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch, FontPixelMode pixel_mode);
|
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch, FontPixelMode pixel_mode);
|
||||||
void Backend_UnloadGlyph(Backend_Glyph *glyph);
|
void Backend_UnloadGlyph(Backend_Glyph *glyph);
|
||||||
void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, long y, const unsigned char *colours);
|
void Backend_PrepareToDrawGlyphs(Backend_Surface *destination_surface, const unsigned char *colour_channels);
|
||||||
|
void Backend_DrawGlyph(Backend_Glyph *glyph, long x, long y);
|
||||||
void Backend_HandleRenderTargetLoss(void);
|
void Backend_HandleRenderTargetLoss(void);
|
||||||
void Backend_HandleWindowResize(void);
|
void Backend_HandleWindowResize(void);
|
||||||
|
|
|
@ -95,6 +95,9 @@ static RenderMode last_render_mode;
|
||||||
|
|
||||||
static Backend_Surface framebuffer;
|
static Backend_Surface framebuffer;
|
||||||
|
|
||||||
|
static unsigned char glyph_colour_channels[3];
|
||||||
|
static Backend_Surface *glyph_destination_surface;
|
||||||
|
|
||||||
#ifdef USE_OPENGLES2
|
#ifdef USE_OPENGLES2
|
||||||
static const GLchar *vertex_shader_plain = " \
|
static const GLchar *vertex_shader_plain = " \
|
||||||
#version 100\n \
|
#version 100\n \
|
||||||
|
@ -976,7 +979,17 @@ void Backend_UnloadGlyph(Backend_Glyph *glyph)
|
||||||
free(glyph);
|
free(glyph);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, long y, const unsigned char *colours)
|
void Backend_PrepareToDrawGlyphs(Backend_Surface *destination_surface, const unsigned char *colour_channels)
|
||||||
|
{
|
||||||
|
if (destination_surface == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glyph_destination_surface = destination_surface;
|
||||||
|
|
||||||
|
memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Backend_DrawGlyph(Backend_Glyph *glyph, long x, long y)
|
||||||
{
|
{
|
||||||
static Backend_Surface *last_surface;
|
static Backend_Surface *last_surface;
|
||||||
static Backend_Glyph *last_glyph;
|
static Backend_Glyph *last_glyph;
|
||||||
|
@ -984,36 +997,36 @@ void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, l
|
||||||
static unsigned char last_green;
|
static unsigned char last_green;
|
||||||
static unsigned char last_blue;
|
static unsigned char last_blue;
|
||||||
|
|
||||||
if (glyph == NULL || surface == NULL)
|
if (glyph == NULL || glyph_destination_surface == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const RenderMode render_mode = (glyph->pixel_mode == FONT_PIXEL_MODE_LCD ? MODE_DRAW_GLYPH_LCD : MODE_DRAW_GLYPH);
|
const RenderMode render_mode = (glyph->pixel_mode == FONT_PIXEL_MODE_LCD ? MODE_DRAW_GLYPH_LCD : MODE_DRAW_GLYPH);
|
||||||
|
|
||||||
if (last_render_mode != render_mode || last_surface != surface || last_glyph != glyph || last_red != colours[0] || last_green != colours[1] || last_blue != colours[2])
|
if (last_render_mode != render_mode || last_surface != glyph_destination_surface || last_glyph != glyph || last_red != glyph_colour_channels[0] || last_green != glyph_colour_channels[1] || last_blue != glyph_colour_channels[2])
|
||||||
{
|
{
|
||||||
FlushVertexBuffer();
|
FlushVertexBuffer();
|
||||||
|
|
||||||
last_render_mode = render_mode;
|
last_render_mode = render_mode;
|
||||||
last_surface = surface;
|
last_surface = glyph_destination_surface;
|
||||||
last_glyph = glyph;
|
last_glyph = glyph;
|
||||||
last_red = colours[0];
|
last_red = glyph_colour_channels[0];
|
||||||
last_green = colours[1];
|
last_green = glyph_colour_channels[1];
|
||||||
last_blue = colours[2];
|
last_blue = glyph_colour_channels[2];
|
||||||
|
|
||||||
if (glyph->pixel_mode == FONT_PIXEL_MODE_LCD)
|
if (glyph->pixel_mode == FONT_PIXEL_MODE_LCD)
|
||||||
{
|
{
|
||||||
glUseProgram(program_glyph_subpixel_part2);
|
glUseProgram(program_glyph_subpixel_part2);
|
||||||
glUniform4f(program_glyph_subpixel_part2_uniform_colour, colours[0] / 255.0f, colours[1] / 255.0f, colours[2] / 255.0f, 1.0f);
|
glUniform4f(program_glyph_subpixel_part2_uniform_colour, glyph_colour_channels[0] / 255.0f, glyph_colour_channels[1] / 255.0f, glyph_colour_channels[2] / 255.0f, 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glUseProgram(program_glyph_normal);
|
glUseProgram(program_glyph_normal);
|
||||||
glUniform4f(program_glyph_normal_uniform_colour, colours[0] / 255.0f, colours[1] / 255.0f, colours[2] / 255.0f, 1.0f);
|
glUniform4f(program_glyph_normal_uniform_colour, glyph_colour_channels[0] / 255.0f, glyph_colour_channels[1] / 255.0f, glyph_colour_channels[2] / 255.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Point our framebuffer to the destination texture
|
// Point our framebuffer to the destination texture
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, surface->texture_id, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glyph_destination_surface->texture_id, 0);
|
||||||
glViewport(0, 0, surface->width, surface->height);
|
glViewport(0, 0, glyph_destination_surface->width, glyph_destination_surface->height);
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
@ -1023,10 +1036,10 @@ void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, l
|
||||||
glBindTexture(GL_TEXTURE_2D, glyph->texture_id);
|
glBindTexture(GL_TEXTURE_2D, glyph->texture_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const GLfloat vertex_left = (x * (2.0f / surface->width)) - 1.0f;
|
const GLfloat vertex_left = (x * (2.0f / glyph_destination_surface->width)) - 1.0f;
|
||||||
const GLfloat vertex_right = ((x + glyph->width) * (2.0f / surface->width)) - 1.0f;
|
const GLfloat vertex_right = ((x + glyph->width) * (2.0f / glyph_destination_surface->width)) - 1.0f;
|
||||||
const GLfloat vertex_top = (y * (2.0f / surface->height)) - 1.0f;
|
const GLfloat vertex_top = (y * (2.0f / glyph_destination_surface->height)) - 1.0f;
|
||||||
const GLfloat vertex_bottom = ((y + glyph->height) * (2.0f / surface->height)) - 1.0f;
|
const GLfloat vertex_bottom = ((y + glyph->height) * (2.0f / glyph_destination_surface->height)) - 1.0f;
|
||||||
|
|
||||||
VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot();
|
VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot();
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@ static SDL_Surface *window_sdlsurface;
|
||||||
|
|
||||||
static Backend_Surface framebuffer;
|
static Backend_Surface framebuffer;
|
||||||
|
|
||||||
|
static unsigned char glyph_colour_channels[3];
|
||||||
|
static SDL_Surface *glyph_destination_sdlsurface;
|
||||||
|
|
||||||
static void RectToSDLRect(const RECT *rect, SDL_Rect *sdl_rect)
|
static void RectToSDLRect(const RECT *rect, SDL_Rect *sdl_rect)
|
||||||
{
|
{
|
||||||
sdl_rect->x = (int)rect->left;
|
sdl_rect->x = (int)rect->left;
|
||||||
|
@ -243,9 +246,19 @@ void Backend_UnloadGlyph(Backend_Glyph *glyph)
|
||||||
free(glyph);
|
free(glyph);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, long y, const unsigned char *colours)
|
void Backend_PrepareToDrawGlyphs(Backend_Surface *destination_surface, const unsigned char *colour_channels)
|
||||||
{
|
{
|
||||||
if (glyph == NULL || surface == NULL)
|
if (destination_surface == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glyph_destination_sdlsurface = destination_surface->sdlsurface;
|
||||||
|
|
||||||
|
memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Backend_DrawGlyph(Backend_Glyph *glyph, long x, long y)
|
||||||
|
{
|
||||||
|
if (glyph == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
|
@ -254,9 +267,9 @@ void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, l
|
||||||
rect.w = glyph->sdlsurface->w;
|
rect.w = glyph->sdlsurface->w;
|
||||||
rect.h = glyph->sdlsurface->h;
|
rect.h = glyph->sdlsurface->h;
|
||||||
|
|
||||||
SDL_SetSurfaceColorMod(glyph->sdlsurface, colours[0], colours[1], colours[2]);
|
SDL_SetSurfaceColorMod(glyph->sdlsurface, glyph_colour_channels[0], glyph_colour_channels[1], glyph_colour_channels[2]);
|
||||||
|
|
||||||
SDL_BlitSurface(glyph->sdlsurface, NULL, surface->sdlsurface, &rect);
|
SDL_BlitSurface(glyph->sdlsurface, NULL, glyph_destination_sdlsurface, &rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend_HandleRenderTargetLoss(void)
|
void Backend_HandleRenderTargetLoss(void)
|
||||||
|
|
|
@ -42,6 +42,8 @@ static Backend_Surface framebuffer;
|
||||||
|
|
||||||
static Backend_Surface *surface_list_head;
|
static Backend_Surface *surface_list_head;
|
||||||
|
|
||||||
|
static unsigned char glyph_colour_channels[3];
|
||||||
|
|
||||||
static void RectToSDLRect(const RECT *rect, SDL_Rect *sdl_rect)
|
static void RectToSDLRect(const RECT *rect, SDL_Rect *sdl_rect)
|
||||||
{
|
{
|
||||||
sdl_rect->x = (int)rect->left;
|
sdl_rect->x = (int)rect->left;
|
||||||
|
@ -376,20 +378,29 @@ void Backend_UnloadGlyph(Backend_Glyph *glyph)
|
||||||
free(glyph);
|
free(glyph);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, long y, const unsigned char *colours)
|
void Backend_PrepareToDrawGlyphs(Backend_Surface *destination_surface, const unsigned char *colour_channels)
|
||||||
|
{
|
||||||
|
if (destination_surface == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SDL_SetRenderTarget(renderer, destination_surface->texture);
|
||||||
|
|
||||||
|
memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Backend_DrawGlyph(Backend_Glyph *glyph, long x, long y)
|
||||||
{
|
{
|
||||||
// The SDL_Texture side of things uses alpha, not a colour-key, so the bug where the font is blended
|
// The SDL_Texture side of things uses alpha, not a colour-key, so the bug where the font is blended
|
||||||
// with the colour key doesn't occur.
|
// with the colour key doesn't occur.
|
||||||
|
|
||||||
if (glyph == NULL || surface == NULL)
|
if (glyph == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SDL_Rect destination_rect = {(int)x, (int)y, (int)glyph->width, (int)glyph->height};
|
SDL_Rect destination_rect = {(int)x, (int)y, (int)glyph->width, (int)glyph->height};
|
||||||
|
|
||||||
// Blit the texture
|
// Blit the texture
|
||||||
SDL_SetTextureColorMod(glyph->texture, colours[0], colours[1], colours[2]);
|
SDL_SetTextureColorMod(glyph->texture, glyph_colour_channels[0], glyph_colour_channels[1], glyph_colour_channels[2]);
|
||||||
SDL_SetTextureBlendMode(glyph->texture, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(glyph->texture, SDL_BLENDMODE_BLEND);
|
||||||
SDL_SetRenderTarget(renderer, surface->texture);
|
|
||||||
SDL_RenderCopy(renderer, glyph->texture, NULL, &destination_rect);
|
SDL_RenderCopy(renderer, glyph->texture, NULL, &destination_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,9 @@ static SDL_Surface *window_sdlsurface;
|
||||||
static SDL_Surface *framebuffer_sdlsurface;
|
static SDL_Surface *framebuffer_sdlsurface;
|
||||||
static Backend_Surface framebuffer;
|
static Backend_Surface framebuffer;
|
||||||
|
|
||||||
|
static unsigned char glyph_colour_channels[3];
|
||||||
|
static Backend_Surface *glyph_destination_surface;
|
||||||
|
|
||||||
Backend_Surface* Backend_Init(const char *title, int width, int height, BOOL fullscreen)
|
Backend_Surface* Backend_Init(const char *title, int width, int height, BOOL fullscreen)
|
||||||
{
|
{
|
||||||
window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0);
|
window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0);
|
||||||
|
@ -371,28 +374,38 @@ void Backend_UnloadGlyph(Backend_Glyph *glyph)
|
||||||
free(glyph);
|
free(glyph);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, long y, const unsigned char *colours)
|
void Backend_PrepareToDrawGlyphs(Backend_Surface *destination_surface, const unsigned char *colour_channels)
|
||||||
{
|
{
|
||||||
if (glyph == NULL || surface == NULL)
|
if (destination_surface == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glyph_destination_surface = destination_surface;
|
||||||
|
|
||||||
|
memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Backend_DrawGlyph(Backend_Glyph *glyph, long x, long y)
|
||||||
|
{
|
||||||
|
if (glyph == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (glyph->pixel_mode)
|
switch (glyph->pixel_mode)
|
||||||
{
|
{
|
||||||
case FONT_PIXEL_MODE_LCD:
|
case FONT_PIXEL_MODE_LCD:
|
||||||
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, surface->height); ++iy)
|
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, glyph_destination_surface->height); ++iy)
|
||||||
{
|
{
|
||||||
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, surface->width); ++ix)
|
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, glyph_destination_surface->width); ++ix)
|
||||||
{
|
{
|
||||||
const float *font_pixel = (float*)glyph->pixels + (iy * glyph->width + ix) * 3;
|
const float *font_pixel = (float*)glyph->pixels + (iy * glyph->width + ix) * 3;
|
||||||
|
|
||||||
if (font_pixel[0] || font_pixel[1] || font_pixel[2])
|
if (font_pixel[0] || font_pixel[1] || font_pixel[2])
|
||||||
{
|
{
|
||||||
unsigned char *bitmap_pixel = surface->pixels + (y + iy) * surface->pitch + (x + ix) * 3;
|
unsigned char *bitmap_pixel = glyph_destination_surface->pixels + (y + iy) * glyph_destination_surface->pitch + (x + ix) * 3;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < 3; ++j)
|
for (unsigned int j = 0; j < 3; ++j)
|
||||||
{
|
{
|
||||||
const float alpha = font_pixel[j];
|
const float alpha = font_pixel[j];
|
||||||
bitmap_pixel[j] = (unsigned char)((colours[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha))); // Alpha blending
|
bitmap_pixel[j] = (unsigned char)((glyph_colour_channels[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha))); // Alpha blending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,18 +414,18 @@ void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, l
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FONT_PIXEL_MODE_GRAY:
|
case FONT_PIXEL_MODE_GRAY:
|
||||||
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, surface->height); ++iy)
|
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, glyph_destination_surface->height); ++iy)
|
||||||
{
|
{
|
||||||
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, surface->width); ++ix)
|
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, glyph_destination_surface->width); ++ix)
|
||||||
{
|
{
|
||||||
const float alpha = ((float*)glyph->pixels)[iy * glyph->width + ix];
|
const float alpha = ((float*)glyph->pixels)[iy * glyph->width + ix];
|
||||||
|
|
||||||
if (alpha)
|
if (alpha)
|
||||||
{
|
{
|
||||||
unsigned char *bitmap_pixel = surface->pixels + (y + iy) * surface->pitch + (x + ix) * 3;
|
unsigned char *bitmap_pixel = glyph_destination_surface->pixels + (y + iy) * glyph_destination_surface->pitch + (x + ix) * 3;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < 3; ++j)
|
for (unsigned int j = 0; j < 3; ++j)
|
||||||
bitmap_pixel[j] = (unsigned char)((colours[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha))); // Alpha blending
|
bitmap_pixel[j] = (unsigned char)((glyph_colour_channels[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha))); // Alpha blending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,16 +433,16 @@ void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, l
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FONT_PIXEL_MODE_MONO:
|
case FONT_PIXEL_MODE_MONO:
|
||||||
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, surface->height); ++iy)
|
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, glyph_destination_surface->height); ++iy)
|
||||||
{
|
{
|
||||||
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, surface->width); ++ix)
|
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, glyph_destination_surface->width); ++ix)
|
||||||
{
|
{
|
||||||
if (((unsigned char*)glyph->pixels)[iy * glyph->width + ix])
|
if (((unsigned char*)glyph->pixels)[iy * glyph->width + ix])
|
||||||
{
|
{
|
||||||
unsigned char *bitmap_pixel = surface->pixels + (y + iy) * surface->pitch + (x + ix) * 3;
|
unsigned char *bitmap_pixel = glyph_destination_surface->pixels + (y + iy) * glyph_destination_surface->pitch + (x + ix) * 3;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < 3; ++j)
|
for (unsigned int j = 0; j < 3; ++j)
|
||||||
bitmap_pixel[j] = colours[j];
|
bitmap_pixel[j] = glyph_colour_channels[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1114,7 +1114,9 @@ void DrawText(FontObject *font_object, Backend_Surface *surface, int x, int y, u
|
||||||
{
|
{
|
||||||
if (font_object != NULL)
|
if (font_object != NULL)
|
||||||
{
|
{
|
||||||
const unsigned char colours[3] = {(unsigned char)colour, (unsigned char)(colour >> 8), (unsigned char)(colour >> 16)};
|
const unsigned char colour_channels[3] = {(unsigned char)colour, (unsigned char)(colour >> 8), (unsigned char)(colour >> 16)};
|
||||||
|
|
||||||
|
Backend_PrepareToDrawGlyphs(surface, colour_channels);
|
||||||
|
|
||||||
unsigned int pen_x = 0;
|
unsigned int pen_x = 0;
|
||||||
|
|
||||||
|
@ -1139,7 +1141,7 @@ void DrawText(FontObject *font_object, Backend_Surface *surface, int x, int y, u
|
||||||
const int letter_y = y + glyph->y;
|
const int letter_y = y + glyph->y;
|
||||||
|
|
||||||
if (glyph->backend != NULL)
|
if (glyph->backend != NULL)
|
||||||
Backend_DrawGlyph(surface, glyph->backend, letter_x, letter_y, colours);
|
Backend_DrawGlyph(glyph->backend, letter_x, letter_y);
|
||||||
|
|
||||||
pen_x += glyph->x_advance;
|
pen_x += glyph->x_advance;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue