mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-25 14:22:54 -06:00
ide: IconDes optimisations
This commit is contained in:
parent
91165d0400
commit
81ebe5dbee
13 changed files with 290 additions and 215 deletions
|
|
@ -8,7 +8,8 @@ enum ImageKind {
|
|||
IMAGE_OPAQUE,
|
||||
};
|
||||
|
||||
inline void Fill(RGBA *t, RGBA c, size_t n) { memset32(t, *(dword *)&c, n); }
|
||||
inline void Fill(RGBA *t, RGBA c, size_t n) { memset32(t, *(dword *)&c, n); }
|
||||
void FillDown(RGBA *t, int linecy, RGBA c, int cy);
|
||||
inline void Copy(RGBA *t, const RGBA *s, int n) { memcpy_t(t, s, n); }
|
||||
|
||||
int Premultiply(RGBA *t, const RGBA *s, size_t len);
|
||||
|
|
@ -256,6 +257,7 @@ struct ImageIml : Moveable<ImageIml> {
|
|||
dword flags = 0;
|
||||
};
|
||||
|
||||
Vector<ImageIml> UnpackImlDataUncompressed(const String& data);
|
||||
Vector<ImageIml> UnpackImlData(const void *ptr, int len);
|
||||
Vector<ImageIml> UnpackImlData(const String& d);
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,25 @@ int Premultiply(RGBA *t, const RGBA *s, size_t len)
|
|||
return IMAGE_OPAQUE;
|
||||
}
|
||||
|
||||
void FillDown(RGBA *t, int linecy, RGBA c, int cy)
|
||||
{
|
||||
for(int n = cy >> 3; n; n--) {
|
||||
t[0] = t[linecy] = t[2 * linecy] = t[3 * linecy] =
|
||||
t[4 * linecy] = t[5 * linecy] = t[6 * linecy] = t[7 * linecy] = c;
|
||||
t += 8 * linecy;
|
||||
}
|
||||
if(cy & 4) {
|
||||
t[0] = t[linecy] = t[2 * linecy] = t[3 * linecy] = c;
|
||||
t += 4 * linecy;
|
||||
}
|
||||
if(cy & 2) {
|
||||
t[0] = t[linecy] = c;
|
||||
t += 2 * linecy;
|
||||
}
|
||||
if(cy & 1)
|
||||
t[0] = c;
|
||||
}
|
||||
|
||||
int um_table__[256];
|
||||
|
||||
void sInitUmTable__()
|
||||
|
|
|
|||
|
|
@ -86,22 +86,28 @@ force_inline Size DstSrc(ImageBuffer& dest, Point& p, const Image& src, Rect& sr
|
|||
}
|
||||
|
||||
void DstSrcOp(ImageBuffer& dest, Point p, const Image& src, const Rect& srect,
|
||||
void (*op)(RGBA *t, const RGBA *s, int n))
|
||||
void (*op)(RGBA *t, const RGBA *s, int n), bool co)
|
||||
{
|
||||
dest.SetResolution(src.GetResolution());
|
||||
Rect sr = srect;
|
||||
Size sz = DstSrc(dest, p, src, sr);
|
||||
if(sz.cx > 0)
|
||||
while(--sz.cy >= 0)
|
||||
(*op)(dest[p.y++] + p.x, src[sr.top++] + sr.left, sz.cx);
|
||||
if(sz.cx > 0) {
|
||||
if(co)
|
||||
CoFor(sz.cy, [&](int i) {
|
||||
(*op)(dest[p.y + i] + p.x, src[sr.top + i] + sr.left, sz.cx);
|
||||
});
|
||||
else
|
||||
while(--sz.cy >= 0)
|
||||
(*op)(dest[p.y++] + p.x, src[sr.top++] + sr.left, sz.cx);
|
||||
}
|
||||
}
|
||||
|
||||
void Copy(ImageBuffer& dest, Point p, const Image& src, const Rect& srect)
|
||||
void Copy(ImageBuffer& dest, Point p, const Image& src, const Rect& srect, bool co)
|
||||
{
|
||||
DstSrcOp(dest, p, src, srect, Copy);
|
||||
}
|
||||
|
||||
void Over(ImageBuffer& dest, Point p, const Image& src, const Rect& srect)
|
||||
void Over(ImageBuffer& dest, Point p, const Image& src, const Rect& srect, bool co)
|
||||
{
|
||||
DstSrcOp(dest, p, src, srect, AlphaBlend);
|
||||
}
|
||||
|
|
@ -113,7 +119,7 @@ Image GetOver(const Image& dest, const Image& src)
|
|||
return r;
|
||||
}
|
||||
|
||||
Image Copy(const Image& src, const Rect& srect)
|
||||
Image Copy(const Image& src, const Rect& srect, bool co)
|
||||
{
|
||||
ImageBuffer ib(srect.GetSize());
|
||||
Copy(ib, Point(0, 0), src, srect);
|
||||
|
|
@ -129,30 +135,30 @@ void Fill(ImageBuffer& dest, const Rect& rect, RGBA color)
|
|||
Fill(dest[y] + r.left, color, cx);
|
||||
}
|
||||
|
||||
void OverStraightOpaque(ImageBuffer& dest, Point p, const Image& src, const Rect& srect)
|
||||
void OverStraightOpaque(ImageBuffer& dest, Point p, const Image& src, const Rect& srect, bool co)
|
||||
{
|
||||
DstSrcOp(dest, p, src, srect, AlphaBlendStraightOpaque);
|
||||
}
|
||||
|
||||
void Copy(Image& dest, Point p, const Image& _src, const Rect& srect)
|
||||
void Copy(Image& dest, Point p, const Image& _src, const Rect& srect, bool co)
|
||||
{
|
||||
Image src = _src;
|
||||
ImageBuffer b(dest);
|
||||
Copy(b, p, src, srect);
|
||||
Copy(b, p, src, srect, co);
|
||||
dest = b;
|
||||
}
|
||||
|
||||
void Over(Image& dest, Point p, const Image& _src, const Rect& srect)
|
||||
void Over(Image& dest, Point p, const Image& _src, const Rect& srect, bool co)
|
||||
{
|
||||
Image src = _src;
|
||||
ImageBuffer b(dest);
|
||||
Over(b, p, src, srect);
|
||||
Over(b, p, src, srect, co);
|
||||
dest = b;
|
||||
}
|
||||
|
||||
void Over(Image& dest, const Image& _src)
|
||||
void Over(Image& dest, const Image& _src, bool co)
|
||||
{
|
||||
Over(dest, Point(0, 0), _src, _src.GetSize());
|
||||
Over(dest, Point(0, 0), _src, _src.GetSize(), co);
|
||||
}
|
||||
|
||||
void Fill(Image& dest, const Rect& rect, RGBA color)
|
||||
|
|
@ -162,11 +168,11 @@ void Fill(Image& dest, const Rect& rect, RGBA color)
|
|||
dest = b;
|
||||
}
|
||||
|
||||
void OverStraightOpaque(Image& dest, Point p, const Image& _src, const Rect& srect)
|
||||
void OverStraightOpaque(Image& dest, Point p, const Image& _src, const Rect& srect, bool co)
|
||||
{
|
||||
Image src = _src;
|
||||
ImageBuffer b(dest);
|
||||
OverStraightOpaque(b, p, src, srect);
|
||||
OverStraightOpaque(b, p, src, srect, co);
|
||||
dest = b;
|
||||
}
|
||||
|
||||
|
|
@ -190,7 +196,7 @@ Image Crop(const Image& img, const Rect& rc)
|
|||
return WithResolution(tgt, img);
|
||||
}
|
||||
|
||||
Image AddMargins(const Image& img, int left, int top, int right, int bottom, RGBA color)
|
||||
Image AddMargins(const Image& img, int left, int top, int right, int bottom, RGBA color, bool co)
|
||||
{
|
||||
Size sz = img.GetSize();
|
||||
ImageBuffer ib(sz.cx + left + right, sz.cy + top + bottom);
|
||||
|
|
|
|||
|
|
@ -13,22 +13,24 @@ Image WithResolution(const Image& m, const Image& res);
|
|||
|
||||
void ScanOpaque(Image& m);
|
||||
void DstSrcOp(ImageBuffer& dest, Point p, const Image& src, const Rect& srect,
|
||||
void (*op)(RGBA *t, const RGBA *s, int n));
|
||||
void (*op)(RGBA *t, const RGBA *s, int n), bool co = false);
|
||||
|
||||
void Copy(ImageBuffer& dest, Point p, const Image& src, const Rect& srect, bool co = false);
|
||||
|
||||
void Over(ImageBuffer& dest, Point p, const Image& src, const Rect& srect, bool co = false);
|
||||
void Over(Image& dest, Point p, const Image& _src, const Rect& srect, bool co = false);
|
||||
void Over(Image& dest, const Image& _src, bool co = false);
|
||||
|
||||
void Over(ImageBuffer& dest, Point p, const Image& src, const Rect& srect);
|
||||
void Over(Image& dest, const Image& src);
|
||||
void Copy(ImageBuffer& dest, Point p, const Image& src, const Rect& srect);
|
||||
void Fill(ImageBuffer& dest, const Rect& rect, RGBA color);
|
||||
|
||||
void Copy(Image& dest, Point p, const Image& src, const Rect& srect);
|
||||
void Over(Image& dest, Point p, const Image& src, const Rect& srect);
|
||||
void Copy(Image& dest, Point p, const Image& src, const Rect& srect, bool co = false);
|
||||
Image GetOver(const Image& dest, const Image& src);
|
||||
void Fill(Image& dest, const Rect& rect, RGBA color);
|
||||
|
||||
Image Copy(const Image& src, const Rect& srect);
|
||||
|
||||
void OverStraightOpaque(ImageBuffer& dest, Point p, const Image& src, const Rect& srect);
|
||||
void OverStraightOpaque(Image& dest, Point p, const Image& _src, const Rect& srect);
|
||||
void OverStraightOpaque(ImageBuffer& dest, Point p, const Image& src, const Rect& srect, bool co = false);
|
||||
void OverStraightOpaque(Image& dest, Point p, const Image& _src, const Rect& srect, bool co = false);
|
||||
|
||||
void Crop(RasterEncoder& tgt, Raster& img, const Rect& rc);
|
||||
Image Crop(const Image& img, const Rect& rc);
|
||||
|
|
@ -241,6 +243,7 @@ Image CachedRescalePaintOnly(const Image& m, Size sz, int filter = Null);
|
|||
Image CachedSetColorKeepAlpha(const Image& img, Color color);
|
||||
Image CachedSetColorKeepAlphaPaintOnly(const Image& img, Color color);
|
||||
|
||||
Image Magnify(const Image& img, const Rect& src, int nx, int ny, bool co);
|
||||
Image Magnify(const Image& img, int nx, int ny);
|
||||
Image Minify(const Image& img, int nx, int ny, bool co = false);
|
||||
Image MinifyCached(const Image& img, int nx, int ny, bool co = false);
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
namespace Upp {
|
||||
|
||||
Vector<ImageIml> UnpackImlData(const void *ptr, int len)
|
||||
Vector<ImageIml> UnpackImlDataUncompressed(const String& data)
|
||||
{
|
||||
Vector<ImageIml> img;
|
||||
String data = ZDecompress(ptr, len);
|
||||
const char *s = data;
|
||||
while(s + 6 * 2 + 1 <= data.End()) {
|
||||
ImageIml& m = img.Add();
|
||||
|
|
@ -35,6 +34,11 @@ Vector<ImageIml> UnpackImlData(const void *ptr, int len)
|
|||
return img;
|
||||
}
|
||||
|
||||
Vector<ImageIml> UnpackImlData(const void *ptr, int len)
|
||||
{
|
||||
return UnpackImlDataUncompressed(ZDecompress(ptr, len));
|
||||
}
|
||||
|
||||
Vector<ImageIml> UnpackImlData(const String& d)
|
||||
{
|
||||
return UnpackImlData(~d, d.GetLength());
|
||||
|
|
|
|||
|
|
@ -179,24 +179,22 @@ Image MinifyCached(const Image& img, int nx, int ny, bool co)
|
|||
return MakeImage(m);
|
||||
}
|
||||
|
||||
Image Magnify(const Image& img, int nx, int ny)
|
||||
Image Magnify(const Image& img, const Rect& src_, int nx, int ny, bool co)
|
||||
{
|
||||
if(nx == 1 && ny == 1)
|
||||
return img;
|
||||
if(nx == 0 || ny == 0)
|
||||
return Image();
|
||||
Size sz = img.GetSize();
|
||||
Rect src = src_ & img.GetSize();
|
||||
bool xdown = nx < 0;
|
||||
nx = abs(nx);
|
||||
int ncx = xdown ? sz.cx / nx : sz.cx * nx;
|
||||
ImageBuffer b(ncx, sz.cy * ny);
|
||||
const RGBA *s = ~img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
RGBA *t = ~b;
|
||||
while(s < e) {
|
||||
Size ssz = src.GetSize();
|
||||
if(ssz.cx <= 0 || ssz.cy <= 0 || nx == 0 || ny == 0)
|
||||
return Image();
|
||||
int ncx = xdown ? ssz.cx / nx : ssz.cx * nx;
|
||||
ImageBuffer b(ncx, ssz.cy * ny);
|
||||
CoFor(co, ssz.cy, [&](int y) {
|
||||
const RGBA *s = img[src.top + y] + src.left;
|
||||
const RGBA *e = s + ssz.cx;
|
||||
RGBA *t = ~b + y * ncx * ny;
|
||||
RGBA *q = t;
|
||||
const RGBA *le = s + sz.cx;
|
||||
while(s < le) {
|
||||
while(s < e) {
|
||||
Fill(q, *s, nx);
|
||||
q += nx;
|
||||
s++;
|
||||
|
|
@ -205,10 +203,16 @@ Image Magnify(const Image& img, int nx, int ny)
|
|||
memcpy(q, t, ncx * sizeof(RGBA));
|
||||
q += ncx;
|
||||
}
|
||||
t = q;
|
||||
}
|
||||
});
|
||||
b.SetResolution(img.GetResolution());
|
||||
return b;
|
||||
}
|
||||
|
||||
Image Magnify(const Image& img, int nx, int ny)
|
||||
{
|
||||
if(nx == 1 && ny == 1)
|
||||
return img;
|
||||
return Magnify(img, img.GetSize(), nx, ny, false);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -32,7 +32,7 @@ void IconDes::SetMagnify(int mag)
|
|||
if( !IsCurrent() )
|
||||
return;
|
||||
|
||||
magnify = minmax(mag, 1, 27);
|
||||
magnify = minmax(mag, 1, 50);
|
||||
|
||||
sb = Point(0, 0);
|
||||
SetSb();
|
||||
|
|
@ -204,11 +204,11 @@ void IconDes::DrawBar(Bar& bar)
|
|||
bar.Add(c, "Supersample 3x", IconDesImg::ResizeDown(), THISBACK(ResizeDown))
|
||||
.Key(AK_RESIZEDOWN3);
|
||||
bar.Add("Show UHD/Dark syntetics", IconDesImg::ShowOther(),
|
||||
[=] { show_other = !show_other; show_small = false; SyncShow(); SetBar(); })
|
||||
.Check(show_other);
|
||||
[=] { show_synthetics = !show_synthetics; show_downscaled = false; SyncShow(); SetBar(); })
|
||||
.Check(show_synthetics);
|
||||
bar.Add("Show downscaled", IconDesImg::ShowSmall(),
|
||||
[=] { show_small = !show_small; show_other = false; SyncShow(); SetBar(); })
|
||||
.Check(show_small);
|
||||
[=] { show_downscaled = !show_downscaled; show_synthetics = false; SyncShow(); SetBar(); })
|
||||
.Check(show_downscaled);
|
||||
bar.Add("Show secondardy grid", IconDesImg::grid2(),
|
||||
[=] { show_grid2 = !show_grid2; Refresh(); SetBar(); })
|
||||
.Check(show_grid2);
|
||||
|
|
@ -324,12 +324,12 @@ void IconDes::SerializeSettings(Stream& s)
|
|||
s % ImgFile();
|
||||
if(version >= 3) {
|
||||
bool b = false;
|
||||
s % b % show_small;
|
||||
s % b % show_downscaled;
|
||||
}
|
||||
if(version >= 4)
|
||||
s % paste_mode;
|
||||
if(version >= 5)
|
||||
s % show_other;
|
||||
s % show_synthetics;
|
||||
if(version >= 6)
|
||||
s % show_grid2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ void IconDes::SyncShow()
|
|||
Slot& c = Current();
|
||||
Image image = c.image;
|
||||
iconshow.image = image;
|
||||
iconshow.show_small = show_small;
|
||||
iconshow.show_other = show_other;
|
||||
iconshow.show_downscaled = show_downscaled;
|
||||
iconshow.show_synthetics = show_synthetics;
|
||||
ilist.Set(2, RawToValue(MakeTuple(image, c.flags)));
|
||||
}
|
||||
iconshow.Refresh();
|
||||
|
|
@ -83,7 +83,7 @@ void IconDes::HorzMouseWheel(Point pt, int zdelta, dword keyflags)
|
|||
void IconDes::Scroll()
|
||||
{
|
||||
magnify = max(magnify, 1);
|
||||
scroller.Scroll(*this, GetSize(), sb, Size(magnify, magnify));
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void IconDes::Layout()
|
||||
|
|
@ -465,19 +465,29 @@ void IconDes::SelectRect()
|
|||
SetBar();
|
||||
}
|
||||
|
||||
String PackUndo(const Vector<ImageIml>& img)
|
||||
{
|
||||
return FastCompress(PackImlDataUncompressed(img));
|
||||
}
|
||||
|
||||
Vector<ImageIml> UnpackUndo(const String& data)
|
||||
{
|
||||
return UnpackImlDataUncompressed(FastDecompress(data));
|
||||
}
|
||||
|
||||
void IconDes::SaveUndo()
|
||||
{
|
||||
if(!IsCurrent())
|
||||
return;
|
||||
Slot& c = Current();
|
||||
Vector<ImageIml> undo = UnpackImlData(c.undo);
|
||||
int maxn = minmax((single_mode ? 4000000 : 400000) / max((int)c.image.GetLength(), 1), 4, 128);
|
||||
Vector<ImageIml> undo = UnpackUndo(c.undo);
|
||||
int maxn = minmax((single_mode ? 40000000 : 2000000) / max((int)c.image.GetLength(), 1), 4, 128);
|
||||
while(undo.GetCount() > maxn)
|
||||
undo.Remove(0);
|
||||
if(undo.GetCount() && undo.Top().image == c.image)
|
||||
return;
|
||||
undo.Add().image = c.image;
|
||||
c.undo = PackImlData(undo);
|
||||
c.undo = PackUndo(undo);
|
||||
c.redo.Clear();
|
||||
SetBar();
|
||||
undo.Clear();
|
||||
|
|
@ -488,14 +498,14 @@ void IconDes::Undo()
|
|||
if(!IsCurrent())
|
||||
return;
|
||||
Slot& c = Current();
|
||||
Vector<ImageIml> undo = UnpackImlData(c.undo);
|
||||
Vector<ImageIml> undo = UnpackUndo(c.undo);
|
||||
if(undo.GetCount() == 0)
|
||||
return;
|
||||
Vector<ImageIml> redo = UnpackImlData(c.redo);
|
||||
Vector<ImageIml> redo = UnpackUndo(c.redo);
|
||||
redo.Add().image = c.image;
|
||||
c.image = undo.Pop().image;
|
||||
c.undo = PackImlData(undo);
|
||||
c.redo = PackImlData(redo);
|
||||
c.undo = PackUndo(undo);
|
||||
c.redo = PackUndo(redo);
|
||||
SyncImage();
|
||||
SetBar();
|
||||
}
|
||||
|
|
@ -505,14 +515,14 @@ void IconDes::Redo()
|
|||
if(!IsCurrent())
|
||||
return;
|
||||
Slot& c = Current();
|
||||
Vector<ImageIml> redo = UnpackImlData(c.redo);
|
||||
Vector<ImageIml> redo = UnpackUndo(c.redo);
|
||||
if(redo.GetCount() == 0)
|
||||
return;
|
||||
Vector<ImageIml> undo = UnpackImlData(c.undo);
|
||||
Vector<ImageIml> undo = UnpackUndo(c.undo);
|
||||
undo.Add().image = c.image;
|
||||
c.image = redo.Pop().image;
|
||||
c.undo = PackImlData(undo);
|
||||
c.redo = PackImlData(redo);
|
||||
c.undo = PackUndo(undo);
|
||||
c.redo = PackUndo(redo);
|
||||
SyncImage();
|
||||
SetBar();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ public:
|
|||
|
||||
struct IconShow : public Ctrl {
|
||||
Image image;
|
||||
bool show_small;
|
||||
bool show_other;
|
||||
bool show_downscaled;
|
||||
bool show_synthetics;
|
||||
|
||||
void Paint(Draw& w);
|
||||
|
||||
|
|
@ -105,9 +105,10 @@ void FloodFill(ImageBuffer& img, RGBA color, Point pt, const Rect& rc, int tol
|
|||
void InterpolateImage(Image& img, const Rect& _rc);
|
||||
void MirrorHorz(Image& img, const Rect& rect);
|
||||
void MirrorVert(Image& img, const Rect& rect);
|
||||
String PackImlDataUncompressed(const Vector<ImageIml>& image);
|
||||
String PackImlData(const Vector<ImageIml>& image);
|
||||
Image DownSample3x(const Image& src);
|
||||
Image DownSample2x(const Image& src);
|
||||
Image DownSample3x(const Image& src, bool co = false);
|
||||
Image DownSample2x(const Image& src, bool co = false);
|
||||
|
||||
/*
|
||||
struct IconDraw : ImagePainter {
|
||||
|
|
@ -177,12 +178,11 @@ private:
|
|||
bool doselection = false;
|
||||
bool selectrect = false;
|
||||
int paste_mode;
|
||||
bool show_other = false;
|
||||
bool show_small = false;
|
||||
bool show_synthetics = false;
|
||||
bool show_downscaled = false;
|
||||
bool show_grid2 = false;
|
||||
|
||||
ScrollBars sb;
|
||||
Scroller scroller;
|
||||
ToolBar toolbar;
|
||||
|
||||
SplitterFrame leftpane;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ void IconDes::KeyMove(int dx, int dy)
|
|||
else {
|
||||
Image h = c.image;
|
||||
c.image = CreateImage(h.GetSize(), Null);
|
||||
UPP::Copy(c.image, Point(dx, dy), h, h.GetSize());
|
||||
UPP::Copy(c.image, Point(dx, dy), h, h.GetSize(), true);
|
||||
}
|
||||
Sync();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ void MirrorVert(Image& img, const Rect& rect)
|
|||
img = ib;
|
||||
}
|
||||
|
||||
String PackImlData(const Vector<ImageIml>& image)
|
||||
String PackImlDataUncompressed(const Vector<ImageIml>& image)
|
||||
{
|
||||
StringBuffer block;
|
||||
for(const ImageIml& m : image) {
|
||||
|
|
@ -181,16 +181,21 @@ String PackImlData(const Vector<ImageIml>& image)
|
|||
s++;
|
||||
}
|
||||
}
|
||||
return ZCompress(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
Image DownSample3x(const Image& src)
|
||||
String PackImlData(const Vector<ImageIml>& image)
|
||||
{
|
||||
return ZCompress(PackImlDataUncompressed(image));
|
||||
}
|
||||
|
||||
Image DownSample3x(const Image& src, bool co)
|
||||
{
|
||||
Size tsz = src.GetSize() / 3;
|
||||
ImageBuffer ib(tsz);
|
||||
int w = src.GetSize().cx;
|
||||
int w2 = 2 * w;
|
||||
for(int y = 0; y < tsz.cy; y++) {
|
||||
CoFor(co, tsz.cy, [&](int y) {
|
||||
RGBA *t = ib[y];
|
||||
RGBA *e = t + tsz.cx;
|
||||
const RGBA *s = src[3 * y];
|
||||
|
|
@ -210,17 +215,17 @@ Image DownSample3x(const Image& src)
|
|||
t++;
|
||||
s += 3;
|
||||
}
|
||||
}
|
||||
});
|
||||
ib.SetResolution(src.GetResolution());
|
||||
return ib;
|
||||
}
|
||||
|
||||
Image DownSample2x(const Image& src)
|
||||
Image DownSample2x(const Image& src, bool co)
|
||||
{
|
||||
Size tsz = src.GetSize() / 2;
|
||||
ImageBuffer ib(tsz);
|
||||
int w = src.GetSize().cx;
|
||||
for(int y = 0; y < tsz.cy; y++) {
|
||||
CoFor(co, tsz.cy, [&](int y) {
|
||||
RGBA *t = ib[y];
|
||||
RGBA *e = t + tsz.cx;
|
||||
const RGBA *s = src[2 * y];
|
||||
|
|
@ -239,7 +244,7 @@ Image DownSample2x(const Image& src)
|
|||
t++;
|
||||
s += 2;
|
||||
}
|
||||
}
|
||||
});
|
||||
ib.SetResolution(src.GetResolution());
|
||||
return ib;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,36 +9,69 @@ namespace Upp {
|
|||
void IconShow::Paint(Draw& w)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
static Color color[] = { White(), WhiteGray(), LtGray(), Gray(), Black(),
|
||||
static Color color[] = { White(), Black(), WhiteGray(), LtGray(), Gray(),
|
||||
Yellow(), Brown(), Red(), Green(), Blue(), Cyan(), Magenta() };
|
||||
Size msz = image.GetSize();
|
||||
Size isz = msz;
|
||||
if(show_small)
|
||||
isz.cx += isz.cx / 2 + DPI(4);
|
||||
int n = msz.cx ? minmax(sz.cx / isz.cx, 1, __countof(color)) : 1;
|
||||
Image m2, m3;
|
||||
if(msz.cx && show_small) {
|
||||
m2 = DownSample2x(image);
|
||||
m3 = DownSample3x(image);
|
||||
int gap = DPI(8);
|
||||
double fits = msz.cx * msz.cy < 20000;
|
||||
if(fits) {
|
||||
if(show_downscaled) {
|
||||
isz.cx += (isz.cx + 1) / 2 + gap;
|
||||
isz.cy += max(isz.cy, (isz.cy + 1) / 2 + (isz.cy + 2) / 3 + gap);
|
||||
}
|
||||
if(show_synthetics) {
|
||||
isz.cx += 3 * isz.cx + gap;
|
||||
isz.cy += 2 * isz.cy + gap;
|
||||
}
|
||||
}
|
||||
int n = sz.cx ? clamp(sz.cx / isz.cx, 1, __countof(color)) : 1;
|
||||
int ncx = sz.cx / n;
|
||||
Image m2, m3;
|
||||
Image dk, up2, up2dk;
|
||||
if(fits) {
|
||||
if(msz.cx && show_downscaled) {
|
||||
m2 = DownSample2x(image);
|
||||
m3 = DownSample3x(image);
|
||||
}
|
||||
if(show_synthetics) {
|
||||
dk = DarkTheme(image);
|
||||
up2 = Upscale2x(image);
|
||||
up2dk = Upscale2x(DarkTheme(image));
|
||||
}
|
||||
}
|
||||
else
|
||||
isz = msz;
|
||||
|
||||
for(int i = 0; i < n; i++) {
|
||||
int x = i * sz.cx / n;
|
||||
int cx = (i + 1) * sz.cx / n - x;
|
||||
int x = i * ncx;
|
||||
int cx = (i + 1) * ncx - x;
|
||||
w.DrawRect(x, 0, cx, sz.cy, color[i]);
|
||||
if(msz.cx) {
|
||||
if(show_other) {
|
||||
Point c(x + cx / 2, sz.cy / 2);
|
||||
w.DrawImage(c.x - DPI(8) - isz.cx, c.y - DPI(8) - isz.cy, image);
|
||||
w.DrawImage(c.x + DPI(8), c.y - DPI(8) - isz.cy, DarkTheme(image));
|
||||
w.DrawImage(c.x - DPI(8) - isz.cx, c.y + DPI(8), Upscale2x(image));
|
||||
w.DrawImage(c.x + DPI(8), c.y + DPI(8), Upscale2x(DarkTheme(image)));
|
||||
Point pos(x + (cx - isz.cx) / 2, (sz.cy - isz.cy) / 2);
|
||||
if(fits) {
|
||||
if(show_synthetics) {
|
||||
int x2 = pos.x + 2 * msz.cx + gap;
|
||||
w.DrawImage(pos.x, pos.y, image);
|
||||
w.DrawImage(x2, pos.y, dk);
|
||||
pos.y += msz.cy + gap;
|
||||
w.DrawImage(pos.x, pos.y, up2);
|
||||
w.DrawImage(x2, pos.y, up2dk);
|
||||
}
|
||||
else {
|
||||
int y = pos.y + (isz.cy - msz.cy) / 2;
|
||||
w.DrawImage(pos.x, y, image);
|
||||
if(show_downscaled) {
|
||||
int x2 = pos.x + msz.cx + gap;
|
||||
w.DrawImage(x2, y, m2);
|
||||
w.DrawImage(x2, y + (msz.cx + 1) / 2 + gap, m3);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
w.DrawImage(x + (cx - isz.cx) / 2, (sz.cy - isz.cy) / 2, image);
|
||||
if(show_small) {
|
||||
w.DrawImage(x + (cx - isz.cx) / 2 + msz.cx + DPI(4), (sz.cy - isz.cy) / 2, m2);
|
||||
w.DrawImage(x + (cx - isz.cx) / 2 + msz.cx + DPI(4), (sz.cy - isz.cy) / 2 + 2 * msz.cy / 3, m3);
|
||||
}
|
||||
w.Clip(x, 0, isz.cx, sz.cy);
|
||||
w.DrawImage(x + DPI(2), DPI(2), image);
|
||||
w.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -59,7 +92,6 @@ void IconDes::Paint(Draw& w)
|
|||
const Image& image = Current().image;
|
||||
const Image& selection = Current().selection;
|
||||
Point spos = sb;
|
||||
scroller.Set(spos);
|
||||
Size isz = image.GetSize();
|
||||
bool pastepaint = HasCapture() && IsPasting();
|
||||
magnify = max(magnify, 1);
|
||||
|
|
@ -68,17 +100,17 @@ void IconDes::Paint(Draw& w)
|
|||
ImageBuffer pb(isz);
|
||||
RGBA c1 = GrayColor(102);
|
||||
RGBA c2 = GrayColor(153);
|
||||
int xn = isz.cx / 4;
|
||||
int xn = isz.cx / DPI(4);
|
||||
for(int y = 0; y < isz.cy; y++) {
|
||||
RGBA *b = pb[y];
|
||||
RGBA cc1 = c1;
|
||||
RGBA cc2 = c2;
|
||||
if(y & 4)
|
||||
if(y & DPI(4))
|
||||
Swap(cc1, cc2);
|
||||
for(int q = xn; q--;) {
|
||||
b[0] = b[1] = b[2] = b[3] = cc1;
|
||||
Fill(b, cc1, DPI(4));
|
||||
Swap(cc1, cc2);
|
||||
b += 4;
|
||||
b += DPI(4);
|
||||
}
|
||||
while(b < pb[y] + isz.cx)
|
||||
*b++ = cc1;
|
||||
|
|
@ -99,126 +131,115 @@ void IconDes::Paint(Draw& w)
|
|||
w.DrawImage(-spos.x, -spos.y, pb);
|
||||
Rect r = pb.GetSize();
|
||||
r.Offset(-spos);
|
||||
w.DrawRect(r.right, 0, 1, r.bottom + 1, LtRed());
|
||||
w.DrawRect(0, r.bottom, r.right, 1, LtRed());
|
||||
if(show_grid2) {
|
||||
w.DrawRect(r.right, 0, 1, r.bottom + 1, LtRed());
|
||||
w.DrawRect(0, r.bottom, r.right, 1, LtRed());
|
||||
}
|
||||
m1refresh = Null;
|
||||
if(IsPasting())
|
||||
DrawFrame(w, Rect(Current().pastepos - spos, Current().paste_image.GetSize()), LtRed);
|
||||
return;
|
||||
}
|
||||
Point hotspot = image.GetHotSpot();
|
||||
Point spot2 = image.Get2ndSpot();
|
||||
int m = isz.cx * magnify + 1;
|
||||
Point mpos = magnify * spos;
|
||||
int grid2 = 0;
|
||||
if(max(isz.cx, isz.cy) > 16 && show_grid2) {
|
||||
if(isz.cx % 3 == 0 && isz.cy % 3 == 0)
|
||||
grid2 = 3;
|
||||
else
|
||||
if(isz.cx % 4 == 0 && isz.cy % 4 == 0)
|
||||
grid2 = 4;
|
||||
}
|
||||
auto GridColor = [&](int x, int sz) -> Color {
|
||||
if(grid2) {
|
||||
if(x == sz / 2)
|
||||
return LtMagenta();
|
||||
if(x % grid2 == 0)
|
||||
return LtRed();
|
||||
}
|
||||
return Black();
|
||||
};
|
||||
for(int y = isz.cy; y >= 0; y--)
|
||||
w.DrawRect(-mpos.x, magnify * y - mpos.y, m, 1, GridColor(y, isz.cy));
|
||||
m = isz.cy * magnify + 1;
|
||||
for(int x = isz.cx; x >= 0; x--)
|
||||
w.DrawRect(magnify * x - mpos.x, -mpos.y, 1, m, GridColor(x, isz.cx));
|
||||
if(!IsHotSpot()) {
|
||||
hotspot = Null;
|
||||
spot2 = Null;
|
||||
}
|
||||
w.DrawRect(isz.cx * magnify - mpos.x + 1, 0, 9999, 9999, SColorPaper());
|
||||
w.DrawRect(0, isz.cy * magnify - mpos.y + 1, 9999, 9999, SColorPaper());
|
||||
int my0 = -magnify * spos.y;
|
||||
int magnify4 = 4 * magnify;
|
||||
int md = (magnify + 1) / 2;
|
||||
int mc = (magnify - 1) / 2;
|
||||
Image masked = Crop(IconDesImg::Masked(), Size(magnify - 1, magnify - 1));
|
||||
for(int y0 = 0; y0 < isz.cy; y0 += 4, my0 += magnify4) {
|
||||
int mx0 = -magnify * spos.x;
|
||||
for(int x0 = 0; x0 < isz.cx; x0 += 4, mx0 += magnify4) {
|
||||
if(w.IsPainting(mx0, my0, magnify4, magnify4)) {
|
||||
int ex = min(x0 + 4, isz.cx);
|
||||
int my = my0;
|
||||
for(int y = y0; y < min(y0 + 4, isz.cy); y++, my += magnify) {
|
||||
const RGBA *s = image[y] + x0;
|
||||
const RGBA *k = selection[y] + x0;
|
||||
const RGBA *pk = y ? selection[y - 1] + x0 : NULL;
|
||||
const RGBA *nk = y + 1 < isz.cy ? selection[y + 1] + x0 : NULL;
|
||||
int mx = mx0;
|
||||
for(int x = x0; x < ex; x++) {
|
||||
if(s->a == 255)
|
||||
w.DrawRect(mx + 1, my + 1, magnify - 1, magnify - 1, *s);
|
||||
else { // paint chequered background
|
||||
Color c = StraightColor(*s);
|
||||
Color c1 = Blend(GrayColor(102), c, s->a);
|
||||
w.DrawRect(mx + 1, my + 1, magnify - 1, magnify - 1, c1);
|
||||
Color c2 = Blend(GrayColor(153), c, s->a);
|
||||
w.DrawRect(mx + md, my + 1, mc, mc, c2);
|
||||
w.DrawRect(mx + 1, my + md, mc, mc, c2);
|
||||
}
|
||||
if(!pastepaint)
|
||||
if(!k->r) {
|
||||
w.DrawImage(mx + 1, my + 1, masked);
|
||||
if(x > 0) {
|
||||
if(pk && pk[-1].r)
|
||||
sDrawChRect(w, mx + 1, my + 1, 4, 4);
|
||||
if(k[-1].r)
|
||||
sDrawChRect(w, mx + 1, my + 1, 4, magnify - 1);
|
||||
if(nk && nk[-1].r)
|
||||
sDrawChRect(w, mx + 1, my + magnify - 4, 4, 4, true);
|
||||
}
|
||||
if(pk && pk->r)
|
||||
sDrawChRect(w, mx + 1, my + 1, magnify - 1, 4);
|
||||
if(nk && nk->r)
|
||||
sDrawChRect(w, mx + 1, my + magnify - 4, magnify - 1, 4, true);
|
||||
if(x + 1 < isz.cx) {
|
||||
if(pk && pk[1].r)
|
||||
sDrawChRect(w, mx + magnify - 4, my + 1, 4, 4, true);
|
||||
if(k[1].r)
|
||||
sDrawChRect(w, mx + magnify - 4, my + 1, 4, magnify - 1, true);
|
||||
if(nk && nk[1].r)
|
||||
sDrawChRect(w, mx + magnify - 4, my + magnify - 4, 4, 4);
|
||||
}
|
||||
}
|
||||
if(spot2.x == x && spot2.y == y)
|
||||
w.DrawImage(mx + 1, my + 1, Rescale(IconDesImg::HotSpotB(), magnify - 1, magnify - 1));
|
||||
if(hotspot.x == x && hotspot.y == y)
|
||||
w.DrawImage(mx + 1, my + 1, Rescale(IconDesImg::HotSpotA(), magnify - 1, magnify - 1));
|
||||
s++;
|
||||
k++;
|
||||
mx += magnify;
|
||||
if(pk)
|
||||
pk++;
|
||||
if(nk)
|
||||
nk++;
|
||||
}
|
||||
}
|
||||
|
||||
Rect src = Rect((sz + magnify) / magnify).Offseted(spos) & isz;
|
||||
Size ssz = src.GetSize();
|
||||
|
||||
ImageBuffer b(src.GetSize() * magnify);
|
||||
int m2 = magnify / 2;
|
||||
CoFor(src.GetHeight(), [&](int y) { // paint chequered background
|
||||
RGBA *q = b[y * magnify];
|
||||
int i = 0;
|
||||
Color c1 = GrayColor(102);
|
||||
Color c2 = GrayColor(153);
|
||||
int m = m2;
|
||||
for(int pass = 0; pass < 2; pass++) {
|
||||
RGBA *t = q;
|
||||
for(int i = 0; i < src.GetWidth(); i++) {
|
||||
Fill(q, c1, magnify);
|
||||
Fill(q + 1, c2, m2);
|
||||
q += magnify;
|
||||
}
|
||||
i++;
|
||||
while(i < m) {
|
||||
memcpy_t(q, t, b.GetWidth());
|
||||
q += b.GetWidth();
|
||||
i++;
|
||||
}
|
||||
m = magnify;
|
||||
Swap(c1, c2);
|
||||
}
|
||||
});
|
||||
|
||||
w.DrawImage(0, 0, b); // paint chequered background
|
||||
w.DrawImage(0, 0, Magnify(image, src, magnify, magnify, true)); // paint actual image
|
||||
|
||||
if(magnify > 6) {
|
||||
int grid2 = 0;
|
||||
if(max(isz.cx, isz.cy) > 16 && show_grid2) {
|
||||
if(isz.cx % 3 == 0 && isz.cy % 3 == 0)
|
||||
grid2 = 3;
|
||||
else
|
||||
if(isz.cx % 4 == 0 && isz.cy % 4 == 0)
|
||||
grid2 = 4;
|
||||
}
|
||||
auto GridColor = [&](int x, int sz) -> Color {
|
||||
if(grid2) {
|
||||
if(x == sz / 2)
|
||||
return LtMagenta();
|
||||
if(x % grid2 == 0)
|
||||
return LtRed();
|
||||
}
|
||||
return Black();
|
||||
};
|
||||
int m = ssz.cx * magnify + 1;
|
||||
for(int y = 0; y <= src.GetHeight(); y++)
|
||||
w.DrawRect(0, magnify * y, m, 1, GridColor(y + src.top, isz.cy));
|
||||
m = ssz.cy * magnify + 1;
|
||||
for(int x = 0; x <= src.GetWidth(); x++)
|
||||
w.DrawRect(magnify * x, 0, 1, m, GridColor(x + src.left, isz.cx));
|
||||
}
|
||||
|
||||
if(!pastepaint && !IsNull(selection)) { // paint selection
|
||||
RGBA c1 = 120 * Black();
|
||||
RGBA c2 = 120 * White();
|
||||
int ncx = ssz.cx * magnify;
|
||||
ImageBuffer b(ncx, ssz.cy * magnify);
|
||||
CoFor(ssz.cy, [&](int y) {
|
||||
const RGBA *s = selection[src.top + y] + src.left;
|
||||
const RGBA *e = s + ssz.cx;
|
||||
RGBA *t = ~b + y * ncx * magnify;
|
||||
RGBA *q = t;
|
||||
while(s < e) {
|
||||
Fill(q, s->r ? RGBAZero() : c1, magnify);
|
||||
Fill(q + ncx, s->r ? RGBAZero() : c2, magnify);
|
||||
q += magnify;
|
||||
s++;
|
||||
}
|
||||
|
||||
for(int i = 2; i < magnify; i++) {
|
||||
q += ncx;
|
||||
memcpy_t(q, t, ncx);
|
||||
t += ncx;
|
||||
}
|
||||
});
|
||||
w.DrawImage(0, 0, b);
|
||||
}
|
||||
|
||||
if(IsPasting() && !pastepaint)
|
||||
DrawFatFrame(w, Rect(magnify * (Current().pastepos - spos),
|
||||
magnify * Current().paste_image.GetSize() + Size(1, 1)),
|
||||
Color(200, 200, 255), 3);
|
||||
|
||||
if(magnify < 9)
|
||||
return;
|
||||
auto PaintHotSpot = [&](Point hotspot, Color c) { // Show hotspots even if not designing them
|
||||
if(hotspot.x > 0 || hotspot.y > 0)
|
||||
DrawFatFrame(w, hotspot.x * magnify, hotspot.y * magnify, magnify + 1, magnify + 1, c, 1 + magnify / 8);
|
||||
};
|
||||
PaintHotSpot(image.GetHotSpot(), LtRed());
|
||||
PaintHotSpot(image.Get2ndSpot(), LtBlue());
|
||||
if(magnify > 8 || IsHotSpot()) {
|
||||
auto PaintHotSpot = [&](Point hotspot, Color c) {
|
||||
if(hotspot.x > 0 || hotspot.y > 0) {
|
||||
hotspot = (hotspot - spos) * magnify;
|
||||
DrawFatFrame(w, hotspot.x, hotspot.y, magnify + 1, magnify + 1, c, max(DPI(1), 1 + magnify / 8));
|
||||
}
|
||||
};
|
||||
PaintHotSpot(image.GetHotSpot(), LtRed());
|
||||
PaintHotSpot(image.Get2ndSpot(), LtBlue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,8 @@ mainconfig
|
|||
"" = "GUI CHECKCLIPBOARD",
|
||||
"" = "GUI PEAKMEM",
|
||||
"" = "GUI HEAPLOG",
|
||||
"" = "GUI X11";
|
||||
"" = "GUI X11",
|
||||
"" = "GUI DEBUGCODE";
|
||||
|
||||
custom() "",
|
||||
"ASDFASDFASDF",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue