mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-09-10 03:54:54 -06:00
Painter: BufferPainter::PreClip #214
git-svn-id: svn://ultimatepp.org/upp/trunk@8094 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
3ebcfa4a7b
commit
3ab7b0d27a
10 changed files with 137 additions and 133 deletions
|
|
@ -31,20 +31,23 @@ private:
|
|||
double w2;
|
||||
double qmiter;
|
||||
double fid;
|
||||
double tw;
|
||||
|
||||
Pointf p0, v0, o0, a0, b0;
|
||||
Pointf p1, v1, o1, a1, b1;
|
||||
Pointf p2;
|
||||
int linecap;
|
||||
int linejoin;
|
||||
Rectf preclip;
|
||||
|
||||
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);
|
||||
bool PreClipped(Pointf p2, Pointf p3);
|
||||
|
||||
public:
|
||||
void Init(double width, double miterlimit, double tolerance, int linecap, int linejoin);
|
||||
void Init(double width, double miterlimit, double tolerance, int linecap, int linejoin, const Rect& preclip);
|
||||
};
|
||||
|
||||
class Dasher : public LinearPathFilter {
|
||||
|
|
@ -150,7 +153,8 @@ public:
|
|||
|
||||
void LineRaw(int x1, int y1, int x2, int y2);
|
||||
|
||||
void SetClip(const Rectf& rect);
|
||||
void SetClip(const Rectf& rect);
|
||||
Rectf GetClip() const { return cliprect; }
|
||||
|
||||
int MinY() const { return min_y; }
|
||||
int MaxY() const { return max_y; }
|
||||
|
|
@ -318,6 +322,7 @@ private:
|
|||
int mode;
|
||||
Buffer<int16> subpixel;
|
||||
int render_cx;
|
||||
bool dopreclip;
|
||||
|
||||
Attr attr;
|
||||
Attr pathattr;
|
||||
|
|
@ -370,6 +375,8 @@ private:
|
|||
public:
|
||||
ImageBuffer& GetBuffer() { return ib; }
|
||||
const ImageBuffer& GetBuffer() const { return ib; }
|
||||
|
||||
BufferPainter& PreClip(bool b = true) { dopreclip = b; return *this; }
|
||||
|
||||
BufferPainter(ImageBuffer& ib, int mode = MODE_ANTIALIASED);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ BufferPainter::BufferPainter(ImageBuffer& ib, int mode)
|
|||
pathattr = attr;
|
||||
|
||||
gradientn = Null;
|
||||
|
||||
dopreclip = false;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ file
|
|||
BufferPainter.h,
|
||||
Xform2D.cpp,
|
||||
Approximate.cpp,
|
||||
Stroker.cpp,
|
||||
Stroker.cpp optimize_speed,
|
||||
Dasher.cpp,
|
||||
Transformer.cpp,
|
||||
Interpolator.cpp optimize_speed,
|
||||
|
|
|
|||
|
|
@ -56,7 +56,24 @@ Buffer<ClippingLine> BufferPainter::RenderPath(double width, SpanSource *ss, con
|
|||
}
|
||||
else
|
||||
if(width > 0) {
|
||||
stroker.Init(width, pathattr.miter_limit, tolerance, pathattr.cap, pathattr.join);
|
||||
Rectf preclip = Null;
|
||||
if(dopreclip) {
|
||||
preclip = rasterizer.GetClip();
|
||||
Xform2D imx = Inverse(pathattr.mtx);
|
||||
Pointf tl, br, a;
|
||||
tl = br = imx.Transform(preclip.TopLeft());
|
||||
a = imx.Transform(preclip.TopRight());
|
||||
tl = min(a, tl);
|
||||
br = max(a, br);
|
||||
a = imx.Transform(preclip.BottomLeft());
|
||||
tl = min(a, tl);
|
||||
br = max(a, br);
|
||||
a = imx.Transform(preclip.BottomRight());
|
||||
tl = min(a, tl);
|
||||
br = max(a, br);
|
||||
preclip = Rectf(tl, br);
|
||||
}
|
||||
stroker.Init(width, pathattr.miter_limit, tolerance, pathattr.cap, pathattr.join, preclip);
|
||||
stroker.target = g;
|
||||
if(pathattr.dash.GetCount()) {
|
||||
dasher.Init(pathattr.dash, pathattr.dash_start);
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
#include "Painter.h"
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Stroker::Init(double width, double miterlimit, double tolerance, int _linecap, int _linejoin)
|
||||
void Stroker::Init(double width, double miterlimit, double tolerance, int _linecap, int _linejoin, const Rect& preclip_)
|
||||
{
|
||||
linecap = _linecap;
|
||||
linejoin = _linejoin;
|
||||
preclip = preclip_;
|
||||
w2 = width / 2;
|
||||
qmiter = miterlimit * w2;
|
||||
if(!IsNull(preclip))
|
||||
tw = 4 * max(qmiter, w2); // preclipping width
|
||||
qmiter *= qmiter;
|
||||
fid = acos(1 - tolerance / w2);
|
||||
p0 = p1 = p2 = Null;
|
||||
|
|
@ -35,6 +38,14 @@ void Stroker::Round(const Pointf& p, const Pointf& v1, const Pointf& v2, double
|
|||
}
|
||||
}
|
||||
|
||||
inline bool Stroker::PreClipped(Pointf p2, Pointf p3)
|
||||
{
|
||||
return p2.x + tw < preclip.left && p3.x + tw < preclip.left ||
|
||||
p2.x - tw > preclip.right && p3.x - tw > preclip.right ||
|
||||
p2.y + tw < preclip.top && p3.y + tw < preclip.top ||
|
||||
p2.y - tw > preclip.bottom && p3.y - tw > preclip.bottom;
|
||||
}
|
||||
|
||||
void Stroker::Line(const Pointf& p3)
|
||||
{
|
||||
LLOG("Stroker::Line " << p3);
|
||||
|
|
@ -70,50 +81,54 @@ void Stroker::Line(const Pointf& p3)
|
|||
Pointf a2 = p2 + o2;
|
||||
Pointf b2 = p2 - o2;
|
||||
|
||||
double d = v1.y * v2.x - v2.y * v1.x;
|
||||
if(d > 1e-30) {
|
||||
Pointf ts = a1 + v1 * (v2.y * (a1.x - a2.x) - v2.x * (a1.y - a2.y)) / d;
|
||||
PutMove(a1);
|
||||
if(linejoin != LINEJOIN_MITER || SquaredDistance(ts, p2) > qmiter) {
|
||||
if(IsNull(preclip) || !PreClipped(p2, p3)) {
|
||||
double d = v1.y * v2.x - v2.y * v1.x;
|
||||
if(d > 1e-30) {
|
||||
Pointf ts = a1 + v1 * (v2.y * (a1.x - a2.x) - v2.x * (a1.y - a2.y)) / d;
|
||||
PutMove(a1);
|
||||
if(linejoin != LINEJOIN_MITER || SquaredDistance(ts, p2) > qmiter) {
|
||||
PutLine(a1 + v1);
|
||||
if(linejoin == LINEJOIN_ROUND)
|
||||
Round(p2, o1, o2, w2);
|
||||
}
|
||||
else
|
||||
PutLine(ts);
|
||||
PutLine(a2);
|
||||
PutMove(b2);
|
||||
PutLine(p2);
|
||||
PutLine(b1 + v1);
|
||||
PutLine(b1);
|
||||
}
|
||||
else
|
||||
if(d < -1e-30) {
|
||||
Pointf ts = b2 + v2 * (v1.y * (a2.x - a1.x) - v1.x * (a2.y - a1.y)) / d;
|
||||
PutMove(b2);
|
||||
if(linejoin != LINEJOIN_MITER || SquaredDistance(ts, p2) > qmiter) {
|
||||
if(linejoin == LINEJOIN_ROUND)
|
||||
Round(p2, -o2, -o1, w2);
|
||||
PutLine(b1 + v1);
|
||||
}
|
||||
else
|
||||
PutLine(ts);
|
||||
PutLine(b1);
|
||||
PutMove(a1);
|
||||
PutLine(a1 + v1);
|
||||
PutLine(p2);
|
||||
PutLine(a2);
|
||||
}
|
||||
else {
|
||||
PutMove(a1);
|
||||
PutLine(a1 + v1);
|
||||
if(linejoin == LINEJOIN_ROUND)
|
||||
Round(p2, o1, o2, w2);
|
||||
PutLine(a2);
|
||||
PutMove(b2);
|
||||
PutLine(b1 + v1);
|
||||
PutLine(b1);
|
||||
}
|
||||
else
|
||||
PutLine(ts);
|
||||
PutLine(a2);
|
||||
PutMove(b2);
|
||||
PutLine(p2);
|
||||
PutLine(b1 + v1);
|
||||
PutLine(b1);
|
||||
}
|
||||
else
|
||||
if(d < -1e-30) {
|
||||
Pointf ts = b2 + v2 * (v1.y * (a2.x - a1.x) - v1.x * (a2.y - a1.y)) / d;
|
||||
PutMove(b2);
|
||||
if(linejoin != LINEJOIN_MITER || SquaredDistance(ts, p2) > qmiter) {
|
||||
if(linejoin == LINEJOIN_ROUND)
|
||||
Round(p2, -o2, -o1, w2);
|
||||
PutLine(b1 + v1);
|
||||
}
|
||||
else
|
||||
PutLine(ts);
|
||||
PutLine(b1);
|
||||
PutMove(a1);
|
||||
PutLine(a1 + v1);
|
||||
PutLine(p2);
|
||||
PutLine(a2);
|
||||
}
|
||||
else {
|
||||
PutMove(a1);
|
||||
PutLine(a1 + v1);
|
||||
if(linejoin == LINEJOIN_ROUND)
|
||||
Round(p2, o1, o2, w2);
|
||||
PutLine(a2);
|
||||
PutMove(b2);
|
||||
PutLine(b1 + v1);
|
||||
PutLine(b1);
|
||||
}
|
||||
LLOG("PRECLIPPED " << p2 << " - " << p3);
|
||||
p1 = p2;
|
||||
v1 = v2;
|
||||
o1 = o2;
|
||||
|
|
@ -125,6 +140,11 @@ void Stroker::Line(const Pointf& p3)
|
|||
void Stroker::Cap(const Pointf& p, const Pointf& v, const Pointf& o,
|
||||
const Pointf& a, const Pointf& b)
|
||||
{
|
||||
if(!IsNull(preclip) &&
|
||||
(p.x + tw < preclip.left || p.x - tw > preclip.right || p.y + tw < preclip.top || p.y - tw > preclip.bottom)) {
|
||||
LLOG("Cap was preclipped out");
|
||||
return;
|
||||
}
|
||||
PutMove(a);
|
||||
if(linecap == LINECAP_SQUARE) {
|
||||
Pointf nv = Orthogonal(o);
|
||||
|
|
@ -140,13 +160,18 @@ void Stroker::Finish()
|
|||
{
|
||||
if(IsNull(p1) || IsNull(p2) || IsNull(p0))
|
||||
return;
|
||||
LLOG("-- Finish " << p1 << " " << p2);
|
||||
if(p2 == p0)
|
||||
Line(p0 + v0);
|
||||
else {
|
||||
PutMove(a1);
|
||||
PutLine(a1 + v1);
|
||||
PutMove(b1 + v1);
|
||||
PutLine(b1);
|
||||
if(IsNull(preclip) || !PreClipped(p1, p2)) {
|
||||
PutMove(a1);
|
||||
PutLine(a1 + v1);
|
||||
PutMove(b1 + v1);
|
||||
PutLine(b1);
|
||||
}
|
||||
else
|
||||
LLOG("FINISH PRECLIPPED " << p1 << " - " << p2);
|
||||
Cap(p0, v0, o0, b0, a0);
|
||||
Cap(p2, -v1, -o1, a1 + v1, b1 + v1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "Debuggers.h"
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LLOG(x) LOG(x)
|
||||
|
||||
#define IMAGECLASS DbgImg
|
||||
#define IMAGEFILE <ide/Debuggers/Debuggers.iml>
|
||||
|
|
@ -100,27 +100,31 @@ String Dbg::Cmd(const char *command)
|
|||
Lock();
|
||||
if(command) {
|
||||
LLOG("Cmd: " << command);
|
||||
dbg->Write(String(command) + "\n"); // TRC 04/10/11: must not use \r\n, LINUX doesn't like it
|
||||
dbg->Write(String(command) + "\n"); _DBG_ // TRC 04/10/11: must not use \r\n, LINUX doesn't like it
|
||||
PutVerbose(command);
|
||||
}
|
||||
String result;
|
||||
int sleep = 0;
|
||||
int ms0 = msecs();
|
||||
while(dbg) {
|
||||
String s;
|
||||
LLOG("About to read");
|
||||
if(!dbg->Read(s)) {
|
||||
LLOG(result);
|
||||
LLOG("Read: " << result);
|
||||
PutVerbose(result);
|
||||
PutVerbose("Debugger terminated");
|
||||
break;
|
||||
}
|
||||
if(!s.IsEmpty() && Result(result, s)) {
|
||||
LLOG(result);
|
||||
LLOG("Processed " << result);
|
||||
PutVerbose(result);
|
||||
break;
|
||||
}
|
||||
GuiSleep(sleep);
|
||||
Ctrl::ProcessEvents();
|
||||
sleep = min(20, sleep + max(1, 3 * sleep / 2));
|
||||
LLOG("Unprocessed Result length: " << s);
|
||||
GuiSleep(0);
|
||||
if(ms0 != msecs()) {
|
||||
ProcessEvents();
|
||||
ms0 = msecs();
|
||||
}
|
||||
if(TTYQuit())
|
||||
Stop();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ uses
|
|||
HexView;
|
||||
|
||||
file
|
||||
Debuggers.h options PCH,
|
||||
Debuggers.h options(BUILDER_OPTION) PCH,
|
||||
Debuggers.iml,
|
||||
Gdb.lay,
|
||||
Terminal.cpp,
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ void DbgDisas::Clear()
|
|||
|
||||
void DbgDisas::Add(adr_t adr, const String& code, const String& args, const String& bytes)
|
||||
{
|
||||
DDUMP(code);
|
||||
DDUMP(args);
|
||||
if(adr < low)
|
||||
low = adr;
|
||||
if(adr > high)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "Debuggers.h"
|
||||
|
||||
#define PROMPT "<\xcd\xeb>"
|
||||
#define PROMPT "<wksuiherk" "bnuiohnsfoptmb>"
|
||||
|
||||
bool Gdb::Result(String& result, const String& s)
|
||||
{
|
||||
|
|
@ -87,81 +87,28 @@ void Gdb::SetDisas(const String& text)
|
|||
StringStream ss(text);
|
||||
while(!ss.IsEof()) {
|
||||
String ln = ss.GetLine();
|
||||
CParser p(ln);
|
||||
try {
|
||||
if(p.Char2('0', 'x')) {
|
||||
adr_t adr = p.IsNumber(16) ? (adr_t)p.ReadNumber64(16) : 0;
|
||||
String code;
|
||||
String args;
|
||||
int level = 0;
|
||||
while(!p.IsEof()) {
|
||||
if(p.Char(':') && level == 0)
|
||||
break;
|
||||
else
|
||||
if(p.Char('<'))
|
||||
level++;
|
||||
else
|
||||
if(p.Char('>'))
|
||||
level--;
|
||||
else
|
||||
p.GetChar();
|
||||
}
|
||||
p.Spaces();
|
||||
if(p.IsId()) {
|
||||
code = p.ReadId();
|
||||
for(;;) {
|
||||
if(p.Spaces())
|
||||
args.Cat(' ');
|
||||
if(p.IsEof())
|
||||
break;
|
||||
if(p.Char2('0', 'x')) {
|
||||
adr_t adr = 0;
|
||||
if(p.IsNumber(16))
|
||||
adr = (adr_t)p.ReadNumber64(16);
|
||||
String fname;
|
||||
bool usefname = false;
|
||||
if(p.Char('<')) {
|
||||
const char *b = p.GetPtr();
|
||||
int level = 1;
|
||||
usefname = true;
|
||||
while(!p.IsEof()) {
|
||||
if(p.Char('>') && --level == 0) {
|
||||
fname = String(b, p.GetPtr() - 1);
|
||||
break;
|
||||
}
|
||||
if(p.Char('<'))
|
||||
level++;
|
||||
if(p.Char('+'))
|
||||
usefname = false;
|
||||
else {
|
||||
p.GetChar();
|
||||
p.Spaces();
|
||||
}
|
||||
}
|
||||
}
|
||||
args << (usefname ? fname : Sprintf("0x%X", adr));
|
||||
disas.AddT(adr);
|
||||
}
|
||||
else
|
||||
if(p.Id("DWORD"))
|
||||
args.Cat("dword ");
|
||||
else
|
||||
if(p.Id("WORD"))
|
||||
args.Cat("word ");
|
||||
else
|
||||
if(p.Id("BYTE"))
|
||||
args.Cat("byte ");
|
||||
else
|
||||
if(p.Id("PTR"))
|
||||
args.Cat("ptr ");
|
||||
else
|
||||
args.Cat(p.GetChar());
|
||||
}
|
||||
}
|
||||
disas.Add(adr, code, args);
|
||||
}
|
||||
const char *s = ln;
|
||||
while(*s && !IsDigit(*s))
|
||||
s++;
|
||||
adr_t adr = 0;
|
||||
String code, args;
|
||||
if(s[0] == '0' && ToLower(s[1]) == 'x')
|
||||
adr = (adr_t)ScanInt64(s + 2, NULL, 16);
|
||||
int q = ln.Find(">:");
|
||||
if(q >= 0) {
|
||||
s = ~ln + q + 2;
|
||||
while(IsSpace(*s))
|
||||
s++;
|
||||
while(*s && !IsSpace(*s))
|
||||
code.Cat(*s++);
|
||||
while(IsSpace(*s))
|
||||
s++;
|
||||
args = s;
|
||||
q = args.Find("0x");
|
||||
if(q >= 0)
|
||||
disas.AddT(ScanInt(~args + q + 2, NULL, 16));
|
||||
disas.Add(adr, code, args);
|
||||
}
|
||||
catch(CParser::Error) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include "ide\Common/init"
|
||||
#include "plugin\ndisasm/init"
|
||||
#include "HexView/init"
|
||||
#define BLITZ_INDEX__ F2300ec0d3d2de4bde7af30102b728c5d
|
||||
#define BLITZ_INDEX__ Fa2117e771964dad617cdd6a1792596ea
|
||||
#include "UppSimplifiers.icpp"
|
||||
#undef BLITZ_INDEX__
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue