Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 5 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ if(NOT AGS_USE_LOCAL_SDL2 AND NOT EMSCRIPTEN)
include(FetchSDL2)
else()
find_package(SDL2 REQUIRED)
include_directories("${SDL2_INCLUDE_DIRS}")
include_directories(${SDL2_INCLUDE_DIRS})
endif()

if(NOT AGS_USE_LOCAL_SDL2_SOUND)
Expand Down Expand Up @@ -320,17 +320,16 @@ add_subdirectory(libsrc/miniz EXCLUDE_FROM_ALL)

add_subdirectory(Common/libsrc/aastr-0.1.1 EXCLUDE_FROM_ALL)

add_subdirectory(Common/libsrc/freetype-2.1.3 EXCLUDE_FROM_ALL)
set(FREETYPE_LIBRARIES FreeType::FreeType)
add_subdirectory(libsrc/freetype EXCLUDE_FROM_ALL)
add_subdirectory(libsrc/sdl_ttf EXCLUDE_FROM_ALL)

add_subdirectory(Common/libsrc/alfont-2.0.9 EXCLUDE_FROM_ALL)
add_subdirectory(Common)

add_subdirectory(Engine/libsrc/apeg-1.2.1 EXCLUDE_FROM_ALL)
if(AGS_OPENGLES2)
add_subdirectory(Engine/libsrc/glad-gles2 EXCLUDE_FROM_ALL)
add_subdirectory(Engine/libsrc/glad-gles2 EXCLUDE_FROM_ALL)
else()
add_subdirectory(Engine/libsrc/glad EXCLUDE_FROM_ALL)
add_subdirectory(Engine/libsrc/glad EXCLUDE_FROM_ALL)
endif()

