ThorVG: Update to v0.11.1

https://github.com/thorvg/thorvg/releases/tag/v0.11.1

Godot related:
+ [SwEngine] Enhanced the quality of the dash line corners.
+ [SVG] Fixed a regression bug related to maskContentUnit,
	userSpaceOnUse/objectBoundingBox.

Fixes #82982 icons.
Fixes #83198 svg ← png/jpg.
This commit is contained in:
Martin Capitanio 2023-10-13 13:09:33 +02:00
parent 1ab77f410e
commit 0983022e0c
21 changed files with 6558 additions and 27 deletions

View file

@ -24,6 +24,9 @@ thirdparty_sources = [
"src/loaders/svg/tvgSvgUtil.cpp",
"src/loaders/svg/tvgXmlParser.cpp",
"src/loaders/raw/tvgRawLoader.cpp",
"src/loaders/external_png/tvgPngLoader.cpp",
"src/loaders/jpg/tvgJpgd.cpp",
"src/loaders/jpg/tvgJpgLoader.cpp",
# renderer common
"src/renderer/tvgAccessor.cpp",
# "src/renderer/tvgAnimation.cpp",
@ -68,6 +71,8 @@ env_thirdparty.Prepend(
thirdparty_dir + "src/renderer",
thirdparty_dir + "src/renderer/sw_engine",
thirdparty_dir + "src/loaders/raw",
thirdparty_dir + "src/loaders/external_png",
thirdparty_dir + "src/loaders/jpg",
]
)

View file

@ -55,6 +55,9 @@ if env["thorvg_enabled"] and env["freetype_enabled"]:
"src/loaders/svg/tvgSvgUtil.cpp",
"src/loaders/svg/tvgXmlParser.cpp",
"src/loaders/raw/tvgRawLoader.cpp",
"src/loaders/external_png/tvgPngLoader.cpp",
"src/loaders/jpg/tvgJpgd.cpp",
"src/loaders/jpg/tvgJpgLoader.cpp",
# renderer common
"src/renderer/tvgAccessor.cpp",
# "src/renderer/tvgAnimation.cpp",
@ -88,10 +91,12 @@ if env["thorvg_enabled"] and env["freetype_enabled"]:
CPPPATH=[
"../../../thirdparty/thorvg/inc",
"../../../thirdparty/thorvg/src/common",
"../../../thirdparty/thorvg/src/loaders/svg",
"../../../thirdparty/thorvg/src/loaders/raw",
"../../../thirdparty/thorvg/src/renderer",
"../../../thirdparty/thorvg/src/renderer/sw_engine",
"../../../thirdparty/thorvg/src/loaders/svg",
"../../../thirdparty/thorvg/src/loaders/raw",
"../../../thirdparty/thorvg/src/loaders/external_png",
"../../../thirdparty/thorvg/src/loaders/jpg",
]
)

View file

@ -50,6 +50,9 @@ if env["thorvg_enabled"] and env["freetype_enabled"]:
"src/loaders/svg/tvgSvgUtil.cpp",
"src/loaders/svg/tvgXmlParser.cpp",
"src/loaders/raw/tvgRawLoader.cpp",
"src/loaders/external_png/tvgPngLoader.cpp",
"src/loaders/jpg/tvgJpgd.cpp",
"src/loaders/jpg/tvgJpgLoader.cpp",
# renderer common
"src/renderer/tvgAccessor.cpp",
# "src/renderer/tvgAnimation.cpp",
@ -83,10 +86,12 @@ if env["thorvg_enabled"] and env["freetype_enabled"]:
CPPPATH=[
"../../../thirdparty/thorvg/inc",
"../../../thirdparty/thorvg/src/common",
"../../../thirdparty/thorvg/src/loaders/svg",
"../../../thirdparty/thorvg/src/loaders/raw",
"../../../thirdparty/thorvg/src/renderer",
"../../../thirdparty/thorvg/src/renderer/sw_engine",
"../../../thirdparty/thorvg/src/loaders/svg",
"../../../thirdparty/thorvg/src/loaders/raw",
"../../../thirdparty/thorvg/src/loaders/external_png",
"../../../thirdparty/thorvg/src/loaders/jpg",
]
)

View file

