diff options
author | Martin Capitanio <capnm@capitanio.org> | 2023-09-29 14:58:36 +0200 |
---|---|---|
committer | Martin Capitanio <capnm@capitanio.org> | 2023-09-29 19:50:19 +0200 |
commit | aab650f2ef97915e22312e5da543e01989bbfd76 (patch) | |
tree | 847d2e5c6033ab1d06122c57beefa6dc6c019aad /thirdparty/thorvg/src/common/tvgStr.cpp | |
parent | 19890614c6a78ec36030ce65c7da05f07fcdb9ed (diff) | |
download | redot-engine-aab650f2ef97915e22312e5da543e01989bbfd76.tar.gz |
ThorVG: update to v0.11.0 release.
See https://github.com/thorvg/thorvg/releases/tag/v0.11.0
+ Infrastructure
Repository folder structure was make it more intuitive and coherent.
"thorvg/src/lib" -> "thorvg/src/common"
(providing essential common functionalities
used internally among the renderer and sub-modules)
"thorvg/src/lib" -> "thorvg/src/renderer"
(for vector drawing features)
+ SVG related
Fix stroke regression https://github.com/thorvg/thorvg/issues/1670
Support stroke dash offset function https://github.com/thorvg/thorvg/issues/1591#issuecomment-1681319321
Support Focal property in Radial Gradient https://github.com/thorvg/thorvg/issues/1558
Diffstat (limited to 'thirdparty/thorvg/src/common/tvgStr.cpp')
-rw-r--r-- | thirdparty/thorvg/src/common/tvgStr.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/thirdparty/thorvg/src/common/tvgStr.cpp b/thirdparty/thorvg/src/common/tvgStr.cpp new file mode 100644 index 0000000000..eeed4fc404 --- /dev/null +++ b/thirdparty/thorvg/src/common/tvgStr.cpp @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + + * 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. + */ + +#include "config.h" +#include <cstring> +#include <memory.h> +#include "tvgMath.h" +#include "tvgStr.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static inline bool _floatExact(float a, float b) +{ + return memcmp(&a, &b, sizeof(float)) == 0; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +namespace tvg { + +/* + * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtof-strtof-l-wcstof-wcstof-l?view=msvc-160 + * + * src should be one of the following form : + * + * [whitespace] [sign] {digits [radix digits] | radix digits} [{e | E} [sign] digits] + * [whitespace] [sign] {INF | INFINITY} + * [whitespace] [sign] NAN [sequence] + * + * No hexadecimal form supported + * no sequence supported after NAN + */ +float strToFloat(const char *nPtr, char **endPtr) +{ + if (endPtr) *endPtr = (char *) (nPtr); + if (!nPtr) return 0.0f; + + auto a = nPtr; + auto iter = nPtr; + auto val = 0.0f; + unsigned long long integerPart = 0; + int minus = 1; + + //ignore leading whitespaces + while (isspace(*iter)) iter++; + + //signed or not + if (*iter == '-') { + minus = -1; + iter++; + } else if (*iter == '+') { + iter++; + } + + if (tolower(*iter) == 'i') { + if ((tolower(*(iter + 1)) == 'n') && (tolower(*(iter + 2)) == 'f')) iter += 3; + else goto error; + + if (tolower(*(iter)) == 'i') { + if ((tolower(*(iter + 1)) == 'n') && (tolower(*(iter + 2)) == 'i') && (tolower(*(iter + 3)) == 't') && + (tolower(*(iter + 4)) == 'y')) + iter += 5; + else goto error; + } + if (endPtr) *endPtr = (char *) (iter); + return (minus == -1) ? -INFINITY : INFINITY; + } + + if (tolower(*iter) == 'n') { + if ((tolower(*(iter + 1)) == 'a') && (tolower(*(iter + 2)) == 'n')) iter += 3; + else goto error; + + if (endPtr) *endPtr = (char *) (iter); + return (minus == -1) ? -NAN : NAN; + } + + //Optional: integer part before dot + if (isdigit(*iter)) { + for (; isdigit(*iter); iter++) { + integerPart = integerPart * 10ULL + (unsigned long long) (*iter - '0'); + } + a = iter; + } else if (*iter != '.') { + goto success; + } + + val = static_cast<float>(integerPart); + + //Optional: decimal part after dot + if (*iter == '.') { + unsigned long long decimalPart = 0; + unsigned long long pow10 = 1; + int count = 0; + + iter++; + + if (isdigit(*iter)) { + for (; isdigit(*iter); iter++, count++) { + if (count < 19) { + decimalPart = decimalPart * 10ULL + +static_cast<unsigned long long>(*iter - '0'); + pow10 *= 10ULL; + } + } + } else if (isspace(*iter)) { //skip if there is a space after the dot. + a = iter; + goto success; + } + + val += static_cast<float>(decimalPart) / static_cast<float>(pow10); + a = iter; + } + + //Optional: exponent + if (*iter == 'e' || *iter == 'E') { + ++iter; + + //Exception: svg may have 'em' unit for fonts. ex) 5em, 10.5em + if ((*iter == 'm') || (*iter == 'M')) { + //TODO: We don't support font em unit now, but has to multiply val * font size later... + a = iter + 1; + goto success; + } + + //signed or not + int minus_e = 1; + + if (*iter == '-') { + minus_e = -1; + ++iter; + } else if (*iter == '+') { + iter++; + } + + unsigned int exponentPart = 0; + + if (isdigit(*iter)) { + while (*iter == '0') iter++; + for (; isdigit(*iter); iter++) { + exponentPart = exponentPart * 10U + static_cast<unsigned int>(*iter - '0'); + } + } else if (!isdigit(*(a - 1))) { + a = nPtr; + goto success; + } else if (*iter == 0) { + goto success; + } + + //if ((_floatExact(val, 2.2250738585072011f)) && ((minus_e * static_cast<int>(exponentPart)) <= -308)) { + if ((_floatExact(val, 1.175494351f)) && ((minus_e * static_cast<int>(exponentPart)) <= -38)) { + //val *= 1.0e-308f; + val *= 1.0e-38f; + a = iter; + goto success; + } + + a = iter; + auto scale = 1.0f; + + while (exponentPart >= 8U) { + scale *= 1E8; + exponentPart -= 8U; + } + while (exponentPart > 0U) { + scale *= 10.0f; + exponentPart--; + } + val = (minus_e == -1) ? (val / scale) : (val * scale); + } else if ((iter > nPtr) && !isdigit(*(iter - 1))) { + a = nPtr; + goto success; + } + +success: + if (endPtr) *endPtr = (char *)(a); + return minus * val; + +error: + if (endPtr) *endPtr = (char *)(nPtr); + return 0.0f; +} + + +int str2int(const char* str, size_t n) +{ + int ret = 0; + for(size_t i = 0; i < n; ++i) { + ret = ret * 10 + (str[i] - '0'); + } + return ret; +} + +char* strDuplicate(const char *str, size_t n) +{ + auto len = strlen(str); + if (len < n) n = len; + + auto ret = (char *) malloc(n + 1); + if (!ret) return nullptr; + ret[n] = '\0'; + + return (char *) memcpy(ret, str, n); +} + +char* strDirname(const char* path) +{ + const char *ptr = strrchr(path, '/'); +#ifdef _WIN32 + if (ptr) ptr = strrchr(ptr + 1, '\\'); +#endif + int len = int(ptr + 1 - path); // +1 to include '/' + return strDuplicate(path, len); +} + +} |