#include "config.h"
#if SVG_SUPPORT
#include "KCanvasMatrix.h"
#include "KCanvasPath.h"
#include "AffineTransform.h"
#include <math.h>
namespace WebCore {
static const double deg2rad = 0.017453292519943295769;
KCanvasMatrix::KCanvasMatrix()
{
m_mode = OPS_PREMUL;
}
KCanvasMatrix::KCanvasMatrix(const AffineTransform &matrix)
{
m_mode = OPS_PREMUL;
(*this) = matrix;
}
KCanvasMatrix::KCanvasMatrix(const KCanvasMatrix &matrix)
{
m_mode = OPS_PREMUL;
(*this) = matrix;
}
KCanvasMatrix::KCanvasMatrix(double a, double b, double c, double d, double e, double f)
{
m_mode = OPS_PREMUL;
m_matrix.setMatrix(a, b, c, d, e, f);
}
KCanvasMatrix::~KCanvasMatrix()
{
}
KCanvasMatrix &KCanvasMatrix::operator=(const AffineTransform &other)
{
m_matrix = other;
return *this;
}
KCanvasMatrix &KCanvasMatrix::operator=(const KCanvasMatrix &other)
{
m_matrix = other.m_matrix;
return *this;
}
bool KCanvasMatrix::operator==(const AffineTransform &other) const
{
return (m_matrix == other);
}
bool KCanvasMatrix::operator!=(const AffineTransform &other) const
{
return !operator==(other);
}
bool KCanvasMatrix::operator==(const KCanvasMatrix &other) const
{
return (m_matrix == other.m_matrix);
}
bool KCanvasMatrix::operator!=(const KCanvasMatrix &other) const
{
return !operator==(other);
}
void KCanvasMatrix::setOperationMode(KCMatrixOperationMode mode)
{
m_mode = mode;
}
void KCanvasMatrix::setA(double a)
{
m_matrix.setMatrix(a, m_matrix.m12(), m_matrix.m21(), m_matrix.m22(), m_matrix.dx(), m_matrix.dy());
}
double KCanvasMatrix::a() const
{
return m_matrix.m11();
}
void KCanvasMatrix::setB(double b)
{
m_matrix.setMatrix(m_matrix.m11(), b, m_matrix.m21(), m_matrix.m22(), m_matrix.dx(), m_matrix.dy());
}
double KCanvasMatrix::b() const
{
return m_matrix.m12();
}
void KCanvasMatrix::setC(double c)
{
m_matrix.setMatrix(m_matrix.m11(), m_matrix.m12(), c, m_matrix.m22(), m_matrix.dx(), m_matrix.dy());
}
double KCanvasMatrix::c() const
{
return m_matrix.m21();
}
void KCanvasMatrix::setD(double d)
{
m_matrix.setMatrix(m_matrix.m11(), m_matrix.m12(), m_matrix.m21(), d, m_matrix.dx(), m_matrix.dy());
}
double KCanvasMatrix::d() const
{
return m_matrix.m22();
}
void KCanvasMatrix::setE(double e)
{
m_matrix.setMatrix(m_matrix.m11(), m_matrix.m12(), m_matrix.m21(), m_matrix.m22(), e, m_matrix.dy());
}
double KCanvasMatrix::e() const
{
return m_matrix.dx();
}
void KCanvasMatrix::setF(double f)
{
m_matrix.setMatrix(m_matrix.m11(), m_matrix.m12(), m_matrix.m21(), m_matrix.m22(), m_matrix.dx(), f);
}
double KCanvasMatrix::f() const
{
return m_matrix.dy();
}
KCanvasMatrix &KCanvasMatrix::translate(double x, double y)
{
if(m_mode == OPS_PREMUL)
m_matrix.translate(x, y);
else
{
AffineTransform temp;
temp.translate(x, y);
m_matrix *= temp;
}
return *this;
}
KCanvasMatrix &KCanvasMatrix::multiply(const KCanvasMatrix &other)
{
AffineTransform temp(other.a(), other.b(), other.c(), other.d(), other.e(), other.f());
if(m_mode == OPS_PREMUL)
{
temp *= m_matrix;
m_matrix = temp;
}
else
m_matrix *= temp;
return *this;
}
KCanvasMatrix &KCanvasMatrix::scale(double scaleFactorX, double scaleFactorY)
{
if(m_mode == OPS_PREMUL)
m_matrix.scale(scaleFactorX, scaleFactorY);
else
{
AffineTransform temp;
temp.scale(scaleFactorX, scaleFactorY);
m_matrix *= temp;
}
return *this;
}
KCanvasMatrix &KCanvasMatrix::rotate(double angle)
{
if(m_mode == OPS_PREMUL)
m_matrix.rotate(angle);
else
{
AffineTransform temp;
temp.rotate(angle);
m_matrix *= temp;
}
return *this;
}
KCanvasMatrix &KCanvasMatrix::rotateFromVector(double x, double y)
{
if(m_mode == OPS_PREMUL)
m_matrix.rotate(atan2(y, x) / deg2rad);
else
{
AffineTransform temp;
temp.rotate(atan2(y, x) / deg2rad);
m_matrix *= temp;
}
return *this;
}
KCanvasMatrix &KCanvasMatrix::flipX()
{
return scale(-1.0f, 1.0f);
}
KCanvasMatrix &KCanvasMatrix::flipY()
{
return scale(1.0f, -1.0f);
}
KCanvasMatrix &KCanvasMatrix::skewX(double angle)
{
if(m_mode == OPS_PREMUL)
m_matrix.shear(tan(angle * deg2rad), 0.0f);
else
{
AffineTransform temp;
temp.shear(tan(angle * deg2rad), 0.0f);
m_matrix *= temp;
}
return *this;
}
KCanvasMatrix &KCanvasMatrix::skewY(double angle)
{
if(m_mode == OPS_PREMUL)
m_matrix.shear(0.0f, tan(angle * deg2rad));
else
{
AffineTransform temp;
temp.shear(0.0f, tan(angle * deg2rad));
m_matrix *= temp;
}
return *this;
}
void KCanvasMatrix::reset()
{
m_matrix.reset();
}
void KCanvasMatrix::removeScale(double *xScale, double *yScale)
{
double sx = sqrt(a() * a() + b() *b());
double sy = sqrt(c() * c() + d() *d());
setA(a() / sx); setB(b() / sx);
setC(c() / sy); setD(d() / sy);
*xScale = sx; *yScale = sy;
}
AffineTransform KCanvasMatrix::matrix() const
{
return m_matrix;
}
}
#endif // SVG_SUPPORT