@ -804,7 +804,7 @@ instead of `miniz.h` as an external dependency.
## thorvg
- Upstream: https://github.com/thorvg/thorvg
- Version: 0.11.0 (12260198d12719ea20939b68492accfc155d9ff5, 2023)
- Version: 0.11.1 (ca00e52125446a1a5cca20f9d8621b382cff5cb9, 2023)
- License: MIT
Files extracted from upstream source:
@ -812,6 +812,7 @@ Files extracted from upstream source:
See `thorvg/update-thorvg.sh` for extraction instructions. Set the version
number and run the script.
Apply patches from the `patches` folder.
## vhacd

View file

@ -3,9 +3,11 @@
#define THORVG_SW_RASTER_SUPPORT
#define THORVG_SVG_LOADER_SUPPORT
#define THORVG_PNG_LOADER_SUPPORT
#define THORVG_JPG_LOADER_SUPPORT
// For internal debugging:
//#define THORVG_LOG_ENABLED
#define THORVG_VERSION_STRING "0.11.0"
#define THORVG_VERSION_STRING "0.11.1"
#endif

View file

@ -0,0 +1,13 @@
diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp
index 88d359aaa3..61a5dc1c0f 100644
--- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp
+++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp
@@ -431,7 +431,7 @@ struct Row<1>
{
static void idct(int* pTemp, const jpgd_block_t* pSrc)
{
- const int dcval = pSrc[0] * (pSrc[0] * (PASS1_BITS * 2));
+ const int dcval = pSrc[0] * PASS1_BITS * 2;
pTemp[0] = dcval;
pTemp[1] = dcval;

View file

@ -0,0 +1,120 @@
/*
* 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 "tvgLoader.h"
#include "tvgPngLoader.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
PngLoader::PngLoader()
{
image = static_cast<png_imagep>(calloc(1, sizeof(png_image)));
image->version = PNG_IMAGE_VERSION;
image->opaque = NULL;
}
PngLoader::~PngLoader()
{
if (content) {
free((void*)content);
content = nullptr;
}
free(image);
}
bool PngLoader::open(const string& path)
{
image->opaque = NULL;
if (!png_image_begin_read_from_file(image, path.c_str())) return false;
w = (float)image->width;
h = (float)image->height;
cs = ColorSpace::ARGB8888;
return true;
}
bool PngLoader::open(const char* data, uint32_t size, bool copy)
{
image->opaque = NULL;
if (!png_image_begin_read_from_memory(image, data, size)) return false;
w = (float)image->width;
h = (float)image->height;
cs = ColorSpace::ARGB8888;
return true;
}
bool PngLoader::read()
{
png_bytep buffer;
image->format = PNG_FORMAT_BGRA;
buffer = static_cast<png_bytep>(malloc(PNG_IMAGE_SIZE((*image))));
if (!buffer) {
//out of memory, only time when libpng doesnt free its data
png_image_free(image);
return false;
}
if (!png_image_finish_read(image, NULL, buffer, 0, NULL)) {
free(buffer);
return false;
}
content = reinterpret_cast<uint32_t*>(buffer);
return true;
}
bool PngLoader::close()
{
png_image_free(image);
return true;
}
unique_ptr<Surface> PngLoader::bitmap()
{
if (!content) return nullptr;
//TODO: It's better to keep this surface instance in the loader side
auto surface = new Surface;
surface->buf32 = content;
surface->stride = w;
surface->w = w;
surface->h = h;
surface->cs = cs;
surface->channelSize = sizeof(uint32_t);
surface->owner = true;
surface->premultiplied = false;
return unique_ptr<Surface>(surface);
}

View file

@ -0,0 +1,47 @@
/*
* 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.
*/
#ifndef _TVG_PNG_LOADER_H_
#define _TVG_PNG_LOADER_H_
#include <png.h>
class PngLoader : public LoadModule
{
public:
PngLoader();
~PngLoader();
using LoadModule::open;
bool open(const string& path) override;
bool open(const char* data, uint32_t size, bool copy) override;
bool read() override;
bool close() override;
unique_ptr<Surface> bitmap() override;
private:
png_imagep image = nullptr;
uint32_t* content = nullptr;
};
#endif //_TVG_PNG_LOADER_H_

View file

@ -0,0 +1,143 @@
/*
* Copyright (c) 2021 - 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 <memory.h>
#include "tvgLoader.h"
#include "tvgJpgLoader.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
void JpgLoader::clear()
{
jpgdDelete(decoder);
if (freeData) free(data);
decoder = nullptr;
data = nullptr;
freeData = false;
}
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
JpgLoader::~JpgLoader()
{
jpgdDelete(decoder);
if (freeData) free(data);
free(image);
}
bool JpgLoader::open(const string& path)
{
clear();
int width, height;
decoder = jpgdHeader(path.c_str(), &width, &height);
if (!decoder) return false;
w = static_cast<float>(width);
h = static_cast<float>(height);
cs = ColorSpace::ARGB8888;
return true;
}
bool JpgLoader::open(const char* data, uint32_t size, bool copy)
{
clear();
if (copy) {
this->data = (char *) malloc(size);
if (!this->data) return false;
memcpy((char *)this->data, data, size);
freeData = true;
} else {
this->data = (char *) data;
freeData = false;
}
int width, height;
decoder = jpgdHeader(this->data, size, &width, &height);
if (!decoder) return false;
w = static_cast<float>(width);
h = static_cast<float>(height);
cs = ColorSpace::ARGB8888;
return true;
}
bool JpgLoader::read()
{
if (!decoder || w <= 0 || h <= 0) return false;
TaskScheduler::request(this);
return true;
}
bool JpgLoader::close()
{
this->done();
clear();
return true;
}
unique_ptr<Surface> JpgLoader::bitmap()
{
this->done();
if (!image) return nullptr;
//TODO: It's better to keep this surface instance in the loader side
auto surface = new Surface;
surface->buf8 = image;
surface->stride = static_cast<uint32_t>(w);
surface->w = static_cast<uint32_t>(w);
surface->h = static_cast<uint32_t>(h);
surface->cs = cs;
surface->channelSize = sizeof(uint32_t);
surface->premultiplied = true;
surface->owner = true;
return unique_ptr<Surface>(surface);
}
void JpgLoader::run(unsigned tid)
{
if (image) {
free(image);
image = nullptr;
}
image = jpgdDecompress(decoder);
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2021 - 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.
*/
#ifndef _TVG_JPG_LOADER_H_
#define _TVG_JPG_LOADER_H_
#include "tvgTaskScheduler.h"
#include "tvgJpgd.h"
class JpgLoader : public LoadModule, public Task
{
private:
jpeg_decoder* decoder = nullptr;
char* data = nullptr;
unsigned char *image = nullptr;
bool freeData = false;
void clear();
public:
~JpgLoader();
using LoadModule::open;
bool open(const string& path) override;
bool open(const char* data, uint32_t size, bool copy) override;
bool read() override;
bool close() override;
unique_ptr<Surface> bitmap() override;
void run(unsigned tid) override;
};
#endif //_TVG_JPG_LOADER_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2021 - 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.
*/
// jpgd.h - C++ class for JPEG decompression.
// Public domain, Rich Geldreich <richgel99@gmail.com>
#ifndef _TVG_JPGD_H_
#define _TVG_JPGD_H_
class jpeg_decoder;
jpeg_decoder* jpgdHeader(const char* data, int size, int* width, int* height);
jpeg_decoder* jpgdHeader(const char* filename, int* width, int* height);
unsigned char* jpgdDecompress(jpeg_decoder* decoder);
void jpgdDelete(jpeg_decoder* decoder);
#endif //_TVG_JPGD_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,174 @@
/*
* 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.
*/
/*
LodePNG version 20200306
Copyright (c) 2005-2020 Lode Vandevenne
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef _TVG_LODEPNG_H_
#define _TVG_LODEPNG_H_
#include <stddef.h>
/*The PNG color types (also used for raw image).*/
enum LodePNGColorType
{
LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/
LCT_RGB = 2, /*RGB: 8,16 bit*/
LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/
LCT_GREY_ALPHA = 4, /*grayscale with alpha: 8,16 bit*/
LCT_RGBA = 6, /*RGB with alpha: 8,16 bit*/
/*LCT_MAX_OCTET_VALUE lets the compiler allow this enum to represent any invalid
byte value from 0 to 255 that could be present in an invalid PNG file header. Do
not use, compare with or set the name LCT_MAX_OCTET_VALUE, instead either use
the valid color type names above, or numeric values like 1 or 7 when checking for
particular disallowed color type byte values, or cast to integer to print it.*/
LCT_MAX_OCTET_VALUE = 255
};
/*Settings for zlib decompression*/
struct LodePNGDecompressSettings
{
/* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/
/*use custom zlib decoder instead of built in one (default: null)*/
unsigned (*custom_zlib)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGDecompressSettings*);
/*use custom deflate decoder instead of built in one (default: null) if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate)*/
unsigned (*custom_inflate)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGDecompressSettings*);
const void* custom_context; /*optional custom settings for custom functions*/
};
/*
Color mode of an image. Contains all information required to decode the pixel
bits to RGBA colors. This information is the same as used in the PNG file
format, and is used both for PNG and raw image data in LodePNG.
*/
struct LodePNGColorMode
{
/*header (IHDR)*/
LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/
unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/
/*
palette (PLTE and tRNS)
Dynamically allocated with the colors of the palette, including alpha.
This field may not be allocated directly, use lodepng_color_mode_init first,
then lodepng_palette_add per color to correctly initialize it (to ensure size
of exactly 1024 bytes).
The alpha channels must be set as well, set them to 255 for opaque images.
When decoding, by default you can ignore this palette, since LodePNG already
fills the palette colors in the pixels of the raw RGBA output.
The palette is only supported for color type 3.
*/
unsigned char* palette; /*palette in RGBARGBA... order. Must be either 0, or when allocated must have 1024 bytes*/
size_t palettesize; /*palette size in number of colors (amount of used bytes is 4 * palettesize)*/
/*
transparent color key (tRNS)
This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit.
For grayscale PNGs, r, g and b will all 3 be set to the same.
When decoding, by default you can ignore this information, since LodePNG sets
pixels with this key to transparent already in the raw RGBA output.
The color key is only supported for color types 0 and 2.
*/
unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/
unsigned key_r; /*red/grayscale component of color key*/
unsigned key_g; /*green component of color key*/
unsigned key_b; /*blue component of color key*/
};
/*Information about the PNG image, except pixels, width and height.*/
struct LodePNGInfo
{
/*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/
unsigned compression_method;/*compression method of the original file. Always 0.*/
unsigned filter_method; /*filter method of the original file*/
unsigned interlace_method; /*interlace method of the original file: 0=none, 1=Adam7*/
LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/
};
/*
Settings for the decoder. This contains settings for the PNG and the Zlib
decoder, but not the Info settings from the Info structs.
*/
struct LodePNGDecoderSettings
{
LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
/* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */
unsigned ignore_crc; /*ignore CRC checksums*/
unsigned ignore_critical; /*ignore unknown critical chunks*/
unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/
/* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable
errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some
strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters
in string keys, etc... */
unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
};
/*The settings, state and information for extended encoding and decoding.*/
struct LodePNGState
{
LodePNGDecoderSettings decoder; /*the decoding settings*/
LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/
LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/
unsigned error;
};
void lodepng_state_init(LodePNGState* state);
void lodepng_state_cleanup(LodePNGState* state);
unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize);
unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize);
#endif //_TVG_LODEPNG_H_

