+
+// ----------------------------------------------------------------------------
+// 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);
+}