#include "SystemDraw.h" NAMESPACE_UPP #ifdef PLATFORM_WIN32 SystemDraw& ScreenInfo(); bool ScreenInPaletteMode() { return ScreenInfo().PaletteMode(); } Size GetScreenSize() { return ScreenInfo().GetPageSize(); } 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(); } #endif #ifdef PLATFORM_X11 Vector RectRgn(const Rect& r) { Vector q; q.Add(r); return q; } Vector Intersect(const Vector& r1, const Vector& r2) { Vector q; for(int i = 0; i < r1.GetCount(); i++) for(int j = 0; j < r2.GetCount(); j++) { Rect r = r1[i] & r2[j]; if(!r.IsEmpty()) q.Add(r); } return q; } Vector Subtract(const Vector& r1, const Vector& r2) { Vector q; bool dummy; q <<= r1; for(int i = 0; i < r2.GetCount(); i++) q = Subtract(q, r2[i], dummy); return q; } Vector Xor(const Vector& r1, const Vector& r2) { Vector is = Intersect(r1, r2); Vector q = Subtract(r1, is); q.Append(Subtract(r2, is)); return q; } Vector GetFrameRgn(const Rect& rect, int n) { Vector 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); } #endif static Image sRenderGlyph(int cx, int x, Font font, int chr, int py, int pcy) { ImageDraw iw(cx, pcy); iw.DrawRect(0, 0, cx, pcy, White); iw.DrawText(x, -py, WString(chr, 1), font, Black); return iw; } void SetRenderGlyph(Image (*f)(int cx, int x, Font font, int chr, int py, int pcy)); INITBLOCK { SetRenderGlyph(sRenderGlyph); } END_UPP_NAMESPACE