AGS: Always precalculate and save font linespacing (as outlined)

From upstream 8ba3a77e38a6dc8ace6d6393042730d73292a1a7
This commit is contained in:
Paul Gilbert 2022-03-22 22:01:16 -07:00
parent 977925d105
commit d42b639142
14 changed files with 51 additions and 57 deletions

View File

@ -450,8 +450,8 @@ void DialogOptions::Prepare(int _dlgnum, bool _runGameLoopsInBackground) {
dlgyp = get_fixed_pixel_size(160);
usingfont = FONT_NORMAL;
lineheight = getfontheight_outlined(usingfont);
linespacing = getfontspacing_outlined(usingfont);
lineheight = get_font_height_outlined(usingfont);
linespacing = get_font_linespacing(usingfont);
curswas = _G(cur_cursor);
bullet_wid = 0;
ddb = nullptr;

View File

@ -100,8 +100,8 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
ensure_text_valid_for_font(todis, usingfont);
break_up_text_into_lines(todis, _GP(Lines), wii - 2 * padding, usingfont);
disp.lineheight = getfontheight_outlined(usingfont);
disp.linespacing = getfontspacing_outlined(usingfont);
disp.lineheight = get_font_height_outlined(usingfont);
disp.linespacing = get_font_linespacing(usingfont);
disp.fulltxtheight = getheightoflines(usingfont, _GP(Lines).Count());
// AGS 2.x: If the screen is faded out, fade in again when displaying a message box.
@ -563,18 +563,8 @@ int get_font_outline_padding(int font) {
return 0;
}
int getfontheight_outlined(int font) {
return get_font_height(font) + 2 * get_font_outline_padding(font);
}
int getfontspacing_outlined(int font) {
return use_default_linespacing(font) ?
getfontheight_outlined(font) :
get_font_linespacing(font);
}
int getheightoflines(int font, int numlines) {
return getfontspacing_outlined(font) * (numlines - 1) + getfontheight_outlined(font);
return get_font_linespacing(font) * (numlines - 1) + get_font_height_outlined(font);
}
int get_text_width_outlined(const char *tex, int font) {

View File

@ -52,14 +52,6 @@ int GetTextDisplayTime(const char *text, int canberel = 0);
// Draw an outline if requested, then draw the text on top
void wouttext_outline(Shared::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx);
void wouttext_aligned(Shared::Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, color_t text_color, const char *text, HorAlignment align);
// TODO: GUI classes located in Common library do not make use of outlining,
// need to find a way to make all code use same functions.
// Get the maximal height of the given font, with corresponding outlining
int getfontheight_outlined(int font);
// Get outline's thickness addition to the font's width or height
int get_font_outline_padding(int font);
// Get line spacing for the given font, with possible outlining in mind
int getfontspacing_outlined(int font);
// Gets the total maximal height of the given number of lines printed with the given font
int getheightoflines(int font, int numlines);
// Get the maximal width of the given font, with corresponding outlining

View File

@ -644,7 +644,8 @@ void mark_current_background_dirty() {
void draw_and_invalidate_text(Bitmap *ds, int x1, int y1, int font, color_t text_color, const char *text) {
wouttext_outline(ds, x1, y1, font, text_color, text);
invalidate_rect(x1, y1, x1 + get_text_width_outlined(text, font), y1 + getfontheight_outlined(font) + get_fixed_pixel_size(1), false);
invalidate_rect(x1, y1, x1 + get_text_width_outlined(text, font),
y1 + get_font_height_outlined(font) + get_fixed_pixel_size(1), false);
}
// Renders black borders for the legacy boxed game mode,
@ -1930,7 +1931,7 @@ void draw_fps(const Rect &viewport) {
static Bitmap *fpsDisplay = nullptr;
const int font = FONT_NORMAL;
if (fpsDisplay == nullptr) {
fpsDisplay = CreateCompatBitmap(viewport.GetWidth(), (getfontheight_outlined(font) + get_fixed_pixel_size(5)), _GP(game).GetColorDepth());
fpsDisplay = CreateCompatBitmap(viewport.GetWidth(), (get_font_height_outlined(font) + get_fixed_pixel_size(5)));
}
fpsDisplay->ClearTransparent();
@ -2266,7 +2267,7 @@ void construct_engine_overlay() {
if ((_GP(play).debug_mode > 0) && (_G(display_console) != 0)) {
const int font = FONT_NORMAL;
int ypp = 1;
int txtspacing = getfontspacing_outlined(font);
int txtspacing = get_font_linespacing(font);
int barheight = getheightoflines(font, DEBUG_CONSOLE_NUMLINES - 1) + 4;
if (_G(debugConsoleBuffer) == nullptr) {

View File

@ -333,7 +333,7 @@ void DrawingSurface_DrawStringWrapped_Old(ScriptDrawingSurface *sds, int xx, int
}
void DrawingSurface_DrawStringWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg) {
int linespacing = getfontspacing_outlined(font);
int linespacing = get_font_linespacing(font);
sds->PointToGameResolution(&xx, &yy);
sds->SizeToGameResolution(&wid);

View File

@ -27,6 +27,7 @@
#include "ags/engine/ac/draw.h"
#include "ags/engine/ac/game.h"
#include "ags/shared/ac/game_setup_struct.h"
#include "ags/shared/font/fonts.h"
#include "ags/engine/ac/game_state.h"
#include "ags/engine/ac/global_character.h"
#include "ags/engine/ac/global_display.h"
@ -72,7 +73,7 @@ void DisplayTopBar(int ypos, int ttexcol, int backcol, const char *title, const
_GP(topBar).wantIt = 1;
_GP(topBar).font = FONT_NORMAL;
_GP(topBar).height = getfontheight_outlined(_GP(topBar).font);
_GP(topBar).height = get_font_height_outlined(_GP(topBar).font);
_GP(topBar).height += data_to_game_coord(_GP(play).top_bar_borderwidth) * 2 + get_fixed_pixel_size(1);
// they want to customize the font

View File

@ -147,7 +147,7 @@ void RawPrint(int xx, int yy, const char *text) {
}
void RawPrintMessageWrapped(int xx, int yy, int wid, int font, int msgm) {
char displbuf[3000];
int linespacing = getfontspacing_outlined(font);
const int linespacing = get_font_linespacing(font);
data_to_game_coords(&xx, &yy);
wid = data_to_game_coord(wid);

View File

@ -193,13 +193,13 @@ int GetTextHeight(const char *text, int fontnum, int width) {
int GetFontHeight(int fontnum) {
if ((fontnum < 0) || (fontnum >= _GP(game).numfonts))
quit("!GetFontHeight: invalid font number.");
return game_to_data_coord(getfontheight_outlined(fontnum));
return game_to_data_coord(get_font_height_outlined(fontnum));
}
int GetFontLineSpacing(int fontnum) {
if ((fontnum < 0) || (fontnum >= _GP(game).numfonts))
quit("!GetFontLineSpacing: invalid font number.");
return game_to_data_coord(getfontspacing_outlined(fontnum));
return game_to_data_coord(get_font_linespacing(fontnum));
}
void SetGUIBackgroundPic(int guin, int slotn) {

View File

@ -272,16 +272,6 @@ void LoadFonts(GameDataVersion data_ver) {
set_font_outline(i, FONT_OUTLINE_AUTO, FontInfo::kSquared, get_font_scaling_mul(i));
}
}
// Backward compatibility: if the real font's height != formal height
// and there's no custom linespacing, then set linespacing = formal height.
if (!is_bitmap_font(i)) {
int req_height = _GP(game).fonts[i].SizePt * _GP(game).fonts[i].SizeMultiplier;
int height = get_font_height(i);
if ((height != req_height) && (_GP(game).fonts[i].LineSpacing == 0)) {
set_font_linespacing(i, req_height + get_font_outline_padding(i));
}
}
}
// Additional fixups - after all the fonts are registered
@ -301,6 +291,27 @@ void LoadFonts(GameDataVersion data_ver) {
set_font_outline(i, FONT_OUTLINE_AUTO);
}
}
// Precalculate and cache any additional parameters; do this after all the fixups
for (int i = 0; i < _GP(game).numfonts; ++i) {
FontInfo &finfo = _GP(game).fonts[i];
const int height = get_font_height(i);
if (finfo.LineSpacing == 0) {
set_font_linespacing(i, height + 2 * finfo.AutoOutlineThickness);
// WORKAROUND: For qfg2vga at least, fInfo.SizePt == 0, which causes below
// to screw up line spacing. Since by the current upstream HEAD this has all
// been replaced anyway, for now I'm adding an explicit 0 check
if (finfo.SizePt != 0) {
// Backward compatibility: if the real font's height != formal height
// and there's no custom linespacing, then set linespacing = formal height.
const int compat_height = finfo.SizePt * finfo.SizeMultiplier;
if (height != compat_height) {
set_font_linespacing(i, compat_height + 2 * finfo.AutoOutlineThickness);
}
}
}
}
}
void LoadLipsyncData() {

View File

@ -123,7 +123,7 @@ void engine_setup_system_gamesize() {
void engine_init_resolution_settings(const Size game_size) {
Debug::Printf("Initializing resolution settings");
_GP(usetup).textheight = getfontheight_outlined(0) + 1;
_GP(usetup).textheight = get_font_height_outlined(0) + 1;
Debug::Printf(kDbgMsg_Info, "Game native resolution: %d x %d (%d bit)%s", game_size.Width, game_size.Height, _GP(game).color_depth * 8,
_GP(game).IsLegacyLetterbox() ? " letterbox-by-design" : "");

View File

@ -279,7 +279,7 @@ bool IAGSEngine::FSeek(soff_t offset, int origin, int32 handle) {
void IAGSEngine::DrawTextWrapped(int32 xx, int32 yy, int32 wid, int32 font, int32 color, const char *text) {
// TODO: use generic function from the engine instead of having copy&pasted code here
int linespacing = getfontspacing_outlined(font);
const int linespacing = get_font_linespacing(font);
if (break_up_text_into_lines(text, _GP(Lines), wid, font) == 0)
return;

View File

@ -246,7 +246,7 @@ struct FontInfo {
int8 Outline;
// Custom vertical render offset, used mainly for fixing broken fonts
int YOffset;
// custom line spacing between two lines of text (0 = use font height)
// Custom line spacing between two lines of text (0 = use font height)
int LineSpacing;
// When automatic outlining, thickness of the outline (0 = no auto outline)
int AutoOutlineThickness;

View File

@ -32,7 +32,6 @@
#include "ags/shared/util/string_utils.h"
#include "ags/globals.h"
namespace AGS3 {
using namespace AGS::Shared;
@ -172,13 +171,17 @@ int get_font_height(size_t fontNumber) {
return _GP(fonts)[fontNumber].Metrics.RealHeight;
}
int get_font_height_outlined(size_t fontNumber) {
if (fontNumber >= _GP(fonts).size() || !_GP(fonts)[fontNumber].Renderer)
return 0;
return _GP(fonts)[fontNumber].Metrics.RealHeight
+ 2 * _GP(fonts)[fontNumber].Info.AutoOutlineThickness;
}
int get_font_linespacing(size_t fontNumber) {
if (fontNumber >= _GP(fonts).size())
return 0;
int spacing = _GP(fonts)[fontNumber].Info.LineSpacing;
// If the spacing parameter is not provided, then return default
// spacing, that is font's height.
return spacing > 0 ? spacing : get_font_height(fontNumber);
return _GP(fonts)[fontNumber].Info.LineSpacing;
}
void set_font_linespacing(size_t fontNumber, int spacing) {
@ -186,12 +189,6 @@ void set_font_linespacing(size_t fontNumber, int spacing) {
_GP(fonts)[fontNumber].Info.LineSpacing = spacing;
}
bool use_default_linespacing(size_t fontNumber) {
if (fontNumber >= _GP(fonts).size())
return false;
return _GP(fonts)[fontNumber].Info.LineSpacing == 0;
}
// Project-dependent implementation
extern int get_text_width_outlined(const char *tex, int font);

View File

@ -86,12 +86,14 @@ int get_font_scaling_mul(size_t fontNumber);
int get_text_width(const char *texx, size_t fontNumber);
// Get font's height (maximal height of any line of text printed with this font)
int get_font_height(size_t fontNumber);
// TODO: GUI classes located in Common library do not make use of outlining,
// need to find a way to make all code use same functions.
// Get the maximal height of the given font, with corresponding outlining
int get_font_height_outlined(size_t fontNumber);
// Get font's line spacing
int get_font_linespacing(size_t fontNumber);
// Set font's line spacing
void set_font_linespacing(size_t fontNumber, int spacing);
// Get is font is meant to use default line spacing
bool use_default_linespacing(size_t fontNumber);
// Get font's outline type
int get_font_outline(size_t font_number);
// Get font's automatic outline thickness (if set)