1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkShaper_DEFINED
9 #define SkShaper_DEFINED
10 
11 #include <memory>
12 
13 #include "SkPoint.h"
14 #include "SkTextBlob.h"
15 #include "SkTypeface.h"
16 
17 class SkFont;
18 
19 /**
20    Shapes text using HarfBuzz and places the shaped text into a
21    client-managed buffer.
22 
23    If compiled without HarfBuzz, fall back on SkPaint::textToGlyphs.
24  */
25 class SkShaper {
26 public:
27     SkShaper(sk_sp<SkTypeface> face);
28     ~SkShaper();
29 
30     class RunHandler {
31     public:
32         virtual ~RunHandler() = default;
33 
34         struct RunInfo {
35             size_t   fLineIndex;
36             SkVector fAdvance;
37             SkScalar fAscent,
38                      fDescent,
39                      fLeading;
40         };
41 
42         struct Buffer {
43             SkGlyphID* glyphs;    // required
44             SkPoint*   positions; // required
45             char*      utf8text;  // optional
46             uint32_t*  clusters;  // optional
47         };
48 
49         virtual Buffer newRunBuffer(const RunInfo&, const SkFont&, int glyphCount,
50                                     int utf8textCount) = 0;
51     };
52 
53     bool good() const;
54     SkPoint shape(RunHandler* handler,
55                   const SkFont& srcFont,
56                   const char* utf8text,
57                   size_t textBytes,
58                   bool leftToRight,
59                   SkPoint point,
60                   SkScalar width) const;
61 
62 private:
63     SkShaper(const SkShaper&) = delete;
64     SkShaper& operator=(const SkShaper&) = delete;
65 
66     struct Impl;
67     std::unique_ptr<Impl> fImpl;
68 };
69 
70 /**
71  * Helper for shaping text directly into a SkTextBlob.
72  */
73 class SkTextBlobBuilderRunHandler final : public SkShaper::RunHandler {
74 public:
75     sk_sp<SkTextBlob> makeBlob();
76 
77     SkShaper::RunHandler::Buffer newRunBuffer(const RunInfo&, const SkFont&, int, int) override;
78 
79 private:
80     SkTextBlobBuilder fBuilder;
81 };
82 
83 #endif  // SkShaper_DEFINED
84