From 3ab7b0d27a09c62e6f4abd5604c5ced69d2cfdfe Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 26 Jan 2015 15:11:14 +0000 Subject: [PATCH] Painter: BufferPainter::PreClip #214 git-svn-id: svn://ultimatepp.org/upp/trunk@8094 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Painter/BufferPainter.h | 11 ++- uppsrc/Painter/Context.cpp | 2 + uppsrc/Painter/Painter.upp | 2 +- uppsrc/Painter/Render.cpp | 19 ++++- uppsrc/Painter/Stroker.cpp | 113 ++++++++++++++++++----------- uppsrc/ide/Debuggers/Dbg.cpp | 20 +++-- uppsrc/ide/Debuggers/Debuggers.upp | 2 +- uppsrc/ide/Debuggers/Disas.cpp | 2 + uppsrc/ide/Debuggers/Gdb.cpp | 97 ++++++------------------- uppsrc/ide/Debuggers/init | 2 +- 10 files changed, 137 insertions(+), 133 deletions(-) diff --git a/uppsrc/Painter/BufferPainter.h b/uppsrc/Painter/BufferPainter.h index 637a19ca0..fc30acf96 100644 --- a/uppsrc/Painter/BufferPainter.h +++ b/uppsrc/Painter/BufferPainter.h @@ -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 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); }; diff --git a/uppsrc/Painter/Context.cpp b/uppsrc/Painter/Context.cpp index 5930e48f1..2b8ef2a31 100644 --- a/uppsrc/Painter/Context.cpp +++ b/uppsrc/Painter/Context.cpp @@ -136,6 +136,8 @@ BufferPainter::BufferPainter(ImageBuffer& ib, int mode) pathattr = attr; gradientn = Null; + + dopreclip = false; } END_UPP_NAMESPACE diff --git a/uppsrc/Painter/Painter.upp b/uppsrc/Painter/Painter.upp index b092bfb60..f84e5eab9 100644 --- a/uppsrc/Painter/Painter.upp +++ b/uppsrc/Painter/Painter.upp @@ -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, diff --git a/uppsrc/Painter/Render.cpp b/uppsrc/Painter/Render.cpp index 37640c7fc..c049fb934 100644 --- a/uppsrc/Painter/Render.cpp +++ b/uppsrc/Painter/Render.cpp @@ -56,7 +56,24 @@ Buffer 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); diff --git a/uppsrc/Painter/Stroker.cpp b/uppsrc/Painter/Stroker.cpp index e7e3192c5..73b2c9635 100644 --- a/uppsrc/Painter/Stroker.cpp +++ b/uppsrc/Painter/Stroker.cpp @@ -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); } diff --git a/uppsrc/ide/Debuggers/Dbg.cpp b/uppsrc/ide/Debuggers/Dbg.cpp index 2097f3523..ab6622abf 100644 --- a/uppsrc/ide/Debuggers/Dbg.cpp +++ b/uppsrc/ide/Debuggers/Dbg.cpp @@ -1,6 +1,6 @@ #include "Debuggers.h" -#define LLOG(x) // LOG(x) +#define LLOG(x) LOG(x) #define IMAGECLASS DbgImg #define IMAGEFILE @@ -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(); } diff --git a/uppsrc/ide/Debuggers/Debuggers.upp b/uppsrc/ide/Debuggers/Debuggers.upp index d5db62db4..5f2ad3d3c 100644 --- a/uppsrc/ide/Debuggers/Debuggers.upp +++ b/uppsrc/ide/Debuggers/Debuggers.upp @@ -6,7 +6,7 @@ uses HexView; file - Debuggers.h options PCH, + Debuggers.h options(BUILDER_OPTION) PCH, Debuggers.iml, Gdb.lay, Terminal.cpp, diff --git a/uppsrc/ide/Debuggers/Disas.cpp b/uppsrc/ide/Debuggers/Disas.cpp index f5f6d43e9..3a40d78a9 100644 --- a/uppsrc/ide/Debuggers/Disas.cpp +++ b/uppsrc/ide/Debuggers/Disas.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) diff --git a/uppsrc/ide/Debuggers/Gdb.cpp b/uppsrc/ide/Debuggers/Gdb.cpp index 71efe193f..20ea7c41d 100644 --- a/uppsrc/ide/Debuggers/Gdb.cpp +++ b/uppsrc/ide/Debuggers/Gdb.cpp @@ -1,6 +1,6 @@ #include "Debuggers.h" -#define PROMPT "<\xcd\xeb>" +#define PROMPT "" 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) {} } } diff --git a/uppsrc/ide/Debuggers/init b/uppsrc/ide/Debuggers/init index f64473c93..d686fb29e 100644 --- a/uppsrc/ide/Debuggers/init +++ b/uppsrc/ide/Debuggers/init @@ -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