Factor code to rotate a canvas about a point.

SkMatrix::scale and ::rotate take a point around which to scale or rotate.
Canvas lacks these helpers, so the code to rotate a canvas around a
point has been duplicated many times. Factor all of these
implementations into SkCanvas::rotate.

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2142033002

Review-Url: https://codereview.chromium.org/2142033002
This commit is contained in:
bungeman 2016-07-12 15:01:19 -07:00 committed by Commit bot
parent 2edf0c6a71
commit 7438bfc080
14 changed files with 27 additions and 86 deletions

View File

@ -239,10 +239,7 @@ protected:
if (fFlags & kRotate_Flag) {
const SkScalar x = SkIntToScalar(dim.fWidth) / 2;
const SkScalar y = SkIntToScalar(dim.fHeight) / 2;
canvas->translate(x, y);
canvas->rotate(SkIntToScalar(35));
canvas->translate(-x, -y);
canvas->rotate(SkIntToScalar(35), x, y);
}
INHERITED::onDraw(loops, canvas);
}

View File

@ -33,14 +33,6 @@ protected:
return SkISize::Make(1024, 768);
}
static void rotate_about(SkCanvas* canvas,
SkScalar degrees,
SkScalar px, SkScalar py) {
canvas->translate(px, py);
canvas->rotate(degrees);
canvas->translate(-px, -py);
}
virtual void onDraw(SkCanvas* inputCanvas) override {
SkScalar textSizes[] = { 9.0f, 9.0f*2.0f, 9.0f*5.0f, 9.0f*2.0f*5.0f };
SkScalar scales[] = { 2.0f*5.0f, 5.0f, 2.0f, 1.0f };
@ -95,7 +87,7 @@ protected:
SkAutoCanvasRestore acr(canvas, true);
canvas->translate(SkIntToScalar(10 + i * 200), -80);
rotate_about(canvas, SkIntToScalar(i * 5), rotX, rotY);
canvas->rotate(SkIntToScalar(i * 5), rotX, rotY);
for (int ps = 6; ps <= 32; ps += 3) {
paint.setTextSize(SkIntToScalar(ps));
canvas->drawText(text, textLen, rotX, rotY, paint);

View File

@ -15,9 +15,6 @@ public:
this->setBGColor(0xFFFFFFFF);
}
virtual ~FontScalerGM() {
}
protected:
SkString onShortName() override {
@ -30,14 +27,6 @@ protected:
return SkISize::Make(1450, 750);
}
static void rotate_about(SkCanvas* canvas,
SkScalar degrees,
SkScalar px, SkScalar py) {
canvas->translate(px, py);
canvas->rotate(degrees);
canvas->translate(-px, -py);
}
void onDraw(SkCanvas* canvas) override {
SkPaint paint;
@ -59,7 +48,7 @@ protected:
SkAutoCanvasRestore acr(canvas, true);
canvas->translate(SkIntToScalar(50 + i * 230),
SkIntToScalar(20));
rotate_about(canvas, SkIntToScalar(i * 5), x, y * 10);
canvas->rotate(SkIntToScalar(i * 5), x, y * 10);
{
SkPaint p;

View File

@ -19,8 +19,6 @@ public:
this->setBGColor(0xFFFFFFFF);
}
virtual ~FontScalerDistortableGM() { }
protected:
SkString onShortName() override {
@ -31,12 +29,6 @@ protected:
return SkISize::Make(550, 700);
}
static void rotate_about(SkCanvas* canvas, SkScalar degrees, SkScalar px, SkScalar py) {
canvas->translate(px, py);
canvas->rotate(degrees);
canvas->translate(-px, -py);
}
void onDraw(SkCanvas* canvas) override {
SkPaint paint;
paint.setAntiAlias(true);
@ -63,7 +55,7 @@ protected:
SkAutoCanvasRestore acr(canvas, true);
canvas->translate(SkIntToScalar(30 + i * 100), SkIntToScalar(20));
rotate_about(canvas, SkIntToScalar(i * 5), x, y * 10);
canvas->rotate(SkIntToScalar(i * 5), x, y * 10);
{
SkPaint p;

View File

@ -140,18 +140,14 @@ DEF_SIMPLE_GM(rotate_imagefilter, canvas, 500, 500) {
canvas->translate(150, 0);
canvas->save();
canvas->translate(100, 100);
canvas->rotate(30);
canvas->translate(-100, -100);
canvas->rotate(30, 100, 100);
canvas->drawRect(r, paint);
canvas->restore();
paint.setAntiAlias(true);
canvas->translate(150, 0);
canvas->save();
canvas->translate(100, 100);
canvas->rotate(30);
canvas->translate(-100, -100);
canvas->rotate(30, 100, 100);
canvas->drawRect(r, paint);
canvas->restore();

View File

@ -290,12 +290,6 @@ protected:
return SkISize::Make(W, H*2);
}
static void rotate(SkScalar angle, SkScalar px, SkScalar py, SkCanvas* canvas) {
SkMatrix matrix;
matrix.setRotate(angle, px, py);
canvas->concat(matrix);
}
void onDraw(SkCanvas* canvas) override {
canvas->drawColor(SK_ColorWHITE);
@ -316,7 +310,7 @@ protected:
for (int i = 0; i < N/2; i++) {
SkRect r;
rnd_rect(&r, &paint, rand);
rotate(SkIntToScalar(15), SW/2, SH/2, canvas);
canvas->rotate(SkIntToScalar(15), SW/2, SH/2);
canvas->drawPath(fPath, paint);
}
}

View File

@ -154,20 +154,9 @@ private:
typedef skiagm::GM INHERITED;
};
static void rotate_about(SkCanvas* canvas,
SkScalar degrees,
SkScalar px, SkScalar py) {
canvas->translate(px, py);
canvas->rotate(degrees);
canvas->translate(-px, -py);
}
class TypefaceRenderingGM : public skiagm::GM {
sk_sp<SkTypeface> fFace;
public:
TypefaceRenderingGM() { }
protected:
void onOnceBeforeDraw() override {
fFace = MakeResourceAsTypeface("/fonts/hintgasp.ttf");
@ -256,8 +245,8 @@ protected:
for (const bool& rotateABit : rotateABitTypes) {
SkAutoCanvasRestore acr(canvas, true);
if (rotateABit) {
rotate_about(canvas, 2, x + subpixel.offset.x(),
y + subpixel.offset.y());
canvas->rotate(2, x + subpixel.offset.x(),
y + subpixel.offset.y());
}
canvas->drawText("A", 1, x + subpixel.offset.x(),
y + subpixel.offset.y(), paint);

View File

@ -419,11 +419,18 @@ public:
*/
void scale(SkScalar sx, SkScalar sy);
/** Preconcat the current matrix with the specified rotation.
/** Preconcat the current matrix with the specified rotation about the origin.
@param degrees The amount to rotate, in degrees
*/
void rotate(SkScalar degrees);
/** Preconcat the current matrix with the specified rotation about a given point.
@param degrees The amount to rotate, in degrees
@param px The x coordinate of the point to rotate about.
@param py The y coordinate of the point to rotate about.
*/
void rotate(SkScalar degrees, SkScalar px, SkScalar py);
/** Preconcat the current matrix with the specified skew.
@param sx The amount to skew in X
@param sy The amount to skew in Y

View File

@ -1372,9 +1372,7 @@ void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
if (fRotate) {
SkScalar cx = this->width() / 2;
SkScalar cy = this->height() / 2;
canvas->translate(cx, cy);
canvas->rotate(gAnimTimer.scaled(10));
canvas->translate(-cx, -cy);
canvas->rotate(gAnimTimer.scaled(10), cx, cy);
}
if (fPerspAnim) {

View File

@ -87,17 +87,10 @@ protected:
path->close();
}
static void rotate(SkCanvas* canvas, SkScalar angle, SkScalar px, SkScalar py) {
canvas->translate(-px, -py);
canvas->rotate(angle);
canvas->translate(px, py);
}
virtual void onDrawContent(SkCanvas* canvas) {
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
// canvas->drawCircle(250, 250, 220, paint);
SkMatrix matrix;
matrix.setScale(SkIntToScalar(100), SkIntToScalar(100));
matrix.postTranslate(SkIntToScalar(200), SkIntToScalar(200));

View File

@ -37,10 +37,7 @@ static void draw_sweep(SkCanvas* c, int width, int height, SkScalar angle) {
colors, nullptr, SK_ARRAY_COUNT(colors)));
SkAutoCanvasRestore acr(c, true);
c->translate(r.centerX(), r.centerY());
c->rotate(angle);
c->translate(-r.centerX(), -r.centerY());
c->rotate(angle, r.centerX(), r.centerY());
SkRect bounds = r;
r.inset(p.getStrokeWidth(), p.getStrokeWidth());

View File

@ -44,7 +44,6 @@ public:
fFaces[i] = SkTypeface::MakeFromName(
gFaces[i].fName, SkFontStyle::FromOldStyle(gFaces[i].fStyle));
}
// this->setBGColor(0xFFDDDDDD);
}
protected:
@ -57,12 +56,6 @@ protected:
return this->INHERITED::onQuery(evt);
}
static void rotate_about(SkCanvas* canvas, SkScalar degrees, SkScalar px, SkScalar py) {
canvas->translate(px, py);
canvas->rotate(degrees);
canvas->translate(-px, -py);
}
virtual void onDrawContent(SkCanvas* canvas) {
SkPaint paint;
@ -100,7 +93,7 @@ protected:
SkAutoCanvasRestore acr(canvas, true);
canvas->translate(SkIntToScalar(50 + i * 230),
SkIntToScalar(20));
rotate_about(canvas, SkIntToScalar(i * 5), x, y * 10);
canvas->rotate(SkIntToScalar(i * 5), x, y * 10);
{
SkPaint p;

View File

@ -95,9 +95,7 @@ public:
fColor = floats_to_color(values);
canvas->save();
canvas->translate(fR.centerX(), fR.centerY());
canvas->rotate(values[4]);
canvas->translate(-fR.centerX(), -fR.centerY());
canvas->rotate(values[4], fR.centerX(), fR.centerY());
switch (res) {
case SkInterpolator::kFreezeEnd_Result:

View File

@ -1503,6 +1503,12 @@ void SkCanvas::rotate(SkScalar degrees) {
this->concat(m);
}
void SkCanvas::rotate(SkScalar degrees, SkScalar px, SkScalar py) {
SkMatrix m;
m.setRotate(degrees, px, py);
this->concat(m);
}
void SkCanvas::skew(SkScalar sx, SkScalar sy) {
SkMatrix m;
m.setSkew(sx, sy);