bugfix:修复svg线性渐变颜色识别错误

Signed-off-by: Zhang Jinyu <zhangjinyu101@huawei.com>
Change-Id: I53872c205d3b7440e99d71a231e00710446cd538
This commit is contained in:
Zhang Jinyu 2024-08-30 14:02:27 +08:00
parent b9c36704d9
commit 4f0cde8b47
6 changed files with 50 additions and 5 deletions

View File

@ -21,6 +21,10 @@ const char LINECAP_ROUND[] = "round";
const char LINECAP_SQUARE[] = "square"; const char LINECAP_SQUARE[] = "square";
const char LINEJOIN_BEVEL[] = "bevel"; const char LINEJOIN_BEVEL[] = "bevel";
const char LINEJOIN_ROUND[] = "round"; const char LINEJOIN_ROUND[] = "round";
const std::regex COLOR_WITH_ALPHA(
R"(rgba?\(([0-9]{1,3})\,([0-9]{1,3})\,([0-9]{1,3})\,(\d+\.?\d*)\))", std::regex::icase);
constexpr uint32_t RGBA_SUB_MATCH_SIZE = 5;
constexpr double MAX_ALPHA = 1.0;
} }
LineCapStyle SvgAttributesParser::GetLineCapStyle(const std::string& val) LineCapStyle SvgAttributesParser::GetLineCapStyle(const std::string& val)
@ -214,4 +218,20 @@ double SvgAttributesParser::ParseDouble(const std::string& value)
return StringUtils::StringToDouble(value); return StringUtils::StringToDouble(value);
} }
bool SvgAttributesParser::CheckColorAlpha(const std::string& colorStr, Color& result)
{
std::smatch matches;
if (std::regex_match(colorStr, matches, COLOR_WITH_ALPHA)) {
if (matches.size() == RGBA_SUB_MATCH_SIZE) {
auto red = static_cast<uint8_t>(std::stoi(matches[1]));
auto green = static_cast<uint8_t>(std::stoi(matches[2]));
auto blue = static_cast<uint8_t>(std::stoi(matches[3]));
auto alpha = static_cast<double>(std::stod(matches[4]));
// Scale up from 0~1.0 to 255
result = Color::FromARGB(static_cast<uint8_t>(std::min(MAX_ALPHA, alpha)) * 0xff, red, green, blue);
return true;
}
}
return false;
}
} // namespace OHOS::Ace::NG } // namespace OHOS::Ace::NG

View File

