mirror of https://github.com/OpenRCT2/OpenRCT2.git
Add insetting and outlining to OpenGL TTF rendering
This commit is contained in:
parent
6162ff9b00
commit
f64706e1d9
|
@ -4,6 +4,7 @@ const int MASK_REMAP_COUNT = 3;
|
|||
const int FLAG_NO_TEXTURE = (1 << 2);
|
||||
const int FLAG_MASK = (1 << 3);
|
||||
const int FLAG_CROSS_HATCH = (1 << 4);
|
||||
const int FLAG_TTF_TEXT = (1 << 5);
|
||||
|
||||
uniform usampler2DArray uTexture;
|
||||
uniform usampler2D uPaletteTex;
|
||||
|
@ -41,7 +42,14 @@ void main()
|
|||
{
|
||||
discard;
|
||||
}
|
||||
texel += fColour;
|
||||
if ((fFlags & FLAG_TTF_TEXT) == 0)
|
||||
{
|
||||
texel += fColour;
|
||||
}
|
||||
else
|
||||
{
|
||||
texel = fColour;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -118,6 +118,7 @@ struct DrawRectCommand
|
|||
FLAG_NO_TEXTURE = (1u << 2u),
|
||||
FLAG_MASK = (1u << 3u),
|
||||
FLAG_CROSS_HATCH = (1u << 4u),
|
||||
FLAG_TTF_TEXT = (1u << 5u),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
# include <SDL.h>
|
||||
# include <algorithm>
|
||||
# include <array>
|
||||
# include <cmath>
|
||||
# include <openrct2-ui/interface/Window.h>
|
||||
# include <openrct2/Intro.h>
|
||||
|
@ -109,8 +110,9 @@ public:
|
|||
DrawPixelInfo* dpi, int32_t x, int32_t y, const ImageId maskImage, const ImageId colourImage) override;
|
||||
void DrawSpriteSolid(DrawPixelInfo* dpi, const ImageId image, int32_t x, int32_t y, uint8_t colour) override;
|
||||
void DrawGlyph(DrawPixelInfo* dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& palette) override;
|
||||
void DrawBitmap(
|
||||
DrawPixelInfo* dpi, ImageIndex image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y) override;
|
||||
void DrawTTFBitmap(
|
||||
DrawPixelInfo* dpi, TextDrawInfo* info, ImageIndex image, const void* pixels, int32_t width, int32_t height, int32_t x,
|
||||
int32_t y) override;
|
||||
|
||||
void FlushCommandBuffers();
|
||||
|
||||
|
@ -906,8 +908,9 @@ void OpenGLDrawingContext::DrawGlyph(DrawPixelInfo* dpi, const ImageId image, in
|
|||
command.depth = _drawCount++;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawBitmap(
|
||||
DrawPixelInfo* dpi, ImageIndex image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y)
|
||||
void OpenGLDrawingContext::DrawTTFBitmap(
|
||||
DrawPixelInfo* dpi, TextDrawInfo* info, ImageIndex image, const void* pixels, int32_t width, int32_t height, int32_t x,
|
||||
int32_t y)
|
||||
{
|
||||
CalculcateClipping(dpi);
|
||||
|
||||
|
@ -937,16 +940,53 @@ void OpenGLDrawingContext::DrawBitmap(
|
|||
right += _offsetX;
|
||||
bottom += _offsetY;
|
||||
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
if (info->flags & TEXT_DRAW_FLAG_OUTLINE)
|
||||
{
|
||||
std::array<ivec4, 4> boundsArr = { {
|
||||
{ left + 1, top, right + 1, bottom },
|
||||
{ left - 1, top, right - 1, bottom },
|
||||
{ left, top + 1, right, bottom + 1 },
|
||||
{ left, top - 1, right, bottom - 1 },
|
||||
} };
|
||||
for (auto b : boundsArr)
|
||||
{
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture.index;
|
||||
command.texColourBounds = texture.normalizedBounds;
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.flags = DrawRectCommand::FLAG_TTF_TEXT;
|
||||
command.colour = info->palette[3];
|
||||
command.bounds = b;
|
||||
command.depth = _drawCount++;
|
||||
}
|
||||
}
|
||||
if (info->flags & TEXT_DRAW_FLAG_INSET)
|
||||
{
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture.index;
|
||||
command.texColourBounds = texture.normalizedBounds;
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.flags = DrawRectCommand::FLAG_TTF_TEXT;
|
||||
command.colour = info->palette[3];
|
||||
command.bounds = { left + 1, top + 1, right + 1, bottom + 1 };
|
||||
command.depth = _drawCount++;
|
||||
}
|
||||
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture.index;
|
||||
command.texColourBounds = texture.normalizedBounds;
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.flags = 0;
|
||||
command.colour = 0;
|
||||
command.flags = DrawRectCommand::FLAG_TTF_TEXT;
|
||||
command.colour = info->palette[1];
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.depth = _drawCount++;
|
||||
}
|
||||
|
|
|
@ -28,18 +28,6 @@
|
|||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
TEXT_DRAW_FLAG_INSET = 1 << 0,
|
||||
TEXT_DRAW_FLAG_OUTLINE = 1 << 1,
|
||||
TEXT_DRAW_FLAG_DARK = 1 << 2,
|
||||
TEXT_DRAW_FLAG_EXTRA_DARK = 1 << 3,
|
||||
TEXT_DRAW_FLAG_NO_FORMATTING = 1 << 28,
|
||||
TEXT_DRAW_FLAG_Y_OFFSET_EFFECT = 1 << 29,
|
||||
TEXT_DRAW_FLAG_TTF = 1 << 30,
|
||||
TEXT_DRAW_FLAG_NO_DRAW = 1u << 31
|
||||
};
|
||||
|
||||
static int32_t TTFGetStringWidth(std::string_view text, FontStyle fontStyle, bool noFormatting);
|
||||
|
||||
/**
|
||||
|
@ -490,20 +478,6 @@ void DrawNewsTicker(
|
|||
}
|
||||
}
|
||||
|
||||
struct TextDrawInfo
|
||||
{
|
||||
int32_t startX;
|
||||
int32_t startY;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t maxX;
|
||||
int32_t maxY;
|
||||
int32_t flags;
|
||||
uint8_t palette[8];
|
||||
::FontStyle FontStyle;
|
||||
const int8_t* y_offset;
|
||||
};
|
||||
|
||||
static void TTFDrawCharacterSprite(DrawPixelInfo& dpi, int32_t codepoint, TextDrawInfo* info)
|
||||
{
|
||||
int32_t characterWidth = FontSpriteGetCodepointWidth(info->FontStyle, codepoint);
|
||||
|
@ -563,29 +537,17 @@ static void TTFDrawStringRawTTF(DrawPixelInfo& dpi, std::string_view text, TextD
|
|||
int32_t drawY = info->y + fontDesc->offset_y;
|
||||
int32_t width = surface->w;
|
||||
int32_t height = surface->h;
|
||||
bool use_hinting = gConfigFonts.EnableHinting && fontDesc->hinting_threshold > 0;
|
||||
|
||||
if (OpenRCT2::GetContext()->GetDrawingEngineType() == DrawingEngine::OpenGL)
|
||||
{
|
||||
auto pixels = reinterpret_cast<uint8_t*>(const_cast<void*>(surface->pixels));
|
||||
auto pixelsLen = static_cast<size_t>(surface->pitch) * surface->h;
|
||||
for (size_t pp = 0; pp < pixelsLen; pp++)
|
||||
{
|
||||
if (pixels[pp] != 0)
|
||||
{
|
||||
pixels[pp] = colour;
|
||||
}
|
||||
else
|
||||
{
|
||||
pixels[pp] = PALETTE_INDEX_0;
|
||||
}
|
||||
}
|
||||
|
||||
// if(use_hinting) return; // Not implemented yet.
|
||||
auto baseId = uint32_t(0x7FFFF) - 1024;
|
||||
auto imageId = baseId + _ttfGlId;
|
||||
auto drawingEngine = dpi.DrawingEngine;
|
||||
auto drawingContext = drawingEngine->GetDrawingContext();
|
||||
drawingEngine->InvalidateImage(imageId);
|
||||
drawingContext->DrawBitmap(&dpi, imageId, surface->pixels, surface->pitch, surface->h, drawX, drawY);
|
||||
drawingContext->DrawTTFBitmap(&dpi, info, imageId, surface->pixels, surface->pitch, surface->h, drawX, drawY);
|
||||
|
||||
_ttfGlId++;
|
||||
if (_ttfGlId >= 1023)
|
||||
|
@ -670,7 +632,6 @@ static void TTFDrawStringRawTTF(DrawPixelInfo& dpi, std::string_view text, TextD
|
|||
|
||||
dst = dst_orig;
|
||||
src = src_orig;
|
||||
bool use_hinting = gConfigFonts.EnableHinting && fontDesc->hinting_threshold > 0;
|
||||
for (int32_t yy = 0; yy < height; yy++)
|
||||
{
|
||||
for (int32_t xx = 0; xx < width; xx++)
|
||||
|
@ -692,9 +653,7 @@ static void TTFDrawStringRawTTF(DrawPixelInfo& dpi, std::string_view text, TextD
|
|||
// Simulate font hinting by shading the background colour instead.
|
||||
if (info->flags & TEXT_DRAW_FLAG_OUTLINE)
|
||||
{
|
||||
// As outlines are black, these texts should always use a darker shade
|
||||
// of the foreground colour for font hinting.
|
||||
*dst = BlendColours(colour, PALETTE_INDEX_0);
|
||||
*dst = BlendColours(colour, info->palette[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -132,6 +132,32 @@ struct DrawPixelInfo
|
|||
DrawPixelInfo Crop(const ScreenCoordsXY& pos, const ScreenSize& size) const;
|
||||
};
|
||||
|
||||
struct TextDrawInfo
|
||||
{
|
||||
int32_t startX;
|
||||
int32_t startY;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t maxX;
|
||||
int32_t maxY;
|
||||
int32_t flags;
|
||||
uint8_t palette[8];
|
||||
::FontStyle FontStyle;
|
||||
const int8_t* y_offset;
|
||||
};
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
TEXT_DRAW_FLAG_INSET = 1 << 0,
|
||||
TEXT_DRAW_FLAG_OUTLINE = 1 << 1,
|
||||
TEXT_DRAW_FLAG_DARK = 1 << 2,
|
||||
TEXT_DRAW_FLAG_EXTRA_DARK = 1 << 3,
|
||||
TEXT_DRAW_FLAG_NO_FORMATTING = 1 << 28,
|
||||
TEXT_DRAW_FLAG_Y_OFFSET_EFFECT = 1 << 29,
|
||||
TEXT_DRAW_FLAG_TTF = 1 << 30,
|
||||
TEXT_DRAW_FLAG_NO_DRAW = 1u << 31
|
||||
};
|
||||
|
||||
struct RCTG1Element
|
||||
{
|
||||
uint32_t offset; // 0x00 note: uint32_t always!
|
||||
|
|
|
@ -32,9 +32,9 @@ namespace OpenRCT2::Drawing
|
|||
virtual void DrawSpriteSolid(DrawPixelInfo* dpi, const ImageId image, int32_t x, int32_t y, uint8_t colour) abstract;
|
||||
virtual void DrawGlyph(
|
||||
DrawPixelInfo* dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& palette) abstract;
|
||||
virtual void DrawBitmap(
|
||||
DrawPixelInfo* dpi, ImageIndex image, const void* pixels, int32_t width, int32_t height, int32_t x,
|
||||
int32_t y) abstract;
|
||||
virtual void DrawTTFBitmap(
|
||||
DrawPixelInfo* dpi, TextDrawInfo* info, ImageIndex image, const void* pixels, int32_t width, int32_t height,
|
||||
int32_t x, int32_t y) abstract;
|
||||
};
|
||||
|
||||
} // namespace OpenRCT2::Drawing
|
||||
|
|
|
@ -365,12 +365,7 @@ static TTFSurface* TTFRender(TTF_Font* font, std::string_view text)
|
|||
{
|
||||
thread_local std::string buffer;
|
||||
buffer.assign(text);
|
||||
if (TTF_GetFontHinting(font) != 0)
|
||||
{
|
||||
return TTF_RenderUTF8_Shaded(font, buffer.c_str(), 0x000000FF, 0x000000FF);
|
||||
}
|
||||
|
||||
return TTF_RenderUTF8_Solid(font, buffer.c_str(), 0x000000FF);
|
||||
return TTF_RenderUTF8(font, buffer.c_str(), TTF_GetFontHinting(font) != 0);
|
||||
}
|
||||
|
||||
void TTFFreeSurface(TTFSurface* surface)
|
||||
|
|
|
@ -38,8 +38,7 @@ int TTF_Init(void);
|
|||
TTF_Font* TTF_OpenFont(const char* file, int ptsize);
|
||||
int TTF_GlyphIsProvided(const TTF_Font* font, codepoint_t ch);
|
||||
int TTF_SizeUTF8(TTF_Font* font, const char* text, int* w, int* h);
|
||||
TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, uint32_t colour);
|
||||
TTFSurface* TTF_RenderUTF8_Shaded(TTF_Font* font, const char* text, uint32_t fg, uint32_t bg);
|
||||
TTFSurface* TTF_RenderUTF8(TTF_Font* font, const char* text, bool shaded);
|
||||
void TTF_CloseFont(TTF_Font* font);
|
||||
void TTF_SetFontHinting(TTF_Font* font, int hinting);
|
||||
int TTF_GetFontHinting(const TTF_Font* font);
|
||||
|
|
|
@ -1263,7 +1263,7 @@ int TTF_SizeUTF8(TTF_Font* font, const char* text, int* w, int* h)
|
|||
return status;
|
||||
}
|
||||
|
||||
TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, [[maybe_unused]] uint32_t colour)
|
||||
TTFSurface* TTF_RenderUTF8(TTF_Font* font, const char* text, bool shaded)
|
||||
{
|
||||
bool first;
|
||||
int xstart;
|
||||
|
@ -1321,7 +1321,7 @@ TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, [[maybe_unuse
|
|||
continue;
|
||||
}
|
||||
|
||||
error = Find_Glyph(font, c, CACHED_METRICS | CACHED_BITMAP);
|
||||
error = Find_Glyph(font, c, CACHED_METRICS | (shaded ? CACHED_PIXMAP : CACHED_BITMAP));
|
||||
if (error)
|
||||
{
|
||||
TTF_SetFTError("Couldn't find glyph", error);
|
||||
|
@ -1329,7 +1329,7 @@ TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, [[maybe_unuse
|
|||
return NULL;
|
||||
}
|
||||
glyph = font->current;
|
||||
current = &glyph->bitmap;
|
||||
current = shaded ? &glyph->pixmap : &glyph->bitmap;
|
||||
/* Ensure the width of the pixmap is correct. On some cases,
|
||||
* freetype may report a larger pixmap than possible.*/
|
||||
width = current->width;
|
||||
|
@ -1385,152 +1385,20 @@ TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, [[maybe_unuse
|
|||
if (TTF_HANDLE_STYLE_UNDERLINE(font))
|
||||
{
|
||||
row = TTF_underline_top_row(font);
|
||||
TTF_drawLine_Solid(font, textbuf, row);
|
||||
if (shaded)
|
||||
TTF_drawLine_Shaded(font, textbuf, row);
|
||||
else
|
||||
TTF_drawLine_Solid(font, textbuf, row);
|
||||
}
|
||||
|
||||
/* Handle the strikethrough style */
|
||||
if (TTF_HANDLE_STYLE_STRIKETHROUGH(font))
|
||||
{
|
||||
row = TTF_strikethrough_top_row(font);
|
||||
TTF_drawLine_Solid(font, textbuf, row);
|
||||
}
|
||||
return textbuf;
|
||||
}
|
||||
|
||||
TTFSurface* TTF_RenderUTF8_Shaded(TTF_Font* font, const char* text, [[maybe_unused]] uint32_t fg, [[maybe_unused]] uint32_t bg)
|
||||
{
|
||||
bool first;
|
||||
int xstart;
|
||||
int width;
|
||||
int height;
|
||||
TTFSurface* textbuf;
|
||||
uint8_t* src;
|
||||
uint8_t* dst;
|
||||
uint8_t* dst_check;
|
||||
unsigned int row, col;
|
||||
FT_Bitmap* current;
|
||||
c_glyph* glyph;
|
||||
FT_Error error;
|
||||
FT_Long use_kerning;
|
||||
FT_UInt prev_index = 0;
|
||||
size_t textlen;
|
||||
|
||||
TTF_CHECKPOINTER(text, NULL);
|
||||
|
||||
/* Get the dimensions of the text surface */
|
||||
if ((TTF_SizeUTF8(font, text, &width, &height) < 0) || !width)
|
||||
{
|
||||
TTF_SetError("Text has zero width");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create the target surface */
|
||||
textbuf = static_cast<TTFSurface*>(calloc(1, sizeof(TTFSurface)));
|
||||
if (textbuf == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
textbuf->w = width;
|
||||
textbuf->h = height;
|
||||
textbuf->pitch = width;
|
||||
textbuf->pixels = calloc(1, width * height);
|
||||
|
||||
/* Adding bound checking to avoid all kinds of memory corruption errors
|
||||
that may occur. */
|
||||
dst_check = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + textbuf->pitch * textbuf->h;
|
||||
|
||||
/* check kerning */
|
||||
use_kerning = FT_HAS_KERNING(font->face) && font->kerning;
|
||||
|
||||
/* Load and render each character */
|
||||
textlen = strlen(text);
|
||||
first = true;
|
||||
xstart = 0;
|
||||
while (textlen > 0)
|
||||
{
|
||||
uint16_t c = UTF8_getch(&text, &textlen);
|
||||
if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
error = Find_Glyph(font, c, CACHED_METRICS | CACHED_PIXMAP);
|
||||
if (error)
|
||||
{
|
||||
TTF_SetFTError("Couldn't find glyph", error);
|
||||
TTFFreeSurface(textbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
glyph = font->current;
|
||||
|
||||
/* Ensure the width of the pixmap is correct. On some cases,
|
||||
* freetype may report a larger pixmap than possible.*/
|
||||
width = glyph->pixmap.width;
|
||||
if (font->outline <= 0 && width > glyph->maxx - glyph->minx)
|
||||
{
|
||||
width = glyph->maxx - glyph->minx;
|
||||
}
|
||||
|
||||
/* do kerning, if possible AC-Patch */
|
||||
if (use_kerning && prev_index && glyph->index)
|
||||
{
|
||||
FT_Vector delta;
|
||||
FT_Get_Kerning(font->face, prev_index, glyph->index, ft_kerning_default, &delta);
|
||||
xstart += delta.x >> 6;
|
||||
}
|
||||
|
||||
/* Compensate for the wrap around with negative minx's */
|
||||
if (first && (glyph->minx < 0))
|
||||
{
|
||||
xstart -= glyph->minx;
|
||||
}
|
||||
first = false;
|
||||
|
||||
current = &glyph->pixmap;
|
||||
for (row = 0; row < current->rows; ++row)
|
||||
{
|
||||
/* Make sure we don't go either over, or under the
|
||||
* limit */
|
||||
if (static_cast<signed>(row) + glyph->yoffset < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (static_cast<signed>(row) + glyph->yoffset >= textbuf->h)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
dst = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + (row + glyph->yoffset) * textbuf->pitch
|
||||
+ xstart + glyph->minx;
|
||||
src = current->buffer + row * current->pitch;
|
||||
|
||||
for (col = width; col > 0 && dst < dst_check; --col)
|
||||
{
|
||||
*dst++ |= *src++;
|
||||
}
|
||||
}
|
||||
|
||||
xstart += glyph->advance;
|
||||
if (TTF_HANDLE_STYLE_BOLD(font))
|
||||
{
|
||||
xstart += font->glyph_overhang;
|
||||
}
|
||||
prev_index = glyph->index;
|
||||
}
|
||||
|
||||
/* Handle the underline style */
|
||||
if (TTF_HANDLE_STYLE_UNDERLINE(font))
|
||||
{
|
||||
row = TTF_underline_top_row(font);
|
||||
TTF_drawLine_Shaded(font, textbuf, row);
|
||||
}
|
||||
|
||||
/* Handle the strikethrough style */
|
||||
if (TTF_HANDLE_STYLE_STRIKETHROUGH(font))
|
||||
{
|
||||
row = TTF_strikethrough_top_row(font);
|
||||
TTF_drawLine_Shaded(font, textbuf, row);
|
||||
if (shaded)
|
||||
TTF_drawLine_Shaded(font, textbuf, row);
|
||||
else
|
||||
TTF_drawLine_Solid(font, textbuf, row);
|
||||
}
|
||||
return textbuf;
|
||||
}
|
||||
|
|
|
@ -147,9 +147,9 @@ namespace OpenRCT2
|
|||
void DrawSpriteSolid(DrawPixelInfo* dpi, const ImageId image, int32_t x, int32_t y, uint8_t colour) override;
|
||||
void DrawGlyph(
|
||||
DrawPixelInfo* dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& paletteMap) override;
|
||||
void DrawBitmap(
|
||||
DrawPixelInfo* dpi, uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x,
|
||||
int32_t y) override
|
||||
void DrawTTFBitmap(
|
||||
DrawPixelInfo* dpi, TextDrawInfo* info, uint32_t image, const void* pixels, int32_t width, int32_t height,
|
||||
int32_t x, int32_t y) override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue