[Scummvm-git-logs] scummvm master -> 8b90ea85df77f2e17db213d73dd73c8fa65b3ef1

dreammaster dreammaster at scummvm.org
Tue Sep 21 00:45:21 UTC 2021


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
8058862f7d AGS: Precalculate and save font's height on load
96ad02b3b9 AGS: Use real font height in game calculations, compat linespacing
d8335ed435 AGS: Partially revert previous commit: had engine logic moved to fonts
9d9080ffda AGS: Also return real TTF height in TTFFontRenderer::GetTextHeight()
d865acf606 AGS: introduced font outline style and thickness parameters
8b90ea85df AGS: Implemented auto outlining with custom thickness and style


Commit: 8058862f7d25fb17f7a6a0a476235fd8540a5aff
    https://github.com/scummvm/scummvm/commit/8058862f7d25fb17f7a6a0a476235fd8540a5aff
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-09-20T17:20:58-07:00

Commit Message:
AGS: Precalculate and save font's height on load

>From upstream 47001a398a1bc4ad022645ad21e1c891a3757167

Note: Since we don't implement alfont in full, the
referenced methods are stubbed in our alfont.cpp

Changed paths:
    engines/ags/lib/alfont/alfont.cpp
    engines/ags/lib/alfont/alfont.h
    engines/ags/shared/font/ags_font_renderer.h
    engines/ags/shared/font/fonts.cpp
    engines/ags/shared/font/fonts.h
    engines/ags/shared/font/ttf_font_renderer.cpp
    engines/ags/shared/font/ttf_font_renderer.h
    engines/ags/shared/font/wfn_font_renderer.cpp
    engines/ags/shared/font/wfn_font_renderer.h


diff --git a/engines/ags/lib/alfont/alfont.cpp b/engines/ags/lib/alfont/alfont.cpp
index 99fec416e6..188007b18c 100644
--- a/engines/ags/lib/alfont/alfont.cpp
+++ b/engines/ags/lib/alfont/alfont.cpp
@@ -98,6 +98,14 @@ void alfont_set_font_size(ALFONT_FONT *font, int size) {
 	font->_size = size;
 }
 
+int alfont_get_font_height(ALFONT_FONT *font) {
+	return font->_size;
+}
+
+int alfont_get_font_real_height(ALFONT_FONT *font) {
+	return font->_size;
+}
+
 const char *alfont_get_name(ALFONT_FONT *font) {
 	// TODO: Return ttf font name
 	return "Unsupported";
diff --git a/engines/ags/lib/alfont/alfont.h b/engines/ags/lib/alfont/alfont.h
index 61b80f488e..ee9c32e452 100644
--- a/engines/ags/lib/alfont/alfont.h
+++ b/engines/ags/lib/alfont/alfont.h
@@ -58,7 +58,8 @@ extern size_t alfont_text_height(ALFONT_FONT *font);
 extern void alfont_textout(BITMAP *bmp, ALFONT_FONT *font, ALFONT_FONT *refFont, const char *text, int x, int y, uint32 color);
 extern const char *alfont_get_name(ALFONT_FONT *font);
 extern void alfont_set_font_size(ALFONT_FONT *font, int size);
-
+extern int alfont_get_font_height(ALFONT_FONT *font);
+extern int alfont_get_font_real_height(ALFONT_FONT *font);
 
 } // namespace AGS3
 
diff --git a/engines/ags/shared/font/ags_font_renderer.h b/engines/ags/shared/font/ags_font_renderer.h
index 1625e4e4fe..e5e8d5429d 100644
--- a/engines/ags/shared/font/ags_font_renderer.h
+++ b/engines/ags/shared/font/ags_font_renderer.h
@@ -51,13 +51,20 @@ struct FontRenderParams {
 	int SizeMultiplier = 1;
 };
 
+// Used to tell font information after loading one
+struct LoadedFontInfo {
+	int Height = 0; // formal font height value
+	int RealHeight = 0; // real graphical height of a font
+};
+
 // NOTE: this extending interface is not yet exposed to plugins
 class IAGSFontRenderer2 {
 public:
 	virtual bool IsBitmapFont() = 0;
 	// Load font, applying extended font rendering parameters
-	virtual bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) = 0;
-	protected:
+	virtual bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params,
+		LoadedFontInfo *info) = 0;
+protected:
 	IAGSFontRenderer2() {}
 	~IAGSFontRenderer2() {}
 };
diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp
index 7f16cf5635..93450fd210 100644
--- a/engines/ags/shared/font/fonts.cpp
+++ b/engines/ags/shared/font/fonts.cpp
@@ -87,12 +87,28 @@ bool is_font_loaded(size_t fontNumber) {
 	return fontNumber < _GP(fonts).size() && _GP(fonts)[fontNumber].Renderer != nullptr;;
 }
 
+// Finish font's initialization
+static void post_init_font(size_t fontNumber) {
+	Font &font = _GP(fonts)[fontNumber];
+	if (font.LoadedInfo.Height == 0) {
+		// There is no explicit method for getting maximal possible height of any
+		// random font renderer at the moment; the implementations of GetTextHeight
+		// are allowed to return varied results depending on the text parameter.
+		// We use special line of text to get more or less reliable font height.
+		const char *height_test_string = "ZHwypgfjqhkilIK";
+		int height = font.Renderer->GetTextHeight(height_test_string, fontNumber);
+		font.LoadedInfo.Height = height;
+		font.LoadedInfo.RealHeight = height;
+	}
+}
+
 IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *renderer) {
 	if (fontNumber >= _GP(fonts).size())
 		return nullptr;
 	IAGSFontRenderer *oldRender = _GP(fonts)[fontNumber].Renderer;
 	_GP(fonts)[fontNumber].Renderer = renderer;
 	_GP(fonts)[fontNumber].Renderer2 = nullptr;
+	post_init_font(fontNumber);
 	return oldRender;
 }
 
