Last active
June 7, 2023 12:59
-
-
Save HalCanary/334c388d53ca5119a57484b965ec111e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2019 Google LLC. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
#include "SkUTF.h" | |
#include "SkShaper.h" | |
#include "SkCanvas.h" | |
template <typename T, SkUnichar (*FN)(const T**, const T*)> | |
static SkString convert_to_utf8(const void* src, size_t srcBytes) { | |
SkString result; | |
const T* ptr = (const T*)src; | |
const T* stop = (const T*)((const char*)src + srcBytes); | |
size_t count = 0; | |
while (ptr < stop) { | |
count += SkUTF::ToUTF8(FN(&ptr, stop), nullptr); | |
} | |
result.resize(count); | |
ptr = (const T*)src; | |
char* dst = result.writable_str(); | |
while (ptr < stop) { | |
dst += SkUTF::ToUTF8(FN(&ptr, stop), dst); | |
} | |
return result; | |
} | |
static SkString to_string(const void* text, size_t byteLength, SkTextEncoding encoding) { | |
switch (encoding) { | |
case kUTF8_SkTextEncoding: | |
return SkString((const char*)text, byteLength); | |
case SkTextEncoding::kUTF16: | |
return convert_to_utf8<uint16_t, SkUTF::NextUTF16>(text, byteLength); | |
case SkTextEncoding::kUTF32: | |
return convert_to_utf8<int32_t, SkUTF::NextUTF32>(text, byteLength); | |
default: | |
return SkString(); | |
} | |
} | |
static std::pair<const char*, size_t> to_utf8(SkString* tmp, const void* text, | |
size_t byteLength, SkTextEncoding encoding) { | |
if (kUTF8_SkTextEncoding == encoding) { | |
return std::make_pair((const char*)text, byteLength); | |
} | |
*tmp = to_string(text, byteLength, encoding); | |
return std::make_pair(tmp->c_str(), tmp->size()); | |
} | |
static sk_sp<SkTextBlob> shape(const void* text, size_t byteLength, | |
SkTextEncoding encoding, const SkFont& font) { | |
if (!byteLength || !text) { return nullptr; } | |
if (SkTextEncoding::kGlyphID == encoding) { | |
return SkBlob::MakeFromText(text, byteLength, font, SkTextEncoding::kGlyphID); | |
} | |
SkString tmp; | |
auto str = to_utf8(&tmp, text, bytelength, encoding); | |
SkTextBlobBuilderRunHandler handler; | |
SkShaper shaper(font.refTypeface()); | |
shaper.shape(&handler, font, str.first, str.second, true, {0, 0}, FLT_MAX); | |
return handler.makeBlob(); | |
} | |
static void draw_shaped_text(SkCanvas* canvas, const void* text, | |
size_t byteLength, SkTextEncoding encoding, | |
SkScalar x, SkScalar y, const SkFont& font, | |
const SkPaint& paint) { | |
if (!byteLength || !text || !canvas) { return; } | |
sk_sp<SkTextBlob> blob = shape(text, byteLength, encoding, font); | |
canvas->drawTextBlob(blob.get(), x, y, paint); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment