Skip to content

Commit

Permalink
fix: handle unicode symbols in android
Browse files Browse the repository at this point in the history
  • Loading branch information
vcellu committed Jun 5, 2022
1 parent 617569b commit 01bf141
Showing 1 changed file with 48 additions and 10 deletions.
58 changes: 48 additions & 10 deletions cpp/jsi/Text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <include/core/SkFont.h>
#include <include/core/SkFontMetrics.h>
#include <include/utils/SkTextUtils.h>
#include <include/core/SkFontMgr.h>
/*
*
* Sample object
Expand All @@ -27,39 +28,76 @@
x:36.5
y:124.1081560283688
*/
bool isASCII (const std::string& s)
{
return !std::any_of(s.begin(), s.end(), [](char c) {
return static_cast<unsigned char>(c) > 127;
});
}

std::size_t GetFirst(const std::string &text) {
if (text.empty()) return 0;
std::size_t length = 1;
while ((text[length] & 0b11000000) == 0b10000000) {
++length;
}
return length;
}

Text::Text(jsi::Runtime &rt, const jsi::Object &object) {
text = object.getProperty(rt, "text").toString(rt).utf8(rt);
SkScalar fontSize = static_cast<SkScalar>(Helium::toPx(object.getProperty(rt, "fontSize").asNumber()));
auto fontFamily = object.getProperty(rt, "fontFamily").toString(rt).utf8(rt);
auto typeFace = SkTypeface::MakeFromName(fontFamily.c_str(), SkFontStyle::Normal());
auto typeFace = SkTypeface::MakeFromName(fontFamily.c_str(), SkFontStyle::Bold());

#ifdef SK_BUILD_FOR_ANDROID
if(!isASCII(text)) {
// get first two byte
std::size_t len = GetFirst(text);
if(len >= 2) {
auto sk = SkFontMgr::RefDefault();
const char *bcp47_locale = "";

char *b = text.data();
char b1 = b[0];
char b2 = b[1];
SkUnichar unichar = (b2 << 8) + b1;
auto tp = sk->matchFamilyStyleCharacter(fontFamily.c_str(), SkFontStyle::Normal(),
&bcp47_locale, 1, unichar);
typeFace.reset(tp);
}
}
#endif
auto baseline = object.getProperty(rt, "baseline").toString(rt).utf8(rt);
auto anchor = object.getProperty(rt, "anchor").toString(rt).utf8(rt);
position.fX = (Helium::toPx(object.getProperty(rt, "x").asNumber()));
position.fY = (Helium::toPx(object.getProperty(rt, "y").asNumber()));
font = SkFont(typeFace, fontSize);
font.getMetrics(&fontMetrics);




calcBaseline(baseline);
calcAnchor(anchor);

initFillPaint(rt, object);

if(object.hasProperty(rt, "transform")) {
TransformFactory txFactory;
transform = txFactory.parse(rt, object);
}
transform = SkMatrix::Translate(position.fX, position.fY);

splitText();
}

void Text::calcBaseline(const std::string& baseline) {
SkRect bounds;
font.measureText(text.c_str(), text.length(), SkTextEncoding::kUTF8, &bounds);
position.fX -= bounds.left();

float emHeight = fontMetrics.fDescent - fontMetrics.fAscent;

if(baseline == "central") {
position.fY = position.fY - fontMetrics.fAscent - (emHeight * 0.5f);
}
Expand All @@ -69,7 +107,7 @@ void Text::calcBaseline(const std::string& baseline) {
if(baseline == "bottom") {
position.fY = position.fY - (bounds.height() + bounds.top());
}

}

void Text::splitText() {
Expand All @@ -87,13 +125,13 @@ void Text::draw(SkCanvas *canvas) {
float emHeight = fontMetrics.fDescent - fontMetrics.fAscent;
SkScalar dy = 0;
SkRect bounds;

font.measureText(text.c_str(), text.length(), SkTextEncoding::kUTF8, &bounds);
for(auto&& line: lines) {
SkTextUtils::DrawString(canvas, line.c_str(), 0, dy, font, *brush, textAlign );
dy += emHeight + fontMetrics.fDescent;
};

canvas->restore();
}

Expand Down

0 comments on commit 01bf141

Please sign in to comment.