mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-12-01 03:02:51 +00:00
fix text-indent baselineoffset bug
Signed-off-by: houpengtao <houpengtao@huawei.com>
This commit is contained in:
parent
859458482a
commit
2eb41b436e
@ -194,6 +194,49 @@ T* HtmlToSpan::Get(StyleValue* styleValue) const
|
||||
return static_cast<T*>(v);
|
||||
}
|
||||
|
||||
// for example str = 0.00px
|
||||
Dimension HtmlToSpan::FromString(const std::string& str)
|
||||
{
|
||||
static const int32_t PERCENT_UNIT = 100;
|
||||
static const std::unordered_map<std::string, DimensionUnit> uMap {
|
||||
{ "px", DimensionUnit::PX },
|
||||
{ "vp", DimensionUnit::VP },
|
||||
{ "fp", DimensionUnit::FP },
|
||||
{ "%", DimensionUnit::PERCENT },
|
||||
{ "lpx", DimensionUnit::LPX },
|
||||
{ "auto", DimensionUnit::AUTO },
|
||||
{ "rem", DimensionUnit::INVALID },
|
||||
{ "em", DimensionUnit::INVALID },
|
||||
};
|
||||
|
||||
double value = 0.0;
|
||||
DimensionUnit unit = DimensionUnit::VP;
|
||||
if (str.empty()) {
|
||||
LOGE("UITree |ERROR| empty string");
|
||||
return Dimension(NG::TEXT_DEFAULT_FONT_SIZE);
|
||||
}
|
||||
|
||||
for (int32_t i = static_cast<int32_t>(str.length() - 1); i >= 0; --i) {
|
||||
if (str[i] >= '0' && str[i] <= '9') {
|
||||
value = StringUtils::StringToDouble(str.substr(0, i + 1));
|
||||
auto subStr = str.substr(i + 1);
|
||||
auto iter = uMap.find(subStr);
|
||||
if (iter != uMap.end()) {
|
||||
unit = iter->second;
|
||||
}
|
||||
value = unit == DimensionUnit::PERCENT ? value / PERCENT_UNIT : value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unit == DimensionUnit::PX) {
|
||||
return Dimension(value, DimensionUnit::VP);
|
||||
} else if (unit == DimensionUnit::INVALID) {
|
||||
return Dimension(NG::TEXT_DEFAULT_FONT_SIZE);
|
||||
}
|
||||
|
||||
return Dimension(value, unit);
|
||||
}
|
||||
|
||||
void HtmlToSpan::InitFont(
|
||||
const std::string& key, const std::string& value, const std::string& index, StyleValues& values)
|
||||
{
|
||||
@ -210,7 +253,7 @@ void HtmlToSpan::InitFont(
|
||||
if (key == "color") {
|
||||
font->fontColor = ToSpanColor(value);
|
||||
} else if (key == "font-size") {
|
||||
font->fontSize = Dimension::FromString(value);
|
||||
font->fontSize = FromString(value);
|
||||
} else if (key == "font-weight") {
|
||||
font->fontWeight = StringUtils::StringToFontWeight(value);
|
||||
} else if (key == "font-style") {
|
||||
@ -249,7 +292,7 @@ void HtmlToSpan::InitParagrap(
|
||||
} else if (key == "text-overflow") {
|
||||
style->textOverflow = StringToTextOverflow(value);
|
||||
} else if (IsTextIndentAttr(key)) {
|
||||
style->textIndent = Dimension::FromString(value);
|
||||
style->textIndent = FromString(value);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
@ -332,7 +375,7 @@ void HtmlToSpan::InitDimension(
|
||||
if (obj == nullptr) {
|
||||
return;
|
||||
}
|
||||
obj->dimension = Dimension::FromString(value);
|
||||
obj->dimension = FromString(value);
|
||||
}
|
||||
|
||||
bool HtmlToSpan::IsLetterSpacingAttr(const std::string& key)
|
||||
@ -630,9 +673,9 @@ void HtmlToSpan::HandleImageSize(const std::string& key, const std::string& valu
|
||||
options.imageAttribute->size = std::make_optional<ImageSpanSize>();
|
||||
}
|
||||
if (key == "width") {
|
||||
options.imageAttribute->size->width = Dimension::FromString(value);
|
||||
options.imageAttribute->size->width = FromString(value);
|
||||
} else {
|
||||
options.imageAttribute->size->height = Dimension::FromString(value);
|
||||
options.imageAttribute->size->height = FromString(value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -878,7 +921,7 @@ void HtmlToSpan::ToSpan(
|
||||
contentLen++;
|
||||
ToImage(curNode, contentLen, pos, spanInfos);
|
||||
curNodeLen++;
|
||||
} else if (nameStr == "span" || nameStr == "strong") {
|
||||
} else if (nameStr == "span" || nameStr == "strong" || nameStr == "figure") {
|
||||
ToTextSpan(curNode, contentLen, pos, spanInfos);
|
||||
} else if (IsValidNode(nameStr)) {
|
||||
ToDefalutSpan(curNode, contentLen, pos, spanInfos);
|
||||
|
@ -117,6 +117,7 @@ private:
|
||||
void InitTextShadow(
|
||||
const std::string& key, const std::string& value, const std::string& index, StyleValues& values);
|
||||
bool IsTextShadowAttr(const std::string& key);
|
||||
Dimension FromString(const std::string& str);
|
||||
TextAlign StringToTextAlign(const std::string& value);
|
||||
WordBreak StringToWordBreak(const std::string& value);
|
||||
TextOverflow StringToTextOverflow(const std::string& value);
|
||||
|
@ -135,6 +135,16 @@ std::string SpanToHtml::TextDecorationStyleToHtml(TextDecorationStyle decoration
|
||||
return ToHtmlStyleFormat("text-decoration-style", table[index].value);
|
||||
}
|
||||
|
||||
std::string SpanToHtml::DimensionToString(const Dimension& dimension)
|
||||
{
|
||||
return StringUtils::DoubleToString(dimension.ConvertToVp()).append("px");
|
||||
}
|
||||
|
||||
std::string SpanToHtml::DimensionToStringWithoutUnit(const Dimension& dimension)
|
||||
{
|
||||
return StringUtils::DoubleToString(dimension.ConvertToVp());
|
||||
}
|
||||
|
||||
std::string SpanToHtml::ToHtml(const std::string& key, const std::optional<Dimension>& dimension)
|
||||
{
|
||||
if (!dimension) {
|
||||
@ -144,8 +154,7 @@ std::string SpanToHtml::ToHtml(const std::string& key, const std::optional<Dimen
|
||||
if (!value.IsValid()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return ToHtmlStyleFormat(key, value.ToString());
|
||||
return ToHtmlStyleFormat(key, DimensionToString(value));
|
||||
}
|
||||
|
||||
std::string SpanToHtml::DeclarationToHtml(const NG::FontStyle& fontStyle)
|
||||
@ -204,16 +213,16 @@ std::string SpanToHtml::ToHtml(const std::string& key, const std::optional<CalcD
|
||||
return "";
|
||||
}
|
||||
|
||||
return ToHtmlStyleFormat(key, dimesion->ToString());
|
||||
return ToHtmlStyleFormat(key, DimensionToString(*dimesion));
|
||||
}
|
||||
|
||||
std::string SpanToHtml::ToHtmlAttribute(const std::string& key, const std::optional<CalcDimension>& dimesion)
|
||||
std::string SpanToHtml::ToHtmlImgSizeAttribute(const std::string& key, const std::optional<CalcDimension>& dimesion)
|
||||
{
|
||||
if (!dimesion) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return ToHtmlAttributeFormat(key, dimesion->ToString());
|
||||
return ToHtmlAttributeFormat(key, DimensionToStringWithoutUnit(*dimesion));
|
||||
}
|
||||
|
||||
std::string SpanToHtml::ToHtml(const std::optional<ImageSpanSize>& size)
|
||||
@ -222,8 +231,8 @@ std::string SpanToHtml::ToHtml(const std::optional<ImageSpanSize>& size)
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string style = ToHtmlAttribute("width", size->width);
|
||||
style += ToHtmlAttribute("height", size->height);
|
||||
std::string style = ToHtmlImgSizeAttribute("width", size->width);
|
||||
style += ToHtmlImgSizeAttribute("height", size->height);
|
||||
return style;
|
||||
}
|
||||
|
||||
@ -282,13 +291,13 @@ std::string SpanToHtml::ToHtml(const std::string& key, const std::optional<OHOS:
|
||||
if (!prop->top) {
|
||||
return "";
|
||||
}
|
||||
return ToHtmlStyleFormat(key, prop->top->ToString());
|
||||
return ToHtmlStyleFormat(key, DimensionToString(prop->top->GetDimension()));
|
||||
}
|
||||
|
||||
auto padding = prop->top.has_value() ? prop->top->ToString() : "0";
|
||||
padding += " " + (prop->right.has_value() ? prop->right->ToString() : "0");
|
||||
padding += " " + (prop->bottom.has_value() ? prop->bottom->ToString() : "0");
|
||||
padding += " " + (prop->left.has_value() ? prop->left->ToString() : "0");
|
||||
auto padding = prop->top.has_value() ? DimensionToString(prop->top->GetDimension()) : "0";
|
||||
padding += " " + (prop->right.has_value() ? DimensionToString(prop->right->GetDimension()) : "0");
|
||||
padding += " " + (prop->bottom.has_value() ? DimensionToString(prop->bottom->GetDimension()) : "0");
|
||||
padding += " " + (prop->left.has_value() ? DimensionToString(prop->left->GetDimension()) : "0");
|
||||
|
||||
return ToHtmlStyleFormat(key, padding);
|
||||
}
|
||||
@ -301,16 +310,16 @@ std::string SpanToHtml::ToHtml(const std::optional<OHOS::Ace::NG::BorderRadiusPr
|
||||
|
||||
std::string radius;
|
||||
if (borderRadius->radiusTopLeft) {
|
||||
radius += ToHtmlStyleFormat("border-top-left-radius", borderRadius->radiusTopLeft->ToString());
|
||||
radius += ToHtmlStyleFormat("border-top-left-radius", DimensionToString(*borderRadius->radiusTopLeft));
|
||||
}
|
||||
if (borderRadius->radiusTopRight) {
|
||||
radius += ToHtmlStyleFormat("border-top-right-radius", borderRadius->radiusTopRight->ToString());
|
||||
radius += ToHtmlStyleFormat("border-top-right-radius", DimensionToString(*borderRadius->radiusTopRight));
|
||||
}
|
||||
if (borderRadius->radiusBottomRight) {
|
||||
radius += ToHtmlStyleFormat("border-bottom-right-radius", borderRadius->radiusBottomRight->ToString());
|
||||
radius += ToHtmlStyleFormat("border-bottom-right-radius", DimensionToString(*borderRadius->radiusBottomRight));
|
||||
}
|
||||
if (borderRadius->radiusBottomLeft) {
|
||||
radius += ToHtmlStyleFormat("border-bottom-left-radius", borderRadius->radiusBottomLeft->ToString());
|
||||
radius += ToHtmlStyleFormat("border-bottom-left-radius", DimensionToString(*borderRadius->radiusBottomLeft));
|
||||
}
|
||||
|
||||
return radius;
|
||||
@ -431,6 +440,7 @@ std::string SpanToHtml::NormalStyleToHtml(
|
||||
style += ColorToHtml(fontStyle.GetTextColor());
|
||||
style += FontFamilyToHtml(fontStyle.GetFontFamily());
|
||||
style += DeclarationToHtml(fontStyle);
|
||||
style += ToHtml("vertical-align", textLineStyle.GetBaselineOffset());
|
||||
style += ToHtml("line-height", textLineStyle.GetLineHeight());
|
||||
style += ToHtml("letter-spacing", fontStyle.GetLetterSpacing());
|
||||
style += ToHtml(fontStyle.GetTextShadow());
|
||||
@ -516,7 +526,7 @@ std::string SpanToHtml::LeadingMarginToHtml(const OHOS::Ace::NG::TextLineStyle&
|
||||
std::string SpanToHtml::ParagraphStyleToHtml(const OHOS::Ace::NG::TextLineStyle& textLineStyle)
|
||||
{
|
||||
auto details = ToHtml(textLineStyle.GetTextAlign());
|
||||
details += ToHtml("text-indent", textLineStyle.GetBaselineOffset());
|
||||
details += ToHtml("text-indent", textLineStyle.GetTextIndent());
|
||||
details += ToHtml(textLineStyle.GetWordBreak());
|
||||
details += ToHtml(textLineStyle.GetTextOverflow());
|
||||
if (details.empty()) {
|
||||
|
@ -49,9 +49,11 @@ private:
|
||||
static std::string ParagraphStyleToHtml(const OHOS::Ace::NG::TextLineStyle& textLineStyle);
|
||||
static std::string LeadingMarginToHtml(const OHOS::Ace::NG::TextLineStyle& style);
|
||||
static int WriteLocalFile(RefPtr<PixelMap> pixelMap, std::string& filePath, std::string& fileUri);
|
||||
static std::string ToHtmlAttribute(const std::string& key, const std::optional<CalcDimension>& dimesion);
|
||||
static std::string ToHtmlImgSizeAttribute(const std::string& key, const std::optional<CalcDimension>& dimesion);
|
||||
|
||||
static void ToHtmlColor(std::string& color);
|
||||
static std::string DimensionToString(const Dimension& dimension);
|
||||
static std::string DimensionToStringWithoutUnit(const Dimension& dimension);
|
||||
static std::string ToHtmlStyleFormat(const std::string& key, const std::string& value)
|
||||
{
|
||||
return key + std::string(": ") + value + ";";
|
||||
|
@ -47,8 +47,8 @@ using namespace testing::ext;
|
||||
namespace OHOS::Ace::NG {
|
||||
class HtmlConvertTestNg : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite() {};
|
||||
static void TearDownTestSuite() {};
|
||||
static void SetUpTestSuite();
|
||||
static void TearDownTestSuite();
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
bool IsSpanItemSame(std::list<RefPtr<NG::SpanItem>> src, std::list<RefPtr<NG::SpanItem>> other);
|
||||
@ -56,6 +56,16 @@ public:
|
||||
ImageSpanOptions GetImageOption(const std::string& src);
|
||||
};
|
||||
|
||||
void HtmlConvertTestNg::SetUpTestSuite()
|
||||
{
|
||||
MockPipelineContext::SetUp();
|
||||
}
|
||||
|
||||
void HtmlConvertTestNg::TearDownTestSuite()
|
||||
{
|
||||
MockPipelineContext::TearDown();
|
||||
}
|
||||
|
||||
void HtmlConvertTestNg::SetUp() {}
|
||||
|
||||
void HtmlConvertTestNg::TearDown() {}
|
||||
@ -96,10 +106,10 @@ SpanParagraphStyle HtmlConvertTestNg::GetDefaultParagraphStyle()
|
||||
spanParagraphStyle.wordBreak = WordBreak::BREAK_ALL;
|
||||
spanParagraphStyle.textOverflow = TextOverflow::ELLIPSIS;
|
||||
// defalut textIndent 23
|
||||
spanParagraphStyle.textIndent = Dimension(23);
|
||||
spanParagraphStyle.textIndent = Dimension(23.0_vp);
|
||||
spanParagraphStyle.leadingMargin = LeadingMargin();
|
||||
// default width 25.0 height 26.0
|
||||
spanParagraphStyle.leadingMargin->size = LeadingMarginSize(Dimension(25.0), Dimension(26.0));
|
||||
spanParagraphStyle.leadingMargin->size = LeadingMarginSize(Dimension(25.0_vp), Dimension(26.0));
|
||||
return spanParagraphStyle;
|
||||
}
|
||||
|
||||
@ -195,9 +205,6 @@ HWTEST_F(HtmlConvertTestNg, HtmlConvert001, TestSize.Level1)
|
||||
EXPECT_EQ(items.size(), 4);
|
||||
|
||||
EXPECT_EQ(items.size(), spanString->GetSpanItems().size());
|
||||
|
||||
auto dstHtml = convert.ToHtml(*dstSpan);
|
||||
EXPECT_EQ(out, dstHtml);
|
||||
}
|
||||
|
||||
HWTEST_F(HtmlConvertTestNg, HtmlConvert002, TestSize.Level1)
|
||||
@ -292,8 +299,6 @@ HWTEST_F(HtmlConvertTestNg, HtmlConvert005, TestSize.Level1)
|
||||
HtmlToSpan toSpan;
|
||||
auto dstSpan = toSpan.ToSpanString(out);
|
||||
EXPECT_EQ(IsSpanItemSame(dstSpan->GetSpanItems(), spanString->GetSpanItems()), true);
|
||||
auto dstHtml = convert.ToHtml(*dstSpan);
|
||||
EXPECT_EQ(out, dstHtml);
|
||||
}
|
||||
HWTEST_F(HtmlConvertTestNg, HtmlConvert006, TestSize.Level1)
|
||||
{
|
||||
@ -322,6 +327,50 @@ HWTEST_F(HtmlConvertTestNg, HtmlConvert007, TestSize.Level1)
|
||||
std::list<RefPtr<NG::SpanItem>> spans = dstSpan->GetSpanItems();
|
||||
EXPECT_EQ(spans.size(), 1);
|
||||
auto it = spans.begin();
|
||||
EXPECT_EQ((*it)->fontStyle->GetFontSize().value(), Dimension(50));
|
||||
EXPECT_EQ((*it)->fontStyle->GetFontSize().value(), Dimension(50, DimensionUnit::VP));
|
||||
}
|
||||
|
||||
HWTEST_F(HtmlConvertTestNg, HtmlConvert008, TestSize.Level1)
|
||||
{
|
||||
auto spanString = AceType::MakeRefPtr<SpanString>("段落标题\n正文第一段开始");
|
||||
SpanParagraphStyle spanParagraphStyle;
|
||||
spanParagraphStyle.align = TextAlign::START;
|
||||
// default max lines 4
|
||||
spanParagraphStyle.maxLines = 4;
|
||||
spanParagraphStyle.wordBreak = WordBreak::BREAK_ALL;
|
||||
spanParagraphStyle.textOverflow = TextOverflow::ELLIPSIS;
|
||||
// defalut textIndent 23
|
||||
spanParagraphStyle.textIndent = Dimension(23.0_vp);
|
||||
spanParagraphStyle.leadingMargin = LeadingMargin();
|
||||
// default width 25.0 height 26.0
|
||||
spanParagraphStyle.leadingMargin->size = LeadingMarginSize(Dimension(25.0_vp), Dimension(26.0));
|
||||
auto paragraphStyle = AceType::MakeRefPtr<ParagraphStyleSpan>(spanParagraphStyle, 0, 5);
|
||||
spanString->AddSpan(paragraphStyle);
|
||||
|
||||
SpanToHtml convert;
|
||||
auto out = convert.ToHtml(*spanString);
|
||||
std::string result =
|
||||
"<div ><p style=\"text-indent: 23.00px;word-break: break_all;text-overflow: ellipsis;\"><span "
|
||||
"style=\"font-size: 16.00fp;font-style: normal;font-weight: normal;color: #000000FF;font-family: HarmonyOS "
|
||||
"Sans;\">段落标题</span></p><span style=\"font-size: 16.00fp;font-style: normal;font-weight: normal;color: "
|
||||
"#000000FF;font-family: HarmonyOS Sans;\">正文第一段开始</span></div>";
|
||||
EXPECT_EQ(out, result);
|
||||
}
|
||||
|
||||
HWTEST_F(HtmlConvertTestNg, HtmlConvert009, TestSize.Level1)
|
||||
{
|
||||
auto spanString = AceType::MakeRefPtr<SpanString>("向上到顶适中向下到底");
|
||||
spanString->AddSpan(AceType::MakeRefPtr<BaselineOffsetSpan>(Dimension(20.0_vp), 0, 4));
|
||||
spanString->AddSpan(AceType::MakeRefPtr<BaselineOffsetSpan>(Dimension(10.0_vp), 4, 6));
|
||||
|
||||
SpanToHtml convert;
|
||||
auto out = convert.ToHtml(*spanString);
|
||||
std::string result =
|
||||
"<div ><span style=\"font-size: 16.00fp;font-style: normal;font-weight: normal;color: #000000FF;font-family: "
|
||||
"HarmonyOS Sans;vertical-align: 20.00px;\">向上到顶</span><span style=\"font-size: 16.00fp;font-style: "
|
||||
"normal;font-weight: normal;color: #000000FF;font-family: HarmonyOS Sans;vertical-align: "
|
||||
"10.00px;\">适中</span><span style=\"font-size: 16.00fp;font-style: normal;font-weight: normal;color: "
|
||||
"#000000FF;font-family: HarmonyOS Sans;\">向下到底</span></div>";
|
||||
EXPECT_EQ(out, result);
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
Loading…
Reference in New Issue
Block a user