!10985 Add LineMetrics ArkTs interface

Merge pull request !10985 from changleipeng/0509yqf
This commit is contained in:
openharmony_ci 2024-05-25 07:07:12 +00:00 committed by Gitee
commit 3a0d332441
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
14 changed files with 485 additions and 14 deletions

View File

@ -109,6 +109,18 @@ static const std::vector<struct JsEnumInt> g_blurType = {
{ "INNER", static_cast<int32_t>(BlurType::INNER) },
};
static const std::vector<struct JsEnumInt> g_fontMetricsFlags = {
{ "UNDERLINE_THICKNESS_VALID", static_cast<int32_t>(
Drawing::FontMetrics::FontMetricsFlags::UNDERLINE_THICKNESS_IS_VALID_FLAG) },
{ "UNDERLINE_POSITION_VALID", static_cast<int32_t>(
Drawing::FontMetrics::FontMetricsFlags::UNDERLINE_POSITION_IS_VALID_FLAG) },
{ "STRIKETHROUGH_THICKNESS_VALID", static_cast<int32_t>(
Drawing::FontMetrics::FontMetricsFlags::STRIKEOUT_THICKNESS_IS_VALID_FLAG) },
{ "STRIKETHROUGH_POSITION_VALID", static_cast<int32_t>(
Drawing::FontMetrics::FontMetricsFlags::STRIKEOUT_POSITION_IS_VALID_FLAG) },
{ "BOUNDS_INVALID", static_cast<int32_t>(Drawing::FontMetrics::FontMetricsFlags::BOUNDS_INVALID_FLAG) },
};
static const std::map<std::string_view, const std::vector<struct JsEnumInt>&> g_intEnumClassMap = {
{ "BlendMode", g_blendMode },
{ "TextEncoding", g_textEncoding },
@ -117,6 +129,7 @@ static const std::map<std::string_view, const std::vector<struct JsEnumInt>&> g_
{ "JoinStyle", g_joinStyle },
{ "CapStyle", g_capStyle },
{ "BlurType", g_blurType },
{ "FontMetricsFlags", g_fontMetricsFlags },
};
napi_value JsEnum::JsEnumIntInit(napi_env env, napi_value exports)

View File

@ -114,5 +114,34 @@ bool ConvertFromJsRect(napi_env env, napi_value jsValue, double* ltrb, size_t si
}
return true;
}
napi_value GetFontMetricsAndConvertToJsValue(napi_env env, FontMetrics* metrics)
{
napi_value objValue = nullptr;
napi_create_object(env, &objValue);
if (metrics != nullptr && objValue != nullptr) {
napi_set_named_property(env, objValue, "top", CreateJsNumber(env, metrics->fTop));
napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, metrics->fAscent));
napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, metrics->fDescent));
napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, metrics->fBottom));
napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, metrics->fLeading));
napi_set_named_property(env, objValue, "flags", CreateJsNumber(env, metrics->fFlags));
napi_set_named_property(env, objValue, "avgCharWidth", CreateJsNumber(env, metrics->fAvgCharWidth));
napi_set_named_property(env, objValue, "maxCharWidth", CreateJsNumber(env, metrics->fMaxCharWidth));
napi_set_named_property(env, objValue, "xMin", CreateJsNumber(env, metrics->fXMin));
napi_set_named_property(env, objValue, "xMax", CreateJsNumber(env, metrics->fXMax));
napi_set_named_property(env, objValue, "xHeight", CreateJsNumber(env, metrics->fXHeight));
napi_set_named_property(env, objValue, "capHeight", CreateJsNumber(env, metrics->fCapHeight));
napi_set_named_property(env, objValue, "underlineThickness", CreateJsNumber(env,
metrics->fUnderlineThickness));
napi_set_named_property(env, objValue, "underlinePosition", CreateJsNumber(env,
metrics->fUnderlinePosition));
napi_set_named_property(env, objValue, "strikethroughThickness", CreateJsNumber(env,
metrics->fStrikeoutThickness));
napi_set_named_property(env, objValue, "strikethroughPosition", CreateJsNumber(env,
metrics->fStrikeoutPosition));
}
return objValue;
}
} // namespace Drawing
} // namespace OHOS::Rosen

View File