if(AGS_BUILD_COMPILER)
Expand Down
13 changes: 7 additions & 6 deletions Common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ target_sources(common
util/android_file.cpp
util/android_file.h
util/bbop.h
util/bufferedstream.cpp
util/bufferedstream.h
util/cmdlineopts.cpp
util/cmdlineopts.h
util/compress.cpp
Expand Down Expand Up @@ -160,6 +162,8 @@ target_sources(common
util/path.h
util/resourcecache.h
util/scaling.h
util/sdl2_util.h
util/sdl2_util.cpp
util/smart_ptr.h
util/stdio_compat.c
util/stdio_compat.h
Expand All @@ -168,6 +172,8 @@ target_sources(common
util/stream.h
util/string.cpp
util/string.h
util/string_compat.c
util/string_compat.h
util/string_types.h
util/string_utils.cpp
util/string_utils.h
Expand All @@ -183,19 +189,14 @@ target_sources(common
util/version.h
util/wgt2allg.cpp
util/wgt2allg.h
util/bufferedstream.cpp
util/bufferedstream.h
util/string_compat.c
util/string_compat.h
util/matrix.h

platform/windows/windows.h
)

target_link_libraries(common PUBLIC
${SDL2_LIBRARY}
Allegro::Allegro
AlFont::AlFont
SDL_ttf::SDL_ttf
AAStr::AAStr
glm::glm
MiniZ::MiniZ)
Expand Down
6 changes: 2 additions & 4 deletions Common/ac/gamestructdefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,9 @@ enum SpeechStyle
// REPORTNOMINALHEIGHT: get_font_height should return nominal font's height,
// eq to "font size" parameter, otherwise returns real pixel height.
#define FFLG_REPORTNOMINALHEIGHT 0x04
// ASCENDFIXUP: do the TTF ascender fixup, where font's ascender is resized
// to the nominal font's height.
#define FFLG_ASCENDERFIXUP 0x08
//#define FFLG_ASCENDERFIXUP 0x08 // [DEPRECATED]
// Collection of flags defining font's load mode
#define FFLG_LOADMODEMASK (FFLG_REPORTNOMINALHEIGHT | FFLG_ASCENDERFIXUP)
#define FFLG_LOADMODEMASK (FFLG_REPORTNOMINALHEIGHT)
// Font outline types
#define FONT_OUTLINE_NONE -1
#define FONT_OUTLINE_AUTO -10
Expand Down
1 change: 0 additions & 1 deletion Common/font/fonts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <algorithm>
#include <cstdio>
#include <vector>
#include <alfont.h>
#include "ac/common.h" // set_our_eip
#include "ac/gamestructdefines.h"
#include "debug/out.h"
Expand Down
166 changes: 103 additions & 63 deletions Common/font/ttffontrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@
//
//=============================================================================
#include "font/ttffontrenderer.h"
#include <alfont.h>
#include <SDL_ttf.h>
#include "ac/game_version.h"
#include "core/platform.h"
#include "core/assetmanager.h"
#include "font/fonts.h"
#include "gfx/blender.h"
#include "util/stream.h"
#include "util/sdl2_util.h"

using namespace AGS::Common;

TTFFontRenderer::TTFFontRenderer(AssetManager *amgr)
: _amgr(amgr)
{
alfont_init();
alfont_text_mode(-1);
TTF_Init();
}

TTFFontRenderer::~TTFFontRenderer()
{
alfont_exit();
TTF_Quit();
}

void TTFFontRenderer::AdjustYCoordinateForFont(int *ycoord, int /*fontNumber*/)
Expand All @@ -51,41 +51,81 @@ void TTFFontRenderer::EnsureTextValidForFont(char * /*text*/, int /*fontNumber*/

int TTFFontRenderer::GetTextWidth(const char *text, int fontNumber)
{
return alfont_text_length(_fontData[fontNumber].AlFont, text);
int w = 0;
TTF_SizeUTF8(_fontData[fontNumber].Font, text, &w, nullptr);
return w;
}

int TTFFontRenderer::GetTextHeight(const char * /*text*/, int fontNumber)
{
return TTF_FontHeight(_fontData[fontNumber].Font);
/* FIXME: what to do with this?
// Compatibility mode: if we required to return "nominal font height",
// then ask alfont to return one the font was loaded with
if ((_fontData[fontNumber].Params.LoadMode & FFLG_REPORTNOMINALHEIGHT) != 0)
return alfont_get_font_height(_fontData[fontNumber].AlFont);
else
return alfont_get_font_real_height(_fontData[fontNumber].AlFont);
*/
}

void TTFFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour)
void TTFFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int color)
{
if (y > destination->cb) // optimisation
return;

// Check if this is a alpha-blending case, and init corresponding draw mode
const bool is_indexed_dst = (bitmap_color_depth(destination) == 8);
const bool alpha_blend = (bitmap_color_depth(destination) == 32) &&
((geta32(colour) != 0xFF) || (_blendMode != kBlend_Normal));
if (alpha_blend)
((geta32(color) != 0xFF) || (_blendMode != kBlend_Normal));
const bool text_smooth = (ShouldAntiAliasText()) && (!is_indexed_dst);

SDL_Color fg;
if (is_indexed_dst)
fg = { (Uint8)getr8(color), (Uint8)getg8(color), (Uint8)getb8(color), (Uint8)255 };
else
fg = { (Uint8)getr32(color), (Uint8)getg32(color), (Uint8)getb32(color), (Uint8)geta32(color) };

SDL_Surface *surf = nullptr;
if (text_smooth)
surf = TTF_RenderUTF8_Blended(_fontData[fontNumber].Font, text, fg);
else
surf = TTF_RenderUTF8_Solid(_fontData[fontNumber].Font, text, fg);

if (!surf)
return;

Bitmap helper(surf, false);
Bitmap dest(destination, true);

// For solid render: temporarily replace palette color at slot 1 with the text color
RGB old_pal_color;
if (!text_smooth)
{
alfont_blend_mode(GetBlenderFunc(_blendMode));
if (is_indexed_dst)
{
BitmapHelper::ReplaceColor(&helper, 1, color);
}
else
{
get_color(1, &old_pal_color);
set_color(1, (RGB *)&fg); // NOTE: SDL_Color and Allegro RGB match fields
}
}

// Y - 1 because it seems to get drawn down a bit
if ((ShouldAntiAliasText()) && (bitmap_color_depth(destination) > 8))
alfont_textout_aa(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour);
if (alpha_blend)
{
SetBlender(_blendMode, 255);
dest.TransBlendBlt(&helper, x, y);
}
else
alfont_textout(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour);
{
dest.MaskedBlit(&helper, x, y);
}

if (alpha_blend)
if (!text_smooth && !is_indexed_dst)
{
alfont_blend_mode(nullptr);
set_color(1, &old_pal_color);
}
}

Expand All @@ -99,51 +139,49 @@ bool TTFFontRenderer::IsBitmapFont()
return false;
}

static int GetAlfontFlags(int load_mode)
{
int flags = ALFONT_FLG_FORCE_RESIZE | ALFONT_FLG_SELECT_NOMINAL_SZ;
// Compatibility: font ascender is always adjusted to the formal font's height
if ((load_mode & FFLG_ASCENDERFIXUP) != 0)
flags |= ALFONT_FLG_ASCENDER_EQ_HEIGHT;
// Precalculate real glyphs extent (will make loading fonts relatively slower)
flags |= ALFONT_FLG_PRECALC_MAX_CBOX;
return flags;
}

// Loads a TTF font of a certain size
static ALFONT_FONT *LoadTTFFromMem(const uint8_t *data, size_t data_len, int font_size, int alfont_flags)
static TTF_Font *LoadTTF(std::unique_ptr<Stream> &&in, int font_size)
{
ALFONT_FONT *alfptr = alfont_load_font_from_mem(reinterpret_cast<const char*>(data), static_cast<int>(data_len));
if (!alfptr)
return nullptr;
alfont_set_font_size_ex(alfptr, font_size, alfont_flags);
return alfptr;
SDL_RWops *rw = SDL2Util::OpenRWops(std::move(in));
TTF_Font *font = TTF_OpenFontRW(rw, 1, font_size);
return font;
}

// FIXME: would be best to use SDL_ttf API for retrieving FT_Face's BBOX
#include <freetype/freetype.h>

// Fill the FontMetrics struct from the given ALFONT
static void FillMetrics(ALFONT_FONT *alfptr, FontMetrics *metrics)
static void FillMetrics(TTF_Font *font, int nominal_size, FontMetrics *metrics)
{
metrics->NominalHeight = alfont_get_font_height(alfptr);
metrics->RealHeight = alfont_get_font_real_height(alfptr);
metrics->NominalHeight = nominal_size;
metrics->RealHeight = TTF_FontHeight(font);
metrics->CompatHeight = metrics->NominalHeight; // just set to default here
alfont_get_font_real_vextent(alfptr, &metrics->VExtent.first, &metrics->VExtent.second);
std::pair<int, int> vextent;
{
int miny, maxy;
TTF_GetFontBBox(font, nullptr, nullptr, &miny, &maxy);
int real_face_extent_asc = (int)maxy;
int real_face_extent_desc = -(int)miny;
int face_ascender = TTF_FontAscent(font);
int face_descender = TTF_FontDescent(font);
int top = face_ascender - real_face_extent_asc; // may be negative
int bottom = face_ascender + real_face_extent_desc;
vextent = std::make_pair(top, bottom);
}

metrics->VExtent = vextent;
// fixup vextent to be *not less* than realheight
metrics->VExtent.first = std::min(0, metrics->VExtent.first);
metrics->VExtent.second = std::max(metrics->RealHeight, metrics->VExtent.second);
}

ALFONT_FONT *TTFFontRenderer::LoadTTF(const AGS::Common::String &filename, int font_size, int alfont_flags)
TTF_Font *TTFFontRenderer::LoadTTF(const AGS::Common::String &filename, int font_size)
{
auto reader = _amgr->OpenAsset(filename);
if (!reader)
auto in = _amgr->OpenAsset(filename);
if (!in)
return nullptr;

const size_t lenof = reader->GetLength();
std::vector<uint8_t> buf(lenof);
reader->Read(buf.data(), lenof);
reader.reset();

return LoadTTFFromMem(buf.data(), lenof, font_size, alfont_flags);
return ::LoadTTF(std::move(in), font_size);
}

bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const String &filename,
Expand All @@ -156,31 +194,31 @@ bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const String
if (f_params.SizeMultiplier > 1)
fontSize *= f_params.SizeMultiplier;

ALFONT_FONT *alfptr = LoadTTF(filename, fontSize,
GetAlfontFlags(f_params.LoadMode));
if (!alfptr)
TTF_Font *font = LoadTTF(filename, fontSize);
if (!font)
return false;

_fontData[fontNumber].AlFont = alfptr;
_fontData[fontNumber].Font = font;
_fontData[fontNumber].SizePt = fontSize;
_fontData[fontNumber].Params = f_params;
if (metrics)
FillMetrics(alfptr, metrics);
FillMetrics(font, fontSize, metrics);
return true;
}

