+ wxCHECK_MSG( Ok(), 0, "invalid dc" );
+ wxCHECK_MSG( m_font.Ok(), 0, "invalid font" );
+
+ WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display);
+
+ int direction, ascent, descent;
+ XCharStruct overall;
+ XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
+ &descent, &overall);
+ // return XDEV2LOGREL(overall.ascent + overall.descent);
+ return XDEV2LOGREL(ascent + descent);
+}
+
+void wxWindowDC::Clear()
+{
+ wxCHECK_RET( Ok(), "invalid dc" );
+
+ int w, h;
+ if (m_window)
+ {
+ m_window->GetSize(&w, &h);
+
+ if (m_window && m_window->GetBackingPixmap())
+ {
+ w = m_window->GetPixmapWidth();
+ h = m_window->GetPixmapHeight();
+ }
+ }
+ else
+ {
+ if (this->IsKindOf(CLASSINFO(wxMemoryDC)))
+ {
+ wxMemoryDC* memDC = (wxMemoryDC*) this;
+ w = memDC->GetBitmap().GetWidth();
+ h = memDC->GetBitmap().GetHeight();
+ }
+ else
+ return;
+ }
+
+ wxBrush saveBrush = m_brush;
+ SetBrush (m_backgroundBrush);
+
+ XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, 0, 0, w, h);
+
+ if (m_window && m_window->GetBackingPixmap())
+ XFillRectangle ((Display*) m_display, (Pixmap) m_window->GetBackingPixmap(),(GC) m_gcBacking, 0, 0, w, h);
+
+ m_brush = saveBrush;
+}
+
+void wxWindowDC::Clear(const wxRect& rect)
+{
+ wxCHECK_RET( Ok(), "invalid dc" );
+
+ int x = rect.x; int y = rect.y;
+ int w = rect.width; int h = rect.height;
+
+ wxBrush saveBrush = m_brush;
+ SetBrush (m_backgroundBrush);
+
+ XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, x, y, w, h);
+
+ if (m_window && m_window->GetBackingPixmap())
+ XFillRectangle ((Display*) m_display, (Pixmap) m_window->GetBackingPixmap(),(GC) m_gcBacking, x, y, w, h);
+
+ m_brush = saveBrush;
+}
+
+void wxWindowDC::SetFont( const wxFont &font )
+{
+ wxCHECK_RET( Ok(), "invalid dc" );
+
+ m_font = font;
+
+ if (!m_font.Ok())
+ {
+ if ((m_oldFont != (WXFont) 0) && ((wxCoord) m_oldFont != -1))
+ {
+ XSetFont ((Display*) m_display, (GC) m_gc, (Font) m_oldFont);
+
+ if (m_window && m_window->GetBackingPixmap())
+ XSetFont ((Display*) m_display,(GC) m_gcBacking, (Font) m_oldFont);
+ }
+ return;
+ }
+
+ WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display);
+
+ Font fontId = ((XFontStruct*)pFontStruct)->fid;
+ XSetFont ((Display*) m_display, (GC) m_gc, fontId);
+
+ if (m_window && m_window->GetBackingPixmap())
+ XSetFont ((Display*) m_display,(GC) m_gcBacking, fontId);
+}
+
+void wxWindowDC::SetPen( const wxPen &pen )
+{
+ wxCHECK_RET( Ok(), "invalid dc" );
+
+ m_pen = pen;
+ if (!m_pen.Ok())
+ return;
+
+ wxBitmap oldStipple = m_currentStipple;
+ int oldStyle = m_currentStyle;
+ int oldFill = m_currentFill;
+ int old_pen_width = m_currentPenWidth;
+ int old_pen_join = m_currentPenJoin;
+ int old_pen_cap = m_currentPenCap;
+ int old_pen_nb_dash = m_currentPenDashCount;
+ char *old_pen_dash = m_currentPenDash;
+
+ wxColour oldPenColour = m_currentColour;
+ m_currentColour = m_pen.GetColour ();
+ m_currentStyle = m_pen.GetStyle ();
+ m_currentFill = m_pen.GetStyle (); // TODO?
+ m_currentPenWidth = m_pen.GetWidth ();
+ m_currentPenJoin = m_pen.GetJoin ();
+ m_currentPenCap = m_pen.GetCap ();
+ m_currentPenDashCount = m_pen.GetDashCount();
+ m_currentPenDash = m_pen.GetDash();
+
+ if (m_currentStyle == wxSTIPPLE)
+ m_currentStipple = * m_pen.GetStipple ();
+
+ bool sameStyle = (oldStyle == m_currentStyle &&
+ oldFill == m_currentFill &&
+ old_pen_join == m_currentPenJoin &&
+ old_pen_cap == m_currentPenCap &&
+ old_pen_nb_dash == m_currentPenDashCount &&
+ old_pen_dash == m_currentPenDash &&
+ old_pen_width == m_currentPenWidth);
+
+ bool sameColour = (oldPenColour.Ok () &&
+ (oldPenColour.Red () == m_currentColour.Red ()) &&
+ (oldPenColour.Blue () == m_currentColour.Blue ()) &&
+ (oldPenColour.Green () == m_currentColour.Green ()) &&
+ (oldPenColour.GetPixel() == m_currentColour.GetPixel()));
+
+ if (!sameStyle || !GetOptimization())
+ {
+ int scaled_width = (int) XLOG2DEVREL (m_pen.GetWidth ());
+ if (scaled_width < 0)
+ scaled_width = 0;
+
+ int style;
+ int join;
+ int cap;
+ static const char dotted[] = {2, 5};
+ static const char short_dashed[] = {4, 4};
+ static const char long_dashed[] = {4, 8};
+ static const char 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 char *req_dash;
+
+ switch (m_pen.GetStyle ())
+ {
+ case wxUSER_DASH:
+ req_nb_dash = m_currentPenDashCount;
+ req_dash = m_currentPenDash;
+ style = LineOnOffDash;
+ break;
+ case wxDOT:
+ req_nb_dash = 2;
+ req_dash = dotted;
+ style = LineOnOffDash;
+ break;
+ case wxSHORT_DASH:
+ req_nb_dash = 2;
+ req_dash = short_dashed;
+ style = LineOnOffDash;
+ break;
+ case wxLONG_DASH:
+ req_nb_dash = 2;
+ req_dash = long_dashed;
+ style = LineOnOffDash;
+ break;
+ case wxDOT_DASH:
+ req_nb_dash = 4;
+ req_dash = dotted_dashed;
+ style = LineOnOffDash;
+ break;
+ case wxSTIPPLE:
+ case wxSOLID:
+ case wxTRANSPARENT:
+ default:
+ style = LineSolid;
+ req_dash = NULL;
+ req_nb_dash = 0;
+ }
+
+ if (req_dash && req_nb_dash)
+ {
+ char *real_req_dash = new char[req_nb_dash];
+ if (real_req_dash)
+ {
+ int factor = scaled_width == 0 ? 1 : scaled_width;
+ for (int i = 0; i < req_nb_dash; i++)
+ real_req_dash[i] = req_dash[i] * factor;
+ XSetDashes ((Display*) m_display, (GC) m_gc, 0, real_req_dash, req_nb_dash);
+
+ if (m_window && m_window->GetBackingPixmap())
+ XSetDashes ((Display*) m_display,(GC) m_gcBacking, 0, real_req_dash, req_nb_dash);
+ delete[]real_req_dash;
+ }
+ else
+ {
+ // No Memory. We use non-scaled dash pattern...
+ XSetDashes ((Display*) m_display, (GC) m_gc, 0, req_dash, req_nb_dash);
+
+ if (m_window && m_window->GetBackingPixmap())
+ XSetDashes ((Display*) m_display,(GC) m_gcBacking, 0, req_dash, req_nb_dash);
+ }
+ }
+
+ switch (m_pen.GetCap ())
+ {
+ case wxCAP_PROJECTING:
+ cap = CapProjecting;
+ break;
+ case wxCAP_BUTT:
+ cap = CapButt;
+ break;
+ case wxCAP_ROUND:
+ default:
+ cap = (scaled_width <= 1) ? CapNotLast : CapRound;
+ break;
+ }
+
+ switch (m_pen.GetJoin ())
+ {
+ case wxJOIN_BEVEL:
+ join = JoinBevel;
+ break;
+ case wxJOIN_MITER:
+ join = JoinMiter;
+ break;
+ case wxJOIN_ROUND:
+ default:
+ join = JoinRound;
+ break;
+ }
+
+ XSetLineAttributes ((Display*) m_display, (GC) m_gc, scaled_width, style, cap, join);
+
+ if (m_window && m_window->GetBackingPixmap())
+ XSetLineAttributes ((Display*) m_display,(GC) m_gcBacking, scaled_width, style, cap, join);
+ }
+
+ if (IS_HATCH(m_currentFill) && ((m_currentFill != oldFill) || !GetOptimization()))
+ {
+ Pixmap myStipple;
+
+ oldStipple = wxNullBitmap; // For later reset!!
+
+ switch (m_currentFill)
+ {
+ case wxBDIAGONAL_HATCH:
+ if (bdiag == (Pixmap) 0)
+ bdiag = XCreateBitmapFromData ((Display*) m_display,
+ RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)),
+ bdiag_bits, bdiag_width, bdiag_height);
+ myStipple = bdiag;
+ break;
+ case wxFDIAGONAL_HATCH:
+ if (fdiag == (Pixmap) 0)
+ fdiag = XCreateBitmapFromData ((Display*) m_display,
+ RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)),
+ fdiag_bits, fdiag_width, fdiag_height);
+ myStipple = fdiag;
+ break;
+ case wxCROSS_HATCH:
+ if (cross == (Pixmap) 0)
+ cross = XCreateBitmapFromData ((Display*) m_display,
+ RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)),
+ cross_bits, cross_width, cross_height);
+ myStipple = cross;
+ break;
+ case wxHORIZONTAL_HATCH:
+ if (horiz == (Pixmap) 0)
+ horiz = XCreateBitmapFromData ((Display*) m_display,
+ RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)),
+ horiz_bits, horiz_width, horiz_height);
+ myStipple = horiz;
+ break;
+ case wxVERTICAL_HATCH:
+ if (verti == (Pixmap) 0)
+ verti = XCreateBitmapFromData ((Display*) m_display,
+ RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)),
+ verti_bits, verti_width, verti_height);
+ myStipple = verti;
+ break;
+ case wxCROSSDIAG_HATCH:
+ default:
+ if (cdiag == (Pixmap) 0)
+ cdiag = XCreateBitmapFromData ((Display*) m_display,
+ RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)),
+ cdiag_bits, cdiag_width, cdiag_height);
+ myStipple = cdiag;
+ break;
+ }
+ XSetStipple ((Display*) m_display, (GC) m_gc, myStipple);
+
+ if (m_window && m_window->GetBackingPixmap())
+ XSetStipple ((Display*) m_display,(GC) m_gcBacking, myStipple);
+ }
+ else if (m_currentStipple.Ok()
+ && ((m_currentStipple != oldStipple) || !GetOptimization()))
+ {
+ 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());
+ }
+
+ if ((m_currentFill != oldFill) || !GetOptimization())
+ {
+ int fill_style;
+
+ if (m_currentFill == wxSTIPPLE)
+ fill_style = FillStippled;
+ else if (IS_HATCH (m_currentFill))
+ fill_style = FillStippled;
+ else
+ fill_style = FillSolid;
+ XSetFillStyle ((Display*) m_display, (GC) m_gc, fill_style);
+ if (m_window && m_window->GetBackingPixmap())
+ XSetFillStyle ((Display*) m_display,(GC) m_gcBacking, fill_style);
+ }
+
+ // must test m_logicalFunction, because it involves background!
+ if (!sameColour || !GetOptimization()
+ || ((m_logicalFunction == wxXOR) || (m_autoSetting & 0x2)))
+ {
+ 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);
+ }
+
+ // 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);
+ }
+ }
+ }
+ else
+ m_pen.GetColour().SetPixel(oldPenColour.GetPixel());
+
+ m_autoSetting = 0;
+}
+
+void wxWindowDC::SetBrush( const wxBrush &brush )
+{
+ wxCHECK_RET( Ok(), "invalid dc" );
+
+ m_brush = brush;
+
+ if (!m_brush.Ok() || m_brush.GetStyle () == wxTRANSPARENT)
+ return;
+
+ int oldFill = m_currentFill;
+ wxBitmap oldStipple = m_currentStipple;
+
+ m_autoSetting |= 0x1;
+
+ m_currentFill = m_brush.GetStyle ();
+ if (m_currentFill == wxSTIPPLE)
+ m_currentStipple = * m_brush.GetStipple ();
+
+ wxColour oldBrushColour(m_currentColour);
+ m_currentColour = m_brush.GetColour ();