@ -319,19 +319,7 @@ inline napi_value GetStringAndConvertToJsValue(napi_env env, std::string str)
return objValue;
}
inline napi_value GetFontMetricsAndConvertToJsValue(napi_env env, FontMetrics* metrics)
{
napi_value objValue = nullptr;
napi_create_object(env, &objValue);
if (metrics != nullptr && objValue != nullptr) {
napi_set_named_property(env, objValue, "top", CreateJsNumber(env, metrics->fTop));
napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, metrics->fAscent));
napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, metrics->fDescent));
napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, metrics->fBottom));
napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, metrics->fLeading));
}
return objValue;
}
napi_value GetFontMetricsAndConvertToJsValue(napi_env env, FontMetrics* metrics);
inline napi_value GetRectAndConvertToJsValue(napi_env env, std::shared_ptr<Rect> rect)
{

View File

@ -379,6 +379,55 @@ size_t GetParamLen(napi_env env, napi_value param)
return buffSize;
}
bool GetFontMetricsFromJS(napi_env env, napi_value argValue, Drawing::FontMetrics& fontMetrics)
{
if (argValue == nullptr) {
return false;
}
napi_value tempValue = nullptr;
napi_get_named_property(env, argValue, "flags", &tempValue);
uint32_t flags = 0;
if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &flags) == napi_ok) {
fontMetrics.fFlags = Drawing::FontMetrics::FontMetricsFlags(flags);
}
SetFontMetricsFloatValueFromJS(env, argValue, "top", fontMetrics.fTop);
SetFontMetricsFloatValueFromJS(env, argValue, "ascent", fontMetrics.fAscent);
SetFontMetricsFloatValueFromJS(env, argValue, "descent", fontMetrics.fDescent);
SetFontMetricsFloatValueFromJS(env, argValue, "bottom", fontMetrics.fBottom);
SetFontMetricsFloatValueFromJS(env, argValue, "leading", fontMetrics.fLeading);
SetFontMetricsFloatValueFromJS(env, argValue, "avgCharWidth", fontMetrics.fAvgCharWidth);
SetFontMetricsFloatValueFromJS(env, argValue, "maxCharWidth", fontMetrics.fMaxCharWidth);
SetFontMetricsFloatValueFromJS(env, argValue, "xMin", fontMetrics.fXMin);
SetFontMetricsFloatValueFromJS(env, argValue, "xMax", fontMetrics.fXMax);
SetFontMetricsFloatValueFromJS(env, argValue, "xHeight", fontMetrics.fXHeight);
SetFontMetricsFloatValueFromJS(env, argValue, "capHeight", fontMetrics.fCapHeight);
SetFontMetricsFloatValueFromJS(env, argValue, "underlineThickness", fontMetrics.fUnderlineThickness);
SetFontMetricsFloatValueFromJS(env, argValue, "underlinePosition", fontMetrics.fUnderlinePosition);
SetFontMetricsFloatValueFromJS(env, argValue, "strikethroughThickness", fontMetrics.fStrikeoutThickness);
SetFontMetricsFloatValueFromJS(env, argValue, "strikethroughPosition", fontMetrics.fStrikeoutPosition);
return true;
}
bool GetRunMetricsFromJS(napi_env env, napi_value argValue, RunMetrics& runMetrics)
{
if (argValue == nullptr) {
return false;
}
napi_value tempValue = nullptr;
napi_get_named_property(env, argValue, "textStyle", &tempValue);
OHOS::Rosen::TextStyle tempTextStyle;
if (tempValue != nullptr && GetTextStyleFromJS(env, tempValue, tempTextStyle)) {
runMetrics.textStyle = &tempTextStyle;
}
napi_get_named_property(env, argValue, "fontMetrics", &tempValue);
Drawing::FontMetrics tempFontMetrics;
if (tempValue != nullptr && GetFontMetricsFromJS(env, tempValue, tempFontMetrics)) {
runMetrics.fontMetrics = tempFontMetrics;
}
return true;
}
void SetStrutStyleFromJS(napi_env env, napi_value argValue, TypographyStyle& pographyStyle)
{
if (!argValue) {
@ -431,4 +480,103 @@ void SetRectStyleFromJS(napi_env env, napi_value argValue, RectStyle& rectStyle)
SetDoubleValueFromJS(env, tempValue, "rightBottomRadius", rectStyle.rightBottomRadius);
SetDoubleValueFromJS(env, tempValue, "leftBottomRadius", rectStyle.leftBottomRadius);
}
napi_value CreateLineMetricsJsValue(napi_env env, OHOS::Rosen::LineMetrics& lineMetrics)
{
napi_value objValue = nullptr;
napi_create_object(env, &objValue);
if (objValue != nullptr) {
napi_set_named_property(env, objValue, "startIndex", CreateJsNumber(env, (uint32_t)lineMetrics.startIndex));
napi_set_named_property(env, objValue, "endIndex", CreateJsNumber(env, (uint32_t)lineMetrics.endIndex));
napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, lineMetrics.ascender));
napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, lineMetrics.descender));
napi_set_named_property(env, objValue, "height", CreateJsNumber(env, lineMetrics.height));
napi_set_named_property(env, objValue, "width", CreateJsNumber(env, lineMetrics.width));
napi_set_named_property(env, objValue, "left", CreateJsNumber(env, lineMetrics.x));
napi_set_named_property(env, objValue, "baseline", CreateJsNumber(env, lineMetrics.baseline));
napi_set_named_property(env, objValue, "lineNumber", CreateJsNumber(env, lineMetrics.lineNumber));
napi_set_named_property(env, objValue, "topHeight", CreateJsNumber(env, lineMetrics.y));
napi_set_named_property(env, objValue, "runMetrics", ConvertMapToNapiMap(env, lineMetrics.runMetrics));
}
return objValue;
}
napi_value CreateTextStyleJsValue(napi_env env, TextStyle textStyle)
{
napi_value objValue = nullptr;
napi_create_object(env, &objValue);
if (objValue != nullptr) {
napi_set_named_property(env, objValue, "decoration", CreateJsNumber(
env, static_cast<uint32_t>(textStyle.decoration)));
napi_set_named_property(env, objValue, "color", CreateJsNumber(env,
(uint32_t)textStyle.color.CastToColorQuad()));
napi_set_named_property(env, objValue, "fontWeight", CreateJsNumber(
env, static_cast<uint32_t>(textStyle.fontWeight)));
napi_set_named_property(env, objValue, "fontStyle", CreateJsNumber(
env, static_cast<uint32_t>(textStyle.fontStyle)));
napi_set_named_property(env, objValue, "baseline", CreateJsNumber(
env, static_cast<uint32_t>(textStyle.baseline)));
napi_set_named_property(env, objValue, "fontFamilies", CreateArrayStringJsValue(env, textStyle.fontFamilies));
napi_set_named_property(env, objValue, "fontSize", CreateJsNumber(env, textStyle.fontSize));
napi_set_named_property(env, objValue, "letterSpacing", CreateJsNumber(env, textStyle.letterSpacing));
napi_set_named_property(env, objValue, "wordSpacing", CreateJsNumber(env, textStyle.wordSpacing));
napi_set_named_property(env, objValue, "heightScale", CreateJsNumber(env, textStyle.heightScale));
napi_set_named_property(env, objValue, "halfLeading", CreateJsValue(env, textStyle.halfLeading));
napi_set_named_property(env, objValue, "heightOnly", CreateJsValue(env, textStyle.heightOnly));
napi_set_named_property(env, objValue, "ellipsis", CreateStringJsValue(env, textStyle.ellipsis));
napi_set_named_property(env, objValue, "ellipsisMode", CreateJsNumber(
env, static_cast<uint32_t>(textStyle.ellipsisModal)));
napi_set_named_property(env, objValue, "locale", CreateJsValue(env, textStyle.locale));
}
return objValue;
}
napi_value ConvertMapToNapiMap(napi_env env, const std::map<size_t, RunMetrics>& map)
{
napi_value result = nullptr;
napi_status status = napi_create_object(env, &result);
if (status != napi_ok) {
ROSEN_LOGE("ConvertMapToNapiMap create napi object failed");
return nullptr;
}
napi_value jsSize = nullptr;
napi_create_uint32(env, map.size(), &jsSize);
napi_set_named_property(env, result, "size", jsSize);
for (const auto &[key, val] : map) {
status = napi_set_property(env, result, CreateJsNumber(env, key), CreateRunMetricsJsValue(env, val));
if (status != napi_ok) {
return nullptr;
}
}
return result;
}
napi_value CreateFontMetricsJsValue(napi_env env, Drawing::FontMetrics& fontMetrics)
{
napi_value objValue = nullptr;
napi_create_object(env, &objValue);
if (objValue != nullptr) {
napi_set_named_property(env, objValue, "flags", CreateJsNumber(env, fontMetrics.fFlags));
napi_set_named_property(env, objValue, "top", CreateJsNumber(env, fontMetrics.fTop)); // float type
napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, fontMetrics.fAscent));
napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, fontMetrics.fDescent));
napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, fontMetrics.fBottom));
napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, fontMetrics.fLeading));
napi_set_named_property(env, objValue, "avgCharWidth", CreateJsNumber(env, fontMetrics.fAvgCharWidth));
napi_set_named_property(env, objValue, "maxCharWidth", CreateJsNumber(env, fontMetrics.fMaxCharWidth));
napi_set_named_property(env, objValue, "xMin", CreateJsNumber(env, fontMetrics.fXMin));
napi_set_named_property(env, objValue, "xMax", CreateJsNumber(env, fontMetrics.fXMax));
napi_set_named_property(env, objValue, "xHeight", CreateJsNumber(env, fontMetrics.fXHeight));
napi_set_named_property(env, objValue, "capHeight", CreateJsNumber(env, fontMetrics.fCapHeight));
napi_set_named_property(env, objValue, "underlineThickness", CreateJsNumber(env,
fontMetrics.fUnderlineThickness));
napi_set_named_property(env, objValue, "underlinePosition", CreateJsNumber(env,
fontMetrics.fUnderlinePosition));
napi_set_named_property(env, objValue, "strikethroughThickness", CreateJsNumber(env,
fontMetrics.fStrikeoutThickness));
napi_set_named_property(env, objValue, "strikethroughPosition", CreateJsNumber(env,
fontMetrics.fStrikeoutPosition));
}
return objValue;
}
} // namespace OHOS::Rosen