const char *TTFFontRenderer::GetFontName(int fontNumber)
{
return alfont_get_name(_fontData[fontNumber].AlFont);
return TTF_FontFaceFamilyName(_fontData[fontNumber].Font);
}

int TTFFontRenderer::GetFontHeight(int fontNumber)
{
return alfont_get_font_real_height(_fontData[fontNumber].AlFont);
return TTF_FontHeight(_fontData[fontNumber].Font);
}

void TTFFontRenderer::GetFontMetrics(int fontNumber, FontMetrics *metrics)
{
FillMetrics(_fontData[fontNumber].AlFont, metrics);
FillMetrics(_fontData[fontNumber].Font, _fontData[fontNumber].SizePt, metrics);
}

void TTFFontRenderer::AdjustFontForAntiAlias(int /*fontNumber*/, bool /*aa_mode*/)
Expand All @@ -194,26 +232,28 @@ void TTFFontRenderer::SetBlendMode(BlendMode blend_mode)

void TTFFontRenderer::FreeMemory(int fontNumber)
{
alfont_destroy_font(_fontData[fontNumber].AlFont);
_fontData.erase(fontNumber);
TTF_CloseFont(_fontData[fontNumber].Font);
_fontData.erase(fontNumber);
}

bool TTFFontRenderer::MeasureFontOfPointSize(const String &filename, int size_pt, FontMetrics *metrics)
{
ALFONT_FONT *alfptr = LoadTTF(filename, size_pt, ALFONT_FLG_FORCE_RESIZE | ALFONT_FLG_SELECT_NOMINAL_SZ);
if (!alfptr)
TTF_Font *font = LoadTTF(filename, size_pt);
if (!font)
return false;
FillMetrics(alfptr, metrics);
alfont_destroy_font(alfptr);
FillMetrics(font, size_pt, metrics);
TTF_CloseFont(font);
return true;
}

bool TTFFontRenderer::MeasureFontOfPixelHeight(const String &filename, int pixel_height, FontMetrics *metrics)
{
ALFONT_FONT *alfptr = LoadTTF(filename, pixel_height, ALFONT_FLG_FORCE_RESIZE);
if (!alfptr)
// FIXME: pixel_height to size_pt
int size_pt = pixel_height;
TTF_Font *font = LoadTTF(filename, size_pt);
if (!font)
return false;
FillMetrics(alfptr, metrics);
alfont_destroy_font(alfptr);
FillMetrics(font, size_pt, metrics);
TTF_CloseFont(font);
return true;
}
Loading
Loading