Skip to content

Commit

Permalink
Remove the translate(), scale(), rotate(), and skew() methods from th…
Browse files Browse the repository at this point in the history
…e DrawContext class. (#180)
  • Loading branch information
domchen committed Mar 29, 2024
1 parent 17ced8e commit 17e7b62
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 104 deletions.
2 changes: 1 addition & 1 deletion include/tgfx/core/Canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ class Canvas {

bool drawSimplePath(const Path& path, const FillStyle& style);
void drawImage(std::shared_ptr<Image> image, SamplingOptions sampling, const Paint* paint,
const Matrix* extraMatrix);
Matrix extraMatrix);
void drawRect(const Rect& rect, const FillStyle& style, const Matrix* extraMatrix = nullptr);
bool wouldOverwriteEntireSurface(const Rect& rect, const FillStyle& style) const;
};
Expand Down
63 changes: 52 additions & 11 deletions include/tgfx/core/Matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,42 @@ class Matrix {
return m;
}

/**
* Sets Matrix to skew by (kx, ky) about pivot point (0, 0).
* @param kx horizontal skew factor
* @param ky vertical skew factor
* @return Matrix with skew
*/
static Matrix MakeSkew(float kx, float ky) {
Matrix m = {};
m.setSkew(kx, ky);
return m;
}

/**
* Sets Matrix to rotate by |degrees| about a pivot point at (0, 0).
* @param degrees rotation angle in degrees (positive rotates clockwise)
* @return Matrix with rotation
*/
static Matrix MakeRotate(float degrees) {
Matrix m = {};
m.setRotate(degrees);
return m;
}

/**
* Sets Matrix to rotate by |degrees| about a pivot point at (px, py).
* @param degrees rotation angle in degrees (positive rotates clockwise)
* @param px pivot on x-axis
* @param py pivot on y-axis
* @return Matrix with rotation
*/
static Matrix MakeRotate(float degrees, float px, float py) {
Matrix m = {};
m.setRotate(degrees, px, py);
return m;
}

/**
* Sets Matrix to:
*
Expand All @@ -103,6 +139,17 @@ class Matrix {
return m;
}

/**
* Returns reference to const identity Matrix. Returned Matrix is set to:
*
* | 1 0 0 |
* | 0 1 0 |
* | 0 0 1 |
*
* @return const identity Matrix
*/
static const Matrix& I();

/**
* Returns true if Matrix is identity. The identity matrix is:
*
Expand Down Expand Up @@ -661,6 +708,11 @@ class Matrix {
return !(a == b);
}

/**
* Returns Matrix A multiplied by Matrix B.
*/
friend Matrix operator*(const Matrix& a, const Matrix& b);

/**
* Returns the minimum scale factor of the Matrix by decomposing the scaling and skewing elements.
* The scale factor is an absolute value and may not align with the x/y axes. Returns -1 if the
Expand All @@ -687,17 +739,6 @@ class Matrix {
*/
bool isFinite() const;

/**
* Returns reference to const identity Matrix. Returned Matrix is set to:
*
* | 1 0 0 |
* | 0 1 0 |
* | 0 0 1 |
*
* @return const identity Matrix
*/
static const Matrix& I();

private:
float values[6];
/**
Expand Down
2 changes: 1 addition & 1 deletion include/tgfx/core/Paint.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ class Paint {
bool antiAlias = true;
PaintStyle style = PaintStyle::Fill;
Color color = Color::White();
Stroke stroke = Stroke(0);
Stroke stroke = {};
std::shared_ptr<Shader> shader = nullptr;
std::shared_ptr<MaskFilter> maskFilter = nullptr;
std::shared_ptr<ColorFilter> colorFilter = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion include/tgfx/core/Stroke.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class Stroke {
/**
* The thickness of the pen used to outline the paths or glyphs.
*/
float width = 1.0;
float width = 0.0f;