View file

@ -0,0 +1,185 @@
/*
* Copyright (c) 2021 - 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 <memory.h>
#include "tvgLoader.h"
#include "tvgPngLoader.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
void PngLoader::clear()
{
lodepng_state_cleanup(&state);
if (freeData) free(data);
data = nullptr;
size = 0;
freeData = false;
}
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
PngLoader::PngLoader()
{
lodepng_state_init(&state);
}
PngLoader::~PngLoader()
{
if (freeData) free(data);
free(image);
}
bool PngLoader::open(const string& path)
{
clear();
auto pngFile = fopen(path.c_str(), "rb");
if (!pngFile) return false;
auto ret = false;
//determine size
if (fseek(pngFile, 0, SEEK_END) < 0) goto finalize;
if (((size = ftell(pngFile)) < 1)) goto finalize;
if (fseek(pngFile, 0, SEEK_SET)) goto finalize;
data = (unsigned char *) malloc(size);
if (!data) goto finalize;
freeData = true;
if (fread(data, size, 1, pngFile) < 1) goto failure;
lodepng_state_init(&state);
unsigned int width, height;
if (lodepng_inspect(&width, &height, &state, data, size) > 0) goto failure;
w = static_cast<float>(width);
h = static_cast<float>(height);
if (state.info_png.color.colortype == LCT_RGBA) cs = ColorSpace::ABGR8888;
else cs = ColorSpace::ARGB8888;
ret = true;
goto finalize;
failure:
clear();
finalize:
fclose(pngFile);
return ret;
}
bool PngLoader::open(const char* data, uint32_t size, bool copy)
{
clear();
lodepng_state_init(&state);
unsigned int width, height;
if (lodepng_inspect(&width, &height, &state, (unsigned char*)(data), size) > 0) return false;
if (copy) {
this->data = (unsigned char *) malloc(size);
if (!this->data) return false;
memcpy((unsigned char *)this->data, data, size);
freeData = true;
} else {
this->data = (unsigned char *) data;
freeData = false;
}
w = static_cast<float>(width);
h = static_cast<float>(height);
this->size = size;
cs = ColorSpace::ABGR8888;
return true;
}
bool PngLoader::read()
{
if (!data || w <= 0 || h <= 0) return false;
TaskScheduler::request(this);
return true;
}
bool PngLoader::close()
{
this->done();
clear();
return true;
}
unique_ptr<Surface> PngLoader::bitmap()
{
this->done();
if (!image) return nullptr;
//TODO: It's better to keep this surface instance in the loader side
auto surface = new Surface;
surface->buf8 = image;
surface->stride = static_cast<uint32_t>(w);
surface->w = static_cast<uint32_t>(w);
surface->h = static_cast<uint32_t>(h);
surface->cs = cs;
surface->channelSize = sizeof(uint32_t);
surface->premultiplied = false;
surface->owner = true;
return unique_ptr<Surface>(surface);
}
void PngLoader::run(unsigned tid)
{
if (image) {
free(image);
image = nullptr;
}
auto width = static_cast<unsigned>(w);
auto height = static_cast<unsigned>(h);
if (lodepng_decode(&image, &width, &height, &state, data, size)) {
TVGERR("PNG", "Failed to decode image");
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021 - 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.
*/
#ifndef _TVG_PNG_LOADER_H_
#define _TVG_PNG_LOADER_H_
#include "tvgLodePng.h"
#include "tvgTaskScheduler.h"
class PngLoader : public LoadModule, public Task
{
private:
LodePNGState state;
unsigned char* data = nullptr;
unsigned char *image = nullptr;
unsigned long size = 0;
bool freeData = false;
void clear();
public:
PngLoader();
~PngLoader();
using LoadModule::open;
bool open(const string& path) override;
bool open(const char* data, uint32_t size, bool copy) override;
bool read() override;
bool close() override;
unique_ptr<Surface> bitmap() override;
void run(unsigned tid) override;
};
#endif //_TVG_PNG_LOADER_H_

