mirror of https://github.com/OpenRCT2/OpenRCT2.git
Refactor TTF drawing (#21621)
This commit is contained in:
parent
4eacb21f57
commit
d48b75fb86
|
@ -37,7 +37,6 @@
|
||||||
# include <openrct2/ui/UiContext.h>
|
# include <openrct2/ui/UiContext.h>
|
||||||
# include <openrct2/util/Util.h>
|
# include <openrct2/util/Util.h>
|
||||||
# include <openrct2/world/Climate.h>
|
# include <openrct2/world/Climate.h>
|
||||||
# include <unordered_map>
|
|
||||||
|
|
||||||
using namespace OpenRCT2;
|
using namespace OpenRCT2;
|
||||||
using namespace OpenRCT2::Drawing;
|
using namespace OpenRCT2::Drawing;
|
||||||
|
@ -74,6 +73,8 @@ private:
|
||||||
|
|
||||||
int32_t _drawCount = 0;
|
int32_t _drawCount = 0;
|
||||||
|
|
||||||
|
uint32_t _ttfGlId = 0;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
LineCommandBatch lines;
|
LineCommandBatch lines;
|
||||||
|
@ -110,8 +111,7 @@ public:
|
||||||
void DrawSpriteSolid(DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, uint8_t colour) 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 DrawGlyph(DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& palette) override;
|
||||||
void DrawTTFBitmap(
|
void DrawTTFBitmap(
|
||||||
DrawPixelInfo& dpi, TextDrawInfo* info, ImageIndex image, const void* pixels, int32_t width, int32_t height, int32_t x,
|
DrawPixelInfo& dpi, TextDrawInfo* info, TTFSurface* surface, int32_t x, int32_t y, uint8_t hintingThreshold) override;
|
||||||
int32_t y, uint8_t hinting_threshold) override;
|
|
||||||
|
|
||||||
void FlushCommandBuffers();
|
void FlushCommandBuffers();
|
||||||
|
|
||||||
|
@ -908,17 +908,25 @@ void OpenGLDrawingContext::DrawGlyph(DrawPixelInfo& dpi, const ImageId image, in
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDrawingContext::DrawTTFBitmap(
|
void OpenGLDrawingContext::DrawTTFBitmap(
|
||||||
DrawPixelInfo& dpi, TextDrawInfo* info, ImageIndex image, const void* pixels, int32_t width, int32_t height, int32_t x,
|
DrawPixelInfo& dpi, TextDrawInfo* info, TTFSurface* surface, int32_t x, int32_t y, uint8_t hintingThreshold)
|
||||||
int32_t y, uint8_t hinting_threshold)
|
|
||||||
{
|
{
|
||||||
|
# ifndef NO_TTF
|
||||||
CalculcateClipping(dpi);
|
CalculcateClipping(dpi);
|
||||||
|
|
||||||
const auto texture = _textureCache->GetOrLoadBitmapTexture(image, pixels, width, height);
|
auto baseId = uint32_t(0x7FFFF) - 1024;
|
||||||
|
auto imageId = baseId + _ttfGlId;
|
||||||
|
_engine.InvalidateImage(imageId);
|
||||||
|
const auto texture = _textureCache->GetOrLoadBitmapTexture(imageId, surface->pixels, surface->w, surface->h);
|
||||||
|
_ttfGlId++;
|
||||||
|
if (_ttfGlId >= 1023)
|
||||||
|
{
|
||||||
|
_ttfGlId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t drawOffsetX = 0;
|
int32_t drawOffsetX = 0;
|
||||||
int32_t drawOffsetY = 0;
|
int32_t drawOffsetY = 0;
|
||||||
int32_t drawWidth = static_cast<uint16_t>(width);
|
int32_t drawWidth = static_cast<uint16_t>(surface->w);
|
||||||
int32_t drawHeight = static_cast<uint16_t>(height);
|
int32_t drawHeight = static_cast<uint16_t>(surface->h);
|
||||||
|
|
||||||
int32_t left = x + drawOffsetX;
|
int32_t left = x + drawOffsetX;
|
||||||
int32_t top = y + drawOffsetY;
|
int32_t top = y + drawOffsetY;
|
||||||
|
@ -976,7 +984,7 @@ void OpenGLDrawingContext::DrawTTFBitmap(
|
||||||
command.bounds = { left + 1, top + 1, right + 1, bottom + 1 };
|
command.bounds = { left + 1, top + 1, right + 1, bottom + 1 };
|
||||||
command.depth = _drawCount++;
|
command.depth = _drawCount++;
|
||||||
}
|
}
|
||||||
auto& cmdBuf = hinting_threshold > 0 ? _commandBuffers.transparent : _commandBuffers.rects;
|
auto& cmdBuf = hintingThreshold > 0 ? _commandBuffers.transparent : _commandBuffers.rects;
|
||||||
DrawRectCommand& command = cmdBuf.allocate();
|
DrawRectCommand& command = cmdBuf.allocate();
|
||||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||||
command.texColourAtlas = texture.index;
|
command.texColourAtlas = texture.index;
|
||||||
|
@ -984,10 +992,11 @@ void OpenGLDrawingContext::DrawTTFBitmap(
|
||||||
command.texMaskAtlas = 0;
|
command.texMaskAtlas = 0;
|
||||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
command.palettes = { 0, 0, 0 };
|
command.palettes = { 0, 0, 0 };
|
||||||
command.flags = DrawRectCommand::FLAG_TTF_TEXT | (hinting_threshold << 8);
|
command.flags = DrawRectCommand::FLAG_TTF_TEXT | (hintingThreshold << 8);
|
||||||
command.colour = info->palette[1];
|
command.colour = info->palette[1];
|
||||||
command.bounds = { left, top, right, bottom };
|
command.bounds = { left, top, right, bottom };
|
||||||
command.depth = _drawCount++;
|
command.depth = _drawCount++;
|
||||||
|
# endif // NO_TTF
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDrawingContext::FlushCommandBuffers()
|
void OpenGLDrawingContext::FlushCommandBuffers()
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "../localisation/LocalisationService.h"
|
#include "../localisation/LocalisationService.h"
|
||||||
#include "../platform/Platform.h"
|
#include "../platform/Platform.h"
|
||||||
#include "../sprites.h"
|
#include "../sprites.h"
|
||||||
#include "../util/Util.h"
|
|
||||||
#include "TTF.h"
|
#include "TTF.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -509,7 +508,6 @@ static void TTFDrawStringRawSprite(DrawPixelInfo& dpi, std::string_view text, Te
|
||||||
|
|
||||||
#ifndef NO_TTF
|
#ifndef NO_TTF
|
||||||
|
|
||||||
static int _ttfGlId = 0;
|
|
||||||
static void TTFDrawStringRawTTF(DrawPixelInfo& dpi, std::string_view text, TextDrawInfo* info)
|
static void TTFDrawStringRawTTF(DrawPixelInfo& dpi, std::string_view text, TextDrawInfo* info)
|
||||||
{
|
{
|
||||||
if (!TTFInitialise())
|
if (!TTFInitialise())
|
||||||
|
@ -528,135 +526,20 @@ static void TTFDrawStringRawTTF(DrawPixelInfo& dpi, std::string_view text, TextD
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t colour = info->palette[1];
|
|
||||||
TTFSurface* surface = TTFSurfaceCacheGetOrAdd(fontDesc->font, text);
|
TTFSurface* surface = TTFSurfaceCacheGetOrAdd(fontDesc->font, text);
|
||||||
if (surface == nullptr)
|
if (surface == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int32_t drawX = info->x + fontDesc->offset_x;
|
auto drawingEngine = dpi.DrawingEngine;
|
||||||
int32_t drawY = info->y + fontDesc->offset_y;
|
if (drawingEngine != nullptr)
|
||||||
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 baseId = uint32_t(0x7FFFF) - 1024;
|
int32_t drawX = info->x + fontDesc->offset_x;
|
||||||
auto imageId = baseId + _ttfGlId;
|
int32_t drawY = info->y + fontDesc->offset_y;
|
||||||
auto drawingEngine = dpi.DrawingEngine;
|
uint8_t hintThresh = gConfigFonts.EnableHinting ? fontDesc->hinting_threshold : 0;
|
||||||
auto drawingContext = drawingEngine->GetDrawingContext();
|
OpenRCT2::Drawing::IDrawingContext* dc = drawingEngine->GetDrawingContext();
|
||||||
uint8_t hint_thresh = use_hinting ? fontDesc->hinting_threshold : 0;
|
dc->DrawTTFBitmap(dpi, info, surface, drawX, drawY, hintThresh);
|
||||||
drawingEngine->InvalidateImage(imageId);
|
|
||||||
drawingContext->DrawTTFBitmap(
|
|
||||||
dpi, info, imageId, surface->pixels, surface->pitch, surface->h, drawX, drawY, hint_thresh);
|
|
||||||
|
|
||||||
_ttfGlId++;
|
|
||||||
if (_ttfGlId >= 1023)
|
|
||||||
{
|
|
||||||
_ttfGlId = 0;
|
|
||||||
}
|
|
||||||
info->x += width;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t overflowX = (dpi.x + dpi.width) - (drawX + width);
|
|
||||||
int32_t overflowY = (dpi.y + dpi.height) - (drawY + height);
|
|
||||||
if (overflowX < 0)
|
|
||||||
width += overflowX;
|
|
||||||
if (overflowY < 0)
|
|
||||||
height += overflowY;
|
|
||||||
int32_t skipX = drawX - dpi.x;
|
|
||||||
int32_t skipY = drawY - dpi.y;
|
|
||||||
info->x += width;
|
|
||||||
|
|
||||||
auto src = static_cast<const uint8_t*>(surface->pixels);
|
|
||||||
uint8_t* dst = dpi.bits;
|
|
||||||
|
|
||||||
int32_t srcXStart = 0;
|
|
||||||
int32_t srcYStart = 0;
|
|
||||||
if (skipX < 0)
|
|
||||||
{
|
|
||||||
width += skipX;
|
|
||||||
src += -skipX;
|
|
||||||
srcXStart += -skipX;
|
|
||||||
skipX = 0;
|
|
||||||
}
|
|
||||||
if (skipY < 0)
|
|
||||||
{
|
|
||||||
height += skipY;
|
|
||||||
src += (-skipY * surface->pitch);
|
|
||||||
srcYStart += -skipY;
|
|
||||||
skipY = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst += skipX;
|
|
||||||
dst += skipY * (dpi.width + dpi.pitch);
|
|
||||||
|
|
||||||
int32_t srcScanSkip = surface->pitch - width;
|
|
||||||
int32_t dstScanSkip = dpi.width + dpi.pitch - width;
|
|
||||||
uint8_t* dst_orig = dst;
|
|
||||||
|
|
||||||
// Draw shadow/outline
|
|
||||||
if (info->flags & (TEXT_DRAW_FLAG_OUTLINE | TEXT_DRAW_FLAG_INSET))
|
|
||||||
{
|
|
||||||
for (int32_t yy = 0; yy < height; yy++)
|
|
||||||
{
|
|
||||||
for (int32_t xx = 0; xx < width; xx++)
|
|
||||||
{
|
|
||||||
if (info->flags & TEXT_DRAW_FLAG_OUTLINE)
|
|
||||||
{
|
|
||||||
if (GetPixel(*surface, xx + srcXStart + 1, yy + srcYStart)
|
|
||||||
|| GetPixel(*surface, xx + srcXStart - 1, yy + srcYStart)
|
|
||||||
|| GetPixel(*surface, xx + srcXStart, yy + srcYStart + 1)
|
|
||||||
|| GetPixel(*surface, xx + srcXStart, yy + srcYStart - 1))
|
|
||||||
{
|
|
||||||
*dst = info->palette[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (info->flags & TEXT_DRAW_FLAG_INSET)
|
|
||||||
{
|
|
||||||
if (GetPixel(*surface, xx + srcXStart - 1, yy + srcYStart - 1))
|
|
||||||
{
|
|
||||||
*dst = info->palette[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst++;
|
|
||||||
}
|
|
||||||
// Skip any remaining bits
|
|
||||||
dst += dstScanSkip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = dst_orig;
|
|
||||||
for (int32_t yy = 0; yy < height; yy++)
|
|
||||||
{
|
|
||||||
for (int32_t xx = 0; xx < width; xx++)
|
|
||||||
{
|
|
||||||
if (*src != 0)
|
|
||||||
{
|
|
||||||
if (*src > 180 || !use_hinting)
|
|
||||||
{
|
|
||||||
// Centre of the glyph: use full colour.
|
|
||||||
*dst = colour;
|
|
||||||
}
|
|
||||||
else if (use_hinting && *src > fontDesc->hinting_threshold)
|
|
||||||
{
|
|
||||||
// Simulate font hinting by shading the background colour instead.
|
|
||||||
if (info->flags & TEXT_DRAW_FLAG_OUTLINE)
|
|
||||||
{
|
|
||||||
*dst = BlendColours(colour, info->palette[3]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*dst = BlendColours(colour, *dst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
src++;
|
|
||||||
dst++;
|
|
||||||
}
|
|
||||||
src += srcScanSkip;
|
|
||||||
dst += dstScanSkip;
|
|
||||||
}
|
}
|
||||||
|
info->x += surface->w;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NO_TTF
|
#endif // NO_TTF
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "../common.h"
|
#include "../common.h"
|
||||||
#include "Drawing.h"
|
#include "Drawing.h"
|
||||||
|
#include "TTF.h"
|
||||||
|
|
||||||
namespace OpenRCT2::Drawing
|
namespace OpenRCT2::Drawing
|
||||||
{
|
{
|
||||||
|
@ -33,8 +34,8 @@ namespace OpenRCT2::Drawing
|
||||||
virtual void DrawGlyph(
|
virtual void DrawGlyph(
|
||||||
DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& palette) abstract;
|
DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& palette) abstract;
|
||||||
virtual void DrawTTFBitmap(
|
virtual void DrawTTFBitmap(
|
||||||
DrawPixelInfo& dpi, TextDrawInfo* info, ImageIndex image, const void* pixels, int32_t width, int32_t height,
|
DrawPixelInfo& dpi, TextDrawInfo* info, TTFSurface* surface, int32_t x, int32_t y,
|
||||||
int32_t x, int32_t y, uint8_t hinting_threshold) abstract;
|
uint8_t hintingThreshold) abstract;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OpenRCT2::Drawing
|
} // namespace OpenRCT2::Drawing
|
||||||
|
|
|
@ -1577,12 +1577,11 @@ static void ScrollingTextSetBitmapForTTF(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t pitch = surface->pitch;
|
|
||||||
int32_t width = surface->w;
|
int32_t width = surface->w;
|
||||||
auto src = static_cast<const uint8_t*>(surface->pixels);
|
auto src = static_cast<const uint8_t*>(surface->pixels);
|
||||||
|
|
||||||
// Pitch offset
|
// Pitch offset
|
||||||
src += 2 * pitch;
|
src += 2 * width;
|
||||||
|
|
||||||
// Line height offset
|
// Line height offset
|
||||||
int32_t min_vpos = -fontDesc->offset_y;
|
int32_t min_vpos = -fontDesc->offset_y;
|
||||||
|
@ -1608,7 +1607,7 @@ static void ScrollingTextSetBitmapForTTF(
|
||||||
|
|
||||||
for (int32_t y = min_vpos; y < max_vpos; y++)
|
for (int32_t y = min_vpos; y < max_vpos; y++)
|
||||||
{
|
{
|
||||||
uint8_t src_pixel = src[y * pitch + x];
|
uint8_t src_pixel = src[y * width + x];
|
||||||
if ((!use_hinting && src_pixel != 0) || src_pixel > 140)
|
if ((!use_hinting && src_pixel != 0) || src_pixel > 140)
|
||||||
{
|
{
|
||||||
// Centre of the glyph: use full colour.
|
// Centre of the glyph: use full colour.
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#ifndef NO_TTF
|
#ifndef NO_TTF
|
||||||
|
|
||||||
# include <atomic>
|
|
||||||
# include <mutex>
|
# include <mutex>
|
||||||
# pragma clang diagnostic push
|
# pragma clang diagnostic push
|
||||||
# pragma clang diagnostic ignored "-Wdocumentation"
|
# pragma clang diagnostic ignored "-Wdocumentation"
|
||||||
|
@ -21,7 +20,6 @@
|
||||||
# include "../config/Config.h"
|
# include "../config/Config.h"
|
||||||
# include "../core/Numerics.hpp"
|
# include "../core/Numerics.hpp"
|
||||||
# include "../core/String.hpp"
|
# include "../core/String.hpp"
|
||||||
# include "../localisation/Localisation.h"
|
|
||||||
# include "../localisation/LocalisationService.h"
|
# include "../localisation/LocalisationService.h"
|
||||||
# include "../platform/Platform.h"
|
# include "../platform/Platform.h"
|
||||||
# include "TTF.h"
|
# include "TTF.h"
|
||||||
|
@ -374,13 +372,6 @@ void TTFFreeSurface(TTFSurface* surface)
|
||||||
free(surface);
|
free(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t GetPixel(const TTFSurface& surface, int32_t x, int32_t y)
|
|
||||||
{
|
|
||||||
if (x < 0 || y < 0 || x >= surface.w || y >= surface.h)
|
|
||||||
return 0;
|
|
||||||
return static_cast<const uint8_t*>(surface.pixels)[y * surface.pitch + x];
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
# include "TTF.h"
|
# include "TTF.h"
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
bool TTFInitialise();
|
bool TTFInitialise();
|
||||||
void TTFDispose();
|
void TTFDispose();
|
||||||
|
struct TTFSurface;
|
||||||
|
|
||||||
#ifndef NO_TTF
|
#ifndef NO_TTF
|
||||||
|
|
||||||
|
@ -23,7 +24,6 @@ struct TTFSurface
|
||||||
const void* pixels;
|
const void* pixels;
|
||||||
int32_t w;
|
int32_t w;
|
||||||
int32_t h;
|
int32_t h;
|
||||||
int32_t pitch;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TTFFontDescriptor* TTFGetFontFromSpriteBase(FontStyle fontStyle);
|
TTFFontDescriptor* TTFGetFontFromSpriteBase(FontStyle fontStyle);
|
||||||
|
@ -43,6 +43,5 @@ void TTF_CloseFont(TTF_Font* font);
|
||||||
void TTF_SetFontHinting(TTF_Font* font, int hinting);
|
void TTF_SetFontHinting(TTF_Font* font, int hinting);
|
||||||
int TTF_GetFontHinting(const TTF_Font* font);
|
int TTF_GetFontHinting(const TTF_Font* font);
|
||||||
void TTF_Quit(void);
|
void TTF_Quit(void);
|
||||||
uint8_t GetPixel(const TTFSurface& surface, int32_t x, int32_t y);
|
|
||||||
|
|
||||||
#endif // NO_TTF
|
#endif // NO_TTF
|
||||||
|
|
|
@ -216,7 +216,7 @@ static void TTF_initLineMectrics(const TTF_Font* font, const TTFSurface* textbuf
|
||||||
dst = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels));
|
dst = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels));
|
||||||
if (row > 0)
|
if (row > 0)
|
||||||
{
|
{
|
||||||
dst += row * textbuf->pitch;
|
dst += row * textbuf->w;
|
||||||
}
|
}
|
||||||
|
|
||||||
height = font->underline_height;
|
height = font->underline_height;
|
||||||
|
@ -236,7 +236,7 @@ outline into account.
|
||||||
static void TTF_drawLine_Solid(const TTF_Font* font, const TTFSurface* textbuf, const int row)
|
static void TTF_drawLine_Solid(const TTF_Font* font, const TTFSurface* textbuf, const int row)
|
||||||
{
|
{
|
||||||
int line;
|
int line;
|
||||||
uint8_t* dst_check = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + textbuf->pitch * textbuf->h;
|
uint8_t* dst_check = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + textbuf->w * textbuf->h;
|
||||||
uint8_t* dst;
|
uint8_t* dst;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ static void TTF_drawLine_Solid(const TTF_Font* font, const TTFSurface* textbuf,
|
||||||
{
|
{
|
||||||
/* 1 because 0 is the bg color */
|
/* 1 because 0 is the bg color */
|
||||||
std::fill_n(dst, textbuf->w, 0x01);
|
std::fill_n(dst, textbuf->w, 0x01);
|
||||||
dst += textbuf->pitch;
|
dst += textbuf->w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ static void TTF_drawLine_Solid(const TTF_Font* font, const TTFSurface* textbuf,
|
||||||
static void TTF_drawLine_Shaded(const TTF_Font* font, const TTFSurface* textbuf, const int row)
|
static void TTF_drawLine_Shaded(const TTF_Font* font, const TTFSurface* textbuf, const int row)
|
||||||
{
|
{
|
||||||
int line;
|
int line;
|
||||||
uint8_t* dst_check = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + textbuf->pitch * textbuf->h;
|
uint8_t* dst_check = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + textbuf->w * textbuf->h;
|
||||||
uint8_t* dst;
|
uint8_t* dst;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ static void TTF_drawLine_Shaded(const TTF_Font* font, const TTFSurface* textbuf,
|
||||||
for (line = height; line > 0 && dst < dst_check; --line)
|
for (line = height; line > 0 && dst < dst_check; --line)
|
||||||
{
|
{
|
||||||
std::fill_n(dst, textbuf->w, NUM_GRAYS - 1);
|
std::fill_n(dst, textbuf->w, NUM_GRAYS - 1);
|
||||||
dst += textbuf->pitch;
|
dst += textbuf->w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1299,12 +1299,11 @@ TTFSurface* TTF_RenderUTF8(TTF_Font* font, const char* text, bool shaded)
|
||||||
}
|
}
|
||||||
textbuf->w = width;
|
textbuf->w = width;
|
||||||
textbuf->h = height;
|
textbuf->h = height;
|
||||||
textbuf->pitch = width;
|
|
||||||
textbuf->pixels = calloc(1, width * height);
|
textbuf->pixels = calloc(1, width * height);
|
||||||
|
|
||||||
/* Adding bound checking to avoid all kinds of memory corruption errors
|
/* Adding bound checking to avoid all kinds of memory corruption errors
|
||||||
that may occur. */
|
that may occur. */
|
||||||
dst_check = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + textbuf->pitch * textbuf->h;
|
dst_check = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + textbuf->w * textbuf->h;
|
||||||
|
|
||||||
/* check kerning */
|
/* check kerning */
|
||||||
use_kerning = FT_HAS_KERNING(font->face) && font->kerning;
|
use_kerning = FT_HAS_KERNING(font->face) && font->kerning;
|
||||||
|
@ -1363,7 +1362,7 @@ TTFSurface* TTF_RenderUTF8(TTF_Font* font, const char* text, bool shaded)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + (row + glyph->yoffset) * textbuf->pitch
|
dst = const_cast<uint8_t*>(static_cast<const uint8_t*>(textbuf->pixels)) + (row + glyph->yoffset) * textbuf->w
|
||||||
+ xstart + glyph->minx;
|
+ xstart + glyph->minx;
|
||||||
src = current->buffer + row * current->pitch;
|
src = current->buffer + row * current->pitch;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "X8DrawingEngine.h"
|
#include "X8DrawingEngine.h"
|
||||||
|
|
||||||
#include "../Context.h"
|
#include "../Context.h"
|
||||||
#include "../Game.h"
|
|
||||||
#include "../Intro.h"
|
#include "../Intro.h"
|
||||||
#include "../config/Config.h"
|
#include "../config/Config.h"
|
||||||
#include "../core/Numerics.hpp"
|
#include "../core/Numerics.hpp"
|
||||||
|
@ -19,7 +18,6 @@
|
||||||
#include "../interface/Window.h"
|
#include "../interface/Window.h"
|
||||||
#include "../ui/UiContext.h"
|
#include "../ui/UiContext.h"
|
||||||
#include "../util/Util.h"
|
#include "../util/Util.h"
|
||||||
#include "../world/Climate.h"
|
|
||||||
#include "Drawing.h"
|
#include "Drawing.h"
|
||||||
#include "IDrawingContext.h"
|
#include "IDrawingContext.h"
|
||||||
#include "IDrawingEngine.h"
|
#include "IDrawingEngine.h"
|
||||||
|
@ -743,3 +741,100 @@ void X8DrawingContext::DrawGlyph(DrawPixelInfo& dpi, const ImageId image, int32_
|
||||||
{
|
{
|
||||||
GfxDrawSpritePaletteSetSoftware(dpi, image, { x, y }, paletteMap);
|
GfxDrawSpritePaletteSetSoftware(dpi, image, { x, y }, paletteMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_TTF
|
||||||
|
template<bool TUseHinting>
|
||||||
|
static void DrawTTFBitmapInternal(
|
||||||
|
DrawPixelInfo& dpi, uint8_t colour, TTFSurface* surface, int32_t x, int32_t y, uint8_t hintingThreshold)
|
||||||
|
{
|
||||||
|
const int32_t surfaceWidth = surface->w;
|
||||||
|
int32_t width = surfaceWidth;
|
||||||
|
int32_t height = surface->h;
|
||||||
|
|
||||||
|
const int32_t overflowX = (dpi.x + dpi.width) - (x + width);
|
||||||
|
const int32_t overflowY = (dpi.y + dpi.height) - (y + height);
|
||||||
|
if (overflowX < 0)
|
||||||
|
width += overflowX;
|
||||||
|
if (overflowY < 0)
|
||||||
|
height += overflowY;
|
||||||
|
int32_t skipX = x - dpi.x;
|
||||||
|
int32_t skipY = y - dpi.y;
|
||||||
|
|
||||||
|
auto src = static_cast<const uint8_t*>(surface->pixels);
|
||||||
|
uint8_t* dst = dpi.bits;
|
||||||
|
|
||||||
|
if (skipX < 0)
|
||||||
|
{
|
||||||
|
width += skipX;
|
||||||
|
src += -skipX;
|
||||||
|
skipX = 0;
|
||||||
|
}
|
||||||
|
if (skipY < 0)
|
||||||
|
{
|
||||||
|
height += skipY;
|
||||||
|
src += (-skipY * surfaceWidth);
|
||||||
|
skipY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += skipX;
|
||||||
|
dst += skipY * (dpi.width + dpi.pitch);
|
||||||
|
|
||||||
|
const int32_t srcScanSkip = surfaceWidth - width;
|
||||||
|
const int32_t dstScanSkip = dpi.width + dpi.pitch - width;
|
||||||
|
for (int32_t yy = 0; yy < height; yy++)
|
||||||
|
{
|
||||||
|
for (int32_t xx = 0; xx < width; xx++)
|
||||||
|
{
|
||||||
|
if (*src != 0)
|
||||||
|
{
|
||||||
|
if constexpr (TUseHinting)
|
||||||
|
{
|
||||||
|
if (*src > 180)
|
||||||
|
{
|
||||||
|
// Centre of the glyph: use full colour.
|
||||||
|
*dst = colour;
|
||||||
|
}
|
||||||
|
else if (*src > hintingThreshold)
|
||||||
|
{
|
||||||
|
*dst = BlendColours(colour, *dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*dst = colour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
src++;
|
||||||
|
dst++;
|
||||||
|
}
|
||||||
|
src += srcScanSkip;
|
||||||
|
dst += dstScanSkip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // NO_TTF
|
||||||
|
|
||||||
|
void X8DrawingContext::DrawTTFBitmap(
|
||||||
|
DrawPixelInfo& dpi, TextDrawInfo* info, TTFSurface* surface, int32_t x, int32_t y, uint8_t hintingThreshold)
|
||||||
|
{
|
||||||
|
#ifndef NO_TTF
|
||||||
|
const uint8_t fgColor = info->palette[1];
|
||||||
|
const uint8_t bgColor = info->palette[3];
|
||||||
|
|
||||||
|
if (info->flags & TEXT_DRAW_FLAG_OUTLINE)
|
||||||
|
{
|
||||||
|
DrawTTFBitmapInternal<false>(dpi, bgColor, surface, x + 1, y, 0);
|
||||||
|
DrawTTFBitmapInternal<false>(dpi, bgColor, surface, x - 1, y, 0);
|
||||||
|
DrawTTFBitmapInternal<false>(dpi, bgColor, surface, x, y + 1, 0);
|
||||||
|
DrawTTFBitmapInternal<false>(dpi, bgColor, surface, x, y - 1, 0);
|
||||||
|
}
|
||||||
|
if (info->flags & TEXT_DRAW_FLAG_INSET)
|
||||||
|
{
|
||||||
|
DrawTTFBitmapInternal<false>(dpi, bgColor, surface, x + 1, y + 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hintingThreshold > 0)
|
||||||
|
DrawTTFBitmapInternal<true>(dpi, fgColor, surface, x, y, hintingThreshold);
|
||||||
|
else
|
||||||
|
DrawTTFBitmapInternal<false>(dpi, fgColor, surface, x, y, 0);
|
||||||
|
#endif // NO_TTF
|
||||||
|
}
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../common.h"
|
|
||||||
#include "IDrawingContext.h"
|
#include "IDrawingContext.h"
|
||||||
#include "IDrawingEngine.h"
|
#include "IDrawingEngine.h"
|
||||||
|
|
||||||
|
@ -148,10 +147,8 @@ namespace OpenRCT2
|
||||||
void DrawGlyph(
|
void DrawGlyph(
|
||||||
DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& paletteMap) override;
|
DrawPixelInfo& dpi, const ImageId image, int32_t x, int32_t y, const PaletteMap& paletteMap) override;
|
||||||
void DrawTTFBitmap(
|
void DrawTTFBitmap(
|
||||||
DrawPixelInfo& dpi, TextDrawInfo* info, uint32_t image, const void* pixels, int32_t width, int32_t height,
|
DrawPixelInfo& dpi, TextDrawInfo* info, TTFSurface* surface, int32_t x, int32_t y,
|
||||||
int32_t x, int32_t y, uint8_t hinting_threshold) override
|
uint8_t hintingThreshold) override;
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} // namespace Drawing
|
} // namespace Drawing
|
||||||
} // namespace OpenRCT2
|
} // namespace OpenRCT2
|
||||||
|
|
Loading…
Reference in New Issue