void Ctrl::PaintCaret(SystemDraw& w) { GuiLock __; LLOG("PaintCaret " << Name() << ", caretCtrl: " << caretCtrl << ", WndCaretVisible: " << WndCaretVisible); if(this == caretCtrl && WndCaretVisible) w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor); }
void Ctrl::GatherTransparentAreas(Vector<Rect>& area, SystemDraw& w, Rect r, const Rect& clip) { GuiLock __; LTIMING("GatherTransparentAreas"); Point off = r.TopLeft(); Point viewpos = off + GetView().TopLeft(); r.Inflate(overpaint); Rect notr = GetVoidRect(); if(notr.IsEmpty()) notr = GetOpaqueRect(); notr += viewpos; if(!IsShown() || r.IsEmpty() || !clip.Intersects(r) || !w.IsPainting(r)) return; if(notr.IsEmpty()) CombineArea(area, r & clip); else { if(notr != r) { CombineArea(area, clip & Rect(r.left, r.top, notr.left, r.bottom)); CombineArea(area, clip & Rect(notr.right, r.top, r.right, r.bottom)); CombineArea(area, clip & Rect(notr.left, r.top, notr.right, notr.top)); CombineArea(area, clip & Rect(notr.left, notr.bottom, notr.right, r.bottom)); } for(Ctrl *q = firstchild; q; q = q->next) { Point qoff = q->InView() ? viewpos : off; Rect qr = q->GetRect() + qoff; if(clip.Intersects(qr)) q->GatherTransparentAreas(area, w, qr, clip); } } }
void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f) { SystemDraw w; w.Init(Ctrl::GetDesktopSize()); w.Clip(f.clip); /* TODO static int dashes[3][3] = { { 32, 32, 0 }, { 1, 1, 1 }, { 5, 1, 2 }, }; */ DrawDragFrame(w, f.rect1, f.n, f.animation); DrawDragFrame(w, f.rect2, f.n, f.animation); w.End(); }
void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels) { GuiLock __; Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, cx, cy, 24); XPicture picture = XRenderCreatePicture( Xdisplay, pixmap, XRenderFindStandardFormat(Xdisplay, PictStandardRGB24), 0, 0 ); XImage ximg; sInitXImage(ximg, Size(cx, cy)); ximg.bitmap_pad = 32; ximg.bytes_per_line = 4 * cx; ximg.bits_per_pixel = 32; ximg.blue_mask = 0x00ff0000; ximg.green_mask = 0x0000ff00; ximg.red_mask = 0x000000ff; ximg.bitmap_unit = 32; ximg.depth = 24; ximg.data = (char *)pixels; XInitImage(&ximg); GC gc = XCreateGC(Xdisplay, pixmap, 0, 0); XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, cx, cy); XFreeGC(Xdisplay, gc); XFreePixmap(Xdisplay, pixmap); XRenderComposite(Xdisplay, PictOpOver, picture, 0, XftDrawPicture(w.GetXftDraw()), 0, 0, 0, 0, x, y, cx, cy); XRenderFreePicture(Xdisplay, picture); }
void Ctrl::UpdateArea(SystemDraw& draw, const Rect& clip) { GuiLock __; if(IsPanicMode()) return; RemoveFullRefresh(); Point sp = GetScreenRect().TopLeft(); Ctrl *b = FindBestOpaque(clip + sp); if(b) { Point p = b->GetScreenRect().TopLeft() - sp; draw.Offset(p); b->UpdateArea0(draw, clip.Offseted(-p), backpaint); draw.End(); } else UpdateArea0(draw, clip, backpaint); }
void ShowRepaintRect(SystemDraw& w, const Rect& r, Color c) { if(sShowRepaint) { w.DrawRect(r, c); SystemDraw::Flush(); Sleep(sShowRepaint); } }
void Ctrl::PaintCaret(SystemDraw& w) { GuiLock __; #ifdef PLATFORM_X11 if(this == caretCtrl && WndCaretVisible) w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor); #endif }
void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size srcsz, Point srcoff) { GuiLock __; XImage ximg; sInitXImage(ximg, srcsz); ximg.bitmap_pad = 32; ximg.bytes_per_line = sizeof(RGBA) * srcsz.cx; ximg.bits_per_pixel = 32; ximg.blue_mask = 0x00ff0000; ximg.green_mask = 0x0000ff00; ximg.red_mask = 0x000000ff; ximg.bitmap_unit = 32; ximg.depth = 24; ximg.data = (char *)pixels; XInitImage(&ximg); Drawable dw = w.GetDrawable(); GC gc = XCreateGC(Xdisplay, dw, 0, 0); Point p = dest.TopLeft() + w.GetOffset(); XPutImage(Xdisplay, dw, gc, &ximg, srcoff.x, srcoff.y, p.x, p.y, dest.GetWidth(), dest.GetHeight()); XFreeGC(Xdisplay, gc); }
bool Ctrl::PaintOpaqueAreas(SystemDraw& w, const Rect& r, const Rect& clip, bool nochild) { GuiLock __; LTIMING("PaintOpaqueAreas"); if(!IsShown() || r.IsEmpty() || !r.Intersects(clip) || !w.IsPainting(r)) return true; Point off = r.TopLeft(); Point viewpos = off + GetView().TopLeft(); if(backpaint == EXCLUDEPAINT) return w.ExcludeClip(r); Rect cview = clip & (GetView() + off); for(Ctrl *q = lastchild; q; q = q->prev) if(!q->PaintOpaqueAreas(w, q->GetRect() + (q->InView() ? viewpos : off), q->InView() ? cview : clip)) return false; if(nochild && (lastchild || GetNext())) return true; Rect opaque = (GetOpaqueRect() + viewpos) & clip; if(opaque.IsEmpty()) return true; #ifdef SYSTEMDRAW if(backpaint == FULLBACKPAINT && !dynamic_cast<BackDraw *>(&w)) #else if(backpaint == FULLBACKPAINT && !w.IsBack()) #endif { ShowRepaintRect(w, opaque, LtRed()); BackDraw bw; bw.Create(w, opaque.GetSize()); bw.Offset(viewpos - opaque.TopLeft()); bw.SetPaintingDraw(w, opaque.TopLeft()); { LEVELCHECK(bw, this); Paint(bw); PaintCaret(bw); } bw.Put(w, opaque.TopLeft()); } else { w.Clip(opaque); ShowRepaintRect(w, opaque, Green()); w.Offset(viewpos); { LEVELCHECK(w, this); Paint(w); PaintCaret(w); } w.End(); w.End(); } LLOG("Exclude " << opaque); return w.ExcludeClip(opaque); }
void Ctrl::UpdateArea0(SystemDraw& draw, const Rect& clip, int backpaint) { GuiLock __; LTIMING("UpdateArea"); LLOG("========== UPDATE AREA " << UPP::Name(this) << " =========="); if(globalbackbuffer) { CtrlPaint(draw, clip); LLOG("========== END (TARGET IS BACKBUFFER)"); return; } if(backpaint == FULLBACKPAINT || globalbackpaint && !hasdhctrl && !dynamic_cast<DHCtrl *>(this)) { ShowRepaintRect(draw, clip, LtRed()); BackDraw bw; bw.Create(draw, clip.GetSize()); bw.Offset(-clip.TopLeft()); bw.SetPaintingDraw(draw, clip.TopLeft()); CtrlPaint(bw, clip); bw.Put(draw, clip.TopLeft()); LLOG("========== END (FULLBACKPAINT)"); return; } if(backpaint == TRANSPARENTBACKPAINT) { LLOG("TransparentBackpaint"); Vector<Rect> area; GatherTransparentAreas(area, draw, GetRect().GetSize(), clip); for(int i = 0; i < area.GetCount(); i++) { Rect ar = area[i]; LLOG("Painting area: " << ar); ShowRepaintRect(draw, ar, LtBlue()); BackDraw bw; bw.Create(draw, ar.GetSize()); bw.Offset(-ar.TopLeft()); bw.SetPaintingDraw(draw, ar.TopLeft()); CtrlPaint(bw, ar); bw.Put(draw, ar.TopLeft()); if(!draw.ExcludeClip(ar)) { LLOG("========== END"); return; } } PaintOpaqueAreas(draw, GetRect().GetSize(), clip); LLOG("========== END"); return; } CtrlPaint(draw, clip); LLOG("========== END"); }
void Ctrl::DoPaint() { LLOG("@ DoPaint"); if(!PaintLock) { bool scroll = false; if(desktop) desktop->SyncScroll(); for(int i = 0; i < topctrl.GetCount(); i++) topctrl[i]->SyncScroll(); if((invalid.GetCount() || scroll) && desktop) { RemoveCursor(); RemoveCaret(); for(int phase = 0; phase < 2; phase++) { LLOG("DoPaint invalid phase " << phase); LDUMPC(invalid); SystemDraw draw; draw.Set(screen); draw.Init(screen_size); for(int i = 0; i < invalid.GetCount(); i++) { draw.Clip(invalid[i]); AddUpdate(invalid[i]); } for(int i = topctrl.GetCount() - 1; i >= 0; i--) { Rect r = topctrl[i]->GetRect(); Rect ri = GetClipBound(invalid, r); if(!IsNull(ri)) { draw.Clipoff(r); topctrl[i]->UpdateArea(draw, ri - r.TopLeft()); draw.End(); Subtract(invalid, r); draw.ExcludeClip(r); } } Rect ri = GetClipBound(invalid, framebuffer.GetSize()); if(!IsNull(ri)) desktop->UpdateArea(draw, ri); } } } DoUpdate(); }
void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) { GuiLock __; LEVELCHECK(w, this); LTIMING("CtrlPaint"); Rect rect = GetRect().GetSize(); Rect orect = rect.Inflated(overpaint); if(!IsShown() || orect.IsEmpty() || clip.IsEmpty() || !clip.Intersects(orect)) return; Ctrl *q; Rect view = rect; for(int i = 0; i < frame.GetCount(); i++) { LEVELCHECK(w, NULL); frame[i].frame->FramePaint(w, view); view = frame[i].view; } Rect oview = view.Inflated(overpaint); bool hasviewctrls = false; bool viewexcluded = false; for(q = firstchild; q; q = q->next) if(q->IsShown()) if(q->InFrame()) { if(!viewexcluded && IsTransparent() && q->GetRect().Intersects(view)) { w.Begin(); w.ExcludeClip(view); viewexcluded = true; } LEVELCHECK(w, q); Point off = q->GetRect().TopLeft(); w.Offset(off); q->CtrlPaint(w, clip - off); w.End(); } else hasviewctrls = true; if(viewexcluded) w.End(); DOLEVELCHECK; if(!oview.IsEmpty()) { if(oview.Intersects(clip) && w.IsPainting(oview)) { LEVELCHECK(w, this); if(overpaint) { w.Clip(oview); w.Offset(view.left, view.top); Paint(w); PaintCaret(w); w.End(); w.End(); } else { w.Clipoff(view); Paint(w); PaintCaret(w); w.End(); } } } if(hasviewctrls && !view.IsEmpty()) { Rect cl = clip & view; w.Clip(cl); for(q = firstchild; q; q = q->next) if(q->IsShown() && q->InView()) { LEVELCHECK(w, q); Rect qr = q->GetRect(); Point off = qr.TopLeft() + view.TopLeft(); Rect ocl = cl - off; if(ocl.Intersects(Rect(qr.GetSize()).Inflated(overpaint))) { w.Offset(off); q->CtrlPaint(w, cl - off); w.End(); } } w.End(); } }
void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) { GuiLock __; LEVELCHECK(w, this); LTIMING("CtrlPaint"); Rect rect = GetRect().GetSize(); Rect orect = rect.Inflated(overpaint); if(!IsShown() || orect.IsEmpty() || clip.IsEmpty() || !clip.Intersects(orect)) return; w.PushContext(); //glPushMatrix(); ApplyTransform(TS_BEFORE_CTRL_PAINT); Ctrl *q; Rect view = rect; for(int i = 0; i < frame.GetCount(); i++) { LEVELCHECK(w, NULL); frame[i].frame->FramePaint(w, view); view = frame[i].view; } Rect oview = view.Inflated(overpaint); bool hasviewctrls = false; bool viewexcluded = false; for(q = firstchild; q; q = q->next) if(q->IsShown()) if(q->InFrame()) { if(!viewexcluded && IsTransparent() && q->GetRect().Intersects(view)) { w.Begin(); w.ExcludeClip(view); viewexcluded = true; } LEVELCHECK(w, q); Point off = q->GetRect().TopLeft(); w.Offset(off); q->CtrlPaint(w, clip - off); w.End(); } else hasviewctrls = true; if(viewexcluded) w.End(); //DOLEVELCHECK; if(!oview.IsEmpty() && oview.Intersects(clip)) { LEVELCHECK(w, this); if(cliptobounds) w.Clip(overpaint ? oview : view); w.Offset(view.left, view.top); Paint(w); PaintCaret(w); w.End(); if(hasviewctrls && !view.IsEmpty()) { Rect cl = clip & view; for(q = firstchild; q; q = q->next) if(q->IsShown() && q->InView()) { Rect rr(q->popup ? clip : cl); LEVELCHECK(w, q); Rect qr = q->GetRect(); Point off = qr.TopLeft() + view.TopLeft(); Rect ocl = cl - off; if(ocl.Intersects(Rect(qr.GetSize()).Inflated(overpaint))) { w.Offset(off); q->CtrlPaint(w, rr - off); w.End(); } } } if(cliptobounds) w.End(); } ApplyTransform(TS_AFTER_CTRL_PAINT); //glPopMatrix(); w.PopContext(); }
void ImageSysData::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c) { GuiLock __; x += w.GetOffset().x; y += w.GetOffset().y; Size sz = img.GetSize(); int len = sz.cx * sz.cy; Rect sr = src & sz; Size ssz = sr.Size(); if(sr.IsEmpty()) return; int kind = img.GetKind(); if(kind == IMAGE_EMPTY) return; if(kind == IMAGE_OPAQUE && !IsNull(c)) { w.DrawRect(x, y, sz.cx, sz.cy, c); return; } if(kind == IMAGE_OPAQUE && paintcount == 0 && sr == Rect(sz)) { SetSurface(w, x, y, sz.cx, sz.cy, ~img); paintcount++; return; } if(IsNull(c)) { if(!picture) { bool opaque = kind == IMAGE_OPAQUE; Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, opaque ? 24 : 32); picture = XRenderCreatePicture( Xdisplay, pixmap, XRenderFindStandardFormat(Xdisplay, opaque ? PictStandardRGB24 : PictStandardARGB32), 0, 0 ); XImage ximg; sInitXImage(ximg, sz); ximg.bitmap_pad = 32; ximg.bytes_per_line = 4 * sz.cx; ximg.bits_per_pixel = 32; ximg.blue_mask = 0x00ff0000; ximg.green_mask = 0x0000ff00; ximg.red_mask = 0x000000ff; ximg.bitmap_unit = 32; ximg.data = (char *)~img; ximg.depth = opaque ? 24 : 32; XInitImage(&ximg); GC gc = XCreateGC(Xdisplay, pixmap, 0, 0); XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, sz.cx, sz.cy); XFreeGC(Xdisplay, gc); XFreePixmap(Xdisplay, pixmap); SysImageRealized(img); } XRenderComposite(Xdisplay, PictOpOver, picture, 0, XftDrawPicture(w.GetXftDraw()), sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy); } else { if(!picture8) { Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, 8); picture8 = XRenderCreatePicture(Xdisplay, pixmap, XRenderFindStandardFormat(Xdisplay, PictStandardA8), 0, 0); Buffer<byte> ab(len); byte *t = ab; const RGBA *s = ~img; const RGBA *e = s + len; while(s < e) *t++ = (s++)->a; XImage ximg; sInitXImage(ximg, sz); ximg.data = (char *)~ab; ximg.bitmap_unit = 8; ximg.bitmap_pad = 8; ximg.depth = 8; ximg.bytes_per_line = sz.cx; ximg.bits_per_pixel = 8; XInitImage(&ximg); GC gc = XCreateGC(Xdisplay, pixmap, 0, 0); XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, sz.cx, sz.cy); XFreeGC(Xdisplay, gc); XFreePixmap(Xdisplay, pixmap); } XRenderComposite(Xdisplay, PictOpOver, sGetSolidFill(c), picture8, XftDrawPicture(w.GetXftDraw()), sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy); } }