Index: tools/using_skia_and_harfbuzz.cpp |
diff --git a/tools/using_skia_and_harfbuzz.cpp b/tools/using_skia_and_harfbuzz.cpp |
index 1694e962e0e438a3a86617fd5295ac0b9c2e3baf..a3d66e16bc4d404fdc479774ed9d03dffc1fa392 100644 |
--- a/tools/using_skia_and_harfbuzz.cpp |
+++ b/tools/using_skia_and_harfbuzz.cpp |
@@ -19,6 +19,7 @@ |
#include "SkCanvas.h" |
#include "SkDocument.h" |
+#include "SkFontMgr.h" |
#include "SkStream.h" |
#include "SkTextBlob.h" |
#include "SkTypeface.h" |
@@ -86,7 +87,7 @@ struct Config { |
SkStringOption *subject = new SkStringOption("-k", "PDF subject", SkString("---")); |
SkStringOption *keywords = new SkStringOption("-c", "PDF keywords", SkString("---")); |
SkStringOption *creator = new SkStringOption("-t", "PDF creator", SkString("---")); |
- StdStringOption *font_file = new StdStringOption("-f", ".ttf font file", "fonts/DejaVuSans.ttf"); |
+ StdStringOption *font_file = new StdStringOption("-f", ".ttf font file", ""); |
DoubleOption *font_size = new DoubleOption("-z", "Font size", 8.0f); |
DoubleOption *left_margin = new DoubleOption("-m", "Left margin", 20.0f); |
DoubleOption *line_spacing_ratio = new DoubleOption("-h", "Line spacing ratio", 1.5f); |
@@ -170,14 +171,44 @@ struct Face { |
hb_face_set_upem(face, fSkiaTypeface->getUnitsPerEm()); |
fHarfBuzzFace.reset(face); |
} |
+ Face(sk_sp<SkTypeface> typeface) { |
+ fSkiaTypeface = std::move(typeface); |
+ int ttcIndex = 0; |
+ std::unique_ptr<SkStreamAsset> asset(fSkiaTypeface->openStream(&ttcIndex)); |
+ size_t length = asset->getLength(); |
+ void* data = sk_malloc_throw(length); |
+ asset->read(data, length); |
+ asset = nullptr; |
+ hb_blob_t* blob = hb_blob_create( |
+ static_cast<const char*>(data), SkToUInt(length), |
+ HB_MEMORY_MODE_WRITABLE, data, sk_free); |
+ assert(blob); |
+ hb_blob_make_immutable(blob); |
+ hb_face_t* face = hb_face_create(blob, (unsigned)ttcIndex); |
+ hb_blob_destroy(blob); |
+ assert(face); |
+ if (!face) { |
+ fSkiaTypeface.reset(); |
+ return; |
+ } |
+ hb_face_set_index(face, (unsigned)ttcIndex); |
+ hb_face_set_upem(face, fSkiaTypeface->getUnitsPerEm()); |
+ fHarfBuzzFace.reset(face); |
+ } |
}; |
class Placement { |
public: |
Placement(Config &_config, SkWStream* outputStream) : config(_config) { |
- face = new Face(config.font_file->value.c_str(), 0 /* index */); |
+ const char* font_file = config.font_file->value.c_str(); |
+ if (font_file && strlen(font_file)) { |
+ face = new Face(config.font_file->value.c_str(), 0 /* index */); |
+ } else { |
+ sk_sp<SkFontMgr> mgr(SkFontMgr::RefDefault()); |
+ sk_sp<SkTypeface> typeface(mgr->matchFamilyStyle(nullptr, SkFontStyle())); |
+ face = new Face(std::move(typeface)); |
+ } |
hb_font = hb_font_create(face->fHarfBuzzFace.get()); |
- |
hb_font_set_scale(hb_font, |
FONT_SIZE_SCALE * config.font_size->value, |
FONT_SIZE_SCALE * config.font_size->value); |
@@ -226,7 +257,7 @@ class Placement { |
/* Shape it! */ |
hb_shape (hb_font, hb_buffer, NULL, 0); |
- DrawGlyphs(hb_buffer); |
+ DrawGlyphs(text, hb_buffer); |
hb_buffer_destroy (hb_buffer); |
@@ -268,7 +299,7 @@ private: |
current_y = config.line_spacing_ratio->value * config.font_size->value; |
} |
- bool DrawGlyphs(hb_buffer_t *hb_buffer) { |
+ bool DrawGlyphs(const char *text, hb_buffer_t *hb_buffer) { |
SkTextBlobBuilder textBlobBuilder; |
unsigned len = hb_buffer_get_length (hb_buffer); |
if (len == 0) { |
@@ -276,13 +307,17 @@ private: |
} |
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (hb_buffer, NULL); |
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (hb_buffer, NULL); |
- auto runBuffer = textBlobBuilder.allocRunPos(glyph_paint, len); |
+ size_t text_len = strlen(text); |
+ auto runBuffer = textBlobBuilder.allocRunTextPos( |
+ glyph_paint, len, text_len, SkString()); |
+ memcpy(runBuffer.utf8text, text, text_len); |
double x = 0; |
double y = 0; |
for (unsigned int i = 0; i < len; i++) |
{ |
runBuffer.glyphs[i] = info[i].codepoint; |
+ runBuffer.clusters[i] = info[i].cluster; |
reinterpret_cast<SkPoint*>(runBuffer.pos)[i] = SkPoint::Make( |
x + pos[i].x_offset / FONT_SIZE_SCALE, |
y - pos[i].y_offset / FONT_SIZE_SCALE); |