View file

@ -284,8 +284,12 @@ static void _applyComposition(SvgLoaderData& loaderData, Paint* paint, const Svg
bool isMaskWhite = true;
if (auto comp = _sceneBuildHelper(loaderData, compNode, vBox, svgPath, true, 0, &isMaskWhite)) {
Matrix finalTransform = _compositionTransform(paint, node, compNode, SvgNodeType::Mask);
comp->transform(finalTransform);
if (!compNode->node.mask.userSpace) {
Matrix finalTransform = _compositionTransform(paint, node, compNode, SvgNodeType::Mask);
comp->transform(finalTransform);
} else {
if (node->transform) comp->transform(*node->transform);
}
if (compNode->node.mask.type == SvgMaskType::Luminance && !isMaskWhite) {
paint->composite(std::move(comp), CompositeMethod::LumaMask);

View file

@ -205,6 +205,7 @@ struct SwDashStroke
float* pattern = nullptr;
uint32_t cnt = 0;
bool curOpGap = false;
bool move = true;
};
struct SwShape

View file

@ -121,7 +121,10 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
if (len < dash.curLen) {
dash.curLen -= len;
if (!dash.curOpGap) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
if (dash.move) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
dash.move = false;
}
_outlineLineTo(*dash.outline, to, transform);
}
} else {
@ -131,7 +134,10 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
len -= dash.curLen;
_lineSplitAt(cur, dash.curLen, left, right);
if (!dash.curOpGap) {
_outlineMoveTo(*dash.outline, &left.pt1, transform);
if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) {
_outlineMoveTo(*dash.outline, &left.pt1, transform);
dash.move = false;
}
_outlineLineTo(*dash.outline, &left.pt2, transform);
}
} else {
@ -142,11 +148,15 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
dash.curOpGap = !dash.curOpGap;
cur = right;
dash.ptCur = cur.pt1;
dash.move = true;
}
//leftovers
dash.curLen -= len;
if (!dash.curOpGap) {
_outlineMoveTo(*dash.outline, &cur.pt1, transform);
if (dash.move) {
_outlineMoveTo(*dash.outline, &cur.pt1, transform);
dash.move = false;
}
_outlineLineTo(*dash.outline, &cur.pt2, transform);
}
if (dash.curLen < 1 && TO_SWCOORD(len) > 1) {
@ -168,21 +178,22 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
if (len < dash.curLen) {
dash.curLen -= len;
if (!dash.curOpGap) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
if (dash.move) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
dash.move = false;
}
_outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform);
}
} else {
bool begin = true; //starting with move_to
while (len > dash.curLen) {
Bezier left, right;
if (dash.curLen > 0) {
len -= dash.curLen;
bezSplitAt(cur, dash.curLen, left, right);
if (!dash.curOpGap) {
// leftovers from a previous command don't require moveTo
if (begin || dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) {
if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) {
_outlineMoveTo(*dash.outline, &left.start, transform);
begin = false;
dash.move = false;
}
_outlineCubicTo(*dash.outline, &left.ctrl1, &left.ctrl2, &left.end, transform);
}
@ -194,11 +205,15 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
dash.curOpGap = !dash.curOpGap;
cur = right;
dash.ptCur = right.start;
dash.move = true;
}
//leftovers
dash.curLen -= len;
if (!dash.curOpGap) {
_outlineMoveTo(*dash.outline, &cur.start, transform);
if (dash.move) {
_outlineMoveTo(*dash.outline, &cur.start, transform);
dash.move = false;
}
_outlineCubicTo(*dash.outline, &cur.ctrl1, &cur.ctrl2, &cur.end, transform);
}
if (dash.curLen < 1 && TO_SWCOORD(len) > 1) {
@ -212,6 +227,22 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
}
static void _dashClose(SwDashStroke& dash, const Matrix* transform)
{
_dashLineTo(dash, &dash.ptStart, transform);
}
static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const Point* pts, const Matrix* transform)
{
dash.curIdx = offIdx % dash.cnt;
dash.curLen = dash.pattern[dash.curIdx] - offset;
dash.curOpGap = offIdx % 2;
dash.ptStart = dash.ptCur = *pts;
dash.move = true;
}
static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* transform, float length, SwMpool* mpool, unsigned tid)
{
const PathCommand* cmds = rshape->path.cmds.data;
@ -261,7 +292,6 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
trimmed = true;
//just a dasy style.
} else {
if (dash.cnt == 0) return nullptr;
}
@ -303,15 +333,11 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
while (cmdCnt-- > 0) {
switch (*cmds) {
case PathCommand::Close: {
_dashLineTo(dash, &dash.ptStart, transform);
_dashClose(dash, transform);
break;
}
case PathCommand::MoveTo: {
//reset the dash
dash.curIdx = offIdx % dash.cnt;
dash.curLen = dash.pattern[dash.curIdx] - offset;
dash.curOpGap = offIdx % 2;
dash.ptStart = dash.ptCur = *pts;
_dashMoveTo(dash, offIdx, offset, pts, transform);
++pts;
break;
}

View file

@ -689,7 +689,6 @@ static void _endSubPath(SwStroke& stroke)
//No specific corner processing is required if the turn is 0
if (turn != 0) {
//when we turn to the right, the inside is 0
int32_t inside = 0;

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
VERSION=0.11.0
VERSION=0.11.1
cd thirdparty/thorvg/ || true
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/
@ -36,6 +36,8 @@ cat << EOF > ../inc/config.h
#define THORVG_SW_RASTER_SUPPORT
#define THORVG_SVG_LOADER_SUPPORT
#define THORVG_PNG_LOADER_SUPPORT
#define THORVG_JPG_LOADER_SUPPORT
// For internal debugging:
//#define THORVG_LOG_ENABLED
@ -51,9 +53,12 @@ cp -rv src/renderer ../src/
# Only sw_engine is enabled.
rm -rfv ../src/renderer/gl_engine
# Only svg (+raw) loader is enabled.
# Enabled embedded loaders: raw, JPEG, PNG.
mkdir ../src/loaders
cp -rv src/loaders/svg src/loaders/raw ../src/loaders/
cp -rv src/loaders/svg src/loaders/jpg ../src/loaders/
cp -rv src/loaders/svg src/loaders/png ../src/loaders/
cp -rv src/loaders/svg src/loaders/external_png ../src/loaders/
popd
rm -rf tmp