Skip to content

Commit 7ec3823

Browse files
committed
Remove unused SVGCustomWriter callbacks and refactor image encoding to shared helper.
1 parent 77cfd96 commit 7ec3823

5 files changed

Lines changed: 33 additions & 95 deletions

File tree

include/tgfx/svg/SVGCustomWriter.h

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@
1818

1919
#pragma once
2020

21-
#include "tgfx/core/BlendMode.h"
2221
#include "tgfx/core/Color.h"
23-
#include "tgfx/core/ColorFilter.h"
24-
#include "tgfx/core/Shader.h"
2522
#include "tgfx/core/TileMode.h"
2623
#include "tgfx/svg/xml/XMLDOM.h"
2724

@@ -57,29 +54,6 @@ class SVGCustomWriter {
5754
virtual DOMAttribute writeInnerShadowImageFilter(float dx, float dy, float blurrinessX,
5855
float blurrinessY, Color color,
5956
bool innerShadowOnly) = 0;
60-
61-
/**
62-
* Called when exporting a ColorImageFilter to SVG.
63-
* @param colorFilter The color filter being exported.
64-
* return A DOMAttribute to be added to the <filter> element as a custom attribute.
65-
*/
66-
virtual DOMAttribute writeColorImageFilter(const std::shared_ptr<ColorFilter>& colorFilter) {
67-
(void)colorFilter;
68-
return {};
69-
}
70-
71-
/**
72-
* Called when exporting a BlendImageFilter to SVG.
73-
* @param blendMode The blend mode used to composite the shader output with the source.
74-
* @param shader The shader whose output is blended with the source graphic.
75-
* return A DOMAttribute to be added to the <filter> element as a custom attribute.
76-
*/
77-
virtual DOMAttribute writeBlendImageFilter(BlendMode blendMode,
78-
const std::shared_ptr<Shader>& shader) {
79-
(void)blendMode;
80-
(void)shader;
81-
return {};
82-
}
8357
};
8458

8559
} // namespace tgfx

src/svg/ElementWriter.cpp

Lines changed: 8 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -357,13 +357,11 @@ std::string ElementWriter::emitFilterElement(const std::shared_ptr<ImageFilter>&
357357
}
358358
case Types::ImageFilterType::Color: {
359359
const auto colorFilter = static_cast<const ColorImageFilter*>(imageFilter.get());
360-
callbackColorImageFilter(colorFilter, exportWriter, filterElement);
361360
addColorImageFilter(colorFilter);
362361
break;
363362
}
364363
case Types::ImageFilterType::Blend: {
365364
const auto blendFilter = static_cast<const BlendImageFilter*>(imageFilter.get());
366-
callbackBlendImageFilter(blendFilter, exportWriter, filterElement);
367365
addBlendImageFilter(blendFilter, "", &bound, context);
368366
break;
369367
}
@@ -440,7 +438,6 @@ std::string ElementWriter::addImageFilter(const std::shared_ptr<ImageFilter>& im
440438
filterElement.addAttribute("width", bound.width());
441439
filterElement.addAttribute("height", bound.height());
442440
filterElement.addAttribute("filterUnits", "userSpaceOnUse");
443-
callbackColorImageFilter(colorFilter, exportWriter, filterElement);
444441
addColorImageFilter(colorFilter);
445442
return filterID;
446443
}
@@ -456,7 +453,6 @@ std::string ElementWriter::addImageFilter(const std::shared_ptr<ImageFilter>& im
456453
filterElement.addAttribute("width", bound.width());
457454
filterElement.addAttribute("height", bound.height());
458455
filterElement.addAttribute("filterUnits", "userSpaceOnUse");
459-
callbackBlendImageFilter(blendFilter, exportWriter, filterElement);
460456
addBlendImageFilter(blendFilter, "", &bound, context);
461457
return filterID;
462458
}
@@ -549,30 +545,6 @@ void ElementWriter::callbackInnerShadowImageFilter(
549545
}
550546
}
551547

