Skip to content

Instantly share code, notes, and snippets.

@HalCanary
Last active June 7, 2023 12:59
Show Gist options
  • Save HalCanary/334c388d53ca5119a57484b965ec111e to your computer and use it in GitHub Desktop.
Save HalCanary/334c388d53ca5119a57484b965ec111e to your computer and use it in GitHub Desktop.
// 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