SkShaper: optionally disable harfbuzz
authorhalcanary <halcanary@google.com>
Wed, 3 Aug 2016 17:43:55 +0000 (10:43 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 3 Aug 2016 17:43:55 +0000 (10:43 -0700)
also, re-enable warnings.

motivation:  used by me for PDF testing.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2201153002

Review-Url: https://codereview.chromium.org/2201153002

gyp/tools.gyp
tools/SkShaper.h
tools/SkShaper_harfbuzz.cpp [moved from tools/SkShaper.cpp with 92% similarity]
tools/SkShaper_primitive.cpp [new file with mode: 0644]
tools/using_skia_and_harfbuzz.cpp

index b5ec804..b41ecc4 100644 (file)
     {
       'target_name': 'using_skia_and_harfbuzz',
       'type': 'executable',
-      'sources': [
-        '../tools/using_skia_and_harfbuzz.cpp',
-        '../tools/SkShaper.cpp',
+      'sources': [ '../tools/using_skia_and_harfbuzz.cpp', ],
+      'variables': { 'skia_example_use_harfbuzz%': 1, },
+      'conditions': [
+        [ 'skia_example_use_harfbuzz',
+          {
+            'dependencies': [ 'harfbuzz.gyp:harfbuzz', ],
+            'sources' : [ '../tools/SkShaper_harfbuzz.cpp', ],
+          }, {
+            'sources' : [ '../tools/SkShaper_primitive.cpp', ],
+          },
+        ]
       ],
       'dependencies': [
         'skia_lib.gyp:skia_lib',
         'pdf.gyp:pdf',
-        'harfbuzz.gyp:harfbuzz',
       ],
-      'cflags': [ '-w', ],
-      'msvs_settings': { 'VCCLCompilerTool': { 'WarningLevel': '0', }, },
-      'xcode_settings': { 'WARNING_CFLAGS': [ '-w', ], },
     },
     {
       'target_name': 'visualize_color_gamut',
index 5aa93a7..bc78be7 100644 (file)
@@ -17,8 +17,10 @@ class SkPaint;
 class SkTextBlobBuilder;
 
 /**
-   Shapes text using harfbuzz and places the shaped text into a
+   Shapes text using HarfBuzz and places the shaped text into a
    TextBlob.
+
+   If compiled without HarfBuzz, fall back on SkPaint::textToGlyphs.
  */
 class SkShaper {
 public:
similarity index 92%
rename from tools/SkShaper.cpp
rename to tools/SkShaper_harfbuzz.cpp
index 44dd8fc..29dd1b0 100644 (file)
@@ -23,7 +23,7 @@ std::unique_ptr<hb_blob_t, HBFBlobDel> stream_to_blob(std::unique_ptr<SkStreamAs
     size_t size = asset->getLength();
     std::unique_ptr<hb_blob_t, HBFBlobDel> blob;
     if (const void* base = asset->getMemoryBase()) {
-        blob.reset(hb_blob_create((char*)base, size,
+        blob.reset(hb_blob_create((char*)base, SkToUInt(size),
                                   HB_MEMORY_MODE_READONLY, asset.release(),
                                   [](void* p) { delete (SkStreamAsset*)p; }));
     } else {
@@ -31,7 +31,7 @@ std::unique_ptr<hb_blob_t, HBFBlobDel> stream_to_blob(std::unique_ptr<SkStreamAs
         SkAutoMalloc autoMalloc(size);
         asset->read(autoMalloc.get(), size);
         void* ptr = autoMalloc.get();
-        blob.reset(hb_blob_create((char*)autoMalloc.release(), size,
+        blob.reset(hb_blob_create((char*)autoMalloc.release(), SkToUInt(size),
                                   HB_MEMORY_MODE_READONLY, ptr, sk_free));
     }
     SkASSERT(blob);
@@ -116,8 +116,8 @@ SkScalar SkShaper::shape(SkTextBlobBuilder* builder,
     for (unsigned i = 0; i < len; i++) {
         runBuffer.glyphs[i] = info[i].codepoint;
         reinterpret_cast<SkPoint*>(runBuffer.pos)[i] =
-                SkPoint::Make(x + pos[i].x_offset * textSizeX,
-                              y - pos[i].y_offset * textSizeY);
+                SkPoint::Make(SkDoubleToScalar(x + pos[i].x_offset * textSizeX),
+                              SkDoubleToScalar(y - pos[i].y_offset * textSizeY));
         x += pos[i].x_advance * textSizeX;
         y += pos[i].y_advance * textSizeY;
     }
diff --git a/tools/SkShaper_primitive.cpp b/tools/SkShaper_primitive.cpp
new file mode 100644 (file)
index 0000000..65081b3
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkShaper.h"
+#include "SkStream.h"
+#include "SkTextBlob.h"
+#include "SkTypeface.h"
+
+struct SkShaper::Impl {
+    sk_sp<SkTypeface> fTypeface;
+};
+
+SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) {
+    fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault();
+}
+
+SkShaper::~SkShaper() {}
+
+bool SkShaper::good() const { return true; }
+
+SkScalar SkShaper::shape(SkTextBlobBuilder* builder,
+                         const SkPaint& srcPaint,
+                         const char* utf8text,
+                         size_t textBytes,
+                         SkPoint point) const {
+    SkPaint paint(srcPaint);
+    paint.setTypeface(fImpl->fTypeface);
+    paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
+    int glyphCount = paint.countText(utf8text, textBytes);
+    if (glyphCount <= 0) {
+        return 0;
+    }
+    SkRect bounds;
+    (void)paint.measureText(utf8text, textBytes, &bounds);
+    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    const SkTextBlobBuilder::RunBuffer& runBuffer = builder->allocRunPosH(
+            paint, glyphCount, point.y(), &bounds);
+    paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
+    (void)paint.textToGlyphs(utf8text, textBytes, runBuffer.glyphs);
+    (void)paint.getTextWidths(utf8text, textBytes, runBuffer.pos);
+    SkScalar x = point.x();
+    for (int i = 0; i < glyphCount; ++i) {
+        SkScalar w = runBuffer.pos[i];
+        runBuffer.pos[i] = x;
+        x += w;
+    }
+    return (SkScalar)x;
+}
index 7821034..f17a26d 100644 (file)
@@ -134,7 +134,7 @@ public:
         glyph_paint.setColor(SK_ColorBLACK);
         glyph_paint.setFlags(SkPaint::kAntiAlias_Flag |
                              SkPaint::kSubpixelText_Flag);
-        glyph_paint.setTextSize(config->font_size.value);
+        glyph_paint.setTextSize(SkDoubleToScalar(config->font_size.value));
     }
 
     void WriteLine(const SkShaper& shaper, const char *text, size_t textBytes) {
@@ -142,8 +142,9 @@ public:
             if (pageCanvas) {
                 document->endPage();
             }
-            pageCanvas = document->beginPage(config->page_width.value,
-                                             config->page_height.value);
+            pageCanvas = document->beginPage(
+                    SkDoubleToScalar(config->page_width.value),
+                    SkDoubleToScalar(config->page_height.value));
             pageCanvas->drawPaint(white_paint);
             current_x = config->left_margin.value;
             current_y = config->line_spacing_ratio.value * config->font_size.value;
@@ -151,8 +152,9 @@ public:
         SkTextBlobBuilder textBlobBuilder;
         shaper.shape(&textBlobBuilder, glyph_paint, text, textBytes, SkPoint{0, 0});
         sk_sp<const SkTextBlob> blob(textBlobBuilder.build());
-        pageCanvas->drawTextBlob(blob.get(), current_x, current_y, glyph_paint);
-
+        pageCanvas->drawTextBlob(
+                blob.get(), SkDoubleToScalar(current_x),
+                SkDoubleToScalar(current_y), glyph_paint);
         // Advance to the next line.
         current_y += config->line_spacing_ratio.value * config->font_size.value;
     }