mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
SvgArc support
git-svn-id: svn://ultimatepp.org/upp/trunk@863 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
511dc40a45
commit
30b677638f
13 changed files with 303 additions and 11 deletions
|
|
@ -225,6 +225,8 @@ protected:
|
||||||
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
|
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
|
||||||
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel);
|
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel);
|
||||||
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
|
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
|
||||||
|
virtual void SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
|
||||||
|
const Pointf& p, bool rel);
|
||||||
virtual void CloseOp();
|
virtual void CloseOp();
|
||||||
virtual void DivOp();
|
virtual void DivOp();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ void Painter::Paint(const Painting& pic)
|
||||||
double r, w;
|
double r, w;
|
||||||
Font fnt;
|
Font fnt;
|
||||||
int ii = 0;
|
int ii = 0;
|
||||||
|
bool large, sweep;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
int cmd = ss.Get();
|
int cmd = ss.Get();
|
||||||
if(cmd < 0)
|
if(cmd < 0)
|
||||||
|
|
@ -79,6 +80,15 @@ void Painter::Paint(const Painting& pic)
|
||||||
sGet(w, ss);
|
sGet(w, ss);
|
||||||
ArcOp(p, p1, r, w, rel);
|
ArcOp(p, p1, r, w, rel);
|
||||||
break;
|
break;
|
||||||
|
case PAINTING_SVGARC:
|
||||||
|
case PAINTING_SVGARC_REL:
|
||||||
|
sGet(p1, ss);
|
||||||
|
sGet(r, ss);
|
||||||
|
sGet(large, ss);
|
||||||
|
sGet(sweep, ss);
|
||||||
|
sGet(p, ss);
|
||||||
|
SvgArcOp(p1, r, large, sweep, p, rel);
|
||||||
|
break;
|
||||||
case PAINTING_CLOSE:
|
case PAINTING_CLOSE:
|
||||||
CloseOp();
|
CloseOp();
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,46 @@ Painter& Painter::RelArc(double x, double y, double r, double angle, double swee
|
||||||
return Arc(x, y, r, angle, sweep, true);
|
return Arc(x, y, r, angle, sweep, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Painter& Painter::SvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p, bool rel)
|
||||||
|
{
|
||||||
|
return SvgArc(Pointf(rx, ry), xangle, large, sweep, p, rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter& Painter::SvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y, bool rel)
|
||||||
|
{
|
||||||
|
return SvgArc(Pointf(rx, ry), xangle, large, sweep, Pointf(x, y), rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter& Painter::SvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p)
|
||||||
|
{
|
||||||
|
return SvgArc(r, xangle, large, sweep, p, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter& Painter::SvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p)
|
||||||
|
{
|
||||||
|
return SvgArc(rx, ry, xangle, large, sweep, p, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter& Painter::SvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y)
|
||||||
|
{
|
||||||
|
return SvgArc(rx, ry, xangle, large, sweep, x, y, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter& Painter::RelSvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p)
|
||||||
|
{
|
||||||
|
return SvgArc(r, xangle, large, sweep, p, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter& Painter::RelSvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p)
|
||||||
|
{
|
||||||
|
return SvgArc(rx, ry, xangle, large, sweep, p, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter& Painter::RelSvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y)
|
||||||
|
{
|
||||||
|
return SvgArc(rx, ry, xangle, large, sweep, x, y, true);
|
||||||
|
}
|
||||||
|
|
||||||
Xform2D GetLineSzXform(const Pointf& p1, const Pointf& p2, const Sizef& sz)
|
Xform2D GetLineSzXform(const Pointf& p1, const Pointf& p2, const Sizef& sz)
|
||||||
{
|
{
|
||||||
Xform2D m = Xform2D::Scale(Distance(p1, p2) / sz.cx);
|
Xform2D m = Xform2D::Scale(Distance(p1, p2) / sz.cx);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ struct Xform2D {
|
||||||
double GetScale() const;
|
double GetScale() const;
|
||||||
bool IsRegular() const;
|
bool IsRegular() const;
|
||||||
Pointf Transform(const Pointf& f) const;
|
Pointf Transform(const Pointf& f) const;
|
||||||
|
Pointf Transform(double x, double y) const;
|
||||||
|
|
||||||
static Xform2D Identity();
|
static Xform2D Identity();
|
||||||
static Xform2D Translation(double x, double y);
|
static Xform2D Translation(double x, double y);
|
||||||
|
|
@ -93,6 +94,8 @@ protected:
|
||||||
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel) = 0;
|
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel) = 0;
|
||||||
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel) = 0;
|
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel) = 0;
|
||||||
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel) = 0;
|
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel) = 0;
|
||||||
|
virtual void SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
|
||||||
|
const Pointf& p, bool rel) = 0;
|
||||||
virtual void CloseOp() = 0;
|
virtual void CloseOp() = 0;
|
||||||
virtual void DivOp() = 0;
|
virtual void DivOp() = 0;
|
||||||
|
|
||||||
|
|
@ -140,7 +143,16 @@ protected:
|
||||||
virtual void BeginMaskOp() = 0;
|
virtual void BeginMaskOp() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Pointf ReadPoint(CParser& p);
|
static bool ReadBool(CParser& p);
|
||||||
|
static double ReadDouble(CParser& p);
|
||||||
|
static Pointf ReadPoint(CParser& p);
|
||||||
|
void ArcSegment(const Pointf& c, double th0, double th1, const Pointf& r, double xAxisRotation);
|
||||||
|
void DoArc(const Pointf& c, const Pointf& r, double angle, double sweep, double xangle);
|
||||||
|
void DoSvgArc(const Pointf& rr, double xangle, int large, int sweep,
|
||||||
|
const Pointf& p, const Pointf& p0);
|
||||||
|
// void DoSvgArc(double rx, double ry, double x_axis_rotation,
|
||||||
|
// int large_arc_flag, int sweep_flag,
|
||||||
|
// double x, double y, double curx, double cury);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Clear(const RGBA& color);
|
void Clear(const RGBA& color);
|
||||||
|
|
@ -201,6 +213,16 @@ public:
|
||||||
Painter& RelArc(double x, double y, double rx, double ry, double angle, double sweep);
|
Painter& RelArc(double x, double y, double rx, double ry, double angle, double sweep);
|
||||||
Painter& RelArc(double x, double y, double r, double angle, double sweep);
|
Painter& RelArc(double x, double y, double r, double angle, double sweep);
|
||||||
|
|
||||||
|
Painter& SvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p, bool rel);
|
||||||
|
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p, bool rel);
|
||||||
|
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y, bool rel);
|
||||||
|
Painter& SvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p);
|
||||||
|
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p);
|
||||||
|
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y);
|
||||||
|
Painter& RelSvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p);
|
||||||
|
Painter& RelSvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p);
|
||||||
|
Painter& RelSvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y);
|
||||||
|
|
||||||
Painter& Close();
|
Painter& Close();
|
||||||
Painter& Div();
|
Painter& Div();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,13 @@ Painter& Painter::Arc(const Pointf& c, const Pointf& r, double angle, double swe
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
Painter& Painter::SvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p, bool rel)
|
||||||
|
{
|
||||||
|
SvgArcOp(r, xangle, large, sweep, p, rel);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
Painter& Painter::Close()
|
Painter& Painter::Close()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ file
|
||||||
Painter.h,
|
Painter.h,
|
||||||
Painter.hpp,
|
Painter.hpp,
|
||||||
Painter.cpp,
|
Painter.cpp,
|
||||||
|
SvgArc.cpp,
|
||||||
PainterPath.cpp,
|
PainterPath.cpp,
|
||||||
FontWin32.cpp optimize_speed,
|
FontWin32.cpp optimize_speed,
|
||||||
FontX11.cpp optimize_speed,
|
FontX11.cpp optimize_speed,
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,25 @@
|
||||||
|
|
||||||
NAMESPACE_UPP
|
NAMESPACE_UPP
|
||||||
|
|
||||||
|
bool Painter::ReadBool(CParser& p)
|
||||||
|
{
|
||||||
|
while(p.Char(','));
|
||||||
|
if(p.Char('1')) return true;
|
||||||
|
p.Char('0');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Painter::ReadDouble(CParser& p)
|
||||||
|
{
|
||||||
|
while(p.Char(','));
|
||||||
|
return p.IsDouble() ? p.ReadDouble() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
Pointf Painter::ReadPoint(CParser& p)
|
Pointf Painter::ReadPoint(CParser& p)
|
||||||
{
|
{
|
||||||
Pointf t;
|
Pointf t;
|
||||||
t.x = p.IsDouble() ? p.ReadDouble() : 0;
|
t.x = ReadDouble(p);
|
||||||
p.Char(',');
|
t.y = ReadDouble(p);
|
||||||
t.y = p.IsDouble() ? p.ReadDouble() : 0;
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21,11 +34,11 @@ Painter& Painter::Path(CParser& p)
|
||||||
switch(ToUpper(c)) {
|
switch(ToUpper(c)) {
|
||||||
case 'M':
|
case 'M':
|
||||||
t = ReadPoint(p);
|
t = ReadPoint(p);
|
||||||
Move(t.x, t.y);
|
Move(t, rel);
|
||||||
case 'L':
|
case 'L':
|
||||||
while(p.IsDouble()) {
|
while(p.IsDouble()) {
|
||||||
t = ReadPoint(p);
|
t = ReadPoint(p);
|
||||||
Line(t.x, t.y, rel);
|
Line(t, rel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Z':
|
case 'Z':
|
||||||
|
|
@ -44,27 +57,37 @@ Painter& Painter::Path(CParser& p)
|
||||||
t1 = ReadPoint(p);
|
t1 = ReadPoint(p);
|
||||||
t2 = ReadPoint(p);
|
t2 = ReadPoint(p);
|
||||||
t = ReadPoint(p);
|
t = ReadPoint(p);
|
||||||
Cubic(t1.x, t1.y, t2.x, t2.y, t.x, t.y, rel);
|
Cubic(t1, t2, t, rel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
while(p.IsDouble()) {
|
while(p.IsDouble()) {
|
||||||
t2 = ReadPoint(p);
|
t2 = ReadPoint(p);
|
||||||
t = ReadPoint(p);
|
t = ReadPoint(p);
|
||||||
Cubic(t2.x, t2.y, t.x, t.y, rel);
|
Cubic(t2, t, rel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
while(p.IsDouble()) {
|
while(p.IsDouble()) {
|
||||||
t1 = ReadPoint(p);
|
t1 = ReadPoint(p);
|
||||||
t = ReadPoint(p);
|
t = ReadPoint(p);
|
||||||
Quadratic(t1.x, t1.y, t.x, t.y, rel);
|
Quadratic(t1, t, rel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
while(p.IsDouble()) {
|
while(p.IsDouble()) {
|
||||||
t = ReadPoint(p);
|
t = ReadPoint(p);
|
||||||
Quadratic(t.x, t.y, rel);
|
Quadratic(t, rel);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
while(p.IsDouble()) {
|
||||||
|
t1 = ReadPoint(p);
|
||||||
|
double xangle = ReadDouble(p);
|
||||||
|
bool large = ReadBool(p);
|
||||||
|
bool sweep = ReadBool(p);
|
||||||
|
t = ReadPoint(p);
|
||||||
|
SvgArc(t1, xangle * M_PI / 180.0, large, sweep, t, rel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,16 @@ void PaintingPainter::ArcOp(const Pointf& c, const Pointf& r, double angle, doub
|
||||||
Putf(sweep);
|
Putf(sweep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PaintingPainter::SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p, bool rel)
|
||||||
|
{
|
||||||
|
Put(PAINTING_SVGARC + rel);
|
||||||
|
Putf(r);
|
||||||
|
Putf(xangle);
|
||||||
|
Put(large);
|
||||||
|
Put(sweep);
|
||||||
|
Putf(p);
|
||||||
|
}
|
||||||
|
|
||||||
void PaintingPainter::CloseOp()
|
void PaintingPainter::CloseOp()
|
||||||
{
|
{
|
||||||
Put(PAINTING_CLOSE);
|
Put(PAINTING_CLOSE);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ enum {
|
||||||
PAINTING_CUBIC_S_REL,
|
PAINTING_CUBIC_S_REL,
|
||||||
PAINTING_ARC,
|
PAINTING_ARC,
|
||||||
PAINTING_ARC_REL,
|
PAINTING_ARC_REL,
|
||||||
|
PAINTING_SVGARC,
|
||||||
|
PAINTING_SVGARC_REL,
|
||||||
PAINTING_CLOSE,
|
PAINTING_CLOSE,
|
||||||
PAINTING_DIV,
|
PAINTING_DIV,
|
||||||
|
|
||||||
|
|
@ -72,6 +74,8 @@ protected:
|
||||||
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
|
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
|
||||||
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel);
|
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel);
|
||||||
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
|
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
|
||||||
|
virtual void SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
|
||||||
|
const Pointf& p, bool rel);
|
||||||
virtual void CloseOp();
|
virtual void CloseOp();
|
||||||
virtual void DivOp();
|
virtual void DivOp();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,14 @@ void BufferPainter::ArcOp(const Pointf& c, const Pointf& r, double angle, double
|
||||||
current = m.EndPoint();
|
current = m.EndPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BufferPainter::SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
|
||||||
|
const Pointf& p, bool rel)
|
||||||
|
{
|
||||||
|
DoMove0();
|
||||||
|
Pointf c = current;
|
||||||
|
DoSvgArc(r, xangle, large, sweep, EndPoint(p, rel), c);
|
||||||
|
}
|
||||||
|
|
||||||
void BufferPainter::CloseOp()
|
void BufferPainter::CloseOp()
|
||||||
{
|
{
|
||||||
if(!IsNull(move) && current != move) {
|
if(!IsNull(move) && current != move) {
|
||||||
|
|
|
||||||
160
uppsrc/Painter/SvgArc.cpp
Normal file
160
uppsrc/Painter/SvgArc.cpp
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
#include "Painter.h"
|
||||||
|
|
||||||
|
NAMESPACE_UPP
|
||||||
|
|
||||||
|
void Painter::DoArc(const Pointf& c, const Pointf& r, double angle, double sweep, double xangle)
|
||||||
|
{
|
||||||
|
int n_segs = int(ceil(fabs(sweep / (M_PI * 0.5 + 0.001))));
|
||||||
|
for (int i = 0; i < n_segs; i++) {
|
||||||
|
double th0 = angle + i * sweep / n_segs;
|
||||||
|
double th1 = angle + (i + 1) * sweep / n_segs;
|
||||||
|
double thHalf = 0.5 * (th1 - th0);
|
||||||
|
double t = (8.0 / 3.0) * sin(thHalf * 0.5) * sin(thHalf * 0.5) / sin(thHalf);
|
||||||
|
double x3 = c.x + cos(th1);
|
||||||
|
double y3 = c.y + sin(th1);
|
||||||
|
Xform2D m = Xform2D::Rotation(xangle);
|
||||||
|
m.x *= r;
|
||||||
|
m.y *= r;
|
||||||
|
Cubic(m.Transform(c.x + cos(th0) - t * sin(th0), c.y + sin(th0) + t * cos(th0)),
|
||||||
|
m.Transform(x3 + t * sin(th1), y3 - t * cos(th1)),
|
||||||
|
m.Transform(x3, y3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the arc handling code underneath is from XSVG (BSD license)
|
||||||
|
/*
|
||||||
|
* Copyright 2002 USC/Information Sciences Institute
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software
|
||||||
|
* and its documentation for any purpose is hereby granted without
|
||||||
|
* fee, provided that the above copyright notice appear in all copies
|
||||||
|
* and that both that copyright notice and this permission notice
|
||||||
|
* appear in supporting documentation, and that the name of
|
||||||
|
* Information Sciences Institute not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without
|
||||||
|
* specific, written prior permission. Information Sciences Institute
|
||||||
|
* makes no representations about the suitability of this software for
|
||||||
|
* any purpose. It is provided "as is" without express or implied
|
||||||
|
* warranty.
|
||||||
|
*
|
||||||
|
* INFORMATION SCIENCES INSTITUTE DISCLAIMS ALL WARRANTIES WITH REGARD
|
||||||
|
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL INFORMATION SCIENCES
|
||||||
|
* INSTITUTE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||||
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
|
||||||
|
* OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Painter::DoSvgArc(const Pointf& rr, double xangle, int large, int sweep,
|
||||||
|
const Pointf& p1, const Pointf& p0)
|
||||||
|
{
|
||||||
|
Pointf r(fabs(rr.x), fabs(rr.y));
|
||||||
|
|
||||||
|
Xform2D m = Xform2D::Rotation(-xangle);
|
||||||
|
Pointf d1 = m.Transform((p0 - p1) / 2);
|
||||||
|
Pointf Pr = r * r;
|
||||||
|
Pointf P = d1 * d1;
|
||||||
|
double check = P.x / Pr.x + P.y / Pr.y;
|
||||||
|
if(check > 1)
|
||||||
|
r *= sqrt(check);
|
||||||
|
m.x /= r.x;
|
||||||
|
m.y /= r.y;
|
||||||
|
Pointf q0 = m.Transform(p0);
|
||||||
|
Pointf q1 = m.Transform(p1);
|
||||||
|
double d = SquaredDistance(q1, q0);
|
||||||
|
double sfactor_sq = 1.0 / d - 0.25;
|
||||||
|
if(sfactor_sq < 0) sfactor_sq = 0;
|
||||||
|
double sfactor = sqrt(sfactor_sq);
|
||||||
|
if (sweep == large) sfactor = -sfactor;
|
||||||
|
Pointf c(0.5 * (q0.x + q1.x) - sfactor * (q1.y - q0.y),
|
||||||
|
0.5 * (q0.y + q1.y) + sfactor * (q1.x - q0.x));
|
||||||
|
double th0 = Bearing(q0 - c);
|
||||||
|
double th_sweep = Bearing(q1 - c) - th0;
|
||||||
|
if(th_sweep < 0 && sweep)
|
||||||
|
th_sweep += 2 * M_PI;
|
||||||
|
else
|
||||||
|
if(th_sweep > 0 && !sweep)
|
||||||
|
th_sweep -= 2 * M_PI;
|
||||||
|
|
||||||
|
DoArc(c, r, th0, th_sweep, xangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void Painter::DoSvgArc(double rx, double ry,
|
||||||
|
double x_axis_rotation, int large_arc_flag, int sweep_flag,
|
||||||
|
double x, double y, double curx, double cury)
|
||||||
|
{
|
||||||
|
double sin_th, cos_th;
|
||||||
|
double a00, a01, a10, a11;
|
||||||
|
double x0, y0, x1, y1, xc, yc;
|
||||||
|
double d, sfactor, sfactor_sq;
|
||||||
|
double th0, th1, th_arc;
|
||||||
|
int i, n_segs;
|
||||||
|
double dx, dy, dx1, dy1, Pr1, Pr2, Px, Py, check;
|
||||||
|
|
||||||
|
rx = fabs(rx);
|
||||||
|
ry = fabs(ry);
|
||||||
|
|
||||||
|
sin_th = sin(x_axis_rotation);
|
||||||
|
cos_th = cos(x_axis_rotation);
|
||||||
|
|
||||||
|
dx = (curx - x) / 2.0;
|
||||||
|
dy = (cury - y) / 2.0;
|
||||||
|
dx1 = cos_th * dx + sin_th * dy;
|
||||||
|
dy1 = -sin_th * dx + cos_th * dy;
|
||||||
|
Pr1 = rx * rx;
|
||||||
|
Pr2 = ry * ry;
|
||||||
|
Px = dx1 * dx1;
|
||||||
|
Py = dy1 * dy1;
|
||||||
|
/* Spec : check if radii are large enough */
|
||||||
|
check = Px / Pr1 + Py / Pr2;
|
||||||
|
if(check > 1) {
|
||||||
|
rx = rx * sqrt(check);
|
||||||
|
ry = ry * sqrt(check);
|
||||||
|
}
|
||||||
|
|
||||||
|
a00 = cos_th / rx;
|
||||||
|
a01 = sin_th / rx;
|
||||||
|
a10 = -sin_th / ry;
|
||||||
|
a11 = cos_th / ry;
|
||||||
|
x0 = a00 * curx + a01 * cury;
|
||||||
|
y0 = a10 * curx + a11 * cury;
|
||||||
|
x1 = a00 * x + a01 * y;
|
||||||
|
y1 = a10 * x + a11 * y;
|
||||||
|
/* (x0, y0) is current point in transformed coordinate space.
|
||||||
|
(x1, y1) is new point in transformed coordinate space.
|
||||||
|
|
||||||
|
The arc fits a unit-radius circle in this space.
|
||||||
|
*/
|
||||||
|
d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
|
||||||
|
sfactor_sq = 1.0 / d - 0.25;
|
||||||
|
if (sfactor_sq < 0) sfactor_sq = 0;
|
||||||
|
sfactor = sqrt(sfactor_sq);
|
||||||
|
if (sweep_flag == large_arc_flag) sfactor = -sfactor;
|
||||||
|
xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
|
||||||
|
yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
|
||||||
|
/* (xc, yc) is center of the circle. */
|
||||||
|
|
||||||
|
th0 = atan2(y0 - yc, x0 - xc);
|
||||||
|
th1 = atan2(y1 - yc, x1 - xc);
|
||||||
|
|
||||||
|
th_arc = th1 - th0;
|
||||||
|
if (th_arc < 0 && sweep_flag)
|
||||||
|
th_arc += 2 * M_PI;
|
||||||
|
else if (th_arc > 0 && !sweep_flag)
|
||||||
|
th_arc -= 2 * M_PI;
|
||||||
|
|
||||||
|
n_segs = int(ceil(fabs(th_arc / (M_PI * 0.5 + 0.001))));
|
||||||
|
|
||||||
|
for (i = 0; i < n_segs; i++)
|
||||||
|
ArcSegment(xc, yc,
|
||||||
|
th0 + i * th_arc / n_segs,
|
||||||
|
th0 + (i + 1) * th_arc / n_segs,
|
||||||
|
rx, ry, x_axis_rotation);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
END_UPP_NAMESPACE
|
||||||
|
|
@ -7,6 +7,11 @@ Pointf Xform2D::Transform(const Pointf& f) const
|
||||||
return Pointf(f.x * x.x + f.y * x.y + t.x, f.x * y.x + f.y * y.y + t.y);
|
return Pointf(f.x * x.x + f.y * x.y + t.x, f.x * y.x + f.y * y.y + t.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pointf Xform2D::Transform(double x, double y) const
|
||||||
|
{
|
||||||
|
return Transform(Pointf(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
Pointf Xform2D::GetScaleXY() const
|
Pointf Xform2D::GetScaleXY() const
|
||||||
{
|
{
|
||||||
return Pointf(sqrt(x.x * x.x + y.x * y.x), sqrt(x.y * x.y + y.y * y.y));
|
return Pointf(sqrt(x.x * x.x + y.x * y.x), sqrt(x.y * x.y + y.y * y.y));
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#define _Painter_icpp_init_stub
|
#define _Painter_icpp_init_stub
|
||||||
#include "Core/init"
|
#include "Core/init"
|
||||||
#include "CtrlLib/init"
|
#include "CtrlLib/init"
|
||||||
#define BLITZ_INDEX__ FB97560702FE0F85B954F5A6632CEB2DB
|
#define BLITZ_INDEX__ F41D82715284B94932890A06EF04E4CA5
|
||||||
#include "PaintPainting.icpp"
|
#include "PaintPainting.icpp"
|
||||||
#undef BLITZ_INDEX__
|
#undef BLITZ_INDEX__
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue