📄 dc.cpp
字号:
}
#else
if ( ::TextOut(GetHdc(), XLOG2DEV(x), YLOG2DEV(y),
text.c_str(), text.length()) == 0 )
{
wxLogLastError(wxT("TextOut"));
}
#endif
// restore the old parameters (text foreground colour may be left because
// it never is set to anything else, but background should remain
// transparent even if we just drew an opaque string)
if ( m_textBackgroundColour.Ok() )
(void)SetBkColor(GetHdc(), old_background);
SetBkMode(GetHdc(), TRANSPARENT);
}
void wxDC::DoDrawRotatedText(const wxString& text,
wxCoord x, wxCoord y,
double angle)
{
WXMICROWIN_CHECK_HDC
// we test that we have some font because otherwise we should still use the
// "else" part below to avoid that DrawRotatedText(angle = 180) and
// DrawRotatedText(angle = 0) use different fonts (we can't use the default
// font for drawing rotated fonts unfortunately)
if ( (angle == 0.0) && m_font.Ok() )
{
DoDrawText(text, x, y);
}
#ifndef __WXMICROWIN__
else
{
// NB: don't take DEFAULT_GUI_FONT (a.k.a. wxSYS_DEFAULT_GUI_FONT)
// because it's not TrueType and so can't have non zero
// orientation/escapement under Win9x
wxFont font = m_font.Ok() ? m_font : *wxSWISS_FONT;
HFONT hfont = (HFONT)font.GetResourceHandle();
LOGFONT lf;
if ( ::GetObject(hfont, sizeof(lf), &lf) == 0 )
{
wxLogLastError(wxT("GetObject(hfont)"));
}
// GDI wants the angle in tenth of degree
long angle10 = (long)(angle * 10);
lf.lfEscapement = angle10;
lf. lfOrientation = angle10;
hfont = ::CreateFontIndirect(&lf);
if ( !hfont )
{
wxLogLastError(wxT("CreateFont"));
}
else
{
HFONT hfontOld = (HFONT)::SelectObject(GetHdc(), hfont);
DrawAnyText(text, x, y);
(void)::SelectObject(GetHdc(), hfontOld);
(void)::DeleteObject(hfont);
}
// call the bounding box by adding all four vertices of the rectangle
// containing the text to it (simpler and probably not slower than
// determining which of them is really topmost/leftmost/...)
wxCoord w, h;
GetTextExtent(text, &w, &h);
double rad = DegToRad(angle);
// "upper left" and "upper right"
CalcBoundingBox(x, y);
CalcBoundingBox(x + wxCoord(w*cos(rad)), y - wxCoord(w*sin(rad)));
// "bottom left" and "bottom right"
x += (wxCoord)(h*sin(rad));
y += (wxCoord)(h*cos(rad));
CalcBoundingBox(x, y);
CalcBoundingBox(x + wxCoord(w*cos(rad)), y - wxCoord(w*sin(rad)));
}
#endif
}
// ---------------------------------------------------------------------------
// set GDI objects
// ---------------------------------------------------------------------------
#if wxUSE_PALETTE
void wxDC::DoSelectPalette(bool realize)
{
WXMICROWIN_CHECK_HDC
// Set the old object temporarily, in case the assignment deletes an object
// that's not yet selected out.
if (m_oldPalette)
{
::SelectPalette(GetHdc(), (HPALETTE) m_oldPalette, FALSE);
m_oldPalette = 0;
}
if ( m_palette.Ok() )
{
HPALETTE oldPal = ::SelectPalette(GetHdc(),
GetHpaletteOf(m_palette),
false);
if (!m_oldPalette)
m_oldPalette = (WXHPALETTE) oldPal;
if (realize)
::RealizePalette(GetHdc());
}
}
void wxDC::SetPalette(const wxPalette& palette)
{
if ( palette.Ok() )
{
m_palette = palette;
DoSelectPalette(true);
}
}
void wxDC::InitializePalette()
{
if ( wxDisplayDepth() <= 8 )
{
// look for any window or parent that has a custom palette. If any has
// one then we need to use it in drawing operations
wxWindow *win = m_canvas->GetAncestorWithCustomPalette();
m_hasCustomPalette = win && win->HasCustomPalette();
if ( m_hasCustomPalette )
{
m_palette = win->GetPalette();
// turn on MSW translation for this palette
DoSelectPalette();
}
}
}
#endif // wxUSE_PALETTE
// SetFont/Pen/Brush() really ask to be implemented as a single template
// function... but doing it is not worth breaking OpenWatcom build <sigh>
void wxDC::SetFont(const wxFont& font)
{
WXMICROWIN_CHECK_HDC
if ( font == m_font )
return;
if ( font.Ok() )
{
HGDIOBJ hfont = ::SelectObject(GetHdc(), GetHfontOf(font));
if ( hfont == HGDI_ERROR )
{
wxLogLastError(_T("SelectObject(font)"));
}
else // selected ok
{
if ( !m_oldFont )
m_oldFont = (WXHPEN)hfont;
m_font = font;
}
}
else // invalid font, reset the current font
{
if ( m_oldFont )
{
if ( ::SelectObject(GetHdc(), (HPEN) m_oldFont) == HGDI_ERROR )
{
wxLogLastError(_T("SelectObject(old font)"));
}
m_oldFont = 0;
}
m_font = wxNullFont;
}
}
void wxDC::SetPen(const wxPen& pen)
{
WXMICROWIN_CHECK_HDC
if ( pen == m_pen )
return;
if ( pen.Ok() )
{
HGDIOBJ hpen = ::SelectObject(GetHdc(), GetHpenOf(pen));
if ( hpen == HGDI_ERROR )
{
wxLogLastError(_T("SelectObject(pen)"));
}
else // selected ok
{
if ( !m_oldPen )
m_oldPen = (WXHPEN)hpen;
m_pen = pen;
}
}
else // invalid pen, reset the current pen
{
if ( m_oldPen )
{
if ( ::SelectObject(GetHdc(), (HPEN) m_oldPen) == HGDI_ERROR )
{
wxLogLastError(_T("SelectObject(old pen)"));
}
m_oldPen = 0;
}
m_pen = wxNullPen;
}
}
void wxDC::SetBrush(const wxBrush& brush)
{
WXMICROWIN_CHECK_HDC
if ( brush == m_brush )
return;
if ( brush.Ok() )
{
// we must make sure the brush is aligned with the logical coordinates
// before selecting it
wxBitmap *stipple = brush.GetStipple();
if ( stipple && stipple->Ok() )
{
if ( !::SetBrushOrgEx
(
GetHdc(),
m_deviceOriginX % stipple->GetWidth(),
m_deviceOriginY % stipple->GetHeight(),
NULL // [out] previous brush origin
) )
{
wxLogLastError(_T("SetBrushOrgEx()"));
}
}
HGDIOBJ hbrush = ::SelectObject(GetHdc(), GetHbrushOf(brush));
if ( hbrush == HGDI_ERROR )
{
wxLogLastError(_T("SelectObject(brush)"));
}
else // selected ok
{
if ( !m_oldBrush )
m_oldBrush = (WXHPEN)hbrush;
m_brush = brush;
}
}
else // invalid brush, reset the current brush
{
if ( m_oldBrush )
{
if ( ::SelectObject(GetHdc(), (HPEN) m_oldBrush) == HGDI_ERROR )
{
wxLogLastError(_T("SelectObject(old brush)"));
}
m_oldBrush = 0;
}
m_brush = wxNullBrush;
}
}
void wxDC::SetBackground(const wxBrush& brush)
{
WXMICROWIN_CHECK_HDC
m_backgroundBrush = brush;
if ( m_backgroundBrush.Ok() )
{
(void)SetBkColor(GetHdc(), m_backgroundBrush.GetColour().GetPixel());
}
}
void wxDC::SetBackgroundMode(int mode)
{
WXMICROWIN_CHECK_HDC
m_backgroundMode = mode;
// SetBackgroundColour now only refers to text background
// and m_backgroundMode is used there
}
void wxDC::SetLogicalFunction(int function)
{
WXMICROWIN_CHECK_HDC
m_logicalFunction = function;
SetRop(m_hDC);
}
void wxDC::SetRop(WXHDC dc)
{
if ( !dc || m_logicalFunction < 0 )
return;
int rop;
switch (m_logicalFunction)
{
case wxCLEAR: rop = R2_BLACK; break;
case wxXOR: rop = R2_XORPEN; break;
case wxINVERT: rop = R2_NOT; break;
case wxOR_REVERSE: rop = R2_MERGEPENNOT; break;
case wxAND_REVERSE: rop = R2_MASKPENNOT; break;
case wxCOPY: rop = R2_COPYPEN; break;
case wxAND: rop = R2_MASKPEN; break;
case wxAND_INVERT: rop = R2_MASKNOTPEN; break;
case wxNO_OP: rop = R2_NOP; break;
case wxNOR: rop = R2_NOTMERGEPEN; break;
case wxEQUIV: rop = R2_NOTXORPEN; break;
case wxSRC_INVERT: rop = R2_NOTCOPYPEN; break;
case wxOR_INVERT: rop = R2_MERGENOTPEN; break;
case wxNAND: rop = R2_NOTMASKPEN; break;
case wxOR: rop = R2_MERGEPEN; break;
case wxSET: rop = R2_WHITE; break;
default:
wxFAIL_MSG( wxT("unsupported logical function") );
return;
}
SetROP2(GetHdc(), rop);
}
bool wxDC::StartDoc(const wxString& WXUNUSED(message))
{
// We might be previewing, so return true to let it continue.
return true;
}
void wxDC::EndDoc()
{
}
void wxDC::StartPage()
{
}
void wxDC::EndPage()
{
}
// ---------------------------------------------------------------------------
// text metrics
// ---------------------------------------------------------------------------
wxCoord wxDC::GetCharHeight() const
{
WXMICROWIN_CHECK_HDC_RET(0)
TEXTMETRIC lpTextMetric;
GetTextMetrics(GetHdc(), &lpTextMetric);
return lpTextMetric.tmHeight;
}
wxCoord wxDC::GetCharWidth() const
{
WXMICROWIN_CHECK_HDC_RET(0)
TEXTMETRIC lpTextMetric;
GetTextMetrics(GetHdc(), &lpTextMetric);
return lpTextMetric.tmAveCharWidth;
}
void wxDC::DoGetTextExtent(const wxString& string, wxCoord *x, wxCoord *y,
wxCoord *descent, wxCoord *externalLeading,
wxFont *font) const
{
#ifdef __WXMICROWIN__
if (!GetHDC())
{
if (x) *x = 0;
if (y) *y = 0;
if (descent) *descent = 0;
if (externalLeading) *externalLeading = 0;
return;
}
#endif // __WXMICROWIN__
HFONT hfontOld;
if ( font )
{
wxASSERT_MSG( font->Ok(), _T("invalid font in wxDC::GetTextExtent") );
hfontOld = (HFONT)::SelectObject(GetHdc(), GetHfontOf(*font));
}
else // don't change the font
{
hfontOld = 0;
}
SIZE sizeRect;
TEXTMETRIC tm;
::GetTextExtentPoint32(GetHdc(), string, string.length(), &sizeRect);
GetTextMetrics(GetHdc(), &tm);
if (x)
*x = sizeRect.cx;
if (y)
*y = sizeRect.cy;
if (descent)
*descent = tm.tmDescent;
if (externalLeading)
*externalLeading = tm.tmExternalLeading;
if ( hfontOld )
{
::SelectObject(GetHdc(), hfontOld);
}
}
// Each element of the array will be the width of the string up to and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -