[canvaskit] Remove ShapedText API.

The Paragraph API is what should be used.

Bug: skia:10717
Change-Id: I135aff09bffae0718045b5c744f8e774e2ee1bce
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/371338
Reviewed-by: Ben Wagner <bungeman@google.com>
Reviewed-by: Nathaniel Nifong <nifong@google.com>
diff --git a/modules/canvaskit/CHANGELOG.md b/modules/canvaskit/CHANGELOG.md
index a680f2b..8eecd8f 100644
--- a/modules/canvaskit/CHANGELOG.md
+++ b/modules/canvaskit/CHANGELOG.md
@@ -6,6 +6,10 @@
 
 ## [Unreleased]
 
+### Breaking
+ - The `ShapedText` type has been removed. Clients who want ShapedText should use the
+   Paragraph APIs.
+
 ## [0.24.0] - 2021-02-18
 
 ### Added
diff --git a/modules/canvaskit/canvaskit/example.html b/modules/canvaskit/canvaskit/example.html
index 436f2e1..d6ead9f 100644
--- a/modules/canvaskit/canvaskit/example.html
+++ b/modules/canvaskit/canvaskit/example.html
@@ -42,9 +42,7 @@
 <canvas id=atlas width=300 height=300></canvas>
 <canvas id=decode width=300 height=300></canvas>
 
-<h2> CanvasKit can allow for text shaping (e.g. breaking, kerning)</h2>
-<canvas id=shape1 width=600 height=600></canvas>
-<canvas id=shape2 width=600 height=600></canvas>
+<h2> CanvasKit can allow for text measurement/placement (e.g. breaking, kerning)</h2>
 <canvas id=textonpath width=300 height=300></canvas>
 
 <script type="text/javascript" src="/node_modules/canvaskit/bin/canvaskit.js"></script>
@@ -82,10 +80,6 @@
 
   // Examples requiring external resources
   Promise.all([ckLoaded, loadRoboto]).then((results) => {DrawingExample(...results)});
-  Promise.all([ckLoaded, loadNotoSerif]).then((results) => {
-    TextShapingAPI1(...results);
-    TextShapingAPI2(...results);
-  });
   Promise.all([ckLoaded, loadTestImage]).then((results) => {AtlasAPI1(...results)});
   Promise.all([ckLoaded, loadTestImage]).then((results) => {DecodeAPI(...results)});
 
@@ -928,132 +922,6 @@
     surface.flush();
   }
 
-  function TextShapingAPI1(CanvasKit, notoserifData) {
-    if (!notoserifData || !CanvasKit) {
-      return;
-    }
-    const surface = CanvasKit.MakeSWCanvasSurface('shape1');
-    if (!surface) {
-      console.error('Could not make surface');
-      return;
-    }
-    const canvas = surface.getCanvas();
-    const paint = new CanvasKit.Paint();
-    paint.setColor(CanvasKit.BLUE);
-    paint.setStyle(CanvasKit.PaintStyle.Stroke);
-
-    const fontMgr = CanvasKit.FontMgr.RefDefault();
-    const notoSerif = fontMgr.MakeTypefaceFromData(notoserifData);
-
-    const textPaint = new CanvasKit.Paint();
-    const textFont = new CanvasKit.Font(notoSerif, 20);
-
-    canvas.drawRect(CanvasKit.LTRBRect(30, 30, 200, 200), paint);
-    canvas.drawText('This text is not shaped, and overflows the boundry',
-                    35, 50, textPaint, textFont);
-
-    const shapedText = new CanvasKit.ShapedText({
-      font: textFont,
-      leftToRight: true,
-      text: 'This text *is* shaped, and wraps to the right width.',
-      width: 160,
-    });
-    const textBoxX = 35;
-    const textBoxY = 55;
-    canvas.drawText(shapedText, textBoxX, textBoxY, textPaint);
-    const bounds = shapedText.getBounds();
-
-    bounds[0] += textBoxX; // left
-    bounds[2] += textBoxX; // right
-    bounds[1] += textBoxY; // top
-    bounds[3] += textBoxY; // bottom
-
-    canvas.drawRect(bounds, paint);
-    const SHAPE_TEST_TEXT = 'VAVAVAVAVAFIfi';
-    const textFont2 = new CanvasKit.Font(notoSerif, 60);
-    const shapedText2 = new CanvasKit.ShapedText({
-      font: textFont2,
-      leftToRight: true,
-      text: SHAPE_TEST_TEXT,
-      width: 600,
-    });
-
-    canvas.drawText('no kerning ↓', 10, 240, textPaint, textFont);
-    canvas.drawText(SHAPE_TEST_TEXT, 10, 300, textPaint, textFont2);
-    canvas.drawText(shapedText2, 10, 300, textPaint);
-    canvas.drawText('kerning ↑', 10, 390, textPaint, textFont);
-
-    surface.flush();
-
-    paint.delete();
-    notoSerif.delete();
-    textPaint.delete();
-    textFont.delete();
-    shapedText.delete();
-    textFont2.delete();
-    shapedText2.delete();
-
-    surface.delete();
-  }
-
-  function TextShapingAPI2(CanvasKit, notoserifData) {
-    if (!notoserifData || !CanvasKit) {
-      return;
-    }
-    const surface = CanvasKit.MakeSWCanvasSurface('shape2');
-    if (!surface) {
-      console.error('Could not make surface');
-      return;
-    }
-    const paint = new CanvasKit.Paint();
-    paint.setColor(CanvasKit.BLUE);
-    paint.setStyle(CanvasKit.PaintStyle.Stroke);
-
-    const fontMgr = CanvasKit.FontMgr.RefDefault();
-    const notoSerif = fontMgr.MakeTypefaceFromData(notoserifData);
-
-    const textPaint = new CanvasKit.Paint();
-    const bigFont = new CanvasKit.Font(notoSerif, 40);
-    const smallFont = new CanvasKit.Font(notoSerif, 25);
-
-    const TEXT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ac leo vitae ipsum hendrerit euismod quis rutrum nibh. Quisque non suscipit urna. Donec enim urna, facilisis vitae volutpat in, mattis at elit. Sed quis augue et dolor dignissim fringilla. Sed non massa eu neque tristique malesuada. ';
-
-    let X = 240;
-    let Y = 190;
-
-    function drawFrame(canvas) {
-      canvas.clear(CanvasKit.TRANSPARENT);
-
-      const shapedText = new CanvasKit.ShapedText({
-        font: smallFont,
-        leftToRight: true,
-        text: TEXT,
-        width: (X * 2) - 10,
-      });
-
-      canvas.drawRect(CanvasKit.LTRBRect(10, 10, X*2, Y*2), paint);
-      canvas.drawText(shapedText, 10, 40, textPaint, smallFont);
-      canvas.drawText('Try Clicking!', 10, 480, textPaint, bigFont);
-
-      shapedText.delete();
-
-      surface.requestAnimationFrame(drawFrame);
-    }
-    surface.requestAnimationFrame(drawFrame);
-
-    // Make animation interactive
-    let interact = (e) => {
-      if (!e.pressure) {
-        return;
-      }
-      X = e.offsetX;
-      Y = e.offsetY;
-    };
-    document.getElementById('shape2').addEventListener('pointermove', interact);
-    document.getElementById('shape2').addEventListener('pointerdown', interact);
-    preventScrolling(document.getElementById('shape2'));
-  }
-
   function TextOnPathAPI1(CanvasKit) {
     const surface = CanvasKit.MakeSWCanvasSurface('textonpath');
     if (!surface) {
diff --git a/modules/canvaskit/canvaskit/types/canvaskit-wasm-tests.ts b/modules/canvaskit/canvaskit/types/canvaskit-wasm-tests.ts
index ee334bb..00585d1 100644
--- a/modules/canvaskit/canvaskit/types/canvaskit-wasm-tests.ts
+++ b/modules/canvaskit/canvaskit/types/canvaskit-wasm-tests.ts
@@ -17,7 +17,6 @@
     Path,
     PathEffect,
     Shader,
-    ShapedText,
     SkPicture,
     TextBlob,
     Typeface,
@@ -50,7 +49,6 @@
     runtimeEffectTests(CK);
     skottieTests(CK);
     shaderTests(CK);
-    shapedTextTests(CK);
     surfaceTests(CK);
     textBlobTests(CK);
     vectorTests(CK);
@@ -76,11 +74,10 @@
 // cause errors.
 function canvasTests(CK: CanvasKit, canvas?: Canvas, paint?: Paint, path?: Path,
                      img?: Image, aImg?: AnimatedImage, para?: Paragraph,
-                     skp?: SkPicture, font?: Font, shapedText?: ShapedText,
-                     textBlob?: TextBlob, verts?: Vertices, imageInfo?: ImageInfo,
-                     imgFilter?: ImageFilter) {
+                     skp?: SkPicture, font?: Font, textBlob?: TextBlob, verts?: Vertices,
+                     imageInfo?: ImageInfo, imgFilter?: ImageFilter) {
     if (!canvas || !paint || !path || !img || !aImg || !para || !skp || !font ||
-        !shapedText || !textBlob || !verts || !imageInfo || !imgFilter) {
+        !textBlob || !verts || !imageInfo || !imgFilter) {
         return;
     }
     const someColor = [0.9, 0.8, 0.7, 0.6]; // Making sure arrays are accepted as colors.
@@ -137,7 +134,6 @@
     const mallocedVector3 = CK.Malloc(Float32Array, 3);
     canvas.drawShadow(path, mallocedVector3, mallocedVector3, 7, someColor, CK.BLUE, 0);
     canvas.drawText('foo', 1, 2, paint, font);
-    canvas.drawText(shapedText, 1, 2, paint, font);
     canvas.drawTextBlob(textBlob, 10, 20, paint);
     canvas.drawVertices(verts, CK.BlendMode.DstOut, paint);
     const matrOne = canvas.findMarkedCTM('thing'); // $ExpectType Float32Array | null
@@ -799,19 +795,6 @@
     const s13 = CK.Shader.MakeTurbulence(0.1, 0.05, 2, 0, 80, 80); // $ExpectType Shader
 }
 
-function shapedTextTests(CK: CanvasKit, textFont?: Font) {
-    if (!textFont) return;
-
-    const shaped = new CK.ShapedText({ // $ExpectType ShapedText
-       font: textFont,
-       leftToRight: true,
-       text: 'this is shaped',
-       width: 20,
-    });
-    const bounds = shaped.getBounds();
-    shaped.getBounds(bounds);
-}
-
 function surfaceTests(CK: CanvasKit) {
     const canvasEl = document.querySelector('canvas') as HTMLCanvasElement;
     const surfaceOne = CK.MakeCanvasSurface(canvasEl)!; // $ExpectType Surface
diff --git a/modules/canvaskit/canvaskit/types/index.d.ts b/modules/canvaskit/canvaskit/types/index.d.ts
index e34a9bb..62b70f6 100644
--- a/modules/canvaskit/canvaskit/types/index.d.ts
+++ b/modules/canvaskit/canvaskit/types/index.d.ts
@@ -402,7 +402,6 @@
     // Constructors, i.e. things made with `new CanvasKit.Foo()`;
     readonly ImageData: ImageDataConstructor;
     readonly ParagraphStyle: ParagraphStyleConstructor;
-    readonly ShapedText: ShapedTextConstructor;
     readonly ContourMeasureIter: ContourMeasureIterConstructor;
     readonly Font: FontConstructor;
     readonly Paint: DefaultConstructor<Paint>;
@@ -887,25 +886,6 @@
 }
 
 /**
- * A simple wrapper around TextBlob and the simple Text Shaper.
- */
-export interface ShapedText extends EmbindObject<ShapedText> {
-    /**
-     * Return the bounding area for the given text.
-     * @param outputArray - if provided, the bounding box will be copied into this array instead of
-     *                      allocating a new one.
-     */
-    getBounds(outputArray?: Rect): Rect;
-}
-
-export interface ShapedTextOpts {
-    text: string;
-    font: Font;
-    leftToRight: boolean;
-    width: number;
-}
-
-/**
  * See SkAnimatedImage.h for more information on this class.
  */
 export interface AnimatedImage extends EmbindObject<AnimatedImage> {
@@ -1257,15 +1237,15 @@
                ambientColor: InputColor, spotColor: InputColor, flags: number): void;
 
     /**
-     * Draw the given text at the location (x, y) using the provided paint and font. If non-shaped
-     * text is provided, the text will be drawn as is; no line-breaking, no ligatures, etc.
-     * @param str - either a string or pre-shaped text. Unicode text is supported.
+     * Draw the given text at the location (x, y) using the provided paint and font. The text will
+     * be drawn as is; no shaping, left-to-right, etc.
+     * @param str
      * @param x
      * @param y
      * @param paint
      * @param font
      */
-    drawText(str: string | ShapedText, x: number, y: number, paint: Paint, font: Font): void;
+    drawText(str: string, x: number, y: number, paint: Paint, font: Font): void;
 
     /**
      * Draws the given TextBlob at (x, y) using the current clip, current matrix, and the
@@ -2893,17 +2873,6 @@
 }
 
 /**
- * This class is an abstraction around SkShaper.h
- */
-export interface ShapedTextConstructor {
-    /**
-     * Return a ShapedText from the given options. See SkShaper.h for more.
-     * @param opts
-     */
-    new (opts: ShapedTextOpts): ShapedText;
-}
-
-/**
  * See SkColorFilter.h for more.
  */
 export interface ColorFilterFactory {
diff --git a/modules/canvaskit/canvaskit_bindings.cpp b/modules/canvaskit/canvaskit_bindings.cpp
index de72318..86b6e3f 100644
--- a/modules/canvaskit/canvaskit_bindings.cpp
+++ b/modules/canvaskit/canvaskit_bindings.cpp
@@ -603,62 +603,6 @@
     return p.getFillPath(path, &path, nullptr, opts.precision);
 }
 
-// Text Shaping abstraction
-
-#ifndef SK_NO_FONTS
-struct ShapedTextOpts {
-    SkFont font;
-    bool leftToRight;
-    std::string text;
-    SkScalar width;
-};
-
-std::unique_ptr<SkShaper> shaper;
-
-static sk_sp<SkTextBlob> do_shaping(const ShapedTextOpts& opts, SkPoint* pt) {
-    SkTextBlobBuilderRunHandler builder(opts.text.c_str(), {0, 0});
-    if (!shaper) {
-        shaper = SkShaper::Make();
-    }
-    shaper->shape(opts.text.c_str(), opts.text.length(),
-                  opts.font, opts.leftToRight,
-                  opts.width, &builder);
-    *pt = builder.endPoint();
-    return builder.makeBlob();
-}
-
-// TODO(kjlubick) ShapedText is a very thin veneer around SkTextBlob - can probably remove it.
-class ShapedText {
- public:
-    ShapedText(ShapedTextOpts opts) : fOpts(opts) {}
-
-    SkRect getBounds() {
-        this->init();
-        return SkRect::MakeLTRB(0, 0, fOpts.width, fPoint.y());
-    }
-
-    SkTextBlob* blob() {
-        this->init();
-        return fBlob.get();
-    }
- private:
-    const ShapedTextOpts fOpts;
-    SkPoint fPoint;
-    sk_sp<SkTextBlob> fBlob;
-
-    void init() {
-        if (!fBlob) {
-            fBlob = do_shaping(fOpts, &fPoint);
-        }
-    }
-};
-
-void drawShapedText(SkCanvas& canvas, ShapedText st, SkScalar x,
-                    SkScalar y, const SkPaint& paint) {
-    canvas.drawTextBlob(st.blob(), x, y, paint);
-}
-#endif //SK_NO_FONTS
-
 // This function is private, we call it in interface.js
 void computeTonalColors(uintptr_t cPtrAmbi /* float * */, uintptr_t cPtrSpot /* float * */) {
     // private methods accepting colors take pointers to floats already copied into wasm memory.
@@ -1045,7 +989,6 @@
                                       flags);
         }))
 #ifndef SK_NO_FONTS
