X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fe2e43661ec454a020e57deda94db36ca26f8a1e..4aaef122cbbd5bbe0e70b824e320458e2329dd13:/src/common/dcbase.cpp diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 9cd65312e3..83e9980940 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: dc.cpp -// Purpose: wxDC Class -// Author: Brian Macy +// Name: common/dcbase.cpp +// Purpose: generic methods of the wxDC Class +// Author: Vadim Zeitlin // Modified by: // Created: 05/25/99 // RCS-ID: $Id$ @@ -9,10 +9,18 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + #ifdef __GNUG__ -#pragma implementation "dcbase.h" + #pragma implementation "dcbase.h" #endif +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -22,6 +30,18 @@ #include "wx/dc.h" +#include + +// bool wxDCBase::sm_cacheing = FALSE; + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// special symbols +// ---------------------------------------------------------------------------- + void wxDCBase::DoDrawCheckMark(wxCoord x1, wxCoord y1, wxCoord width, wxCoord height) { @@ -43,6 +63,10 @@ void wxDCBase::DoDrawCheckMark(wxCoord x1, wxCoord y1, CalcBoundingBox(x2, y2); } +// ---------------------------------------------------------------------------- +// line/polygons +// ---------------------------------------------------------------------------- + void wxDCBase::DrawLines(const wxList *list, wxCoord xoffset, wxCoord yoffset) { int n = list->Number(); @@ -82,6 +106,9 @@ void wxDCBase::DrawPolygon(const wxList *list, delete [] points; } +// ---------------------------------------------------------------------------- +// splines +// ---------------------------------------------------------------------------- #if wxUSE_SPLINES @@ -290,3 +317,230 @@ void wxDCBase::DoDrawSpline( wxList *points ) } #endif // wxUSE_SPLINES + +// ---------------------------------------------------------------------------- +// enhanced text drawing +// ---------------------------------------------------------------------------- + +void wxDCBase::GetMultiLineTextExtent(const wxString& text, + wxCoord *x, + wxCoord *y, + wxCoord *h, + wxFont *font) +{ + wxCoord widthTextMax = 0, widthLine, + heightTextTotal = 0, heightLineDefault = 0, heightLine = 0; + + wxString curLine; + for ( const wxChar *pc = text; ; pc++ ) + { + if ( *pc == _T('\n') || *pc == _T('\0') ) + { + if ( curLine.empty() ) + { + // we can't use GetTextExtent - it will return 0 for both width + // and height and an empty line should count in height + // calculation + + // assume that this line has the same height as the previous + // one + if ( !heightLineDefault ) + heightLineDefault = heightLine; + + if ( !heightLineDefault ) + { + // but we don't know it yet - choose something reasonable + GetTextExtent(_T("W"), NULL, &heightLineDefault, + NULL, NULL, font); + } + + heightTextTotal += heightLineDefault; + } + else + { + GetTextExtent(curLine, &widthLine, &heightLine, + NULL, NULL, font); + if ( widthLine > widthTextMax ) + widthTextMax = widthLine; + heightTextTotal += heightLine; + } + + if ( *pc == _T('\n') ) + { + curLine.clear(); + } + else + { + // the end of string + break; + } + } + else + { + curLine += *pc; + } + } + + if ( x ) + *x = widthTextMax; + if ( y ) + *y = heightTextTotal; + if ( h ) + *h = heightLine; +} + +void wxDCBase::DrawLabel(const wxString& text, + const wxBitmap& bitmap, + const wxRect& rect, + int alignment, + int indexAccel, + wxRect *rectBounding) +{ + // find the text position + wxCoord widthText, heightText, heightLine; + GetMultiLineTextExtent(text, &widthText, &heightText, &heightLine); + + wxCoord width, height; + if ( bitmap.Ok() ) + { + width = widthText + bitmap.GetWidth(); + height = bitmap.GetHeight(); + } + else // no bitmap + { + width = widthText; + height = heightText; + } + + wxCoord x, y; + if ( alignment & wxALIGN_RIGHT ) + { + x = rect.GetRight() - width; + } + else if ( alignment & wxALIGN_CENTRE_HORIZONTAL ) + { + x = (rect.GetLeft() + rect.GetRight() + 1 - width) / 2; + } + else // alignment & wxALIGN_LEFT + { + x = rect.GetLeft(); + } + + if ( alignment & wxALIGN_BOTTOM ) + { + y = rect.GetBottom() - height; + } + else if ( alignment & wxALIGN_CENTRE_VERTICAL ) + { + y = (rect.GetTop() + rect.GetBottom() + 1 - height) / 2; + } + else // alignment & wxALIGN_TOP + { + y = rect.GetTop(); + } + + // draw the bitmap first + wxCoord x0 = x, + y0 = y, + width0 = width; + if ( bitmap.Ok() ) + { + DrawBitmap(bitmap, x, y, TRUE /* use mask */); + + wxCoord offset = bitmap.GetWidth() + 4; + x += offset; + width -= offset; + + y += (height - heightText) / 2; + } + + // we will draw the underscore under the accel char later + wxCoord startUnderscore = 0, + endUnderscore = 0, + yUnderscore = 0; + + // split the string into lines and draw each of them separately + wxString curLine; + for ( const wxChar *pc = text; ; pc++ ) + { + if ( *pc == _T('\n') || *pc == _T('\0') ) + { + int xRealStart = x; // init it here to avoid compielr warnings + + if ( !curLine.empty() ) + { + // NB: can't test for !(alignment & wxALIGN_LEFT) because + // wxALIGN_LEFT is 0 + if ( alignment & (wxALIGN_RIGHT | wxALIGN_CENTRE_HORIZONTAL) ) + { + wxCoord widthLine; + GetTextExtent(curLine, &widthLine, NULL); + + if ( alignment & wxALIGN_RIGHT ) + { + xRealStart += width - widthLine; + } + else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL ) + { + xRealStart += (width - widthLine) / 2; + } + } + //else: left aligned, nothing to do + + DrawText(curLine, xRealStart, y); + } + + y += heightLine; + + // do we have underscore in this line? we can check yUnderscore + // because it is set below to just y + heightLine if we do + if ( y == yUnderscore ) + { + // adjust the horz positions to account for the shift + startUnderscore += xRealStart; + endUnderscore += xRealStart; + } + + if ( *pc == _T('\0') ) + break; + + curLine.clear(); + } + else // not end of line + { + if ( pc - text.c_str() == indexAccel ) + { + // remeber to draw underscore here + GetTextExtent(curLine, &startUnderscore, NULL); + curLine += *pc; + GetTextExtent(curLine, &endUnderscore, NULL); + + yUnderscore = y + heightLine; + } + else + { + curLine += *pc; + } + } + } + + // draw the underscore if found + if ( startUnderscore != endUnderscore ) + { + // it should be of the same colour as text + SetPen(wxPen(GetTextForeground(), 0, wxSOLID)); + + yUnderscore--; + + DrawLine(startUnderscore, yUnderscore, endUnderscore, yUnderscore); + } + + // return bounding rect if requested + if ( rectBounding ) + { + *rectBounding = wxRect(x, y - heightText, widthText, heightText); + } + + CalcBoundingBox(x0, y0); + CalcBoundingBox(x0 + width0, y0 + height); +}