diff --git a/uppsrc/Core/Mt.h b/uppsrc/Core/Mt.h index 161586832..4961004b3 100644 --- a/uppsrc/Core/Mt.h +++ b/uppsrc/Core/Mt.h @@ -280,7 +280,7 @@ for(static ::Upp::Mutex o_ss_; !o_b_.load(std::memory_order_acquire);) \ for(::Upp::Mutex::Lock o_ss_lock__(o_ss_); !o_b_.load(std::memory_order_acquire); o_b_.store(true, std::memory_order_release)) #define ONCELOCK \ -for(static OnceFlag o_b_; !o_b_.load(std::memory_order_acquire);) ONCELOCK_(o_b_) +for(static ::Upp::OnceFlag o_b_; !o_b_.load(std::memory_order_acquire);) ONCELOCK_(o_b_) class Mutex::Lock : NoCopy { diff --git a/uppsrc/Core/lheap.cpp b/uppsrc/Core/lheap.cpp index d1bf1477c..1cbb2a526 100644 --- a/uppsrc/Core/lheap.cpp +++ b/uppsrc/Core/lheap.cpp @@ -43,7 +43,7 @@ void Heap::GlobalLInit() } k = LBINS - 1; for(int i = MAXBLOCK / 8; i >= 0; i--) { - while(i * 8 < BinSz[k]) k--; + while(i * 8 < BinSz[k] && k >= 0) k--; BlBin[i] = k; } BlBin[0] = 0; diff --git a/uppsrc/CppBase/CppBase.h b/uppsrc/CppBase/CppBase.h index 59ee4e4f4..461664ec6 100644 --- a/uppsrc/CppBase/CppBase.h +++ b/uppsrc/CppBase/CppBase.h @@ -384,21 +384,21 @@ struct CppItem { String tname; String ctname; String using_namespaces; - byte access; - byte kind; - int16 at; - bool virt; + byte access = PUBLIC; + byte kind = STRUCT; + int16 at = 0; + bool virt = false; - bool decla; - bool lvalue; - bool isptr; + bool decla = false; + bool lvalue = false; + bool isptr = false; - byte filetype; - bool impl; - int file; - int line; + byte filetype = FILE_OTHER; + bool impl = false; + int file = 0; + int line = 0; - bool qualify; + bool qualify = true; bool IsType() const { return IsCppType(kind); } bool IsCode() const { return IsCppCode(kind); } @@ -410,8 +410,6 @@ struct CppItem { void Dump(Stream& s) const; String ToString() const; - - CppItem() { at = decla = virt = false; qualify = true; isptr = false; } }; String CppItemKindAsString(int kind); diff --git a/uppsrc/Draw/Image.h b/uppsrc/Draw/Image.h index 8c1f709a3..17a7e29b8 100644 --- a/uppsrc/Draw/Image.h +++ b/uppsrc/Draw/Image.h @@ -262,13 +262,33 @@ public: Image Premultiply(const Image& img); Image Unmultiply(const Image& img); -Vector UnpackImlData(const void *ptr, int len); -Vector UnpackImlData(const String& d); +struct ImageIml : Moveable { + Image image; + dword flags = 0; +}; + +Vector UnpackImlData(const void *ptr, int len); +Vector UnpackImlData(const String& d); + +enum { + GUI_MODE_NORMAL = 0, + GUI_MODE_DARK = 1, + GUI_MODE_UHD = 2, + GUI_MODE_DARK_UHD = 3, +}; + +enum { + IML_IMAGE_FLAG_FIXED = 0x1, + IML_IMAGE_FLAG_FIXED_COLORS = 0x2, + IML_IMAGE_FLAG_FIXED_SIZE = 0x4, + IML_IMAGE_FLAG_UHD = 0x8, + IML_IMAGE_FLAG_DARK = 0x10, +}; class Iml { struct IImage : Moveable { - bool loaded; - Image image; + std::atomic loaded; + Image image; IImage() { loaded = false; } }; @@ -276,12 +296,14 @@ class Iml { const char *data; int len, count; }; - Vector data; + Vector data[4]; // 0 normal, 1 HiDPI - HD, 2 DK - Dark, 3 HDK - HiDPI + dark VectorMap map; const Image::Init *img_init; const char **name; bool premultiply; + Index ex_name[3]; // 0 HiDPI - HD, 1 DK - Dark, 2 HDK - HiDPI + dark + void Init(int n); public: @@ -289,16 +311,20 @@ public: int GetCount() const { return map.GetCount(); } String GetId(int i) { return map.GetKey(i); } Image Get(int i); - int Find(const String& s) const { return map.Find(s); } + int Find(const String& id) const { return map.Find(id); } void Set(int i, const Image& img); - void Premultiplied() { premultiply = false; } #ifdef _DEBUG int GetBinSize() const; #endif + void Premultiplied() { premultiply = false; } + ImageIml GetRaw(int mode, int i); // tries to get image for mode, can return Null + ImageIml GetRaw(int mode, const String& id); // tries to get image for mode by id, can return Null + Iml(const Image::Init *img_init, const char **name, int n);//Deprecated - legacy .iml - void AddData(const byte *data, int len, int count); + void AddData(const byte *data, int len, int count, int mode = 0); + void AddId(int mode1, const char *name); }; void Register(const char *imageclass, Iml& iml); diff --git a/uppsrc/Draw/ImageOp.cpp b/uppsrc/Draw/ImageOp.cpp index 2f5fdcedf..f061384e2 100644 --- a/uppsrc/Draw/ImageOp.cpp +++ b/uppsrc/Draw/ImageOp.cpp @@ -439,6 +439,9 @@ Image Colorize(const Image& img, Color color, int alpha) Image DarkTheme(const Image& img) { + if(IsNull(img)) + return img; + Image simg = Unmultiply(img); const RGBA *s = simg.begin(); const RGBA *e = simg.end(); diff --git a/uppsrc/Draw/ImageOp.h b/uppsrc/Draw/ImageOp.h index 3ad8f3ef6..88c646f6a 100644 --- a/uppsrc/Draw/ImageOp.h +++ b/uppsrc/Draw/ImageOp.h @@ -216,7 +216,7 @@ Image CachedSetColorKeepAlpha(const Image& img, Color color); Image CachedSetColorKeepAlphaPaintOnly(const Image& img, Color color); Image Upscale2x(const Image& src); -Image ImlUpscale2x(const Image& src); +Image Downscale2x(const Image& src); void SetUHDMode(bool b = true); bool IsUHDMode(); diff --git a/uppsrc/Draw/Iml.cpp b/uppsrc/Draw/Iml.cpp index ea7adf612..5e8edce37 100644 --- a/uppsrc/Draw/Iml.cpp +++ b/uppsrc/Draw/Iml.cpp @@ -2,15 +2,18 @@ namespace Upp { -Vector UnpackImlData(const void *ptr, int len) +Vector UnpackImlData(const void *ptr, int len) { - Vector img; + Vector img; String data = ZDecompress(ptr, len); const char *s = data; while(s + 6 * 2 + 1 <= data.End()) { + ImageIml& m = img.Add(); ImageBuffer ib(Peek16le(s + 1), Peek16le(s + 3)); - int q = byte(*s) >> 6; - ib.SetResolution(decode(q, 0, IMAGE_RESOLUTION_STANDARD, 1, IMAGE_RESOLUTION_UHD, IMAGE_RESOLUTION_NONE)); + m.flags = byte(*s) & 0x3f; + ib.SetResolution(decode(byte(*s) >> 6, 0, IMAGE_RESOLUTION_STANDARD, + 1, IMAGE_RESOLUTION_UHD, + IMAGE_RESOLUTION_NONE)); ib.SetHotSpot(Point(Peek16le(s + 5), Peek16le(s + 7))); ib.Set2ndSpot(Point(Peek16le(s + 9), Peek16le(s + 11))); s += 13; @@ -27,12 +30,12 @@ Vector UnpackImlData(const void *ptr, int len) s += 4; t++; } - img.Add() = ib; + m.image = ib; } return img; } -Vector UnpackImlData(const String& d) +Vector UnpackImlData(const String& d) { return UnpackImlData(~d, d.GetLength()); } @@ -58,46 +61,70 @@ void Iml::Set(int i, const Image& img) static StaticMutex sImlLock; +ImageIml Iml::GetRaw(int mode, int i) +{ + Mutex::Lock __(sImlLock); + if(data[mode].GetCount()) { + int ii = 0; + for(;;) { + const Data& d = data[mode][ii]; + if(i < d.count) { + static const char *cached_data[4]; + static Vector cached[4]; + if(cached_data[mode] != d.data) { // cache single .iml + cached_data[mode] = d.data; + cached[mode] = UnpackImlData(d.data, d.len); + if(premultiply) + for(int i = 0; i < cached[mode].GetCount(); i++) + cached[mode][i].image = Premultiply(cached[mode][i].image); + } + return cached[mode][i]; + } + i -= d.count; + ii++; + } + } + return ImageIml(); +} + +ImageIml Iml::GetRaw(int mode, const String& id) +{ + ASSERT(mode >= 0 && mode < 4); + int ii = -1; + if(mode == 0) + ii = map.Find(id); + else { + ii = ex_name[mode - 1].Find(id); + } + return ii >= 0 ? GetRaw(mode, ii) : ImageIml(); +} + Image Iml::Get(int i) { IImage& m = map[i]; if(!m.loaded) { Mutex::Lock __(sImlLock); - if(data.GetCount()) { - int ii = 0; - for(;;) { - const Data& d = data[ii]; - if(i < d.count) { - static const char *cached_data; - static Vector cached; - if(cached_data != d.data) { // cache single .iml - cached_data = d.data; - cached = UnpackImlData(d.data, d.len); - if(premultiply) - for(int i = 0; i < cached.GetCount(); i++) - cached[i] = Premultiply(cached[i]); - } - bool gui_image = cached[i].GetResolution() != IMAGE_RESOLUTION_NONE; - if(IsUHDMode() && cached[i].GetResolution() == IMAGE_RESOLUTION_STANDARD) { - int q = Find(GetId(i) + "__UHD"); - if(q >= 0) { - m.image = Get(q); - if(m.image.GetResolution() == IMAGE_RESOLUTION_UHD) - break; - } - } - m.image = DPI(cached[i]); - if(gui_image && IsDark(SColorPaper())) - m.image = DarkTheme(m.image); - break; + if(!m.loaded) { + int mode = IsUHDMode() * GUI_MODE_UHD + IsDarkTheme() * GUI_MODE_DARK; + String id = GetId(i); + if(mode == GUI_MODE_NORMAL) + m.image = GetRaw(0, i).image; + else { + auto Mode = [&](dword m, const char *s) { return mode & m ? String(s) : String(); }; + m.image = GetRaw(0, id + Mode(GUI_MODE_UHD, "__UHD") + Mode(GUI_MODE_DARK, "__DARK")).image; + if(IsNull(m.image)) + m.image = GetRaw(mode, id).image; + if(IsNull(m.image)) { + ImageIml im = GetRaw(0, id); + if((mode & GUI_MODE_UHD) && !(im.flags & (IML_IMAGE_FLAG_FIXED|IML_IMAGE_FLAG_FIXED_SIZE))) + im.image = Upscale2x(im.image); + if((mode & GUI_MODE_DARK) && !(im.flags & (IML_IMAGE_FLAG_FIXED|IML_IMAGE_FLAG_FIXED_COLORS))) + im.image = DarkTheme(im.image); + m.image = im.image; } - i -= d.count; - ii++; } + m.loaded = true; } - else - m.image = Premultiply(Image(img_init[i])); - m.loaded = true; } return m.image; } @@ -120,20 +147,24 @@ Iml::Iml(const Image::Init *img_init, const char **name, int n) : img_init(img_init), name(name) { -#ifdef flagCHECKINIT - RLOG("Constructing iml " << *name); -#endif premultiply = true; Init(n); } -void Iml::AddData(const byte *_data, int len, int count) +void Iml::AddData(const byte *s, int len, int count, int mode) { - Data& d = data.Add(); - d.data = (const char *)_data; + Data& d = data[mode].Add(); + d.data = (const char *)s; d.len = len; d.count = count; - data.Shrink(); + data[mode].Shrink(); +} + +void Iml::AddId(int mode1, const char *name) +{ + DDUMP(name); + DDUMP(mode1); + ex_name[mode1].Add(name); } static StaticCriticalSection sImgMapLock; diff --git a/uppsrc/Draw/Uhd.cpp b/uppsrc/Draw/Uhd.cpp index b5d785158..7b0c6c924 100644 --- a/uppsrc/Draw/Uhd.cpp +++ b/uppsrc/Draw/Uhd.cpp @@ -71,6 +71,8 @@ Image Upscale2x(const Image& src, RGBA bg) Image Upscale2x(const Image& src) { + if(IsNull(src)) + return src; Size s2 = src.Get2ndSpot(); Image s; if(s2.cx > 0 || s2.cy > 0) // When 2nd spot is defined, it is likely Chameleon rescaling item (e.g. button) @@ -104,6 +106,8 @@ Image Upscale2x(const Image& src) Image Downscale2x(const Image& src) { + if(IsNull(src)) + return src; Size s2 = src.Get2ndSpot(); // see above... Image m = RescaleFilter(src, src.GetSize() / 2, s2.cx > 0 || s2.cy > 0 ? FILTER_BILINEAR : FILTER_LANCZOS3); ImageBuffer h(m); diff --git a/uppsrc/Draw/iml_source.h b/uppsrc/Draw/iml_source.h index 85cdacfbc..eb27ef1bb 100644 --- a/uppsrc/Draw/iml_source.h +++ b/uppsrc/Draw/iml_source.h @@ -31,49 +31,72 @@ UPP::Iml& IMAGECLASS::Iml() { - static UPP::Image::Init init[] = { + static UPP::Image::Init init[] = { // legacy format #define IMAGE_PACKED(n, d) { COMBINE(COMBINE(IMAGECLASS, _), n##__scans__), __countof(COMBINE(COMBINE(IMAGECLASS, _), n##__scans__)), d }, - #include IMAGEFILE - { NULL } #undef IMAGE_PACKED }; static const char *name[IMAGECLASS::COUNT] = { #define IMAGE_PACKED(n, d) #n, - #undef IMAGE_ID + #undef IMAGE_ID #define IMAGE_ID(n) #n, - #include IMAGEFILE + }; - #undef IMAGE_PACKED - #undef IMAGE_ID + static UPP::Iml iml(init, name, COUNT); + + #undef IMAGE_PACKED + #undef IMAGE_ID #define IMAGE_ID(n) #define IMAGE_PACKED(n, d) - }; - static UPP::Iml iml(init, name, COUNT); - static bool imlinit; - if(!imlinit) { - imlinit = true; - #undef IMAGE_BEGIN_DATA - #undef IMAGE_DATA - #undef IMAGE_END_DATA + ONCELOCK { + + #undef IMAGE_BEGIN_DATA + #undef IMAGE_DATA + #undef IMAGE_END_DATA #define IMAGE_BEGIN_DATA { static const UPP::byte data[] = { #define IMAGE_DATA(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf)\ a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf, #define IMAGE_END_DATA(n, c) }; iml.AddData(data, n, c); } - #include IMAGEFILE + #include IMAGEFILE + + #ifdef IMAGEFILE_DARK + #undef IMAGE_ID + #undef IMAGE_END_DATA + #define IMAGE_ID(n) iml.AddId(0, #n); + #define IMAGE_END_DATA(n, c) }; iml.AddData(data, n, c, 1); } + #include IMAGEFILE_DARK + #endif + + #ifdef IMAGEFILE_UHD + #undef IMAGE_ID + #undef IMAGE_END_DATA + #define IMAGE_ID(n) iml.AddId(1, #n); + #define IMAGE_END_DATA(n, c) }; iml.AddData(data, n, c, 2); } + #include IMAGEFILE_UHD + #endif + + #ifdef IMAGEFILE_DARK_UHD + #undef IMAGE_ID + #undef IMAGE_END_DATA + #define IMAGE_ID(n) iml.AddId(2, #n); + #define IMAGE_END_DATA(n, c) }; iml.AddData(data, n, c, 3); } + #include IMAGEFILE_DARK_UHD + #endif #undef IMAGE_BEGIN_DATA #undef IMAGE_END_DATA #undef IMAGE_DATA + #undef IMAGE_ID #define IMAGE_BEGIN_DATA #define IMAGE_END_DATA(n, c) #define IMAGE_DATA(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) + #define IMAGE_ID(n) #undef PREMULTIPLIED #define PREMULTIPLIED iml.Premultiplied(); @@ -143,3 +166,15 @@ static COMBINE(IMAGECLASS, __Reg) COMBINE(IMAGECLASS, ___Reg); #endif #undef IMAGE_META + +#ifdef IMAGEFILE_UHD +#undef IMAGEFILE_UHD +#endif + +#ifdef IMAGEFILE_DARK +#undef IMAGEFILE_DARK +#endif + +#ifdef IMAGEFILE_DARK_UHD +#undef IMAGEFILE_DARK_UHD +#endif diff --git a/uppsrc/IconDes/IconDes.cpp b/uppsrc/IconDes/IconDes.cpp index 79ef7a81f..fd29401b8 100644 --- a/uppsrc/IconDes/IconDes.cpp +++ b/uppsrc/IconDes/IconDes.cpp @@ -449,13 +449,13 @@ void IconDes::SaveUndo() if(!IsCurrent()) return; Slot& c = Current(); - Vector undo = UnpackImlData(c.undo); + Vector undo = UnpackImlData(c.undo); int maxn = minmax((single_mode ? 4000000 : 400000) / max(c.image.GetLength(), 1), 4, 128); while(undo.GetCount() > maxn) undo.Remove(0); - if(undo.GetCount() && undo.Top() == c.image) + if(undo.GetCount() && undo.Top().image == c.image) return; - undo.Add(c.image); + undo.Add().image = c.image; c.undo = PackImlData(undo); c.redo.Clear(); SetBar(); @@ -467,12 +467,12 @@ void IconDes::Undo() if(!IsCurrent()) return; Slot& c = Current(); - Vector undo = UnpackImlData(c.undo); + Vector undo = UnpackImlData(c.undo); if(undo.GetCount() == 0) return; - Vector redo = UnpackImlData(c.redo); - redo.Add(c.image); - c.image = undo.Pop(); + Vector redo = UnpackImlData(c.redo); + redo.Add().image = c.image; + c.image = undo.Pop().image; c.undo = PackImlData(undo); c.redo = PackImlData(redo); SyncImage(); @@ -484,12 +484,12 @@ void IconDes::Redo() if(!IsCurrent()) return; Slot& c = Current(); - Vector redo = UnpackImlData(c.redo); + Vector redo = UnpackImlData(c.redo); if(redo.GetCount() == 0) return; - Vector undo = UnpackImlData(c.undo); - undo.Add(c.image); - c.image = redo.Pop(); + Vector undo = UnpackImlData(c.undo); + undo.Add().image = c.image; + c.image = redo.Pop().image; c.undo = PackImlData(undo); c.redo = PackImlData(redo); SyncImage(); diff --git a/uppsrc/IconDes/IconDes.h b/uppsrc/IconDes/IconDes.h index 82e47533a..ae68348a4 100644 --- a/uppsrc/IconDes/IconDes.h +++ b/uppsrc/IconDes/IconDes.h @@ -100,7 +100,7 @@ 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 PackImlData(const Vector& image); +String PackImlData(const Vector& image); Image DownSample3x(const Image& src); Image DownSample2x(const Image& src); @@ -151,6 +151,7 @@ private: String undo; String redo; bool exp; + dword flags = 0; Slot(); }; @@ -341,8 +342,10 @@ private: void ListCursor(); void PrepareImageDlg(WithImageLayout& dlg); void PrepareImageSizeDlg(WithImageSizeLayout& dlg); - void ImageInsert(int ii, const String& name, const Image& m, bool exp = false); - void ImageInsert(const String& name, const Image& m, bool exp = false); + void SyncDlg(WithImageLayout& dlg); + dword GetFlags(WithImageLayout& dlg); + Slot& ImageInsert(int ii, const String& name, const Image& m, bool exp = false); + Slot& ImageInsert(const String& name, const Image& m, bool exp = false); void Slice(); void InsertImage(); void InsertRemoved(int ii); @@ -360,6 +363,7 @@ private: void Drag(); static FileSel& ImgFile(); + static String FormatImageName(const Slot& c); public: virtual void ToolEx(Bar& bar); @@ -385,11 +389,12 @@ public: }; void Clear(); - void AddImage(const String& name, const Image& image, bool exp = false); + Slot& AddImage(const String& name, const Image& image, bool exp); int GetCount() const; Image GetImage(int ii) const; String GetName(int ii) const; bool GetExport(int ii) const; + dword GetFlags(int ii) const; bool FindName(const String& name); String GetCurrentName() const; @@ -409,9 +414,8 @@ public: IconDes(); }; -struct ImlImage { +struct ImlImage : ImageIml { String name; - Image image; bool exp; }; diff --git a/uppsrc/IconDes/IconDes.lay b/uppsrc/IconDes/IconDes.lay index d87e1076f..bf3c5be9d 100644 --- a/uppsrc/IconDes/IconDes.lay +++ b/uppsrc/IconDes/IconDes.lay @@ -1,15 +1,18 @@ -LAYOUT(ImageLayout, 168, 188) +LAYOUT(ImageLayout, 168, 208) ITEM(Label, dv___0, SetLabel(t_("Name")).LeftPosZ(8, 40).TopPosZ(8, 19)) ITEM(EditString, name, LeftPosZ(52, 108).TopPosZ(8, 19)) ITEM(Label, dv___2, SetLabel(t_("Size")).LeftPosZ(8, 40).TopPosZ(32, 19)) ITEM(EditIntSpin, cx, Max(8192).Min(1).LeftPosZ(52, 44).TopPosZ(32, 19)) + ITEM(Label, dv___4, SetLabel(t_("x")).LeftPosZ(100, 12).TopPosZ(32, 16)) ITEM(EditIntSpin, cy, Max(8192).Min(1).LeftPosZ(116, 44).TopPosZ(32, 19)) - ITEM(Label, dv___5, SetLabel(t_("x")).LeftPosZ(100, 12).TopPosZ(32, 16)) - ITEM(Option, exp, SetLabel(t_("Export as icon.ico and .png")).LeftPosZ(8, 160).TopPosZ(136, 16)) - ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(28, 64).TopPosZ(156, 24)) - ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(96, 64).TopPosZ(156, 24)) - ITEM(LabelBox, dv___9, SetLabel(t_("Resolution")).LeftPosZ(8, 152).TopPosZ(56, 72)) - ITEM(Switch, resolution, SetLabel(t_("Standard\nUHD\nNone")).LeftPosZ(16, 144).TopPosZ(72, 52)) + ITEM(Option, fixed, SetLabel(t_("Fixed")).LeftPosZ(8, 156).TopPosZ(56, 16)) + ITEM(Option, fixed_colors, SetLabel(t_("Fixed colors")).LeftPosZ(12, 156).TopPosZ(72, 16)) + ITEM(Option, fixed_size, SetLabel(t_("Fixed size")).LeftPosZ(12, 156).TopPosZ(88, 16)) + ITEM(Option, uhd, SetLabel(t_("UHD variant")).LeftPosZ(8, 156).TopPosZ(112, 16)) + ITEM(Option, dark, SetLabel(t_("Dark variant")).LeftPosZ(8, 156).TopPosZ(128, 16)) + ITEM(Option, exp, SetLabel(t_("Export as icon.ico and .png")).LeftPosZ(8, 160).TopPosZ(152, 16)) + ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(28, 64).TopPosZ(176, 24)) + ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(96, 64).TopPosZ(176, 24)) END_LAYOUT LAYOUT(ImageSizeLayout, 168, 68) diff --git a/uppsrc/IconDes/ImageOp.cpp b/uppsrc/IconDes/ImageOp.cpp index 47d9e2cf5..d29a6b59c 100644 --- a/uppsrc/IconDes/ImageOp.cpp +++ b/uppsrc/IconDes/ImageOp.cpp @@ -154,13 +154,13 @@ void MirrorVert(Image& img, const Rect& rect) img = ib; } -String PackImlData(const Vector& image) +String PackImlData(const Vector& image) { StringBuffer block; - for(int i = 0; i < image.GetCount(); i++) { - const Image& img = image[i]; + for(const ImageIml& m : image) { + const Image& img = m.image; StringStream ss; - ss.Put(img.GetResolution() << 6); + ss.Put((img.GetResolution() << 6) | m.flags); Size sz = img.GetSize(); ss.Put16le(sz.cx); ss.Put16le(sz.cy); diff --git a/uppsrc/IconDes/ImlFile.cpp b/uppsrc/IconDes/ImlFile.cpp index ed52e8c57..919aab54d 100644 --- a/uppsrc/IconDes/ImlFile.cpp +++ b/uppsrc/IconDes/ImlFile.cpp @@ -238,16 +238,16 @@ bool LoadIml(const String& data, Array& img, int& format) p.PassChar(')'); data.Trim(zlen); - Vector m = UnpackImlData(data, data.GetCount()); + Vector m = UnpackImlData(data, data.GetCount()); if(m.GetCount() != count || ii + count > name.GetCount()) p.ThrowError(""); for(int i = 0; i < count; i++) { ImlImage& c = img.Add(); + (ImageIml &)c = m[i]; c.name = name[ii]; c.exp = exp[ii++]; - c.image = m[i]; - if(c.image.GetResolution() == IMAGE_RESOLUTION_UHD) - c.name.TrimEnd("__UHD"); + c.name.TrimEnd("__DARK"); + c.name.TrimEnd("__UHD"); if(premultiply) c.image = Premultiply(c.image); } @@ -345,8 +345,10 @@ String SaveIml(const Array& iml, int format) { for(int i = 0; i < iml.GetCount(); i++) { const ImlImage& c = iml[i]; out << "IMAGE_ID(" << c.name; - if(c.image.GetResolution() == IMAGE_RESOLUTION_UHD && std_name.Find(c.name) >= 0) + if(c.flags & IML_IMAGE_FLAG_UHD) out << "__UHD"; + if(c.flags & IML_IMAGE_FLAG_DARK) + out << "__DARK"; out << ")"; if(c.exp) out << " IMAGE_META(\"exp\", \"\")\r\n"; @@ -356,10 +358,16 @@ String SaveIml(const Array& iml, int format) { while(ii < iml.GetCount()) { int bl = 0; int bn = 0; - Vector bimg; + Vector bimg; while(bl < 4096 && ii < iml.GetCount()) { const ImlImage& c = iml[ii++]; - bimg.Add(c.image); + ImageIml& m = bimg.Add(); + m.image = c.image; + m.flags = c.flags; + if(c.flags & IML_IMAGE_FLAG_UHD) + SetResolution(m.image, IMAGE_RESOLUTION_UHD); + if(c.flags & (IML_IMAGE_FLAG_FIXED|IML_IMAGE_FLAG_FIXED_SIZE)) + SetResolution(m.image, IMAGE_RESOLUTION_NONE); bl += c.image.GetLength(); bn++; } diff --git a/uppsrc/IconDes/List.cpp b/uppsrc/IconDes/List.cpp index 45093ac9b..0f6ecbb95 100644 --- a/uppsrc/IconDes/List.cpp +++ b/uppsrc/IconDes/List.cpp @@ -2,15 +2,25 @@ namespace Upp { -static String sFormatImageName(const String& name, const Image& img, bool exp) +String IconDes::FormatImageName(const Slot& c) { - Size sz = img.GetSize(); + Size sz = c.image.GetSize(); String r; - r << name << " (" << sz.cx << " x " << sz.cy - << decode(img.GetResolution(), IMAGE_RESOLUTION_UHD, " UHD", IMAGE_RESOLUTION_NONE, " n.r.", "") - << ')'; - if(exp) - r << " ex."; + r << c.name << " " << sz.cx << " x " << sz.cy; + if(c.flags & IML_IMAGE_FLAG_FIXED) + r << " Fxd"; + else { + if(c.flags & IML_IMAGE_FLAG_FIXED_COLORS) + r << " Clr"; + if(c.flags & IML_IMAGE_FLAG_FIXED_SIZE) + r << " Sz"; + } + if(c.flags & IML_IMAGE_FLAG_UHD) + r << " HD"; + if(c.flags & IML_IMAGE_FLAG_DARK) + r << " Dk"; + if(c.exp) + r << " X"; return r; } @@ -26,7 +36,7 @@ void IconDes::SyncList() for(int i = 0; i < slot.GetCount(); i++) { Slot& c = slot[i]; if(ToUpper(c.name).Find(s) >= 0) - ilist.Add(i, sFormatImageName(c.name, c.image, c.exp), c.image); + ilist.Add(i, FormatImageName(c), c.image); } ilist.ScrollTo(sc); ilist.FindSetCursor(q); @@ -69,17 +79,44 @@ void IconDes::PrepareImageDlg(WithImageLayout& dlg) Size sz = GetImageSize(); dlg.cx <<= sz.cx; dlg.cy <<= sz.cy; - int resolution = IMAGE_RESOLUTION_STANDARD; - if(IsCurrent()) - resolution = Current().image.GetResolution(); - dlg.resolution.Set(0, IMAGE_RESOLUTION_STANDARD); - dlg.resolution.Set(1, IMAGE_RESOLUTION_UHD); - dlg.resolution.Set(2, IMAGE_RESOLUTION_NONE); - dlg.resolution <<= resolution; + + dword flags = IsCurrent() ? Current().flags : 0; + dlg.fixed <<= !!(flags & IML_IMAGE_FLAG_FIXED); + dlg.fixed_colors <<= !!(flags & IML_IMAGE_FLAG_FIXED_COLORS); + dlg.fixed_size <<= !!(flags & IML_IMAGE_FLAG_FIXED_SIZE); + + dlg.uhd <<= !!(flags & IML_IMAGE_FLAG_UHD); + dlg.dark <<= !!(flags & IML_IMAGE_FLAG_DARK); + + dlg.uhd ^= dlg.dark ^= dlg.exp ^= dlg.fixed_colors ^= dlg.fixed_size ^= dlg.fixed ^= + [&] { dlg.Break(-1000); }; } dlg.name.SetFilter(sCharFilterCid); } +void IconDes::SyncDlg(WithImageLayout& dlg) +{ + bool b = !dlg.fixed; + dlg.fixed_colors.Enable(b); + dlg.fixed_size.Enable(b); +} + +dword IconDes::GetFlags(WithImageLayout& dlg) +{ + dword flags = 0; + if(dlg.fixed) + flags |= IML_IMAGE_FLAG_FIXED; + if(dlg.fixed_colors) + flags |= IML_IMAGE_FLAG_FIXED_COLORS; + if(dlg.fixed_size) + flags |= IML_IMAGE_FLAG_FIXED_SIZE; + if(dlg.uhd) + flags |= IML_IMAGE_FLAG_UHD; + if(dlg.dark) + flags |= IML_IMAGE_FLAG_DARK; + return flags; +} + void IconDes::PrepareImageSizeDlg(WithImageSizeLayout& dlg) { CtrlLayoutOKCancel(dlg, "New image"); @@ -121,7 +158,7 @@ void SetRes(Image& m, int resolution) m = ib; } -void IconDes::ImageInsert(int ii, const String& name, const Image& m, bool exp) +IconDes::Slot& IconDes::ImageInsert(int ii, const String& name, const Image& m, bool exp) { Slot& c = slot.Insert(ii); c.name = name; @@ -129,29 +166,31 @@ void IconDes::ImageInsert(int ii, const String& name, const Image& m, bool exp) c.exp = exp; SyncList(); GoTo(ii); + return c; } -void IconDes::ImageInsert(const String& name, const Image& m, bool exp) +IconDes::Slot& IconDes::ImageInsert(const String& name, const Image& m, bool exp) { int ii = ilist.IsCursor() ? (int)ilist.GetKey() : 0; if(ii == slot.GetCount() - 1) ii = slot.GetCount(); - ImageInsert(ii, name, m, exp); + return ImageInsert(ii, name, m, exp); } void IconDes::InsertImage() { WithImageLayout dlg; PrepareImageDlg(dlg); - dlg.resolution <<= IMAGE_RESOLUTION_STANDARD; - do { - if(dlg.Run() != IDOK) + for(;;) { + SyncDlg(dlg); + int c = dlg.Run(); + if(c == IDCANCEL) return; + if(c == IDOK && CheckName(dlg)) + break; } - while(!CheckName(dlg)); Image m = CreateImage(Size(~dlg.cx, ~dlg.cy), Null); - SetRes(m, ~dlg.resolution); - ImageInsert(~dlg.name, m, dlg.exp); + ImageInsert(~dlg.name, m, dlg.exp).flags = GetFlags(dlg); } void IconDes::Slice() @@ -169,20 +208,21 @@ void IconDes::Slice() dlg.cx <<= cc; dlg.cy <<= cc; dlg.Title("Slice image"); - dlg.resolution <<= IMAGE_RESOLUTION_STANDARD; - do { - if(dlg.Run() != IDOK) + for(;;) { + SyncDlg(dlg); + int c = dlg.Run(); + if(c == IDCANCEL) return; + if(c == IDOK && CheckName(dlg)) + break; } - while(!CheckName(dlg)); String s = ~dlg.name; int n = 0; int ii = ilist.GetKey(); for(int y = 0; y < isz.cy; y += (int)~dlg.cy) for(int x = 0; x < isz.cx; x += (int)~dlg.cx) { Image m = Crop(src, x, y, ~dlg.cx, ~dlg.cy); - SetRes(m, ~dlg.resolution); - ImageInsert(++ii, s + AsString(n++), m, ~dlg.exp); + ImageInsert(++ii, s + AsString(n++), m, ~dlg.exp).flags = GetFlags(dlg); } } @@ -320,11 +360,11 @@ void IconDes::ExportPngs() void IconDes::InsertIml() { - Array m; + Array iml; int f; - if(LoadIml(SelectLoadFile("Iml files\t*.iml"), m, f)) - for(int i = 0; i < m.GetCount(); i++) { - ImageInsert(m[i].name, m[i].image, m[i].exp); + if(LoadIml(SelectLoadFile("Iml files\t*.iml"), iml, f)) + for(const ImlImage& m : iml) { + ImageInsert(m.name, m.image, m.exp).flags = m.flags; GoTo((int)ilist.GetKey() + 1); } } @@ -381,27 +421,29 @@ void IconDes::EditImage() dlg.name <<= c.name; dlg.exp <<= c.exp; for(;;) { + SyncDlg(dlg); switch(dlg.Run()) { case IDCANCEL: c.image = img; Reset(); return; case IDOK: - if(!CheckName(dlg)) break; - c.name = ~dlg.name; - c.exp = ~dlg.exp; - SetRes(c.image, ~dlg.resolution); - ilist.Set(1, sFormatImageName(c.name, c.image, c.exp)); - int q = ilist.GetKey(); - Reset(); - SyncList(); - GoTo(q); - return; + if(CheckName(dlg)) { + c.name = ~dlg.name; + c.exp = ~dlg.exp; + c.flags = GetFlags(dlg); + ilist.Set(1, FormatImageName(c)); + int q = ilist.GetKey(); + Reset(); + SyncList(); + GoTo(q); + return; + } } - int r = c.image.GetResolution(); + c.flags = GetFlags(dlg); c.image = CreateImage(Size(minmax((int)~dlg.cx, 1, 8192), minmax((int)~dlg.cy, 1, 8192)), Null); + c.exp = ~dlg.exp; UPP::Copy(c.image, Point(0, 0), img, img.GetSize()); - SetRes(c.image, r); Reset(); } } @@ -462,8 +504,7 @@ void IconDes::ListMenu(Bar& bar) bar.Separator(); for(int i = removed.GetCount() - 1; i >= 0; i--) { Slot& r = removed[i]; - bar.Add("Insert " + sFormatImageName(r.name, r.image, r.exp), r.base_image, - THISBACK1(InsertRemoved, i)); + bar.Add("Insert " + FormatImageName(r), r.base_image, THISBACK1(InsertRemoved, i)); } } } @@ -482,15 +523,16 @@ void IconDes::Clear() Reset(); } -void IconDes::AddImage(const String& name, const Image& image, bool exp) +IconDes::Slot& IconDes::AddImage(const String& name, const Image& image, bool exp) { int q = slot.GetCount(); Slot& c = slot.Add(); c.name = name; c.image = image; c.exp = exp; - ilist.Add(q, sFormatImageName(c.name, c.image, c.exp), c.image); + ilist.Add(q, FormatImageName(c), c.image); ilist.GoBegin(); + return c; } int IconDes::GetCount() const @@ -508,6 +550,11 @@ String IconDes::GetName(int ii) const return slot[ii].name; } +dword IconDes::GetFlags(int ii) const +{ + return slot[ii].flags; +} + bool IconDes::FindName(const String& name) { for(int i = 0; i < slot.GetCount(); i++) diff --git a/uppsrc/ide/IconDes/IconDes.cpp b/uppsrc/ide/IconDes/IconDes.cpp index 4456fae01..97cdc7374 100644 --- a/uppsrc/ide/IconDes/IconDes.cpp +++ b/uppsrc/ide/IconDes/IconDes.cpp @@ -8,13 +8,13 @@ bool IdeIconDes::Load(const char *_filename) Clear(); filename = _filename; filetime = FileGetTime(filename); - Array m; + Array iml; int f; - if(!LoadIml(LoadFile(filename), m, f)) + if(!LoadIml(LoadFile(filename), iml, f)) return false; format = f; - for(int i = 0; i < m.GetCount(); i++) - AddImage(m[i].name, m[i].image, m[i].exp); + for(const ImlImage& m : iml) + AddImage(m.name, m.image, m.exp).flags = m.flags; return true; } @@ -44,6 +44,7 @@ void IdeIconDes::Save() c.name = GetName(i); c.image = GetImage(i); c.exp = GetExport(i); + c.flags = GetFlags(i); if(c.exp) { Size sz = c.image.GetSize(); exp.GetAdd(sz) = c.image; diff --git a/uppsrc/ide/Insert.cpp b/uppsrc/ide/Insert.cpp index af3a3b4fe..6d89fdad7 100644 --- a/uppsrc/ide/Insert.cpp +++ b/uppsrc/ide/Insert.cpp @@ -77,7 +77,7 @@ void Ide::InsertLay(const String& fn) editor.Paste(s.ToWString()); } -void Ide::InsertIml(const String& fn, String classname) +void Ide::InsertIml(const Package& pkg, const String& fn, String classname) { if(editor.IsReadOnly()) return; @@ -85,11 +85,47 @@ void Ide::InsertIml(const String& fn, String classname) return; String h; h << "#define IMAGECLASS " << classname << "\n" - << "#define IMAGEFILE <" << fn << ">\n" - << "#include \n").ToWString()); + << "#define IMAGEFILE <" << fn << ">\n"; + editor.Paste((h + "#include \n").ToWString()); ClearClipboard(); - AppendClipboardText((h + "_source.h>\n")); + int q = fn.ReverseFind('.'); + if(q >= 0) { + String fn0 = fn.Mid(0, q); + + Index done; + auto Variant = [&](const char *add, const char *m) { + if(done.Find(m) >= 0) + return; + String fn = fn0 + add + ".iml"; + for(int i = 0; i < pkg.GetCount(); i++) { + if(fn.EndsWith('/' + pkg[i])) { + h << "#define IMAGEFILE" << m << " <" << fn << ">\n"; + done.Add(m); + break; + } + } + }; + + Variant("HD_DARK", "_DARK_UHD"); + Variant("HD_DK", "_DARK_UHD"); + Variant("HDDK", "_DARK_UHD"); + Variant("HDK", "_DARK_UHD"); + + Variant("DARK_UHD", "_DARK_UHD"); + Variant("DK_HD", "_DARK_UHD"); + Variant("DK_UHD", "_DARK_UHD"); + Variant("DKHD", "_DARK_UHD"); + Variant("DKUHD", "_DARK_UHD"); + + Variant("HD", "_UHD"); + + Variant("DK", "_DARK"); + Variant("DARK", "_DARK"); + } + + h << "#include \n"; + + AppendClipboardText(h); PromptOK("The .cpp part was saved to clipboard"); } @@ -144,7 +180,7 @@ void Ide::InsertMenu(Bar& bar) if(ext == ".iml") { String c = GetFileTitle(fn); c.Set(0, ToUpper(c[0])); - bar.Add(fn + " include", THISBACK2(InsertIml, pp, c.EndsWith("Img") ? c : c + "Img")); + bar.Add(fn + " include", [=] { InsertIml(IdeWorkspace().GetPackage(pi), pp, c.EndsWith("Img") ? c : c + "Img"); }); n++; } if(ext == ".tpp") { diff --git a/uppsrc/ide/icon.ico b/uppsrc/ide/icon.ico index 99a7f892b..f85a52a40 100644 Binary files a/uppsrc/ide/icon.ico and b/uppsrc/ide/icon.ico differ diff --git a/uppsrc/ide/ide.h b/uppsrc/ide/ide.h index 1c067fe18..fba366c6f 100644 --- a/uppsrc/ide/ide.h +++ b/uppsrc/ide/ide.h @@ -808,7 +808,7 @@ public: void FindFileAll(const Vector>& f); void InsertColor(); void InsertLay(const String& fn); - void InsertIml(const String& fn, String classname); + void InsertIml(const Package& pkg, const String& fn, String classname); void InsertText(const String& text); void InsertCString(); void InsertFilePath(bool c);