1 /*
2  * Copyright 2013 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 "SkArithmeticModePriv.h"
9 #include "SkReadBuffer.h"
10 
11 // This class only exists to unflatten instances that were serialized into old pictures as part of
12 // SkXfermodeImageFilter before the advent of SkBlendMode. Those image filters will now be
13 // transformed to SkArithmeticImageFilter which does not use this class in its implementation.
14 class SkArithmeticMode_scalar : public SkXfermode {
15 public:
SkArithmeticMode_scalar(SkScalar k1,SkScalar k2,SkScalar k3,SkScalar k4,bool enforcePMColor)16     SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
17                             bool enforcePMColor) {
18         fK[0] = k1;
19         fK[1] = k2;
20         fK[2] = k3;
21         fK[3] = k4;
22         fEnforcePMColor = enforcePMColor;
23     }
24 
xfer32(SkPMColor[],const SkPMColor[],int count,const SkAlpha[]) const25     void xfer32(SkPMColor[], const SkPMColor[], int count, const SkAlpha[]) const override {
26         SkFAIL("This should never be called.");
27     }
28 
29     SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar)30     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar)
31 
32     // This is used to extract the arithmetic params into an SkArithmeticImageFilter. Afterwards,
33     // this object is destroyed and arithemtic blending is implemented directly in the image filter.
34     bool isArithmetic(SkArithmeticParams* params) const override {
35         if (params) {
36             memcpy(params->fK, fK, 4 * sizeof(float));
37             params->fEnforcePMColor = fEnforcePMColor;
38         }
39         return true;
40     }
41 
42 private:
flatten(SkWriteBuffer & buffer) const43     void flatten(SkWriteBuffer& buffer) const override { SkFAIL("This shouild never be called."); }
44 
45     SkScalar fK[4];
46     bool fEnforcePMColor;
47 
48     friend class SkArithmeticMode;
49 
50     typedef SkXfermode INHERITED;
51 };
52 
CreateProc(SkReadBuffer & buffer)53 sk_sp<SkFlattenable> SkArithmeticMode_scalar::CreateProc(SkReadBuffer& buffer) {
54     const SkScalar k1 = buffer.readScalar();
55     const SkScalar k2 = buffer.readScalar();
56     const SkScalar k3 = buffer.readScalar();
57     const SkScalar k4 = buffer.readScalar();
58     const bool enforcePMColor = buffer.readBool();
59     return SkArithmeticMode::Make(k1, k2, k3, k4, enforcePMColor);
60 }
61 
62 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const63 void SkArithmeticMode_scalar::toString(SkString* str) const {
64     SkFAIL("This should never be called.");
65 }
66 #endif
67 
68 ///////////////////////////////////////////////////////////////////////////////
69 
Make(SkScalar k1,SkScalar k2,SkScalar k3,SkScalar k4,bool enforcePMColor)70 sk_sp<SkXfermode> SkArithmeticMode::Make(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
71                                          bool enforcePMColor) {
72     if (SkScalarNearlyZero(k1) && SkScalarNearlyEqual(k2, SK_Scalar1) &&
73         SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) {
74         return SkXfermode::Make(SkXfermode::kSrc_Mode);
75     } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) &&
76                SkScalarNearlyEqual(k3, SK_Scalar1) && SkScalarNearlyZero(k4)) {
77         return SkXfermode::Make(SkXfermode::kDst_Mode);
78     }
79     return sk_make_sp<SkArithmeticMode_scalar>(k1, k2, k3, k4, enforcePMColor);
80 }
81 
82 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode)
83     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar)
84 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
85