Skip to content
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

Multiple font related optimization and improvements #491

Merged
merged 8 commits into from
May 15, 2024
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 45 additions & 45 deletions internal/c/libqb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
#include "shell.h"
#include "thread.h"

// These are here because they are used in func__loadfont()
#include <string>
#include <algorithm>

int32 disableEvents = 0;

// Global console vvalues
Expand Down Expand Up @@ -3563,7 +3567,7 @@ void convert_text_to_utf16(int32 fonthandle, void *buf, int32 size) {
unicode16_buf = (uint16 *)malloc(unicode16_buf_size);
}
// convert text
if ((fontflags[fonthandle] & 32) && (fonthandle != NULL)) { // unicode font
if ((fontflags[fonthandle] & FONT_LOAD_UNICODE) && (fonthandle != NULL)) { // unicode font
if (size == 1)
size = 4;
convert_unicode(32, buf, size, 16, unicode16_buf);
Expand Down Expand Up @@ -11202,7 +11206,7 @@ void printchr(int32 character) {
x = im->cursor_x - 1;
y = (im->cursor_y - 1) * fontheight[f];
h = fontheight[f];
if ((fontflags[f] & 32) == 0)
if ((fontflags[f] & FONT_LOAD_UNICODE) == 0)
character &= 255; // unicodefontsupport

// if (mode==1) img[i].print_mode=3;//fill
Expand All @@ -11212,7 +11216,7 @@ void printchr(int32 character) {
if (f >= 32) { // custom font

// 8-bit / alpha-disabled 32-bit / dont-blend(alpha may still be applied)
if ((im->bytes_per_pixel == 1) || ((im->bytes_per_pixel == 4) && (im->alpha_disabled)) || (fontflags[f] & 8)) {
if ((im->bytes_per_pixel == 1) || ((im->bytes_per_pixel == 4) && (im->alpha_disabled)) || (fontflags[f] & FONT_LOAD_DONTBLEND)) {

// render character
static int32 ok;
Expand Down Expand Up @@ -11408,7 +11412,7 @@ int32_t chrwidth(uint32_t character) {

// Custom font
// a740g: No need to render just to find the pixel length
if ((fontflags[f] & 32)) { // UNICODE character
if ((fontflags[f] & FONT_LOAD_UNICODE)) { // UNICODE character
w = FontPrintWidthUTF32(font[f], (uint32_t *)&character, 1);
} else { // ASCII character
character &= 255;
Expand Down Expand Up @@ -11684,7 +11688,7 @@ void qbs_print(qbs *str, int32 finish_on_new_line) {

character = str->chr[i];

if (fontflags[write_page->font] & 32) { // unicode font
if (fontflags[write_page->font] & FONT_LOAD_UNICODE) { // unicode font
if (i > (str->len - 4))
break; // not enough data for a utf32 encoding
character = *((int32 *)(&str->chr[i]));
Expand Down Expand Up @@ -20141,7 +20145,7 @@ void sub__printstring(float x, float y, qbs *text, int32 i, int32 passed) {
if (f >= 32) { // custom font

// 8-bit / alpha-disabled 32-bit / dont-blend(alpha may still be applied)
if ((im->bytes_per_pixel == 1) || ((im->bytes_per_pixel == 4) && (im->alpha_disabled)) || (fontflags[f] & 8)) {
if ((im->bytes_per_pixel == 1) || ((im->bytes_per_pixel == 4) && (im->alpha_disabled)) || (fontflags[f] & FONT_LOAD_DONTBLEND)) {

// render character
static int32 ok;
Expand Down Expand Up @@ -20376,18 +20380,14 @@ int32 func__printwidth(qbs *text, int32 screenhandle, int32 passed) {
}

/// @brief f = _LOADFONT(ttf_filename$, height[, "monospace,dontblend,unicode,memory"][, index])
/// @param f The font file path name or a font memory buffer when loading from memory
/// @param qbsFileName The font file path name or a font memory buffer when loading from memory
/// @param size The font height in pixels
/// @param requirements This can be monospace, dontblend, unicode, memory
/// @param qbsRequirements This can be monospace, dontblend, unicode, memory
/// @param font_index The index of the font to load from a font collection
/// @param passed Which optional arguments were passed
/// @return Returns a valid handle on success or zero on failure
int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t font_index, int32_t passed) {
// Some QB strings that we'll need
static qbs *fileNameZ = nullptr;
static qbs *reqs = nullptr;

if (is_error_pending() || !file_name->len)
int32_t func__loadfont(const qbs *qbsFileName, int32_t size, const qbs *qbsRequirements, int32_t font_index, int32_t passed) {
if (is_error_pending() || !qbsFileName->len)
return INVALID_FONT_HANDLE; // return invalid handle for any garbage input

// validate size
Expand All @@ -20396,12 +20396,6 @@ int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t
return INVALID_FONT_HANDLE;
}

if (!fileNameZ)
fileNameZ = qbs_new(0, 0);

if (!reqs)
reqs = qbs_new(0, 0);

auto isLoadFromMemory = false; // should the font be loaded from memory?
int32_t options = 0; // font flags that we'll prepare and save to fontflags[]

Expand All @@ -20411,29 +20405,35 @@ int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t
// 8 dontblend (blending is the default in 32-bit alpha-enabled modes)
// 16 monospace
// 32 unicode
if ((passed & 1) && requirements->len) {
FONT_DEBUG_PRINT("Parsing requirements");
if ((passed & 1) && qbsRequirements->len) {
std::string requirements(reinterpret_cast<char *>(qbsRequirements->chr), qbsRequirements->len);
std::transform(requirements.begin(), requirements.end(), requirements.begin(), [](unsigned char c) { return std::toupper(c); });

qbs_set(reqs, qbs_ucase(requirements)); // Convert tmp str to perm str
FONT_DEBUG_PRINT("Parsing requirements string: %s", requirements.c_str());

if (func_instr(1, reqs, qbs_new_txt("DONTBLEND"), 1)) {
if (requirements.find("DONTBLEND") != std::string::npos) {
options |= FONT_LOAD_DONTBLEND;
FONT_DEBUG_PRINT("DONTBLEND requested");
FONT_DEBUG_PRINT("No alpha blending requested");
}

if (func_instr(1, reqs, qbs_new_txt("MONOSPACE"), 1)) {
if (requirements.find("MONOSPACE") != std::string::npos) {
options |= FONT_LOAD_MONOSPACE;
FONT_DEBUG_PRINT("MONOSPACE requested");
FONT_DEBUG_PRINT("Monospaced font requested");
}

if (func_instr(1, reqs, qbs_new_txt("UNICODE"), 1)) {
if (requirements.find("UNICODE") != std::string::npos) {
options |= FONT_LOAD_UNICODE;
FONT_DEBUG_PRINT("UNICODE requested");
FONT_DEBUG_PRINT("Unicode requested");
}

if (func_instr(1, reqs, qbs_new_txt("MEMORY"), 1)) {
if (requirements.find("MEMORY") != std::string::npos) {
isLoadFromMemory = true;
FONT_DEBUG_PRINT("MEMORY requested");
FONT_DEBUG_PRINT("Loading from memory requested");
}

if (requirements.find("AUTOMONO") != std::string::npos) {
options |= FONT_LOAD_AUTOMONO;
FONT_DEBUG_PRINT("Automatic monospacing requested");
}
}

Expand All @@ -20449,13 +20449,13 @@ int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t
int32_t bytes;

if (isLoadFromMemory) {
content = file_name->chr; // we should not free this!!!
bytes = file_name->len;
content = qbsFileName->chr; // we should not free this!!!
bytes = qbsFileName->len;
FONT_DEBUG_PRINT("Loading font from memory. Size = %i", bytes);
} else {
qbs_set(fileNameZ, qbs_add(file_name, qbs_new_txt_len("\0", 1))); // s1 = filename + CHR$(0)
content = FontLoadFileToMemory(filepath_fix_directory(fileNameZ), &bytes); // this we must free!!!
FONT_DEBUG_PRINT("Loading font from file %s", fileNameZ->chr);
std::string fileName(reinterpret_cast<char *>(qbsFileName->chr), qbsFileName->len);
content = FontLoadFileToMemory(filepath_fix_directory(fileName), &bytes); // this we must free!!!
FONT_DEBUG_PRINT("Loading font from file %s", fileName.c_str());
}

if (!content)
Expand Down Expand Up @@ -20489,9 +20489,9 @@ int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t
return INVALID_FONT_HANDLE;

font[i] = h;
fontflags[i] = options;
fontheight[i] = size;
fontwidth[i] = FontWidth(h);
fontflags[i] = options;

return i;
}
Expand Down Expand Up @@ -20537,8 +20537,8 @@ void sub__font(int32 f, int32 i, int32 passed) {
return;
}

if (im->text && ((fontflags[f] & 16) == 0)) { // fontflags[f] & 16 is the bit which we set for MONOSPACE fonts. If it's a SCREEN 0 screen, and the font
error(5);// isn't monospaced, toss and error and return.
if (im->text && ((fontflags[f] & FONT_LOAD_MONOSPACE) == 0)) { // fontflags[f] & 16 is the bit which we set for MONOSPACE fonts. If it's a SCREEN 0 screen, and the font
error(5); // isn't monospaced, toss an error and return.
return;
}
// note: font changes to text screen mode images requires:
Expand Down Expand Up @@ -29585,18 +29585,18 @@ int main(int argc, char *argv[]) {
fontheight[8] = 8;
fontheight[14] = 14;
fontheight[16] = 16;
fontflags[8] = 16;
fontflags[14] = 16;
fontflags[16] = 16; // monospace flag
fontflags[8] = FONT_LOAD_MONOSPACE;
fontflags[14] = FONT_LOAD_MONOSPACE;
fontflags[16] = FONT_LOAD_MONOSPACE; // monospace flag
fontwidth[8 + 1] = 8 * 2;
fontwidth[14 + 1] = 8 * 2;
fontwidth[16 + 1] = 8 * 2;
fontheight[8 + 1] = 8;
fontheight[14 + 1] = 14;
fontheight[16 + 1] = 16;
fontflags[8 + 1] = 16;
fontflags[14 + 1] = 16;
fontflags[16 + 1] = 16; // monospace flag
fontflags[8 + 1] = FONT_LOAD_MONOSPACE;
fontflags[14 + 1] = FONT_LOAD_MONOSPACE;
fontflags[16 + 1] = FONT_LOAD_MONOSPACE; // monospace flag

memset(img, 0, IMG_BUFFERSIZE * sizeof(img_struct));
x = newimg(); // reserve index 0
Expand Down
7 changes: 4 additions & 3 deletions internal/c/libqb/include/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
FONT_DEBUG_PRINT("Condition (%s) failed", #_exp_)
#else
# ifdef _MSC_VER
# define FONT_DEBUG_PRINT(_fmt_, ...) // Don't do anything in release builds
# define FONT_DEBUG_PRINT(_fmt_, ...) // Don't do anything in release builds
# else
# define FONT_DEBUG_PRINT(_fmt_, _args_...) // Don't do anything in release builds
# endif
# define FONT_DEBUG_CHECK(_exp_) // Don't do anything in release builds
# define FONT_DEBUG_CHECK(_exp_) // Don't do anything in release builds
#endif

#define INVALID_FONT_HANDLE 0
Expand All @@ -32,6 +32,7 @@
#define FONT_LOAD_DONTBLEND 8
#define FONT_LOAD_MONOSPACE 16
#define FONT_LOAD_UNICODE 32
#define FONT_LOAD_AUTOMONO 64
// Font render options
#define FONT_RENDER_MONOCHROME 1

Expand All @@ -41,7 +42,7 @@ struct qbs;
extern uint16_t codepage437_to_unicode16[];

uint8_t *FontLoadFileToMemory(const char *file_path_name, int32_t *out_bytes);
int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t default_pixel_height, int32_t which_font, int32_t options);
int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t default_pixel_height, int32_t which_font, int32_t &options);
void FontFree(int32_t fh);
int32_t FontWidth(int32_t fh);
bool FontRenderTextUTF32(int32_t fh, const uint32_t *codepoint, int32_t codepoints, int32_t options, uint8_t **out_data, int32_t *out_x, int32_t *out_y);
Expand Down
Loading