/**
* The geometry drawn at the beginning and end of strokes.
Expand Down
45 changes: 19 additions & 26 deletions src/core/Canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,23 @@ void Canvas::restore() {
}

void Canvas::translate(float dx, float dy) {
drawContext->translate(dx, dy);
drawContext->concat(Matrix::MakeTrans(dx, dy));
}

void Canvas::scale(float sx, float sy) {
drawContext->scale(sx, sy);
drawContext->concat(Matrix::MakeScale(sx, sy));
}

void Canvas::rotate(float degrees) {
drawContext->rotate(degrees);
drawContext->concat(Matrix::MakeRotate(degrees));
}

void Canvas::rotate(float degress, float px, float py) {
drawContext->rotate(degress, px, py);
drawContext->concat(Matrix::MakeRotate(degress, px, py));
}

void Canvas::skew(float sx, float sy) {
drawContext->skew(sx, sy);
drawContext->concat(Matrix::MakeSkew(sx, sy));
}

void Canvas::concat(const Matrix& matrix) {
Expand Down Expand Up @@ -224,44 +224,35 @@ void Canvas::drawImage(std::shared_ptr<Image> image, float left, float top, cons

void Canvas::drawImage(std::shared_ptr<Image> image, const Matrix& matrix, const Paint* paint) {
auto sampling = GetDefaultSamplingOptions(image);
drawImage(std::move(image), sampling, paint, &matrix);
drawImage(std::move(image), sampling, paint, matrix);
}

void Canvas::drawImage(std::shared_ptr<Image> image, const Paint* paint) {
auto sampling = GetDefaultSamplingOptions(image);
drawImage(std::move(image), sampling, paint, nullptr);
drawImage(std::move(image), sampling, paint, Matrix::I());
}

void Canvas::drawImage(std::shared_ptr<Image> image, SamplingOptions sampling, const Paint* paint) {
drawImage(std::move(image), sampling, paint, nullptr);
drawImage(std::move(image), sampling, paint, Matrix::I());
}

void Canvas::drawImage(std::shared_ptr<Image> image, SamplingOptions sampling, const Paint* paint,
const Matrix* extraMatrix) {
Matrix extraMatrix) {
if (image == nullptr || (paint && paint->nothingToDraw())) {
return;
}
auto oldMatrix = drawContext->getMatrix();
auto matrixChanged = extraMatrix != nullptr;
if (extraMatrix) {
drawContext->concat(*extraMatrix);
}
auto imageFilter = paint ? paint->getImageFilter() : nullptr;
if (imageFilter != nullptr) {
auto offset = Point::Zero();
image = image->makeWithFilter(std::move(imageFilter), &offset);
if (image == nullptr) {
return;
}
matrixChanged = true;
drawContext->translate(offset.x, offset.y);
extraMatrix.preTranslate(offset.x, offset.y);
}
auto rect = Rect::MakeWH(image->width(), image->height());
auto style = CreateFillStyle(std::move(image), sampling, paint);
drawRect(rect, style);
if (matrixChanged) {
drawContext->setMatrix(oldMatrix);
}
drawRect(rect, style, &extraMatrix);
}

void Canvas::drawSimpleText(const std::string& text, float x, float y, const tgfx::Font& font,
Expand All @@ -271,12 +262,13 @@ void Canvas::drawSimpleText(const std::string& text, float x, float y, const tgf
}
auto glyphRun = SimpleTextShaper::Shape(text, font);
if (x != 0 || y != 0) {
drawContext->translate(x, y);
drawContext->save();
translate(x, y);
}
auto style = CreateFillStyle(paint);
drawContext->drawGlyphRun(std::move(glyphRun), style, paint.getStroke());
if (x != 0 || y != 0) {
drawContext->translate(-x, -y);
drawContext->restore();
}
}

Expand Down Expand Up @@ -311,17 +303,18 @@ void Canvas::drawAtlas(std::shared_ptr<Image> atlas, const Matrix matrix[], cons
}

void Canvas::drawRect(const Rect& rect, const FillStyle& style, const Matrix* extraMatrix) {
auto oldMatrix = drawContext->getMatrix();
if (extraMatrix) {
auto hasExtraMatrix = extraMatrix && !extraMatrix->isIdentity();
if (hasExtraMatrix) {
drawContext->save();
drawContext->concat(*extraMatrix);
}
if (surface) {
auto discardContent = wouldOverwriteEntireSurface(rect, style);
surface->aboutToDraw(discardContent);
}
drawContext->drawRect(rect, style);
if (extraMatrix) {
drawContext->setMatrix(oldMatrix);
if (hasExtraMatrix) {
drawContext->restore();
}
}

Expand Down
28 changes: 8 additions & 20 deletions src/core/DrawContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,20 @@ void DrawContext::save() {
stack.push(state);
}

void DrawContext::restore() {
bool DrawContext::restore() {
if (stack.empty()) {
return;
return false;
}
state = stack.top();
stack.pop();
return true;
}

void DrawContext::translate(float dx, float dy) {
state.matrix.preTranslate(dx, dy);
}

void DrawContext::scale(float sx, float sy) {
state.matrix.preScale(sx, sy);
}

void DrawContext::rotate(float degrees) {
state.matrix.preRotate(degrees);
}

void DrawContext::rotate(float degress, float px, float py) {
state.matrix.preRotate(degress, px, py);
}

void DrawContext::skew(float sx, float sy) {
state.matrix.preSkew(sx, sy);
void DrawContext::restoreToCount(size_t saveCount) {
auto n = stack.size() - saveCount;
for (size_t i = 0; i < n; i++) {
restore();
}
}

void DrawContext::concat(const Matrix& matrix) {
Expand Down
61 changes: 17 additions & 44 deletions src/core/DrawContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,70 +42,43 @@ class DrawContext {
/**
* Returns the current total matrix.
*/
virtual const Matrix& getMatrix() const {
const Matrix& getMatrix() const {
return state.matrix;
}

/**
* Returns the current total clip Path.
*/
virtual const Path& getClip() const {
const Path& getClip() const {
return state.clip;
}

/**
* Saves matrix and clip. Calling restore() discards changes to them, restoring them to their
* state when save() was called. Saved Canvas state is put on a stack, multiple calls to save()
* should be balanced by an equal number of calls to restore().
*/
virtual void save();

/**
* Removes changes to matrix and clip since Canvas state was last saved. The state is removed from
* the stack. Does nothing if the stack is empty.
*/
virtual void restore();

/**
* Translates the current matrix by dx along the x-axis and dy along the y-axis. Mathematically,
* it replaces the current matrix with a translation matrix premultiplied with the current matrix.
* This has the effect of moving the drawing by (dx, dy) before transforming the result with the
* current matrix.
*/
virtual void translate(float dx, float dy);

/**
* Scales the current matrix by sx along the x-axis and sy along the y-axis. Mathematically, it
* replaces the current matrix with a scale matrix premultiplied with the current matrix. This has
* the effect of scaling the drawing by (sx, sy) before transforming the result with the current
* matrix.
* Returns the number of saved states. This is the number of times save() has been called minus
* the number of times restore() has been called.
*/
virtual void scale(float sx, float sy);
size_t getSaveCount() const {
return stack.size();
}

/**
* Rotates the current matrix by degrees. Positive values rotate the drawing clockwise.
* Mathematically, it replaces the current matrix with a rotation matrix premultiplied with the
* current matrix. This has the effect of rotating the drawing by degrees before transforming the
* result with the current matrix.
* Restores state to the specified saveCount. If saveCount is greater than the number of saved
* states, this method does nothing.
*/
virtual void rotate(float degrees);
void restoreToCount(size_t saveCount);

/**
* Rotates the current matrix by degrees around the point (px, py). Positive values rotate the
* drawing clockwise. Mathematically, it replaces the current matrix with a rotation matrix
* premultiplied with the current matrix. This has the effect of rotating the drawing around the
* point (px, py) by degrees before transforming the result with the current matrix.
* Saves matrix and clip. Calling restore() discards changes to them, restoring them to their
* state when save() was called. Saved Canvas state is put on a stack, multiple calls to save()
* should be balanced by an equal number of calls to restore().
*/
virtual void rotate(float degress, float px, float py);
virtual void save();

/**
* Skews the current matrix by sx along the x-axis and sy along the y-axis. A positive value of sx
* skews the drawing right as y-axis values increase; a positive value of sy skews the drawing
* down as x-axis values increase. Mathematically, it replaces the current matrix with a skew
* matrix premultiplied with the current matrix. This has the effect of skewing the drawing by
* (sx, sy) before transforming the result with the current matrix.
* Removes changes to matrix and clip since Canvas state was last saved. The state is removed from
* the stack. Does nothing if the stack is empty.
*/
virtual void skew(float sx, float sy);
virtual bool restore();

/**
* Replaces the current Matrix with matrix premultiplied with the existing one. This has the
Expand Down
6 changes: 6 additions & 0 deletions src/core/Matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ bool operator==(const Matrix& a, const Matrix& b) {
ma[5] == mb[5];
}

Matrix operator*(const Matrix& a, const Matrix& b) {
Matrix result = {};
result.setConcat(a, b);
return result;
}

void Matrix::setAll(float scaleX, float skewX, float transX, float skewY, float scaleY,
float transY) {
values[SCALE_X] = scaleX;
Expand Down

0 comments on commit 17e7b62

Please sign in to comment.