View File

@ -387,6 +387,82 @@ inline napi_value CreateTextRectJsValue(napi_env env, TextRect textrect)
return objValue;
}
inline napi_value CreateArrayStringJsValue(napi_env env, std::vector<std::string>& vectorString)
{
napi_value jsArray = nullptr;
if (napi_create_array_with_length(env, vectorString.size(), &jsArray) == napi_ok) {
size_t index = 0;
for (const auto& family : vectorString) {
napi_value jsString;
napi_create_string_utf8(env, family.c_str(), family.length(), &jsString);
napi_set_element(env, jsArray, index++, jsString);
}
}
return jsArray;
}
inline napi_value CreateStringJsValue(napi_env env, std::u16string& u16String)
{
napi_value jsStr = nullptr;
napi_create_string_utf16(env, reinterpret_cast<const char16_t*>(u16String.c_str()), u16String.length(), &jsStr);
return jsStr;
}
napi_value CreateTextStyleJsValue(napi_env env, TextStyle textStyle);
napi_value CreateFontMetricsJsValue(napi_env env, Drawing::FontMetrics& fontMetrics);
inline napi_value CreateRunMetricsJsValue(napi_env env, RunMetrics runMetrics)
{
napi_value objValue = nullptr;
napi_create_object(env, &objValue);
if (objValue != nullptr) {
napi_set_named_property(env, objValue, "textStyle", CreateTextStyleJsValue(env, *(runMetrics.textStyle)));
napi_set_named_property(env, objValue, "fontMetrics", CreateFontMetricsJsValue(env, runMetrics.fontMetrics));
}
return objValue;
}
napi_value ConvertMapToNapiMap(napi_env env, const std::map<size_t, RunMetrics>& map);
napi_value CreateLineMetricsJsValue(napi_env env, OHOS::Rosen::LineMetrics& lineMetrics);
inline void SetFontMetricsFloatValueFromJS(napi_env env, napi_value argValue, const std::string& str, float& cValue)
{
napi_value tempValue = nullptr;
napi_get_named_property(env, argValue, str.c_str(), &tempValue);
if (tempValue == nullptr) {
return;
}
double tempValuechild = 0.0;
ConvertFromJsValue(env, tempValue, tempValuechild);
cValue = static_cast<float>(tempValuechild);
}
inline void SetLineMetricsDoubleValueFromJS(napi_env env, napi_value argValue, const std::string str, double& cValue)
{
napi_value tempValue = nullptr;
napi_get_named_property(env, argValue, str.c_str(), &tempValue);
if (tempValue == nullptr) {
return;
}
ConvertFromJsValue(env, tempValue, cValue);
}
inline void SetLineMetricsSizeTValueFromJS(napi_env env, napi_value argValue, const std::string str, size_t& cValue)
{
napi_value tempValue = nullptr;
napi_get_named_property(env, argValue, str.c_str(), &tempValue);
if (tempValue == nullptr) {
return;
}
uint32_t tempValuechild = 0;
ConvertFromJsValue(env, tempValue, tempValuechild);
cValue = static_cast<size_t>(tempValuechild);
}
bool OnMakeFontFamilies(napi_env& env, napi_value jsValue, std::vector<std::string> &fontFamilies);
bool SetColorFromJS(napi_env env, napi_value argValue, const std::string& str, Drawing::Color& colorSrc);
@ -407,6 +483,10 @@ void ReceiveFontFeature(napi_env env, napi_value argValue, TextStyle& textStyle)
size_t GetParamLen(napi_env env, napi_value param);
bool GetFontMetricsFromJS(napi_env env, napi_value argValue, Drawing::FontMetrics& fontMetrics);
bool GetRunMetricsFromJS(napi_env env, napi_value argValue, RunMetrics& runMetrics);
bool GetNamePropertyFromJS(napi_env env, napi_value argValue, const std::string& str, napi_value& propertyValue);
template<class Type>

