/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkEdgeBuilder_DEFINED
#define SkEdgeBuilder_DEFINED
#include "SkAnalyticEdge.h"
#include "SkArenaAlloc.h"
#include "SkEdge.h"
#include "SkRect.h"
#include "SkTDArray.h"
class SkPath;
class SkEdgeBuilder {
public:
int buildEdges(const SkPath& path,
const SkIRect* shiftedClip);
protected:
SkEdgeBuilder() = default;
virtual ~SkEdgeBuilder() = default;
// In general mode we allocate pointers in fList and fEdgeList points to its head.
// In polygon mode we preallocated edges contiguously in fAlloc and fEdgeList points there.
void** fEdgeList = nullptr;
SkTDArray<void*> fList;
SkSTArenaAlloc<512> fAlloc;
enum Combine {
kNo_Combine,
kPartial_Combine,
kTotal_Combine
};
private:
int build (const SkPath& path, const SkIRect* clip, bool clipToTheRight);
int buildPoly(const SkPath& path, const SkIRect* clip, bool clipToTheRight);
virtual char* allocEdges(size_t n, size_t* sizeof_edge) = 0;
virtual SkRect recoverClip(const SkIRect&) const = 0;
virtual bool chopCubics() const = 0;
virtual void addLine (const SkPoint pts[]) = 0;
virtual void addQuad (const SkPoint pts[]) = 0;
virtual void addCubic(const SkPoint pts[]) = 0;
virtual Combine addPolyLine(SkPoint pts[], char* edge, char** edgePtr) = 0;
};
class SkBasicEdgeBuilder final : public SkEdgeBuilder {
public:
explicit SkBasicEdgeBuilder(int clipShift) : fClipShift(clipShift) {}
SkEdge** edgeList() { return (SkEdge**)fEdgeList; }
private:
Combine combineVertical(const SkEdge* edge, SkEdge* last);
char* allocEdges(size_t, size_t*) override;
SkRect recoverClip(const SkIRect&) const override;
bool chopCubics() const override { return true; }
void addLine (const SkPoint pts[]) override;
void addQuad (const SkPoint pts[]) override;
void addCubic(const SkPoint pts[]) override;
Combine addPolyLine(SkPoint pts[], char* edge, char** edgePtr) override;
const int fClipShift;
};
class SkAnalyticEdgeBuilder final : public SkEdgeBuilder {
public:
SkAnalyticEdgeBuilder() {}
SkAnalyticEdge** analyticEdgeList() { return (SkAnalyticEdge**)fEdgeList; }
private:
Combine combineVertical(const SkAnalyticEdge* edge, SkAnalyticEdge* last);
char* allocEdges(size_t, size_t*) override;
SkRect recoverClip(const SkIRect&) const override;
bool chopCubics() const override { return true; }
void addLine (const SkPoint pts[]) override;
void addQuad (const SkPoint pts[]) override;
void addCubic(const SkPoint pts[]) override;
Combine addPolyLine(SkPoint pts[], char* edge, char** edgePtr) override;
};
class SkBezierEdgeBuilder final : public SkEdgeBuilder {
public:
SkBezierEdgeBuilder() {}
SkBezier** bezierList() { return (SkBezier**)fEdgeList; }
private:
char* allocEdges(size_t, size_t*) override;
SkRect recoverClip(const SkIRect&) const override;
bool chopCubics() const override { return false; }
void addLine (const SkPoint pts[]) override;
void addQuad (const SkPoint pts[]) override;
void addCubic(const SkPoint pts[]) override;
Combine addPolyLine(SkPoint pts[], char* edge, char** edgePtr) override;
};
#endif