552-
void ElementWriter::callbackColorImageFilter(const ColorImageFilter* filter,
553-
const std::shared_ptr<SVGCustomWriter>& exportWriter,
554-
ElementWriter& filterElement) {
555-
if (!exportWriter || !filter->filter) {
556-
return;
557-
}
558-
auto attribute = exportWriter->writeColorImageFilter(filter->filter);
559-
if (!attribute.name.empty() && !attribute.value.empty()) {
560-
filterElement.addAttribute(attribute.name, attribute.value);
561-
}
562-
}
563-
564-
void ElementWriter::callbackBlendImageFilter(const BlendImageFilter* filter,
565-
const std::shared_ptr<SVGCustomWriter>& exportWriter,
566-
ElementWriter& filterElement) {
567-
if (!exportWriter || !filter->shader) {
568-
return;
569-
}
570-
auto attribute = exportWriter->writeBlendImageFilter(filter->blendMode, filter->shader);
571-
if (!attribute.name.empty() && !attribute.value.empty()) {
572-
filterElement.addAttribute(attribute.name, attribute.value);
573-
}
574-
}
575-
576548
void ElementWriter::addBlurImageFilter(const GaussianBlurImageFilter* filter,
577549
const std::string& inputResult) {
578550
ElementWriter blurElement("feGaussianBlur", writer);
@@ -813,16 +785,7 @@ void ElementWriter::addBlendImageFilter(const BlendImageFilter* filter,
813785
return;
814786
}
815787
const auto imageShader = static_cast<const ImageShader*>(filter->shader.get());
816-
auto data = SVGExportContext::ImageToEncodedData(imageShader->image);
817-
std::shared_ptr<Data> dataUri = nullptr;
818-
if (data && (JpegCodec::IsJpeg(data) || PngCodec::IsPng(data))) {
819-
dataUri = AsDataUri(data);
820-
} else if (context) {
821-
Bitmap bitmap = SVGExportContext::ImageExportToBitmap(context, imageShader->image);
822-
if (!bitmap.isEmpty()) {
823-
dataUri = AsDataUri(Pixmap(bitmap));
824-
}
825-
}
788+
auto dataUri = SVGExportContext::EncodeImageToDataUri(imageShader->image, context);
826789
if (!dataUri) {
827790
reportUnsupportedElement("Failed to encode DstIn image shader in BlendImageFilter");
828791
return;
@@ -918,11 +881,14 @@ void ElementWriter::addBlendImageFilter(const BlendImageFilter* filter,
918881
svgFragment += " y1='" + FloatToString(info.points[0].y) + "'";
919882
svgFragment += " x2='" + FloatToString(info.points[1].x) + "'";
920883
svgFragment += " y2='" + FloatToString(info.points[1].y) + "'>";
921-
} else {
884+
} else if (gradientType == GradientType::Radial) {
922885
svgFragment += "<defs><radialGradient id='g' gradientUnits='userSpaceOnUse'";
923886
svgFragment += " cx='" + FloatToString(info.points[0].x) + "'";
924887
svgFragment += " cy='" + FloatToString(info.points[0].y) + "'";
925888
svgFragment += " r='" + FloatToString(info.radiuses[0]) + "'>";
889+
} else {
890+
reportUnsupportedElement("Unsupported gradient type in BlendImageFilter");
891+
break;
926892
}
927893
for (size_t i = 0; i < info.colors.size(); ++i) {
928894
auto color = ConvertColorSpace(info.colors[i], _targetColorSpace);
@@ -953,7 +919,7 @@ void ElementWriter::addBlendImageFilter(const BlendImageFilter* filter,
953919
Base64Encode(svgData, svgLength, base64String.data());
954920
{
955921
ElementWriter feImageElement("feImage", writer);
956-
feImageElement.addAttribute("href", "data:image/svg+xml;base64," + base64String);
922+
feImageElement.addAttribute("xlink:href", "data:image/svg+xml;base64," + base64String);
957923
if (filterBounds) {
958924
feImageElement.addAttribute("x", filterBounds->x());
959925
feImageElement.addAttribute("y", filterBounds->y());
@@ -972,16 +938,7 @@ void ElementWriter::addBlendImageFilter(const BlendImageFilter* filter,
972938
}
973939
case Types::ShaderType::Image: {
974940
const auto imageShader = static_cast<const ImageShader*>(blendShader);
975-
auto data = SVGExportContext::ImageToEncodedData(imageShader->image);
976-
std::shared_ptr<Data> dataUri = nullptr;
977-
if (data && (JpegCodec::IsJpeg(data) || PngCodec::IsPng(data))) {
978-
dataUri = AsDataUri(data);
979-
} else if (context) {
980-
Bitmap bitmap = SVGExportContext::ImageExportToBitmap(context, imageShader->image);
981-
if (!bitmap.isEmpty()) {
982-
dataUri = AsDataUri(Pixmap(bitmap));
983-
}
984-
}
941+
auto dataUri = SVGExportContext::EncodeImageToDataUri(imageShader->image, context);
985942
if (!dataUri) {
986943
reportUnsupportedElement("Failed to encode image shader in BlendImageFilter");
987944
break;
@@ -1429,19 +1386,7 @@ void ElementWriter::addImageShaderResources(const ImageShader* shader, const Mat
14291386
auto image = shader->image;
14301387
DEBUG_ASSERT(image);
14311388
image = ConvertImageColorSpace(image, context, _targetColorSpace, _assignColorSpace);
1432-
std::shared_ptr<Data> dataUri = nullptr;
1433-
1434-
auto data = SVGExportContext::ImageToEncodedData(image);
1435-
if (data && (JpegCodec::IsJpeg(data) || PngCodec::IsPng(data))) {
1436-
dataUri = AsDataUri(data);
1437-
} else {
1438-
Bitmap bitmap = SVGExportContext::ImageExportToBitmap(context, image);
1439-
if (bitmap.isEmpty()) {
1440-
return;
1441-
}
1442-
dataUri = AsDataUri(Pixmap(bitmap));
1443-
}
1444-
1389+
auto dataUri = SVGExportContext::EncodeImageToDataUri(image, context);
14451390
if (!dataUri) {
14461391
return;
14471392
}

src/svg/ElementWriter.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,7 @@ class ElementWriter {
161161
void callbackInnerShadowImageFilter(const InnerShadowImageFilter* filter,
162162
const std::shared_ptr<SVGCustomWriter>& exportWriter,
163163
ElementWriter& filterElement);
164-
void callbackColorImageFilter(const ColorImageFilter* filter,
165-
const std::shared_ptr<SVGCustomWriter>& exportWriter,
166-
ElementWriter& filterElement);
167-
void callbackBlendImageFilter(const BlendImageFilter* filter,
168-
const std::shared_ptr<SVGCustomWriter>& exportWriter,
169-
ElementWriter& filterElement);
164+
170165
void addHardAlphaElement();
171166
void addSoftAlphaElement();
172167
void addBlurImageFilter(const GaussianBlurImageFilter* filter,

src/svg/SVGExportContext.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "SVGUtils.h"
2323
#include "core/GlyphTransform.h"
2424
#include "core/RunRecord.h"
25+
#include "core/codecs/jpeg/JpegCodec.h"
26+
#include "core/codecs/png/PngCodec.h"
2527
#include "core/filters/GaussianBlurImageFilter.h"
2628
#include "core/filters/ShaderMaskFilter.h"
2729
#include "core/images/CodecImage.h"
@@ -864,4 +866,19 @@ std::shared_ptr<Data> SVGExportContext::ImageToEncodedData(const std::shared_ptr
864866
return imageCodec->getEncodedData();
865867
}
866868

869+
std::shared_ptr<Data> SVGExportContext::EncodeImageToDataUri(const std::shared_ptr<Image>& image,
870+
Context* context) {
871+
auto data = ImageToEncodedData(image);
872+
if (data && (JpegCodec::IsJpeg(data) || PngCodec::IsPng(data))) {
873+
return AsDataUri(data);
874+
}
875+
if (context) {
876+
Bitmap bitmap = ImageExportToBitmap(context, image);
877+
if (!bitmap.isEmpty()) {
878+
return AsDataUri(Pixmap(bitmap));
879+
}
880+
}
881+
return nullptr;
882+
}
883+
867884
} // namespace tgfx

src/svg/SVGExportContext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ class SVGExportContext : public DrawContext {
101101
*/
102102
static std::shared_ptr<Data> ImageToEncodedData(const std::shared_ptr<Image>& image);
103103

104+
/**
105+
* Encodes an image to a data URI string. Tries to use the original encoded data if available
106+
* (JPEG/PNG), otherwise rasterizes via the GPU context and encodes as PNG.
107+
*/
108+
static std::shared_ptr<Data> EncodeImageToDataUri(const std::shared_ptr<Image>& image,
109+
Context* context);
110+
104111
private:
105112
/**
106113
* Determine if the paint requires us to reset the viewport.Currently, we do this whenever the

0 commit comments

Comments
 (0)