mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
Add support for Canvas.setMatrix and getTotalMatrix
Part of fixing issue #138. R=abarth@google.com
This commit is contained in:
@@ -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})',
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
unittest-suite-wait-for-done
|
||||
PASS: matrix access should work
|
||||
|
||||
All 1 tests passed.
|
||||
unittest-suite-success
|
||||
DONE
|
||||
@@ -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));
|
||||
});
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user