mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Flesh out the Painting API a bit.
This exposes most methods from Skia's C canvas API to Dart. For now, SkRect and SkMatrix are represented simply as an array of floats, which requires a conversion at the bindings layer. More complex types like SkPath are still TODO. R=eseidel@chromium.org Review URL: https://codereview.chromium.org/1144483002
This commit is contained in:
parent
1eb17996fb
commit
6729917a2d
@ -13,6 +13,14 @@
|
||||
|
||||
namespace blink {
|
||||
|
||||
SkRect toSkRect(const Vector<float>& rect)
|
||||
{
|
||||
ASSERT(rect.size() == 4);
|
||||
SkRect sk_rect;
|
||||
sk_rect.set(rect[0], rect[1], rect[2], rect[3]);
|
||||
return sk_rect;
|
||||
}
|
||||
|
||||
Canvas::Canvas(const FloatSize& size)
|
||||
: m_size(size)
|
||||
{
|
||||
@ -24,7 +32,113 @@ Canvas::~Canvas()
|
||||
{
|
||||
}
|
||||
|
||||
void Canvas::drawCircle(double x, double y, double radius, Paint* paint)
|
||||
void Canvas::save()
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->save();
|
||||
}
|
||||
|
||||
void Canvas::saveLayer(const Vector<float>& bounds, const Paint* paint)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(m_displayList->isRecording());
|
||||
SkRect sk_bounds;
|
||||
if (!bounds.isEmpty())
|
||||
sk_bounds = toSkRect(bounds);
|
||||
m_canvas->saveLayer(!bounds.isEmpty() ? &sk_bounds : nullptr,
|
||||
paint ? &paint->paint() : nullptr);
|
||||
}
|
||||
|
||||
void Canvas::restore()
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->restore();
|
||||
}
|
||||
|
||||
void Canvas::translate(float dx, float dy)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->translate(dx, dy);
|
||||
}
|
||||
|
||||
void Canvas::scale(float sx, float sy)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->scale(sx, sy);
|
||||
}
|
||||
|
||||
void Canvas::rotateDegrees(float degrees)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->rotate(degrees);
|
||||
}
|
||||
|
||||
void Canvas::skew(float sx, float sy)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->skew(sx, sy);
|
||||
}
|
||||
|
||||
void Canvas::concat(const Vector<float>& matrix)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(m_displayList->isRecording());
|
||||
ASSERT(matrix.size() == 9);
|
||||
SkMatrix sk_matrix;
|
||||
sk_matrix.set9(matrix.data());
|
||||
m_canvas->concat(sk_matrix);
|
||||
}
|
||||
|
||||
void Canvas::clipRect(const Vector<float>& rect)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->clipRect(toSkRect(rect));
|
||||
}
|
||||
|
||||
void Canvas::drawPaint(Paint* paint)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(paint);
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->drawPaint(paint->paint());
|
||||
}
|
||||
|
||||
void Canvas::drawRect(const Vector<float>& rect, const Paint* paint)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(paint);
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->drawRect(toSkRect(rect), paint->paint());
|
||||
}
|
||||
|
||||
void Canvas::drawOval(const Vector<float>& rect, const Paint* paint)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
ASSERT(paint);
|
||||
ASSERT(m_displayList->isRecording());
|
||||
m_canvas->drawOval(toSkRect(rect), paint->paint());
|
||||
}
|
||||
|
||||
void Canvas::drawCircle(float x, float y, float radius, Paint* paint)
|
||||
{
|
||||
if (!m_canvas)
|
||||
return;
|
||||
|
||||
@ -22,10 +22,25 @@ public:
|
||||
|
||||
// Width/Height define a culling rect which Skia may use for optimizing
|
||||
// out draw calls issued outside the rect.
|
||||
double width() const { return m_size.width(); }
|
||||
double height() const { return m_size.height(); }
|
||||
float width() const { return m_size.width(); }
|
||||
float height() const { return m_size.height(); }
|
||||
|
||||
void drawCircle(double x, double y, double radius, Paint* paint);
|
||||
void save();
|
||||
void saveLayer(const Vector<float>& bounds, const Paint* paint);
|
||||
void restore();
|
||||
|
||||
void translate(float dx, float dy);
|
||||
void scale(float sx, float sy);
|
||||
void rotateDegrees(float degrees);
|
||||
void skew(float sx, float sy);
|
||||
void concat(const Vector<float>& matrix);
|
||||
|
||||
void clipRect(const Vector<float>& rect);
|
||||
|
||||
void drawPaint(Paint* paint);
|
||||
void drawRect(const Vector<float>& rect, const Paint* paint);
|
||||
void drawOval(const Vector<float>& rect, const Paint* paint);
|
||||
void drawCircle(float x, float y, float radius, Paint* paint);
|
||||
|
||||
protected:
|
||||
PassRefPtr<DisplayList> finishRecording();
|
||||
|
||||
@ -1,11 +1,28 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// TODO(mpcomplete): Figure out a better SkMatrix/SkRect representation.
|
||||
interface Canvas {
|
||||
// Height and width are used for culling optimizations and do not necessarily
|
||||
// imply that the Canvas is backed by a buffer with any specific bounds.
|
||||
readonly attribute double height;
|
||||
readonly attribute double width;
|
||||
readonly attribute float height;
|
||||
readonly attribute float width;
|
||||
|
||||
void drawCircle(double x, double y, double radius, Paint paint);
|
||||
void save();
|
||||
void saveLayer(float[] bounds4 /* optional */, Paint paint /* optional */);
|
||||
void restore();
|
||||
|
||||
void translate(float dx, float dy);
|
||||
void scale(float sx, float sy);
|
||||
void rotateDegrees(float degrees);
|
||||
void skew(float sx, float sy);
|
||||
void concat(float[] matrix9);
|
||||
|
||||
void clipRect(float[] rect4);
|
||||
|
||||
void drawPaint(Paint paint);
|
||||
void drawRect(float[] rect4, Paint paint);
|
||||
void drawOval(float[] rect4, Paint paint);
|
||||
void drawCircle(float x, float y, float radius, Paint paint);
|
||||
};
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#define SKY_ENGINE_CORE_PAINTING_PAINTINGCONTEXT_H_
|
||||
|
||||
#include "sky/engine/core/painting/Canvas.h"
|
||||
#include "sky/engine/wtf/Vector.h"
|
||||
|
||||
namespace blink {
|
||||
class Element;
|
||||
|
||||
46
examples/raw/painting.sky
Normal file
46
examples/raw/painting.sky
Normal file
@ -0,0 +1,46 @@
|
||||
<sky>
|
||||
<style>
|
||||
div {
|
||||
height: 200px;
|
||||
background-color: lightblue;
|
||||
}
|
||||
</style>
|
||||
<div id="canvas" />
|
||||
<script>
|
||||
import 'dart:math' as math;
|
||||
import 'dart:sky';
|
||||
|
||||
void main() {
|
||||
var element = document.getElementById('canvas');
|
||||
element.requestPaint((PaintingContext context) {
|
||||
Paint paint = new Paint();
|
||||
double radius = math.min(context.width, context.height) / 2.0;
|
||||
|
||||
context.save();
|
||||
|
||||
context.clipRect([0.0, 0.0, context.width, radius]);
|
||||
|
||||
context.translate(context.width / 2.0, context.height / 2.0);
|
||||
paint.setARGB(128, 255, 0, 255);
|
||||
context.rotateDegrees(45.0);
|
||||
context.drawRect([-radius, -radius, radius, radius], paint);
|
||||
|
||||
// Scale x and y by 0.5.
|
||||
var scaleMatrix = [
|
||||
0.5, 0.0, 0.0,
|
||||
0.0, 0.5, 0.0,
|
||||
0.0, 0.0, 1.0
|
||||
];
|
||||
context.concat(scaleMatrix);
|
||||
paint.setARGB(128, 0, 255, 0);
|
||||
context.drawCircle(0.0, 0.0, radius, paint);
|
||||
|
||||
context.restore();
|
||||
|
||||
context.drawCircle(0.0, 0.0, radius, paint);
|
||||
|
||||
context.commit();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</sky>
|
||||
Loading…
x
Reference in New Issue
Block a user