@@ -156,12 +172,7 @@ void set_font_outline(size_t font_number, int outline_type) {
 int getfontheight(size_t fontNumber) {
 	if (fontNumber >= _GP(fonts).size() || !_GP(fonts)[fontNumber].Renderer)
 		return 0;
-	// There is no explicit method for getting maximal possible height of any
-	// random font renderer at the moment; the implementations of GetTextHeight
-	// are allowed to return varied results depending on the text parameter.
-	// We use special line of text to get more or less reliable font height.
-	const char *height_test_string = "ZHwypgfjqhkilIK";
-	return _GP(fonts)[fontNumber].Renderer->GetTextHeight(height_test_string, fontNumber);
+	return _GP(fonts)[fontNumber].LoadedInfo.Height;
 }
 
 int getfontlinespacing(size_t fontNumber) {
@@ -331,20 +342,23 @@ bool wloadfont_size(size_t fontNumber, const FontInfo &font_info) {
 		wfreefont(fontNumber);
 	FontRenderParams params;
 	params.SizeMultiplier = font_info.SizeMultiplier;
+	LoadedFontInfo load_info;
 
-	if (_GP(ttfRenderer).LoadFromDiskEx(fontNumber, font_info.SizePt, &params)) {
+	if (_GP(ttfRenderer).LoadFromDiskEx(fontNumber, font_info.SizePt, &params, &load_info)) {
 		_GP(fonts)[fontNumber].Renderer = &_GP(ttfRenderer);
 		_GP(fonts)[fontNumber].Renderer2 = &_GP(ttfRenderer);
-	} else if (_GP(wfnRenderer).LoadFromDiskEx(fontNumber, font_info.SizePt, &params)) {
+	} else if (_GP(wfnRenderer).LoadFromDiskEx(fontNumber, font_info.SizePt, &params, &load_info)) {
 		_GP(fonts)[fontNumber].Renderer = &_GP(wfnRenderer);
 		_GP(fonts)[fontNumber].Renderer2 = &_GP(wfnRenderer);
 	}
 
-	if (_GP(fonts)[fontNumber].Renderer) {
-		_GP(fonts)[fontNumber].Info = font_info;
-		return true;
-	}
-	return false;
+	if (!_GP(fonts)[fontNumber].Renderer)
+		return false;
+
+	_GP(fonts)[fontNumber].Info = font_info;
+	_GP(fonts)[fontNumber].LoadedInfo = load_info;
+	post_init_font(fontNumber);
+	return true;
 }
 
 void wgtprintf(Shared::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...) {
diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h
index 5636c02624..47025b0919 100644
--- a/engines/ags/shared/font/fonts.h
+++ b/engines/ags/shared/font/fonts.h
@@ -27,6 +27,7 @@
 #include "ags/shared/core/types.h"
 #include "ags/shared/util/string.h"
 #include "ags/shared/ac/game_struct_defines.h"
+#include "ags/shared/font/ags_font_renderer.h"
 
 namespace AGS3 {
 
@@ -43,6 +44,8 @@ struct Font {
 	IAGSFontRenderer *Renderer = nullptr;
 	IAGSFontRenderer2 *Renderer2 = nullptr;
 	FontInfo            Info;
+	// Values received from the renderer and saved for the reference
+	AGS3::LoadedFontInfo LoadedInfo;
 
 	Font();
 };
diff --git a/engines/ags/shared/font/ttf_font_renderer.cpp b/engines/ags/shared/font/ttf_font_renderer.cpp
index 9247bb8024..e44326264e 100644
--- a/engines/ags/shared/font/ttf_font_renderer.cpp
+++ b/engines/ags/shared/font/ttf_font_renderer.cpp
@@ -83,14 +83,15 @@ void TTFFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *desti
 }
 
 bool TTFFontRenderer::LoadFromDisk(int fontNumber, int fontSize) {
-	return LoadFromDiskEx(fontNumber, fontSize, nullptr);
+	return LoadFromDiskEx(fontNumber, fontSize, nullptr, nullptr);
 }
 
 bool TTFFontRenderer::IsBitmapFont() {
 	return false;
 }
 
-bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) {
+bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize,
+		const FontRenderParams *params, LoadedFontInfo *load_info) {
 	String file_name = String::FromFormat("agsfnt%d.ttf", fontNumber);
 	soff_t lenof = 0;
 	Stream *reader = _GP(AssetMgr)->OpenAsset(file_name, &lenof);
@@ -134,6 +135,12 @@ bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRen
 
 	_fontData[fontNumber].AlFont = alfptr;
 	_fontData[fontNumber].Params = params ? *params : FontRenderParams();
+
+	if (load_info) {
+		load_info->Height = alfont_get_font_height(alfptr);
+		load_info->RealHeight = alfont_get_font_real_height(alfptr);
+	}
+
 	return true;
 }
 
diff --git a/engines/ags/shared/font/ttf_font_renderer.h b/engines/ags/shared/font/ttf_font_renderer.h
index 5ad3f8102d..7ee9a2d8e2 100644
--- a/engines/ags/shared/font/ttf_font_renderer.h
+++ b/engines/ags/shared/font/ttf_font_renderer.h
@@ -48,7 +48,8 @@ public:
 
 	// IAGSFontRenderer2 implementation
 	bool IsBitmapFont() override;
-	bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) override;
+	bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params,
+		LoadedFontInfo *info) override;
 
 private:
 	struct FontData {
diff --git a/engines/ags/shared/font/wfn_font_renderer.cpp b/engines/ags/shared/font/wfn_font_renderer.cpp
index c58c901e55..78720d4b58 100644
--- a/engines/ags/shared/font/wfn_font_renderer.cpp
+++ b/engines/ags/shared/font/wfn_font_renderer.cpp
@@ -122,14 +122,15 @@ int RenderChar(Bitmap *ds, const int at_x, const int at_y, const WFNChar &wfn_ch
 }
 
 bool WFNFontRenderer::LoadFromDisk(int fontNumber, int fontSize) {
-	return LoadFromDiskEx(fontNumber, fontSize, nullptr);
+	return LoadFromDiskEx(fontNumber, fontSize, nullptr, nullptr);
 }
 
 bool WFNFontRenderer::IsBitmapFont() {
 	return true;
 }
 
-bool WFNFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) {
+bool WFNFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize,
+		const FontRenderParams *params, LoadedFontInfo *load_info) {
 	String file_name;
 	Stream *ffi = nullptr;
 	soff_t asset_size = 0;
diff --git a/engines/ags/shared/font/wfn_font_renderer.h b/engines/ags/shared/font/wfn_font_renderer.h
index 43e4c98433..24a730f4d9 100644
--- a/engines/ags/shared/font/wfn_font_renderer.h
+++ b/engines/ags/shared/font/wfn_font_renderer.h
@@ -32,6 +32,7 @@ class WFNFont;
 
 class WFNFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 {
 public:
+	// IAGSFontRenderer implementation
 	virtual ~WFNFontRenderer() {}
 
 	bool LoadFromDisk(int fontNumber, int fontSize) override;
@@ -43,8 +44,10 @@ public:
 	void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override;
 	void EnsureTextValidForFont(char *text, int fontNumber) override;
 
+	// IAGSFontRenderer2 implementation
 	bool IsBitmapFont() override;
-	bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) override;
+	bool LoadFromDiskEx(int fontNumber, int fontSize,
+		const FontRenderParams *params, LoadedFontInfo *info) override;
 
 private:
 	struct FontData {


Commit: 96ad02b3b9fb58125522fb38b303800f9dfeb8e9
    https://github.com/scummvm/scummvm/commit/96ad02b3b9fb58125522fb38b303800f9dfeb8e9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-09-20T17:20:58-07:00

Commit Message:
AGS: Use real font height in game calculations, compat linespacing

>From upstream  3a9b8f199e09b9919a201c1d2fa486a79761b339

Changed paths:
    engines/ags/engine/ac/display.cpp
    engines/ags/engine/ac/display.h
    engines/ags/shared/font/fonts.cpp
    engines/ags/shared/font/fonts.h


diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index 4d06e6e223..2a47c16d29 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -492,21 +492,8 @@ void wouttext_aligned(Bitmap *ds, int usexp, int yy, int oriwid, int usingfont,
 	wouttext_outline(ds, usexp, yy, usingfont, text_color, text);
 }
 
-int get_outline_adjustment(int font) {
-	// automatic outline fonts are 2 pixels taller
-	if (get_font_outline(font) == FONT_OUTLINE_AUTO) {
-		// scaled up bitmap font, push outline further out
-		if (is_bitmap_font(font) && get_font_scaling_mul(font) > 1)
-			return get_fixed_pixel_size(2);
-		// otherwise, just push outline by 1 pixel
-		else
-			return 2;
-	}
-	return 0;
-}
-
 int getfontheight_outlined(int font) {
-	return getfontheight(font) + get_outline_adjustment(font);
+	return getfontheight(font) + 2 * get_font_outline_thickness(font);
 }
 
 int getfontspacing_outlined(int font) {
diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h
index aa7395508d..9103adc6f0 100644
--- a/engines/ags/engine/ac/display.h
+++ b/engines/ags/engine/ac/display.h
@@ -54,7 +54,7 @@ void wouttext_outline(Shared::Bitmap *ds, int xxp, int yyp, int usingfont, color
 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 possible outlining in mind
+// Get the maximal height of the given font, with corresponding outlining
 int getfontheight_outlined(int font);
 // Get line spacing for the given font, with possible outlining in mind
 int getfontspacing_outlined(int font);
@@ -62,6 +62,7 @@ int getfontspacing_outlined(int font);
 int getfontlinegap(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
 int wgettextwidth_compensate(const char *tex, int font);
 void do_corner(Shared::Bitmap *ds, int sprn, int xx1, int yy1, int typx, int typy);
 // Returns the image of a button control on the GUI under given child index
diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp
index 93450fd210..b024e6a20a 100644
--- a/engines/ags/shared/font/fonts.cpp
+++ b/engines/ags/shared/font/fonts.cpp
@@ -37,8 +37,7 @@ namespace AGS3 {
 
 // Project-dependent implementation
 extern int wgettextwidth_compensate(const char *tex, int font);
-
-#define STD_BUFFER_SIZE 3000
+extern int get_fixed_pixel_size(int pixels);
 
 using namespace AGS::Shared;
 
@@ -100,6 +99,14 @@ static void post_init_font(size_t fontNumber) {
 		font.LoadedInfo.Height = height;
 		font.LoadedInfo.RealHeight = height;
 	}
+
+	// Backward compatibility: if the real height != formal height
+	// and there's no custom linespacing, then set linespacing = formal height.
+	if ((font.LoadedInfo.RealHeight != font.LoadedInfo.Height) &&
+		(font.Info.LineSpacing == 0)) {
+		font.Info.LineSpacing = font.LoadedInfo.Height +
+			2 * get_font_outline_thickness(fontNumber);
+	}
 }
 
 IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *renderer) {
@@ -154,6 +161,19 @@ int get_font_outline(size_t font_number) {
 	return _GP(fonts)[font_number].Info.Outline;
 }
 
+int get_font_outline_thickness(size_t font_number) {
+	if (font_number >= _GP(fonts).size())
+		return 0;
+	if (_GP(fonts)[font_number].Info.Outline == FONT_OUTLINE_AUTO) {
+		// scaled up bitmap font, push outline further out
+		if (is_bitmap_font(font_number) && get_font_scaling_mul(font_number) > 1)
+			return get_fixed_pixel_size(1);
+		else
+			return 1;
+	}
+	return 0;
+}
+
 int get_outline_font(size_t font_number) {
 	for (size_t fontNum = 0; fontNum < _GP(fonts).size(); ++fontNum) {
 		if (_GP(fonts)[fontNum].Info.Outline == (int)font_number)
@@ -172,7 +192,7 @@ void set_font_outline(size_t font_number, int outline_type) {
 int getfontheight(size_t fontNumber) {
 	if (fontNumber >= _GP(fonts).size() || !_GP(fonts)[fontNumber].Renderer)
 		return 0;
-	return _GP(fonts)[fontNumber].LoadedInfo.Height;
+	return _GP(fonts)[fontNumber].LoadedInfo.RealHeight;
 }
 
 int getfontlinespacing(size_t fontNumber) {
diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h
index 47025b0919..d2e0648188 100644
--- a/engines/ags/shared/font/fonts.h
+++ b/engines/ags/shared/font/fonts.h
@@ -75,6 +75,7 @@ bool font_supports_extended_characters(size_t fontNumber);
 // at random times (usually - drawing routines).
 // Need to check whether it is safe to completely remove it.
 void ensure_text_valid_for_font(char *text, size_t fontnum);
+// Get font's scaling multiplier
 int get_font_scaling_mul(size_t fontNumber);
 // Calculate actual width of a line of text
 int wgettextwidth(const char *texx, size_t fontNumber);
@@ -86,12 +87,14 @@ int getfontheight(size_t fontNumber);
 int getfontlinespacing(size_t fontNumber);
 // 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);
 int  get_outline_font(size_t font_number);
+// Get font's automatic outline thickness (if set)
+int  get_font_outline_thickness(size_t font_number);
+// Set font's outline type
 void set_font_outline(size_t font_number, int outline_type);
 // Outputs a single line of text on the defined position on bitmap, using defined font, color and parameters
-int getfontlinespacing(size_t fontNumber);
-// Print text on a surface using a given font
 void wouttextxy(Shared::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx);
 // Assigns FontInfo to the font
 void set_fontinfo(size_t fontNumber, const FontInfo &finfo);


Commit: d8335ed4352240f7d3fd63dbb2482c056e4c8b9d
    https://github.com/scummvm/scummvm/commit/d8335ed4352240f7d3fd63dbb2482c056e4c8b9d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-09-20T17:20:58-07:00

Commit Message:
AGS: Partially revert previous commit: had engine logic moved to fonts

>From upstream a4bafa3597a98a0df1cb5f5e921b2e6651c28a89

Changed paths:
    engines/ags/engine/ac/display.cpp
    engines/ags/shared/font/fonts.cpp


diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index 2a47c16d29..f0a2b69494 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -492,8 +492,21 @@ void wouttext_aligned(Bitmap *ds, int usexp, int yy, int oriwid, int usingfont,
 	wouttext_outline(ds, usexp, yy, usingfont, text_color, text);
 }
 
+// Get outline's thickness addition to the font's width or height
+int get_outline_padding(int font) {
+	if (get_font_outline(font) == FONT_OUTLINE_AUTO) {
+		// scaled up bitmap font, push outline further out
+		if (is_bitmap_font(font) && get_font_scaling_mul(font) > 1)
+			return get_fixed_pixel_size(2); // FIXME: should be 2 + get_fixed_pixel_size(2)?
+		// otherwise, just push outline by 1 pixel
+		else
+			return 2;
+	}
+	return 0;
+}
+
 int getfontheight_outlined(int font) {
-	return getfontheight(font) + 2 * get_font_outline_thickness(font);
+	return getfontheight(font) + get_outline_padding(font);
 }
 
 int getfontspacing_outlined(int font) {
@@ -511,18 +524,7 @@ int getheightoflines(int font, int numlines) {
 }
 
 int wgettextwidth_compensate(const char *tex, int font) {
-	int wdof = wgettextwidth(tex, font);
-
-	if (get_font_outline(font) == FONT_OUTLINE_AUTO) {
-		// scaled up SCI font, push outline further out
-		if (is_bitmap_font(font) && get_font_scaling_mul(font) > 1)
-			wdof += get_fixed_pixel_size(2);
-		// otherwise, just push outline by 1 pixel
-		else
-			wdof += get_fixed_pixel_size(1);
-	}
-
-	return wdof;
+	return wgettextwidth(tex, font) + get_outline_padding(font);
 }
 
 void do_corner(Bitmap *ds, int sprn, int x, int y, int offx, int offy) {
diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp
index b024e6a20a..df3e38da93 100644
--- a/engines/ags/shared/font/fonts.cpp
+++ b/engines/ags/shared/font/fonts.cpp
@@ -99,13 +99,20 @@ static void post_init_font(size_t fontNumber) {
 		font.LoadedInfo.Height = height;
 		font.LoadedInfo.RealHeight = height;
 	}
-
+	// FIXME: move this out of the font module, as compatibility fixes
+	// depend on the other game data, such as format version, etc.
 	// Backward compatibility: if the real height != formal height
 	// and there's no custom linespacing, then set linespacing = formal height.
 	if ((font.LoadedInfo.RealHeight != font.LoadedInfo.Height) &&
 		(font.Info.LineSpacing == 0)) {
-		font.Info.LineSpacing = font.LoadedInfo.Height +
-			2 * get_font_outline_thickness(fontNumber);
+		font.Info.LineSpacing = font.LoadedInfo.Height;
+		if (get_font_outline(fontNumber) == FONT_OUTLINE_AUTO) {
+			// scaled up bitmap fonts have extra outline offset
+			if (is_bitmap_font(fontNumber) && get_font_scaling_mul(fontNumber) > 1)
+				font.Info.LineSpacing += get_fixed_pixel_size(2);  // FIXME: should be 2 + get_fixed_pixel_size(2)?
+			else
+				font.Info.LineSpacing += 2;
+		}
 	}
 }
 


Commit: 9d9080ffda2226dbde1e2622ceb11acf540a03fe
    https://github.com/scummvm/scummvm/commit/9d9080ffda2226dbde1e2622ceb11acf540a03fe
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-09-20T17:20:58-07:00

Commit Message:
AGS: Also return real TTF height in TTFFontRenderer::GetTextHeight()

>From upstream 5115943fce180fe3e0bd9fe3678faa2d01b6d474

Changed paths:
    engines/ags/shared/font/ttf_font_renderer.cpp


diff --git a/engines/ags/shared/font/ttf_font_renderer.cpp b/engines/ags/shared/font/ttf_font_renderer.cpp
index e44326264e..f74a7b76c8 100644
--- a/engines/ags/shared/font/ttf_font_renderer.cpp
+++ b/engines/ags/shared/font/ttf_font_renderer.cpp
@@ -61,7 +61,7 @@ int TTFFontRenderer::GetTextWidth(const char *text, int fontNumber) {
 }
 
 int TTFFontRenderer::GetTextHeight(const char *text, int fontNumber) {
-	return alfont_text_height(_fontData[fontNumber].AlFont);
+	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) {


Commit: d865acf6062f2d6119df05c9fe6234b4668ef82d
    https://github.com/scummvm/scummvm/commit/d865acf6062f2d6119df05c9fe6234b4668ef82d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-09-20T17:20:59-07:00

Commit Message:
AGS: introduced font outline style and thickness parameters

>From upstream 43425f738dc6beb7d0758e256a840c5f37a4d38a

Changed paths:
    engines/ags/engine/ac/display.cpp
    engines/ags/engine/game/game_init.cpp
    engines/ags/shared/ac/game_struct_defines.h
    engines/ags/shared/ac/game_version.h
    engines/ags/shared/font/fonts.cpp
    engines/ags/shared/font/fonts.h
    engines/ags/shared/font/ttf_font_renderer.cpp
    engines/ags/shared/game/main_game_file.cpp


diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index f0a2b69494..5d157765fc 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -492,21 +492,8 @@ void wouttext_aligned(Bitmap *ds, int usexp, int yy, int oriwid, int usingfont,
 	wouttext_outline(ds, usexp, yy, usingfont, text_color, text);
 }
 
-// Get outline's thickness addition to the font's width or height
-int get_outline_padding(int font) {
-	if (get_font_outline(font) == FONT_OUTLINE_AUTO) {
-		// scaled up bitmap font, push outline further out
-		if (is_bitmap_font(font) && get_font_scaling_mul(font) > 1)
-			return get_fixed_pixel_size(2); // FIXME: should be 2 + get_fixed_pixel_size(2)?
-		// otherwise, just push outline by 1 pixel
-		else
-			return 2;
-	}
-	return 0;
-}
-
 int getfontheight_outlined(int font) {
-	return getfontheight(font) + get_outline_padding(font);
+	return getfontheight(font) + 2 * get_font_outline_thickness(font);
 }
 
 int getfontspacing_outlined(int font) {
@@ -524,7 +511,7 @@ int getheightoflines(int font, int numlines) {
 }
 
 int wgettextwidth_compensate(const char *tex, int font) {
-	return wgettextwidth(tex, font) + get_outline_padding(font);
+	return wgettextwidth(tex, font) + 2 * get_font_outline_thickness(font);
 }
 
 void do_corner(Bitmap *ds, int sprn, int x, int y, int offx, int offy) {
diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp
index 798fc556c5..d1a2b719b4 100644
--- a/engines/ags/engine/game/game_init.cpp
+++ b/engines/ags/engine/game/game_init.cpp
@@ -258,8 +258,28 @@ HError InitAndRegisterGameEntities() {
 
 void LoadFonts(GameDataVersion data_ver) {
 	for (int i = 0; i < _GP(game).numfonts; ++i) {
-		if (!wloadfont_size(i, _GP(game).fonts[i]))
+		FontInfo &finfo = _GP(game).fonts[i];
+		if (!wloadfont_size(i, finfo))
 			quitprintf("Unable to load font %d, no renderer could load a matching file", i);
+
+		const bool is_wfn = is_bitmap_font(i);
+		// Outline thickness corresponds to 1 game pixel by default;
+		// but if it's a scaled up bitmap font in a legacy hires game, then it equals to scale
+		if ((data_ver < kGameVersion_360) && _GP(game).IsLegacyHiRes()) {
+			if (is_wfn && (finfo.Outline == FONT_OUTLINE_AUTO)) {
+				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_wfn) {
+			int req_height = finfo.SizePt * finfo.SizeMultiplier;
+			int height = getfontheight(i);
+			if ((height != req_height) && (finfo.LineSpacing == 0)) {
+				set_font_linespacing(i, req_height + 2 * get_font_outline_thickness(i));
+			}
+		}
 	}
 }
 
diff --git a/engines/ags/shared/ac/game_struct_defines.h b/engines/ags/shared/ac/game_struct_defines.h
index d769188c86..0d0fa2fc35 100644
--- a/engines/ags/shared/ac/game_struct_defines.h
+++ b/engines/ags/shared/ac/game_struct_defines.h
@@ -232,18 +232,27 @@ struct SpriteInfo {
 // provide instructions on adjusting drawing position, as well as arranging
 // multiple lines, and similar cases.
 struct FontInfo {
+	enum AutoOutlineStyle : int {
+		kSquared = 0,
+		kRounded = 1,
+	};
+
 	// General font's loading and rendering flags
-	uint32_t      Flags = 0;
+	uint32_t      Flags;
 	// Font size, in points (basically means pixels in AGS)
-	int           SizePt = 0;
+	int           SizePt;
 	// Factor to multiply base font size by
-	int           SizeMultiplier = 0;
+	int           SizeMultiplier;
 	// Outlining font index, or auto-outline flag
-	int8          Outline = 0;
+	int8          Outline;
 	// Custom vertical render offset, used mainly for fixing broken fonts
-	int           YOffset = 0;
+	int           YOffset;
 	// custom line spacing between two lines of text (0 = use font height)
-	int           LineSpacing = 0;
+	int           LineSpacing;
+	// When automatic outlining, thickness of the outline (0 = no auto outline)
+	int           AutoOutlineThickness;
+	// When automatic outlining, style of the outline
+	AutoOutlineStyle AutoOutlineStyle;
 
 	FontInfo();
 };
diff --git a/engines/ags/shared/ac/game_version.h b/engines/ags/shared/ac/game_version.h
index 9d4b6467b4..84710733ea 100644
--- a/engines/ags/shared/ac/game_version.h
+++ b/engines/ags/shared/ac/game_version.h
@@ -146,6 +146,7 @@ enum GameDataVersion {
 	kGameVersion_341 = 48,
 	kGameVersion_341_2 = 49,
 	kGameVersion_350 = 50,
+	kGameVersion_360 = 3060000,
 	kGameVersion_Current = kGameVersion_350
 };
 
diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp
index df3e38da93..cc6fa18da8 100644
--- a/engines/ags/shared/font/fonts.cpp
+++ b/engines/ags/shared/font/fonts.cpp
@@ -58,7 +58,9 @@ FontInfo::FontInfo()
 	, SizeMultiplier(1)
 	, Outline(FONT_OUTLINE_NONE)
 	, YOffset(0)
-	, LineSpacing(0) {
+	, LineSpacing(0)
+	, AutoOutlineStyle(kSquared)
+	, AutoOutlineThickness(0) {
 }
 
 
@@ -114,6 +116,9 @@ static void post_init_font(size_t fontNumber) {
 				font.Info.LineSpacing += 2;
 		}
 	}
+	if (font.Info.Outline != FONT_OUTLINE_AUTO) {
+		font.Info.AutoOutlineThickness = 0;
+	}
 }
 
 IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *renderer) {
@@ -171,29 +176,26 @@ int get_font_outline(size_t font_number) {
 int get_font_outline_thickness(size_t font_number) {
 	if (font_number >= _GP(fonts).size())
 		return 0;
-	if (_GP(fonts)[font_number].Info.Outline == FONT_OUTLINE_AUTO) {
-		// scaled up bitmap font, push outline further out
-		if (is_bitmap_font(font_number) && get_font_scaling_mul(font_number) > 1)
-			return get_fixed_pixel_size(1);
-		else
-			return 1;
-	}
-	return 0;
+	return _GP(fonts)[font_number].Info.AutoOutlineThickness;
 }
 
-int get_outline_font(size_t font_number) {
+int get_font_outline_font(size_t font_number) {
 	for (size_t fontNum = 0; fontNum < _GP(fonts).size(); ++fontNum) {
 		if (_GP(fonts)[fontNum].Info.Outline == (int)font_number)
 			return fontNum;
 	}
 
 	return FONT_OUTLINE_NONE;
+	return _GP(fonts)[font_number].Info.AutoOutlineThickness;
 }
 
-void set_font_outline(size_t font_number, int outline_type) {
+void set_font_outline(size_t font_number, int outline_type,
+	enum FontInfo::AutoOutlineStyle style, int thickness) {
 	if (font_number >= _GP(fonts).size())
 		return;
 	_GP(fonts)[font_number].Info.Outline = outline_type;
+	_GP(fonts)[font_number].Info.AutoOutlineStyle = style;
+	_GP(fonts)[font_number].Info.AutoOutlineThickness = thickness;
 }
 
 int getfontheight(size_t fontNumber) {
@@ -211,6 +213,11 @@ int getfontlinespacing(size_t fontNumber) {
 	return spacing > 0 ? spacing : getfontheight(fontNumber);
 }
 
+void set_font_linespacing(size_t fontNumber, int spacing) {
+	if (fontNumber < _GP(fonts).size())
+		_GP(fonts)[fontNumber].Info.LineSpacing = spacing;
+}
+
 bool use_default_linespacing(size_t fontNumber) {
 	if (fontNumber >= _GP(fonts).size())
 		return false;
diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h
index d2e0648188..dcdc1ad852 100644
--- a/engines/ags/shared/font/fonts.h
+++ b/engines/ags/shared/font/fonts.h
@@ -24,7 +24,7 @@
 #define AGS_SHARED_FONT_FONTS_H
 
 #include "ags/lib/std/vector.h"
-#include "ags/shared/core/types.h"
+#include "ags/shared/ac/game_struct_defines.h"
 #include "ags/shared/util/string.h"
 #include "ags/shared/ac/game_struct_defines.h"
 #include "ags/shared/font/ags_font_renderer.h"
@@ -85,15 +85,19 @@ int wgettextheight(const char *text, size_t fontNumber);
 int getfontheight(size_t fontNumber);
 // Get font's line spacing
 int getfontlinespacing(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);
-int  get_outline_font(size_t font_number);
 // Get font's automatic outline thickness (if set)
 int  get_font_outline_thickness(size_t font_number);
+// get the source font associated with an outline font
+int get_font_outline_font(size_t font_number);
 // Set font's outline type
-void set_font_outline(size_t font_number, int outline_type);
+void set_font_outline(size_t font_number, int outline_type,
+	enum FontInfo::AutoOutlineStyle style = FontInfo::kSquared, int thickness = 1);
 // Outputs a single line of text on the defined position on bitmap, using defined font, color and parameters
 void wouttextxy(Shared::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx);
 // Assigns FontInfo to the font
diff --git a/engines/ags/shared/font/ttf_font_renderer.cpp b/engines/ags/shared/font/ttf_font_renderer.cpp
index f74a7b76c8..a8017a6492 100644
--- a/engines/ags/shared/font/ttf_font_renderer.cpp
+++ b/engines/ags/shared/font/ttf_font_renderer.cpp
@@ -68,7 +68,7 @@ void TTFFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *desti
 	if (y > destination->cb)  // optimisation
 		return;
 
-	int srcFontNum = get_outline_font(fontNumber);
+	int srcFontNum = get_font_outline_font(fontNumber);
 	ALFONT_FONT *srcFont = nullptr;
 	if (srcFontNum != FONT_OUTLINE_NONE) {
 		// Get the font without outline (if it's loaded) for use in
diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp
index 3f7f1899ee..cfe290520a 100644
--- a/engines/ags/shared/game/main_game_file.cpp
+++ b/engines/ags/shared/game/main_game_file.cpp
@@ -31,6 +31,7 @@
 #include "ags/shared/core/asset_manager.h"
 #include "ags/shared/debugging/out.h"
 #include "ags/shared/game/main_game_file.h"
+#include "ags/shared/font/fonts.h"
 #include "ags/shared/gui/gui_main.h"
 #include "ags/shared/script/cc_error.h"
 #include "ags/shared/util/aligned_stream.h"
@@ -478,6 +479,15 @@ void UpgradeFonts(GameSetupStruct &game, GameDataVersion data_ver) {
 			}
 		}
 	}
+	if (data_ver < kGameVersion_360) {
+		for (int i = 0; i < game.numfonts; ++i) {
+			FontInfo &finfo = game.fonts[i];
+			if (finfo.Outline == FONT_OUTLINE_AUTO) {
+				finfo.AutoOutlineStyle = FontInfo::kSquared;
+				finfo.AutoOutlineThickness = 1;
+			}
+		}
+	}
 }
 
 // Convert audio data to the current version


Commit: 8b90ea85df77f2e17db213d73dd73c8fa65b3ef1
    https://github.com/scummvm/scummvm/commit/8b90ea85df77f2e17db213d73dd73c8fa65b3ef1
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-09-20T17:20:59-07:00

Commit Message:
AGS: Implemented auto outlining with custom thickness and style

>From upstream f2736d21677d2db4b0559c1ded31e284b8a8f64f

Changed paths:
    engines/ags/engine/ac/display.cpp
    engines/ags/engine/ac/display.h


diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index 5d157765fc..acd8c49436 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -60,6 +60,7 @@
 namespace AGS3 {
 
 using namespace AGS::Shared;
+using namespace AGS::Shared::BitmapHelper;
 
 struct DisplayVars {
 	int lineheight;    // font's height of single line
@@ -228,7 +229,6 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
 				wouttext_aligned(text_window_ds, ttxleft, ttyp, oriwid, usingfont, text_color, _GP(Lines)[ee].GetCStr(), _GP(play).text_align);
 			} else {
 				text_color = text_window_ds->GetCompatibleColor(asspch);
-				//wouttext_outline(ttxp,ttyp,usingfont,lines[ee]);
 				wouttext_aligned(text_window_ds, ttxleft, ttyp, wii, usingfont, text_color, _GP(Lines)[ee].GetCStr(), _GP(play).speech_text_align);
 			}
 		}
@@ -452,34 +452,72 @@ bool ShouldAntiAliasText() {
 	return (_GP(game).options[OPT_ANTIALIASFONTS] != 0 || ::AGS::g_vm->_forceTextAA);
 }
 
-void wouttext_outline(Shared::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx) {
-	color_t outline_color = ds->GetCompatibleColor(_GP(play).speech_text_shadow);
-	if (get_font_outline(usingfont) >= 0) {
-		// MACPORT FIX 9/6/5: cast
-		wouttextxy(ds, xxp, yyp, (int)get_font_outline(usingfont), outline_color, texx);
-	} else if (get_font_outline(usingfont) == FONT_OUTLINE_AUTO) {
-		int outlineDist = 1;
-
-		if (is_bitmap_font(usingfont) && get_font_scaling_mul(usingfont) > 1) {
-			// if it's a scaled up bitmap font, move the outline out more
-			outlineDist = get_fixed_pixel_size(1);
+void wouttextxy_AutoOutline(Bitmap *ds, size_t font, int32_t color, const char *texx, int &xxp, int &yyp) {
+	using AGS::Shared::kBitmap_Transparency;
+
+	int thickness = _GP(game).fonts.at(font).AutoOutlineThickness;
+	auto style = _GP(game).fonts.at(font).AutoOutlineStyle;
+	if (thickness <= 0)
+		return;
+
+	size_t const t_width = wgettextwidth(texx, font);
+	size_t const t_height = wgettextheight(texx, font);
+	Bitmap *outline_stencil =
+		CreateTransparentBitmap(t_width, t_height + 2 * thickness, ds->GetColorDepth());
+	Bitmap *texx_stencil =
+		CreateTransparentBitmap(t_width, t_height, ds->GetColorDepth());
+	if (!outline_stencil || !texx_stencil)
+		return;
+	wouttextxy(texx_stencil, 0, 0, font, color, texx);
+
+	// move start of text so that the outline doesn't drop off the bitmap
+	xxp += thickness;
+	int const outline_y = yyp;
+	yyp += thickness;
+
+	int largest_y_diff_reached_so_far = -1;
+	for (int x_diff = thickness; x_diff >= 0; x_diff--) {
+		// Integer arithmetics: In the following, we use terms k*(k + 1) to account for rounding.
+		//     (k + 0.5)^2 == k*k + 2*k*0.5 + 0.5^2 == k*k + k + 0.25 ==approx. k*(k + 1)
+		int y_term_limit = thickness * (thickness + 1);
+		if (FontInfo::kRounded == style)
+			y_term_limit -= x_diff * x_diff;
+
+		// extend the outline stencil to the top and bottom
+		for (int y_diff = largest_y_diff_reached_so_far + 1;
+			y_diff <= thickness && y_diff * y_diff <= y_term_limit;
+			y_diff++) {
+			outline_stencil->Blit(texx_stencil, 0, thickness - y_diff, kBitmap_Transparency);
+			if (y_diff > 0)
+				outline_stencil->Blit(texx_stencil, 0, thickness + y_diff, kBitmap_Transparency);
+			largest_y_diff_reached_so_far = y_diff;
 		}
 
-		// move the text over so that it's still within the bounding rect
-		xxp += outlineDist;
-		yyp += outlineDist;
-
-		wouttextxy(ds, xxp - outlineDist, yyp, usingfont, outline_color, texx);
-		wouttextxy(ds, xxp + outlineDist, yyp, usingfont, outline_color, texx);
-		wouttextxy(ds, xxp, yyp + outlineDist, usingfont, outline_color, texx);
-		wouttextxy(ds, xxp, yyp - outlineDist, usingfont, outline_color, texx);
-		wouttextxy(ds, xxp - outlineDist, yyp - outlineDist, usingfont, outline_color, texx);
-		wouttextxy(ds, xxp - outlineDist, yyp + outlineDist, usingfont, outline_color, texx);
-		wouttextxy(ds, xxp + outlineDist, yyp + outlineDist, usingfont, outline_color, texx);
-		wouttextxy(ds, xxp + outlineDist, yyp - outlineDist, usingfont, outline_color, texx);
+		// stamp the outline stencil to the left and right of the text
+		ds->Blit(outline_stencil, xxp - x_diff, outline_y, kBitmap_Transparency);
+		if (x_diff > 0)
+			ds->Blit(outline_stencil, xxp + x_diff, outline_y, kBitmap_Transparency);
 	}
 
-	wouttextxy(ds, xxp, yyp, usingfont, text_color, texx);
+	delete texx_stencil;
+	delete outline_stencil;
+}
+
+// Draw an outline if requested, then draw the text on top 
+void wouttext_outline(Shared::Bitmap *ds, int xxp, int yyp, int font, color_t text_color, const char *texx) {
+	size_t const text_font = static_cast<size_t>(font);
+	// Draw outline (a backdrop) if requested
+	color_t const outline_color = ds->GetCompatibleColor(_GP(play).speech_text_shadow);
+	int const outline_font = get_font_outline(font);
+	if (outline_font >= 0)
+		wouttextxy(ds, xxp, yyp, static_cast<size_t>(outline_font), outline_color, texx);
+	else if (outline_font == FONT_OUTLINE_AUTO)
+		wouttextxy_AutoOutline(ds, text_font, outline_color, texx, xxp, yyp);
+	else
+		; // no outline
+
+	// Draw text on top
+	wouttextxy(ds, xxp, yyp, text_font, text_color, texx);
 }
 
 void wouttext_aligned(Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, color_t text_color, const char *text, HorAlignment align) {
diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h
index 9103adc6f0..9a9abf71a9 100644
--- a/engines/ags/engine/ac/display.h
+++ b/engines/ags/engine/ac/display.h
@@ -50,6 +50,7 @@ bool ShouldAntiAliasText();
 int GetTextDisplayLength(const char *text);
 // Calculates number of game loops for displaying a text on screen
 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,




More information about the Scummvm-git-logs mailing list