#pragma once #include #include #include #include #include "iconv.h" #include "uemf.h" #include #define SAFEPRINTF_SUCCESS 0 #define SAFEPRINTF_ERROR -1 static const char * HexStringToByteArray(string hexString) { size_t length = hexString.length(); char * byteArray = new char[length / 2]; for (int i = 0; i < length; i += 2) { //byteArray[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16); // 将每一对十六进制字符转换成一个字节 byteArray[i / 2] = std::stoi(hexString.substr(i, 2), nullptr, 16); } return byteArray; } // 读取出文件中的所有内容 static std::vector ReadFullFileData(CFile &fr) { ULONGLONG fileSize = fr.GetLength(); std::vector buffer(fileSize); ULONGLONG left = fileSize; ULONGLONG nread = 0; BYTE* ptr = buffer.data(); while (left > 0) { UINT n = static_cast(min(UINT_MAX, left)); if (fr.Read(ptr, n) != n) { return {}; } left -= n; ptr += n; } return buffer; } //string->wstring static std::wstring UTF8ToWide(const char* utf8Str) { if (!utf8Str) return L""; int wideLen = MultiByteToWideChar(CP_ACP, 0, utf8Str, -1, nullptr, 0); if (wideLen <= 0) return L""; std::wstring wideStr(wideLen, 0); MultiByteToWideChar(CP_UTF8, 0, utf8Str, -1, &wideStr[0], wideLen); wideStr.resize(wideLen - 1); // 去除末尾的 null 字符 return wideStr; } inline char *utf8_to_gbk(const char *utf8_str) { if (!utf8_str) return NULL; // 计算输入字符串的长度 size_t utf8_len = strlen(utf8_str) + 1; // +1 为 null 结束符 size_t gbk_len = utf8_len * 2; // GBK 最大长度估算 // 分配输出缓冲区 char *gbk_str = (char *)malloc(gbk_len); if (!gbk_str) return NULL; char *in_buf = (char *)utf8_str; char *out_buf = gbk_str; // iconv 初始化 iconv_t conv = iconv_open("GBK", "UTF-8"); if (conv == (iconv_t)-1) { free(gbk_str); return NULL; } size_t in_bytes_left = utf8_len; size_t out_bytes_left = gbk_len; // 转换 size_t result = iconv(conv, &in_buf, &in_bytes_left, &out_buf, &out_bytes_left); iconv_close(conv); if (result == (size_t)-1) { free(gbk_str); return NULL; // 转换失败 } // 计算实际长度并添加 null 结束符 size_t out_len = gbk_len - out_bytes_left; gbk_str[out_len] = '\0'; return gbk_str; } inline char *gbk_to_utf8(const char *gbk_str) { if (!gbk_str) return NULL; // 计算输入字符串的长度 size_t gbk_len = strlen(gbk_str) + 1; // +1 为 null 结束符 size_t utf8_len = gbk_len * 3; // UTF-8 最大长度估算,每个GBK字符可能变成最多3个UTF-8字符 // 分配输出缓冲区 char *utf8_str = (char *)malloc(utf8_len); if (!utf8_str) return NULL; char *in_buf = (char *)gbk_str; char *out_buf = utf8_str; // iconv 初始化 iconv_t conv = iconv_open("UTF-8", "GBK"); if (conv == (iconv_t)-1) { free(utf8_str); return NULL; } size_t in_bytes_left = gbk_len; size_t out_bytes_left = utf8_len; // 转换 size_t result = iconv(conv, &in_buf, &in_bytes_left, &out_buf, &out_bytes_left); iconv_close(conv); if (result == (size_t)-1) { free(utf8_str); return NULL; // 转换失败 } // 计算实际长度并添加 null 结束符 size_t out_len = utf8_len - out_bytes_left; utf8_str[out_len] = '\0'; return utf8_str; } /** \brief Find a (sub)string in a caseinvariant manner, used for locating "Narrow" in font name \return Returns -1 if no match, else returns the position (numbered from 0) of the first character of the match. \param string Text to search \param sub Text to find */ inline int TR_findcasesub(const char *string, const char *sub) { int i, j; int match = 0; for (i = 0; string[i]; i++) { for (match = 1, j = 0; sub[j] && string[i + j]; j++) { if (toupper(sub[j]) != toupper(string[i + j])) { match = 0; break; } } if (match && !sub[j]) { break; /* matched over the entire substring */ } } return((match ? i : -1)); } inline void U_swap4(void *ul, unsigned int count) { uint8_t ctmp; uint8_t *cl = (uint8_t *)ul; for (; count; count--, cl += 4) { ctmp = *(cl + 0); *(cl + 0) = *(cl + 3); *(cl + 3) = ctmp; ctmp = *(cl + 1); *(cl + 1) = *(cl + 2); *(cl + 2) = ctmp; } } /* Useful composition macros */ constexpr double SP_COLOR_U_TO_F(uint32_t v) { return v / 255.0; } constexpr uint32_t SP_COLOR_F_TO_U(double v) { return (unsigned int)(v * 255. + .5); } constexpr uint32_t SP_RGBA32_R_U(uint32_t v) { return (v >> 24) & 0xff; } constexpr uint32_t SP_RGBA32_G_U(uint32_t v) { return (v >> 16) & 0xff; } constexpr uint32_t SP_RGBA32_B_U(uint32_t v) { return (v >> 8) & 0xff; } constexpr uint32_t SP_RGBA32_A_U(uint32_t v) { return v & 0xff; } constexpr double SP_RGBA32_R_F(uint32_t v) { return SP_COLOR_U_TO_F(SP_RGBA32_R_U(v)); } constexpr double SP_RGBA32_G_F(uint32_t v) { return SP_COLOR_U_TO_F(SP_RGBA32_G_U(v)); } constexpr double SP_RGBA32_B_F(uint32_t v) { return SP_COLOR_U_TO_F(SP_RGBA32_B_U(v)); } constexpr double SP_RGBA32_A_F(uint32_t v) { return SP_COLOR_U_TO_F(SP_RGBA32_A_U(v)); } constexpr uint32_t SP_RGBA32_U_COMPOSE(uint32_t r, uint32_t g, uint32_t b, uint32_t a) { return ((b & 0xff) << 24) | ((g & 0xff) << 16) | ((r & 0xff) << 8) | (a & 0xff); } constexpr uint32_t SP_RGBA32_F_COMPOSE(double r, double g, double b, double a) { return SP_RGBA32_U_COMPOSE(SP_COLOR_F_TO_U(r), SP_COLOR_F_TO_U(g), SP_COLOR_F_TO_U(b), SP_COLOR_F_TO_U(a)); } constexpr uint32_t SP_RGBA32_C_COMPOSE(uint32_t c, double o) { return SP_RGBA32_U_COMPOSE(SP_RGBA32_R_U(c), SP_RGBA32_G_U(c), SP_RGBA32_B_U(c), SP_COLOR_F_TO_U(o)); } constexpr uint32_t U_RGB_COMPOSE(U_COLORREF c) { return SP_RGBA32_U_COMPOSE(U_RGBAGetR(c), U_RGBAGetG(c), U_RGBAGetB(c), 0xff); } constexpr uint32_t U_RGBA_COMPOSE(U_COLORREF c) { return SP_RGBA32_U_COMPOSE(U_RGBAGetR(c), U_RGBAGetG(c), U_RGBAGetB(c), U_RGBAGetA(c)); } template int safeprintf(char(&buf)[N], const char* fmt, ...) { va_list args; va_start(args, fmt); auto len = vsnprintf(buf, N, fmt, args); va_end(args); return len; }