Reland "[skottie] AllCaps support"
This reverts commit6142500513
. Reason for revert: relanding with fixes Original change's description: > Revert "[skottie] AllCaps support" > > This reverts commitefc7ca4a71
. > > Reason for revert: broke Chromium, NoDEPS builds > > Original change's description: > > [skottie] AllCaps support > > > > AfterEffects and Bodymovin support an "AllCaps" text flag which forces > > text capitalization. > > > > * add toUpper() bindings to SkUnicode/SkICU > > * add capitalization options to SkottieShaper > > * plumb existing Lottie 'ca' (AllCaps) prop > > * also fix a couple of unrelated whoopsies > > > > Change-Id: I8e80921b66530e9830938004946082c6e450b04b > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/445104 > > Reviewed-by: Ben Wagner <bungeman@google.com> > > Commit-Queue: Florin Malita <fmalita@google.com> > > TBR=bungeman@google.com,fmalita@chromium.org,fmalita@google.com,jlavrova@google.com,skcq-be@skia-corp.google.com.iam.gserviceaccount.com > > Change-Id: I3bb43f37f07cfc021e397df578499a4c4da15ca3 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/444980 > Reviewed-by: Florin Malita <fmalita@google.com> > Commit-Queue: Florin Malita <fmalita@google.com> Change-Id: Id729e09d4cade0cead193ffc5e6bd4fea1cdcff6 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/445598 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Florin Malita <fmalita@google.com>
This commit is contained in:
parent
6142500513
commit
5572b2a3ed
@ -281,6 +281,7 @@ def compile_fn(api, checkout_root, out_dir):
|
||||
'skia_use_expat': 'false',
|
||||
'skia_use_freetype': 'false',
|
||||
'skia_use_harfbuzz': 'false',
|
||||
'skia_use_icu': 'false',
|
||||
'skia_use_libjpeg_turbo_decode': 'false',
|
||||
'skia_use_libjpeg_turbo_encode': 'false',
|
||||
'skia_use_libpng_decode': 'false',
|
||||
|
@ -52,7 +52,7 @@
|
||||
"[START_DIR]/cache/work/skia/bin/gn",
|
||||
"gen",
|
||||
"[START_DIR]/cache/work/skia/out/Build-Debian10-Clang-x86_64-Release-NoDEPS/Release",
|
||||
"--args=cc=\"[START_DIR]/clang_linux/bin/clang\" cc_wrapper=\"[START_DIR]/ccache_linux/bin/ccache\" cxx=\"[START_DIR]/clang_linux/bin/clang++\" extra_cflags=[\"-B[START_DIR]/clang_linux/bin\", \"-DPLACEHOLDER_clang_linux_version=42\"] extra_ldflags=[\"-B[START_DIR]/clang_linux/bin\", \"-fuse-ld=lld\", \"-L[START_DIR]/clang_linux/lib\"] is_debug=false is_official_build=true skia_enable_fontmgr_empty=true skia_enable_gpu=true skia_enable_pdf=false skia_use_expat=false skia_use_freetype=false skia_use_harfbuzz=false skia_use_libjpeg_turbo_decode=false skia_use_libjpeg_turbo_encode=false skia_use_libpng_decode=false skia_use_libpng_encode=false skia_use_libwebp_decode=false skia_use_libwebp_encode=false skia_use_vulkan=false skia_use_zlib=false target_cpu=\"x86_64\" werror=true"
|
||||
"--args=cc=\"[START_DIR]/clang_linux/bin/clang\" cc_wrapper=\"[START_DIR]/ccache_linux/bin/ccache\" cxx=\"[START_DIR]/clang_linux/bin/clang++\" extra_cflags=[\"-B[START_DIR]/clang_linux/bin\", \"-DPLACEHOLDER_clang_linux_version=42\"] extra_ldflags=[\"-B[START_DIR]/clang_linux/bin\", \"-fuse-ld=lld\", \"-L[START_DIR]/clang_linux/lib\"] is_debug=false is_official_build=true skia_enable_fontmgr_empty=true skia_enable_gpu=true skia_enable_pdf=false skia_use_expat=false skia_use_freetype=false skia_use_harfbuzz=false skia_use_icu=false skia_use_libjpeg_turbo_decode=false skia_use_libjpeg_turbo_encode=false skia_use_libpng_decode=false skia_use_libpng_encode=false skia_use_libwebp_decode=false skia_use_libwebp_encode=false skia_use_vulkan=false skia_use_zlib=false target_cpu=\"x86_64\" werror=true"
|
||||
],
|
||||
"cwd": "[START_DIR]/cache/work/skia",
|
||||
"env": {
|
||||
|
@ -139,7 +139,7 @@
|
||||
"[START_DIR]\\skia\\bin\\gn",
|
||||
"gen",
|
||||
"[START_DIR]\\skia\\out\\Build-Win10-Clang-x86_64-Release-NoDEPS\\Release_x64",
|
||||
"--args=cc=\"clang\" clang_win=\"[START_DIR]\\clang_win\" cxx=\"clang++\" extra_cflags=[\"-DPLACEHOLDER_clang_win_version=42\"] is_debug=false is_official_build=true skia_enable_fontmgr_empty=true skia_enable_gpu=true skia_enable_pdf=false skia_use_expat=false skia_use_freetype=false skia_use_harfbuzz=false skia_use_libjpeg_turbo_decode=false skia_use_libjpeg_turbo_encode=false skia_use_libpng_decode=false skia_use_libpng_encode=false skia_use_libwebp_decode=false skia_use_libwebp_encode=false skia_use_vulkan=false skia_use_zlib=false target_cpu=\"x86_64\" werror=true win_sdk=\"[START_DIR]\\win_toolchain/win_sdk\" win_vc=\"[START_DIR]\\win_toolchain/VC\""
|
||||
"--args=cc=\"clang\" clang_win=\"[START_DIR]\\clang_win\" cxx=\"clang++\" extra_cflags=[\"-DPLACEHOLDER_clang_win_version=42\"] is_debug=false is_official_build=true skia_enable_fontmgr_empty=true skia_enable_gpu=true skia_enable_pdf=false skia_use_expat=false skia_use_freetype=false skia_use_harfbuzz=false skia_use_icu=false skia_use_libjpeg_turbo_decode=false skia_use_libjpeg_turbo_encode=false skia_use_libpng_decode=false skia_use_libpng_encode=false skia_use_libwebp_decode=false skia_use_libwebp_encode=false skia_use_vulkan=false skia_use_zlib=false target_cpu=\"x86_64\" werror=true win_sdk=\"[START_DIR]\\win_toolchain/win_sdk\" win_vc=\"[START_DIR]\\win_toolchain/VC\""
|
||||
],
|
||||
"cwd": "[START_DIR]\\skia",
|
||||
"env": {
|
||||
|
@ -23,6 +23,7 @@ if (skia_enable_skottie) {
|
||||
"../skresources",
|
||||
"../sksg",
|
||||
"../skshaper",
|
||||
"../skunicode",
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -39,24 +39,25 @@ enum class TextPaintOrder : uint8_t {
|
||||
struct TextPropertyValue {
|
||||
sk_sp<SkTypeface> fTypeface;
|
||||
SkString fText;
|
||||
float fTextSize = 0,
|
||||
fMinTextSize = 0, // when auto-sizing
|
||||
fMaxTextSize = std::numeric_limits<float>::max(), // when auto-sizing
|
||||
fStrokeWidth = 0,
|
||||
fLineHeight = 0,
|
||||
fLineShift = 0,
|
||||
fAscent = 0;
|
||||
SkTextUtils::Align fHAlign = SkTextUtils::kLeft_Align;
|
||||
Shaper::VAlign fVAlign = Shaper::VAlign::kTop;
|
||||
Shaper::ResizePolicy fResize = Shaper::ResizePolicy::kNone;
|
||||
Shaper::LinebreakPolicy fLineBreak = Shaper::LinebreakPolicy::kExplicit;
|
||||
Shaper::Direction fDirection = Shaper::Direction::kLTR;
|
||||
SkRect fBox = SkRect::MakeEmpty();
|
||||
SkColor fFillColor = SK_ColorTRANSPARENT,
|
||||
fStrokeColor = SK_ColorTRANSPARENT;
|
||||
TextPaintOrder fPaintOrder = TextPaintOrder::kFillStroke;
|
||||
bool fHasFill = false,
|
||||
fHasStroke = false;
|
||||
float fTextSize = 0,
|
||||
fMinTextSize = 0, // when auto-sizing
|
||||
fMaxTextSize = std::numeric_limits<float>::max(), // when auto-sizing
|
||||
fStrokeWidth = 0,
|
||||
fLineHeight = 0,
|
||||
fLineShift = 0,
|
||||
fAscent = 0;
|
||||
SkTextUtils::Align fHAlign = SkTextUtils::kLeft_Align;
|
||||
Shaper::VAlign fVAlign = Shaper::VAlign::kTop;
|
||||
Shaper::ResizePolicy fResize = Shaper::ResizePolicy::kNone;
|
||||
Shaper::LinebreakPolicy fLineBreak = Shaper::LinebreakPolicy::kExplicit;
|
||||
Shaper::Direction fDirection = Shaper::Direction::kLTR;
|
||||
Shaper::Capitalization fCapitalization = Shaper::Capitalization::kNone;
|
||||
SkRect fBox = SkRect::MakeEmpty();
|
||||
SkColor fFillColor = SK_ColorTRANSPARENT,
|
||||
fStrokeColor = SK_ColorTRANSPARENT;
|
||||
TextPaintOrder fPaintOrder = TextPaintOrder::kFillStroke;
|
||||
bool fHasFill = false,
|
||||
fHasStroke = false;
|
||||
|
||||
bool operator==(const TextPropertyValue& other) const;
|
||||
bool operator!=(const TextPropertyValue& other) const;
|
||||
|
@ -27,6 +27,7 @@ bool TextPropertyValue::operator==(const TextPropertyValue& other) const {
|
||||
&& fResize == other.fResize
|
||||
&& fLineBreak == other.fLineBreak
|
||||
&& fDirection == other.fDirection
|
||||
&& fCapitalization == other.fCapitalization
|
||||
&& fBox == other.fBox
|
||||
&& fFillColor == other.fFillColor
|
||||
&& fStrokeColor == other.fStrokeColor
|
||||
|
@ -326,6 +326,7 @@ DEF_TEST(Skottie_Properties, reporter) {
|
||||
Shaper::ResizePolicy::kNone,
|
||||
Shaper::LinebreakPolicy::kExplicit,
|
||||
Shaper::Direction::kLTR,
|
||||
Shaper::Capitalization::kNone,
|
||||
SkRect::MakeEmpty(),
|
||||
SK_ColorTRANSPARENT,
|
||||
SK_ColorTRANSPARENT,
|
||||
@ -478,6 +479,7 @@ DEF_TEST(Skottie_Shaper_HAlign, reporter) {
|
||||
Shaper::ResizePolicy::kNone,
|
||||
Shaper::LinebreakPolicy::kExplicit,
|
||||
Shaper::Direction::kLTR,
|
||||
Shaper::Capitalization::kNone,
|
||||
Shaper::Flags::kNone
|
||||
};
|
||||
|
||||
@ -548,6 +550,7 @@ DEF_TEST(Skottie_Shaper_VAlign, reporter) {
|
||||
Shaper::ResizePolicy::kNone,
|
||||
Shaper::LinebreakPolicy::kParagraph,
|
||||
Shaper::Direction::kLTR,
|
||||
Shaper::Capitalization::kNone,
|
||||
Shaper::Flags::kNone
|
||||
};
|
||||
|
||||
@ -588,6 +591,7 @@ DEF_TEST(Skottie_Shaper_FragmentGlyphs, reporter) {
|
||||
Shaper::ResizePolicy::kNone,
|
||||
Shaper::LinebreakPolicy::kParagraph,
|
||||
Shaper::Direction::kLTR,
|
||||
Shaper::Capitalization::kNone,
|
||||
Shaper::Flags::kNone
|
||||
};
|
||||
|
||||
@ -680,6 +684,7 @@ DEF_TEST(Skottie_Shaper_ExplicitFontMgr, reporter) {
|
||||
Shaper::ResizePolicy::kNone,
|
||||
Shaper::LinebreakPolicy::kParagraph,
|
||||
Shaper::Direction::kLTR,
|
||||
Shaper::Capitalization::kNone,
|
||||
Shaper::Flags::kNone
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "include/private/SkTPin.h"
|
||||
#include "include/private/SkTemplates.h"
|
||||
#include "modules/skshaper/include/SkShaper.h"
|
||||
#include "modules/skunicode/include/SkUnicode.h"
|
||||
#include "src/core/SkTLazy.h"
|
||||
#include "src/core/SkTextBlobPriv.h"
|
||||
#include "src/utils/SkUTF.h"
|
||||
@ -446,18 +447,47 @@ Shaper::Result ShapeToFit(const SkString& txt, const Shaper::TextDesc& orig_desc
|
||||
return best_result;
|
||||
}
|
||||
|
||||
|
||||
// Applies capitalization rules.
|
||||
class AdjustedText {
|
||||
public:
|
||||
AdjustedText(const SkString& txt, const Shaper::TextDesc& desc)
|
||||
: fText(txt) {
|
||||
switch (desc.fCapitalization) {
|
||||
case Shaper::Capitalization::kNone:
|
||||
break;
|
||||
case Shaper::Capitalization::kUpperCase:
|
||||
#ifdef SK_UNICODE_AVAILABLE
|
||||
if (auto skuni = SkUnicode::Make()) {
|
||||
*fText.writable() = skuni->toUpper(*fText);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
operator const SkString&() const { return *fText; }
|
||||
|
||||
private:
|
||||
SkTCopyOnFirstWrite<SkString> fText;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
Shaper::Result Shaper::Shape(const SkString& txt, const TextDesc& desc, const SkPoint& point,
|
||||
Shaper::Result Shaper::Shape(const SkString& orig_txt, const TextDesc& desc, const SkPoint& point,
|
||||
const sk_sp<SkFontMgr>& fontmgr) {
|
||||
const AdjustedText txt(orig_txt, desc);
|
||||
|
||||
return (desc.fResize == ResizePolicy::kScaleToFit ||
|
||||
desc.fResize == ResizePolicy::kDownscaleToFit) // makes no sense in point mode
|
||||
? Result()
|
||||
: ShapeImpl(txt, desc, SkRect::MakeEmpty().makeOffset(point.x(), point.y()), fontmgr);
|
||||
}
|
||||
|
||||
Shaper::Result Shaper::Shape(const SkString& txt, const TextDesc& desc, const SkRect& box,
|
||||
Shaper::Result Shaper::Shape(const SkString& orig_txt, const TextDesc& desc, const SkRect& box,
|
||||
const sk_sp<SkFontMgr>& fontmgr) {
|
||||
const AdjustedText txt(orig_txt, desc);
|
||||
|
||||
switch(desc.fResize) {
|
||||
case ResizePolicy::kNone:
|
||||
return ShapeImpl(txt, desc, box, fontmgr);
|
||||
|
@ -86,6 +86,11 @@ public:
|
||||
// Initial text direction.
|
||||
enum class Direction : uint8_t { kLTR, kRTL };
|
||||
|
||||
enum class Capitalization {
|
||||
kNone,
|
||||
kUpperCase,
|
||||
};
|
||||
|
||||
enum Flags : uint32_t {
|
||||
kNone = 0x00,
|
||||
|
||||
@ -110,6 +115,7 @@ public:
|
||||
ResizePolicy fResize;
|
||||
LinebreakPolicy fLinebreak;
|
||||
Direction fDirection;
|
||||
Capitalization fCapitalization;
|
||||
uint32_t fFlags;
|
||||
};
|
||||
|
||||
|
@ -279,6 +279,7 @@ void TextAdapter::reshape() {
|
||||
fText->fResize,
|
||||
fText->fLineBreak,
|
||||
fText->fDirection,
|
||||
fText->fCapitalization,
|
||||
this->shaperFlags(),
|
||||
};
|
||||
const auto shape_result = Shaper::Shape(fText->fText, text_desc, fText->fBox, fFontMgr);
|
||||
|
@ -46,7 +46,7 @@ bool Parse(const skjson::Value& jv, const internal::AnimationBuilder& abuilder,
|
||||
SkTextUtils::kCenter_Align // 'j': 2
|
||||
};
|
||||
v->fHAlign = gAlignMap[std::min<size_t>(ParseDefault<size_t>((*jtxt)["j"], 0),
|
||||
SK_ARRAY_COUNT(gAlignMap))];
|
||||
SK_ARRAY_COUNT(gAlignMap) - 1)];
|
||||
|
||||
// Optional text box size.
|
||||
if (const skjson::ArrayValue* jsz = (*jtxt)["sz"]) {
|
||||
@ -72,7 +72,7 @@ bool Parse(const skjson::Value& jv, const internal::AnimationBuilder& abuilder,
|
||||
// TODO: remove "sk_rs" support after migrating clients.
|
||||
v->fResize = gResizeMap[std::min(std::max(ParseDefault<size_t>((*jtxt)[ "rs"], 0),
|
||||
ParseDefault<size_t>((*jtxt)["sk_rs"], 0)),
|
||||
SK_ARRAY_COUNT(gResizeMap))];
|
||||
SK_ARRAY_COUNT(gResizeMap) - 1)];
|
||||
|
||||
// Optional min/max font size (used when aute-resizing)
|
||||
v->fMinTextSize = ParseDefault<SkScalar>((*jtxt)["mf"], 0.0f);
|
||||
@ -93,6 +93,14 @@ bool Parse(const skjson::Value& jv, const internal::AnimationBuilder& abuilder,
|
||||
: Shaper::LinebreakPolicy::kParagraph; // 'm': 1 -> paragraph text
|
||||
}
|
||||
|
||||
// Optional capitalization.
|
||||
static constexpr Shaper::Capitalization gCapMap[] = {
|
||||
Shaper::Capitalization::kNone, // 'ca': 0
|
||||
Shaper::Capitalization::kUpperCase, // 'ca': 1
|
||||
};
|
||||
v->fCapitalization = gCapMap[std::min<size_t>(ParseDefault<size_t>((*jtxt)["ca"], 0),
|
||||
SK_ARRAY_COUNT(gCapMap) - 1)];
|
||||
|
||||
// In point mode, the text is baseline-aligned.
|
||||
v->fVAlign = v->fBox.isEmpty() ? Shaper::VAlign::kTopBaseline
|
||||
: Shaper::VAlign::kTop;
|
||||
|
@ -116,6 +116,7 @@ class SKUNICODE_API SkUnicode {
|
||||
virtual bool isWhitespace(SkUnichar utf8) = 0;
|
||||
virtual bool isSpace(SkUnichar utf8) = 0;
|
||||
virtual SkString convertUtf16ToUtf8(const std::u16string& utf16) = 0;
|
||||
virtual SkString toUpper(const SkString&) = 0;
|
||||
|
||||
// Methods used in SkShaper and SkText
|
||||
virtual std::unique_ptr<SkBidiIterator> makeBidiIterator
|
||||
|
@ -498,6 +498,37 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
SkString toUpper(const SkString& str) override {
|
||||
// Convert to UTF16 since that's what ICU wants.
|
||||
std::unique_ptr<uint16_t[]> str16;
|
||||
const auto str16len = utf8ToUtf16(str.c_str(), str.size(), &str16);
|
||||
if (str16len <= 0) {
|
||||
return SkString();
|
||||
}
|
||||
|
||||
UErrorCode icu_err = U_ZERO_ERROR;
|
||||
const auto upper16len = sk_u_strToUpper(nullptr, 0, (UChar*)(str16.get()), str16len,
|
||||
nullptr, &icu_err);
|
||||
if (icu_err != U_BUFFER_OVERFLOW_ERROR || upper16len <= 0) {
|
||||
return SkString();
|
||||
}
|
||||
|
||||
SkAutoSTArray<128, uint16_t> upper16(upper16len);
|
||||
icu_err = U_ZERO_ERROR;
|
||||
sk_u_strToUpper((UChar*)(upper16.get()), SkToS32(upper16.size()),
|
||||
(UChar*)(str16.get()), str16len,
|
||||
nullptr, &icu_err);
|
||||
SkASSERT(!U_FAILURE(icu_err));
|
||||
|
||||
// ... and back to utf8 'cause that's what we want.
|
||||
std::unique_ptr<char[]> upper8;
|
||||
auto upper8len = utf16ToUtf8(upper16.data(), upper16.size(), &upper8);
|
||||
|
||||
return upper8len >= 0
|
||||
? SkString(upper8.get(), upper8len)
|
||||
: SkString();
|
||||
}
|
||||
|
||||
bool getBidiRegions(const char utf8[],
|
||||
int utf8Units,
|
||||
TextDirection dir,
|
||||
|
@ -22,6 +22,7 @@
|
||||
SKICU_FUNC(u_iscntrl) \
|
||||
SKICU_FUNC(u_isspace) \
|
||||
SKICU_FUNC(u_isWhitespace) \
|
||||
SKICU_FUNC(u_strToUpper) \
|
||||
SKICU_FUNC(ubidi_close) \
|
||||
SKICU_FUNC(ubidi_getLength) \
|
||||
SKICU_FUNC(ubidi_getLevelAt) \
|
||||
|
1
resources/skottie/skottie-text-allcaps.json
Normal file
1
resources/skottie/skottie-text-allcaps.json
Normal file
@ -0,0 +1 @@
|
||||
{"assets":[],"ddd":0,"fonts":{"list":[{"ascent":71.5988159179688,"fClass":"","fFamily":"Arial","fName":"ArialMT","fPath":"","fStyle":"Regular","fWeight":"","origin":0}]},"fr":60,"h":500,"ip":0,"layers":[{"ao":0,"bm":0,"ddd":0,"ind":1,"ip":0,"ks":{"a":{"a":0,"ix":1,"k":[0,0,0],"l":2},"o":{"a":0,"ix":11,"k":100},"p":{"a":0,"ix":2,"k":[245,226.5,0],"l":2},"r":{"a":0,"ix":10,"k":0},"s":{"a":0,"ix":6,"k":[100,100,100],"l":2}},"nm":"Foo Bar - allcaps","op":600,"sr":1,"st":0,"t":{"a":[],"d":{"k":[{"s":{"ca":0,"f":"ArialMT","fc":[0.706,0,1],"j":2,"lh":75.6,"ls":0,"mc":100,"mf":10,"ps":[-164,-141.5],"rs":1,"s":63,"sz":[354,335],"t":"Hello there, κεφαλαίο κείμενο!","tr":0,"vj":1,"xf":100},"t":0},{"s":{"ca":1,"f":"ArialMT","fc":[0.706,0,1],"j":2,"lh":75.6,"ls":0,"mc":100,"mf":10,"ps":[-164,-141.5],"rs":1,"s":63,"sz":[354,335],"t":"Hello there, κεφαλαίο κείμενο!","tr":0,"vj":1,"xf":100},"t":150},{"s":{"ca":0,"f":"ArialMT","fc":[0.706,0,1],"j":2,"lh":75.6,"ls":0,"mc":100,"mf":10,"ps":[-164,-141.5],"rs":1,"s":63,"sz":[354,335],"t":"Hello there, κεφαλαίο κείμενο!","tr":0,"vj":1,"xf":100},"t":300},{"s":{"ca":1,"f":"ArialMT","fc":[0.706,0,1],"j":2,"lh":75.6,"ls":0,"mc":100,"mf":10,"ps":[-164,-141.5],"rs":1,"s":63,"sz":[354,335],"t":"Hello there, κεφαλαίο κείμενο!","tr":0,"vj":1,"xf":100},"t":450}]},"m":{"a":{"a":0,"ix":2,"k":[0,0]},"g":1},"p":{}},"ty":5}],"markers":[],"nm":"allcaps","op":600,"v":"5.7.11","w":500}
|
Loading…
Reference in New Issue
Block a user