View File

@ -78,6 +78,8 @@ napi_value JsParagraph::Init(napi_env env, napi_value exportObj)
DECLARE_NAPI_FUNCTION("getLineWidth", JsParagraph::GetLineWidth),
DECLARE_NAPI_FUNCTION("didExceedMaxLines", JsParagraph::DidExceedMaxLines),
DECLARE_NAPI_FUNCTION("getTextLines", JsParagraph::GetTextLines),
DECLARE_NAPI_FUNCTION("getActualTextRange", JsParagraph::GetActualTextRange),
DECLARE_NAPI_FUNCTION("getLineMetrics", JsParagraph::GetLineMetrics),
};
napi_value constructor = nullptr;
napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
@ -501,6 +503,94 @@ napi_value JsParagraph::OnDidExceedMaxLines(napi_env env, napi_callback_info inf
return CreateJsValue(env, didExceedMaxLines);
}
napi_value JsParagraph::GetActualTextRange(napi_env env, napi_callback_info info)
{
JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
return (me != nullptr) ? me->OnGetActualTextRange(env, info) : nullptr;
}
napi_value JsParagraph::OnGetActualTextRange(napi_env env, napi_callback_info info)
{
if (paragraph_ == nullptr) {
ROSEN_LOGE("JsParagraph::OnGetActualTextRange paragraph_ is nullptr");
return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
}
size_t argc = ARGC_TWO;
napi_value argv[ARGC_TWO] = {nullptr};
napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
if (status != napi_ok || argc < ARGC_TWO) {
ROSEN_LOGE("JsParagraph::OnGetActualTextRange Argc is invalid: %{public}zu", argc);
return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
}
int lineNumber = 0;
if (!(ConvertFromJsValue(env, argv[0], lineNumber))) {
ROSEN_LOGE("JsParagraph::OnGetActualTextRange Argv is invalid");
return NapiGetUndefined(env);
}
bool includeSpaces = false;
if (!(ConvertFromJsValue(env, argv[1], includeSpaces))) {
ROSEN_LOGE("JsParagraph::OnGetActualTextRange Argv is invalid");
return NapiGetUndefined(env);
}
OHOS::Rosen::Boundary range = paragraph_->GetActualTextRange(lineNumber, includeSpaces);
return GetRangeAndConvertToJsValue(env, &range);
}
napi_value JsParagraph::GetLineMetrics(napi_env env, napi_callback_info info)
{
size_t argc = ARGC_ONE;
napi_value argv[ARGC_ONE] = {nullptr};
napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
if (status == napi_ok && argc < ARGC_ONE) {
return (me != nullptr) ? me->OnGetLineMetrics(env, info) : nullptr;
}
return (me != nullptr) ? me->OnGetLineMetricsAt(env, info) : nullptr;
}
napi_value JsParagraph::OnGetLineMetrics(napi_env env, napi_callback_info info)
{
if (paragraph_ == nullptr) {
ROSEN_LOGE("JsParagraph::OnGetLineMetrics paragraph_ is nullptr");
return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
}
std::vector<LineMetrics> vectorLineMetrics = paragraph_->GetLineMetrics();
napi_value returnLineMetrics = nullptr;
NAPI_CALL(env, napi_create_array(env, &returnLineMetrics));
int num = static_cast<int>(vectorLineMetrics.size());
for (int index = 0; index < num; ++index) {
napi_value tempValue = CreateLineMetricsJsValue(env, vectorLineMetrics[index]);
napi_set_element(env, returnLineMetrics, index, tempValue);
}
return returnLineMetrics;
}
napi_value JsParagraph::OnGetLineMetricsAt(napi_env env, napi_callback_info info)
{
if (paragraph_ == nullptr) {
ROSEN_LOGE("JsParagraph::OnGetLineMetricsAt paragraph_ is nullptr");
return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
}
size_t argc = ARGC_ONE;
napi_value argv[ARGC_ONE] = {nullptr};
napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
if (status != napi_ok || argc < ARGC_ONE) {
ROSEN_LOGE("JsParagraph::OnLayout Argc is invalid: %{public}zu", argc);
return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
}
int lineNumber = 0;
if (!(ConvertFromJsValue(env, argv[0], lineNumber))) {
ROSEN_LOGE("JsParagraph::OnGetLineMetricsAt Argv is invalid");
return NapiGetUndefined(env);
}
LineMetrics lineMetrics;
if (!paragraph_->GetLineMetricsAt(lineNumber, &lineMetrics)) {
return nullptr;
}
return CreateLineMetricsJsValue(env, lineMetrics);
}
JsParagraph::JsParagraph(std::shared_ptr<Typography> typography)
: paragraph_(typography)
{

View File

@ -47,6 +47,8 @@ public:
static napi_value GetLineWidth(napi_env env, napi_callback_info info);
static napi_value GetTextLines(napi_env env, napi_callback_info info);
static napi_value DidExceedMaxLines(napi_env env, napi_callback_info info);
static napi_value GetActualTextRange(napi_env env, napi_callback_info info);
static napi_value GetLineMetrics(napi_env env, napi_callback_info info);
static void Destructor(napi_env env, void *nativeObject, void *finalize);
static napi_value CreateJsTypography(napi_env env, std::unique_ptr<Typography> typography);
static napi_value Constructor(napi_env env, napi_callback_info info);
@ -72,6 +74,9 @@ private:
napi_value OnGetLineWidth(napi_env env, napi_callback_info info);
napi_value OnDidExceedMaxLines(napi_env env, napi_callback_info info);
napi_value OnGetTextLines(napi_env env, napi_callback_info info);
napi_value OnGetActualTextRange(napi_env env, napi_callback_info info);
napi_value OnGetLineMetrics(napi_env env, napi_callback_info info);
napi_value OnGetLineMetricsAt(napi_env env, napi_callback_info info);
std::shared_ptr<Typography> paragraph_ = nullptr;
};
} // namespace OHOS::Rosen

