Merge branch 'QB64-Phoenix-Edition:main' into midi-update
|
@ -11413,7 +11413,7 @@ int32_t chrwidth(uint32_t character) {
|
|||
// Custom font
|
||||
// a740g: No need to render just to find the pixel length
|
||||
if ((fontflags[f] & FONT_LOAD_UNICODE)) { // UNICODE character
|
||||
w = FontPrintWidthUTF32(font[f], (uint32_t *)&character, 1);
|
||||
w = FontPrintWidthUTF32(font[f], (char32_t *)&character, 1);
|
||||
} else { // ASCII character
|
||||
character &= 255;
|
||||
w = FontPrintWidthASCII(font[f], (uint8_t *)&character, 1);
|
||||
|
@ -30354,7 +30354,7 @@ void display() {
|
|||
render_option = 1;
|
||||
if (rt_data_last)
|
||||
free(rt_data_last);
|
||||
ok = FontRenderTextUTF32(font[f], &chr_utf32, 1, render_option, &rt_data, &rt_w, &rt_h);
|
||||
ok = FontRenderTextUTF32(font[f], (char32_t *)&chr_utf32, 1, render_option, &rt_data, &rt_w, &rt_h);
|
||||
rt_data_last = rt_data;
|
||||
cp2 = rt_data;
|
||||
f_pitch = 0;
|
||||
|
@ -31964,11 +31964,11 @@ extern "C" void qb64_os_event_linux(XEvent *event, Display *display, int *qb64_o
|
|||
|
||||
if (*qb64_os_event_info == OS_EVENT_POST_PROCESSING) {
|
||||
switch (event->type) {
|
||||
case EnterNotify:
|
||||
case FocusIn:
|
||||
window_focused = -1;
|
||||
break;
|
||||
|
||||
case LeaveNotify:
|
||||
case FocusOut:
|
||||
window_focused = 0;
|
||||
// Iterate over all modifiers
|
||||
for (uint32 key = VK + QBVK_RSHIFT; key <= VK + QBVK_MODE; key++) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// QB64-PE Font Library
|
||||
// Powered by FreeType 2.4.12 (https://github.com/vinniefalco/FreeTypeAmalgam)
|
||||
// Powered by FreeType (https://freetype.org/)
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
@ -45,14 +45,15 @@ 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);
|
||||
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);
|
||||
bool FontRenderTextUTF32(int32_t fh, const char32_t *codepoint, int32_t codepoints, int32_t options, uint8_t **out_data, int32_t *out_x, int32_t *out_y);
|
||||
bool FontRenderTextASCII(int32_t fh, const uint8_t *codepoint, int32_t codepoints, int32_t options, uint8_t **out_data, int32_t *out_x, int32_t *out_y);
|
||||
int32_t FontPrintWidthUTF32(int32_t fh, const uint32_t *codepoint, int32_t codepoints);
|
||||
int32_t FontPrintWidthUTF32(int32_t fh, const char32_t *codepoint, int32_t codepoints);
|
||||
int32_t FontPrintWidthASCII(int32_t fh, const uint8_t *codepoint, int32_t codepoints);
|
||||
|
||||
qbs *func__md5(qbs *text);
|
||||
int32_t func__UFontHeight(int32_t qb64_fh, int32_t passed);
|
||||
int32_t func__UPrintWidth(const qbs *text, int32_t utf_encoding, int32_t qb64_fh, int32_t passed);
|
||||
int32_t func__ULineSpacing(int32_t qb64_fh, int32_t passed);
|
||||
void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_t max_width, int32_t utf_encoding, int32_t qb64_fh, int32_t passed);
|
||||
void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_t max_width, int32_t utf_encoding, int32_t qb64_fh, int32_t dst_img,
|
||||
int32_t passed);
|
||||
int32_t func__UCharPos(const qbs *text, void *arr, int32_t utf_encoding, int32_t qb64_fh, int32_t passed);
|
||||
|
|
|
@ -70,13 +70,11 @@ void sub_environ(qbs *str) {
|
|||
buf = (char *)malloc(str->len + 1);
|
||||
buf[str->len] = '\0';
|
||||
memcpy(buf, str->chr, str->len);
|
||||
// Name and value may be separated by = or space
|
||||
separator = strchr(buf, ' ');
|
||||
if (!separator) {
|
||||
separator = strchr(buf, '=');
|
||||
}
|
||||
if (!separator) {
|
||||
// Name and value may be separated by = or space, whichever appears first.
|
||||
separator = buf + strcspn(buf, " =");
|
||||
if (*separator == '\0') {
|
||||
// It is an error is there is no separator
|
||||
free(buf);
|
||||
error(5);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -635,7 +635,7 @@ qbs *func__files(qbs *qbsFileSpec, int32_t passed) {
|
|||
std::string fileSpec(reinterpret_cast<char *>(qbsFileSpec->chr), qbsFileSpec->len);
|
||||
|
||||
if (fileSpec.empty())
|
||||
fileSpec = "*.*";
|
||||
fileSpec = "*";
|
||||
|
||||
if (FS_DirectoryExists(filepath_fix_directory(fileSpec))) {
|
||||
directory = fileSpec;
|
||||
|
|
|
@ -1155,7 +1155,10 @@ void fgOpenWindow( SFG_Window* window, const char* title,
|
|||
StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
|
||||
ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
|
||||
VisibilityChangeMask | EnterWindowMask | LeaveWindowMask |
|
||||
PointerMotionMask | ButtonMotionMask;
|
||||
PointerMotionMask | ButtonMotionMask |
|
||||
// QB64-PE: custom code begin
|
||||
FocusChangeMask;
|
||||
// QB64-PE: custom code end
|
||||
winAttr.background_pixmap = None;
|
||||
winAttr.background_pixel = 0;
|
||||
winAttr.border_pixel = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// QB64-PE Font Library
|
||||
// Powered by FreeType 2.4.12 (https://github.com/vinniefalco/FreeTypeAmalgam)
|
||||
// Powered by FreeType (https://freetype.org/)
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define FONT_DEBUG 0
|
||||
|
@ -12,12 +12,15 @@
|
|||
#include "libqb-common.h"
|
||||
#include "mutex.h"
|
||||
#include "rounding.h"
|
||||
#include <codecvt>
|
||||
#include <cstdio>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
extern "C" {
|
||||
#include "freetype/md5.h"
|
||||
}
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
|
@ -40,146 +43,82 @@ void pset_and_clip(int32_t x, int32_t y, uint32_t col);
|
|||
|
||||
/// @brief A simple class that manages conversions from various encodings to UTF32
|
||||
class UTF32 {
|
||||
private:
|
||||
// See DecodeUTF8() below for more details
|
||||
enum UTF8DecoderState { ACCEPT = 0, REJECT = 1 };
|
||||
|
||||
/// @brief See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
/// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
/// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
/// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
/// is furnished to do so, subject to the following conditions:
|
||||
/// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
/// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
/// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
/// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
/// @param state The current state of the decoder
|
||||
/// @param codep The decoded codepoint after state changes to UTF8DecodeState::ACCEPT
|
||||
/// @param byte The next UTF-8 byte in the input stream
|
||||
/// @return UTF8DecodeState::ACCEPT if enough bytes have been read for a character,
|
||||
/// UTF8DecodeState::REJECT if the byte is not allowed to occur at its position,
|
||||
/// and some other positive value if more bytes have to be read
|
||||
uint32_t DecodeUTF8(uint32_t *state, uint32_t *codep, uint8_t byte) {
|
||||
// clang-format off
|
||||
static const uint8_t utf8d[] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
|
||||
0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
|
||||
0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
|
||||
0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
|
||||
1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
|
||||
1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
|
||||
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
uint32_t type = utf8d[byte];
|
||||
*codep = (*state != UTF8DecoderState::ACCEPT) ? (byte & 0x3fu) | (*codep << 6) : (0xff >> type) & (byte);
|
||||
*state = utf8d[256 + *state * 16 + type];
|
||||
|
||||
return *state;
|
||||
}
|
||||
static const uint32_t MAX_UNICODE_CODEPOINT = 0x10FFFFu;
|
||||
|
||||
public:
|
||||
std::u32string string; // UTF32 string
|
||||
|
||||
UTF32 &operator=(const UTF32 &) = delete;
|
||||
UTF32 &operator=(UTF32 &&) = delete;
|
||||
|
||||
std::vector<uint32_t> codepoints; // UTF32 codepoint dynamic array
|
||||
|
||||
/// @brief Converts an ASCII array to UTF-32
|
||||
/// @param str The ASCII array
|
||||
/// @param byte_len The size of the array in bytes
|
||||
/// @brief Converts an ASCII string to UTF-32
|
||||
/// @param str The ASCII string
|
||||
/// @param len The size of the string in bytes
|
||||
/// @return The number of codepoints that were converted
|
||||
size_t ConvertASCII(const uint8_t *str, size_t byte_len) {
|
||||
// Clear the codepoint vector
|
||||
codepoints.clear();
|
||||
size_t ConvertASCII(const uint8_t *str, size_t len) {
|
||||
string.resize(len);
|
||||
|
||||
// Convert the ASCII string
|
||||
for (size_t i = 0; i < byte_len; i++)
|
||||
codepoints.push_back(codepage437_to_unicode16[str[i]]);
|
||||
for (size_t i = 0; i < len; i++)
|
||||
string[i] = codepage437_to_unicode16[str[i]];
|
||||
|
||||
return codepoints.size();
|
||||
return string.size();
|
||||
}
|
||||
|
||||
/// @brief Converts an UTF-8 array to UTF-32. This does not check for BOM
|
||||
/// @param str The UTF-8 array
|
||||
/// @param byte_len The size of the array in bytes
|
||||
/// @brief Converts an UTF-8 string to UTF-32
|
||||
/// @param str The UTF-8 string
|
||||
/// @param len The size of the string in bytes
|
||||
/// @return The number of codepoints that were converted
|
||||
size_t ConvertUTF8(const uint8_t *str, size_t byte_len) {
|
||||
// Clear the codepoint vector
|
||||
codepoints.clear();
|
||||
|
||||
uint32_t prevState = UTF8DecoderState::ACCEPT, currentState = UTF8DecoderState::ACCEPT;
|
||||
uint32_t cp;
|
||||
|
||||
for (size_t i = 0; i < byte_len; i++, prevState = currentState) {
|
||||
switch (DecodeUTF8(¤tState, &cp, str[i])) {
|
||||
case UTF8DecoderState::ACCEPT:
|
||||
// Good codepoint
|
||||
codepoints.push_back(cp);
|
||||
break;
|
||||
|
||||
case UTF8DecoderState::REJECT:
|
||||
// Codepoint would be U+FFFD (replacement character)
|
||||
cp = 0xFFFD;
|
||||
currentState = UTF8DecoderState::ACCEPT;
|
||||
if (prevState != UTF8DecoderState::ACCEPT)
|
||||
--i;
|
||||
codepoints.push_back(cp);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Need to read continuation bytes
|
||||
continue;
|
||||
}
|
||||
size_t ConvertUTF8(const uint8_t *str, size_t len) {
|
||||
try {
|
||||
string = std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t>().from_bytes((const char *)str, (const char *)str + len);
|
||||
} catch (...) {
|
||||
string.clear();
|
||||
}
|
||||
|
||||
return codepoints.size();
|
||||
return string.size();
|
||||
}
|
||||
|
||||
/// @brief Converts an UTF-16LE array to UTF-32. This does not check for BOM
|
||||
/// @param str The UTF-16LE array
|
||||
/// @param byte_len The size of the array in bytes
|
||||
/// @brief Converts an UTF-16 LE/BE string (with BOM or naked) to UTF-32
|
||||
/// @param str The UTF-16 string. If no BOM is present, little-endian is assumed
|
||||
/// @param len The size of the string in bytes
|
||||
/// @return The number of codepoints that were converted
|
||||
size_t ConvertUTF16(const uint8_t *str, size_t byte_len) {
|
||||
// Clear the codepoint vector
|
||||
codepoints.clear();
|
||||
|
||||
// We'll assume the worst case scenario and allocate a buffer that is byte_len / 2 codepoints long
|
||||
auto len16 = byte_len / sizeof(uint16_t);
|
||||
auto str16 = (const uint16_t *)str;
|
||||
uint32_t cp;
|
||||
|
||||
for (size_t i = 0; i < len16; i++) {
|
||||
auto ch = str16[i];
|
||||
|
||||
// If the character is a surrogate, we need to combine it with the next character to get the actual codepoint
|
||||
if (ch >= 0xD800 && ch <= 0xDBFF && i + 1 < len16) {
|
||||
auto ch2 = str16[i + 1];
|
||||
if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
|
||||
cp = ((ch - 0xD800) << 10) + (ch2 - 0xDC00) + 0x10000;
|
||||
++i; // skip the second surrogate
|
||||
size_t ConvertUTF16(const uint8_t *str, size_t len) {
|
||||
try {
|
||||
if (len > 2) {
|
||||
// Detect BOM
|
||||
if (str[0] == 0xFF && str[1] == 0xFE) {
|
||||
// Little-endian
|
||||
string = std::wstring_convert<
|
||||
std::codecvt_utf16<char32_t, MAX_UNICODE_CODEPOINT,
|
||||
static_cast<std::codecvt_mode>(std::codecvt_mode::consume_header | std::codecvt_mode::little_endian)>,
|
||||
char32_t>()
|
||||
.from_bytes((const char *)str, (const char *)str + len);
|
||||
} else if (str[0] == 0xFE && str[1] == 0xFF) {
|
||||
// Big-endian (C++ default)
|
||||
string =
|
||||
std::wstring_convert<std::codecvt_utf16<char32_t, MAX_UNICODE_CODEPOINT, std::codecvt_mode::consume_header>, char32_t>().from_bytes(
|
||||
(const char *)str, (const char *)str + len);
|
||||
} else {
|
||||
cp = 0xFFFD; // invalid surrogate pair
|
||||
// No BOM, assuming little-endian by default
|
||||
string = std::wstring_convert<
|
||||
std::codecvt_utf16<char32_t, MAX_UNICODE_CODEPOINT,
|
||||
static_cast<std::codecvt_mode>(std::codecvt_mode::consume_header | std::codecvt_mode::little_endian)>,
|
||||
char32_t>()
|
||||
.from_bytes((const char *)str, (const char *)str + len);
|
||||
}
|
||||
} else if (ch >= 0xDC00 && ch <= 0xDFFF) {
|
||||
cp = 0xFFFD; // invalid surrogate pair
|
||||
} else {
|
||||
cp = ch;
|
||||
// Short string, assuming little-endian by default
|
||||
string = std::wstring_convert<
|
||||
std::codecvt_utf16<char32_t, MAX_UNICODE_CODEPOINT,
|
||||
static_cast<std::codecvt_mode>(std::codecvt_mode::consume_header | std::codecvt_mode::little_endian)>,
|
||||
char32_t>()
|
||||
.from_bytes((const char *)str, (const char *)str + len);
|
||||
}
|
||||
|
||||
codepoints.push_back(cp);
|
||||
} catch (...) {
|
||||
string.clear();
|
||||
}
|
||||
|
||||
return codepoints.size();
|
||||
return string.size();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -317,7 +256,7 @@ struct FontManager {
|
|||
/// @param codepoint A valid UTF-32 codepoint
|
||||
/// @param parentFont The parent font object
|
||||
/// @return True if successful or if bitmap is already cached
|
||||
bool CacheBitmap(uint32_t codepoint, Font *parentFont) {
|
||||
bool CacheBitmap(char32_t codepoint, Font *parentFont) {
|
||||
if (!bitmap) {
|
||||
// Get the glyph index first and store it
|
||||
// Note that this can return a valid glyph index but the index need not have any glyph bitmap
|
||||
|
@ -396,7 +335,7 @@ struct FontManager {
|
|||
}
|
||||
};
|
||||
|
||||
std::unordered_map<uint32_t, Glyph *> glyphs; // holds pointers to cached glyph data for codepoints
|
||||
std::unordered_map<char32_t, Glyph *> glyphs; // holds pointers to cached glyph data for codepoints
|
||||
|
||||
// Delete copy and move constructors and assignments
|
||||
Font(const Font &) = delete;
|
||||
|
@ -436,7 +375,7 @@ struct FontManager {
|
|||
/// @param codepoint A valid UTF-32 codepoint
|
||||
/// @param isMono True for mono bitmap and false for gray
|
||||
/// @return The glyph pointer if successful or if the glyph is already in the map, nullptr otherwise
|
||||
Glyph *GetGlyph(uint32_t codepoint, bool isMono) {
|
||||
Glyph *GetGlyph(char32_t codepoint, bool isMono) {
|
||||
if (glyphs.count(codepoint) == 0) {
|
||||
// The glyph is not cached yet
|
||||
auto newGlyph = new Glyph;
|
||||
|
@ -471,7 +410,7 @@ struct FontManager {
|
|||
/// @param codepoint The codepoint array (string)
|
||||
/// @param codepoints The number of codepoints in the array
|
||||
/// @return The length of the string in pixels
|
||||
FT_Pos GetStringPixelWidth(const uint32_t *codepoint, size_t codepoints) {
|
||||
FT_Pos GetStringPixelWidth(const char32_t *codepoint, size_t codepoints) {
|
||||
if (monospaceWidth) // return monospace width simply by multiplying the fixed width by the codepoints
|
||||
return monospaceWidth * codepoints;
|
||||
|
||||
|
@ -896,7 +835,7 @@ int32_t FontWidth(int32_t fh) {
|
|||
/// @param codepoint The UTF32 codepoint array
|
||||
/// @param codepoints The number of codepoints
|
||||
/// @return Length in pixels
|
||||
int32_t FontPrintWidthUTF32(int32_t fh, const uint32_t *codepoint, int32_t codepoints) {
|
||||
int32_t FontPrintWidthUTF32(int32_t fh, const char32_t *codepoint, int32_t codepoints) {
|
||||
libqb_mutex_guard lock(fontManager.m);
|
||||
|
||||
if (codepoints > 0) {
|
||||
|
@ -922,7 +861,7 @@ int32_t FontPrintWidthASCII(int32_t fh, const uint8_t *codepoint, int32_t codepo
|
|||
|
||||
// Attempt to convert the string to UTF32 and get the actual width in pixels
|
||||
auto count = utf32.ConvertASCII(codepoint, codepoints);
|
||||
return FontPrintWidthUTF32(fh, utf32.codepoints.data(), count);
|
||||
return FontPrintWidthUTF32(fh, utf32.string.data(), count);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -937,7 +876,7 @@ int32_t FontPrintWidthASCII(int32_t fh, const uint8_t *codepoint, int32_t codepo
|
|||
/// @param out_x A pointer to the output width of the rendered text in pixels
|
||||
/// @param out_y A pointer to the output height of the rendered text in pixels
|
||||
/// @return success = 1, failure = 0
|
||||
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) {
|
||||
bool FontRenderTextUTF32(int32_t fh, const char32_t *codepoint, int32_t codepoints, int32_t options, uint8_t **out_data, int32_t *out_x, int32_t *out_y) {
|
||||
libqb_mutex_guard lock(fontManager.m);
|
||||
|
||||
FONT_DEBUG_CHECK(IS_VALID_FONT_HANDLE(fh));
|
||||
|
@ -972,7 +911,7 @@ bool FontRenderTextUTF32(int32_t fh, const uint32_t *codepoint, int32_t codepoin
|
|||
auto glyph = fnt->GetGlyph(cp, isMonochrome);
|
||||
if (glyph) {
|
||||
glyph->RenderBitmap(outBuf, strPixSize.x, strPixSize.y,
|
||||
penX + glyph->bitmap->bearing.x + fnt->monospaceWidth / 2 - glyph->bitmap->advanceWidth / 2,
|
||||
penX + glyph->bitmap->bearing.x + (fnt->monospaceWidth >> 1) - (glyph->bitmap->advanceWidth >> 1),
|
||||
fnt->baseline - glyph->bitmap->bearing.y);
|
||||
penX += fnt->monospaceWidth;
|
||||
}
|
||||
|
@ -1025,7 +964,7 @@ bool FontRenderTextASCII(int32_t fh, const uint8_t *codepoint, int32_t codepoint
|
|||
|
||||
// Attempt to convert the string to UTF32 and forward to FontRenderTextUTF32()
|
||||
auto count = utf32.ConvertASCII(codepoint, codepoints);
|
||||
return FontRenderTextUTF32(fh, utf32.codepoints.data(), count, options, out_data, out_x, out_y);
|
||||
return FontRenderTextUTF32(fh, utf32.string.data(), count, options, out_data, out_x, out_y);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1082,7 +1021,7 @@ int32_t func__UFontHeight(int32_t qb64_fh, int32_t passed) {
|
|||
auto face = fnt->face;
|
||||
|
||||
if (FT_IS_SCALABLE(face))
|
||||
return (((FT_Pos)face->ascender - (FT_Pos)face->descender) * fnt->defaultHeight) / (FT_Pos)face->units_per_EM;
|
||||
return FT_MulDiv(((FT_Long)face->ascender - (FT_Long)face->descender), (FT_Long)fnt->defaultHeight, (FT_Long)face->units_per_EM);
|
||||
|
||||
return fnt->defaultHeight;
|
||||
}
|
||||
|
@ -1120,31 +1059,31 @@ int32_t func__UPrintWidth(const qbs *text, int32_t utf_encoding, int32_t qb64_fh
|
|||
}
|
||||
|
||||
// Convert the string to UTF-32 if needed
|
||||
uint32_t const *str32 = nullptr;
|
||||
char32_t const *str32 = nullptr;
|
||||
size_t codepoints = 0;
|
||||
|
||||
switch (utf_encoding) {
|
||||
case 32: // UTF-32: no conversion needed
|
||||
str32 = (uint32_t *)text->chr;
|
||||
codepoints = text->len / sizeof(uint32_t);
|
||||
str32 = (char32_t *)text->chr;
|
||||
codepoints = text->len / sizeof(char32_t);
|
||||
break;
|
||||
|
||||
case 16: // UTF-16: conversion required
|
||||
codepoints = utf32.ConvertUTF16(text->chr, text->len);
|
||||
if (codepoints)
|
||||
str32 = utf32.codepoints.data();
|
||||
str32 = utf32.string.data();
|
||||
break;
|
||||
|
||||
case 8: // UTF-8: conversion required
|
||||
codepoints = utf32.ConvertUTF8(text->chr, text->len);
|
||||
if (codepoints)
|
||||
str32 = utf32.codepoints.data();
|
||||
str32 = utf32.string.data();
|
||||
break;
|
||||
|
||||
default: // ASCII: conversion required
|
||||
codepoints = utf32.ConvertASCII(text->chr, text->len);
|
||||
if (codepoints)
|
||||
str32 = utf32.codepoints.data();
|
||||
str32 = utf32.string.data();
|
||||
}
|
||||
|
||||
if (qb64_fh < 32)
|
||||
|
@ -1184,7 +1123,7 @@ int32_t func__ULineSpacing(int32_t qb64_fh, int32_t passed) {
|
|||
auto face = fnt->face;
|
||||
|
||||
if (FT_IS_SCALABLE(face))
|
||||
return ((FT_Pos)face->height * fnt->defaultHeight) / (FT_Pos)face->units_per_EM;
|
||||
return FT_MulDiv((FT_Long)face->height, (FT_Long)fnt->defaultHeight, (FT_Long)face->units_per_EM);
|
||||
|
||||
return fnt->defaultHeight;
|
||||
}
|
||||
|
@ -1193,28 +1132,23 @@ int32_t func__ULineSpacing(int32_t qb64_fh, int32_t passed) {
|
|||
/// @param start_x The starting x position
|
||||
/// @param start_y The starting y position
|
||||
/// @param text The text that needs to be rendered
|
||||
/// @param max_width The maximum width of the text (rendering will be clipped beyond width)
|
||||
/// @param utf_encoding The UTF encoding of the text (0 = ASCII, 8 = UTF-8, 16 - UTF-16, 32 = UTF-32)
|
||||
/// @param qb64_fh A QB64 font handle (this can be a builtin font as well)
|
||||
/// @param max_width [optional] The maximum width of the text (rendering will be clipped beyond width)
|
||||
/// @param utf_encoding [optional] The UTF encoding of the text (0 = ASCII, 8 = UTF-8, 16 - UTF-16, 32 = UTF-32)
|
||||
/// @param qb64_fh [optional] A QB64 font handle (this can be a builtin font as well)
|
||||
/// @param dst_img [optional] A QB64 image handle (zero designates current SCREEN page)
|
||||
/// @param passed Optional arguments flag
|
||||
void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_t max_width, int32_t utf_encoding, int32_t qb64_fh, int32_t passed) {
|
||||
void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_t max_width, int32_t utf_encoding, int32_t qb64_fh, int32_t dst_img,
|
||||
int32_t passed) {
|
||||
libqb_mutex_guard lock(fontManager.m);
|
||||
|
||||
if (is_error_pending() || !text->len)
|
||||
return;
|
||||
|
||||
// Check if we are in text mode and generate an error if we are
|
||||
if (write_page->text) {
|
||||
error(QB_ERROR_ILLEGAL_FUNCTION_CALL);
|
||||
return;
|
||||
}
|
||||
|
||||
FONT_DEBUG_PRINT("Graphics mode set. Proceeding...");
|
||||
|
||||
// Check max width
|
||||
if (passed & 1) {
|
||||
if (max_width < 1)
|
||||
if (max_width < 1) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
max_width = 0;
|
||||
}
|
||||
|
@ -1229,10 +1163,29 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_
|
|||
utf_encoding = 0;
|
||||
}
|
||||
|
||||
int32_t old_dst_img;
|
||||
|
||||
if (passed & 8) {
|
||||
old_dst_img = func__dest();
|
||||
sub__dest(dst_img);
|
||||
}
|
||||
|
||||
// Check if we are in text mode and generate an error if we are
|
||||
if (write_page->text) {
|
||||
error(QB_ERROR_ILLEGAL_FUNCTION_CALL);
|
||||
if (passed & 8)
|
||||
sub__dest(old_dst_img);
|
||||
return;
|
||||
}
|
||||
|
||||
FONT_DEBUG_PRINT("Graphics mode set. Proceeding...");
|
||||
|
||||
// Check if a valid font handle was passed
|
||||
if (passed & 4) {
|
||||
if (!IS_VALID_QB64_FONT_HANDLE(qb64_fh)) {
|
||||
error(QB_ERROR_INVALID_HANDLE);
|
||||
if (passed & 8)
|
||||
sub__dest(old_dst_img);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -1240,39 +1193,42 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_
|
|||
}
|
||||
|
||||
// Convert the string to UTF-32 if needed
|
||||
uint32_t const *str32 = nullptr;
|
||||
char32_t const *str32 = nullptr;
|
||||
size_t codepoints = 0;
|
||||
|
||||
switch (utf_encoding) {
|
||||
case 32: // UTF-32: no conversion needed
|
||||
FONT_DEBUG_PRINT("UTF-32 string. Skipping conversion");
|
||||
str32 = (uint32_t *)text->chr;
|
||||
codepoints = text->len / sizeof(uint32_t);
|
||||
str32 = (char32_t *)text->chr;
|
||||
codepoints = text->len / sizeof(char32_t);
|
||||
break;
|
||||
|
||||
case 16: // UTF-16: conversion required
|
||||
FONT_DEBUG_PRINT("UTF-16 string. Converting to UTF32");
|
||||
codepoints = utf32.ConvertUTF16(text->chr, text->len);
|
||||
if (codepoints)
|
||||
str32 = utf32.codepoints.data();
|
||||
str32 = utf32.string.data();
|
||||
break;
|
||||
|
||||
case 8: // UTF-8: conversion required
|
||||
FONT_DEBUG_PRINT("UTF-8 string. Converting to UTF32");
|
||||
codepoints = utf32.ConvertUTF8(text->chr, text->len);
|
||||
if (codepoints)
|
||||
str32 = utf32.codepoints.data();
|
||||
str32 = utf32.string.data();
|
||||
break;
|
||||
|
||||
default: // ASCII: conversion required
|
||||
FONT_DEBUG_PRINT("ASCII string. Converting to UTF32");
|
||||
codepoints = utf32.ConvertASCII(text->chr, text->len);
|
||||
if (codepoints)
|
||||
str32 = utf32.codepoints.data();
|
||||
str32 = utf32.string.data();
|
||||
}
|
||||
|
||||
if (!codepoints)
|
||||
if (!codepoints) {
|
||||
if (passed & 8)
|
||||
sub__dest(old_dst_img);
|
||||
return;
|
||||
}
|
||||
|
||||
FontManager::Font *fnt = nullptr;
|
||||
FT_Face face = nullptr;
|
||||
|
@ -1290,7 +1246,7 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_
|
|||
strPixSize.x = fnt->GetStringPixelWidth(str32, codepoints);
|
||||
pen.x = 0;
|
||||
if (FT_IS_SCALABLE(face)) {
|
||||
strPixSize.y = (((FT_Pos)face->ascender - (FT_Pos)face->descender) * fnt->defaultHeight) / (FT_Pos)face->units_per_EM;
|
||||
strPixSize.y = FT_MulDiv(((FT_Long)face->ascender - (FT_Long)face->descender), (FT_Long)fnt->defaultHeight, (FT_Long)face->units_per_EM);
|
||||
pen.y = ((FT_Pos)face->ascender * fnt->defaultHeight) / (FT_Pos)face->units_per_EM;
|
||||
} else {
|
||||
strPixSize.y = fnt->defaultHeight;
|
||||
|
@ -1305,8 +1261,11 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_
|
|||
strPixSize.x = max_width;
|
||||
|
||||
auto drawBuf = (uint8_t *)calloc(strPixSize.x, strPixSize.y);
|
||||
if (!drawBuf)
|
||||
if (!drawBuf) {
|
||||
if (passed & 8)
|
||||
sub__dest(old_dst_img);
|
||||
return;
|
||||
}
|
||||
|
||||
FONT_DEBUG_PRINT("Allocated (%lu x %lu) buffer", strPixSize.x, strPixSize.y);
|
||||
|
||||
|
@ -1364,7 +1323,7 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_
|
|||
break;
|
||||
|
||||
glyph->RenderBitmap(drawBuf, strPixSize.x, strPixSize.y,
|
||||
pen.x + glyph->bitmap->bearing.x + fnt->monospaceWidth / 2 - glyph->bitmap->advanceWidth / 2,
|
||||
pen.x + glyph->bitmap->bearing.x + (fnt->monospaceWidth >> 1) - (glyph->bitmap->advanceWidth >> 1),
|
||||
pen.y - glyph->bitmap->bearing.y);
|
||||
pen.x += fnt->monospaceWidth;
|
||||
}
|
||||
|
@ -1506,6 +1465,9 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_
|
|||
}
|
||||
|
||||
free(drawBuf);
|
||||
|
||||
if (passed & 8)
|
||||
sub__dest(old_dst_img);
|
||||
}
|
||||
|
||||
/// @brief Calculate the starting pixel positions of each codepoint to an array. First one being zero.
|
||||
|
@ -1550,31 +1512,31 @@ int32_t func__UCharPos(const qbs *text, void *arr, int32_t utf_encoding, int32_t
|
|||
}
|
||||
|
||||
// Convert the string to UTF-32 if needed
|
||||
uint32_t const *str32 = nullptr;
|
||||
char32_t const *str32 = nullptr;
|
||||
size_t codepoints = 0;
|
||||
|
||||
switch (utf_encoding) {
|
||||
case 32: // UTF-32: no conversion needed
|
||||
str32 = (uint32_t *)text->chr;
|
||||
codepoints = text->len / sizeof(uint32_t);
|
||||
str32 = (char32_t *)text->chr;
|
||||
codepoints = text->len / sizeof(char32_t);
|
||||
break;
|
||||
|
||||
case 16: // UTF-16: conversion required
|
||||
codepoints = utf32.ConvertUTF16(text->chr, text->len);
|
||||
if (codepoints)
|
||||
str32 = utf32.codepoints.data();
|
||||
str32 = utf32.string.data();
|
||||
break;
|
||||
|
||||
case 8: // UTF-8: conversion required
|
||||
codepoints = utf32.ConvertUTF8(text->chr, text->len);
|
||||
if (codepoints)
|
||||
str32 = utf32.codepoints.data();
|
||||
str32 = utf32.string.data();
|
||||
break;
|
||||
|
||||
default: // ASCII: conversion required
|
||||
codepoints = utf32.ConvertASCII(text->chr, text->len);
|
||||
if (codepoints)
|
||||
str32 = utf32.codepoints.data();
|
||||
str32 = utf32.string.data();
|
||||
}
|
||||
|
||||
// Simply return the codepoint count if we do not have any array
|
||||
|
|
|
@ -24,7 +24,7 @@ int32_t FontWidth(int32_t fh) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
bool FontRenderTextUTF32(int32_t fh, const char32_t *codepoint, int32_t codepoints, int32_t options, uint8_t **out_data, int32_t *out_x, int32_t *out_y) {
|
||||
(void)fh;
|
||||
(void)codepoint;
|
||||
(void)codepoints;
|
||||
|
@ -46,7 +46,7 @@ bool FontRenderTextASCII(int32_t fh, const uint8_t *codepoint, int32_t codepoint
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t FontPrintWidthUTF32(int32_t fh, const uint32_t *codepoint, int32_t codepoints) {
|
||||
int32_t FontPrintWidthUTF32(int32_t fh, const char32_t *codepoint, int32_t codepoints) {
|
||||
(void)fh;
|
||||
(void)codepoint;
|
||||
(void)codepoints;
|
||||
|
|
|
@ -7,7 +7,7 @@ if (_FUNC_EVALUATEFUNCTION_ARRAY_UDT_ARGS[2]&1){
|
|||
tmp_long=_FUNC_EVALUATEFUNCTION_ARRAY_UDT_ARGS[5];
|
||||
while(tmp_long--) {
|
||||
|
||||
qbs_free(*(qbs**)(_FUNC_EVALUATEFUNCTION_ARRAY_UDT_ARGS[0]+(480/8+1-1)*tmp_long+ 48));}
|
||||
qbs_free(*(qbs**)(_FUNC_EVALUATEFUNCTION_ARRAY_UDT_ARGS[0]+60*tmp_long+ 48));}
|
||||
free((void*)(_FUNC_EVALUATEFUNCTION_ARRAY_UDT_ARGS[0]));
|
||||
}
|
||||
free_mem_lock( (mem_lock*)((ptrszint*)_FUNC_EVALUATEFUNCTION_ARRAY_UDT_ARGS)[8] );
|
||||
|
|
|
@ -3,7 +3,7 @@ if (_SUB_DEBUGMODE_ARRAY_UDT_BUTTON[2]&1){
|
|||
tmp_long=_SUB_DEBUGMODE_ARRAY_UDT_BUTTON[5];
|
||||
while(tmp_long--) {
|
||||
|
||||
qbs_free(*(qbs**)(_SUB_DEBUGMODE_ARRAY_UDT_BUTTON[0]+(128/8+1-1)*tmp_long+ 8));}
|
||||
qbs_free(*(qbs**)(_SUB_DEBUGMODE_ARRAY_UDT_BUTTON[0]+16*tmp_long+ 8));}
|
||||
free((void*)(_SUB_DEBUGMODE_ARRAY_UDT_BUTTON[0]));
|
||||
}
|
||||
free_mem_lock( (mem_lock*)((ptrszint*)_SUB_DEBUGMODE_ARRAY_UDT_BUTTON)[8] );
|
||||
|
|
|
@ -20,7 +20,7 @@ if (_FUNC_IDEVARIABLEWATCHBOX_ARRAY_UDT_VARDLGLIST[2]&1){
|
|||
tmp_long=_FUNC_IDEVARIABLEWATCHBOX_ARRAY_UDT_VARDLGLIST[5];
|
||||
while(tmp_long--) {
|
||||
|
||||
qbs_free(*(qbs**)(_FUNC_IDEVARIABLEWATCHBOX_ARRAY_UDT_VARDLGLIST[0]+(264/8+1-1)*tmp_long+ 25));}
|
||||
qbs_free(*(qbs**)(_FUNC_IDEVARIABLEWATCHBOX_ARRAY_UDT_VARDLGLIST[0]+33*tmp_long+ 25));}
|
||||
free((void*)(_FUNC_IDEVARIABLEWATCHBOX_ARRAY_UDT_VARDLGLIST[0]));
|
||||
}
|
||||
free_mem_lock( (mem_lock*)((ptrszint*)_FUNC_IDEVARIABLEWATCHBOX_ARRAY_UDT_VARDLGLIST)[8] );
|
||||
|
|
|
@ -19,7 +19,7 @@ if (_FUNC_IDEELEMENTWATCHBOX_ARRAY_UDT_VARDLGLIST[2]&1){
|
|||
tmp_long=_FUNC_IDEELEMENTWATCHBOX_ARRAY_UDT_VARDLGLIST[5];
|
||||
while(tmp_long--) {
|
||||
|
||||
qbs_free(*(qbs**)(_FUNC_IDEELEMENTWATCHBOX_ARRAY_UDT_VARDLGLIST[0]+(264/8+1-1)*tmp_long+ 25));}
|
||||
qbs_free(*(qbs**)(_FUNC_IDEELEMENTWATCHBOX_ARRAY_UDT_VARDLGLIST[0]+33*tmp_long+ 25));}
|
||||
free((void*)(_FUNC_IDEELEMENTWATCHBOX_ARRAY_UDT_VARDLGLIST[0]));
|
||||
}
|
||||
free_mem_lock( (mem_lock*)((ptrszint*)_FUNC_IDEELEMENTWATCHBOX_ARRAY_UDT_VARDLGLIST)[8] );
|
||||
|
|
|
@ -11,7 +11,7 @@ if (_FUNC_IDEASCIIBOX_ARRAY_UDT_ASCIITABLE[2]&1){
|
|||
tmp_long=_FUNC_IDEASCIIBOX_ARRAY_UDT_ASCIITABLE[5];
|
||||
while(tmp_long--) {
|
||||
|
||||
qbs_free(*(qbs**)(_FUNC_IDEASCIIBOX_ARRAY_UDT_ASCIITABLE[0]+(96/8+1-1)*tmp_long+ 4));}
|
||||
qbs_free(*(qbs**)(_FUNC_IDEASCIIBOX_ARRAY_UDT_ASCIITABLE[0]+12*tmp_long+ 4));}
|
||||
free((void*)(_FUNC_IDEASCIIBOX_ARRAY_UDT_ASCIITABLE[0]));
|
||||
}
|
||||
free_mem_lock( (mem_lock*)((ptrszint*)_FUNC_IDEASCIIBOX_ARRAY_UDT_ASCIITABLE)[8] );
|
||||
|
|
47122
internal/source/main.txt
|
@ -52,7 +52,7 @@ if (__ARRAY_UDT_CONSTFUNCS[2]&1){
|
|||
tmp_long=__ARRAY_UDT_CONSTFUNCS[5];
|
||||
while(tmp_long--) {
|
||||
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_CONSTFUNCS[0]+(80/8+1-1)*tmp_long+ 0));}
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_CONSTFUNCS[0]+10*tmp_long+ 0));}
|
||||
free((void*)(__ARRAY_UDT_CONSTFUNCS[0]));
|
||||
}
|
||||
free_mem_lock( (mem_lock*)((ptrszint*)__ARRAY_UDT_CONSTFUNCS)[8] );
|
||||
|
@ -401,17 +401,17 @@ if (__ARRAY_UDT_BACKUPUSEDVARIABLELIST[2]&1){
|
|||
tmp_long=__ARRAY_UDT_BACKUPUSEDVARIABLELIST[5];
|
||||
while(tmp_long--) {
|
||||
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 32));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 40));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 48));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 56));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 64));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 72));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 80));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 88));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 96));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 104));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 112));}
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 32));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 40));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 48));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 56));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 64));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 72));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 80));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 88));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 96));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 104));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]+120*tmp_long+ 112));}
|
||||
free((void*)(__ARRAY_UDT_BACKUPUSEDVARIABLELIST[0]));
|
||||
}
|
||||
free_mem_lock( (mem_lock*)((ptrszint*)__ARRAY_UDT_BACKUPUSEDVARIABLELIST)[8] );
|
||||
|
@ -802,7 +802,7 @@ if (__ARRAY_UDT_IDS[2]&1){
|
|||
tmp_long=__ARRAY_UDT_IDS[5];
|
||||
while(tmp_long--) {
|
||||
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_IDS[0]+(22952/8+1-1)*tmp_long+ 2861));}
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_IDS[0]+2869*tmp_long+ 2861));}
|
||||
free((void*)(__ARRAY_UDT_IDS[0]));
|
||||
}
|
||||
free_mem_lock( (mem_lock*)((ptrszint*)__ARRAY_UDT_IDS)[8] );
|
||||
|
@ -955,17 +955,17 @@ if (__ARRAY_UDT_USEDVARIABLELIST[2]&1){
|
|||
tmp_long=__ARRAY_UDT_USEDVARIABLELIST[5];
|
||||
while(tmp_long--) {
|
||||
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 32));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 40));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 48));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 56));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 64));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 72));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 80));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 88));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 96));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 104));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+(960/8+1-1)*tmp_long+ 112));}
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 32));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 40));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 48));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 56));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 64));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 72));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 80));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 88));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 96));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 104));
|
||||
qbs_free(*(qbs**)(__ARRAY_UDT_USEDVARIABLELIST[0]+120*tmp_long+ 112));}
|
||||
free((void*)(__ARRAY_UDT_USEDVARIABLELIST[0]));
|
||||
}
|
||||
free_mem_lock( (mem_lock*)((ptrszint*)__ARRAY_UDT_USEDVARIABLELIST)[8] );
|
||||
|
|
|
@ -1536,16 +1536,14 @@ FUNCTION ide2 (ignore)
|
|||
END IF
|
||||
END IF
|
||||
|
||||
IF os$ = "WIN" OR MacOSX = 1 THEN
|
||||
IF _WINDOWHASFOCUS THEN
|
||||
LOCATE , , 1
|
||||
_PALETTECOLOR 5, IDEBracketHighlightColor, 0
|
||||
_PALETTECOLOR 6, IDEBackgroundColor2, 0
|
||||
ELSE
|
||||
LOCATE , , 0
|
||||
_PALETTECOLOR 5, IDEBackgroundColor, 0
|
||||
_PALETTECOLOR 6, IDEBackgroundColor, 0
|
||||
END IF
|
||||
IF _WINDOWHASFOCUS THEN
|
||||
LOCATE , , 1
|
||||
_PALETTECOLOR 5, IDEBracketHighlightColor, 0
|
||||
_PALETTECOLOR 6, IDEBackgroundColor2, 0
|
||||
ELSE
|
||||
LOCATE , , 0
|
||||
_PALETTECOLOR 5, IDEBackgroundColor, 0
|
||||
_PALETTECOLOR 6, IDEBackgroundColor, 0
|
||||
END IF
|
||||
|
||||
IF KALT THEN 'alt held
|
||||
|
@ -1570,7 +1568,7 @@ FUNCTION ide2 (ignore)
|
|||
idealthighlight = 0
|
||||
LOCATE , , 0: COLOR 0, 7: _PRINTSTRING (1, 1), menubar$
|
||||
IF ideentermenu = 1 AND KCONTROL = 0 THEN 'alt was pressed then released
|
||||
IF _WINDOWHASFOCUS OR os$ = "LNX" THEN
|
||||
IF _WINDOWHASFOCUS THEN
|
||||
LOCATE , , , IDENormalCursorStart, IDENormalCursorEnd
|
||||
skipdisplay = 0
|
||||
ideentermenu = 0
|
||||
|
@ -4421,7 +4419,7 @@ FUNCTION ide2 (ignore)
|
|||
DO
|
||||
_LIMIT 100
|
||||
GetInput
|
||||
IF _WINDOWHASFOCUS = 0 AND (os$ = "WIN" OR MacOSX = 1) THEN
|
||||
IF _WINDOWHASFOCUS = 0 THEN
|
||||
COLOR 0, 7: _PRINTSTRING (1, 1), menubar$
|
||||
SCREEN , , 3, 0: PCOPY 3, 0
|
||||
GOTO ideloop
|
||||
|
@ -4434,7 +4432,7 @@ FUNCTION ide2 (ignore)
|
|||
KB = KEY_ESC
|
||||
END IF
|
||||
|
||||
IF _WINDOWHASFOCUS = 0 AND (os$ = "WIN" OR MacOSX = 1) THEN
|
||||
IF _WINDOWHASFOCUS = 0 THEN
|
||||
COLOR 0, 7: _PRINTSTRING (1, 1), menubar$
|
||||
SCREEN , , 3, 0: PCOPY 3, 0
|
||||
GOTO ideloop
|
||||
|
@ -4657,7 +4655,7 @@ FUNCTION ide2 (ignore)
|
|||
DO
|
||||
_LIMIT 100
|
||||
GetInput
|
||||
IF _WINDOWHASFOCUS = 0 AND (os$ = "WIN" OR MacOSX = 1) THEN
|
||||
IF _WINDOWHASFOCUS = 0 THEN
|
||||
COLOR 0, 7: _PRINTSTRING (1, 1), menubar$
|
||||
PCOPY 3, 0: SCREEN , , 3, 0
|
||||
GOTO ideloop
|
||||
|
@ -4677,7 +4675,7 @@ FUNCTION ide2 (ignore)
|
|||
ideexit = 1: GOTO ideloop
|
||||
END IF
|
||||
END IF
|
||||
IF _WINDOWHASFOCUS = 0 AND (os$ = "WIN" OR MacOSX = 1) THEN
|
||||
IF _WINDOWHASFOCUS = 0 THEN
|
||||
COLOR 0, 7: _PRINTSTRING (1, 1), menubar$
|
||||
PCOPY 3, 0: SCREEN , , 3, 0
|
||||
IF IdeDebugMode = 2 THEN GOTO EnterDebugMode
|
||||
|
@ -11856,7 +11854,7 @@ SUB ideinsline (i, text$)
|
|||
idegotoline i
|
||||
'insert line
|
||||
textlen = LEN(text$)
|
||||
idet$ = LEFT$(idet$, ideli - 1) + MKL$(textlen) + text$ + MKL$(textlen) + RIGHT$(idet$, LEN(idet$) - ideli + 1)
|
||||
idet$ = LEFT$(idet$, ideli - 1) + (MKL$(textlen) + text$ + MKL$(textlen)) + RIGHT$(idet$, LEN(idet$) - ideli + 1)
|
||||
iden = iden + 1
|
||||
END SUB
|
||||
|
||||
|
@ -12536,7 +12534,7 @@ SUB idesetline (i, text$)
|
|||
|
||||
IF i <> -1 THEN idegotoline i
|
||||
textlen = LEN(text$)
|
||||
idet$ = LEFT$(idet$, ideli - 1) + MKL$(textlen) + text$ + MKL$(textlen) + RIGHT$(idet$, LEN(idet$) - ideli + 1 - CVL(MID$(idet$, ideli, 4)) - 8)
|
||||
idet$ = LEFT$(idet$, ideli - 1) + (MKL$(textlen) + text$ + MKL$(textlen)) + RIGHT$(idet$, LEN(idet$) - ideli + 1 - CVL(MID$(idet$, ideli, 4)) - 8)
|
||||
|
||||
END SUB
|
||||
|
||||
|
|
|
@ -1537,10 +1537,10 @@ id.n = qb64prefix$ + "UPrintString"
|
|||
id.Dependency = DEPENDENCY_LOADFONT
|
||||
id.subfunc = 2
|
||||
id.callname = "sub__UPrintString"
|
||||
id.args = 6
|
||||
id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER)
|
||||
id.specialformat = "(?,?),?[,[?][,[?][,?]]]"
|
||||
id.hr_syntax = "_UPRINTSTRING (x&, y&), text$[, maxWidth&][, utfEncoding&][, fontHandle&]"
|
||||
id.args = 7
|
||||
id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER)
|
||||
id.specialformat = "(?,?),?[,[?][,[?][,[?][,?]]]]"
|
||||
id.hr_syntax = "_UPRINTSTRING (x&, y&), text$[, maxWidth&][, utfEncoding&][, fontHandle&][, imageHandle&]"
|
||||
regid
|
||||
|
||||
clearid
|
||||
|
|
48
tests/compile_tests/environ/set_environ.bas
Normal file
|
@ -0,0 +1,48 @@
|
|||
$CONSOLE:ONLY
|
||||
ON ERROR GOTO ehandler
|
||||
|
||||
'Test setting with =
|
||||
ENVIRON "FOO=BAR"
|
||||
PRINT ENVIRON$("FOO")
|
||||
|
||||
|
||||
'Test settings with space
|
||||
ENVIRON "VAR VAL"
|
||||
PRINT ENVIRON$("VAR")
|
||||
|
||||
|
||||
'Test setting value with spaces with = separator
|
||||
ENVIRON "ABC=DEF GHI"
|
||||
PRINT ENVIRON$("ABC")
|
||||
|
||||
|
||||
'Test setting value with spaces with space separator
|
||||
ENVIRON "JKL MNO PQR"
|
||||
PRINT ENVIRON$("JKL")
|
||||
|
||||
|
||||
'Test overwriting existing
|
||||
ENVIRON "X=XY"
|
||||
ENVIRON "X=ZZZ"
|
||||
PRINT ENVIRON$("X")
|
||||
|
||||
|
||||
'Test unset variable with = separator
|
||||
ENVIRON "NAME=LUKE"
|
||||
ENVIRON "NAME="
|
||||
PRINT "["; ENVIRON$("NAME"); "]"
|
||||
|
||||
|
||||
'Test unset variable with space separator
|
||||
ENVIRON "TEXT BOO"
|
||||
ENVIRON "TEXT "
|
||||
PRINT "["; ENVIRON$("TEXT"); "]"
|
||||
|
||||
'Test no separator
|
||||
ENVIRON "NOSEP"
|
||||
|
||||
SYSTEM
|
||||
|
||||
ehandler:
|
||||
print "Error"; ERR; "line"; _ERRORLINE
|
||||
RESUME NEXT
|
8
tests/compile_tests/environ/set_environ.output
Normal file
|
@ -0,0 +1,8 @@
|
|||
BAR
|
||||
VAL
|
||||
DEF GHI
|
||||
MNO PQR
|
||||
ZZZ
|
||||
[]
|
||||
[]
|
||||
Error 5 line 42
|
|
@ -20,7 +20,7 @@ NAME "temp_dir" AS "dummy_dir"
|
|||
PRINT "_DIREXISTS(dummy_dir):"; _DIREXISTS("./dummy_dir")
|
||||
|
||||
PRINT "Creating a temporary file inside dummy_dir"
|
||||
DIM fileName AS STRING: fileName = CreateDummyFile$("./dummy_dir/")
|
||||
DIM fileName AS STRING: fileName = CreateDummyFile("./dummy_dir/", ".tmp")
|
||||
|
||||
PRINT "_FILEEXISTS(fileName):"; _FILEEXISTS(fileName)
|
||||
|
||||
|
@ -29,9 +29,41 @@ KILL fileName
|
|||
|
||||
PRINT "Creating 10 dummy files inside dummy_dir"
|
||||
DIM i AS LONG: FOR i = 0 TO 9
|
||||
fileName = CreateDummyFile$("./dummy_dir/")
|
||||
fileName = CreateDummyFile("./dummy_dir/", ".tmp")
|
||||
NEXT i
|
||||
|
||||
' Start _FILES$ test
|
||||
CHDIR "dummy_dir"
|
||||
|
||||
fileName = CreateDummyFile("./", "")
|
||||
|
||||
i = 0
|
||||
DIM dirEntry AS STRING: dirEntry = _FILES$("") ' should count 13 entries
|
||||
|
||||
DO WHILE LEN(dirEntry) > 0
|
||||
i = i + 1
|
||||
|
||||
dirEntry = _FILES$
|
||||
LOOP
|
||||
|
||||
PRINT "Counted"; i; "entries."
|
||||
|
||||
i = 0
|
||||
dirEntry = _FILES$("*.*") ' should count 12 entries
|
||||
|
||||
DO WHILE LEN(dirEntry) > 0
|
||||
i = i + 1
|
||||
|
||||
dirEntry = _FILES$
|
||||
LOOP
|
||||
|
||||
PRINT "Counted"; i; "entries."
|
||||
|
||||
KILL fileName
|
||||
|
||||
CHDIR ".."
|
||||
' End _FILES$ test
|
||||
|
||||
PRINT "Deleting all 10 dummy files"
|
||||
KILL "./dummy_dir/*.tmp"
|
||||
|
||||
|
@ -44,9 +76,10 @@ test_failed:
|
|||
PRINT "Test failed!"
|
||||
SYSTEM 1
|
||||
|
||||
FUNCTION CreateDummyFile$ (directory AS STRING)
|
||||
|
||||
FUNCTION CreateDummyFile$ (directory AS STRING, extension AS STRING)
|
||||
DO
|
||||
DIM fileName AS STRING: fileName = directory + LTRIM$(STR$(100! * (TIMER + RND))) + ".tmp"
|
||||
DIM fileName AS STRING: fileName = directory + LTRIM$(STR$(INT(100! * (TIMER + RND)))) + extension
|
||||
LOOP WHILE _FILEEXISTS(fileName)
|
||||
|
||||
DIM h AS LONG: h = FREEFILE
|
||||
|
|
|
@ -7,5 +7,7 @@ Creating a temporary file inside dummy_dir
|
|||
_FILEEXISTS(fileName):-1
|
||||
Deleting fileName
|
||||
Creating 10 dummy files inside dummy_dir
|
||||
Counted 13 entries.
|
||||
Counted 12 entries.
|
||||
Deleting all 10 dummy files
|
||||
Deleting dummy_dir
|
||||
|
|
|
@ -97,8 +97,8 @@ SUB PrintFontDetails (handle AS LONG, testFileName AS STRING)
|
|||
_DEST image
|
||||
_FONT handle
|
||||
COLOR _RGB32(255)
|
||||
_UPRINTSTRING (0, 0), SAMPLE_TEXT_1
|
||||
_UPRINTSTRING (0, uLineSpacing), SAMPLE_TEXT_2
|
||||
_UPRINTSTRING (0, 0), SAMPLE_TEXT_1, , , handle
|
||||
_UPRINTSTRING (0, uLineSpacing), SAMPLE_TEXT_2, , , , image
|
||||
'_SAVEIMAGE testFileName + "u", image, TEST_IMAGE_FORMAT
|
||||
|
||||
_FONT 16
|
||||
|
|
|
@ -65,8 +65,8 @@ Success, images are identical!
|
|||
Loading font from memory (automono) ... done.
|
||||
_FONTWIDTH = 0
|
||||
_FONTHEIGHT = 22
|
||||
_UFONTHEIGHT = 27
|
||||
_ULINESPACING = 27
|
||||
_UFONTHEIGHT = 28
|
||||
_ULINESPACING = 28
|
||||
_PRINTWIDTH = 1088
|
||||
_UPRINTWIDTH = 1088
|
||||
_UCHARPOS = 95
|
||||
|
@ -78,7 +78,7 @@ Loading font LiberationSans-Regular.ttf () ... done.
|
|||
_FONTWIDTH = 0
|
||||
_FONTHEIGHT = 12
|
||||
_UFONTHEIGHT = 13
|
||||
_ULINESPACING = 13
|
||||
_ULINESPACING = 14
|
||||
_PRINTWIDTH = 606
|
||||
_UPRINTWIDTH = 606
|
||||
_UCHARPOS = 95
|
||||
|
@ -89,7 +89,7 @@ Success, images are identical!
|
|||
Loading font LiberationSans-Regular.ttf (monospace) ... done.
|
||||
_FONTWIDTH = 15
|
||||
_FONTHEIGHT = 16
|
||||
_UFONTHEIGHT = 17
|
||||
_UFONTHEIGHT = 18
|
||||
_ULINESPACING = 18
|
||||
_PRINTWIDTH = 1425
|
||||
_UPRINTWIDTH = 1425
|
||||
|
@ -101,7 +101,7 @@ Success, images are identical!
|
|||
Loading font LiberationSans-Regular.ttf (automono) ... done.
|
||||
_FONTWIDTH = 0
|
||||
_FONTHEIGHT = 22
|
||||
_UFONTHEIGHT = 24
|
||||
_UFONTHEIGHT = 25
|
||||
_ULINESPACING = 25
|
||||
_PRINTWIDTH = 1094
|
||||
_UPRINTWIDTH = 1094
|
||||
|
@ -114,7 +114,7 @@ Loading font LiberationSerif-Regular.ttf () ... done.
|
|||
_FONTWIDTH = 0
|
||||
_FONTHEIGHT = 12
|
||||
_UFONTHEIGHT = 13
|
||||
_ULINESPACING = 13
|
||||
_ULINESPACING = 14
|
||||
_PRINTWIDTH = 583
|
||||
_UPRINTWIDTH = 583
|
||||
_UCHARPOS = 95
|
||||
|
@ -125,7 +125,7 @@ Success, images are identical!
|
|||
Loading font LiberationSerif-Regular.ttf (monospace) ... done.
|
||||
_FONTWIDTH = 15
|
||||
_FONTHEIGHT = 16
|
||||
_UFONTHEIGHT = 17
|
||||
_UFONTHEIGHT = 18
|
||||
_ULINESPACING = 18
|
||||
_PRINTWIDTH = 1425
|
||||
_UPRINTWIDTH = 1425
|
||||
|
@ -149,8 +149,8 @@ Success, images are identical!
|
|||
Loading font LiberationMono-Regular.ttf () ... done.
|
||||
_FONTWIDTH = 0
|
||||
_FONTHEIGHT = 12
|
||||
_UFONTHEIGHT = 13
|
||||
_ULINESPACING = 13
|
||||
_UFONTHEIGHT = 14
|
||||
_ULINESPACING = 14
|
||||
_PRINTWIDTH = 665
|
||||
_UPRINTWIDTH = 665
|
||||
_UCHARPOS = 95
|
||||
|
@ -173,8 +173,8 @@ Success, images are identical!
|
|||
Loading font LiberationMono-Regular.ttf (automono) ... done.
|
||||
_FONTWIDTH = 13
|
||||
_FONTHEIGHT = 22
|
||||
_UFONTHEIGHT = 24
|
||||
_ULINESPACING = 24
|
||||
_UFONTHEIGHT = 25
|
||||
_ULINESPACING = 25
|
||||
_PRINTWIDTH = 1235
|
||||
_UPRINTWIDTH = 1235
|
||||
_UCHARPOS = 95
|
||||
|
|
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 238 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 200 KiB |
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 214 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 200 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 241 KiB |
|
@ -148,6 +148,9 @@ SUB AssertImage2 (originalActualImage AS LONG, expectedFileName AS STRING)
|
|||
|
||||
DIM actual AS _MEM, expected AS _MEM
|
||||
|
||||
actual = _MEMIMAGE(actualImage)
|
||||
expected = _MEMIMAGE(expectedImage)
|
||||
|
||||
IF _WIDTH(actualImage) <> _WIDTH(expectedImage) THEN
|
||||
PRINT "Failure! Image width differs, actual:"; _WIDTH(actualImage); ", Expected:"; _WIDTH(expectedImage)
|
||||
GOTO freeImages
|
||||
|
@ -158,9 +161,6 @@ SUB AssertImage2 (originalActualImage AS LONG, expectedFileName AS STRING)
|
|||
GOTO freeImages
|
||||
END IF
|
||||
|
||||
actual = _MEMIMAGE(actualImage)
|
||||
expected = _MEMIMAGE(expectedImage)
|
||||
|
||||
IF actual.SIZE <> expected.SIZE THEN
|
||||
PRINT "Failure! Image sizes differ, Actual:"; actual.SIZE; ", Expected:"; expected.SIZE
|
||||
GOTO freeImages
|
||||
|
|