mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
CtrlCore: gtk3 DrawImage optimization, DragRect cleanup
git-svn-id: svn://ultimatepp.org/upp/trunk@14345 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
50c7118301
commit
85702ae3b9
8 changed files with 25 additions and 161 deletions
|
|
@ -3,10 +3,6 @@ private:
|
|||
friend struct MMCtrl;
|
||||
friend struct MMImp;
|
||||
|
||||
friend void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation);
|
||||
friend void FinishDragRect(Ctrl& q);
|
||||
|
||||
static int WndCaretTime;
|
||||
static bool WndCaretVisible;
|
||||
static bool local_dnd_copy;
|
||||
|
|
|
|||
|
|
@ -1481,10 +1481,6 @@ enum {
|
|||
DRAWDRAGRECT_SOLID, DRAWDRAGRECT_NORMAL, DRAWDRAGRECT_DASHED
|
||||
};
|
||||
|
||||
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation);
|
||||
void FinishDragRect(Ctrl& q);
|
||||
|
||||
bool PointLoop(Ctrl& ctrl, const Vector<Image>& ani, int ani_ms);
|
||||
bool PointLoop(Ctrl& ctrl, const Image& img);
|
||||
|
||||
|
|
|
|||
|
|
@ -160,9 +160,6 @@ _DBG_
|
|||
static bool ProcessInvalids();
|
||||
|
||||
friend void InitGtkApp(int argc, char **argv, const char **envptr);
|
||||
friend void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation);
|
||||
friend void FinishDragRect(Ctrl& q);
|
||||
friend void GuiPlatformGripResize(TopWindow *q);
|
||||
|
||||
public: // really private:
|
||||
|
|
|
|||
|
|
@ -32,17 +32,18 @@ void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size srcsz,
|
|||
|
||||
struct ImageSysData {
|
||||
Image img;
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t *surface = NULL;
|
||||
|
||||
void Init(const Image& img);
|
||||
void Init(const Image& m, cairo_surface_t *other);
|
||||
~ImageSysData();
|
||||
};
|
||||
|
||||
cairo_surface_t *CreateCairoSurface(const Image& img)
|
||||
cairo_surface_t *CreateCairoSurface(const Image& img, cairo_surface_t *other)
|
||||
{
|
||||
Size isz = img.GetSize();
|
||||
cairo_format_t fmt = CAIRO_FORMAT_ARGB32;
|
||||
cairo_surface_t *surface = cairo_image_surface_create(fmt, isz.cx, isz.cy);
|
||||
cairo_surface_t *surface = other ? cairo_surface_create_similar_image(other, fmt, isz.cx, isz.cy)
|
||||
: cairo_image_surface_create(fmt, isz.cx, isz.cy);
|
||||
cairo_surface_flush(surface);
|
||||
byte *a = (byte *)cairo_image_surface_get_data(surface);
|
||||
int stride = cairo_format_stride_for_width(fmt, isz.cx);
|
||||
|
|
@ -54,10 +55,15 @@ cairo_surface_t *CreateCairoSurface(const Image& img)
|
|||
return surface;
|
||||
}
|
||||
|
||||
void ImageSysData::Init(const Image& m)
|
||||
cairo_surface_t *CreateCairoSurface(const Image& img)
|
||||
{
|
||||
return CreateCairoSurface(img, NULL);
|
||||
}
|
||||
|
||||
void ImageSysData::Init(const Image& m, cairo_surface_t *other)
|
||||
{
|
||||
img = m;
|
||||
surface = CreateCairoSurface(img);
|
||||
surface = CreateCairoSurface(m, other);
|
||||
SysImageRealized(img);
|
||||
}
|
||||
|
||||
|
|
@ -69,9 +75,10 @@ ImageSysData::~ImageSysData()
|
|||
|
||||
struct ImageSysDataMaker : LRUCache<ImageSysData, int64>::Maker {
|
||||
Image img;
|
||||
cairo_surface_t *other;
|
||||
|
||||
virtual int64 Key() const { return img.GetSerialId(); }
|
||||
virtual int Make(ImageSysData& object) const { object.Init(img); return img.GetLength(); }
|
||||
virtual int Make(ImageSysData& object) const { object.Init(img, other); return img.GetLength(); }
|
||||
};
|
||||
|
||||
void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, Color color)
|
||||
|
|
@ -93,13 +100,13 @@ void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, Color color)
|
|||
}
|
||||
LLOG("SysImage cache pixels " << cache.GetSize() << ", count " << cache.GetCount());
|
||||
m.img = img;
|
||||
m.other = cairo_get_target(cr);
|
||||
ImageSysData& sd = cache.Get(m);
|
||||
if(!IsNull(color)) {
|
||||
SetColor(color);
|
||||
cairo_mask_surface(cr, sd.surface, x, y);
|
||||
}
|
||||
else {
|
||||
RTIMESTOP("cairo_paint");
|
||||
cairo_set_source_surface(cr, sd.surface, x, y);
|
||||
cairo_paint(cr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ RectTracker::RectTracker(Ctrl& master)
|
|||
maxrect = Rect(-100000, -100000, 100000, 100000);
|
||||
keepratio = false;
|
||||
cursorimage = Image::Arrow();
|
||||
color = InvertColor;
|
||||
color = Black();
|
||||
pattern = DRAWDRAGRECT_NORMAL;
|
||||
animation = 0;
|
||||
rounder = NULL;
|
||||
|
|
|
|||
|
|
@ -11,84 +11,6 @@ bool ScreenInPaletteMode()
|
|||
return ScreenInfo().PaletteMode();
|
||||
}
|
||||
|
||||
HRGN GetFrameRgn(const Rect& rect, int n) {
|
||||
HRGN rgn = CreateRectRgnIndirect(rect);
|
||||
Rect r = rect;
|
||||
r.Deflate(n);
|
||||
if(r.Width() > 0 && r.Height() > 0) {
|
||||
HRGN rgnin = CreateRectRgnIndirect(r);
|
||||
CombineRgn(rgn, rgn, rgnin, RGN_XOR);
|
||||
DeleteObject(rgnin);
|
||||
}
|
||||
return rgn;
|
||||
}
|
||||
|
||||
void DrawDragRect(SystemDraw& w, const Rect& _rect1, const Rect& _rect2, const Rect& _clip, int n, Color color, uint64 pattern)
|
||||
{
|
||||
Point o = w.GetOffset();
|
||||
Rect rect1 = _rect1 + o;
|
||||
Rect rect2 = _rect2 + o;
|
||||
Rect clip = _clip + o;
|
||||
HDC hdc = w.BeginGdi();
|
||||
word wpat[8] = {
|
||||
(byte)(pattern >> 56), (byte)(pattern >> 48), (byte)(pattern >> 40), (byte)(pattern >> 32),
|
||||
(byte)(pattern >> 24), (byte)(pattern >> 16), (byte)(pattern >> 8), (byte)(pattern >> 0),
|
||||
};
|
||||
HBITMAP bitmap = CreateBitmap(8, 8, 1, 1, wpat);
|
||||
HBRUSH brush = ::CreatePatternBrush(bitmap);
|
||||
DeleteObject(bitmap);
|
||||
SetTextColor(hdc, color);
|
||||
SetBkColor(hdc, SColorText());
|
||||
Point offset;
|
||||
#ifdef PLATFORM_WINCE
|
||||
offset = Point(0, 0);
|
||||
#else
|
||||
::GetViewportOrgEx(hdc, offset);
|
||||
#endif
|
||||
HRGN rgn = GetFrameRgn(rect1 + offset, n);
|
||||
HRGN rgn2 = GetFrameRgn(rect2 + offset, n);
|
||||
HRGN cliprgn = CreateRectRgnIndirect(clip + offset);
|
||||
CombineRgn(rgn, rgn, rgn2, RGN_XOR);
|
||||
CombineRgn(rgn, rgn, cliprgn, RGN_AND);
|
||||
SelectClipRgn(hdc, rgn);
|
||||
Rect r;
|
||||
GetClipBox(hdc, r);
|
||||
HBRUSH obrush = (HBRUSH) SelectObject(hdc, brush);
|
||||
PatBlt(hdc, r.left, r.top, r.Width(), r.Height(), PATINVERT);
|
||||
SelectObject(hdc, obrush);
|
||||
SelectClipRgn(hdc, NULL);
|
||||
DeleteObject(rgn);
|
||||
DeleteObject(rgn2);
|
||||
DeleteObject(cliprgn);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteObject(brush);
|
||||
w.EndGdi();
|
||||
}
|
||||
|
||||
void FinishDragRect(Ctrl& q)
|
||||
{
|
||||
}
|
||||
|
||||
static uint64 sGetAniPat(uint64 src, int pos)
|
||||
{
|
||||
uint64 out = 0;
|
||||
pos &= 7;
|
||||
for(int i = 8; --i >= 0;) {
|
||||
byte sr = (byte)(src >> (8 * ((7 - i - pos) & 7)));
|
||||
out = (out << 8) | (byte)((sr | (sr << 8)) >> pos);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation)
|
||||
{
|
||||
ViewDraw w(&q);
|
||||
uint64 pattern = type == DRAWDRAGRECT_DASHED ? I64(0xf0783c1e0f87c3e1) :
|
||||
type == DRAWDRAGRECT_NORMAL ? I64(0x55aa55aa55aa55aa) : 0;
|
||||
DrawDragRect(w, rect1, rect2, clip, n, color, sGetAniPat(pattern, animation));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,63 +41,4 @@ Vector<Rect> Xor(const Vector<Rect>& r1, const Vector<Rect>& r2)
|
|||
return q;
|
||||
}
|
||||
|
||||
Vector<Rect> GetFrameRgn(const Rect& rect, int n) {
|
||||
Vector<Rect> q = RectRgn(rect);
|
||||
q.Add(rect);
|
||||
Rect r = rect;
|
||||
r.Deflate(n);
|
||||
if(r.Width() > 0 && r.Height() > 0)
|
||||
q = Xor(q, RectRgn(r));
|
||||
return q;
|
||||
}
|
||||
|
||||
void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, uint64 pattern)
|
||||
{
|
||||
char bd[8];
|
||||
for(int i = 0; i < 8; i++)
|
||||
bd[i] = ~(byte)(pattern >> (8 * (7 - i)));
|
||||
Pixmap stipple = XCreateBitmapFromData(Xdisplay, w.GetDrawable(), bd, 8, 8);
|
||||
Point offset = w.GetOffset();
|
||||
GC gc = XCreateGC(Xdisplay, w.GetDrawable(), 0, 0);
|
||||
SetClip(gc, w.GetXftDraw(),
|
||||
Intersect(Xor(GetFrameRgn(rect1 + offset, n), GetFrameRgn(rect2 + offset, n)),
|
||||
RectRgn(clip + offset)));
|
||||
|
||||
XGCValues gcv;
|
||||
gcv.function = X11_ROP2_XOR;
|
||||
gcv.foreground = GetXPixel(color);
|
||||
gcv.fill_style = FillStippled;
|
||||
gcv.stipple = stipple;
|
||||
XChangeGC(Xdisplay, gc, GCForeground|GCFunction|GCStipple|GCFillStyle, &gcv);
|
||||
XFillRectangle(Xdisplay, w.GetDrawable(), gc, 0, 0, Xwidth, Xheight);
|
||||
XFreePixmap(Xdisplay, stipple);
|
||||
}
|
||||
|
||||
static uint64 sGetAniPat(uint64 src, int pos)
|
||||
{
|
||||
uint64 out = 0;
|
||||
pos &= 7;
|
||||
for(int i = 8; --i >= 0;) {
|
||||
byte sr = (byte)(src >> (8 * ((7 - i - pos) & 7)));
|
||||
out = (out << 8) | (byte)((sr | (sr << 8)) >> pos);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation)
|
||||
{
|
||||
ViewDraw w(&q);
|
||||
uint64 pattern = type == DRAWDRAGRECT_DASHED ? I64(0xf0783c1e0f87c3e1) :
|
||||
type == DRAWDRAGRECT_NORMAL ? I64(0x55aa55aa55aa55aa) : 0;
|
||||
DrawDragRect(w, rect1, rect2, clip, n, color, sGetAniPat(pattern, animation));
|
||||
}
|
||||
|
||||
void FinishDragRect(Ctrl& q)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -340,21 +340,26 @@ void DrawDragLine(Draw& w, bool horz, int x, int y, int len, int n, const int *p
|
|||
else
|
||||
w.Clip(x, y, n, len);
|
||||
|
||||
Color color2 = IsDark(color) ? White() : Black();
|
||||
(horz ? x : y) -= animation;
|
||||
len += animation;
|
||||
bool ch = false;
|
||||
while(len > 0) {
|
||||
int segment = pattern[ch];
|
||||
int d = segment + pattern[2];
|
||||
int pause = pattern[2];
|
||||
if(horz) {
|
||||
w.DrawRect(x, y, segment, n, color);
|
||||
x += d;
|
||||
x += segment;
|
||||
w.DrawRect(x, y, pause, n, color2);
|
||||
x += pause;
|
||||
}
|
||||
else {
|
||||
w.DrawRect(x, y, n, segment, color);
|
||||
y += d;
|
||||
y += segment;
|
||||
w.DrawRect(x, y, n, pause, color2);
|
||||
y += pause;
|
||||
}
|
||||
len -= d;
|
||||
len -= pause + segment;
|
||||
ch = !ch;
|
||||
}
|
||||
w.End();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue