X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0cbff1201aa47e2b73ec90a97886f18e88270ea6..973ac5bbb2ca39f0f3e21b85c1c130d2215f1552:/src/motif/dcclient.cpp diff --git a/src/motif/dcclient.cpp b/src/motif/dcclient.cpp index f442f9ebca..de005e664d 100644 --- a/src/motif/dcclient.cpp +++ b/src/motif/dcclient.cpp @@ -12,11 +12,11 @@ /* About pens, brushes, and the autoSetting flag: - Under X, pens and brushes control some of the same X drawing parameters. - Therefore, it is impossible to independently maintain the current pen and the - current brush. Also, some settings depend on the current logical function. The - m_currentFill, etc. instance variables remember state across the brush and - pen. + Under X, pens and brushes control some of the same X drawing + parameters. Therefore, it is impossible to independently maintain + the current pen and the current brush. Also, some settings depend on + the current logical function. The m_currentFill, etc. instance + variables remember state across the brush and pen. Since pens are used more than brushes, the autoSetting flag is used to indicate that a brush was recently used, and SetPen must be called to @@ -45,6 +45,7 @@ #include "wx/window.h" #include "wx/app.h" #include "wx/image.h" +#include "wx/log.h" #include @@ -134,7 +135,7 @@ wxWindowDC::wxWindowDC() m_currentPenWidth = 1; m_currentPenJoin = -1; m_currentPenDashCount = -1; - m_currentPenDash = (wxMOTIFDash*) NULL; + m_currentPenDash = (wxX11Dash*) NULL; m_currentStyle = -1; m_currentFill = -1; // m_currentBkMode = wxTRANSPARENT; @@ -159,7 +160,7 @@ wxWindowDC::wxWindowDC( wxWindow *window ) m_currentPenWidth = 1; m_currentPenJoin = -1; m_currentPenDashCount = -1; - m_currentPenDash = (wxMOTIFDash*) NULL; + m_currentPenDash = (wxX11Dash*) NULL; m_currentStyle = -1; m_currentFill = -1; // m_currentBkMode = wxTRANSPARENT; @@ -230,12 +231,15 @@ wxWindowDC::~wxWindowDC() m_userRegion = (WXRegion) 0; } -void wxWindowDC::DoFloodFill( wxCoord WXUNUSED(x1), wxCoord WXUNUSED(y1), - const wxColour& WXUNUSED(col), int WXUNUSED(style) ) +extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y, + const wxColour & col, int style); + +bool wxWindowDC::DoFloodFill(wxCoord x, wxCoord y, + const wxColour& col, int style) { - wxFAIL_MSG("not implemented"); + return wxDoFloodFill(this, x, y, col, style); } - + bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const { // Generic (and therefore rather inefficient) method. @@ -245,7 +249,7 @@ bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const memdc.SelectObject(bitmap); memdc.Blit(0, 0, 1, 1, (wxDC*) this, x1, y1); memdc.SelectObject(wxNullBitmap); - wxImage image(bitmap); + wxImage image = bitmap.ConvertToImage(); col->Set(image.GetRed(0, 0), image.GetGreen(0, 0), image.GetBlue(0, 0)); return TRUE; } @@ -882,11 +886,35 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he // FreeGetPixelCache(); - // Be sure that foreground pixels (1) of the Icon will be painted with pen - // colour. [m_pen.SetColour()] Background pixels (0) will be painted with - // last selected background color. [::SetBackground] - if (m_pen.Ok() && m_autoSetting) - SetPen (m_pen); + // Be sure that foreground pixels (1) of the Icon will be painted with + // foreground colour. [m_textForegroundColour] Background pixels (0) + // will be painted with backgound colour (m_textBackgroundColour) + // Using ::SetPen is horribly slow, so avoid doing it + int oldBackgroundPixel = -1; + int oldForegroundPixel = -1; + + if (m_textBackgroundColour.Ok()) + { + oldBackgroundPixel = m_backgroundPixel; + int pixel = m_textBackgroundColour.AllocColour(m_display); + + XSetBackground ((Display*) m_display, (GC) m_gc, pixel); + if (m_window && m_window->GetBackingPixmap()) + XSetBackground ((Display*) m_display,(GC) m_gcBacking, + pixel); + } + if (m_textForegroundColour.Ok()) + { + oldForegroundPixel = m_currentColour.GetPixel(); + + if( m_textForegroundColour.GetPixel() <= -1 ) + CalculatePixel( m_textForegroundColour, + m_textForegroundColour, TRUE); + + int pixel = m_textForegroundColour.GetPixel(); + if (pixel > -1) + SetForegroundPixelWithLogicalFunction(pixel); + } // Do bitmap scaling if necessary @@ -894,6 +922,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he Pixmap sourcePixmap = (Pixmap) NULL; double scaleX, scaleY; GetUserScale(& scaleX, & scaleY); + bool retVal = FALSE; /* TODO: use the mask origin when drawing transparently */ if (xsrcMask == -1 && ysrcMask == -1) @@ -909,7 +938,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he wxASSERT_MSG( (bitmap.Ok()), "Bad source bitmap in wxWindowDC::Blit"); - wxImage image(bitmap); + wxImage image = bitmap.ConvertToImage(); if (!image.Ok()) { sourcePixmap = (Pixmap) bitmap.GetPixmap(); @@ -920,7 +949,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he int scaledH = (int) (bitmap.GetHeight() * scaleY); image = image.Scale(scaledW, scaledH); - scaledBitmap = new wxBitmap(image.ConvertToBitmap()); + scaledBitmap = new wxBitmap(image); sourcePixmap = (Pixmap) scaledBitmap->GetPixmap(); } } @@ -975,7 +1004,9 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he } } else - { + { //XGCValues values; + //XGetGCValues((Display*)m_display, (GC)m_gc, GCForeground, &values); + if (m_window && m_window->GetBackingPixmap()) { // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1 @@ -1042,13 +1073,26 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he SetLogicalFunction(orig); - if (scaledBitmap) delete scaledBitmap; - - return TRUE; + retVal = TRUE; } if (scaledBitmap) delete scaledBitmap; - return FALSE; + if (oldBackgroundPixel > -1) + { + XSetBackground ((Display*) m_display, (GC) m_gc, oldBackgroundPixel); + if (m_window && m_window->GetBackingPixmap()) + XSetBackground ((Display*) m_display,(GC) m_gcBacking, + oldBackgroundPixel); + } + if (oldForegroundPixel > -1) + { + XSetForeground ((Display*) m_display, (GC) m_gc, oldForegroundPixel); + if (m_window && m_window->GetBackingPixmap()) + XSetForeground ((Display*) m_display,(GC) m_gcBacking, + oldForegroundPixel); + } + + return retVal; } void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) @@ -1061,6 +1105,18 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) int ascent = 0; int slen; + // Set FillStyle, otherwise X will use current stipple! + XGCValues gcV, gcBackingV; + + XGetGCValues ((Display*) m_display, (GC)m_gc, GCFillStyle, &gcV); + XSetFillStyle ((Display*) m_display, (GC) m_gc, FillSolid); + if (m_window && m_window->GetBackingPixmap()) + { + XGetGCValues ((Display*) m_display, (GC)m_gcBacking, GCFillStyle, + &gcBackingV ); + XSetFillStyle ((Display*) m_display, (GC) m_gcBacking, FillSolid); + } + slen = strlen(text); if (m_font.Ok()) @@ -1074,7 +1130,9 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) &ascent, &descent, &overall_return); else #endif // 0 - (void)XTextExtents((XFontStruct*) pFontStruct, (char*) (const char*) text, slen, &direction, + (void)XTextExtents((XFontStruct*) pFontStruct, + wxConstCast(text.c_str(), char), + slen, &direction, &ascent, &descent, &overall_return); cx = overall_return.width; @@ -1132,34 +1190,8 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) if (!sameColour || !GetOptimization()) { - int pixel = -1; - if (!m_colour) // Mono display - { - // Unless foreground is really white, draw it in black - unsigned char red = m_textForegroundColour.Red (); - unsigned char blue = m_textForegroundColour.Blue (); - unsigned char green = m_textForegroundColour.Green (); - if (red == (unsigned char) 255 && blue == (unsigned char) 255 - && green == (unsigned char) 255) - { - m_currentColour = *wxWHITE; - pixel = (int) WhitePixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour.SetPixel(pixel); - m_textForegroundColour.SetPixel(pixel); - } - else - { - m_currentColour = *wxBLACK; - pixel = (int) BlackPixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour.SetPixel(pixel); - m_textForegroundColour.SetPixel(pixel); - } - } - else - { - pixel = m_textForegroundColour.AllocColour((Display*) m_display); - m_currentColour.SetPixel(pixel); - } + int pixel = CalculatePixel(m_textForegroundColour, + m_currentColour, FALSE); // Set the GC to the required colour if (pixel > -1) @@ -1192,16 +1224,24 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) else #endif // 0 XDrawString((Display*) m_display, (Pixmap) m_window->GetBackingPixmap(), (GC) m_gcBacking, - XLOG2DEV_2 (x), YLOG2DEV_2 (y) + ascent, (char*) (const char*) text, slen); + XLOG2DEV_2 (x), YLOG2DEV_2 (y) + ascent, + wxConstCast(text.c_str(), char), slen); } + // restore fill style + XSetFillStyle ((Display*) m_display, (GC) m_gc, gcV.fill_style); + if (m_window && m_window->GetBackingPixmap()) + XSetFillStyle ((Display*) m_display, (GC) m_gcBacking, + gcBackingV.fill_style); + wxCoord w, h; GetTextExtent (text, &w, &h); CalcBoundingBox (x + w, y + h); CalcBoundingBox (x, y); } -void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, double angle ) +void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, + double angle ) { if (angle == 0.0) { @@ -1211,27 +1251,51 @@ void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, wxCHECK_RET( Ok(), "invalid dc" ); + int oldBackgroundPixel = -1; + int oldForegroundPixel = -1; + int foregroundPixel = -1; + int backgroundPixel = -1; + + if (m_textBackgroundColour.Ok()) + { + oldBackgroundPixel = m_backgroundPixel; + backgroundPixel = m_textBackgroundColour.AllocColour(m_display); + } + if (m_textForegroundColour.Ok()) + { + oldForegroundPixel = m_currentColour.GetPixel(); + + if( m_textForegroundColour.GetPixel() <= -1 ) + CalculatePixel( m_textForegroundColour, + m_textForegroundColour, TRUE); + + foregroundPixel = m_textForegroundColour.GetPixel(); + } + // Since X draws from the baseline of the text, must add the text height int cx = 0; int cy = 0; int ascent = 0; - int slen; - - slen = strlen(text); + int slen = text.length(); if (m_font.Ok()) { // Calculate text extent. - WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display); + WXFontStructPtr pFontStruct = + m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display); int direction, descent; XCharStruct overall_return; #if 0 if (use16) - (void)XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *)(const char*) text, slen, &direction, + (void)XTextExtents16((XFontStruct*) pFontStruct, + (XChar2b *)(const char*) text, + slen, &direction, &ascent, &descent, &overall_return); else #endif // 0 - (void)XTextExtents((XFontStruct*) pFontStruct, (char*) (const char*) text, slen, &direction, + (void)XTextExtents((XFontStruct*) pFontStruct, + wxConstCast(text.c_str(), char), + slen, &direction, &ascent, &descent, &overall_return); cx = overall_return.width; @@ -1251,92 +1315,86 @@ void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, // Calculate the size of the rotated bounding box. double dx = cos(angle / 180.0 * M_PI); double dy = sin(angle / 180.0 * M_PI); - double x4 = -cy * dy; + double x4 = cy * dy; double y4 = cy * dx; double x3 = cx * dx; - double y3 = cx * dy; + double y3 = -cx * dy; double x2 = x3 + x4; double y2 = y3 + y4; double x1 = x; double y1 = y; // Create image from the source bitmap after writing the text into it. - wxImage image(src); + wxImage image = src.ConvertToImage(); int minx = roundmin(0, roundmin(x4, roundmin(x2, x3))); int miny = roundmin(0, roundmin(y4, roundmin(y2, y3))); int maxx = roundmax(0, roundmax(x4, roundmax(x2, x3))); int maxy = roundmax(0, roundmax(y4, roundmax(y2, y3))); + bool lastFore = false, lastBack = false; + // This rotates counterclockwise around the top left corner. for (int rx = minx; rx < maxx; rx++) { for (int ry = miny; ry < maxy; ry++) { // transform dest coords to source coords - int sx = (int) (rx * dx + ry * dy + 0.5); - int sy = (int) (ry * dx - rx * dy + 0.5); + int sx = (int) (rx * dx - ry * dy + 0.5); + int sy = - (int) (-ry * dx - rx * dy + 0.5); if (sx >= 0 && sx < cx && sy >= 0 && sy < cy) { + bool textPixel = image.GetRed(sx, sy) == 0; + + if (!textPixel && m_backgroundMode != wxSOLID) + continue; + + wxCoord ox = (wxCoord) (x1 + rx), + oy = (wxCoord) (y1 + ry); // draw black pixels, ignore white ones (i.e. transparent b/g) - if (image.GetRed(sx, sy) == 0) + if (textPixel && !lastFore) { - DrawPoint((wxCoord) (x1 + maxx - rx), (wxCoord) (cy + y1 - ry)); + XSetForeground ((Display*) m_display, (GC) m_gc, + foregroundPixel); + lastFore = true; + lastBack = false; } - else + else if (!textPixel && !lastBack) { - // Background - //DrawPoint(x1 + maxx - rx, cy + y1 + maxy - ry); + XSetForeground ((Display*) m_display, (GC) m_gc, + backgroundPixel); + lastFore = false; + lastBack = true; } - } - } - } -#if 0 - // First draw a rectangle representing the text background, if a text - // background is specified - if (m_textBackgroundColour.Ok () && (m_backgroundMode != wxTRANSPARENT)) - { - wxColour oldPenColour = m_currentColour; - m_currentColour = m_textBackgroundColour; - bool sameColour = (oldPenColour.Ok () && m_textBackgroundColour.Ok () && - (oldPenColour.Red () == m_textBackgroundColour.Red ()) && - (oldPenColour.Blue () == m_textBackgroundColour.Blue ()) && - (oldPenColour.Green () == m_textBackgroundColour.Green ())); - - // This separation of the big && test required for gcc2.7/HP UX 9.02 - // or pixel value can be corrupted! - sameColour = (sameColour && - (oldPenColour.GetPixel() == m_textBackgroundColour.GetPixel())); - - if (!sameColour || !GetOptimization()) - { - int pixel = m_textBackgroundColour.AllocColour(m_display); - m_currentColour = m_textBackgroundColour; - - // Set the GC to the required colour - if (pixel > -1) - { - XSetForeground ((Display*) m_display, (GC) m_gc, pixel); + XDrawPoint ((Display*) m_display, (Pixmap) m_pixmap, + (GC) m_gc, XLOG2DEV (ox), YLOG2DEV (oy)); if (m_window && m_window->GetBackingPixmap()) - XSetForeground ((Display*) m_display,(GC) m_gcBacking, pixel); + XDrawPoint ((Display*) m_display, + (Pixmap) m_window->GetBackingPixmap(), + (GC) m_gcBacking, + XLOG2DEV_2 (ox), YLOG2DEV_2 (oy)); } } - else - m_textBackgroundColour = oldPenColour ; + } - XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, XLOG2DEV (x), YLOG2DEV (y), cx, cy); + if (oldBackgroundPixel > -1) + { + XSetBackground ((Display*) m_display, (GC) m_gc, oldBackgroundPixel); if (m_window && m_window->GetBackingPixmap()) - XFillRectangle ((Display*) m_display, (Pixmap) m_window->GetBackingPixmap(),(GC) m_gcBacking, - XLOG2DEV_2 (x), YLOG2DEV_2 (y), cx, cy); + XSetBackground ((Display*) m_display,(GC) m_gcBacking, + oldBackgroundPixel); + } + if (oldForegroundPixel > -1) + { + XSetForeground ((Display*) m_display, (GC) m_gc, oldForegroundPixel); + if (m_window && m_window->GetBackingPixmap()) + XSetForeground ((Display*) m_display,(GC) m_gcBacking, + oldForegroundPixel); } -#endif - long w, h; - // XXX use pixmap size - GetTextExtent (text, &w, &h); - CalcBoundingBox (x + w, y + h); - CalcBoundingBox (x, y); + CalcBoundingBox (minx, miny); + CalcBoundingBox (maxx, maxy); } bool wxWindowDC::CanGetTextExtent() const @@ -1383,7 +1441,8 @@ void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoor &ascent, &descent2, &overall); else #endif // 0 - XTextExtents((XFontStruct*) pFontStruct, (char*) (const char*) string, slen, &direction, + XTextExtents((XFontStruct*) pFontStruct, + wxConstCast(string.c_str(), char), slen, &direction, &ascent, &descent2, &overall); if (width) *width = XDEV2LOGREL (overall.width); @@ -1506,6 +1565,67 @@ void wxWindowDC::SetFont( const wxFont &font ) XSetFont ((Display*) m_display,(GC) m_gcBacking, fontId); } +void wxWindowDC::SetForegroundPixelWithLogicalFunction(int pixel) +{ + if (m_logicalFunction == wxXOR) + { + XGCValues values; + XGetGCValues ((Display*) m_display, (GC) m_gc, GCBackground, &values); + XSetForeground ((Display*) m_display, (GC) m_gc, + pixel ^ values.background); + if (m_window && m_window->GetBackingPixmap()) + XSetForeground ((Display*) m_display,(GC) m_gcBacking, + pixel ^ values.background); + } + else + { + XSetForeground ((Display*) m_display, (GC) m_gc, pixel); + if (m_window && m_window->GetBackingPixmap()) + XSetForeground ((Display*) m_display,(GC) m_gcBacking, pixel); + } +} + +int wxWindowDC::CalculatePixel(wxColour& colour, wxColour& curCol, + bool roundToWhite) const +{ + const unsigned char wp = (unsigned char)255; + + int pixel = -1; + if(!m_colour) // Mono display + { + unsigned char red = colour.Red (); + unsigned char blue = colour.Blue (); + unsigned char green = colour.Green (); + // white + if((red == wp && blue == wp && green == wp) || + // not black and roundToWhite was specified + ((red != 0 || blue != 0 || green != 0) && roundToWhite)) + { + curCol = *wxWHITE; + pixel = (int)WhitePixel((Display*) m_display, + DefaultScreen((Display*) m_display)); + curCol.SetPixel(pixel); + colour.SetPixel(pixel); + } + else + { + curCol = *wxBLACK; + pixel = (int)BlackPixel((Display*) m_display, + DefaultScreen((Display*) m_display)); + curCol.SetPixel(pixel); + colour.SetPixel(pixel); + } + } + else + { + curCol = colour; + pixel = colour.AllocColour((Display*) m_display); + curCol.SetPixel(pixel); + } + + return pixel; +} + void wxWindowDC::SetPen( const wxPen &pen ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -1521,7 +1641,7 @@ void wxWindowDC::SetPen( const wxPen &pen ) int old_pen_join = m_currentPenJoin; int old_pen_cap = m_currentPenCap; int old_pen_nb_dash = m_currentPenDashCount; - wxMOTIFDash *old_pen_dash = m_currentPenDash; + wxX11Dash *old_pen_dash = m_currentPenDash; wxColour oldPenColour = m_currentColour; m_currentColour = m_pen.GetColour (); @@ -1531,7 +1651,7 @@ void wxWindowDC::SetPen( const wxPen &pen ) m_currentPenJoin = m_pen.GetJoin (); m_currentPenCap = m_pen.GetCap (); m_currentPenDashCount = m_pen.GetDashCount(); - m_currentPenDash = (wxMOTIFDash*)m_pen.GetDash(); + m_currentPenDash = (wxX11Dash*)m_pen.GetDash(); if (m_currentStyle == wxSTIPPLE) m_currentStipple = * m_pen.GetStipple (); @@ -1559,15 +1679,15 @@ void wxWindowDC::SetPen( const wxPen &pen ) int style; int join; int cap; - static const wxMOTIFDash dotted[] = {2, 5}; - static const wxMOTIFDash short_dashed[] = {4, 4}; - static const wxMOTIFDash long_dashed[] = {4, 8}; - static const wxMOTIFDash dotted_dashed[] = {6, 6, 2, 6}; + static const wxX11Dash dotted[] = {2, 5}; + static const wxX11Dash short_dashed[] = {4, 4}; + static const wxX11Dash long_dashed[] = {4, 8}; + static const wxX11Dash dotted_dashed[] = {6, 6, 2, 6}; // We express dash pattern in pen width unit, so we are // independent of zoom factor and so on... int req_nb_dash; - const wxMOTIFDash *req_dash; + const wxX11Dash *req_dash; switch (m_pen.GetStyle ()) { @@ -1601,13 +1721,13 @@ void wxWindowDC::SetPen( const wxPen &pen ) case wxTRANSPARENT: default: style = LineSolid; - req_dash = (wxMOTIFDash*)NULL; + req_dash = (wxX11Dash*)NULL; req_nb_dash = 0; } if (req_dash && req_nb_dash) { - wxMOTIFDash *real_req_dash = new wxMOTIFDash[req_nb_dash]; + wxX11Dash *real_req_dash = new wxX11Dash[req_nb_dash]; if (real_req_dash) { int factor = scaled_width == 0 ? 1 : scaled_width; @@ -1751,50 +1871,14 @@ void wxWindowDC::SetPen( const wxPen &pen ) int pixel = -1; if (m_pen.GetStyle () == wxTRANSPARENT) pixel = m_backgroundPixel; - else if (!m_colour) - { - unsigned char red = m_pen.GetColour ().Red (); - unsigned char blue = m_pen.GetColour ().Blue (); - unsigned char green = m_pen.GetColour ().Green (); - if (red == (unsigned char) 255 && blue == (unsigned char) 255 - && green == (unsigned char) 255) - { - pixel = (int) WhitePixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour = *wxWHITE; - m_pen.GetColour().SetPixel(pixel); - m_currentColour.SetPixel(pixel); - } - else - { - pixel = (int) BlackPixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour = *wxBLACK; - m_pen.GetColour().SetPixel(pixel); - } - } else { - pixel = m_pen.GetColour ().AllocColour(m_display); - m_currentColour.SetPixel(pixel); + pixel = CalculatePixel(m_pen.GetColour(), m_currentColour, FALSE); } // Finally, set the GC to the required colour if (pixel > -1) - { - if (m_logicalFunction == wxXOR) - { - XGCValues values; - XGetGCValues ((Display*) m_display, (GC) m_gc, GCBackground, &values); - XSetForeground ((Display*) m_display, (GC) m_gc, pixel ^ values.background); - if (m_window && m_window->GetBackingPixmap()) - XSetForeground ((Display*) m_display,(GC) m_gcBacking, pixel ^ values.background); - } - else - { - XSetForeground ((Display*) m_display, (GC) m_gc, pixel); - if (m_window && m_window->GetBackingPixmap()) - XSetForeground ((Display*) m_display,(GC) m_gcBacking, pixel); - } - } + SetForegroundPixelWithLogicalFunction(pixel); } else m_pen.GetColour().SetPixel(oldPenColour.GetPixel()); @@ -1829,23 +1913,33 @@ void wxWindowDC::SetBrush( const wxBrush &brush ) (oldBrushColour.Green () == m_currentColour.Green ()) && (oldBrushColour.GetPixel() == m_currentColour.GetPixel())); + int stippleDepth = -1; + if ((oldFill != m_brush.GetStyle ()) || !GetOptimization()) { switch (brush.GetStyle ()) { case wxTRANSPARENT: break; + case wxSTIPPLE: + stippleDepth = m_currentStipple.GetDepth(); + // fall through! case wxBDIAGONAL_HATCH: case wxCROSSDIAG_HATCH: case wxFDIAGONAL_HATCH: case wxCROSS_HATCH: case wxHORIZONTAL_HATCH: case wxVERTICAL_HATCH: - case wxSTIPPLE: { - // Chris Breeze 23/07/97: use background mode to determine whether - // fill style should be solid or transparent - int style = (m_backgroundMode == wxSOLID ? FillOpaqueStippled : FillStippled); + if (stippleDepth == -1) stippleDepth = 1; + + // Chris Breeze 23/07/97: use background mode to + // determine whether fill style should be solid or + // transparent + int style = stippleDepth == 1 ? + (m_backgroundMode == wxSOLID ? + FillOpaqueStippled : FillStippled) : + FillTiled; XSetFillStyle ((Display*) m_display, (GC) m_gc, style); if (m_window && m_window->GetBackingPixmap()) XSetFillStyle ((Display*) m_display,(GC) m_gcBacking, style); @@ -1855,7 +1949,8 @@ void wxWindowDC::SetBrush( const wxBrush &brush ) default: XSetFillStyle ((Display*) m_display, (GC) m_gc, FillSolid); if (m_window && m_window->GetBackingPixmap()) - XSetFillStyle ((Display*) m_display,(GC) m_gcBacking, FillSolid); + XSetFillStyle ((Display*) m_display,(GC) m_gcBacking, + FillSolid); } } @@ -1916,74 +2011,34 @@ void wxWindowDC::SetBrush( const wxBrush &brush ) } // X can forget the stipple value when resizing a window (apparently) // so always set the stipple. - else if (m_currentStipple.Ok()) // && m_currentStipple != oldStipple) + else if (m_currentFill != wxSOLID && m_currentFill != wxTRANSPARENT && + m_currentStipple.Ok()) // && m_currentStipple != oldStipple) { - XSetStipple ((Display*) m_display, (GC) m_gc, (Pixmap) m_currentStipple.GetPixmap()); + if (m_currentStipple.GetDepth() == 1) + { + XSetStipple ((Display*) m_display, (GC) m_gc, + (Pixmap) m_currentStipple.GetPixmap()); if (m_window && m_window->GetBackingPixmap()) - XSetStipple ((Display*) m_display,(GC) m_gcBacking, (Pixmap) m_currentStipple.GetPixmap()); + XSetStipple ((Display*) m_display,(GC) m_gcBacking, + (Pixmap) m_currentStipple.GetPixmap()); + } + else + { + XSetTile ((Display*) m_display, (GC) m_gc, + (Pixmap) m_currentStipple.GetPixmap()); + if (m_window && m_window->GetBackingPixmap()) + XSetTile ((Display*) m_display,(GC) m_gcBacking, + (Pixmap) m_currentStipple.GetPixmap()); + } } // must test m_logicalFunction, because it involves background! if (!sameColour || !GetOptimization() || m_logicalFunction == wxXOR) { - int pixel = -1; - if (!m_colour) - { - // Policy - on a monochrome screen, all brushes are white, - // except when they're REALLY black!!! - unsigned char red = m_brush.GetColour ().Red (); - unsigned char blue = m_brush.GetColour ().Blue (); - unsigned char green = m_brush.GetColour ().Green (); - - if (red == (unsigned char) 0 && blue == (unsigned char) 0 - && green == (unsigned char) 0) - { - pixel = (int) BlackPixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour = *wxBLACK; - m_brush.GetColour().SetPixel(pixel); - m_currentColour.SetPixel(pixel); - } - else - { - pixel = (int) WhitePixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour = *wxWHITE; - m_brush.GetColour().SetPixel(pixel); - m_currentColour.SetPixel(pixel); - } - - // N.B. comment out the above line and uncomment the following lines - // if you want non-white colours to be black on a monochrome display. - /* - if (red == (unsigned char )255 && blue == (unsigned char)255 - && green == (unsigned char)255) - pixel = (int)WhitePixel((Display*) m_display, DefaultScreen((Display*) m_display)); - else - pixel = (int)BlackPixel((Display*) m_display, DefaultScreen((Display*) m_display)); - */ - } - else if (m_brush.GetStyle () != wxTRANSPARENT) - { - pixel = m_brush.GetColour().AllocColour(m_display); - m_currentColour.SetPixel(pixel); - } + int pixel = CalculatePixel(m_brush.GetColour(), m_currentColour, TRUE); + if (pixel > -1) - { - // Finally, set the GC to the required colour - if (m_logicalFunction == wxXOR) - { - XGCValues values; - XGetGCValues ((Display*) m_display, (GC) m_gc, GCBackground, &values); - XSetForeground ((Display*) m_display, (GC) m_gc, pixel ^ values.background); - if (m_window && m_window->GetBackingPixmap()) - XSetForeground ((Display*) m_display,(GC) m_gcBacking, pixel ^ values.background); - } - else - { - XSetForeground ((Display*) m_display, (GC) m_gc, pixel); - if (m_window && m_window->GetBackingPixmap()) - XSetForeground ((Display*) m_display,(GC) m_gcBacking, pixel); - } - } + SetForegroundPixelWithLogicalFunction(pixel); } else m_brush.GetColour().SetPixel(oldBrushColour.GetPixel()); @@ -1998,7 +2053,7 @@ void wxWindowDC::SetBackground( const wxBrush &brush ) if (!m_backgroundBrush.Ok()) return; - int pixel = m_backgroundBrush.GetColour().AllocColour(m_display); + m_backgroundPixel = m_backgroundBrush.GetColour().AllocColour(m_display); // New behaviour, 10/2/99: setting the background brush of a DC // doesn't affect the window background colour. @@ -2010,9 +2065,10 @@ void wxWindowDC::SetBackground( const wxBrush &brush ) // Necessary for ::DrawIcon, which use fg/bg pixel or the GC. // And Blit,... (Any fct that use XCopyPlane, in fact.) - XSetBackground ((Display*) m_display, (GC) m_gc, pixel); + XSetBackground ((Display*) m_display, (GC) m_gc, m_backgroundPixel); if (m_window && m_window->GetBackingPixmap()) - XSetBackground ((Display*) m_display,(GC) m_gcBacking, pixel); + XSetBackground ((Display*) m_display,(GC) m_gcBacking, + m_backgroundPixel); } void wxWindowDC::SetLogicalFunction( int function )