blob: cc9a9e5bbf193690d7a6c440123b9a69d7bcb86d [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/config.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/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(const FloatSize& size)
: m_size(size)
{
m_displayList = adoptRef(new DisplayList);
m_canvas = m_displayList->beginRecording(expandedIntSize(m_size));
}
Canvas::~Canvas()
{
}
void Canvas::save()
{
if (!m_canvas)
return;
ASSERT(m_displayList->isRecording());
m_canvas->save();
}
void Canvas::saveLayer(const Rect& bounds, const Paint* paint)
{
if (!m_canvas)
return;
ASSERT(m_displayList->isRecording());
m_canvas->saveLayer(!bounds.is_null ? &bounds.sk_rect : 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::rotate(float radians)
{
if (!m_canvas)
return;
ASSERT(m_displayList->isRecording());
m_canvas->rotate(radians * 180.0/M_PI);
}
void Canvas::skew(float sx, float sy)
{
if (!m_canvas)
return;
ASSERT(m_displayList->isRecording());
m_canvas->skew(sx, sy);
}
void Canvas::concat(const Float32List& matrix4)
{
if (!m_canvas)
return;
ASSERT(m_displayList->isRecording());
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::clipRect(const Rect& rect)
{
if (!m_canvas)
return;
ASSERT(m_displayList->isRecording());
m_canvas->clipRect(rect.sk_rect);
}
void Canvas::clipRRect(const RRect* rrect)
{
if (!m_canvas)
return;
ASSERT(m_displayList->isRecording());
m_canvas->clipRRect(rrect->rrect());
}
void Canvas::clipPath(const CanvasPath* path)
{
if (!m_canvas)
return;
ASSERT(m_displayList->isRecording());
m_canvas->clipPath(path->path());
}
void Canvas::drawLine(float x0, float y0, float x1, float y1, const Paint* paint)
{
if (!m_canvas)
return;
ASSERT(paint);
ASSERT(m_displayList->isRecording());
m_canvas->drawLine(x0, y0, x1, y1, paint->paint());
}
void Canvas::drawPicture(Picture* picture)
{
if (!m_canvas)
return;
ASSERT(picture);
ASSERT(m_displayList->isRecording());
m_canvas->drawPicture(picture->toSkia());
}
void Canvas::drawPaint(const Paint* paint)
{
if (!m_canvas)
return;
ASSERT(paint);
ASSERT(m_displayList->isRecording());
m_canvas->drawPaint(paint->paint());
}
void Canvas::drawRect(const Rect& rect, const Paint* paint)
{
if (!m_canvas)
return;
ASSERT(paint);
ASSERT(m_displayList->isRecording());
m_canvas->drawRect(rect.sk_rect, paint->paint());
}
void Canvas::drawRRect(const RRect* rrect, const Paint* paint)
{
if (!m_canvas)
return;
ASSERT(rrect);
ASSERT(paint);
ASSERT(m_displayList->isRecording());
m_canvas->drawRRect(rrect->rrect(), paint->paint());
}
void Canvas::drawOval(const Rect& rect, const Paint* paint)
{
if (!m_canvas)
return;
ASSERT(paint);
ASSERT(m_displayList->isRecording());
m_canvas->drawOval(rect.sk_rect, paint->paint());
}
void Canvas::drawCircle(float x, float y, float radius, const Paint* paint)
{
if (!m_canvas)
return;
ASSERT(paint);
ASSERT(m_displayList->isRecording());
m_canvas->drawCircle(x, y, radius, paint->paint());
}
void Canvas::drawPath(const CanvasPath* path, const Paint* paint)
{
if (!m_canvas)
return;
ASSERT(path);
ASSERT(paint);
ASSERT(m_displayList->isRecording());
m_canvas->drawPath(path->path(), paint->paint());
}
void Canvas::drawImage(const CanvasImage* image,
float x,
float y,
const Paint* paint) {
if (!m_canvas)
return;
ASSERT(image);
ASSERT(m_displayList->isRecording());
m_canvas->drawBitmap(image->bitmap(), x, y, &paint->paint());
}
PassRefPtr<DisplayList> Canvas::finishRecording()
{
if (!isRecording())
return nullptr;
m_canvas = nullptr;
m_displayList->endRecording();
return m_displayList.release();
}
} // namespace blink