mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
235 lines
5.7 KiB
C++
235 lines
5.7 KiB
C++
#ifndef _ScanLine_ScanLine_h_
|
|
#define _ScanLine_ScanLine_h_
|
|
|
|
#include <CtrlLib/CtrlLib.h>
|
|
|
|
using namespace Upp;
|
|
|
|
#define PAINTER_TIMING(x) // RTIMING(x)
|
|
|
|
inline RGBA Mul8(const RGBA& s, int mul)
|
|
{
|
|
RGBA t;
|
|
t.r = (mul * s.r) >> 8;
|
|
t.g = (mul * s.g) >> 8;
|
|
t.b = (mul * s.b) >> 8;
|
|
t.a = (mul * s.a) >> 8;
|
|
return t;
|
|
}
|
|
|
|
inline void AlphaBlend(RGBA& t, const RGBA& c)
|
|
{
|
|
int alpha = 256 - (c.a + (c.a >> 7));
|
|
t.r = c.r + (alpha * t.r >> 8);
|
|
t.g = c.g + (alpha * t.g >> 8);
|
|
t.b = c.b + (alpha * t.b >> 8);
|
|
t.a = c.a + (alpha * t.a >> 8);
|
|
}
|
|
|
|
inline void AlphaBlendCover8(RGBA& t, const RGBA& c, int cover)
|
|
{
|
|
int a = c.a * cover >> 8;
|
|
int alpha = 256 - (a + (a >> 7));
|
|
t.r = (c.r * cover >> 8) + (alpha * t.r >> 8);
|
|
t.g = (c.g * cover >> 8) + (alpha * t.g >> 8);
|
|
t.b = (c.b * cover >> 8) + (alpha * t.b >> 8);
|
|
t.a = a + (alpha * t.a >> 8);
|
|
}
|
|
|
|
struct ScanLine {
|
|
int xmin, xmax;
|
|
Buffer<byte> data;
|
|
int datalen;
|
|
|
|
bool IsFull();
|
|
bool IsEmpty();
|
|
|
|
String ToString() const;
|
|
};
|
|
|
|
double SquareDist(const Pointf& p1, const Pointf& p2);
|
|
Pointf Mid(const Pointf& a, const Pointf& b);
|
|
Pointf Ortogonal(const Pointf& p);
|
|
double SquareLength(const Pointf& p);
|
|
double Length(const Pointf& p);
|
|
double Bearing(const Pointf& p);
|
|
double Distance(const Pointf& p1, const Pointf& p2);
|
|
double SquareDistance(const Pointf& p1, const Pointf& p2);
|
|
Pointf PolarPointf(double a);
|
|
Pointf Polar(const Pointf& p, double r, double a);
|
|
|
|
struct LinearPathConsumer {
|
|
virtual void Move(const Pointf& p) = 0;
|
|
virtual void Line(const Pointf& p) = 0;
|
|
virtual void End();
|
|
};
|
|
|
|
struct LinearPathFilter : LinearPathConsumer {
|
|
virtual void End();
|
|
|
|
LinearPathConsumer *target;
|
|
|
|
void PutMove(const Pointf& p) { target->Move(p); }
|
|
void PutLine(const Pointf& p) { target->Line(p); }
|
|
void PutEnd() { target->End(); }
|
|
|
|
template <class T> T& operator|(T& b) { target = &b; return b; }
|
|
};
|
|
|
|
enum {
|
|
LINECAP_BUTT,
|
|
LINECAP_SQUARE,
|
|
LINECAP_ROUND,
|
|
|
|
LINEJOIN_MITER,
|
|
LINEJOIN_ROUND,
|
|
LINEJOIN_BEVEL,
|
|
};
|
|
|
|
class Stroker : public LinearPathFilter {
|
|
double w2;
|
|
double qmiter;
|
|
double fid;
|
|
|
|
Pointf p0, v0, o0, a0, b0;
|
|
Pointf p1, v1, o1, a1, b1;
|
|
Pointf p2;
|
|
int linecap;
|
|
int linejoin;
|
|
|
|
void Finish();
|
|
void Round(const Pointf& p, const Pointf& v1, const Pointf& v2, double r);
|
|
void Cap(const Pointf& p0, const Pointf& v0, const Pointf& o0,
|
|
const Pointf& a0, const Pointf& b0);
|
|
|
|
public:
|
|
virtual void Move(const Pointf& p);
|
|
virtual void Line(const Pointf& p);
|
|
virtual void End();
|
|
|
|
Stroker(double width, double miterlimit, double tolerance, int linecap, int linejoin);
|
|
};
|
|
|
|
struct Dasher : public LinearPathFilter {
|
|
Vector<double> pattern;
|
|
int patterni;
|
|
double rem;
|
|
bool flag;
|
|
Pointf p0;
|
|
|
|
void Put(const Pointf& p);
|
|
|
|
public:
|
|
virtual void Move(const Pointf& p);
|
|
virtual void Line(const Pointf& p);
|
|
|
|
Dasher(double width, const Vector<double>& pattern, double distance);
|
|
};
|
|
|
|
void ApproximateQuadratic(LinearPathConsumer& t, const Pointf& p1, const Pointf& p2, const Pointf& p3, double tolerance);
|
|
void ApproximateCubic(LinearPathConsumer& t, const Pointf& x0, const Pointf& x1, const Pointf& x2, const Pointf& x, double tolerance);
|
|
|
|
class Rasterizer : public LinearPathConsumer {
|
|
public:
|
|
virtual void Move(const Pointf& p);
|
|
virtual void Line(const Pointf& p);
|
|
|
|
private:
|
|
struct Cell : MoveableWithSwap<Cell> {
|
|
int16 x;
|
|
int16 cover;
|
|
int area;
|
|
|
|
bool operator<(const Cell& b) const { return x < b.x; }
|
|
};
|
|
|
|
Rectf cliprect;
|
|
Pointf p0;
|
|
Buffer< Vector<Cell> > cell;
|
|
int xmax, ymax;
|
|
int min_y;
|
|
int max_y;
|
|
Size sz;
|
|
|
|
void Init();
|
|
Cell *AddCells(int y, int n);
|
|
void RenderHLine(int ey, int x1, int y1, int x2, int y2);
|
|
void LineClip(double x1, double y1, double x2, double y2);
|
|
int CvX(double x);
|
|
int CvY(double y);
|
|
void CvLine(double x1, double y1, double x2, double y2);
|
|
bool BeginRender(int y, const Cell *&c, const Cell *&e);
|
|
|
|
public:
|
|
struct Target {
|
|
virtual void Start(int x, int len) = 0;
|
|
virtual void Render(int val) = 0;
|
|
virtual void Render(int val, int len) = 0;
|
|
};
|
|
|
|
void LineRaw(int x1, int y1, int x2, int y2);
|
|
|
|
void SetClip(const Rectf& rect);
|
|
|
|
int MinY() const { return min_y; }
|
|
int MaxY() const { return max_y; }
|
|
void Render(int y, Target& g, bool evenodd);
|
|
|
|
void Reset();
|
|
|
|
Rasterizer(int cx, int cy);
|
|
};
|
|
|
|
void Render(ImageBuffer& ib, Rasterizer& r, const RGBA& color, bool evenodd);
|
|
|
|
struct Xform2D {
|
|
Pointf x, y, t;
|
|
|
|
Pointf GetScaleXY() const;
|
|
double GetScale() const;
|
|
bool IsRegular() const;
|
|
Pointf Transform(const Pointf& f) const;
|
|
|
|
static Xform2D Identity();
|
|
static Xform2D Translation(double x, double y);
|
|
static Xform2D Scale(double sx, double sy);
|
|
static Xform2D Scale(double scale);
|
|
static Xform2D Rotation(double fi);
|
|
static Xform2D Sheer(double fi);
|
|
};
|
|
|
|
Xform2D operator*(const Xform2D& a, const Xform2D& b);
|
|
Xform2D Inverse(const Xform2D& m);
|
|
|
|
class BufferPainter {
|
|
enum {
|
|
MOVE, LINE, QUADRATIC, CUBIC
|
|
};
|
|
struct Segment {
|
|
byte kind;
|
|
Pointf p;
|
|
};
|
|
struct QuadraticSegment : Segment{
|
|
Pointf p1;
|
|
};
|
|
struct CubicSegment : QuadraticSegment {
|
|
Pointf p2;
|
|
};
|
|
|
|
Vector<byte> path;
|
|
|
|
template <class T>
|
|
T& PathAdd() {
|
|
int q = path.GetCount();
|
|
path.SetCount(q + sizeof(T));
|
|
return *(T *)&path[q];
|
|
}
|
|
|
|
public:
|
|
void Move(Pointf p);
|
|
void Line(Pointf p);
|
|
void Quadratic(Pointf p1, Pointf p);
|
|
void Cubic(Pointf p1, Pointf p2, Pointf p);
|
|
};
|
|
|
|
#endif
|