// // UspAttrTextOut // // Display a line of text previously analyzed with UspAnalyze. The stored // ATTR[] visual-attribute list is used to stylize the text as it is drawn. // // Coloured text-display using Uniscribe is very complicated. // Three passes are required if high-quality text output is the goal. // // Returns: adjusted x-coordinate // int WINAPI UspTextOut ( USPDATA * uspData, HDC hdc, int xpos, int ypos, int lineHeight, int lineAdjustY, RECT * bounds ) { HRGN hrgn, hrgnClip; if(uspData->stringLen == 0 || uspData->glyphCount == 0) return xpos; hrgnClip = CreateRectRgn(0,0,1,1); GetClipRgn(hdc, hrgnClip); // // 1. draw all background colours, including selection-highlights; // selected areas are added to the HDC clipping region which prevents // step#2 (below) from drawing over them // SetBkMode(hdc, OPAQUE); PaintBackground(uspData, hdc, xpos, ypos, lineHeight, bounds); // // 2. draw the text normally. Selected areas are left untouched // because of the clipping-region created in step#1 // SetBkMode(hdc, TRANSPARENT); PaintForeground(uspData, hdc, xpos, ypos + lineAdjustY, bounds, FALSE); // // 3. redraw the text using a single text-selection-colour (i.e. white) // in the same position, directly over the top of the text drawn in step#2 // // Before we do this, the HDC clipping-region is inverted, // so only selection areas are modified this time // hrgn = CreateRectRgnIndirect(bounds); ExtSelectClipRgn(hdc, hrgn, RGN_XOR); SetBkMode(hdc, TRANSPARENT); xpos = PaintForeground(uspData, hdc, xpos, ypos + lineAdjustY, bounds, TRUE); // remove clipping regions SelectClipRgn(hdc, hrgnClip); DeleteObject(hrgn); DeleteObject(hrgnClip); return xpos; }
void wxStaticBox::OnPaint(wxPaintEvent& WXUNUSED(event)) { RECT rc; ::GetClientRect(GetHwnd(), &rc); // draw the entire box in a memory DC wxMemoryDC memdc; wxBitmap bitmap(rc.right, rc.bottom); memdc.SelectObject(bitmap); PaintBackground(memdc, rc); PaintForeground(memdc, rc); // now only blit the static box border itself, not the interior, to avoid // flicker when background is drawn below // // note that it seems to be faster to do 4 small blits here and then paint // directly into wxPaintDC than painting background in wxMemoryDC and then // blitting everything at once to wxPaintDC, this is why we do it like this wxPaintDC dc(this); int borderTop, border; GetBordersForSizer(&borderTop, &border); // top dc.Blit(border, 0, rc.right - border, borderTop, &memdc, border, 0); // bottom dc.Blit(border, rc.bottom - border, rc.right - border, border, &memdc, border, rc.bottom - border); // left dc.Blit(0, 0, border, rc.bottom, &memdc, 0, 0); // right (note that upper and bottom right corners were already part of the // first two blits so we shouldn't overwrite them here to avoi flicker) dc.Blit(rc.right - border, borderTop, border, rc.bottom - borderTop - border, &memdc, rc.right - border, borderTop); // create the region excluding box children AutoHRGN hrgn((HRGN)MSWGetRegionWithoutChildren()); RECT rcWin; ::GetWindowRect(GetHwnd(), &rcWin); ::OffsetRgn(hrgn, -rcWin.left, -rcWin.top); // and also the box itself MSWGetRegionWithoutSelf((WXHRGN) hrgn, rc.right, rc.bottom); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); HDCClipper clipToBg(GetHdcOf(*impl), hrgn); // paint the inside of the box (excluding box itself and child controls) PaintBackground(dc, rc); }