Add support for Canvas.setMatrix and getTotalMatrix

Part of fixing issue #138.

R=abarth@google.com
This commit is contained in:
Eric Seidel
2015-07-23 11:11:09 -07:00
parent 5fcf9e68b5
commit 4e17ceefdb
8 changed files with 119 additions and 19 deletions
@@ -646,6 +646,7 @@ DART_SET_RETURN_VALUE = {
'ArrayBuffer': 'Dart_SetReturnValue(args, DartUtilities::arrayBufferToDart({cpp_value}))',
'TypedList': 'Dart_SetReturnValue(args, DartUtilities::arrayBufferViewToDart({cpp_value}))',
'Color': 'DartConverter<CanvasColor>::SetReturnValue(args, {cpp_value})',
'Float32List': 'DartConverter<Float32List>::SetReturnValue(args, {cpp_value})',
}
+55 -17
View File
@@ -75,29 +75,67 @@ void Canvas::skew(float sx, float sy)
m_canvas->skew(sx, sy);
}
void Canvas::concat(const Float32List& matrix4)
// Mappings from SkMatrix-index to input-index.
static const int kSkMatrixIndexToMatrix4Index[] = {
0, 4, 12,
1, 5, 13,
3, 7, 15,
};
SkMatrix toSkMatrix(const Float32List& matrix4, ExceptionState& es)
{
ASSERT(matrix4.data());
SkMatrix sk_matrix;
if (matrix4.num_elements() != 16) {
es.ThrowTypeError("Incorrect number of elements in matrix.");
return sk_matrix;
}
for (intptr_t i = 0; i < 9; ++i)
sk_matrix[i] = matrix4[kSkMatrixIndexToMatrix4Index[i]];
return sk_matrix;
}
Float32List toMatrix4(const SkMatrix& sk_matrix)
{
Float32List matrix4(Dart_NewTypedData(Dart_TypedData_kFloat32, 16));
for (intptr_t i = 0; i < 9; ++i)
matrix4[kSkMatrixIndexToMatrix4Index[i]] = sk_matrix[i];
matrix4[10] = 1.0; // Identity along the z axis.
return matrix4;
}
void Canvas::concat(const Float32List& matrix4, ExceptionState& es)
{
if (!m_canvas)
return es.ThrowTypeError("No canvas");
SkMatrix sk_matrix = toSkMatrix(matrix4, es);
if (es.had_exception())
return;
ASSERT(matrix4.data());
// TODO(mpcomplete): how can we raise an error in this case?
if (matrix4.num_elements() != 16)
return;
SkMatrix sk_matrix;
// Mappings from SkMatrix-index to input-index.
static const int kMappings[] = {
0, 4, 12,
1, 5, 13,
3, 7, 15,
};
for (intptr_t i = 0; i < 9; ++i)
sk_matrix[i] = matrix4.data()[kMappings[i]];
m_canvas->concat(sk_matrix);
}
void Canvas::setMatrix(const Float32List& matrix4, ExceptionState& es)
{
if (!m_canvas)
return es.ThrowTypeError("No canvas");
SkMatrix sk_matrix = toSkMatrix(matrix4, es);
if (es.had_exception())
return;
m_canvas->setMatrix(sk_matrix);
}
Float32List Canvas::getTotalMatrix() const
{
// Maybe we should throw an exception instead of returning an empty matrix?
SkMatrix sk_matrix;
if (m_canvas)
sk_matrix = m_canvas->getTotalMatrix();
return toMatrix4(sk_matrix);
}
void Canvas::clipRect(const Rect& rect)
{
if (!m_canvas)
+4 -1
View File
@@ -68,7 +68,10 @@ public:
void scale(float sx, float sy);
void rotate(float radians);
void skew(float sx, float sy);
void concat(const Float32List& matrix4);
void concat(const Float32List& matrix4, ExceptionState&);
void setMatrix(const Float32List& matrix4, ExceptionState&);
Float32List getTotalMatrix() const;
void clipRect(const Rect& rect);
void clipRRect(const RRect* rrect);
+4 -1
View File
@@ -16,7 +16,10 @@
void scale(float sx, float sy);
void rotate(float radians);
void skew(float sx, float sy);
void concat(Float32List matrix4);
[RaisesException] void concat(Float32List matrix4);
[RaisesException] void setMatrix(Float32List matrix4);
Float32List getTotalMatrix();
void clipRect(Rect rect);
void clipRRect(RRect rrect);
+6
View File
@@ -43,4 +43,10 @@ Float32List DartConverter<Float32List>::FromArgumentsWithNullCheck(
return result;
}
void DartConverter<Float32List>::SetReturnValue(Dart_NativeArguments args,
Float32List val) {
Dart_SetReturnValue(args, val.dart_handle());
}
} // namespace blink
+17
View File
@@ -21,8 +21,23 @@ class Float32List {
Float32List(Float32List&& other);
~Float32List();
float& at(intptr_t i)
{
CHECK(i < num_elements_);
return data_[i];
}
const float& at(intptr_t i) const
{
CHECK(i < num_elements_);
return data_[i];
}
float& operator[](intptr_t i) { return at(i); }
const float& operator[](intptr_t i) const { return at(i); }
const float* data() const { return data_; }
intptr_t num_elements() const { return num_elements_; }
Dart_Handle dart_handle() const { return dart_handle_; }
private:
float* data_;
@@ -34,6 +49,8 @@ class Float32List {
template <>
struct DartConverter<Float32List> {
static void SetReturnValue(Dart_NativeArguments args, Float32List val);
static Float32List FromArgumentsWithNullCheck(Dart_NativeArguments args,
int index,
Dart_Handle& exception);
+6
View File
@@ -0,0 +1,6 @@
unittest-suite-wait-for-done
PASS: matrix access should work
All 1 tests passed.
unittest-suite-success
DONE
+26
View File
@@ -0,0 +1,26 @@
import "../resources/dom_utils.dart";
import "../resources/third_party/unittest/unittest.dart";
import "../resources/unit.dart";
import "dart:sky";
import 'package:vector_math/vector_math.dart';
void main() {
initUnit();
PictureRecorder recorder = new PictureRecorder();
Canvas canvas = new Canvas(recorder, new Rect.fromLTRB(0.0, 0.0, 100.0, 100.0));
test("matrix access should work", () {
// Matrix equality doesn't work!
// https://github.com/google/vector_math.dart/issues/147
expect(canvas.getTotalMatrix(), equals(new Matrix4.identity().storage));
Matrix4 matrix = new Matrix4.identity();
// Round-tripping through getTotalMatrix will lose the z value
// So only scale to 1x in the z direction.
matrix.scale(2.0, 2.0, 1.0);
canvas.setMatrix(matrix.storage);
expect(canvas.getTotalMatrix(), equals(matrix.storage));
});
}