1 // Copyright 2018 Google LLC.
2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3 #ifndef SkPDFGlyphUse_DEFINED
4 #define SkPDFGlyphUse_DEFINED
5 
6 #include "SkBitSet.h"
7 #include "SkTypes.h"
8 
9 class SkPDFGlyphUse {
10 public:
11     SkPDFGlyphUse() : fBitSet(0) {}
12     SkPDFGlyphUse(SkGlyphID firstNonZero, SkGlyphID lastGlyph)
13         : fBitSet((int)lastGlyph - firstNonZero + 2)
14         , fFirstNonZero(firstNonZero)
15         , fLastGlyph(lastGlyph) { SkASSERT(firstNonZero >= 1); }
16     ~SkPDFGlyphUse() = default;
17     SkPDFGlyphUse(SkPDFGlyphUse&&) = default;
18     SkPDFGlyphUse& operator=(SkPDFGlyphUse&&) = default;
19 
20     SkGlyphID firstNonZero() const { return fFirstNonZero; }
21     SkGlyphID lastGlyph() const { return fLastGlyph; }
22     void set(SkGlyphID gid) { fBitSet.set(this->toCode(gid)); }
23     bool has(SkGlyphID gid) const { return fBitSet.has(this->toCode(gid)); }
24 
25     template<typename FN>
26     void getSetValues(FN f) const {
27         if (fFirstNonZero == 1) {
28             return fBitSet.getSetValues(std::move(f));
29         }
30         uint16_t offset = fFirstNonZero - 1;
31         fBitSet.getSetValues([&f, offset](unsigned v) { f(v == 0 ? v : v + offset); });
32     }
33 
34 private:
35     SkBitSet fBitSet;
36     SkGlyphID fFirstNonZero = 0;
37     SkGlyphID fLastGlyph = 0;
38 
39     uint16_t toCode(SkGlyphID gid) const {
40         if (gid == 0 || fFirstNonZero == 1) {
41             return gid;
42         }
43         SkASSERT(gid >= fFirstNonZero && gid <= fLastGlyph);
44         return gid - fFirstNonZero + 1;
45     }
46     SkPDFGlyphUse(const SkPDFGlyphUse&) = delete;
47     SkPDFGlyphUse& operator=(const SkPDFGlyphUse&) = delete;
48 };
49 #endif  // SkPDFGlyphUse_DEFINED
50