OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef ShapeResultBloberizer_h |
| 6 #define ShapeResultBloberizer_h |
| 7 |
| 8 #include "platform/PlatformExport.h" |
| 9 #include "platform/fonts/Glyph.h" |
| 10 #include "platform/fonts/SimpleFontData.h" |
| 11 #include "platform/geometry/FloatPoint.h" |
| 12 #include "third_party/skia/include/core/SkTextBlob.h" |
| 13 #include "wtf/Allocator.h" |
| 14 #include "wtf/Vector.h" |
| 15 |
| 16 namespace blink { |
| 17 |
| 18 class Font; |
| 19 |
| 20 class PLATFORM_EXPORT ShapeResultBloberizer { |
| 21 WTF_MAKE_NONCOPYABLE(ShapeResultBloberizer); |
| 22 STACK_ALLOCATED(); |
| 23 |
| 24 public: |
| 25 enum class Type { Normal, TextIntercepts }; |
| 26 |
| 27 ShapeResultBloberizer(const Font&, |
| 28 float deviceScaleFactor, |
| 29 Type = Type::Normal); |
| 30 |
| 31 Type type() const { return m_type; } |
| 32 |
| 33 void add(Glyph glyph, const SimpleFontData* fontData, float hOffset) { |
| 34 // cannot mix x-only/xy offsets |
| 35 DCHECK(!hasPendingVerticalOffsets()); |
| 36 |
| 37 if (UNLIKELY(fontData != m_pendingFontData)) { |
| 38 commitPendingRun(); |
| 39 m_pendingFontData = fontData; |
| 40 DCHECK_EQ(blobRotation(fontData), BlobRotation::NoRotation); |
| 41 } |
| 42 |
| 43 m_pendingGlyphs.push_back(glyph); |
| 44 m_pendingOffsets.push_back(hOffset); |
| 45 } |
| 46 |
| 47 void add(Glyph glyph, |
| 48 const SimpleFontData* fontData, |
| 49 const FloatPoint& offset) { |
| 50 // cannot mix x-only/xy offsets |
| 51 DCHECK(m_pendingGlyphs.isEmpty() || hasPendingVerticalOffsets()); |
| 52 |
| 53 if (UNLIKELY(fontData != m_pendingFontData)) { |
| 54 commitPendingRun(); |
| 55 m_pendingFontData = fontData; |
| 56 m_pendingVerticalBaselineXOffset = |
| 57 blobRotation(fontData) == BlobRotation::NoRotation |
| 58 ? 0 |
| 59 : fontData->getFontMetrics().floatAscent() - |
| 60 fontData->getFontMetrics().floatAscent(IdeographicBaseline); |
| 61 } |
| 62 |
| 63 m_pendingGlyphs.push_back(glyph); |
| 64 m_pendingOffsets.push_back(offset.x() + m_pendingVerticalBaselineXOffset); |
| 65 m_pendingOffsets.push_back(offset.y()); |
| 66 } |
| 67 |
| 68 enum class BlobRotation { NoRotation, CCWRotation }; |
| 69 struct BlobInfo { |
| 70 BlobInfo(sk_sp<SkTextBlob> b, BlobRotation r) |
| 71 : blob(std::move(b)), rotation(r) {} |
| 72 sk_sp<SkTextBlob> blob; |
| 73 BlobRotation rotation; |
| 74 }; |
| 75 |
| 76 using BlobBuffer = Vector<BlobInfo, 16>; |
| 77 const BlobBuffer& blobs(); |
| 78 |
| 79 private: |
| 80 friend class ShapeResultBloberizerTestInfo; |
| 81 |
| 82 void commitPendingRun(); |
| 83 void commitPendingBlob(); |
| 84 |
| 85 bool hasPendingVerticalOffsets() const; |
| 86 static BlobRotation blobRotation(const SimpleFontData*); |
| 87 |
| 88 const Font& m_font; |
| 89 const float m_deviceScaleFactor; |
| 90 const Type m_type; |
| 91 |
| 92 // Current text blob state. |
| 93 SkTextBlobBuilder m_builder; |
| 94 BlobRotation m_builderRotation = BlobRotation::NoRotation; |
| 95 size_t m_builderRunCount = 0; |
| 96 |
| 97 // Current run state. |
| 98 const SimpleFontData* m_pendingFontData = nullptr; |
| 99 Vector<Glyph, 1024> m_pendingGlyphs; |
| 100 Vector<float, 1024> m_pendingOffsets; |
| 101 float m_pendingVerticalBaselineXOffset = 0; |
| 102 |
| 103 // Constructed blobs. |
| 104 BlobBuffer m_blobs; |
| 105 }; |
| 106 |
| 107 } // namespace blink |
| 108 |
| 109 #endif // ShapeResultBloberizer_h |
OLD | NEW |