/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkMatrixParts.h"
#include "SkAnimateMaker.h"
#include "SkDrawMatrix.h"
#include "SkDrawRectangle.h"
#include "SkDrawPath.h"
SkMatrixPart::SkMatrixPart() : fMatrix(NULL) {
}
void SkMatrixPart::dirty() {
fMatrix->dirty();
}
SkDisplayable* SkMatrixPart::getParent() const {
return fMatrix;
}
bool SkMatrixPart::setParent(SkDisplayable* parent) {
SkASSERT(parent != NULL);
if (parent->isMatrix() == false)
return true;
fMatrix = (SkDrawMatrix*) parent;
return false;
}
#if SK_USE_CONDENSED_INFO == 0
const SkMemberInfo SkRotate::fInfo[] = {
SK_MEMBER(center, Point),
SK_MEMBER(degrees, Float)
};
#endif
DEFINE_GET_MEMBER(SkRotate);
SkRotate::SkRotate() : degrees(0) {
center.fX = center.fY = 0;
}
bool SkRotate::add() {
fMatrix->rotate(degrees, center);
return false;
}
#if SK_USE_CONDENSED_INFO == 0
const SkMemberInfo SkScale::fInfo[] = {
SK_MEMBER(center, Point),
SK_MEMBER(x, Float),
SK_MEMBER(y, Float)
};
#endif
DEFINE_GET_MEMBER(SkScale);
SkScale::SkScale() : x(SK_Scalar1), y(SK_Scalar1) {
center.fX = center.fY = 0;
}
bool SkScale::add() {
fMatrix->scale(x, y, center);
return false;
}
#if SK_USE_CONDENSED_INFO == 0
const SkMemberInfo SkSkew::fInfo[] = {
SK_MEMBER(center, Point),
SK_MEMBER(x, Float),
SK_MEMBER(y, Float)
};
#endif
DEFINE_GET_MEMBER(SkSkew);
SkSkew::SkSkew() : x(0), y(0) {
center.fX = center.fY = 0;
}
bool SkSkew::add() {
fMatrix->skew(x, y, center);
return false;
}
#if SK_USE_CONDENSED_INFO == 0
const SkMemberInfo SkTranslate::fInfo[] = {
SK_MEMBER(x, Float),
SK_MEMBER(y, Float)
};
#endif
DEFINE_GET_MEMBER(SkTranslate);
SkTranslate::SkTranslate() : x(0), y(0) {
}
bool SkTranslate::add() {
fMatrix->translate(x, y);
return false;
}
#if SK_USE_CONDENSED_INFO == 0
const SkMemberInfo SkFromPath::fInfo[] = {
SK_MEMBER(mode, FromPathMode),
SK_MEMBER(offset, Float),
SK_MEMBER(path, Path)
};
#endif
DEFINE_GET_MEMBER(SkFromPath);
SkFromPath::SkFromPath() :
mode(0), offset(0), path(NULL) {
}
SkFromPath::~SkFromPath() {
}
bool SkFromPath::add() {
if (path == NULL)
return true;
static const uint8_t gFlags[] = {
SkPathMeasure::kGetPosAndTan_MatrixFlag, // normal
SkPathMeasure::kGetTangent_MatrixFlag, // angle
SkPathMeasure::kGetPosition_MatrixFlag // position
};
if ((unsigned)mode >= SK_ARRAY_COUNT(gFlags))
return true;
SkMatrix result;
fPathMeasure.setPath(&path->getPath(), false);
if (fPathMeasure.getMatrix(offset, &result, (SkPathMeasure::MatrixFlags)gFlags[mode]))
fMatrix->set(result);
return false;
}
#if SK_USE_CONDENSED_INFO == 0
const SkMemberInfo SkRectToRect::fInfo[] = {
SK_MEMBER(destination, Rect),
SK_MEMBER(source, Rect)
};
#endif
DEFINE_GET_MEMBER(SkRectToRect);
SkRectToRect::SkRectToRect() :
source(NULL), destination(NULL) {
}
SkRectToRect::~SkRectToRect() {
}
bool SkRectToRect::add() {
if (source == NULL || destination == NULL)
return true;
SkMatrix temp;
temp.setRectToRect(source->fRect, destination->fRect,
SkMatrix::kFill_ScaleToFit);
fMatrix->set(temp);
return false;
}
#ifdef SK_DUMP_ENABLED
void SkRectToRect::dump(SkAnimateMaker* maker) {
dumpBase(maker);
SkDebugf("/>\n");
SkDisplayList::fIndent += 4;
if (source) {
SkDebugf("%*s<source>\n", SkDisplayList::fIndent, "");
SkDisplayList::fIndent += 4;
source->dump(maker);
SkDisplayList::fIndent -= 4;
SkDebugf("%*s</source>\n", SkDisplayList::fIndent, "");
}
if (destination) {
SkDebugf("%*s<destination>\n", SkDisplayList::fIndent, "");
SkDisplayList::fIndent += 4;
destination->dump(maker);
SkDisplayList::fIndent -= 4;
SkDebugf("%*s</destination>\n", SkDisplayList::fIndent, "");
}
SkDisplayList::fIndent -= 4;
dumpEnd(maker);
}
#endif
const SkMemberInfo* SkRectToRect::preferredChild(SkDisplayTypes ) {
if (source == NULL)
return getMember("source"); // !!! cwap! need to refer to member through enum like kScope instead
else {
SkASSERT(destination == NULL);
return getMember("destination");
}
}
#if SK_USE_CONDENSED_INFO == 0
const SkMemberInfo SkPolyToPoly::fInfo[] = {
SK_MEMBER(destination, Polygon),
SK_MEMBER(source, Polygon)
};
#endif
DEFINE_GET_MEMBER(SkPolyToPoly);
SkPolyToPoly::SkPolyToPoly() : source(NULL), destination(NULL) {
}
SkPolyToPoly::~SkPolyToPoly() {
}
bool SkPolyToPoly::add() {
SkASSERT(source);
SkASSERT(destination);
SkPoint src[4];
SkPoint dst[4];
SkPath& sourcePath = source->getPath();
int srcPts = sourcePath.getPoints(src, 4);
SkPath& destPath = destination->getPath();
int dstPts = destPath.getPoints(dst, 4);
if (srcPts != dstPts)
return true;
SkMatrix temp;
temp.setPolyToPoly(src, dst, srcPts);
fMatrix->set(temp);
return false;
}
#ifdef SK_DUMP_ENABLED
void SkPolyToPoly::dump(SkAnimateMaker* maker) {
dumpBase(maker);
SkDebugf("/>\n");
SkDisplayList::fIndent += 4;
if (source) {
SkDebugf("%*s<source>\n", SkDisplayList::fIndent, "");
SkDisplayList::fIndent += 4;
source->dump(maker);
SkDisplayList::fIndent -= 4;
SkDebugf("%*s</source>\n", SkDisplayList::fIndent, "");
}
if (destination) {
SkDebugf("%*s<destination>\n", SkDisplayList::fIndent, "");
SkDisplayList::fIndent += 4;
destination->dump(maker);
SkDisplayList::fIndent -= 4;
SkDebugf("%*s</destination>\n", SkDisplayList::fIndent, "");
}
SkDisplayList::fIndent -= 4;
dumpEnd(maker);
}
#endif
void SkPolyToPoly::onEndElement(SkAnimateMaker& ) {
SkASSERT(source);
SkASSERT(destination);
if (source->childHasID() || destination->childHasID())
fMatrix->setChildHasID();
}
const SkMemberInfo* SkPolyToPoly::preferredChild(SkDisplayTypes ) {
if (source == NULL)
return getMember("source"); // !!! cwap! need to refer to member through enum like kScope instead
else {
SkASSERT(destination == NULL);
return getMember("destination");
}
}