svg: remove the condition for white shape fill in luma masking

Immediately apply LumaMask when SvgMaskType::Luminance is specified.
This commit is contained in:
Hermet Park 2024-10-14 19:20:41 +09:00
parent 0a16152d75
commit 6357da3b97

View file

@ -37,9 +37,8 @@
/* Internal Class Implementation */ /* Internal Class Implementation */
/************************************************************************/ /************************************************************************/
static bool _appendShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath);
static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform); static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform);
static unique_ptr<Scene> _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite = nullptr); static unique_ptr<Scene> _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth);
static inline bool _isGroupType(SvgNodeType type) static inline bool _isGroupType(SvgNodeType type)
@ -277,8 +276,7 @@ static void _applyComposition(SvgLoaderData& loaderData, Paint* paint, const Svg
if (compNode && compNode->child.count > 0) { if (compNode && compNode->child.count > 0) {
node->style->mask.applying = true; node->style->mask.applying = true;
bool isMaskWhite = true; if (auto comp = _sceneBuildHelper(loaderData, compNode, vBox, svgPath, true, 0)) {
if (auto comp = _sceneBuildHelper(loaderData, compNode, vBox, svgPath, true, 0, &isMaskWhite)) {
if (!compNode->node.mask.userSpace) { if (!compNode->node.mask.userSpace) {
Matrix finalTransform = _compositionTransform(paint, node, compNode, SvgNodeType::Mask); Matrix finalTransform = _compositionTransform(paint, node, compNode, SvgNodeType::Mask);
comp->transform(finalTransform); comp->transform(finalTransform);
@ -286,7 +284,7 @@ static void _applyComposition(SvgLoaderData& loaderData, Paint* paint, const Svg
if (node->transform) comp->transform(*node->transform); if (node->transform) comp->transform(*node->transform);
} }
if (compNode->node.mask.type == SvgMaskType::Luminance && !isMaskWhite) { if (compNode->node.mask.type == SvgMaskType::Luminance) {
paint->mask(std::move(comp), MaskMethod::Luma); paint->mask(std::move(comp), MaskMethod::Luma);
} else { } else {
paint->mask(std::move(comp), MaskMethod::Alpha); paint->mask(std::move(comp), MaskMethod::Alpha);
@ -380,14 +378,6 @@ static void _applyProperty(SvgLoaderData& loaderData, SvgNode* node, Shape* vg,
} }
static unique_ptr<Shape> _shapeBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const Box& vBox, const string& svgPath)
{
auto shape = Shape::gen();
if (_appendShape(loaderData, node, shape.get(), vBox, svgPath)) return shape;
else return nullptr;
}
static bool _recognizeShape(SvgNode* node, Shape* shape) static bool _recognizeShape(SvgNode* node, Shape* shape)
{ {
switch (node->type) { switch (node->type) {
@ -444,12 +434,12 @@ static bool _recognizeShape(SvgNode* node, Shape* shape)
} }
static bool _appendShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath) static unique_ptr<Shape> _shapeBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const Box& vBox, const string& svgPath)
{ {
if (!_recognizeShape(node, shape)) return false; auto shape = Shape::gen();
if (!_recognizeShape(node, shape.get())) return nullptr;
_applyProperty(loaderData, node, shape, vBox, svgPath, false); _applyProperty(loaderData, node, shape.get(), vBox, svgPath, false);
return true; return shape;
} }
@ -699,9 +689,9 @@ static Matrix _calculateAspectRatioMatrix(AspectRatioAlign align, AspectRatioMee
} }
static unique_ptr<Scene> _useBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, int depth, bool* isMaskWhite) static unique_ptr<Scene> _useBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, int depth)
{ {
auto scene = _sceneBuildHelper(loaderData, node, vBox, svgPath, false, depth + 1, isMaskWhite); auto scene = _sceneBuildHelper(loaderData, node, vBox, svgPath, false, depth + 1);
// mUseTransform = mUseTransform * mTranslate // mUseTransform = mUseTransform * mTranslate
Matrix mUseTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; Matrix mUseTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
@ -813,7 +803,7 @@ static unique_ptr<Text> _textBuildHelper(SvgLoaderData& loaderData, const SvgNod
} }
static unique_ptr<Scene> _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite) static unique_ptr<Scene> _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth)
{ {
/* Exception handling: Prevent invalid SVG data input. /* Exception handling: Prevent invalid SVG data input.
The size is the arbitrary value, we need an experimental size. */ The size is the arbitrary value, we need an experimental size. */
@ -832,34 +822,22 @@ static unique_ptr<Scene> _sceneBuildHelper(SvgLoaderData& loaderData, const SvgN
for (uint32_t i = 0; i < node->child.count; ++i, ++child) { for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
if (_isGroupType((*child)->type)) { if (_isGroupType((*child)->type)) {
if ((*child)->type == SvgNodeType::Use) if ((*child)->type == SvgNodeType::Use)
scene->push(_useBuildHelper(loaderData, *child, vBox, svgPath, depth + 1, isMaskWhite)); scene->push(_useBuildHelper(loaderData, *child, vBox, svgPath, depth + 1));
else if (!((*child)->type == SvgNodeType::Symbol && node->type != SvgNodeType::Use)) else if (!((*child)->type == SvgNodeType::Symbol && node->type != SvgNodeType::Use))
scene->push(_sceneBuildHelper(loaderData, *child, vBox, svgPath, false, depth + 1, isMaskWhite)); scene->push(_sceneBuildHelper(loaderData, *child, vBox, svgPath, false, depth + 1));
if ((*child)->id) scene->id = djb2Encode((*child)->id); if ((*child)->id) scene->id = djb2Encode((*child)->id);
} else if ((*child)->type == SvgNodeType::Image) { } else if ((*child)->type == SvgNodeType::Image) {
auto image = _imageBuildHelper(loaderData, *child, vBox, svgPath); if (auto image = _imageBuildHelper(loaderData, *child, vBox, svgPath)) {
if (image) {
if ((*child)->id) image->id = djb2Encode((*child)->id); if ((*child)->id) image->id = djb2Encode((*child)->id);
scene->push(std::move(image)); scene->push(std::move(image));
if (isMaskWhite) *isMaskWhite = false;
} }
} else if ((*child)->type == SvgNodeType::Text) { } else if ((*child)->type == SvgNodeType::Text) {
auto text = _textBuildHelper(loaderData, *child, vBox, svgPath); if (auto text = _textBuildHelper(loaderData, *child, vBox, svgPath)) {
if (text) {
if ((*child)->id) text->id = djb2Encode((*child)->id); if ((*child)->id) text->id = djb2Encode((*child)->id);
scene->push(std::move(text)); scene->push(std::move(text));
} }
} else if ((*child)->type != SvgNodeType::Mask) { } else if ((*child)->type != SvgNodeType::Mask) {
auto shape = _shapeBuildHelper(loaderData, *child, vBox, svgPath); if (auto shape = _shapeBuildHelper(loaderData, *child, vBox, svgPath)) {
if (shape) {
if (isMaskWhite) {
uint8_t r, g, b;
shape->fillColor(&r, &g, &b);
if (shape->fill() || r < 255 || g < 255 || b < 255 || shape->strokeFill() ||
(shape->strokeFill(&r, &g, &b) == Result::Success && (r < 255 || g < 255 || b < 255))) {
*isMaskWhite = false;
}
}
if ((*child)->id) shape->id = djb2Encode((*child)->id); if ((*child)->id) shape->id = djb2Encode((*child)->id);
scene->push(std::move(shape)); scene->push(std::move(shape));
} }