View File

@ -187,6 +187,84 @@ SPText::TextStyle Convert(const TextStyle& style)
return textStyle;
}
void CopyTextStyleSymbol(const SPText::TextStyle& style, TextStyle& textStyle)
{
textStyle.symbol.SetRenderColor(style.symbol.GetRenderColor());
textStyle.symbol.SetRenderMode(style.symbol.GetRenderMode());
textStyle.symbol.SetSymbolEffect(style.symbol.GetEffectStrategy());
textStyle.symbol.SetAnimationMode(style.symbol.GetAnimationMode());
textStyle.symbol.SetRepeatCount(style.symbol.GetRepeatCount());
textStyle.symbol.SetAnimationStart(style.symbol.GetAnimationStart());
textStyle.symbol.SetCommonSubType(style.symbol.GetCommonSubType());
}
void SplitTextStyleConvert(TextStyle& textStyle, const SPText::TextStyle& style)
{
if (style.isSymbolGlyph) {
CopyTextStyleSymbol(style, textStyle);
}
if (style.background.has_value()) {
textStyle.backgroundBrush = style.background->brush;
textStyle.backgroundPen = style.background->pen;
}
if (style.foreground.has_value()) {
textStyle.foregroundBrush = style.foreground->brush;
textStyle.foregroundPen = style.foreground->pen;
}
for (const auto& [color, offset, radius] : style.textShadows) {
Drawing::Color shadowColor;
shadowColor.SetColorQuad(color);
Drawing::Point shadowOffset(offset.x(), offset.y());
textStyle.shadows.emplace_back(shadowColor, shadowOffset, radius);
}
for (const auto& [tag, value] : style.fontFeatures.GetFontFeatures()) {
textStyle.fontFeatures.SetFeature(RemoveQuotes(tag), value);
}
if (!style.fontVariations.GetAxisValues().empty()) {
for (const auto& [axis, value] : style.fontVariations.GetAxisValues()) {
textStyle.fontVariations.SetAxisValue(axis, value);
}
}
}
TextStyle Convert(const SPText::TextStyle& style)
{
TextStyle textStyle;
textStyle.color.SetColorQuad(style.color);
textStyle.decoration = static_cast<TextDecoration>(style.decoration);
textStyle.decorationColor.SetColorQuad(style.decorationColor);
textStyle.decorationStyle = static_cast<TextDecorationStyle>(style.decorationStyle);
textStyle.decorationThicknessScale = style.decorationThicknessMultiplier;
textStyle.fontWeight = static_cast<FontWeight>(style.fontWeight);
textStyle.fontWidth = static_cast<FontWidth>(style.fontWidth);
textStyle.fontStyle = static_cast<FontStyle>(style.fontStyle);
textStyle.baseline = static_cast<TextBaseline>(style.baseline);
textStyle.halfLeading = style.halfLeading;
textStyle.fontFamilies = style.fontFamilies;
textStyle.fontSize = style.fontSize;
textStyle.letterSpacing = style.letterSpacing;
textStyle.wordSpacing = style.wordSpacing;
textStyle.heightScale = style.height;
textStyle.heightOnly = style.heightOverride;
textStyle.locale = style.locale;
textStyle.backgroundRect = { style.backgroundRect.color, style.backgroundRect.leftTopRadius,
style.backgroundRect.rightTopRadius, style.backgroundRect.rightBottomRadius,
style.backgroundRect.leftBottomRadius };
textStyle.styleId = style.styleId;
textStyle.isSymbolGlyph = style.isSymbolGlyph;
textStyle.baseLineShift = style.baseLineShift;
textStyle.isPlaceholder = style.isPlaceholder;
SplitTextStyleConvert(textStyle, style);
return textStyle;
}
} // namespace AdapterTxt
} // namespace Rosen
} // namespace OHOS

