uppsrc: QHD and XHD support (150% and 200%)

This commit is contained in:
Mirek Fidler 2026-05-03 15:40:29 +02:00
parent fd248968b3
commit dbd357833d
46 changed files with 5529 additions and 5580 deletions

View file

@ -73,6 +73,9 @@ extern const char *sClipFmtsRTF;
id menubar;
double Ctrl::display_scale = 1;
double Ctrl::display_unscale = 1;
void CocoInit(int argc, const char **argv, const char **envptr)
{
Ctrl::GlobalBackBuffer();
@ -102,16 +105,13 @@ void CocoInit(int argc, const char **argv, const char **envptr)
Font::SetFace(0, ToString((CFStringRef)[sysfont familyName]), Font::TTF);
Ctrl::SetUHDEnabled(true);
bool uhd = true;
for (NSScreen *screen in [NSScreen screens]) {
if([screen backingScaleFactor] < 2) {
uhd = false;
break;
}
}
SetUHDMode(uhd);
Font::SetDefaultFont(StdFont(fceil(DPI([sysfont pointSize]))));
Ctrl::display_scale = 1;
for (NSScreen *screen in [NSScreen screens])
Ctrl::display_scale = max(Ctrl::display_scale, [screen backingScaleFactor]);
Ctrl::display_unscale = 1 / Ctrl::display_scale;
Font::SetDefaultFont(StdFont(fceil(Ctrl::display_scale * [sysfont pointSize])));
GUI_DblClickTime_Write(1000 * NSEvent.doubleClickInterval);
@ -293,7 +293,7 @@ Rect Ctrl::GetWorkArea() const
Rect MakeScreenRect(NSScreen *screen, CGRect r)
{
r.origin.y = [screen frame].size.height - r.origin.y - r.size.height;
return MakeRect(r, DPI(1));
return MakeRect(r, Upp::Ctrl::SCL(1));
}
void Ctrl::GetWorkArea(Array<Rect>& rc)

View file

@ -41,7 +41,7 @@ NSPasteboard *Pasteboard(bool dnd = false)
@implementation CocoClipboardOwner
-(void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
{
RLOG(Upp::ToString(type));
LLOG(Upp::ToString(type));
Upp::GuiLock __;
auto render = [&](const Upp::String& fmt) -> Upp::String {
@ -53,7 +53,7 @@ NSPasteboard *Pasteboard(bool dnd = false)
NSPasteboard *pasteboard = Upp::Pasteboard(dnd);
if(Upp::IsStandardPasteboardType(type)) {
RLOG("Standard type - clearning contents!");
LLOG("Standard type - clearning contents!");
[pasteboard clearContents];
}

View file

@ -6,8 +6,12 @@ private:
static Ptr<Ctrl> lastActive;
static bool always_use_bundled_icon;
static double display_scale;
static double display_unscale;
friend void CocoInit(int argc, const char **argv, const char **envptr);
friend void Coco_PaintCh(void *cgcontext, int type, int value, int state);
protected:
virtual void MMClose() {}
@ -33,3 +37,6 @@ public:
void RegisterCocoaDropFormats();
static Rect GetScreenArea(Point pt);
static double GetDisplayScale() { return display_scale; }
static double GetDisplayUnScale() { return display_unscale; }
static int SCL(int x) { return (int)(display_scale * x); }

View file

@ -12,8 +12,9 @@ void SystemDraw::Init(void *cgContext, void *view)
CGContextSetBlendMode(cgHandle, kCGBlendModeNormal);
CGContextSetTextPosition(cgHandle, 0, 0);
CGContextSetTextDrawingMode(cgHandle, kCGTextFill);
if(IsUHDMode())
CGContextScaleCTM(cgHandle, 0.5, 0.5);
double sc = Ctrl::GetDisplayUnScale();
if(sc != 1)
CGContextScaleCTM(cgHandle, sc, sc);
}
SystemDraw::SystemDraw(void *cgContext, void *nsview)
@ -152,7 +153,7 @@ bool SystemDraw::IsPaintingOp(const Rect& r) const
if(cr.IsEmpty())
return false;
return true;
return nsview ? [(NSView *)nsview needsToDrawRect:MakeRectCG(1.0 / DPI(1) * cr)] : true;
// return nsview ? [(NSView *)nsview needsToDrawRect:MakeRectCG(1.0 / DPI(1) * cr)] : true;
}
Rect SystemDraw::GetPaintRect() const

View file

@ -2,7 +2,7 @@
#ifdef GUI_COCOA
#define LLOG(x)
#define LLOG(x) DLOG(x)
namespace Upp {
@ -85,9 +85,7 @@ void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, Color color)
if(cgimg) {
DLOG("Have cgimg");
Size isz = img.GetSize();
DDUMP(isz);
CGContextSaveGState(cgHandle);
Point off = GetOffset();
CGContextTranslateCTM(cgHandle, x + off.x, y + off.y);
@ -103,7 +101,6 @@ void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, Color color)
sCleanImageCache(img);
ImageSysDataMaker m;
LLOG("SysImage cache pixels " << cache.GetSize() << ", count " << cache.GetCount());
m.img = IsNull(color) ? img : CachedSetColorKeepAlpha(img, color); // TODO: Can setcolor be optimized out? By masks e.g.?
ImageSysData& sd = cg_image_cache.Get(m);
if(sd.cgimg) {
@ -273,7 +270,6 @@ NSImage *GetNSImage(const Image& img)
void Ctrl::SetNSAppImage(const Image& img)
{
ImageSysDataMaker m;
LLOG("SysImage cache pixels " << cache.GetSize() << ", count " << cache.GetCount());
m.img = img;
ImageSysData& sd = cg_image_cache.Get(m);
static CGImageRef cgimg;
@ -297,7 +293,6 @@ void Ctrl::SetMouseCursor(const Image& img)
return;
}
ImageSysDataMaker m;
LLOG("SysImage cache pixels " << cache.GetSize() << ", count " << cache.GetCount());
m.img = img;
ImageSysData& sd = cg_image_cache.Get(m);
static CGImageRef cgimg;
@ -329,7 +324,8 @@ void ImageDraw::Init(int cx, int cy)
colorSpace, kCGImageAlphaPremultipliedFirst,
NULL, NULL), NULL);
CGContextTranslateCTM(cgHandle, 0, cy);
if(IsUHDMode()) {
if(Ctrl::GetDisplayScale() == 2) { // scale can only be 1 or 2...
CGContextScaleCTM(cgHandle, 2, -2);
CGContextTranslateCTM(cgHandle, 0, -cy / 2.0);
}

View file

@ -111,13 +111,6 @@ inline Upp::Rect MakeRect(const CGRect& r, int dpi) {
return Upp::RectC(dpi * r.origin.x, dpi * r.origin.y, dpi * r.size.width, dpi * r.size.height);
}
inline CGRect CGRectDPI(const Upp::Rect& r) {
if(Upp::IsUHDMode())
return CGRectMake(0.5 * r.left, 0.5 * r.top, 0.5 * r.GetWidth(), 0.5 * r.GetHeight());
else
return CGRectMake(r.left, r.top, r.GetWidth(), r.GetHeight());
}
#endif
#endif

View file

@ -124,7 +124,7 @@ struct MMImp {
}
NSPoint np = [view convertPoint:[e locationInWindow] fromView:nil];
Rect r = view->ctrl->GetRect();
Upp::Point p(DPI(np.x), DPI(np.y));
Upp::Point p(Upp::Ctrl::SCL(np.x), Upp::Ctrl::SCL(np.y));
coco_mouse_pos = p + r.TopLeft();
if(event == Ctrl::MOUSEMOVE) {
@ -300,7 +300,7 @@ struct MMImp {
clip.action = info.draggingSourceOperationMask & NSDragOperationMove ? DND_MOVE
: DND_COPY;
NSPoint np = [nsview convertPoint:[info draggingLocation] fromView:nil];
coco_mouse_pos = Upp::Point(DPI(np.x), DPI(np.y)) + ctrl->GetScreenRect().TopLeft();
coco_mouse_pos = Upp::Point(Upp::Ctrl::SCL(np.x), Upp::Ctrl::SCL(np.y)) + ctrl->GetScreenRect().TopLeft();
ctrl->DnD(coco_mouse_pos, clip);
if(paste && clip.IsAccepted() && clip.GetAction() == DND_COPY)
Ctrl::local_dnd_copy = true;
@ -358,7 +358,7 @@ struct MMImp {
Upp::GuiLock __;
if(ctrl) {
Upp::SystemDraw w([[NSGraphicsContext currentContext] CGContext], self);
Upp::MMImp::Paint(ctrl, w, MakeRect(r, Upp::DPI(1)));
Upp::MMImp::Paint(ctrl, w, MakeRect(r, Upp::Ctrl::SCL(1)));
}
}

View file

@ -86,7 +86,7 @@ bool Ctrl::IsWndForeground() const
NSRect DesktopRect(const Rect& r)
{
double scalei = 1.0 / DPI(1);
double scalei = 1.0 / Upp::Ctrl::SCL(1);
return NSMakeRect(scalei * r.left,
scalei * (Ctrl::GetScreenArea(r.TopLeft()).GetHeight() - r.top - r.GetHeight()),
scalei * r.GetWidth(), scalei * r.GetHeight());
@ -187,6 +187,11 @@ Vector<Ctrl *> Ctrl::GetTopCtrls()
void WakeUpGuiThread();
inline CGRect CGRectDPI(const Upp::Rect& r) {
double sc = 1.0 / Upp::Ctrl::SCL(1);
return CGRectMake(sc * r.left, sc * r.top, sc * r.GetWidth(), sc * r.GetHeight());
}
void Ctrl::WndInvalidateRect(const Rect& r)
{
GuiLock __;
@ -317,7 +322,7 @@ void TopWindow::SyncCaption()
CGSize MMFrameSize(Size sz, dword style)
{
double scale = 1.0 / DPI(1);
double scale = 1.0 / Upp::Ctrl::SCL(1);
return [NSWindow frameRectForContentRect:
(NSRect)CGRectMake(100, 100, scale * sz.cx, scale * sz.cy) styleMask:style].size;
}

View file

@ -126,8 +126,6 @@ bool InitGtkApp(int argc, char **argv, const char **envptr)
EnterGuiMutex();
Ctrl::SetUHDEnabled(true);
Ctrl::scale = 1;
#if GTK_CHECK_VERSION(3, 10, 0)
if(Ctrl::IsWayland()) {

View file

@ -68,12 +68,12 @@ void TopWindow::Init()
int Ctrl::GetGtkTitleBarHeight(const TopWindow *tw)
{
return max(tw->custom_titlebar_cy, IsUHDMode() ? 60 : 31);
return max(tw->custom_titlebar_cy, DPI(31));
}
int Ctrl::GetGtkTitleBarButtonWidth()
{
return IsUHDMode() ? 94 : 47;
return DPI(47);
}
void TopWindow::SyncIcons()

View file

@ -110,12 +110,12 @@ close 232,17,35
int Ctrl::GetWin32TitleBarHeight(const TopWindow *tw)
{
return max(tw->custom_titlebar_cy, IsUHDMode() ? 60 : 31);
return max(tw->custom_titlebar_cy, DPI(31));
}
int Ctrl::GetWin32TitleBarButtonWidth()
{
return IsUHDMode() ? 94 : 47;
return DPI(47);
}
Rect Ctrl::GetTitleBarRect(const TopWindow *win) // TODO (image, cy)

File diff suppressed because one or more lines are too long

View file

@ -66,6 +66,11 @@ Image CocoImg(int type, int value = 0, int state = 0)
Color CocoColor(int k, Color bg = SColorFace())
{
#if 0
static int ii = 0; _DBG_
String p = GetHomeDirFile("Color" + AsString(ii++) + ".png"); _DBG_
DDUMP(p); PNGEncoder().SaveFile(p, CocoImg(bg, COCO_NSCOLOR, k, 0));
#endif
return AvgColor(CocoImg(bg, COCO_NSCOLOR, k, 0));
}
@ -135,11 +140,20 @@ void ChHostSkin()
SColorPaper_Write(CocoColor(COCO_PAPER));
if(Atoi(GetEnv("UPP_SCALE__"))) {
if(IsDarkTheme())
ChDarkSkin();
else
ChStdSkin();
return;
}
SColorFace_Write(CocoColor(COCO_WINDOW, White()));
SColorHighlight_Write(CocoColor(COCO_SELECTEDPAPER));
SColorHighlightText_Write(CocoColor(COCO_SELECTEDTEXT));
SColorText_Write(CocoColor(COCO_TEXT));
SColorDisabled_Write(CocoColor(COCO_DISABLED));
ChBaseSkin();

View file

@ -17,8 +17,9 @@ void Coco_PaintCh(void *cgcontext, int type, int value, int state)
{
auto dopaint = [&] {
auto cg = (CGContextRef) cgcontext;
if(Upp::IsUHDMode())
CGContextScaleCTM(cg, 2, 2);
double sc = Upp::Ctrl::GetDisplayScale();
if(sc != 1)
CGContextScaleCTM(cg, sc, sc);
CGRect cr = CGRectMake(0, 0, 140, 140);
if(type == COCO_NSCOLOR) {
CGContextSaveGState(cg);

View file

@ -84,11 +84,11 @@ Image CairoImage(int cx, int cy, Event<cairo_t *> draw)
{
Image m[2];
for(int i = 0; i < 2; i++) {
ImageDraw iw(DPI(cx), DPI(cy));
iw.DrawRect(0, 0, DPI(cx), DPI(cy), i ? Black() : White());
ImageDraw iw(cx, cy);
iw.DrawRect(0, 0, cx, cy, i ? Black() : White());
cairo_t *cr = iw;
#if GTK_CHECK_VERSION(3, 20, 0)
cairo_surface_set_device_scale(cairo_get_target(cr), DPI(1), DPI(1));
cairo_surface_set_device_scale(cairo_get_target(cr), Ctrl::SCL(1), Ctrl::SCL(1));
#endif
draw(cr);
m[i] = iw;
@ -100,8 +100,10 @@ Image CairoImage(int cx, int cy, Event<cairo_t *> draw)
Image CairoImage(GtkStyleContext *ctx, int cx = 40, int cy = 32)
{
return CairoImage(cx, cy, [&](cairo_t *cr) {
gtk_render_background(ctx, cr, 0, 0, cx, cy);
gtk_render_frame(ctx, cr, 0, 0, cx, cy);
double sx = cx / Ctrl::SCL(1);
double sy = cy / Ctrl::SCL(1);
gtk_render_background(ctx, cr, 0, 0, sx, sy);
gtk_render_frame(ctx, cr, 0, 0, sx, sy);
});
}
@ -166,7 +168,7 @@ void Gtk_New(const char *name, int state = 0, dword flags = 0)
sCtx = context2;
}
ASSERT(sCtx);
gtk_style_context_set_scale(sCtx, DPI(1));
gtk_style_context_set_scale(sCtx, GetDPIScaleRatio());
Gtk_State(state, flags);
GtkBorder border, padding;
@ -205,15 +207,16 @@ Color GetInkColor()
void SOImages(int imli, dword flags)
{
int n = (GetStdFontCy() - 2) / DPI(1);
if(n < 18) // sometimes it gets too small relative to text..
int n = GetStdFontCy() - 2;
if(n < 14) // sometimes it gets too small relative to text..
n = 14;
for(int st = 0; st < 4; st++) {
Gtk_State(st, flags);
CtrlsImg::Set(imli++, CairoImage(n, n, [&](cairo_t *cr) {
gtk_render_background(sCtx, cr, 0, 0, n, n);
gtk_render_frame(sCtx, cr, 0, 0, n, n);
gtk_render_check(sCtx, cr, 0, 0, n, n);
double sz = n / Ctrl::SCL(1);
gtk_render_background(sCtx, cr, 0, 0, sz, sz);
gtk_render_frame(sCtx, cr, 0, 0, sz, sz);
gtk_render_check(sCtx, cr, 0, 0, sz, sz);
}));
}
}
@ -250,8 +253,8 @@ Image Gtk_Icon(const char *icon_name, int size)
GdkPixbuf *pixbuf = gtk_icon_theme_load_icon_for_scale(gtk_icon_theme_get_default(), icon_name,
size, 2, (GtkIconLookupFlags)0, NULL);
if(pixbuf) {
int cx = gdk_pixbuf_get_width(pixbuf);
int cy = gdk_pixbuf_get_height(pixbuf);
int cx = gdk_pixbuf_get_width(pixbuf) * Ctrl::SCL(1);
int cy = gdk_pixbuf_get_height(pixbuf) * Ctrl::SCL(1);
Image m = CairoImage(cx, cy, [&](cairo_t *cr) {
gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
@ -397,7 +400,7 @@ void ChHostSkin()
Gtk_OverrideDialogIcon(CtrlImg::I_exclamation, "gtk-dialog-warning");
Gtk_OverrideDialogIcon(CtrlImg::I_error, "gtk-dialog-error");
}
YesButtonImage_Write(Gtk_IconAdjusted("gtk-yes", DPI(16)));
Image no_image = Gtk_IconAdjusted("gtk-no", DPI(16));
if(Difference(no_image, cancel_image) > 20) // it is ugly when No and Cancel buttons have the same icon

View file

@ -156,15 +156,12 @@ int ColorPopUp::GetCy()
(withvoid ? StdFont().Info().GetHeight() + DPI(3 + 2) : 0);
}
void ColorPopUp::DrawFilledFrame(Draw &w, int x, int y, int cx, int cy, Color fcol, Color bcol)
Rect ColorPopUp::DrawFilledFrame(Draw &w, Rect r, Color fcol, Color col)
{
DrawFrame(w, x, y, cx, cy, fcol);
w.DrawRect(x + DPI(1), y + DPI(1), cx - DPI(2), cy - DPI(2), bcol);
}
void ColorPopUp::DrawFilledFrame(Draw &w, Rect &r, Color fcol, Color bcol)
{
DrawFilledFrame(w, r.left, r.top, r.GetWidth(), r.GetHeight(), fcol, bcol);
DrawFrame(w, r, fcol);
r.Deflate(DPI(1) + 1);
w.DrawRect(r, col);
return r;
}
void ColorPopUp::Paint(Draw& w)
@ -213,7 +210,7 @@ void ColorPopUp::Paint(Draw& w)
for(;;) {
for(int x = 0; x < 18 * DPI(16); x += DPI(16)) {
if(i >= GetColorCount()) {
if(!norampwheel) {
if(!norampwheel) { // draw selected color in the bottom
Rect r(DPI(8 * 16 + 1), cy + DPI(4), DPI(10 * 16 - 1), sz.cy - DPI(4) - DPI(24));
DrawFilledFrame(w, r, SColorText, dark ? DarkThemeCached(color) : color);
@ -229,15 +226,19 @@ void ColorPopUp::Paint(Draw& w)
}
Color c = RealizeColor(GetColor(i));
DrawFilledFrame(w, x + DPI(1), y, DPI(14), DPI(14), SColorText, dark ? DarkThemeCached(c) : c);
if(i < 18 && scolors)
w.DrawRect(x + DPI(2) + DPI(6), y + DPI(1), DPI(6), DPI(12), dark ? c : DarkThemeCached(c));
Rect r = RectC(x + DPI(1), y, DPI(14), DPI(14));
Rect rc = DrawFilledFrame(w, r, SColorText, dark ? DarkThemeCached(c) : c);
if(i < 18 && scolors) {
rc.left += rc.Width() / 2;
w.DrawRect(rc, dark ? c : DarkThemeCached(c));
}
if(i == colori) {
r.Inflate(1);
if(GetMouseLeft())
DrawFrame(w, x, y - DPI(1), DPI(16), DPI(16), SColorShadow, SColorLight);
DrawFrame(w, r, SColorShadow, SColorLight);
else
DrawFrame(w, x, y - DPI(1), DPI(16), DPI(16), GUI_GlobalStyle() >= GUISTYLE_XP ? SColorText : SColorHighlight);
DrawFrame(w, r, GUI_GlobalStyle() >= GUISTYLE_XP ? SColorText : SColorHighlight);
}
i++;
}

View file

@ -93,7 +93,7 @@ bool CtrlLibDisplayError(const Value& e) {
String s = GetErrorText(e);
if(s.IsEmpty())
s = t_("Invalid data.");
Exclamation(s);
Exclamation("\1" + s);
return true;
}
@ -101,49 +101,7 @@ INITBLOCK
{
DisplayErrorFn() = &CtrlLibDisplayError;
}
/*
String SaveCtrlLayout(Ctrl::LogPos p, const String& classname, const String& variable,
const String& label, const String& help) {
String out;
if(classname.IsEmpty())
out << "\tUNTYPED(";
else
out << "\tITEM(" << classname << ", ";
out << variable << ", ";
switch(p.x.GetAlign()) {
case Ctrl::LEFT: out << Format("LeftPos(%d, %d).", p.x.GetA(), p.x.GetB()); break;
case Ctrl::RIGHT: out << Format("RightPos(%d, %d).", p.x.GetA(), p.x.GetB()); break;
case Ctrl::SIZE: out << Format("HSizePos(%d, %d).", p.x.GetA(), p.x.GetB()); break;
case Ctrl::CENTER: out << Format("HCenterPos(%d, %d).", p.x.GetB(), p.x.GetA()); break;
}
switch(p.y.GetAlign()) {
case Ctrl::TOP: out << Format("TopPos(%d, %d)", p.y.GetA(), p.y.GetB()); break;
case Ctrl::BOTTOM: out << Format("BottomPos(%d, %d)", p.y.GetA(), p.y.GetB()); break;
case Ctrl::SIZE: out << Format("VSizePos(%d, %d)", p.y.GetA(), p.y.GetB()); break;
case Ctrl::CENTER: out << Format("VCenterPos(%d, %d)", p.y.GetB(), p.y.GetA()); break;
}
if(!label.IsEmpty()) {
out << ".SetLabel(\"";
for(const char *s = label; *s; s++)
if(*s == '\n')
out.Cat("\\n");
else
out.Cat(*s);
out << "\")";
}
if(!help.IsEmpty()) {
out << ".HelpC(\"";
for(const char *s = help; *s; s++)
if(*s == '\n')
out.Cat("\\n");
else
out.Cat(*s);
out << "\")";
}
out << ")\n";
return out;
}
*/
void Show2(Ctrl& ctrl1, Ctrl& ctrl2, bool show) {
ctrl1.Show(show);
ctrl2.Show(show);
@ -473,10 +431,11 @@ struct ZoomIconMaker : ImageMaker {
ImagePainter w(sz);
w.Clear(RGBAZero());
w.Move(DPI(11), DPI(11)).Line(DPI(16), DPI(16)).Stroke(DPI(2), SBlack());
w.Circle(DPI(7), DPI(7), IsUHDMode() ? 12 : 6.5).Stroke(IsUHDMode() ? 3 : 1, SBlack());
int scale = GetDPIScale();
w.Circle(DPI(7), DPI(7), scale > DPI_100 ? scale * 3 : 6.5).Stroke(scale - 1, SBlack());
String txt = AsString(int(zoom * 100));
Image numbers = IsUHDMode() ? CtrlImg::Numbers2() : CtrlImg::Numbers1();
int gcx = IsUHDMode() ? 6 : 4;
Image numbers = scale >= DPI_200 ? CtrlImg::Numbers2() : CtrlImg::Numbers1();
int gcx = 3 + scale / 2;
Size tsz(txt.GetCount() * gcx, numbers.GetHeight());
int y = DPI(7) - tsz.cy / 2;
int x = DPI(7) - tsz.cx / 2;

View file

@ -1,4 +1,5 @@
PREMULTIPLIED
VERSION(20260403)
IMAGE_ID(S0)
IMAGE_ID(S0h)
IMAGE_ID(S0p)
@ -113,61 +114,61 @@ IMAGE_ID(TB1)
IMAGE_ID(TB1h)
IMAGE_BEGIN_DATA
IMAGE_DATA(120,156,237,152,75,110,195,48,12,68,221,174,155,109,239,127,19,251,40,217,228,28,109,80,32,128,76,113,88,146,214,135)
IMAGE_DATA(118,168,64,11,3,243,8,145,30,59,147,44,183,229,182,124,60,63,96,253,48,91,212,114,11,176,172,22,176,94,70,165)
IMAGE_DATA(167,231,188,24,51,106,214,94,31,152,252,182,181,54,236,227,241,168,54,96,89,45,96,189,140,74,79,207,121,49,102,212)
IMAGE_DATA(172,189,62,48,249,173,185,97,215,117,173,54,96,89,45,96,189,140,74,79,207,121,49,102,212,172,189,62,48,249,173,185)
IMAGE_DATA(97,183,109,171,54,96,89,45,96,189,140,74,79,207,121,49,102,212,172,189,62,48,249,173,185,97,13,217,229,112,174,42)
IMAGE_DATA(207,5,24,168,23,56,81,143,52,163,25,67,63,158,185,121,239,143,199,7,21,75,246,110,157,58,195,150,231,210,100,55)
IMAGE_DATA(174,31,41,39,130,254,89,205,104,198,208,143,103,110,222,251,227,241,65,197,146,189,91,167,206,176,229,185,52,217,141,235)
IMAGE_DATA(71,202,137,160,127,86,51,154,49,244,227,153,155,247,254,120,124,80,177,100,239,214,169,51,108,121,46,77,118,227,250,145)
IMAGE_DATA(114,34,232,159,213,140,102,12,253,120,230,230,189,63,30,31,84,44,217,251,69,12,43,14,15,109,203,74,38,153,146,177)
IMAGE_DATA(110,250,134,117,21,9,252,31,100,50,193,153,41,134,213,100,29,41,139,37,243,190,204,20,195,6,254,15,50,153,224,204)
IMAGE_DATA(20,195,142,202,59,26,157,133,161,26,238,154,211,255,199,188,174,209,140,16,35,205,84,170,131,250,148,106,161,53,250,158)
IMAGE_DATA(78,49,108,148,140,84,106,52,12,213,112,215,40,119,105,106,160,25,33,70,154,169,84,7,245,41,213,202,12,27,32,35)
IMAGE_DATA(149,26,13,67,53,220,53,202,93,154,26,104,70,136,145,102,42,213,65,125,74,181,142,206,186,21,51,197,176,81,50,82)
IMAGE_DATA(169,209,48,84,195,93,163,220,165,169,129,102,132,24,105,166,82,29,212,167,84,43,51,236,128,188,51,154,209,244,220,130)
IMAGE_DATA(25,213,79,68,102,138,97,163,100,216,214,140,166,231,22,76,228,25,100,134,61,17,163,233,185,5,19,121,6,189,153,41)
IMAGE_DATA(134,141,146,97,91,51,154,158,91,48,145,103,16,45,195,46,95,203,247,242,249,252,20,75,11,255,105,123,125,109,164,62)
IMAGE_DATA(245,169,239,174,55,61,239,91,249,178,184,223,239,234,183,204,75,219,235,71,81,234,83,159,250,190,122,235,243,126,248,101)
IMAGE_DATA(209,43,223,167,62,245,169,239,171,183,62,239,191,35,30,32,191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_DATA(120,156,237,152,75,110,195,48,12,68,221,174,155,109,207,147,155,39,71,241,198,231,104,131,2,1,100,138,195,146,140,62)
IMAGE_DATA(180,67,5,90,24,152,71,136,244,216,153,100,185,44,151,229,227,241,1,235,135,217,162,150,91,128,101,181,128,245,50,42)
IMAGE_DATA(61,61,231,201,152,81,179,246,250,192,228,183,107,107,195,110,219,86,109,192,178,90,192,122,25,149,158,158,243,100,204,168)
IMAGE_DATA(89,123,125,96,242,91,115,195,222,110,183,106,3,150,213,2,214,203,168,244,244,156,39,99,70,205,218,235,3,147,223,154)
IMAGE_DATA(27,246,126,191,87,27,176,172,22,176,94,70,165,167,231,60,25,51,106,214,94,31,152,252,214,220,176,134,236,242,114,174)
IMAGE_DATA(42,207,5,24,168,23,56,81,143,52,163,25,67,63,158,185,121,239,143,199,7,21,75,246,110,29,58,195,150,231,210,100)
IMAGE_DATA(55,174,31,41,39,130,254,89,205,104,198,208,143,103,110,222,251,227,241,65,197,146,189,91,135,206,176,229,185,52,217,141)
IMAGE_DATA(235,71,202,137,160,127,86,51,154,49,244,227,153,155,247,254,120,124,80,177,100,239,214,161,51,108,121,46,77,118,227,250)
IMAGE_DATA(145,114,34,232,159,213,140,102,12,253,120,230,230,189,63,30,31,84,44,217,251,69,12,43,14,15,109,203,74,38,153,146)
IMAGE_DATA(177,110,250,134,117,21,9,252,31,100,50,193,153,41,134,213,100,29,41,139,37,243,190,204,20,195,6,254,15,50,153,224)
IMAGE_DATA(204,20,195,142,202,59,26,157,133,161,26,238,154,211,255,199,60,175,209,140,16,35,205,84,170,131,250,148,106,161,53,250)
IMAGE_DATA(158,78,49,108,148,140,84,106,52,12,213,112,215,40,119,105,106,160,25,33,70,154,169,84,7,245,41,213,202,12,27,32)
IMAGE_DATA(35,149,26,13,67,53,220,53,202,93,154,26,104,70,136,145,102,42,213,65,125,74,181,94,157,117,43,102,138,97,163,100)
IMAGE_DATA(164,82,163,97,168,134,187,70,185,75,83,3,205,8,49,210,76,165,58,168,79,169,86,102,216,1,121,103,52,163,233,185)
IMAGE_DATA(5,51,170,159,136,204,20,195,70,201,176,173,25,77,207,45,152,200,51,200,12,123,32,70,211,115,11,38,242,12,122,51)
IMAGE_DATA(83,12,27,37,195,182,102,52,61,183,96,34,207,32,90,134,93,190,150,239,229,243,241,41,150,22,254,211,246,250,218,72)
IMAGE_DATA(125,234,83,223,93,111,122,222,175,229,203,98,93,87,245,91,230,169,237,245,163,40,245,169,79,125,95,189,245,121,127,249)
IMAGE_DATA(101,209,43,223,167,62,245,169,239,171,183,62,239,191,130,149,22,191,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_END_DATA(576, 23)
IMAGE_BEGIN_DATA
IMAGE_DATA(120,156,237,154,219,79,19,65,24,197,27,124,51,196,39,99,252,43,253,43,124,241,193,248,138,196,71,76,52,33,6,99)
IMAGE_DATA(136,220,90,90,10,244,126,167,8,4,104,75,111,20,138,92,20,125,92,251,97,166,41,223,204,116,207,148,141,172,116,182)
IMAGE_DATA(249,165,219,153,115,182,105,119,230,163,103,134,240,100,224,89,96,162,247,160,163,90,173,58,189,39,8,161,109,54,155,16)
IMAGE_DATA(194,103,245,86,111,245,254,208,27,207,247,39,129,231,253,98,225,220,225,72,237,93,56,83,243,71,16,164,21,135,120,141)
IMAGE_DATA(64,218,65,95,114,247,28,130,251,18,59,223,33,184,47,254,237,12,130,251,98,219,93,8,238,219,44,159,66,72,190,173)
IMAGE_DATA(19,8,238,219,40,117,32,184,111,189,116,12,193,125,209,98,27,130,251,214,10,45,8,201,151,111,66,112,95,36,215,128)
IMAGE_DATA(224,190,112,182,14,193,125,171,25,12,238,11,165,107,16,178,175,10,33,125,190,212,30,132,116,31,82,101,8,105,156,165)
IMAGE_DATA(114,16,131,190,81,235,210,40,135,47,138,105,179,251,27,130,127,185,141,211,95,16,94,249,234,39,215,16,94,249,142,58)
IMAGE_DATA(63,33,188,242,213,142,127,64,120,231,187,130,224,190,106,251,10,66,246,93,66,112,95,165,117,9,33,251,46,32,184,239)
IMAGE_DATA(176,121,1,33,251,206,33,60,243,213,59,16,146,239,168,1,33,249,170,21,136,177,46,166,111,62,102,33,248,151,107,125)
IMAGE_DATA(214,103,125,247,231,155,158,203,65,112,223,251,133,60,4,247,125,142,20,32,124,81,76,195,225,176,51,42,229,82,218,153)
IMAGE_DATA(253,240,22,130,180,194,39,94,35,144,118,208,183,85,76,65,112,95,169,144,132,224,190,98,62,1,193,125,133,92,28,130)
IMAGE_DATA(251,242,217,24,132,228,203,108,66,112,95,46,189,1,193,125,217,244,58,4,247,101,82,81,8,238,75,39,215,32,36,95)
IMAGE_DATA(34,2,193,125,169,120,24,130,251,146,177,85,8,238,75,108,134,32,184,47,190,17,132,144,125,43,16,178,111,25,66,254)
IMAGE_DATA(124,75,16,210,125,136,45,66,12,250,70,173,75,163,16,160,13,150,71,189,7,29,221,206,142,51,10,239,102,131,206,203)
IMAGE_DATA(233,121,231,197,171,79,183,160,54,234,227,90,98,175,218,114,186,231,87,253,170,78,231,212,38,250,133,158,174,65,237,161)
IMAGE_DATA(124,87,73,182,152,185,209,8,61,189,47,93,43,152,59,85,114,112,80,252,171,25,208,211,17,204,157,40,233,95,147,233)
IMAGE_DATA(87,178,29,37,94,233,151,51,199,74,244,250,182,18,189,190,165,68,167,95,74,55,149,120,165,95,76,53,148,232,245,117)
IMAGE_DATA(37,94,233,67,153,138,18,149,158,198,91,52,183,175,132,143,55,49,158,227,197,29,37,124,60,139,249,64,237,116,45,209)
IMAGE_DATA(78,231,212,198,231,139,233,124,52,225,191,41,22,135,237,107,37,186,98,161,211,235,138,133,78,175,27,76,86,255,176,245)
IMAGE_DATA(149,246,165,18,93,177,168,181,207,148,232,138,69,189,221,81,98,139,133,162,88,172,167,211,78,190,92,112,14,42,219,55)
IMAGE_DATA(208,57,181,169,138,5,181,191,238,101,110,21,212,199,139,5,93,75,167,167,62,126,179,233,253,117,122,234,179,250,241,211)
IMAGE_DATA(79,209,90,141,2,149,158,198,212,204,66,94,9,31,111,98,60,207,69,10,74,248,120,54,157,47,190,47,22,209,240,156)
IMAGE_DATA(243,245,203,140,148,145,168,141,250,184,150,216,223,77,56,141,90,190,223,78,231,212,38,250,69,59,93,131,218,117,49,132)
IMAGE_DATA(250,72,35,244,244,190,116,45,93,12,161,62,210,12,234,233,121,88,12,81,233,135,197,10,47,244,195,98,136,90,175,143)
IMAGE_DATA(33,106,189,62,134,168,244,195,98,133,23,250,97,49,68,173,215,199,10,47,244,195,98,8,215,211,152,210,197,16,62,222)
IMAGE_DATA(196,120,214,197,16,62,158,77,231,139,233,124,52,42,22,143,111,254,41,212,188,88,32,213,11,141,28,232,186,4,186,30)
IMAGE_DATA(129,174,67,160,235,9,166,58,183,245,6,116,157,1,93,95,64,215,9,76,117,110,235,8,232,122,128,169,206,109,189,0)
IMAGE_DATA(93,39,64,215,7,76,126,234,123,249,87,219,87,147,207,45,231,163,249,30,205,125,86,231,79,157,91,254,70,115,55,154)
IMAGE_DATA(183,31,244,228,115,203,3,104,110,70,243,50,154,163,172,206,159,58,183,60,139,230,88,52,191,154,228,86,95,76,62,228)
IMAGE_DATA(119,48,250,251,26,205,161,104,254,68,115,39,154,31,77,117,110,249,18,205,149,104,158,68,115,161,169,206,45,55,162,249)
IMAGE_DATA(207,84,231,150,15,209,92,136,230,65,147,28,232,101,254,11,76,6,158,246,166,222,196,173,201,103,247,157,237,190,243,93)
IMAGE_DATA(245,118,223,249,223,239,59,223,219,100,118,203,139,252,203,117,203,141,252,230,249,109,95,210,234,239,87,63,14,251,194,158)
IMAGE_DATA(77,102,187,111,107,245,126,214,143,195,190,237,31,102,158,15,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_DATA(120,156,237,154,91,79,19,65,24,134,27,188,51,196,43,99,252,57,254,34,127,133,55,94,24,111,145,120,137,137,38,196)
IMAGE_DATA(96,12,81,14,45,45,5,122,62,83,4,2,180,165,39,10,69,14,138,94,174,253,48,211,148,111,102,186,239,148,141,172)
IMAGE_DATA(116,182,121,210,237,204,251,110,211,238,204,71,223,25,158,77,6,158,4,38,122,15,58,170,213,170,211,123,130,16,218,102)
IMAGE_DATA(179,9,33,124,86,111,245,86,239,15,189,241,124,127,20,120,218,47,22,206,45,142,212,238,185,51,53,127,8,65,90,113)
IMAGE_DATA(136,215,8,164,29,244,37,119,206,32,184,47,177,253,29,130,251,226,223,78,33,184,47,182,213,133,224,190,141,242,9,132)
IMAGE_DATA(228,219,60,134,224,190,245,82,7,130,251,214,74,71,16,220,23,45,182,33,184,111,181,208,130,144,124,249,38,4,247,69)
IMAGE_DATA(114,13,8,238,11,103,235,16,220,183,146,193,224,190,80,186,6,33,251,170,16,210,231,75,237,66,72,247,33,85,134,144)
IMAGE_DATA(198,89,42,7,49,232,27,181,46,141,114,248,162,152,54,187,191,33,248,151,219,56,249,5,225,149,175,126,124,5,225,149)
IMAGE_DATA(239,176,243,19,194,43,95,237,232,7,132,119,190,75,8,238,171,182,47,33,100,223,5,4,247,85,90,23,16,178,239,28)
IMAGE_DATA(130,251,14,154,231,16,178,239,12,194,51,95,189,3,33,249,14,27,16,146,175,90,129,24,235,98,250,250,67,22,130,127)
IMAGE_DATA(185,214,103,125,214,119,119,190,233,185,28,4,247,189,251,154,135,224,190,79,145,2,132,47,138,105,56,28,118,70,165,92)
IMAGE_DATA(74,59,179,239,223,64,144,86,248,196,107,4,210,14,250,54,139,41,8,238,43,21,146,16,220,87,204,39,32,184,175,144)
IMAGE_DATA(139,67,112,95,62,27,131,144,124,153,13,8,238,203,165,215,33,184,47,155,94,131,224,190,76,42,10,193,125,233,228,42)
IMAGE_DATA(132,228,75,68,32,184,47,21,15,67,112,95,50,182,2,193,125,137,141,16,4,247,197,215,131,16,178,111,25,66,246,45)
IMAGE_DATA(65,200,159,111,17,66,186,15,177,5,136,65,223,168,117,105,20,2,180,193,242,160,247,160,163,219,217,118,70,225,237,108)
IMAGE_DATA(208,121,49,61,239,60,127,249,241,6,212,70,125,92,75,236,86,91,78,247,236,178,95,213,233,156,218,68,191,208,211,53)
IMAGE_DATA(168,61,148,239,42,201,22,51,215,26,161,167,247,165,107,5,115,39,74,246,247,139,127,53,3,122,58,130,185,99,37,253)
IMAGE_DATA(107,50,253,114,182,163,196,43,253,82,230,72,137,94,223,86,162,215,183,148,232,244,139,233,166,18,175,244,11,169,134,18)
IMAGE_DATA(189,190,174,196,43,125,40,83,81,162,210,211,120,139,230,246,148,240,241,38,198,115,188,184,173,132,143,103,49,31,168,157)
IMAGE_DATA(174,37,218,233,156,218,248,124,49,157,143,38,252,55,197,226,160,125,165,68,87,44,116,122,93,177,208,233,117,131,201,234)
IMAGE_DATA(239,183,190,210,190,80,162,43,22,181,246,169,18,93,177,168,183,59,74,108,177,80,20,139,181,116,218,201,151,11,206,126)
IMAGE_DATA(101,235,26,58,167,54,85,177,160,246,87,189,204,173,130,250,120,177,160,107,233,244,212,199,111,54,189,191,78,79,125,86)
IMAGE_DATA(63,126,250,41,90,171,81,160,210,211,152,154,249,154,87,194,199,155,24,207,115,145,130,18,62,158,77,231,139,239,139,69)
IMAGE_DATA(52,60,231,124,249,60,35,101,36,106,163,62,174,37,246,118,18,78,163,150,239,183,211,57,181,137,126,209,78,215,160,118)
IMAGE_DATA(93,12,161,62,210,8,61,189,47,93,75,23,67,168,143,52,131,122,122,30,22,67,84,250,97,177,194,11,253,176,24,162)
IMAGE_DATA(214,235,99,136,90,175,143,33,42,253,176,88,225,133,126,88,12,81,235,245,177,194,11,253,176,24,194,245,52,166,116,49)
IMAGE_DATA(132,143,55,49,158,117,49,132,143,103,211,249,98,58,31,141,138,197,195,235,127,10,53,47,22,72,245,66,35,7,186,46)
IMAGE_DATA(129,174,71,160,235,16,232,122,130,169,206,109,189,1,93,103,64,215,23,208,117,2,83,157,219,58,2,186,30,96,170,115)
IMAGE_DATA(91,47,64,215,9,208,245,1,147,159,250,94,254,213,246,213,228,115,203,249,104,190,71,115,159,213,249,83,231,150,191,209)
IMAGE_DATA(220,141,230,237,123,61,249,220,242,0,154,155,209,188,140,230,40,171,243,167,206,45,207,162,57,22,205,175,38,185,213,23)
IMAGE_DATA(147,15,249,29,140,254,190,70,115,40,154,63,209,220,137,230,71,83,157,91,190,68,115,37,154,39,209,92,104,170,115,203)
IMAGE_DATA(141,104,254,51,213,185,229,67,52,23,162,121,208,36,7,122,153,255,2,147,129,199,189,169,55,113,99,242,217,125,103,187)
IMAGE_DATA(239,124,91,189,221,119,254,247,251,206,119,54,153,221,242,34,255,114,221,114,35,191,121,126,219,151,180,250,187,213,143,195)
IMAGE_DATA(190,176,103,147,217,238,219,90,189,159,245,227,176,111,251,7,172,160,14,202,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_END_DATA(1088, 16)
IMAGE_BEGIN_DATA
@ -221,20 +222,20 @@ IMAGE_DATA(205,84,212,187,160,211,128,248,239,130,62,83,209,204,255,103,139,203,
IMAGE_END_DATA(1504, 56)
IMAGE_BEGIN_DATA
IMAGE_DATA(120,156,237,150,81,75,2,65,16,199,183,76,173,215,162,62,175,95,35,232,193,160,135,160,32,161,160,183,56,72,8,130)
IMAGE_DATA(162,52,77,67,189,243,50,205,174,196,178,94,66,184,118,54,71,118,198,187,83,122,58,186,221,227,135,187,243,255,223,238)
IMAGE_DATA(221,238,236,158,98,77,108,138,148,188,244,146,203,229,124,29,193,10,196,44,203,34,232,190,32,157,251,140,199,120,226,224)
IMAGE_DATA(17,102,3,24,79,146,61,34,43,183,64,212,6,136,74,252,121,3,97,31,113,209,194,38,3,248,243,73,144,207,231,9)
IMAGE_DATA(252,36,224,58,247,25,143,241,196,193,99,62,133,198,147,104,143,217,0,198,147,104,143,249,47,56,193,252,23,52,158,68)
IMAGE_DATA(123,228,73,144,21,203,242,90,145,23,79,124,78,92,118,116,20,34,35,95,104,73,94,33,101,102,55,79,98,60,238,7)
IMAGE_DATA(196,253,144,120,152,63,170,127,250,60,1,15,29,117,67,212,32,81,15,22,246,50,139,246,79,11,159,229,226,170,216,82)
IMAGE_DATA(185,148,22,27,42,112,110,21,252,211,227,61,255,112,127,91,1,117,136,161,6,184,78,197,247,94,28,5,212,49,14,94)
IMAGE_DATA(104,127,125,122,132,147,194,238,180,79,184,103,244,209,39,28,29,236,76,199,3,255,251,176,71,64,13,245,225,224,137,192)
IMAGE_DATA(245,193,219,35,129,235,175,94,155,192,117,175,111,19,184,222,127,110,17,184,222,235,54,8,92,239,118,30,8,92,239,184)
IMAGE_DATA(53,2,215,221,118,149,192,245,182,125,71,224,186,221,44,17,184,222,106,220,18,184,94,191,191,36,232,58,172,111,165,84)
IMAGE_DATA(36,224,250,98,126,220,92,157,17,48,63,48,143,160,13,247,0,80,199,248,188,252,44,102,38,201,156,98,201,28,148,196)
IMAGE_DATA(229,242,133,66,79,94,104,55,237,170,2,234,56,80,173,126,61,141,67,29,7,199,24,98,226,139,199,91,206,47,122,28)
IMAGE_DATA(230,214,145,9,13,224,60,227,186,184,110,85,129,235,18,182,142,97,235,62,123,244,165,85,182,164,36,235,36,91,120,166)
IMAGE_DATA(64,209,179,68,47,152,33,163,209,80,181,225,23,223,70,47,73,142,141,199,223,36,198,231,42,104,78,131,230,62,104,141)
IMAGE_DATA(204,247,203,124,191,254,205,247,235,7,175,208,225,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_DATA(120,156,237,150,209,74,2,65,20,134,167,76,173,219,162,158,167,71,243,53,130,46,12,186,8,10,18,10,186,139,133,130)
IMAGE_DATA(32,40,74,211,52,212,93,55,211,108,75,44,235,38,132,109,206,228,145,57,199,221,85,186,90,218,153,229,195,153,243,255)
IMAGE_DATA(59,179,59,115,102,86,177,34,214,69,74,94,122,201,229,114,190,142,96,5,98,150,101,17,116,95,144,206,125,198,99,60)
IMAGE_DATA(113,240,8,179,1,140,39,201,30,145,149,91,32,106,3,68,37,254,172,129,176,143,184,104,97,147,1,252,249,36,200,231)
IMAGE_DATA(243,4,126,18,112,157,251,140,199,120,226,224,49,159,66,227,73,180,199,108,0,227,73,180,199,252,23,28,99,254,11,26)
IMAGE_DATA(79,162,61,242,36,200,138,69,121,45,201,139,39,62,39,46,59,58,10,145,145,47,180,32,175,144,50,181,155,199,49,30)
IMAGE_DATA(247,3,226,126,72,60,204,31,213,63,125,158,128,135,142,186,33,106,144,168,7,11,123,153,121,251,167,133,207,242,230,178)
IMAGE_DATA(216,80,185,148,22,107,42,112,102,21,252,147,163,93,255,96,111,75,1,117,136,161,6,184,78,217,247,94,28,5,212,49)
IMAGE_DATA(14,94,104,127,125,122,132,227,194,206,164,79,184,103,248,209,35,28,238,111,79,198,3,255,251,160,75,64,13,245,65,255)
IMAGE_DATA(137,192,245,254,219,35,129,235,175,94,139,192,117,175,103,19,184,222,123,110,18,184,222,237,212,9,92,239,180,31,8,92)
IMAGE_DATA(111,187,85,2,215,221,86,133,192,245,150,125,71,224,186,221,40,18,184,222,172,223,18,184,94,187,191,36,232,58,172,111)
IMAGE_DATA(185,120,78,192,245,197,252,184,185,58,37,96,126,96,30,65,27,238,1,160,142,241,89,249,185,153,25,39,115,138,37,115)
IMAGE_DATA(80,18,151,74,23,10,61,121,161,221,176,43,10,168,227,64,213,218,245,36,14,117,28,28,99,136,137,207,31,111,58,191)
IMAGE_DATA(232,113,152,91,71,38,52,128,243,140,235,226,186,21,5,174,75,216,58,134,173,251,244,209,151,86,217,146,146,172,146,108)
IMAGE_DATA(225,153,2,69,207,18,189,96,134,12,135,3,213,134,95,124,27,189,36,57,54,26,125,147,24,159,171,160,57,13,154,251)
IMAGE_DATA(160,53,50,223,47,243,253,250,55,223,175,31,122,108,223,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_END_DATA(512, 17)

View file

@ -95,8 +95,7 @@ private:
Color GetColor(int i) const;
void Select();
void DrawFilledFrame(Draw &w, int x, int y, int cx, int cy, Color fcol, Color bcol);
void DrawFilledFrame(Draw &w, Rect &r, Color fcol, Color bcol);
Rect DrawFilledFrame(Draw &w, Rect r, Color fcol, Color bcol);
int colori;
bool notnull;

View file

@ -230,7 +230,6 @@ public:
DropList& SetScrollBarStyle(const ScrollBar::Style& s) { list.SetScrollBarStyle(s); return *this; }
DropList();
virtual ~DropList();
};
void Append(DropList& list, const VectorMap<Value, Value>& values);

View file

@ -19,8 +19,6 @@ DropList::DropList()
usewheel = true;
}
DropList::~DropList() {}
int DropList::FindKey(const Value& k) const
{
return key.Find(k);

View file

@ -129,7 +129,7 @@ void Font::SyncStdFont()
}
LLOG("SyncStdFont " << StdFontSize);
SyncUHDMode();
SyncDPIScale();
}
void (*whenSetStdFont)();
@ -164,6 +164,13 @@ bool Font::std_font_override;
void Font::SetDefaultFont(Font font)
{
LLOG("SetDefaultFont " << font);
int override_scale = Atoi(GetEnv("UPP_SCALE__"));
if(override_scale) {
int cy = decode(override_scale, 3, 18, 4, 24, 6, 36, 12);
for(int i = 0; i < 20; i++)
if(font.Height(cy + i).GetCy() >= cy)
break;
}
if(!std_font_override)
SetStdFont0(font);
}

View file

@ -81,6 +81,7 @@ class ImageBuffer : NoCopy {
void InitAttrs();
friend class Image;
friend void iml_ReplaceAll(Image& tgt, const Image& src);
public:
void SetKind(int k) { kind = k; }
@ -179,7 +180,7 @@ private:
friend struct scImageMaker;
void SetAuxData(uint64 data);
friend void iml_ReplaceAll(Image& tgt, Image& src);
friend void iml_ReplaceAll(Image& tgt, const Image& src);
public:
Size GetSize() const { return data ? data->buffer.GetSize() : Size(0, 0); }
@ -274,42 +275,41 @@ Vector<ImageIml> UnpackImlDataUncompressed(const String& data);
Vector<ImageIml> UnpackImlData(const void *ptr, int len);
Vector<ImageIml> UnpackImlData(const String& d);
enum {
GUI_MODE_NORMAL = 0,
GUI_MODE_DARK = 1,
GUI_MODE_UHD = 2,
GUI_MODE_DARK_UHD = 3,
};
enum {
enum { // internal - represents binary flags in imported iml data
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,
IML_IMAGE_FLAG_S3 = 0x20,
IML_IMAGE_FLAG_QHD = 0x40,
IML_IMAGE_FLAGS_UNKNOWN = 0xffffffff, // internal - flags are not yet known
};
Image MakeImlImage(const String& id, Function<ImageIml (int, const String&)> GetRaw, dword global_flags);
Image MakeImlImage(const String& id, Event<int, ImageIml&, String&> GetRaw);
class Iml {
struct IImage : Moveable<IImage> {
std::atomic<bool> loaded;
Image image;
IImage() { loaded = false; }
IImage() { loaded = false; }
};
struct Data : Moveable<Data> {
const char *data;
int len, count;
};
Vector<Data> data[4]; // 0 normal, 1 HiDPI - HD, 2 DK - Dark, 3 HDK - HiDPI + dark
VectorMap<String, IImage> map;
Vector<Data> data;
const char **name;
dword global_flags = 0;
bool premultiply;
Index<String> ex_name[3]; // 0 HiDPI - HD, 1 DK - Dark, 2 HDK - HiDPI + dark
VectorMap<String, IImage> map;
Buffer<dword> flags;
int img_count = 0;
int version = 0;
void Init(int n);
@ -322,15 +322,16 @@ public:
int Find(const String& id) const { return map.Find(id); }
void Set(int i, const Image& img);
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
ImageIml GetRaw(int i);
dword GetRawFlags(int i);
// these methods serve for .iml import
Iml(const char **name, int n);//Deprecated - legacy .iml
void AddData(const byte *data, int len, int count, int mode = 0);
void AddData(const byte *data, int len, int count);
void AddId(int mode1, const char *name);
void Premultiplied() { premultiply = false; }
void GlobalFlag(dword f) { global_flags |= f; }
void Version(int v) { version = v; }
static void ResetAll(); // clears all .iml caches
static void SkinAll(); // reskins all .iml caches

View file

@ -7,7 +7,7 @@ Image WithHotSpots(const Image& m, Point hotspot, Point hotspot2 = Point(0, 0));
Image WithHotSpots(const Image& m, int x1, int y1, int x2, int y2);
Image WithHotSpot(const Image& m, int x1, int y1);
void ScanOpaque(Image& m);
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), bool co = false);
@ -266,19 +266,37 @@ Image Upscale2x(const Image& src);
Image Downscale2x(const Image& src);
Image Downscale6x(const Image& src);
void SetUHDMode(bool b = true);
bool IsUHDMode();
void SyncUHDMode();
enum {
DPI_100 = 2, // Normal resolution
DPI_150 = 3, // QHD
DPI_200 = 4, // UHD
DPI_300 = 6,
DPI_600 = 12, // Used for 'master' Image drawn without aliasing
};
// Image DPI(const Image& m);
Image DPI(const Image& img, int expected);
void SetDPIScale(int scale);
void SyncDPIScale();
inline int DPI(int a) { return IsUHDMode() ? 2 * a : a; }
inline double DPI(double a) { return IsUHDMode() ? 2 * a : a; }
inline Size DPI(Size sz) { return IsUHDMode() ? 2 * sz : sz; }
inline Size DPI(int cx, int cy) { return Size(DPI(cx), DPI(cy)); }
inline int GetDPIScale() { extern int DPIScaleGlobal_; return DPIScaleGlobal_; }
inline double GetDPIScaleRatio() { extern double DPIScaleGlobalF_; return DPIScaleGlobalF_; }
inline double GetDPIUnScaleRatio() { extern double IDPIScaleGlobalF_; return IDPIScaleGlobalF_; }
inline Image DPI(const Image& a, const Image& b) { return IsUHDMode() ? b : a; }
inline int DPI(int a) { return (GetDPIScale() * a) >> 1; }
inline double DPI(double a) { return GetDPIScaleRatio() * a; }
inline Size DPI(int cx, int cy) { return Size(DPI(cx), DPI(cy)); }
inline Size DPI(Size sz) { return DPI(sz.cx, sz.cy); }
Image DPISmartRescale(const Image& src, Size sz);
Image DPISmartRescaleCached(const Image& src, Size sz);
int ImlFlagsToDPIScale(int imlflags);
int DPIScaleToImlFlags(int dpiscale);
inline int DPI2(int dpi200val, int dpi100val) {
int scale = GetDPIScale();
return (dpi200val - dpi100val) * (scale - DPI_100) / 2 + dpi100val;
}
struct RGBAV {
dword r, g, b, a;

View file

@ -41,10 +41,13 @@ Vector<ImageIml> UnpackImlData(const String& d)
return UnpackImlData(~d, d.GetLength());
}
void iml_ReplaceAll(Image& tgt, Image& src)
void iml_ReplaceAll(Image& tgt, const Image& src)
{ // this very special function replaces all unmodified instances of Image with new content
if(tgt.GetSize() == src.GetSize() && tgt.data) {
tgt.data->buffer = src.data->buffer;
Image h = src; // make sure src has refcount 1, basically 'clone'
ImageBuffer ib = h;
h = ib;
if(tgt.GetSize() == h.GetSize() && tgt.data && src.data) {
tgt.data->buffer = h.data->buffer;
tgt.data->NewSerial();
}
else
@ -55,6 +58,7 @@ void Iml::Init(int n)
{
for(int i = 0; i < n; i++)
map.Add(name[i]);
flags.Alloc(map.GetCount(), IML_IMAGE_FLAGS_UNKNOWN);
}
void Iml::Reset()
@ -72,25 +76,181 @@ void Iml::Skin()
}
}
void Iml::AddData(const byte *s, int len, int count)
{
Data& d = data.Add();
d.data = (const char *)s;
d.len = len;
d.count = count;
img_count += count;
data.Shrink();
}
void Iml::AddId(int mode1, const char *name)
{
map.Add(name);
}
static StaticMutex sImlLock;
ImageIml Iml::GetRaw(int i)
{
int i0 = 0;
for(const Data& d : data) {
if(i >= i0 && i < i0 + d.count) {
ImageIml m = MakeValue(
[&] {
String key;
RawCat(key, d.data); // all is static
return key;
},
[&](Value& v) {
Vector<ImageIml>& m = CreateRawValue<Vector<ImageIml>>(v);
m = UnpackImlData(d.data, d.len);
ASSERT(m.GetCount() == d.count);
int sz = 0;
int ii = i0;
for(ImageIml& img : m) {
sz += img.image.GetLength();
if(premultiply)
img.image = Premultiply(img.image);
if(version == 0) // cleanup some bits that are set for legacy reasons
img.flags &= 0x3f;
flags[ii++] = img.flags;
}
return sz;
}
).To<Vector<ImageIml>>()[i - i0];
m.flags |= global_flags;
return m;
}
i0 += d.count;
}
return ImageIml();
}
void Iml::Set(int i, const Image& img)
{ // TODO: MT
IImage& m = map[i];
Image h = img; // make sure h has refcount 1, basically 'clone'
ImageBuffer ib = h;
h = ib;
iml_ReplaceAll(m.image, h);
iml_ReplaceAll(m.image, img);
m.loaded = true;
}
Image MakeImlImage(const String& id, Event<int, dword&, String&> GetRawFlags, Function<ImageIml(int)> GetRaw)
{
int scale = GetDPIScale();
bool dark = IsDarkTheme();
int best_i = -1;
int exact_scale_i = -1;
int best_dark = 10; // minimize this
int best_scale = -1; // maximize this
int ii = 0;
for(;;) {
dword flags;
String iid;
GetRawFlags(ii, flags, iid);
if(IsNull(iid))
break;
int q = iid.Find("__");
if(q > 0)
iid.Trim(q);
if(iid == id) {
bool isdark = flags & IML_IMAGE_FLAG_DARK;
int iscale = ImlFlagsToDPIScale(flags);
if(isdark == dark && iscale == scale) // found perfect match
return GetRaw(ii).image;
if(iscale == scale)
exact_scale_i = ii;
int idark = !!isdark - dark;
if(CombineCompare(best_dark, idark)(iscale, best_scale) > 0) { // prioritize color, then find highest scale
best_i = ii;
best_dark = idark;
best_scale = iscale;
}
}
ii++;
}
auto AdjustColor0 = [&](const Image& img, dword flags) { // flip light to dark if needed
if(dark && !(flags & (IML_IMAGE_FLAG_FIXED|IML_IMAGE_FLAG_FIXED_COLORS|IML_IMAGE_FLAG_DARK)))
return DarkTheme(img);
return img;
};
if(best_dark && exact_scale_i >= 0) { // dark color version not found, but we have exact scale
ImageIml m = GetRaw(exact_scale_i);
return AdjustColor0(m.image, m.flags);
}
if(best_i < 0)
return Null;
ImageIml best = GetRaw(best_i);
auto AdjustColor = [&](const Image& m) { // flip light to dark if needed
return best_dark ? AdjustColor0(m, best.flags) : m;
};
if(best.flags & (IML_IMAGE_FLAG_FIXED|IML_IMAGE_FLAG_FIXED_SIZE))
return AdjustColor(best.image);
if(best_scale == DPI_600) {
if(scale == DPI_100)
return AdjustColor(Downscale6x(best.image));
if(scale == DPI_150)
return AdjustColor(Downscale2x(DownSample2x(best.image)));
if(scale == DPI_200)
return AdjustColor(DownSample3x(best.image));
if(scale == DPI_300)
return AdjustColor(DownSample2x(best.image));
}
return DPISmartRescale(best.image, scale * best.image.GetSize() / best_scale);
}
Image MakeImlImage(const String& id, Event<int, ImageIml&, String&> GetRaw)
{
return MakeImlImage(id,
[&](int i, dword& flags, String& id) {
ImageIml m;
GetRaw(i, m, id);
flags = m.flags;
},
[&](int i) -> ImageIml {
ImageIml m;
String id;
GetRaw(i, m, id);
return m;
}
);
}
Image Iml::Get(int i)
{
IImage& m = map[i];
if(!m.loaded) {
Mutex::Lock __(sImlLock);
if(!m.loaded) {
Image h = MakeImlImage(GetId(i), [&](int mode, const String& id) { return GetRaw(mode, id); }, global_flags);
Image h = MakeImlImage(GetId(i),
[&](int i, dword& rflags, String& id) {
id.Clear();
rflags = 0;
if(i < img_count) {
id = map.GetKey(i);
if(flags[i] != IML_IMAGE_FLAGS_UNKNOWN)
rflags = flags[i];
else
rflags = GetRaw(i).flags;
}
},
[&](int i) -> ImageIml {
return GetRaw(i);
}
);
iml_ReplaceAll(m.image, h);
m.loaded = true;
}
@ -98,89 +258,26 @@ Image Iml::Get(int i)
return m.image;
}
ImageIml Iml::GetRaw(int mode, int i)
{
Mutex::Lock __(sImlLock);
if(data[mode].GetCount()) {
int ii = 0;
while(ii < data[mode].GetCount()) {
const Data& d = data[mode][ii];
if(i < d.count) {
static const char *cached_data[4];
static Vector<ImageIml> 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();
int ImlFlagsToDPIScale(int imlflags) {
int scale = DPI_100;
if(imlflags & IML_IMAGE_FLAG_UHD)
scale = DPI_200;
if(imlflags & IML_IMAGE_FLAG_S3)
scale *= 3;
if(imlflags & IML_IMAGE_FLAG_QHD)
scale++;
return scale;
}
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 MakeImlImage(const String& id, Function<ImageIml(int, const String& id)> GetRaw, dword global_flags)
{
int mode = IsUHDMode() * GUI_MODE_UHD + IsDarkTheme() * GUI_MODE_DARK;
const static int mode_candidates[4][4] = {
{ GUI_MODE_NORMAL, GUI_MODE_UHD, -1 },
{ GUI_MODE_DARK, GUI_MODE_DARK_UHD, GUI_MODE_NORMAL, GUI_MODE_UHD },
{ GUI_MODE_UHD, GUI_MODE_NORMAL, -1 },
{ GUI_MODE_DARK_UHD, GUI_MODE_DARK, GUI_MODE_UHD, GUI_MODE_NORMAL }
};
ImageIml im;
Image original;
const int *candidates = mode_candidates[mode];
for(int i = 0; i < 4 && candidates[i] >= 0; i++) {
int cmode = candidates[i];
auto Mode = [&](dword m, const char *s) { return cmode & m ? String(s) : String(); };
im = GetRaw(GUI_MODE_NORMAL, id + Mode(GUI_MODE_UHD, "__UHD") + Mode(GUI_MODE_DARK, "__DARK"));
if(IsNull(im.image))
im = GetRaw(cmode, id); // try alternative iml
if(!IsNull(im.image)) {
original = im.image;
if(im.flags & IML_IMAGE_FLAG_S3)
im.image = DownSample3x(im.image);
break;
}
}
if(IsNull(im.image))
return Null;
if(!(mode & GUI_MODE_UHD) && (im.flags & IML_IMAGE_FLAG_UHD) && !((im.flags | global_flags) & (IML_IMAGE_FLAG_FIXED|IML_IMAGE_FLAG_FIXED_SIZE))) {
if(im.flags & IML_IMAGE_FLAG_S3)
im.image = Downscale6x(original);
else
im.image = Downscale2x(im.image);
}
if((mode & GUI_MODE_UHD) && !(im.flags & IML_IMAGE_FLAG_UHD) && !((im.flags | global_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_DARK) && !((im.flags | global_flags) & (IML_IMAGE_FLAG_FIXED|IML_IMAGE_FLAG_FIXED_COLORS)))
im.image = DarkTheme(im.image);
ScanOpaque(im.image);
return im.image;
int DPIScaleToImlFlags(int dpiscale) {
return dpiscale == DPI_600 ? IML_IMAGE_FLAG_S3|IML_IMAGE_FLAG_UHD
: get_i(dpiscale, 0, 0,
0, // DPI_100
IML_IMAGE_FLAG_QHD, // DPI_150
IML_IMAGE_FLAG_UHD, // DPI_200
IML_IMAGE_FLAG_UHD|IML_IMAGE_FLAG_QHD, // 'DPI_250' - not used
IML_IMAGE_FLAG_S3 // DPI_300
);
}
Iml::Iml(const char **name, int n)
@ -190,20 +287,6 @@ Iml::Iml(const char **name, int n)
Init(n);
}
void Iml::AddData(const byte *s, int len, int count, int mode)
{
Data& d = data[mode].Add();
d.data = (const char *)s;
d.len = len;
d.count = count;
data[mode].Shrink();
}
void Iml::AddId(int mode1, const char *name)
{
ex_name[mode1].Add(name);
}
void Iml::ResetAll()
{
for(int i = 0; i < GetImlCount(); i++)

View file

@ -6,21 +6,17 @@ namespace Upp {
// should eventually lead you to a forum topic where he made the algorithm public:
// http://board.byuu.org/viewtopic.php?f=10&t=2248
namespace Upscale2x_helper {
int d(RGBA c1, RGBA c2)
{
Image Upscale2x_(const Image& src)
{
auto d = [](RGBA c1, RGBA c2) -> int {
int r = abs(c1.r - c2.r);
int g = abs(c1.g - c2.g);
int b = abs(c1.b - c2.b);
return 48 * (r * 299 + g * 587 + b * 114)
+ 7 * (r * -169 + g * -331 + b * 500)
+ 6 * (r * 500 + g * -419 + b * -81);
}
};
};
Image Upscale2x_(const Image& src)
{
using namespace Upscale2x_helper;
Size isz = src.GetSize();
ImageBuffer dst;
dst.Create(2 * isz);
@ -102,18 +98,60 @@ Image Upscale2x(const Image& src)
return Image(h);
}
Image Downscale2x(const Image& src)
Image DPIRescale(const Image& src, Size sz)
{
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);
Size s2 = src.Get2ndSpot();
Size sz0 = src.GetSize();
if(sz0 == sz)
return src;
// When 2nd spot is defined, we are likely rescaling Chameleon item (e.g. button image)
// in that case, filtering by smarter Lanczos could lead to artifacts - stay BILINEAR
Image m;
if(s2.cx > 0 || s2.cy > 0)
m = RescaleFilter(src, sz, FILTER_BILINEAR);
else
if(sz.cx * sz.cy > 128*128)
m = CoRescaleFilter(src, sz, FILTER_LANCZOS3);
else
m = RescaleFilter(src, sz, FILTER_LANCZOS3);
ImageBuffer h(m);
h.SetHotSpot(s2 / 2);
h.Set2ndSpot(src.Get2ndSpot() / 2);
h.SetHotSpot(s2 * sz / sz0);
h.Set2ndSpot(src.Get2ndSpot() * sz / sz0);
return Image(h);
}
Image DPISmartRescale(const Image& src, Size sz)
{
Image m = src;
for(;;) {
Size isz = m.GetSize();
if(isz.cx * isz.cy == 0)
return Null;
if(isz.cx >= sz.cx && isz.cy >= sz.cy)
break;
m = Upscale2x(m);
}
return DPIRescale(m, sz);
}
Image DPISmartRescaleCached(const Image& src, Size sz)
{
return MakeImage(
[&] { StringBuffer s; RawCat(s, src.GetSerialId()); RawCat(s, sz); return (String)s; },
[&] { return DPISmartRescale(src, sz); }
);
}
Image Downscale2x(const Image& src)
{
return DPIRescale(src, src.GetSize() / 2);
}
Image Downscale6x(const Image& src)
{
if(IsNull(src))
@ -126,31 +164,29 @@ Image Downscale6x(const Image& src)
return Image(h);
}
static bool sUHDMode;
int DPIScaleGlobal_ = 2;
double DPIScaleGlobalF_ = 1;
double IDPIScaleGlobalF_ = 1;
void SetUHDMode(bool b)
void SetDPIScale(int scale)
{
Iml::ResetAll();
sUHDMode = b;
DPIScaleGlobal_ = scale;
DPIScaleGlobalF_ = 0.5 * scale;
IDPIScaleGlobalF_ = 1 / DPIScaleGlobalF_;
}
bool IsUHDMode()
void SyncDPIScale()
{
return sUHDMode;
}
void SyncUHDMode()
{
bool uhd = GetStdFontCy() > 24;
if(uhd != IsUHDMode())
SetUHDMode(uhd);
}
Image DPI(const Image& img, int expected)
{
if(img.GetSize().cy <= expected && IsUHDMode())
return AdjustImage(img, Upscale2x);
return img;
int fcy = GetStdFontCy();
int scale = clamp((fcy + 3) / 8, 2, 5);
if(scale == 5)
scale = DPI_300;
int override_scale = Atoi(GetEnv("UPP_SCALE__"));
if(override_scale)
scale = override_scale;
if(scale != GetDPIScale())
SetDPIScale(scale);
}
};

View file

@ -1,10 +1,16 @@
//#BLITZ_APPROVE
#ifdef VERSION
#undef VERSION
#endif
#define IMAGE_META(k, v)
#define IMAGE_VERSION(v)
#define IMAGE_SCAN(s)
#define IMAGE_PACKED(n, d)
#define PREMULTIPLIED
#define VERSION(x)
#define IMAGE_BEGIN_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)
#define IMAGE_END_DATA(n, c)
@ -50,6 +56,7 @@ public:
#undef IMAGE_SCAN
#undef IMAGE_PACKED
#undef IMAGE_META
#undef IMAGE_VERSION
#undef IMAGE_BEGIN_DATA
#undef IMAGE_END_DATA
@ -58,4 +65,8 @@ public:
#ifndef IMAGE_KEEP
#undef IMAGECLASS
#undef IMAGEFILE
#undef PREMULTIPLIED
#undef VERSION
#endif

View file

@ -1,8 +1,14 @@
//#BLITZ_APPROVE
#ifdef VERSION
#undef VERSION
#endif
#define VERSION(v)
#define PREMULTIPLIED
#define IMAGE_META(k, v)
#define PREMULTIPLIED
#define IMAGE_ID(n)
#define IMAGE_BEGIN_DATA
#define IMAGE_END_DATA(n, c)
@ -65,30 +71,6 @@ UPP::Iml& IMAGECLASS::Iml() {
#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
@ -100,10 +82,13 @@ UPP::Iml& IMAGECLASS::Iml() {
#undef PREMULTIPLIED
#define PREMULTIPLIED iml.Premultiplied();
#undef VERSION
#define VERSION(v) iml.Version(v);
#include IMAGEFILE
#undef PREMULTIPLIED
#define PREMULTIPLIED
#undef VERSION
#define VERSION(v)
}
return iml;
}
@ -176,6 +161,9 @@ static COMBINE(IMAGECLASS, __Reg) COMBINE(IMAGECLASS, ___Reg);
#undef IMAGE_META
#undef PREMULTIPLIED
#undef VERSION
#ifdef IMAGEFILE_UHD
#undef IMAGEFILE_UHD
#endif

View file

@ -317,5 +317,16 @@ CKWISE. Flip mode values are compatible with Raster`::GetOrientation
and are equal to EXIF orientation `- 1. This function is intended
to flip Image to correct orientation (usually JPEG from digital
camera).&]
[s2;%% &]
[s3; &]
[s4; &]
[s5;:Upp`:`:DPISmartRescale`(const Image`&`,Size`): Image [* DPISmartRescale]([@(0.0.255) c
onst] Image[@(0.0.255) `&] [*@3 src], Size [*@3 sz])&]
[s2;%% Intended to rescale `"not fitting`" icons to current GUI scaling,
using variety of `"smart`" methods (xBR upscaling, Lancosz 3,
bilienear downscaling) to maintain the acceptable appearance.&]
[s3; &]
[s4; &]
[s5;:Upp`:`:DPISmartRescaleCached`(const Image`&`,Size`): Image [* DPISmartRescaleCache
d]([@(0.0.255) const] Image[@(0.0.255) `&] [*@3 src], Size [*@3 sz])&]
[s2;%% Same as DPISmartRescale, with added caching of results.&]
[s0;%% ]]

File diff suppressed because one or more lines are too long

View file

@ -135,8 +135,10 @@ Size SplashCtrl::MakeLogo(Ctrl& parent, Array<Ctrl>& ctrl, bool splash)
#endif
if(items.GetCount())
h << classes.GetCount() << " classes, " << items.GetCount() << " items\n";
if(IsUHDMode())
h << "UHD ";
int scale = GetDPIScale();
h << decode(scale, DPI_150, "QHD ", DPI_200, "UHD ", DPI_300, "XHD ",
AsString(50 * scale) + "% ");
#ifdef GUI_GTK
if(Ctrl::IsXWayland())

View file

@ -113,12 +113,6 @@ void IconDes::SettingBar(Bar& bar)
{
using namespace IconDesKeys;
Slot *c = IsCurrent() ? &Current() : NULL;
bar.Add("Show UHD/Dark syntetics", IconDesImg::ShowOther(),
[=] { show_synthetics = !show_synthetics; show_downscaled = false; SyncShow(); SetBar(); })
.Check(show_synthetics);
bar.Add("Show downscaled", IconDesImg::ShowSmall(),
[=] { show_downscaled = !show_downscaled; show_synthetics = false; SyncShow(); SetBar(); })
.Check(show_downscaled);
bar.Add("Show secondary grid", IconDesImg::grid2(),
[=] { show_grid2 = !show_grid2; Refresh(); SetBar(); })
.Check(show_grid2);
@ -340,14 +334,14 @@ void IconDes::SerializeSettings(Stream& s)
SetBar();
if(version >= 2)
s % ImgFile();
bool b = false;
if(version >= 3) {
bool b = false;
s % b % show_downscaled;
s % b;
}
if(version >= 4)
s % paste_mode;
if(version >= 5)
s % show_synthetics;
s % b;
if(version >= 6)
s % show_grid2;
if(version >= 7)

View file

@ -56,8 +56,6 @@ void IconDes::SyncShow()
Slot& c = Current();
iconshow.image = c.image;
iconshow.flags = c.flags;
iconshow.show_downscaled = show_downscaled;
iconshow.show_synthetics = show_synthetics;
ilist.Set(2, RawToValue(MakeTuple(c.image, c.flags)));
}
iconshow.Refresh();

View file

@ -193,8 +193,6 @@ private:
bool doselection = false;
bool selectrect = false;
int paste_mode;
bool show_synthetics = true;
bool show_downscaled = false;
bool show_grid2 = true;
bool antialiased = false;
int fill_type = 0;

View file

@ -57,8 +57,6 @@ IMAGE_ID(ResizeUp2__UHD)
IMAGE_ID(ResizeUp__UHD)
IMAGE_ID(ResizeDown2__UHD)
IMAGE_ID(ResizeDown__UHD)
IMAGE_ID(ShowOther)
IMAGE_ID(ShowSmall)
IMAGE_ID(Rescale__UHD)
IMAGE_ID(LargeImage)
IMAGE_ID(LargeImage__UHD)
@ -1759,26 +1757,22 @@ IMAGE_DATA(66,8,33,132,16,66,8,33,100,15,126,0,207,240,237,34,0,0,0,0,0,0,0,0,0,
IMAGE_END_DATA(896, 1)
IMAGE_BEGIN_DATA
IMAGE_DATA(120,156,237,150,237,117,194,48,12,69,51,2,3,116,128,142,197,40,217,156,158,20,104,243,225,196,142,45,231,217,232,222)
IMAGE_DATA(30,255,1,164,72,247,37,208,225,54,220,134,10,60,2,231,249,70,128,96,253,248,60,95,207,247,23,245,195,56,62,134)
IMAGE_DATA(215,95,205,250,169,118,183,254,213,99,183,190,108,127,21,161,185,163,243,207,246,88,120,143,250,219,230,208,68,253,188,54)
IMAGE_DATA(90,191,188,15,202,235,203,252,151,81,233,203,64,69,76,232,227,224,115,191,175,175,131,220,9,53,233,245,88,253,251,198)
IMAGE_DATA(205,169,255,171,61,168,95,124,102,76,219,127,83,19,174,223,247,159,86,191,185,201,207,214,175,31,178,131,189,98,249,195)
IMAGE_DATA(139,239,251,112,23,92,118,10,178,169,95,68,71,188,221,147,193,245,172,221,147,193,117,236,185,39,131,250,196,220,147,65)
IMAGE_DATA(61,82,221,147,129,61,103,221,147,129,29,185,238,201,160,156,82,247,100,144,143,149,123,50,56,143,181,123,50,72,167,150)
IMAGE_DATA(123,50,136,83,219,61,25,236,115,149,123,50,216,114,181,123,50,248,71,229,158,12,244,238,61,103,160,118,78,6,249,224)
IMAGE_DATA(80,11,254,181,224,95,11,254,181,224,95,11,254,181,224,95,11,254,181,224,95,11,254,181,224,95,11,254,181,224,95,11)
IMAGE_DATA(254,181,224,95,11,254,181,224,95,11,254,181,224,95,11,254,181,224,95,11,254,181,224,95,11,254,181,224,95,11,254,181)
IMAGE_DATA(224,95,11,254,181,224,95,11,254,181,224,95,11,254,181,224,95,203,167,250,239,101,135,79,246,223,195,30,159,238,191,245)
IMAGE_DATA(93,60,248,111,121,31,47,254,91,221,201,147,255,218,123,229,244,247,230,191,214,110,185,189,61,250,183,222,175,164,175,87)
IMAGE_DATA(255,86,59,150,246,244,236,191,116,79,139,126,222,253,231,238,106,213,11,255,231,247,181,204,18,255,231,118,182,126,150,240)
IMAGE_DATA(159,190,119,141,239,50,252,167,237,94,210,143,83,150,129,122,22,175,7,247,28,239,135,103,64,235,158,223,0,189,251,51)
IMAGE_DATA(25,88,253,159,214,59,214,238,83,251,90,205,217,59,53,220,167,244,182,154,179,119,106,185,143,245,183,154,179,119,106,186)
IMAGE_DATA(63,186,134,213,156,189,83,219,253,222,117,172,230,236,157,43,220,135,174,101,53,103,239,92,229,126,125,61,171,57,123,231)
IMAGE_DATA(74,247,243,107,230,212,120,243,223,18,61,204,152,67,47,123,245,50,231,89,122,217,201,139,255,22,102,176,62,45,211,202)
IMAGE_DATA(156,30,221,79,180,52,167,55,247,19,173,205,233,201,125,171,224,94,15,238,245,224,94,15,238,245,224,94,15,238,245,224)
IMAGE_DATA(94,15,238,67,252,0,20,177,194,98,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_END_DATA(608, 3)
IMAGE_DATA(120,156,237,214,81,78,195,48,16,0,209,30,135,99,245,254,151,40,170,16,2,149,134,36,246,218,227,205,206,72,249,196)
IMAGE_DATA(241,190,85,91,62,238,183,251,109,126,143,199,215,99,243,251,182,119,7,243,123,181,119,7,243,218,178,119,7,227,219,179)
IMAGE_DATA(119,7,227,58,106,239,14,226,59,107,239,14,226,106,181,119,7,253,245,218,187,131,246,162,236,221,193,249,162,237,221,193)
IMAGE_DATA(241,70,217,187,131,253,70,219,187,131,237,102,217,187,131,191,205,182,119,7,63,81,246,238,128,183,175,188,3,218,220,29)
IMAGE_DATA(180,167,33,155,254,108,250,179,233,207,166,63,155,254,108,250,179,233,207,166,63,155,254,108,250,179,233,207,166,63,155,254)
IMAGE_DATA(108,250,179,233,207,166,63,155,254,108,250,179,233,207,166,63,155,254,108,250,179,233,207,166,63,155,254,108,250,179,233,207)
IMAGE_DATA(166,63,155,254,108,250,179,233,207,166,63,219,85,253,179,204,112,101,255,12,115,92,221,127,245,89,42,248,175,60,79,21)
IMAGE_DATA(255,85,103,170,228,63,122,174,150,243,171,249,143,154,173,245,236,138,254,209,243,245,156,91,213,63,106,198,222,51,43,251)
IMAGE_DATA(247,206,25,113,94,117,255,214,89,163,206,210,255,252,188,145,187,212,255,220,204,209,159,37,253,143,207,61,226,187,76,255)
IMAGE_DATA(99,179,247,156,231,211,183,3,250,46,85,31,237,125,170,63,126,6,88,123,127,3,120,251,51,59,136,250,63,45,123,209)
IMAGE_DATA(246,71,207,141,186,103,246,70,216,31,57,59,234,158,217,27,101,191,119,126,212,61,179,55,210,254,191,119,68,221,51,123)
IMAGE_DATA(163,237,183,222,19,117,207,236,205,176,127,247,174,168,123,102,111,150,253,235,251,162,238,153,189,153,246,191,223,217,242,55)
IMAGE_DATA(213,252,87,42,195,29,91,202,50,87,150,123,158,45,203,76,85,252,87,184,67,244,179,114,171,220,179,162,253,179,149,238)
IMAGE_DATA(89,205,254,217,106,247,172,100,191,106,218,243,105,207,167,61,159,246,124,218,243,105,207,167,61,159,246,239,250,4,229,46)
IMAGE_DATA(163,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_END_DATA(480, 1)
IMAGE_BEGIN_DATA
IMAGE_DATA(120,156,237,157,9,92,86,85,250,199,207,125,87,246,237,69,92,0,5,4,193,93,92,80,113,65,54,21,68,4,100,113)

View file

@ -1,20 +1,20 @@
LAYOUT(ImageLayout, 168, 252)
LAYOUT(ImageLayout, 168, 328)
ITEM(Upp::Label, dv___0, SetLabel(t_("Name")).LeftPosZ(8, 40).TopPosZ(8, 19))
ITEM(Upp::EditString, name, LeftPosZ(52, 108).TopPosZ(8, 19))
ITEM(Upp::Label, dv___2, SetLabel(t_("Size")).LeftPosZ(8, 40).TopPosZ(32, 19))
ITEM(Upp::EditIntSpin, cx, Min(1).Max(8192).LeftPosZ(52, 44).TopPosZ(32, 19))
ITEM(Upp::Label, dv___4, SetLabel(t_("x")).LeftPosZ(100, 12).TopPosZ(32, 16))
ITEM(Upp::EditIntSpin, cy, Min(1).Max(8192).LeftPosZ(116, 44).TopPosZ(32, 19))
ITEM(Upp::Option, fixed, SetLabel(t_("Fixed")).LeftPosZ(8, 156).TopPosZ(56, 16))
ITEM(Upp::Option, fixed_colors, SetLabel(t_("Fixed colors")).LeftPosZ(12, 156).TopPosZ(72, 16))
ITEM(Upp::Option, fixed_size, SetLabel(t_("Fixed size")).LeftPosZ(12, 156).TopPosZ(88, 16))
ITEM(Upp::Option, uhd, SetLabel(t_("UHD variant")).LeftPosZ(8, 156).TopPosZ(112, 16))
ITEM(Upp::Option, dark, SetLabel(t_("Dark variant")).LeftPosZ(8, 156).TopPosZ(128, 16))
ITEM(Upp::Option, s3, SetLabel(t_("Supersampled 3x")).LeftPosZ(8, 156).TopPosZ(152, 16))
ITEM(Upp::Option, exp, SetLabel(t_("Export as icon.ico and .png")).LeftPosZ(8, 160).TopPosZ(176, 16))
ITEM(Upp::Button, ok, SetLabel(t_("OK")).LeftPosZ(28, 64).TopPosZ(220, 24))
ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(96, 64).TopPosZ(220, 24))
ITEM(Upp::Label, estimated_size, SetAlign(Upp::ALIGN_RIGHT).LeftPosZ(8, 156).TopPosZ(196, 19))
ITEM(Upp::Option, fixed, SetLabel(t_("Fixed")).LeftPosZ(8, 156).TopPosZ(60, 16))
ITEM(Upp::Option, fixed_colors, SetLabel(t_("Fixed colors")).LeftPosZ(12, 156).TopPosZ(76, 16))
ITEM(Upp::Option, fixed_size, SetLabel(t_("Fixed size")).LeftPosZ(12, 156).TopPosZ(92, 16))
ITEM(Upp::Option, dark, SetLabel(t_("Dark variant")).LeftPosZ(8, 156).TopPosZ(228, 16))
ITEM(Upp::Option, exp, SetLabel(t_("Export as icon.ico and .png")).LeftPosZ(8, 160).TopPosZ(248, 16))
ITEM(Upp::Button, ok, SetLabel(t_("OK")).LeftPosZ(28, 64).TopPosZ(296, 24))
ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(96, 64).TopPosZ(296, 24))
ITEM(Upp::Label, estimated_size, SetAlign(Upp::ALIGN_RIGHT).LeftPosZ(8, 156).TopPosZ(272, 19))
ITEM(Upp::LabelBox, dv___14, SetLabel(t_("Target resolution")).LeftPosZ(8, 152).TopPosZ(112, 108))
ITEM(Upp::Switch, scale, SetLabel(t_("600% (master)\n100% HD\n150% QHD\n200% UHD\n300% XHD")).LeftPosZ(16, 140).TopPosZ(132, 84))
END_LAYOUT
LAYOUT(ImageSizeLayout, 168, 68)

View file

@ -46,9 +46,8 @@ void AlphaImageInfo::Serialize(Stream& stream)
stream % size % hotspot % encoding;
}
void ScanIML(CParser& parser, Array<ImlImage>& out_images,
VectorMap<String, String>& out_settings)
{
void ScanIML(CParser& parser, Array<ImlImage>& out_images, VectorMap<String, String>& out_settings)
{ // This is for backward compatibility with the very old iml format
String name, bid;
bool exp = false;
while(!parser.IsEof())
@ -189,6 +188,12 @@ bool LoadIml(const String& data, Array<ImlImage>& img, int& format)
format = 0;
try {
bool premultiply = !p.Id("PREMULTIPLIED");
int version = 0;
if(p.Id("VERSION")) {
p.Char('(');
version = p.ReadNumber();
p.Char(')');
}
Vector<String> name;
Vector<bool> exp;
while(p.Id("IMAGE_ID")) {
@ -242,10 +247,19 @@ bool LoadIml(const String& data, Array<ImlImage>& img, int& format)
for(int i = 0; i < count; i++) {
ImlImage& c = img.Add();
(ImageIml &)c = m[i];
if(version == 0)
c.flags &= ~IML_IMAGE_FLAG_QHD;
c.name = name[ii];
c.exp = exp[ii++];
c.name.TrimEnd("__DARK");
c.name.TrimEnd("__UHD");
c.name.TrimEnd("__100");
c.name.TrimEnd("__150");
c.name.TrimEnd("__200");
c.name.TrimEnd("__250");
c.name.TrimEnd("__300");
c.name.TrimEnd("__350");
c.name.TrimEnd("__600");
if(premultiply)
c.image = Premultiply(c.image);
}
@ -272,16 +286,16 @@ bool LoadIml(const String& data, Array<ImlImage>& img, int& format)
String SaveIml(const Array<ImlImage>& iml, int format, const String& eol) {
StringStream out;
out << "PREMULTIPLIED" << eol;
Index<String> names;
out << "VERSION(20260403)" << eol;
Index<String> saved_names;
for(int i = 0; i < iml.GetCount(); i++) {
const ImlImage& c = iml[i];
names.FindAdd(c.name);
out << "IMAGE_ID(" << c.name;
if((c.flags & (IML_IMAGE_FLAG_UHD|IML_IMAGE_FLAG_DARK)) == 0)
int scale = ImlFlagsToDPIScale(c.flags);
if(saved_names.Find(c.name) < 0)
saved_names.FindAdd(c.name);
if(c.flags & IML_IMAGE_FLAG_UHD)
out << "__UHD";
else
out << "__" << AsString(scale * 50);
if(c.flags & IML_IMAGE_FLAG_DARK)
out << "__DARK";
out << ")";
@ -290,16 +304,12 @@ String SaveIml(const Array<ImlImage>& iml, int format, const String& eol) {
out << eol;
}
for(String id : names) // allow UHD versions to be downscaled
if(saved_names.Find(id) < 0)
out << "IMAGE_ID(" << id << ")" << eol;
int ii = 0;
while(ii < iml.GetCount()) {
int bl = 0;
int bn = 0;
Vector<ImageIml> bimg;
while(bl < 4096 && ii < iml.GetCount()) {
while(ii < iml.GetCount() && (bl == 0 || bl + (int)iml[ii].image.GetLength() < 65536)) {
const ImlImage& c = iml[ii++];
ImageIml& m = bimg.Add();
m.image = c.image;

View file

@ -13,12 +13,10 @@ String IconDes::FormatImageName(const Slot& c)
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.flags & IML_IMAGE_FLAG_S3)
r << " S3";
int scale = ImlFlagsToDPIScale(c.flags);
r << decode(scale, DPI_100, " 100%", DPI_150, " 150%", DPI_200, " 200%", DPI_300, " 300%", "");
if(c.exp)
r << " X";
return r;
@ -58,11 +56,6 @@ void IconDes::GoTo(int q)
ilist.FindSetCursor(q);
}
static int sCharFilterCid(int c)
{
return IsAlNum(c) || c == '_' ? c : 0;
}
void IconDes::PlaceDlg(TopWindow& dlg)
{
Rect r = ilist.GetScreenRect();
@ -73,8 +66,9 @@ void IconDes::PlaceDlg(TopWindow& dlg)
void IconDes::PrepareImageDlg(WithImageLayout<TopWindow>& dlg)
{
CtrlLayoutOKCancel(dlg, "New image");
dlg.cx <<= 16;
dlg.cy <<= 16;
dlg.cx <<= 96;
dlg.cy <<= 96;
dlg.scale <<= 0;
if(IsCurrent()) {
Size sz = GetImageSize();
dlg.cx <<= sz.cx;
@ -84,17 +78,31 @@ void IconDes::PrepareImageDlg(WithImageLayout<TopWindow>& dlg)
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.s3 <<= !!(flags & IML_IMAGE_FLAG_S3);
int scale = ImlFlagsToDPIScale(flags);
dlg.scale = decode(scale, DPI_100, 1, DPI_150, 2, DPI_200, 3, DPI_300, 4, 0);
for(Ctrl& q : dlg)
if(dynamic_cast<Option *>(&q))
q << [&] { dlg.Break(-1000); };
}
dlg.name.SetFilter(sCharFilterCid);
dlg.name.SetConvert(
LambdaConvert(
[](const Value& text) {
return text;
},
[](const Value& text) {
if(AsString(text).Find("__") >= 0)
return ErrorValue("Image names must not contain '__'");
return text;
},
[](int c) {
return IsAlNum(c) || c == '_' ? c : 0;
}
)
);
}
void IconDes::SyncDlg(WithImageLayout<TopWindow>& dlg)
@ -113,12 +121,9 @@ dword IconDes::GetFlags(WithImageLayout<TopWindow>& dlg)
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;
if(dlg.s3)
flags |= IML_IMAGE_FLAG_S3;
flags |= DPIScaleToImlFlags(get_i((int)~dlg.scale, DPI_600, DPI_100, DPI_150, DPI_200, DPI_300));
return flags;
}

View file

@ -9,99 +9,52 @@ void IconShow::Paint(Draw& w)
Size sz = GetSize();
static Color color[] = { White(), Black(), WhiteGray(), LtGray(), Gray(),
Yellow(), Brown(), Red(), Green(), Blue(), Cyan(), Magenta() };
Image image = this->image;
if(show_downscaled || show_synthetics)
if(flags & IML_IMAGE_FLAG_S3)
image = DownSample3x(image, true);
int image_scale = ImlFlagsToDPIScale(flags);
auto GetSize = [&](int scale) {
return scale * image.GetSize() / image_scale;
};
auto GetScaled = [&](int scale) {
if(image_scale == DPI_600) {
if(scale == DPI_100)
return Downscale6x(image);
if(scale == DPI_150)
return Downscale2x(DownSample2x(image));
if(scale == DPI_200)
return DownSample3x(image);
if(scale == DPI_300)
return DownSample2x(image);
}
return DPISmartRescale(image, scale * image.GetSize() / image_scale);
};
Size msz = image.GetSize();
Size isz = msz;
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) {
if(flags & IML_IMAGE_FLAG_UHD) {
isz.cx += isz.cx + gap;
isz.cy += (isz.cy + 1) / 2 + gap;
if(IsUHDMode())
isz.cy += msz.cy + gap;
}
else {
isz.cx += 3 * isz.cx + gap;
isz.cy += 2 * isz.cy + gap;
}
}
Size sz300 = GetSize(DPI_300);
if(sz300.cx * sz300.cy > 20000) {
w.DrawRect(sz, SColorPaper);
w.DrawImage(DPI(5), DPI(5), image);
return;
}
int n = isz.cx ? clamp(sz.cx / isz.cx, 1, __countof(color)) : 1;
int ncx = sz.cx / n;
Image m2, m3;
Image dk, s2, s2dk, s22, s2dk2;
if(fits) {
if(msz.cx && show_downscaled) {
m2 = DownSample2x(image);
m3 = DownSample3x(image);
}
if(show_synthetics) {
dk = DarkTheme(image);
if(flags & IML_IMAGE_FLAG_UHD) {
s2 = Downscale2x(image);
s2dk = Downscale2x(DarkTheme(image));
if(IsUHDMode()) {
s22 = Magnify(s2, 2, 2, true);
s2dk2 = Magnify(s2dk, 2, 2, true);
}
}
else {
s2 = Upscale2x(image);
s2dk = Upscale2x(DarkTheme(image));
}
}
}
else
isz = msz;
for(int i = 0; i < n; i++) {
int x = i * ncx;
int cx = (i + 1) * ncx - x;
w.DrawRect(x, 0, cx, sz.cy, color[i]);
if(msz.cx) {
Point pos(x + (cx - isz.cx) / 2, (sz.cy - isz.cy) / 2);
if(fits) {
int x2 = pos.x + isz.cx / 2;
if(show_synthetics) {
w.DrawImage(pos.x, pos.y, image);
w.DrawImage(x2, pos.y, dk);
pos.y += msz.cy + gap;
w.DrawImage(pos.x, pos.y, s2);
w.DrawImage(x2, pos.y, s2dk);
if((flags & IML_IMAGE_FLAG_UHD) && IsUHDMode()) {
pos.y += (msz.cy + 1) / 2 + gap;
w.DrawImage(pos.x, pos.y, s22);
w.DrawImage(x2, pos.y, s2dk2);
}
}
else {
int y = pos.y + (isz.cy - msz.cy) / 2;
w.DrawImage(pos.x, y, image);
if(show_downscaled) {
w.DrawImage(x2, y, m2);
w.DrawImage(x2, y + (msz.cx + 1) / 2 + gap, m3);
}
}
}
else {
w.Clip(x, 0, isz.cx, sz.cy);
w.DrawImage(x + DPI(2), DPI(2), image);
w.End();
}
int n = min(__countof(color), sz.cx / (sz300.cx + DPI(15)));
int cx = sz.cx / n;
int y = DPI(5);
for(int i = 0; i < n; i++)
w.DrawRect(i * cx, 0, cx + n, sz.cy, color[i]);
for(int sc : { DPI_100, DPI_150, DPI_200, DPI_300 }) {
Size isz = GetSize(sc);
Image m1 = GetScaled(sc);
Image m2 = DarkTheme(m1);
for(int i = 0; i < n; i++) {
int x = i * cx;
if(image_scale == sc)
w.DrawRect(x + DPI(1), y, DPI(2), isz.cy, SLtBlue);
w.DrawImage(x + DPI(5), y, m1);
w.DrawImage(x + sz300.cx + DPI(10), y, m2);
}
y += isz.cy + DPI(5);
}
}

View file

@ -101,7 +101,7 @@ void IconDes::Text()
textdlg.NoCenter().SetRect(r);
}
Paste(CreateImage(Size(1, 1), RGBAZero()));
textdlg.nonaa = Current().flags & IML_IMAGE_FLAG_S3;
textdlg.nonaa = ImlFlagsToDPIScale(Current().flags) == DPI_600;
textdlg.WhenClose = THISBACK(CloseText);
textdlg <<= THISBACK(PasteText);
textdlg.Open();

View file

@ -91,9 +91,13 @@ void InsertImageDlg::Load()
id.TrimEnd("__DARK");
id.TrimEnd("__UHD");
if(map.Find(id) < 0) {
Image m = MakeImlImage(id, [&](int mode, const String& id) {
return mode ? ImlImage() : img.Get(id, ImlImage());
}, 0);
Image m = MakeImlImage(id, [&](int ii, ImageIml& m, String& id) {
id.Clear();
if(ii < img.GetCount()) {
id = img.GetKey(ii);
m = img[ii];
}
});
Size isz = m.GetSize();
if(max(isz.cx, isz.cy) > DPI(32))
m = Rescale(m, GetFitSize(isz, DPI(32), DPI(32)));

View file

@ -82,10 +82,10 @@ WebSearchTab::WebSearchTab()
{
list.AddColumn("Name", 5);
list.AddColumn("URI", 5);
if(IsUHDMode())
if(GetDPIScale() >= DPI_200)
list.AddIndex();
list.AddColumn("Icon").SetDisplay(Single<IconDisplay>());
if(!IsUHDMode())
if(GetDPIScale() < DPI_200)
list.AddIndex();
list.Moving().RowName("search engine").Removing();
list.WhenLeftDouble = [=] { Edit(); };
@ -243,9 +243,9 @@ void Ide::OnlineSearchMenu(Bar& menu, const String& what, bool accel)
Image& m = search_icon.At(i);
if(!b) {
b = true;
m = StreamRaster::LoadStringAny(Decode64(search_engines[i][IsUHDMode() ? "Icon32" : "Icon16"]));
m = StreamRaster::LoadStringAny(Decode64(search_engines[i][GetDPIScale() == DPI_100 ? "Icon16" : "Icon32"]));
}
return m;
return DPISmartRescaleCached(m, DPI(16, 16));
};
String name, uri;

View file

@ -748,7 +748,7 @@ struct PackageDisplay : Display {
if(IsNull(icon))
icon = IdeImg::Package();
else
icon = DPI(icon, 16);
icon = DPISmartRescaleCached(icon, DPI(16, 16));
w.DrawRect(r, paper);
w.DrawImage(r.left, r.top + (r.Height() - icon.GetHeight()) / 2, icon);
w.DrawText(r.left + DPI(20), r.top + (r.Height() - Draw::GetStdFontCy()) / 2, txt, fnt, ink);
@ -808,7 +808,7 @@ void SelectPackageDlg::SyncList(const String& find)
icon = pkg.upphub ? IdeImg::HubPackage() : IdeImg::Package();
}
nest_list.Add(pkg.nest);
clist.Add(pkg.package, DPI(icon, 16));
clist.Add(pkg.package, DPISmartRescaleCached(icon, DPI(16, 16)));
alist.Add(pkg.package, GetFileName(pkg.nest), pkg.description, icon);
alist.SetDisplay(alist.GetCount() - 1, 0, pkg.main ? bpd : pd);
}
@ -940,7 +940,7 @@ void SelectPackageDlg::Load(const String& find)
if(d.ispackage) {
String icon_path;
if(IsUHDMode())
if(GetDPIScale() >= DPI_200)
icon_path = AppendFileName(path, "icon32x32.png");
if(IsNull(icon_path) || !FileExists(icon_path))
icon_path = AppendFileName(path, "icon16x16.png");

File diff suppressed because one or more lines are too long

View file

@ -591,7 +591,7 @@ void Ide::MakeIcon() {
int fh = 112;
Size sz(0, 0);
Font font;
while(fh > (IsUHDMode() ? 64 : 80)) {
while(fh > DPI2(64, 80)) {
font = StdFont(fh);
sz = GetTextSize(mp, font) + 8 * Size(4, 2);
if(sz.cx <= isz.cx)
@ -632,11 +632,17 @@ void Ide::SetIcon()
state_icon = new_state_icon;
MakeIcon();
#ifdef PLATFORM_WIN32
auto DoIcon = [&](const Image& shd, const Image& uhd) {
if(GetDPIScale() == DPI_100)
Icon(shd);
else
Icon(DPISmartRescaleCached(uhd, DPI(16, 16)));
};
switch(state_icon) {
case 1: Icon(DPI(IdeImg::IconDebugging(), IdeImg::IconDebuggingLarge())); break;
case 2: Icon(DPI(IdeImg::IconRunning(), IdeImg::IconRunningLarge())); break;
case 3: Icon(DPI(IdeImg::IconBuilding(), IdeImg::IconBuildingLarge())); break;
default: Icon(DPI(IdeImg::Icon(), IdeImg::PackageLarge()));
case 1: DoIcon(IdeImg::IconDebugging(), IdeImg::IconDebuggingLarge()); break;
case 2: DoIcon(IdeImg::IconRunning(), IdeImg::IconRunningLarge()); break;
case 3: DoIcon(IdeImg::IconBuilding(), IdeImg::IconBuildingLarge()); break;
default: DoIcon(IdeImg::Icon(), IdeImg::PackageLarge());
}
#else
switch(state_icon) {

File diff suppressed because it is too large Load diff