blob: 29ea72c5d3ac9a4850acc3771ee8c97406e8ffbf [file] [log] [blame]
// 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.
#include "math.h"
#include "sky/engine/core/painting/Canvas.h"
#include "sky/engine/core/dom/Document.h"
#include "sky/engine/core/dom/Element.h"
#include "sky/engine/core/painting/CanvasImage.h"
#include "sky/engine/core/painting/Matrix.h"
#include "sky/engine/core/painting/PaintingTasks.h"
#include "sky/engine/platform/geometry/IntRect.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace blink {
Canvas::Canvas(SkCanvas* skCanvas)
: m_canvas(skCanvas)
{
}
Canvas::~Canvas()
{
}
void Canvas::save()
{
if (!m_canvas)
return;
m_canvas->save();
}
void Canvas::saveLayer(const Rect& bounds, const Paint& paint)
{
if (!m_canvas)
return;
m_canvas->saveLayer(!bounds.is_null ? &bounds.sk_rect : nullptr,
paint.paint());
}
void Canvas::restore()
{
if (!m_canvas)
return;
m_canvas->restore();
}
int Canvas::getSaveCount()
{
if (!m_canvas)
return 0;
return m_canvas->getSaveCount();
}
void Canvas::translate(float dx, float dy)
{
if (!m_canvas)
return;
m_canvas->translate(dx, dy);
}
void Canvas::scale(float sx, float sy)
{
if (!m_canvas)
return;
m_canvas->scale(sx, sy);
}
void Canvas::rotate(float radians)
{
if (!m_canvas)
return;
m_canvas->rotate(radians * 180.0/M_PI);
}
void Canvas::skew(float sx, float sy)
{
if (!m_canvas)
return;
m_canvas->skew(sx, sy);
}
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;
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)
return;
m_canvas->clipRect(rect.sk_rect);
}
void Canvas::clipRRect(const RRect* rrect)
{
if (!m_canvas)
return;
m_canvas->clipRRect(rrect->rrect(), SkRegion::kIntersect_Op, true);
}
void Canvas::clipPath(const CanvasPath* path)
{
if (!m_canvas)
return;
m_canvas->clipPath(path->path(), SkRegion::kIntersect_Op, true);
}
void Canvas::drawColor(SkColor color, SkXfermode::Mode transferMode)
{
if (!m_canvas)
return;
m_canvas->drawColor(color, transferMode);
}
void Canvas::drawLine(const Point& p1, const Point& p2, const Paint& paint)
{
if (!m_canvas)
return;
m_canvas->drawLine(p1.sk_point.x(), p1.sk_point.y(), p2.sk_point.x(), p2.sk_point.y(), paint.sk_paint);
}
void Canvas::drawPaint(const Paint& paint)
{
if (!m_canvas)
return;
m_canvas->drawPaint(paint.sk_paint);
}
void Canvas::drawRect(const Rect& rect, const Paint& paint)
{
if (!m_canvas)
return;
m_canvas->drawRect(rect.sk_rect, paint.sk_paint);
}
void Canvas::drawRRect(const RRect* rrect, const Paint& paint)
{
if (!m_canvas)
return;
ASSERT(rrect);
m_canvas->drawRRect(rrect->rrect(), paint.sk_paint);
}
void Canvas::drawDRRect(const RRect* outer, const RRect* inner, const Paint& paint)
{
if (!m_canvas)
return;
ASSERT(outer);
ASSERT(inner);
m_canvas->drawDRRect(outer->rrect(), inner->rrect(), paint.sk_paint);
}
void Canvas::drawOval(const Rect& rect, const Paint& paint)
{
if (!m_canvas)
return;
m_canvas->drawOval(rect.sk_rect, paint.sk_paint);
}
void Canvas::drawCircle(const Point& c, float radius, const Paint& paint)
{
if (!m_canvas)
return;
m_canvas->drawCircle(c.sk_point.x(), c.sk_point.y(), radius, paint.sk_paint);
}
void Canvas::drawPath(const CanvasPath* path, const Paint& paint)
{
if (!m_canvas)
return;
ASSERT(path);
m_canvas->drawPath(path->path(), paint.sk_paint);
}
void Canvas::drawImage(const CanvasImage* image, const Point& p, const Paint& paint) {
if (!m_canvas)
return;
ASSERT(image);
m_canvas->drawImage(image->image(), p.sk_point.x(), p.sk_point.y(), paint.paint());
}
void Canvas::drawImageRect(const CanvasImage* image, Rect& src, Rect& dst, const Paint& paint) {
if (!m_canvas)
return;
ASSERT(image);
m_canvas->drawImageRect(image->image(), &src.sk_rect, dst.sk_rect, paint.paint());
}
void Canvas::drawPicture(Picture* picture)
{
if (!m_canvas)
return;
ASSERT(picture);
m_canvas->drawPicture(picture->toSkia());
}
void Canvas::drawDrawable(Drawable* drawable)
{
if (!m_canvas)
return;
ASSERT(drawable);
m_canvas->drawDrawable(drawable->toSkia());
}
void Canvas::drawPaintingNode(PaintingNode* paintingNode, const Point& p)
{
if (!m_canvas)
return;
ASSERT(paintingNode);
translate(p.sk_point.x(), p.sk_point.y());
m_canvas->drawDrawable(paintingNode->toSkia());
translate(-p.sk_point.x(), -p.sk_point.y());
}
void Canvas::drawAtlas(CanvasImage* atlas,
const Vector<RSTransform>& transforms, const Vector<Rect>& rects,
const Vector<SkColor>& colors, SkXfermode::Mode mode,
const Rect& cullRect, const Paint& paint, ExceptionState& es)
{
if (!m_canvas)
return;
RefPtr<SkImage> skImage = atlas->image();
if (transforms.size() != rects.size())
return es.ThrowRangeError("transforms and rects lengths must match");
if (colors.size() && colors.size() != rects.size())
return es.ThrowRangeError("if supplied, colors length must match that of transforms and rects");
Vector<SkRSXform> skXForms;
for (size_t x = 0; x < transforms.size(); x++) {
const RSTransform& transform = transforms[x];
if (transform.is_null)
return es.ThrowRangeError("transforms contained a null");
skXForms.append(transform.sk_xform);
}
Vector<SkRect> skRects;
for (size_t x = 0; x < rects.size(); x++) {
const Rect& rect = rects[x];
if (rect.is_null)
return es.ThrowRangeError("rects contained a null");
skRects.append(rect.sk_rect);
}
m_canvas->drawAtlas(
skImage.get(),
skXForms.data(),
skRects.data(),
colors.isEmpty() ? nullptr : colors.data(),
skXForms.size(),
mode,
cullRect.is_null ? nullptr : &cullRect.sk_rect,
paint.paint()
);
}
} // namespace blink