@ -32,6 +32,7 @@ public:
static LineJoinStyle GetLineJoinStyle(const std::string& val); static LineJoinStyle GetLineJoinStyle(const std::string& val);
static Dimension ParseDimension(const std::string& value, bool useVp = false); static Dimension ParseDimension(const std::string& value, bool useVp = false);
static double ParseDouble(const std::string& value); static double ParseDouble(const std::string& value);
static bool CheckColorAlpha(const std::string& colorStr, Color& result);
}; };
enum class SvgFeColorMatrixType { enum class SvgFeColorMatrixType {

View File

@ -83,6 +83,11 @@ void SvgGraphic::SetLinearGradient(const Size& viewPort, OHOS::Ace::Gradient& gr
const auto& linearGradient = gradient.GetLinearGradient(); const auto& linearGradient = gradient.GetLinearGradient();
auto gradientInfo = OHOS::Ace::LinearGradientInfo(); auto gradientInfo = OHOS::Ace::LinearGradientInfo();
if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_FOURTEEN) &&
NearEqual(linearGradient.x1, linearGradient.y1) && NearEqual(linearGradient.x2, linearGradient.y2)) {
RectifyTargetSize(bounds, width, height);
}
gradientInfo.x1 = linearGradient.x1 ? ConvertDimensionToPx(linearGradient.x1.value(), width) : 0.0; gradientInfo.x1 = linearGradient.x1 ? ConvertDimensionToPx(linearGradient.x1.value(), width) : 0.0;
if (linearGradient.x1 && linearGradient.x1.value().Unit() == DimensionUnit::PERCENT) { if (linearGradient.x1 && linearGradient.x1.value().Unit() == DimensionUnit::PERCENT) {
gradientInfo.x1 += bounds.Left(); gradientInfo.x1 += bounds.Left();
@ -372,4 +377,14 @@ void SvgGraphic::UpdateColorFilter(RSFilter& filter)
} }
filter.SetColorFilter(*colorFilterSptrAddr); filter.SetColorFilter(*colorFilterSptrAddr);
} }
void SvgGraphic::RectifyTargetSize(const Rect& bounds, double& width, double& height)
{
if (NearZero(bounds.Height())) {
return;
}
auto scalar = bounds.Width() / bounds.Height();
width = 2 * bounds.Height() * sin(std::atan(scalar)) * cos(atan(scalar)); // 2: algorithm parameters
height = 2 * bounds.Height() * sin(std::atan(scalar)) * sin(atan(scalar)); // 2: algorithm parameters
}
} // namespace OHOS::Ace::NG } // namespace OHOS::Ace::NG

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022 Huawei Device Co., Ltd. * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -160,6 +160,7 @@ protected:
private: private:
void UpdateColorFilter(RSFilter& filter); void UpdateColorFilter(RSFilter& filter);
bool CheckHrefPattern(); bool CheckHrefPattern();
void RectifyTargetSize(const Rect& bounds, double& width, double& height);
}; };
} // namespace OHOS::Ace::NG } // namespace OHOS::Ace::NG

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022 Huawei Device Co., Ltd. * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -15,6 +15,7 @@
#include "frameworks/core/components_ng/svg/parse/svg_stop.h" #include "frameworks/core/components_ng/svg/parse/svg_stop.h"
#include "core/common/container.h"
#include "frameworks/core/components_ng/svg/parse/svg_constants.h" #include "frameworks/core/components_ng/svg/parse/svg_constants.h"
namespace OHOS::Ace::NG { namespace OHOS::Ace::NG {
@ -31,10 +32,13 @@ RefPtr<SvgNode> SvgStop::Create()
{ {
auto svgNode = AceType::MakeRefPtr<SvgStop>(); auto svgNode = AceType::MakeRefPtr<SvgStop>();
svgNode->stopAttr_.gradientColor.SetDimension(0.0); svgNode->stopAttr_.gradientColor.SetDimension(0.0);
if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_FOURTEEN)) {
svgNode->stopAttr_.gradientColor.SetColor(Color::BLACK);
}
return svgNode; return svgNode;
} }
const GradientColor& SvgStop::GetGradientColor() const const Ace::GradientColor& SvgStop::GetGradientColor() const
{ {
return stopAttr_.gradientColor; return stopAttr_.gradientColor;
} }
@ -50,6 +54,10 @@ bool SvgStop::ParseAndSetSpecializedAttr(const std::string& name, const std::str
[](const std::string& val, SvgStopAttribute& attribute) { [](const std::string& val, SvgStopAttribute& attribute) {
Color color = (val == VALUE_NONE ? Color::TRANSPARENT : SvgAttributesParser::GetColor(val)); Color color = (val == VALUE_NONE ? Color::TRANSPARENT : SvgAttributesParser::GetColor(val));
attribute.gradientColor.SetColor(color); attribute.gradientColor.SetColor(color);
if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_FOURTEEN)) {
SvgAttributesParser::CheckColorAlpha(val, color);
attribute.gradientColor.SetColor(color);
}
} }, } },
{ DOM_SVG_SRC_STOP_OPACITY, { DOM_SVG_SRC_STOP_OPACITY,
[](const std::string& val, SvgStopAttribute& attribute) { [](const std::string& val, SvgStopAttribute& attribute) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022 Huawei Device Co., Ltd. * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -30,7 +30,7 @@ public:
static RefPtr<SvgNode> Create(); static RefPtr<SvgNode> Create();
bool ParseAndSetSpecializedAttr(const std::string& name, const std::string& value) override; bool ParseAndSetSpecializedAttr(const std::string& name, const std::string& value) override;
const GradientColor& GetGradientColor() const; const Ace::GradientColor& GetGradientColor() const;
private: private:
SvgStopAttribute stopAttr_; SvgStopAttribute stopAttr_;