Add more initialization checks for wxSTC SurfaceD2D target

Return early if the check fails. No functional changes.

This commit is best viewed ignoring whitespace changes.

Closes https://github.com/wxWidgets/wxWidgets/pull/1914
This commit is contained in:
Maarten Bent
2020-06-28 20:30:51 +02:00
committed by Vadim Zeitlin
parent a2823983a3
commit dec895e1d7

View File

@@ -1201,8 +1201,8 @@ static float RoundFloat(float f)
void SurfaceD2D::LineTo(int x_, int y_) void SurfaceD2D::LineTo(int x_, int y_)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
int xDiff = x_ - m_x; int xDiff = x_ - m_x;
int xDelta = Delta(xDiff); int xDelta = Delta(xDiff);
int yDiff = y_ - m_y; int yDiff = y_ - m_y;
@@ -1218,8 +1218,8 @@ void SurfaceD2D::LineTo(int x_, int y_)
int top = Platform::Minimum(m_y, yEnd); int top = Platform::Minimum(m_y, yEnd);
int height = abs(m_y - yEnd) + 1; int height = abs(m_y - yEnd) + 1;
D2D1_RECT_F rectangle1 = D2D1::RectF(static_cast<float>(left), D2D1_RECT_F rectangle1 = D2D1::RectF(static_cast<float>(left),
static_cast<float>(top), static_cast<float>(left+width), static_cast<float>(top), static_cast<float>(left + width),
static_cast<float>(top+height)); static_cast<float>(top + height));
m_pRenderTarget->FillRectangle(&rectangle1, m_pSolidBrush); m_pRenderTarget->FillRectangle(&rectangle1, m_pSolidBrush);
} }
else if ( (abs(xDiff) == abs(yDiff)) ) else if ( (abs(xDiff) == abs(yDiff)) )
@@ -1237,14 +1237,13 @@ void SurfaceD2D::LineTo(int x_, int y_)
} }
m_x = x_; m_x = x_;
m_y = y_; m_y = y_;
}
} }
void SurfaceD2D::Polygon(Point *pts, int npts, ColourDesired fore, void SurfaceD2D::Polygon(Point *pts, int npts, ColourDesired fore,
ColourDesired back) ColourDesired back)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
wxCOMPtr<ID2D1Factory> pFactory; wxCOMPtr<ID2D1Factory> pFactory;
wxCOMPtr<ID2D1PathGeometry> geometry; wxCOMPtr<ID2D1PathGeometry> geometry;
wxCOMPtr<ID2D1GeometrySink> sink; wxCOMPtr<ID2D1GeometrySink> sink;
@@ -1261,7 +1260,7 @@ void SurfaceD2D::Polygon(Point *pts, int npts, ColourDesired fore,
{ {
sink->BeginFigure(D2D1::Point2F(pts[0].x + 0.5f, pts[0].y + 0.5f), sink->BeginFigure(D2D1::Point2F(pts[0].x + 0.5f, pts[0].y + 0.5f),
D2D1_FIGURE_BEGIN_FILLED); D2D1_FIGURE_BEGIN_FILLED);
for ( size_t i=1; i<static_cast<size_t>(npts); i++ ) for ( size_t i = 1; i < static_cast<size_t>(npts); i++ )
{ {
sink->AddLine(D2D1::Point2F(pts[i].x + 0.5f, pts[i].y + 0.5f)); sink->AddLine(D2D1::Point2F(pts[i].x + 0.5f, pts[i].y + 0.5f));
} }
@@ -1269,40 +1268,39 @@ void SurfaceD2D::Polygon(Point *pts, int npts, ColourDesired fore,
sink->Close(); sink->Close();
D2DPenColour(back); D2DPenColour(back);
m_pRenderTarget->FillGeometry(geometry,m_pSolidBrush); m_pRenderTarget->FillGeometry(geometry, m_pSolidBrush);
D2DPenColour(fore); D2DPenColour(fore);
m_pRenderTarget->DrawGeometry(geometry,m_pSolidBrush); m_pRenderTarget->DrawGeometry(geometry, m_pSolidBrush);
}
} }
} }
void SurfaceD2D::RectangleDraw(PRectangle rc, ColourDesired fore, void SurfaceD2D::RectangleDraw(PRectangle rc, ColourDesired fore,
ColourDesired back) ColourDesired back)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
D2D1_RECT_F rectangle1 = D2D1::RectF(RoundFloat(rc.left) + 0.5f, D2D1_RECT_F rectangle1 = D2D1::RectF(RoundFloat(rc.left) + 0.5f,
rc.top+0.5f, RoundFloat(rc.right) - 0.5f, rc.bottom-0.5f); rc.top + 0.5f, RoundFloat(rc.right) - 0.5f, rc.bottom - 0.5f);
D2DPenColour(back); D2DPenColour(back);
m_pRenderTarget->FillRectangle(&rectangle1, m_pSolidBrush); m_pRenderTarget->FillRectangle(&rectangle1, m_pSolidBrush);
D2DPenColour(fore); D2DPenColour(fore);
m_pRenderTarget->DrawRectangle(&rectangle1, m_pSolidBrush); m_pRenderTarget->DrawRectangle(&rectangle1, m_pSolidBrush);
}
} }
void SurfaceD2D::FillRectangle(PRectangle rc, ColourDesired back) void SurfaceD2D::FillRectangle(PRectangle rc, ColourDesired back)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
D2DPenColour(back); D2DPenColour(back);
D2D1_RECT_F rectangle1 = D2D1::RectF(RoundFloat(rc.left), rc.top, D2D1_RECT_F rectangle1 = D2D1::RectF(RoundFloat(rc.left), rc.top,
RoundFloat(rc.right), rc.bottom); RoundFloat(rc.right), rc.bottom);
m_pRenderTarget->FillRectangle(&rectangle1, m_pSolidBrush); m_pRenderTarget->FillRectangle(&rectangle1, m_pSolidBrush);
}
} }
void SurfaceD2D::FillRectangle(PRectangle rc, Surface &surfacePattern) void SurfaceD2D::FillRectangle(PRectangle rc, Surface &surfacePattern)
{ {
wxCHECK( Initialised(), void() );
SurfaceD2D &surfOther = static_cast<SurfaceD2D &>(surfacePattern); SurfaceD2D &surfOther = static_cast<SurfaceD2D &>(surfacePattern);
surfOther.FlushDrawing(); surfOther.FlushDrawing();
@@ -1342,20 +1340,19 @@ void SurfaceD2D::FillRectangle(PRectangle rc, Surface &surfacePattern)
void SurfaceD2D::RoundedRectangle(PRectangle rc, ColourDesired fore, void SurfaceD2D::RoundedRectangle(PRectangle rc, ColourDesired fore,
ColourDesired back) ColourDesired back)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
D2D1_ROUNDED_RECT roundedRectFill = { D2D1_ROUNDED_RECT roundedRectFill = {
D2D1::RectF(rc.left+1.0f, rc.top+1.0f, rc.right-1.0f, rc.bottom-1.0f), D2D1::RectF(rc.left + 1.0f, rc.top + 1.0f, rc.right - 1.0f, rc.bottom - 1.0f),
4, 4}; 4, 4 };
D2DPenColour(back); D2DPenColour(back);
m_pRenderTarget->FillRoundedRectangle(roundedRectFill, m_pSolidBrush); m_pRenderTarget->FillRoundedRectangle(roundedRectFill, m_pSolidBrush);
D2D1_ROUNDED_RECT roundedRect = { D2D1_ROUNDED_RECT roundedRect = {
D2D1::RectF(rc.left + 0.5f, rc.top+0.5f, rc.right - 0.5f, rc.bottom-0.5f), D2D1::RectF(rc.left + 0.5f, rc.top + 0.5f, rc.right - 0.5f, rc.bottom - 0.5f),
4, 4}; 4, 4 };
D2DPenColour(fore); D2DPenColour(fore);
m_pRenderTarget->DrawRoundedRectangle(roundedRect, m_pSolidBrush); m_pRenderTarget->DrawRoundedRectangle(roundedRect, m_pSolidBrush);
}
} }
void SurfaceD2D::AlphaRectangle(PRectangle rc, int cornerSize, void SurfaceD2D::AlphaRectangle(PRectangle rc, int cornerSize,
@@ -1363,9 +1360,9 @@ void SurfaceD2D::AlphaRectangle(PRectangle rc, int cornerSize,
ColourDesired outline, int alphaOutline, ColourDesired outline, int alphaOutline,
int /* flags*/ ) int /* flags*/ )
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
if (cornerSize == 0) if ( cornerSize == 0 )
{ {
// When corner size is zero, draw square rectangle to prevent // When corner size is zero, draw square rectangle to prevent
// blurry pixels at corners // blurry pixels at corners
@@ -1385,38 +1382,37 @@ void SurfaceD2D::AlphaRectangle(PRectangle rc, int cornerSize,
D2D1_ROUNDED_RECT roundedRectFill = { D2D1_ROUNDED_RECT roundedRectFill = {
D2D1::RectF(RoundFloat(rc.left) + 1.0f, rc.top + 1.0f, D2D1::RectF(RoundFloat(rc.left) + 1.0f, rc.top + 1.0f,
RoundFloat(rc.right) - 1.0f, rc.bottom - 1.0f), RoundFloat(rc.right) - 1.0f, rc.bottom - 1.0f),
cornerSizeF, cornerSizeF}; cornerSizeF, cornerSizeF };
D2DPenColour(fill, alphaFill); D2DPenColour(fill, alphaFill);
m_pRenderTarget->FillRoundedRectangle(roundedRectFill, m_pSolidBrush); m_pRenderTarget->FillRoundedRectangle(roundedRectFill, m_pSolidBrush);
D2D1_ROUNDED_RECT roundedRect = { D2D1_ROUNDED_RECT roundedRect = {
D2D1::RectF(RoundFloat(rc.left) + 0.5f, rc.top + 0.5f, D2D1::RectF(RoundFloat(rc.left) + 0.5f, rc.top + 0.5f,
RoundFloat(rc.right) - 0.5f, rc.bottom - 0.5f), RoundFloat(rc.right) - 0.5f, rc.bottom - 0.5f),
cornerSizeF, cornerSizeF}; cornerSizeF, cornerSizeF };
D2DPenColour(outline, alphaOutline); D2DPenColour(outline, alphaOutline);
m_pRenderTarget->DrawRoundedRectangle(roundedRect, m_pSolidBrush); m_pRenderTarget->DrawRoundedRectangle(roundedRect, m_pSolidBrush);
} }
}
} }
void SurfaceD2D::DrawRGBAImage(PRectangle rc, int width, int height, void SurfaceD2D::DrawRGBAImage(PRectangle rc, int width, int height,
const unsigned char *pixelsImage) const unsigned char *pixelsImage)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
if (rc.Width() > width) if ( rc.Width() > width )
rc.left += static_cast<int>((rc.Width() - width) / 2); rc.left += static_cast<int>((rc.Width() - width) / 2);
rc.right = rc.left + width; rc.right = rc.left + width;
if (rc.Height() > height) if ( rc.Height() > height )
rc.top += static_cast<int>((rc.Height() - height) / 2); rc.top += static_cast<int>((rc.Height() - height) / 2);
rc.bottom = rc.top + height; rc.bottom = rc.top + height;
wxVector<unsigned char> image(height * width * 4); wxVector<unsigned char> image(height * width * 4);
for ( int yPixel=0; yPixel<height; yPixel++ ) for ( int yPixel = 0; yPixel < height; yPixel++ )
{ {
for ( int xPixel = 0; xPixel<width; xPixel++ ) for ( int xPixel = 0; xPixel < width; xPixel++ )
{ {
unsigned char *pixel = &image[0] + (yPixel*width + xPixel) * 4; unsigned char* pixel = &image[0] + (yPixel * width + xPixel) * 4;
unsigned char alpha = pixelsImage[3]; unsigned char alpha = pixelsImage[3];
// Input is RGBA, output is BGRA with premultiplied alpha // Input is RGBA, output is BGRA with premultiplied alpha
pixel[2] = (*pixelsImage++) * alpha / 255; pixel[2] = (*pixelsImage++) * alpha / 255;
@@ -1428,38 +1424,39 @@ void SurfaceD2D::DrawRGBAImage(PRectangle rc, int width, int height,
wxCOMPtr<ID2D1Bitmap> bitmap; wxCOMPtr<ID2D1Bitmap> bitmap;
D2D1_SIZE_U size = D2D1::SizeU(width, height); D2D1_SIZE_U size = D2D1::SizeU(width, height);
D2D1_BITMAP_PROPERTIES props = {{DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_BITMAP_PROPERTIES props = { {DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_PREMULTIPLIED}, 72.0, 72.0}; D2D1_ALPHA_MODE_PREMULTIPLIED}, 72.0, 72.0 };
HRESULT hr = m_pRenderTarget->CreateBitmap(size, &image[0], HRESULT hr = m_pRenderTarget->CreateBitmap(size, &image[0],
width * 4, &props, &bitmap); width * 4, &props, &bitmap);
if ( SUCCEEDED(hr) ) if ( SUCCEEDED(hr) )
{ {
D2D1_RECT_F rcDestination = {rc.left, rc.top, rc.right, rc.bottom}; D2D1_RECT_F rcDestination = { rc.left, rc.top, rc.right, rc.bottom };
m_pRenderTarget->DrawBitmap(bitmap, rcDestination); m_pRenderTarget->DrawBitmap(bitmap, rcDestination);
} }
}
} }
void SurfaceD2D::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) void SurfaceD2D::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
FLOAT radius = rc.Width() / 2.0f; FLOAT radius = rc.Width() / 2.0f;
D2D1_ELLIPSE ellipse = { D2D1_ELLIPSE ellipse = {
D2D1::Point2F((rc.left + rc.right) / 2.0f, D2D1::Point2F((rc.left + rc.right) / 2.0f,
(rc.top + rc.bottom) / 2.0f), (rc.top + rc.bottom) / 2.0f),
radius, radius}; radius, radius };
PenColour(back); PenColour(back);
m_pRenderTarget->FillEllipse(ellipse, m_pSolidBrush); m_pRenderTarget->FillEllipse(ellipse, m_pSolidBrush);
PenColour(fore); PenColour(fore);
m_pRenderTarget->DrawEllipse(ellipse, m_pSolidBrush); m_pRenderTarget->DrawEllipse(ellipse, m_pSolidBrush);
}
} }
void SurfaceD2D::Copy(PRectangle rc, Point from, Surface &surfaceSource) { void SurfaceD2D::Copy(PRectangle rc, Point from, Surface& surfaceSource)
SurfaceD2D &surfOther = static_cast<SurfaceD2D &>(surfaceSource); {
wxCHECK( Initialised(), void() );
SurfaceD2D& surfOther = static_cast<SurfaceD2D&>(surfaceSource);
surfOther.FlushDrawing(); surfOther.FlushDrawing();
wxCOMPtr<ID2D1Bitmap> pBitmap; wxCOMPtr<ID2D1Bitmap> pBitmap;
@@ -1470,9 +1467,9 @@ void SurfaceD2D::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
if ( SUCCEEDED(hr) ) if ( SUCCEEDED(hr) )
{ {
D2D1_RECT_F rcDestination = {rc.left, rc.top, rc.right, rc.bottom}; D2D1_RECT_F rcDestination = { rc.left, rc.top, rc.right, rc.bottom };
D2D1_RECT_F rcSource = D2D1_RECT_F rcSource =
{from.x, from.y, from.x + rc.Width(), from.y + rc.Height()}; { from.x, from.y, from.x + rc.Width(), from.y + rc.Height() };
m_pRenderTarget->DrawBitmap(pBitmap, rcDestination, 1.0f, m_pRenderTarget->DrawBitmap(pBitmap, rcDestination, 1.0f,
D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, rcSource); D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, rcSource);
@@ -1488,40 +1485,37 @@ void SurfaceD2D::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase,
const char *s, int len, ColourDesired fore, const char *s, int len, ColourDesired fore,
ColourDesired back) ColourDesired back)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
FillRectangle(rc, back); FillRectangle(rc, back);
D2DPenColour(fore); D2DPenColour(fore);
DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE); DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE);
}
} }
void SurfaceD2D::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, void SurfaceD2D::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase,
const char *s, int len, ColourDesired fore, const char *s, int len, ColourDesired fore,
ColourDesired back) ColourDesired back)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
FillRectangle(rc, back); FillRectangle(rc, back);
D2DPenColour(fore); D2DPenColour(fore);
DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE | ETO_CLIPPED); DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE | ETO_CLIPPED);
}
} }
void SurfaceD2D::DrawTextTransparent(PRectangle rc, Font &font_, void SurfaceD2D::DrawTextTransparent(PRectangle rc, Font &font_,
XYPOSITION ybase, const char *s, int len, XYPOSITION ybase, const char *s, int len,
ColourDesired fore) ColourDesired fore)
{ {
wxCHECK( Initialised(), void() );
// Avoid drawing spaces in transparent mode // Avoid drawing spaces in transparent mode
for ( int i=0; i<len; i++ ) for ( int i=0; i<len; i++ )
{ {
if ( s[i] != ' ' ) if ( s[i] != ' ' )
{
if ( m_pRenderTarget.get() )
{ {
D2DPenColour(fore); D2DPenColour(fore);
DrawTextCommon(rc, font_, ybase, s, len, 0); DrawTextCommon(rc, font_, ybase, s, len, 0);
}
return; return;
} }
} }
@@ -1708,12 +1702,11 @@ XYPOSITION SurfaceD2D::AverageCharWidth(Font &font_)
void SurfaceD2D::SetClip(PRectangle rc) void SurfaceD2D::SetClip(PRectangle rc)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
D2D1_RECT_F rcClip = {rc.left, rc.top, rc.right, rc.bottom}; D2D1_RECT_F rcClip = { rc.left, rc.top, rc.right, rc.bottom };
m_pRenderTarget->PushAxisAlignedClip(rcClip, D2D1_ANTIALIAS_MODE_ALIASED); m_pRenderTarget->PushAxisAlignedClip(rcClip, D2D1_ANTIALIAS_MODE_ALIASED);
m_clipsActive++; m_clipsActive++;
}
} }
void SurfaceD2D::FlushCachedState() void SurfaceD2D::FlushCachedState()
@@ -1747,7 +1740,7 @@ void SurfaceD2D::SetFont(Font &font_)
m_yInternalLeading = sfd->GetInternalLeading(); m_yInternalLeading = sfd->GetInternalLeading();
m_averageCharWidth = sfd->GetAverageCharWidth(); m_averageCharWidth = sfd->GetAverageCharWidth();
if ( m_pRenderTarget.get() ) if ( Initialised() )
{ {
D2D1_TEXT_ANTIALIAS_MODE aaMode = sfd->GetFontQuality(); D2D1_TEXT_ANTIALIAS_MODE aaMode = sfd->GetFontQuality();
@@ -1775,13 +1768,14 @@ void SurfaceD2D::SetFont(Font &font_)
HRESULT SurfaceD2D::FlushDrawing() HRESULT SurfaceD2D::FlushDrawing()
{ {
wxCHECK( Initialised(), E_POINTER );
return m_pRenderTarget->Flush(); return m_pRenderTarget->Flush();
} }
void SurfaceD2D::D2DPenColour(ColourDesired fore, int alpha) void SurfaceD2D::D2DPenColour(ColourDesired fore, int alpha)
{ {
if ( m_pRenderTarget.get() ) wxCHECK( Initialised(), void() );
{
D2D_COLOR_F col; D2D_COLOR_F col;
col.r = (fore.AsLong() & 0xff) / 255.0f; col.r = (fore.AsLong() & 0xff) / 255.0f;
col.g = ((fore.AsLong() & 0xff00) >> 8) / 255.0f; col.g = ((fore.AsLong() & 0xff00) >> 8) / 255.0f;
@@ -1799,15 +1793,16 @@ void SurfaceD2D::D2DPenColour(ColourDesired fore, int alpha)
m_pSolidBrush.reset(); m_pSolidBrush.reset();
} }
} }
}
} }
void SurfaceD2D::DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, void SurfaceD2D::DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase,
const char *s, int len, UINT fuOptions) const char *s, int len, UINT fuOptions)
{ {
wxCHECK( Initialised(), void() );
SetFont(font_); SetFont(font_);
if ( m_pRenderTarget.get() && m_pSolidBrush.get() && m_pTextFormat.get() ) if ( m_pSolidBrush.get() && m_pTextFormat.get() )
{ {
// Explicitly creating a text layout appears a little faster // Explicitly creating a text layout appears a little faster
wxCOMPtr<IDWriteTextLayout> pTextLayout; wxCOMPtr<IDWriteTextLayout> pTextLayout;