blob: 18d000a17793f061f45b3a6650d6d1acfcc50e54 [file] [log] [blame]
cdalton855d83f2014-09-18 13:51:53 -07001/*
2 * Copyright 2014 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#include "GrPathRendering.h"
9#include "SkDescriptor.h"
10#include "SkGlyph.h"
11#include "SkMatrix.h"
12#include "SkTypeface.h"
13#include "GrPathRange.h"
14
cdalton193d9cf2016-05-12 11:52:02 -070015const GrUserStencilSettings& GrPathRendering::GetStencilPassSettings(FillType fill) {
16 switch (fill) {
17 default:
18 SkFAIL("Unexpected path fill.");
19 case GrPathRendering::kWinding_FillType: {
20 constexpr static GrUserStencilSettings kWindingStencilPass(
21 GrUserStencilSettings::StaticInit<
22 0xffff,
23 GrUserStencilTest::kAlwaysIfInClip,
24 0xffff,
25 GrUserStencilOp::kIncWrap,
26 GrUserStencilOp::kIncWrap,
27 0xffff>()
28 );
29 return kWindingStencilPass;
30 }
31 case GrPathRendering::kEvenOdd_FillType: {
32 constexpr static GrUserStencilSettings kEvenOddStencilPass(
33 GrUserStencilSettings::StaticInit<
34 0xffff,
35 GrUserStencilTest::kAlwaysIfInClip,
36 0xffff,
37 GrUserStencilOp::kInvert,
38 GrUserStencilOp::kInvert,
39 0xffff>()
40 );
41 return kEvenOddStencilPass;
42 }
43 }
44}
45
cdalton855d83f2014-09-18 13:51:53 -070046class GlyphGenerator : public GrPathRange::PathGenerator {
47public:
reeda9322c22016-04-12 06:47:05 -070048 GlyphGenerator(const SkTypeface& typeface, const SkScalerContextEffects& effects,
49 const SkDescriptor& desc)
50 : fScalerContext(typeface.createScalerContext(effects, &desc))
kkinnunen50b58e62015-05-18 23:02:07 -070051#ifdef SK_DEBUG
52 , fDesc(desc.copy())
53#endif
cdalton7d5c9502015-10-03 13:28:35 -070054 {}
cdalton855d83f2014-09-18 13:51:53 -070055
mtklein36352bf2015-03-25 18:17:31 -070056 int getNumPaths() override {
cdalton855d83f2014-09-18 13:51:53 -070057 return fScalerContext->getGlyphCount();
58 }
59
mtklein36352bf2015-03-25 18:17:31 -070060 void generatePath(int glyphID, SkPath* out) override {
Ben Wagner6e9ac122016-11-11 14:31:06 -050061 fScalerContext->getPath(glyphID, out);
cdalton855d83f2014-09-18 13:51:53 -070062 }
kkinnunen50b58e62015-05-18 23:02:07 -070063#ifdef SK_DEBUG
bsalomonc5d07fa2016-05-17 10:17:45 -070064 bool isEqualTo(const SkDescriptor& desc) const override { return *fDesc == desc; }
kkinnunen50b58e62015-05-18 23:02:07 -070065#endif
cdalton855d83f2014-09-18 13:51:53 -070066private:
bungeman7cfd46a2016-10-20 16:06:52 -040067 const std::unique_ptr<SkScalerContext> fScalerContext;
kkinnunen50b58e62015-05-18 23:02:07 -070068#ifdef SK_DEBUG
bungeman520ced62016-10-18 08:03:42 -040069 const std::unique_ptr<SkDescriptor> fDesc;
kkinnunen50b58e62015-05-18 23:02:07 -070070#endif
cdalton855d83f2014-09-18 13:51:53 -070071};
72
73GrPathRange* GrPathRendering::createGlyphs(const SkTypeface* typeface,
reeda9322c22016-04-12 06:47:05 -070074 const SkScalerContextEffects& effects,
cdalton855d83f2014-09-18 13:51:53 -070075 const SkDescriptor* desc,
bsalomon6663acf2016-05-10 09:14:17 -070076 const GrStyle& style) {
halcanary96fcdcc2015-08-27 07:41:13 -070077 if (nullptr == typeface) {
cdalton855d83f2014-09-18 13:51:53 -070078 typeface = SkTypeface::GetDefaultTypeface();
halcanary96fcdcc2015-08-27 07:41:13 -070079 SkASSERT(nullptr != typeface);
cdalton855d83f2014-09-18 13:51:53 -070080 }
81
82 if (desc) {
Hal Canary144caf52016-11-07 17:57:18 -050083 sk_sp<GlyphGenerator> generator(new GlyphGenerator(*typeface, effects, *desc));
84 return this->createPathRange(generator.get(), style);
cdalton855d83f2014-09-18 13:51:53 -070085 }
86
87 SkScalerContextRec rec;
88 memset(&rec, 0, sizeof(rec));
89 rec.fFontID = typeface->uniqueID();
90 rec.fTextSize = SkPaint::kCanonicalTextSizeForPaths;
91 rec.fPreScaleX = rec.fPost2x2[0][0] = rec.fPost2x2[1][1] = SK_Scalar1;
92 // Don't bake stroke information into the glyphs, we'll let the GPU do the stroking.
93
94 SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
95 SkDescriptor* genericDesc = ad.getDesc();
96
97 genericDesc->init();
98 genericDesc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
99 genericDesc->computeChecksum();
reeda9322c22016-04-12 06:47:05 -0700100
101 // No effects, so we make a dummy struct
102 SkScalerContextEffects noEffects;
cdalton855d83f2014-09-18 13:51:53 -0700103
Hal Canary144caf52016-11-07 17:57:18 -0500104 sk_sp<GlyphGenerator> generator(new GlyphGenerator(*typeface, noEffects, *genericDesc));
105 return this->createPathRange(generator.get(), style);
cdalton855d83f2014-09-18 13:51:53 -0700106}