View File

@ -38,6 +38,7 @@ DEFINE_CONVERT_FUNC(std::shared_ptr<OHOS::Rosen::FontCollection>, FONT_COLLECTIO
DEFINE_CONVERT_FUNC(SPText::PositionWithAffinity, IndexAndAffinity);
DEFINE_CONVERT_FUNC(SPText::Range<size_t>, Boundary);
DEFINE_CONVERT_FUNC(SPText::TextBox, TextRect);
DEFINE_CONVERT_FUNC(SPText::TextStyle, TextStyle);
// from rosen_text to txt
DEFINE_CONVERT_FUNC(TextRectHeightStyle, SPText::RectHeightStyle);

View File

@ -16,6 +16,7 @@
#include "typography.h"
#include <mutex>
#include <numeric>
#include "skia_adapter/skia_canvas.h"
#include "skia_adapter/skia_convert_utils.h"
@ -305,6 +306,10 @@ std::vector<LineMetrics> Typography::GetLineMetrics()
std::vector<LineMetrics> lineMetrics;
if (paragraph_ != nullptr) {
auto metrics = paragraph_->GetLineMetrics();
lineMetricsStyles_.reserve(std::accumulate(metrics.begin(), metrics.end(), 0,
[](const int a, const SPText::LineMetrics& b) { return a + b.runMetrics.size(); }));
for (SPText::LineMetrics& spLineMetrics : metrics) {
LineMetrics& line = lineMetrics.emplace_back();
if (!spLineMetrics.runMetrics.empty()) {
@ -316,6 +321,8 @@ std::vector<LineMetrics> Typography::GetLineMetrics()
line.capHeight = 0.0;
line.xHeight = 0.0;
}
line.lineNumber = spLineMetrics.lineNumber;
line.baseline = spLineMetrics.baseline;
line.ascender = spLineMetrics.ascent;
line.descender = spLineMetrics.descent;
line.width = spLineMetrics.width;
@ -324,6 +331,11 @@ std::vector<LineMetrics> Typography::GetLineMetrics()
line.y = spLineMetrics.topHeight;
line.startIndex = spLineMetrics.startIndex;
line.endIndex = spLineMetrics.endIndex;
for (const auto& [index, styleMtrics] : spLineMetrics.runMetrics) {
lineMetricsStyles_.push_back(Convert(*styleMtrics.textStyle));
line.runMetrics.emplace(std::piecewise_construct, std::forward_as_tuple(index),
std::forward_as_tuple(&lineMetricsStyles_.back(), styleMtrics.fontMetrics));
}
}
}
return lineMetrics;
@ -361,7 +373,15 @@ bool Typography::GetLineMetricsAt(int lineNumber, LineMetrics* lineMetrics)
lineMetrics->y = skLineMetrics.fTopHeight;
lineMetrics->startIndex = skLineMetrics.fStartIndex;
lineMetrics->endIndex = skLineMetrics.fEndIndex;
lineMetrics->lineNumber = skLineMetrics.fLineNumber;
lineMetrics->baseline = skLineMetrics.fBaseline;
for (const auto& [index, styleMtrics] : skLineMetrics.fLineMetrics) {
SPText::TextStyle spTextStyle = paragraph_->SkStyleToTextStyle(*styleMtrics.text_style);
lineMetricsStyles_.emplace_back(Convert(spTextStyle));
lineMetrics->runMetrics.emplace(std::piecewise_construct, std::forward_as_tuple(index),
std::forward_as_tuple(&lineMetricsStyles_.back(), styleMtrics.font_metrics));
}
return true;
}

