#ifndef CC_PAINT_DRAW_LOOPER_H_
#define CC_PAINT_DRAW_LOOPER_H_
#include <memory>
#include <vector>
#include "base/containers/adapters.h"
#include "cc/paint/paint_export.h"
#include "third_party/skia/include/core/SkBlendMode.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "third_party/skia/include/core/SkRefCnt.h"
class SkPaint;
namespace cc {
class CC_PAINT_EXPORT DrawLooper : public SkRefCnt {
public:
enum Flags {
kPostTransformFlag = 1 << 0,
kOverrideAlphaFlag = 1 << 1,
kDontModifyPaintFlag = 1 << 2,
};
~DrawLooper() override;
template <typename DrawProc>
void Apply(SkCanvas* canvas, const SkPaint& paint, DrawProc proc) const {
for (const Layer& layer : base::Reversed(layers_)) {
SkAutoCanvasRestore acr(canvas, true);
SkPaint p(paint);
layer.Apply(canvas, &p);
proc(canvas, p);
}
}
bool EqualsForTesting(const DrawLooper& other) const;
private:
enum {
kAllFlagsMask =
kPostTransformFlag | kOverrideAlphaFlag | kDontModifyPaintFlag,
};
struct Layer {
SkPoint offset;
float blur_sigma;
SkColor4f color;
uint32_t flags;
bool operator==(const Layer& other) const = default;
void Apply(SkCanvas* canvas, SkPaint* paint) const;
};
std::vector<Layer> layers_;
explicit DrawLooper(std::vector<Layer> l);
void UpdateForLayer(const Layer& layer,
SkCanvas* canvas,
SkPaint* paint) const;
friend class DrawLooperBuilder;
friend class PaintOpReader;
friend class PaintOpWriter;
};
class CC_PAINT_EXPORT DrawLooperBuilder {
public:
DrawLooperBuilder();
~DrawLooperBuilder();
void AddUnmodifiedContent(bool add_on_top = false);
void AddShadow(SkPoint offset,
float blur_sigma,
SkColor4f color,
uint32_t flags,
bool add_on_top = false);
sk_sp<DrawLooper> Detach();
private:
std::vector<DrawLooper::Layer> layers_;
};
}
#endif