-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add "Show String Picture" #2870
Conversation
Implementation is through a new class Game_Window which provides more flexibility when we add even more event controlled window functionality later.
By converting from pt to px
These are used to store StringPictures in an incompatible but more flexible way. Removed the sprites deque as I'm unsure what the purpose of this queue is. Makes the window interaction easier to implement.
3dd16f4
to
1d26553
Compare
Needs liblcf changes so our CI has some issues building it I built Windows manually:
|
New exe with this patch (Old text lines were not removed, wups :)): diff --git a/src/game_windows.cpp b/src/game_windows.cpp
index cad84c1b..3cae08ad 100644
--- a/src/game_windows.cpp
+++ b/src/game_windows.cpp
@@ -87,6 +87,8 @@ Game_Windows::Window_User* Game_Windows::GetWindowPtr(int id) {
}
bool Game_Windows::Window_User::Create(const WindowParams& params) {
+ Erase();
+
data.width = params.width;
data.height = params.height;
data.system_name = lcf::DBString(params.system_name); |
Is a maniac patch feature making this crash not that critical.
c7a96bc
to
d3e7ada
Compare
Hi ! the origin is not taken into consideration If you use a StringPic, then a normal Picture with the same ID, the Picture will keep the StringPic inside the "new" Picture ( Sorry I'm really a noob with Git, I don't know how I can explain better >< ) |
45a97a0
to
7e7fce9
Compare
@MackValentine thanks I added your fixes |
I found some other bugs : https://github.com/MackValentine/easyrpg-player-maniacs/blob/master/src/game_windows.cpp |
7e7fce9
to
cc2693f
Compare
… the file is not in index.json
/1 is now resolved /3 is imo a bug in Maniac Patch. It adds space for a command that should be zero space. So I won't implement this. edit: now also /2 and /4 are fixed |
- size autocalc when width or height are 0 - system graphic always loaded - always correct system graphic used - style (no shadow etc.) correctly applied - drawing without border margin works
jenkins: test this please |
I'm still totally confused concerning the font metrics. As already noticed earlier there are multiple confusions about pt/px in the layouting of the text. Found another one: The ExFont is automatically rescaled but because it is not a font (so not handled by WinApi) it uses the "pt" value verbatim as "px" without converting it. So for larger fonts with ExFont you get nonsense like this (much larger than the rest): diff for resizable ExFont I gave up on for now because the metrics are so fcked up diff --git a/src/cache.cpp b/src/cache.cpp
index a6ae6693f..f2c379e91 100644
--- a/src/cache.cpp
+++ b/src/cache.cpp
@@ -385,12 +385,29 @@ BitmapRef Cache::System(StringView file) {
return LoadBitmap<Material::System>(file);
}
-BitmapRef Cache::Exfont() {
- const auto key = MakeHashKey("ExFont", "ExFont", false);
+BitmapRef Cache::Exfont(int size) {
+ const auto key = MakeHashKey("ExFont", std::to_string(size), false);
auto it = cache.find(key);
if (it == cache.end()) {
+ if (size != 12) {
+ // Allow ExFont of custom size
+ auto is = FileFinder::OpenImage("ExFont", "ExFont" + std::to_string(size));
+ if (is) {
+ auto bmp = Bitmap::Create(std::move(is), true);
+ if (bmp) {
+ return AddToCache(key, bmp);
+ }
+ }
+
+ // Not found: Resize the original (result will look bad)
+ auto bmp = Bitmap::Create(size, size, true);
+ auto exfont = Exfont(12);
+ bmp->ZoomOpacityBlit(0, 0, 0, 0, *exfont, exfont->GetRect(), size / 12.0, size / 12.0, Opacity::Opaque());
+ return AddToCache(key, bmp);
+ }
+
// Allow overwriting of built-in exfont with a custom ExFont image file
// exfont_custom is filled by Player::CreateGameObjects
BitmapRef exfont_img;
diff --git a/src/cache.h b/src/cache.h
index 5ea53a5cf..c288be5bf 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -43,7 +43,7 @@ namespace Cache {
BitmapRef Battlecharset(StringView filename);
BitmapRef Battleweapon(StringView filename);
BitmapRef Charset(StringView filename);
- BitmapRef Exfont();
+ BitmapRef Exfont(int size = 12);
BitmapRef Faceset(StringView filename);
BitmapRef Frame(StringView filename, bool transparent = true);
BitmapRef Gameover(StringView filename);
diff --git a/src/font.cpp b/src/font.cpp
index bc6ae2a8c..99adc2efe 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -185,7 +185,7 @@ namespace {
Rect vGetSize(char32_t glyph) const override;
GlyphRet vRender(char32_t glyph) const override;
private:
- mutable BitmapRef bm;
+ mutable BitmapRef bm12;
};
/** FreeType Font Cache */
@@ -792,38 +792,44 @@ ExFont::ExFont() : Font("exfont", HEIGHT, false, false) {
FontRef Font::exfont = std::make_shared<ExFont>();
Font::GlyphRet ExFont::vRender(char32_t glyph) const {
- if (EP_UNLIKELY(!bm)) { bm = Bitmap::Create(WIDTH, HEIGHT, true); }
- auto exfont = Cache::Exfont();
+ if (EP_UNLIKELY(!bm12)) { bm12 = Bitmap::Create(WIDTH, HEIGHT, true); }
+
+ auto bm = bm12;
+ if (EP_UNLIKELY(current_style.size != 12)) {
+ bm = Bitmap::Create(current_style.size, current_style.size, true);
+ }
+
+ auto exfont = Cache::Exfont(current_style.size);
bool is_lower = (glyph >= 'a' && glyph <= 'z');
bool is_upper = (glyph >= 'A' && glyph <= 'Z');
if (!is_lower && !is_upper) {
// Invalid ExFont
- return { bm, {WIDTH, 0}, {0, 0}, false };
+ return { bm, {current_style.size, 0}, {0, 0}, false };
}
glyph = is_lower ? (glyph - 'a' + 26) : (glyph - 'A');
- Rect const rect((glyph % 13) * WIDTH, (glyph / 13) * HEIGHT, WIDTH, HEIGHT);
+ Rect const rect((glyph % 13) * current_style.size, (glyph / 13) * current_style.size, current_style.size, current_style.size);
bm->Clear();
bm->Blit(0, 0, *exfont, rect, Opacity::Opaque());
// EasyRPG Extension: Support for colored ExFont
bool has_color = false;
const auto* pixels = reinterpret_cast<uint8_t*>(bm->pixels());
- // For performance reasons only check the red channel of every 4th pixel (16 = 4 * 4 RGBA pixel) for color
+ // For performance reasons only check every 4th pixel for color
for (int i = 0; i < bm->pitch() * bm->height(); i += 16) {
- auto pixel = pixels[i];
- if (pixel != 0 && pixel != 255) {
+ auto pixel = *reinterpret_cast<const uint32_t*>(pixels + i);
+ if (pixel != 0 && pixel != 0xFFFFFFFF) {
has_color = true;
break;
}
}
- return { bm, {WIDTH, 0}, {0, 0}, has_color };
+ return { bm, {current_style.size, 0}, {0, 0}, has_color };
}
Rect ExFont::vGetSize(char32_t) const {
- return Rect(0, 0, WIDTH, HEIGHT);
+ return { 0, 0, current_style.size, current_style.size };
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A great foundation on free text rendering 👍.
7034b03
to
1ea24c6
Compare
Depends on #2914 merge it first
WIP PR to get some feedback from testers in :)
https://easyrpg.org/play/pr2870/?game=strpic TestCase. Sound is messed up. Likely uses the Maniac extension to do this. Well is a good test for this soon
Incompatible change
Font location
Maniac Patch loads from the Windows font directory. Loading fonts in a cross platform way for all operating systems is alot of work so I decided to not support this.
Instead the Font is searched for in the
Font
folder of the game. Supported are all fonts that FreeType supports. The name must be the same as the one specified in the Show String Picture command.To match with typical font naming conventions the search order is:
FONT_NAME-BoldItalic
FONT_NAME-Bold
FONT_NAME-Italic
FONT_NAME-Regular
FONT_NAME
Savegames
The StrPics are loaded and saved. However the way how the save data is structured is incompatible to the Maniac approach. I could have been compatible here but I want to have more flexibility for further custom Window functionality.
Using the built-in font
The built-in font is a bitmap font and does not support scaling.
Though you can replace the built-in font by providing "Font/Font.ttf" and "Font/Font2.ttf" depending on the system graphic font setting. Then scaling will work.
Known issues, do not report them, I work on them:
Disable Text Gradient option unimplementedEmscripten Async loading missingWhen using the same font with different sizes the rendering looks wrong (the font is shared to save memory). My guess is that the size HarfBuzz uses becomes desynced with the size FreeType uses.New features
You can translate the text with lcftrans :)
Full Harfbuzz shaping support for rendering complex scripts.
Not planned
"The rendering is not pixel perfect to Maniacs". Well yes. This is just how fonts work. FreeType renders them a bit different. Nothing I can do here. But the size and position of the window when using "auto" should be the same in both engines.
Loading fonts installed on the current system.
The letter spacing option is not supported because this is not supported by HarfBuzz and doing it manual will fail for any non-trivial case (that needs some kind of shaping logic).
Bold/Italic: Will only work when the font provides a bold/italic typeface. No automatic transformation is happening.