View File

@ -73,6 +73,7 @@ public:
std::unique_ptr<OHOS::Rosen::Typography> CloneSelf() override;
private:
std::unique_ptr<SPText::Paragraph> paragraph_ = nullptr;
std::vector<TextStyle> lineMetricsStyles_;
};
} // namespace AdapterTxt
} // namespace Rosen

View File

@ -63,6 +63,17 @@ struct IndexAndAffinity {
IndexAndAffinity(size_t charIndex, Affinity charAffinity);
};
class RunMetrics {
public:
explicit RunMetrics(const TextStyle* style) : textStyle(style) {}
RunMetrics(const TextStyle* style, const Drawing::FontMetrics& metrics)
: textStyle(style), fontMetrics(metrics) {}
const TextStyle* textStyle;
Drawing::FontMetrics fontMetrics;
};
struct LineMetrics {
/** Text ascender height */
double ascender;
@ -92,6 +103,12 @@ struct LineMetrics {
size_t endIndex;
Drawing::FontMetrics firstCharMetrics;
/** The y position of the baseline for this line from the top of the paragraph */
double baseline;
/** Zero indexed line number */
size_t lineNumber;
std::map<size_t, RunMetrics> runMetrics;
};
class Typography {

View File

@ -113,9 +113,9 @@ public:
std::vector<Drawing::FontMetrics>& fontMetrics) override;
std::vector<std::unique_ptr<SPText::TextLineBase>> GetTextLines() const override;
std::unique_ptr<Paragraph> CloneSelf() override;
TextStyle SkStyleToTextStyle(const skia::textlayout::TextStyle& skStyle) override;
private:
TextStyle SkStyleToTextStyle(const skia::textlayout::TextStyle& skStyle);
std::unique_ptr<skia::textlayout::Paragraph> paragraph_;
std::vector<PaintRecord> paints_;

View File

@ -191,6 +191,7 @@ public:
size_t& charNumber, std::vector<Drawing::FontMetrics>& fontMetrics) = 0;
virtual std::vector<std::unique_ptr<SPText::TextLineBase>> GetTextLines() const = 0;
virtual std::unique_ptr<Paragraph> CloneSelf() = 0;
virtual TextStyle SkStyleToTextStyle(const skia::textlayout::TextStyle& skStyle) = 0;
};
} // namespace SPText
} // namespace Rosen