X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/60f5b8804baa6d005afd8a595850037a614f0d3c..b3402d0df8c9f763da1e32fc28c824014e5516c6:/src/motif/dcclient.cpp?ds=sidebyside diff --git a/src/motif/dcclient.cpp b/src/motif/dcclient.cpp index bda0770424..aa4970ddef 100644 --- a/src/motif/dcclient.cpp +++ b/src/motif/dcclient.cpp @@ -48,10 +48,20 @@ #include +#ifdef __VMS__ +#pragma message disable nosimpint +#endif #include +#ifdef __VMS__ +#pragma message enable nosimpint +#endif #include "wx/motif/private.h" +#ifdef __EMX__ + #include // for M_PI +#endif // __EMX__ + #include "bdiag.xbm" #include "fdiag.xbm" #include "cdiag.xbm" @@ -65,8 +75,6 @@ static Pixmap bdiag, cdiag, fdiag, cross, horiz, verti; // constants // ---------------------------------------------------------------------------- -#define RAD2DEG 57.2957795131 - // Fudge factor (VZ: what??) #define WX_GC_CF 1 @@ -74,11 +82,9 @@ static Pixmap bdiag, cdiag, fdiag, cross, horiz, verti; // macros // ---------------------------------------------------------------------------- -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC) IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) -#endif // ---------------------------------------------------------------------------- // prototypes @@ -96,6 +102,25 @@ static void XCopyRemote(Display *src_display, Display *dest_display, // implementation // ============================================================================ +/* + * compare two doubles and return the larger rounded + * to the nearest int + */ +static int roundmax(double a, double b) +{ + return (int)((a > b ? a : b) + 0.5); +} + +/* + * compare two doubles and return the smaller rounded + * to the nearest int + */ +static int roundmin(double a, double b) +{ + return (int)((a < b ? a : b) - 0.5); +} + + // ---------------------------------------------------------------------------- // wxWindowDC // ---------------------------------------------------------------------------- @@ -204,20 +229,20 @@ wxWindowDC::~wxWindowDC() m_userRegion = (WXRegion) 0; } -void wxWindowDC::DoFloodFill( long WXUNUSED(x1), long WXUNUSED(y1), +void wxWindowDC::DoFloodFill( wxCoord WXUNUSED(x1), wxCoord WXUNUSED(y1), const wxColour& WXUNUSED(col), int WXUNUSED(style) ) { wxFAIL_MSG("not implemented"); } -bool wxWindowDC::DoGetPixel( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col) ) const +bool wxWindowDC::DoGetPixel( wxCoord WXUNUSED(x1), wxCoord WXUNUSED(y1), wxColour *WXUNUSED(col) ) const { wxFAIL_MSG("not implemented"); return FALSE; } -void wxWindowDC::DoDrawLine( long x1, long y1, long x2, long y2 ) +void wxWindowDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -244,7 +269,7 @@ void wxWindowDC::DoDrawLine( long x1, long y1, long x2, long y2 ) CalcBoundingBox(x2, y2); } -void wxWindowDC::DoCrossHair( long x, long y ) +void wxWindowDC::DoCrossHair( wxCoord x, wxCoord y ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -273,7 +298,7 @@ void wxWindowDC::DoCrossHair( long x, long y ) } } -void wxWindowDC::DoDrawArc( long x1, long y1, long x2, long y2, long xc, long yc ) +void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -288,10 +313,10 @@ void wxWindowDC::DoDrawArc( long x1, long y1, long x2, long y2, long xc, long yc int xxc_2 = XLOG2DEV_2 (xc); int yyc_2 = YLOG2DEV_2 (yc); - long dx = xx1 - xxc; - long dy = yy1 - yyc; + wxCoord dx = xx1 - xxc; + wxCoord dy = yy1 - yyc; double radius = sqrt (dx * dx + dy * dy); - long r = (long) radius; + wxCoord r = (wxCoord) radius; double radius1, radius2; @@ -356,7 +381,7 @@ void wxWindowDC::DoDrawArc( long x1, long y1, long x2, long y2, long xc, long yc CalcBoundingBox (x2, y2); } -void wxWindowDC::DoDrawEllipticArc( long x, long y, long width, long height, double sa, double ea ) +void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double sa, double ea ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -401,7 +426,7 @@ void wxWindowDC::DoDrawEllipticArc( long x, long y, long width, long height, dou CalcBoundingBox (x + width, y + height); } -void wxWindowDC::DoDrawPoint( long x, long y ) +void wxWindowDC::DoDrawPoint( wxCoord x, wxCoord y ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -417,7 +442,7 @@ void wxWindowDC::DoDrawPoint( long x, long y ) CalcBoundingBox (x, y); } -void wxWindowDC::DoDrawLines( int n, wxPoint points[], long xoffset, long yoffset ) +void wxWindowDC::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -452,7 +477,7 @@ void wxWindowDC::DoDrawLines( int n, wxPoint points[], long xoffset, long yoffse } void wxWindowDC::DoDrawPolygon( int n, wxPoint points[], - long xoffset, long yoffset, int fillStyle ) + wxCoord xoffset, wxCoord yoffset, int fillStyle ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -505,7 +530,7 @@ void wxWindowDC::DoDrawPolygon( int n, wxPoint points[], delete[]xpoints2; } -void wxWindowDC::DoDrawRectangle( long x, long y, long width, long height ) +void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -550,7 +575,7 @@ void wxWindowDC::DoDrawRectangle( long x, long y, long width, long height ) CalcBoundingBox (x + width, y + height); } -void wxWindowDC::DoDrawRoundedRectangle( long x, long y, long width, long height, double radius ) +void wxWindowDC::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -714,7 +739,7 @@ void wxWindowDC::DoDrawRoundedRectangle( long x, long y, long width, long height } -void wxWindowDC::DoDrawEllipse( long x, long y, long width, long height ) +void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -777,7 +802,7 @@ bool wxWindowDC::CanDrawBitmap() const } #if 0 -void wxWindowDC::DoDrawIcon( const wxIcon &icon, long x, long y) +void wxWindowDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y) { // FreeGetPixelCache(); @@ -837,8 +862,8 @@ void wxWindowDC::DoDrawIcon( const wxIcon &icon, long x, long y) #endif // 0 // TODO: use scaled Blit e.g. as per John Price's implementation in Contrib/Utilities -bool wxWindowDC::DoBlit( long xdest, long ydest, long width, long height, - wxDC *source, long xsrc, long ysrc, int rop, bool useMask ) +bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, + wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask ) { wxCHECK_MSG( Ok(), FALSE, "invalid dc" ); @@ -1011,7 +1036,7 @@ bool wxWindowDC::DoBlit( long xdest, long ydest, long width, long height, return FALSE; } -void wxWindowDC::DoDrawText( const wxString &text, long x, long y ) +void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) { wxCHECK_RET( Ok(), "invalid dc" ); @@ -1155,7 +1180,145 @@ void wxWindowDC::DoDrawText( const wxString &text, long x, long y ) XLOG2DEV_2 (x), YLOG2DEV_2 (y) + ascent, (char*) (const char*) text, slen); } + 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 ) +{ + if (angle == 0.0) + { + DrawText(text, x, y); + return; + } + + wxCHECK_RET( Ok(), "invalid dc" ); + + // 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); + + if (m_font.Ok()) + { + // Calculate text extent. + 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, + &ascent, &descent, &overall_return); + else +#endif // 0 + (void)XTextExtents((XFontStruct*) pFontStruct, (char*) (const char*) text, slen, &direction, + &ascent, &descent, &overall_return); + + cx = overall_return.width; + cy = ascent + descent; + } + + wxBitmap src(cx, cy); + wxMemoryDC dc; + dc.SelectObject(src); + dc.SetFont(GetFont()); + dc.SetBackground(*wxWHITE_BRUSH); + dc.SetBrush(*wxBLACK_BRUSH); + dc.Clear(); + dc.DrawText(text, 0, 0); + dc.SetFont(wxNullFont); + + // 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 y4 = cy * dx; + double x3 = cx * dx; + 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); + + 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))); + + // 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); + if (sx >= 0 && sx < cx && sy >= 0 && sy < cy) + { + // draw black pixels, ignore white ones (i.e. transparent b/g) + if (image.GetRed(sx, sy) == 0) + { + DrawPoint(x1 + maxx - rx, cy + y1 - ry); + } + else + { + // Background + //DrawPoint(x1 + maxx - rx, cy + y1 + maxy - ry); + } + } + } + } + +#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); + if (m_window && m_window->GetBackingPixmap()) + XSetForeground ((Display*) m_display,(GC) m_gcBacking, pixel); + } + } + else + m_textBackgroundColour = oldPenColour ; + + XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, XLOG2DEV (x), YLOG2DEV (y), cx, cy); + 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); + } +#endif + long w, h; + // XXX use pixmap size GetTextExtent (text, &w, &h); CalcBoundingBox (x + w, y + h); CalcBoundingBox (x, y); @@ -1166,8 +1329,8 @@ bool wxWindowDC::CanGetTextExtent() const return TRUE; } -void wxWindowDC::GetTextExtent( const wxString &string, long *width, long *height, - long *descent, long *externalLeading, +void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoord *height, + wxCoord *descent, wxCoord *externalLeading, wxFont *font ) const { wxCHECK_RET( Ok(), "invalid dc" ); @@ -1216,7 +1379,7 @@ void wxWindowDC::GetTextExtent( const wxString &string, long *width, long *heigh *externalLeading = 0; } -long wxWindowDC::GetCharWidth() const +wxCoord wxWindowDC::GetCharWidth() const { wxCHECK_MSG( Ok(), 0, "invalid dc" ); wxCHECK_MSG( m_font.Ok(), 0, "invalid font" ); @@ -1230,7 +1393,7 @@ long wxWindowDC::GetCharWidth() const return XDEV2LOGREL(overall.width); } -long wxWindowDC::GetCharHeight() const +wxCoord wxWindowDC::GetCharHeight() const { wxCHECK_MSG( Ok(), 0, "invalid dc" ); wxCHECK_MSG( m_font.Ok(), 0, "invalid font" ); @@ -1309,7 +1472,7 @@ void wxWindowDC::SetFont( const wxFont &font ) if (!m_font.Ok()) { - if ((m_oldFont != (WXFont) 0) && ((long) m_oldFont != -1)) + if ((m_oldFont != (WXFont) 0) && ((wxCoord) m_oldFont != -1)) { XSetFont ((Display*) m_display, (GC) m_gc, (Font) m_oldFont); @@ -1381,10 +1544,10 @@ void wxWindowDC::SetPen( const wxPen &pen ) int style; int join; int cap; - const static char dotted[] = {2, 5}; - const static char short_dashed[] = {4, 4}; - const static char long_dashed[] = {4, 8}; - const static char dotted_dashed[] = {6, 6, 2, 6}; + 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... @@ -1991,7 +2154,7 @@ void wxWindowDC::SetDCClipping() } -void wxWindowDC::DoSetClippingRegion( long x, long y, long width, long height ) +void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { wxDC::DoSetClippingRegion( x, y, width, height ); @@ -2194,8 +2357,8 @@ static void wx_spline_draw_point_array(wxDC *dc) void wxWindowDC::DoDrawSpline( wxList *points ) { - wxCHECK_RET( Ok(), _T("invalid window dc") ); - + wxCHECK_RET( Ok(), wxT("invalid window dc") ); + wxPoint *p; double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4; double x1, y1, x2, y2; @@ -2284,6 +2447,9 @@ wxPaintDC::wxPaintDC(wxWindow* win) : wxWindowDC(win) win->SetUpdateRegion(*region); + wxRegion& theRegion(win->GetUpdateRegion()); + theRegion.SetRects(updateRects); // We also store in terms of rects, for iteration to work. + // Set the clipping region. Any user-defined region will be combined with this // one in SetDCClipping. XSetRegion ((Display*) m_display, (GC) m_gc, (Region) region->GetXRegion());