-        .function("_drawShapedText", &drawShapedText)
         .function("_drawSimpleText", optional_override([](SkCanvas& self, uintptr_t /* char* */ sptr,
                                                           size_t len, SkScalar x, SkScalar y, const SkFont& font,
                                                           const SkPaint& paint) {
@@ -1236,14 +1179,6 @@
         .function("setSubpixel", &SkFont::setSubpixel)
         .function("setTypeface", &SkFont::setTypeface, allow_raw_pointers());
 
-    class_<ShapedText>("ShapedText")
-        .constructor<ShapedTextOpts>()
-        .function("_getBounds", optional_override([](ShapedText& self,
-                                                     uintptr_t /* float* */ fPtr)->void {
-            SkRect* output = reinterpret_cast<SkRect*>(fPtr);
-            output[0] = self.getBounds();
-        }));
-
     class_<SkFontMgr>("FontMgr")
         .smart_ptr<sk_sp<SkFontMgr>>("sk_sp<FontMgr>")
         .class_function("_fromData", optional_override([](uintptr_t /* uint8_t**  */ dPtr,
@@ -2019,14 +1954,6 @@
     // object and does not require delete().
     // https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#value-types
 
-#ifndef SK_NO_FONTS
-    value_object<ShapedTextOpts>("ShapedTextOpts")
-        .field("font",        &ShapedTextOpts::font)
-        .field("leftToRight", &ShapedTextOpts::leftToRight)
-        .field("text",        &ShapedTextOpts::text)
-        .field("width",       &ShapedTextOpts::width);
-#endif
-
     value_object<SimpleImageInfo>("ImageInfo")
         .field("width",      &SimpleImageInfo::width)
         .field("height",     &SimpleImageInfo::height)
diff --git a/modules/canvaskit/externs.js b/modules/canvaskit/externs.js
index e914951..af74c2f 100644
--- a/modules/canvaskit/externs.js
+++ b/modules/canvaskit/externs.js
@@ -82,7 +82,6 @@
   _MakePicture: function() {},
   _decodeAnimatedImage: function() {},
   _decodeImage: function() {},
-  _drawShapedText: function() {},
   _getShadowLocalBounds: function() {},
 
   // The testing object is meant to expose internal functions
@@ -186,14 +185,6 @@
   ColorBuilder: function() {},
   RectBuilder: function() {},
 
-  ShapedText: {
-    prototype: {
-      getBounds: function() {},
-    },
-    // private API (from C++ bindings)
-    _getBounds: function() {},
-  },
-
   AnimatedImage: {
     // public API (from C++ bindings)
     decodeNextFrame: function() {},
@@ -525,7 +516,6 @@
     copy: function() {},
     countPoints: function() {},
     equals: function() {},
-    getBounds: function() {},
     getFillType: function() {},
     isEmpty: function() {},
     isVolatile: function() {},
@@ -553,6 +543,7 @@
       computeTightBounds: function() {},
       cubicTo: function() {},
       dash: function() {},
+      getBounds: function() {},
       getPoint: function() {},
       lineTo: function() {},
       moveTo: function() {},
@@ -589,6 +580,7 @@
     _computeTightBounds: function() {},
     _cubicTo: function() {},
     _dash: function() {},
+    _getBounds: function() {},
     _getPoint: function() {},
     _lineTo: function() {},
     _moveTo: function() {},
diff --git a/modules/canvaskit/font.js b/modules/canvaskit/font.js
index eac01ae..68f5523 100644
--- a/modules/canvaskit/font.js
+++ b/modules/canvaskit/font.js
@@ -1,21 +1,16 @@
 CanvasKit._extraInitializations = CanvasKit._extraInitializations || [];
 CanvasKit._extraInitializations.push(function() {
 
-  // str can be either a text string or a ShapedText object
   CanvasKit.Canvas.prototype.drawText = function(str, x, y, paint, font) {
-    if (typeof str === 'string') {
-      // lengthBytesUTF8 and stringToUTF8Array are defined in the emscripten
-      // JS.  See https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#stringToUTF8
-      var strLen = lengthBytesUTF8(str);
-      // Add 1 for null terminator, which we need when copying/converting, but can ignore
-      // when we call into Skia.
-      var strPtr = CanvasKit._malloc(strLen + 1);
-      stringToUTF8(str, strPtr, strLen + 1);
-      this._drawSimpleText(strPtr, strLen, x, y, font, paint);
-      CanvasKit._free(strPtr);
-    } else {
-      this._drawShapedText(str, x, y, paint);
-    }
+    // lengthBytesUTF8 and stringToUTF8Array are defined in the emscripten
+    // JS.  See https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#stringToUTF8
+    var strLen = lengthBytesUTF8(str);
+    // Add 1 for null terminator, which we need when copying/converting, but can ignore
+    // when we call into Skia.
+    var strPtr = CanvasKit._malloc(strLen + 1);
+    stringToUTF8(str, strPtr, strLen + 1);
+    this._drawSimpleText(strPtr, strLen, x, y, font, paint);
+    CanvasKit._free(strPtr);
   };
 
   // Glyphs should be a Uint32Array of glyph ids, e.g. provided by Font.getGlyphIDs.
@@ -171,19 +166,6 @@
     return font;
   };
 
-  // Clients can pass in a Float32Array with length 4 to this and the results
-  // will be copied into that array. Otherwise, a new TypedArray will be allocated
-  // and returned.
-  CanvasKit.ShapedText.prototype.getBounds = function(optionalOutputArray) {
-    this._getBounds(_scratchFourFloatsAPtr);
-    var ta = _scratchFourFloatsA['toTypedArray']();
-    if (optionalOutputArray) {
-      optionalOutputArray.set(ta);
-      return optionalOutputArray;
-    }
-    return ta.slice();
-  };
-
   CanvasKit.TextBlob.MakeOnPath = function(str, path, font, initialOffset) {
     if (!str || !str.length) {
       Debug('ignoring 0 length string');
diff --git a/modules/canvaskit/tests/font.spec.js b/modules/canvaskit/tests/font.spec.js
index 2cae6f1..89a4ea4 100644
--- a/modules/canvaskit/tests/font.spec.js
+++ b/modules/canvaskit/tests/font.spec.js
@@ -33,63 +33,6 @@
         document.body.removeChild(container);
     });
 
-    gm('text_shaping', (canvas) => {
-        const paint = new CanvasKit.Paint();
-
-        paint.setColor(CanvasKit.BLUE);
-        paint.setStyle(CanvasKit.PaintStyle.Stroke);
-
-        const fontMgr = CanvasKit.FontMgr.RefDefault();
-        const notoSerif = fontMgr.MakeTypefaceFromData(notoSerifFontBuffer);
-
-        const textPaint = new CanvasKit.Paint();
-        const textFont = new CanvasKit.Font(notoSerif, 20);
-
-        canvas.drawRect(CanvasKit.LTRBRect(30, 30, 200, 200), paint);
-        canvas.drawText('This text is not shaped, and overflows the boundary',
-                        35, 50, textPaint, textFont);
-
-        const shapedText = new CanvasKit.ShapedText({
-            font: textFont,
-            leftToRight: true,
-            text: 'This text *is* shaped, and wraps to the right width.',
-            width: 160,
-        });
-        const textBoxX = 35;
-        const textBoxY = 55;
-        canvas.drawText(shapedText, textBoxX, textBoxY, textPaint);
-        const bounds = shapedText.getBounds();
-
-        bounds[0] += textBoxX; // left
-        bounds[2] += textBoxX; // right
-        bounds[1] += textBoxY; // top
-        bounds[3] += textBoxY; // bottom
-
-        canvas.drawRect(bounds, paint);
-        const SHAPE_TEST_TEXT = 'VAVAVAVAVAFIfi';
-        const textFont2 = new CanvasKit.Font(notoSerif, 60);
-        const shapedText2 = new CanvasKit.ShapedText({
-            font: textFont2,
-            leftToRight: true,
-            text: SHAPE_TEST_TEXT,
-            width: 600,
-        });
-
-        canvas.drawText('no kerning ↓', 10, 240, textPaint, textFont);
-        canvas.drawText(SHAPE_TEST_TEXT, 10, 300, textPaint, textFont2);
-        canvas.drawText(shapedText2, 10, 300, textPaint);
-        canvas.drawText('kerning ↑', 10, 390, textPaint, textFont);
-
-        paint.delete();
-        notoSerif.delete();
-        textPaint.delete();
-        textFont.delete();
-        shapedText.delete();
-        textFont2.delete();
-        shapedText2.delete();
-        fontMgr.delete();
-    });
-
     gm('monospace_text_on_path', (canvas) => {
         const paint = new CanvasKit.Paint();
         paint.setAntiAlias(true);