Skip to content

Commit

Permalink
Remove the GradientPaint from tgfx, use Paint.setShader() instead.
Browse files Browse the repository at this point in the history
  • Loading branch information
domchen authored Feb 10, 2022
1 parent 7bec3bb commit 4138fac
Show file tree
Hide file tree
Showing 20 changed files with 405 additions and 280 deletions.
6 changes: 3 additions & 3 deletions include/pag/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -867,16 +867,16 @@ class PAG_API Matrix {

/**
* Copies nine scalar values contained by Matrix into buffer, in member value ascending order:
* kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1, kMPersp2.
* ScaleX, SkewX, TransX, SkewY, ScaleY, TransY, Persp0, Persp1, Persp2.
* @param buffer storage for nine scalar values
*/
void get9(float buffer[9]) const {
memcpy(buffer, values, 9 * sizeof(float));
}

/**
* Sets Matrix to nine scalar values in buffer, in member value ascending order: kMScaleX,
* kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1, kMPersp2.
* Sets Matrix to nine scalar values in buffer, in member value ascending order: ScaleX,
* SkewX, TransX, SkewY, ScaleY, TransY, Persp0, Persp1, Persp2.
*
* Sets matrix to:
*
Expand Down
11 changes: 11 additions & 0 deletions src/rendering/graphics/Graphic.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@
#include "gpu/Paint.h"

namespace pag {
/**
* Defines attributes for drawing gradient colors.
*/
struct GradientPaint {
Enum gradientType;
Point startPoint;
Point endPoint;
std::vector<Color> colors;
std::vector<Opacity> alphas;
std::vector<float> positions;
};

enum class GraphicType {
Unknown,
Expand Down
1 change: 0 additions & 1 deletion src/rendering/graphics/Picture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ class RGBAAAPicture : public Picture {
}
}
// 因为视频绘制会涉及自定义的 OpenGL 操作。
// 要先 flush 父级 SkCanvas 里当前的 OpenGL 操作,防止渲染异常。
canvas->flush();
auto snapshot = cache->getSnapshot(this);
if (snapshot) {
Expand Down
60 changes: 40 additions & 20 deletions src/rendering/graphics/Shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,55 @@

#include "Shape.h"
#include "gpu/Canvas.h"
#include "gpu/GradientShader.h"
#include "pag/file.h"

namespace pag {
std::shared_ptr<Graphic> Shape::MakeFrom(const Path& path, Color color) {
if (path.isEmpty()) {
return nullptr;
}
auto fill = new SolidFill();
fill->color = color;
return std::shared_ptr<Graphic>(new Shape(path, fill));
Paint paint = {};
paint.setColor(color);
return std::shared_ptr<Graphic>(new Shape(path, paint));
}

static std::shared_ptr<Shader> MakeGradientShader(const GradientPaint& gradient) {
std::shared_ptr<Shader> shader;
std::vector<Color4f> colors = {};
int index = 0;
auto& alphas = gradient.alphas;
for (auto& color : gradient.colors) {
auto r = static_cast<float>(color.red) / 255.0f;
auto g = static_cast<float>(color.green) / 255.0f;
auto b = static_cast<float>(color.blue) / 255.0f;
auto a = static_cast<float>(alphas[index++]) / 255.0f;
colors.push_back({r, g, b, a});
}
if (gradient.gradientType == GradientFillType::Linear) {
shader = GradientShader::MakeLinear(gradient.startPoint, gradient.endPoint, colors,
gradient.positions);
} else {
auto radius = Point::Distance(gradient.startPoint, gradient.endPoint);
shader = GradientShader::MakeRadial(gradient.startPoint, radius, colors, gradient.positions);
}
if (!shader) {
shader = Shader::MakeColorShader(gradient.colors.back(), gradient.alphas.back());
}
return shader;
}

std::shared_ptr<Graphic> Shape::MakeFrom(const Path& path, const GradientPaint& gradient) {
if (path.isEmpty()) {
return nullptr;
}
auto fill = new GradientFill();
fill->gradient = gradient;
return std::shared_ptr<Graphic>(new Shape(path, fill));
Paint paint = {};
auto shader = MakeGradientShader(gradient);
paint.setShader(shader);
return std::shared_ptr<Graphic>(new Shape(path, paint));
}

Shape::Shape(Path path, ShapeFill* fill) : path(std::move(path)), fill(fill) {
}

Shape::~Shape() {
delete fill;
Shape::Shape(Path path, Paint paint) : path(std::move(path)), paint(paint) {
}

void Shape::measureBounds(Rect* bounds) const {
Expand All @@ -55,7 +78,11 @@ bool Shape::hitTest(RenderCache*, float x, float y) {
}

bool Shape::getPath(Path* result) const {
if (fill->type() == ShapeFillType::Gradient) {
if (paint.getAlpha() != Opaque) {
return false;
}
auto shader = paint.getShader();
if (shader && !shader->isOpaque()) {
return false;
}
result->addPath(path);
Expand All @@ -66,14 +93,7 @@ void Shape::prepare(RenderCache*) const {
}

void Shape::draw(Canvas* canvas, RenderCache*) const {
switch (fill->type()) {
case ShapeFillType::Solid:
canvas->drawPath(path, static_cast<SolidFill*>(fill)->color);
break;
case ShapeFillType::Gradient:
canvas->drawPath(path, static_cast<GradientFill*>(fill)->gradient);
break;
}
canvas->drawPath(path, paint);
}

} // namespace pag
33 changes: 2 additions & 31 deletions src/rendering/graphics/Shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,6 @@
#include "rendering/graphics/Graphic.h"

namespace pag {
enum class ShapeFillType { Solid, Gradient };

class ShapeFill {
public:
virtual ~ShapeFill() = default;

virtual ShapeFillType type() const = 0;
};

class SolidFill : public ShapeFill {
public:
ShapeFillType type() const override {
return ShapeFillType::Solid;
}

Color color;
};

class GradientFill : public ShapeFill {
public:
ShapeFillType type() const override {
return ShapeFillType::Gradient;
}

GradientPaint gradient = {};
};

class Shape : public Graphic {
public:
/**
Expand All @@ -60,8 +33,6 @@ class Shape : public Graphic {
*/
static std::shared_ptr<Graphic> MakeFrom(const Path& path, const GradientPaint& gradient);

~Shape() override;

GraphicType type() const override {
return GraphicType::Shape;
}
Expand All @@ -74,8 +45,8 @@ class Shape : public Graphic {

private:
Path path = {};
ShapeFill* fill = nullptr;
Paint paint = {};

Shape(Path path, ShapeFill* fill);
Shape(Path path, Paint paint);
};
} // namespace pag
6 changes: 1 addition & 5 deletions src/rendering/graphics/Text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,7 @@ static void ApplyPaintToPath(const Paint& paint, Path* path) {
if (strokeEffect) {
strokeEffect->applyTo(&strokePath);
}
if (paint.getStyle() == PaintStyle::Stroke) {
*path = strokePath;
} else {
path->addPath(strokePath);
}
*path = strokePath;
}

bool Text::hitTest(RenderCache*, float x, float y) {
Expand Down
3 changes: 3 additions & 0 deletions tgfx/include/core/PathMeasure.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include "Path.h"

namespace pag {
/**
* PathMeasure calculates the length of a Path and cuts child segments from it.
*/
class PathMeasure {
public:
/**
Expand Down
9 changes: 2 additions & 7 deletions tgfx/include/gpu/Canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,9 @@ class Canvas {
void drawTexture(const Texture* texture, const Matrix& matrix);

/**
* Draws a path with solid color fill, using current alpha, blend mode, clip and Matrix.
* Draws a path with using current clip, matrix and specified paint.
*/
virtual void drawPath(const Path& path, Color color) = 0;

/**
* Draws a path with gradient color fill, using current alpha, blend mode, clip and Matrix.
*/
virtual void drawPath(const Path& path, const GradientPaint& gradient) = 0;
virtual void drawPath(const Path& path, const Paint& paint) = 0;

/**
* Draw array of glyphs with specified font, using current alpha, blend mode, clip and Matrix.
Expand Down
86 changes: 27 additions & 59 deletions tgfx/include/gpu/GradientShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,72 +19,40 @@
#pragma once

#include "core/Color4f.h"
#include "gpu/FragmentProcessor.h"
#include "gpu/Shader.h"

namespace pag {
struct FPArgs {
FPArgs(Context* context, const Matrix& localMatrix) : context(context), localMatrix(localMatrix) {
}

Context* context = nullptr;
Matrix localMatrix = Matrix::I();
};

class Shader {
public:
static std::unique_ptr<Shader> MakeColorShader(Color color, Opacity opacity = Opaque);

virtual ~Shader() = default;

virtual std::unique_ptr<FragmentProcessor> asFragmentProcessor(const FPArgs& args) const = 0;
};

class Color4Shader : public Shader {
public:
explicit Color4Shader(Color4f color) : color(color) {
}

std::unique_ptr<FragmentProcessor> asFragmentProcessor(const FPArgs& args) const override;

private:
Color4f color;
};

class GradientShaderBase : public Shader {
public:
GradientShaderBase(const std::vector<Color4f>& colors, const std::vector<float>& positions,
const Matrix& pointsToUnit);

std::vector<Color4f> originalColors = {};
std::vector<float> originalPositions = {};

protected:
const Matrix pointsToUnit;
};

class LinearGradient : public GradientShaderBase {
public:
LinearGradient(const Point& startPoint, const Point& endPoint, const std::vector<Color4f>& colors,
const std::vector<float>& positions);

std::unique_ptr<FragmentProcessor> asFragmentProcessor(const FPArgs& args) const override;
};

class RadialGradient : public GradientShaderBase {
public:
RadialGradient(const Point& center, float radius, const std::vector<Color4f>& colors,
const std::vector<float>& positions);

std::unique_ptr<FragmentProcessor> asFragmentProcessor(const FPArgs& args) const override;
};

/**
* GradientShader hosts factories for creating subclasses of Shader that render linear and radial
* gradients.
*/
class GradientShader {
public:
static std::unique_ptr<Shader> MakeLinear(const Point& startPoint, const Point& endPoint,
/**
* Returns a shader that generates a linear gradient between the two specified points.
* @param startPoint The start point for the gradient.
* @param endPoint The end point for the gradient.
* @param colors The array of colors, to be distributed between the two points.
* @param positions May be empty. The relative position of each corresponding color in the colors
* array. If this is empty, the the colors are distributed evenly between the start and end point.
* If this is not empty, the values must begin with 0, end with 1.0, and intermediate values must
* be strictly increasing.
*/
static std::shared_ptr<Shader> MakeLinear(const Point& startPoint, const Point& endPoint,
const std::vector<Color4f>& colors,
const std::vector<float>& positions);

static std::unique_ptr<Shader> MakeRadial(const Point& center, float radius,
/**
* Returns a shader that generates a radial gradient given the center and radius.
* @param center The center of the circle for this gradient
* @param radius Must be positive. The radius of the circle for this gradient.
* @param colors The array of colors, to be distributed between the center and edge of the circle.
* @param positions May be empty. The relative position of each corresponding color in the colors
* array. If this is empty, the the colors are distributed evenly between the start and end point.
* If this is not empty, the values must begin with 0, end with 1.0, and intermediate values must
* be strictly increasing.
*/
static std::shared_ptr<Shader> MakeRadial(const Point& center, float radius,
const std::vector<Color4f>& colors,
const std::vector<float>& positions);
};
Expand Down
Loading

0 comments on commit 4138fac

Please sign in to comment.