From 7f9453dfdf6b6dc356378bdc212b23c57d8de23c Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Mon, 17 Apr 2017 14:15:51 +0200 Subject: [PATCH] Handle unsuccessful creation of graphics font in Direct2D Apparently, DirectWrite fonts can be created only from TrueType fonts and therefore only such fonts can be used with Direct2D-based wxGraphicsContext. When unsuported GDI font is passed to CreateFont() then no graphics font is created and this unsuccessful attempt is signalled by returning wxNullGraphicsFont. This null object can be used in e.g. wxGC::SetFont() to check if font was actually created. See #17790. --- interface/wx/graphics.h | 11 ++++++++++- src/msw/graphicsd2d.cpp | 23 +++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/interface/wx/graphics.h b/interface/wx/graphics.h index fc27a2fb39..ba37013b88 100644 --- a/interface/wx/graphics.h +++ b/interface/wx/graphics.h @@ -847,6 +847,9 @@ public: /** Creates a native graphics font from a wxFont and a text colour. + + @remarks + For Direct2D graphics fonts can be created from TrueType fonts only. */ virtual wxGraphicsFont CreateFont(const wxFont& font, const wxColour& col = *wxBLACK) const; @@ -857,8 +860,11 @@ public: The use of overload taking wxFont is preferred, see wxGraphicsRenderer::CreateFont() for more details. + @remarks + For Direct2D graphics fonts can be created from TrueType fonts only. + @since 2.9.3 - */ + */ virtual wxGraphicsFont CreateFont(double sizeInPixels, const wxString& facename, int flags = wxFONTFLAG_DEFAULT, @@ -866,6 +872,9 @@ public: /** Sets the font for drawing text. + + @remarks + For Direct2D only TrueType fonts can be used. */ void SetFont(const wxFont& font, const wxColour& colour); diff --git a/src/msw/graphicsd2d.cpp b/src/msw/graphicsd2d.cpp index a0659626a5..e420519457 100644 --- a/src/msw/graphicsd2d.cpp +++ b/src/msw/graphicsd2d.cpp @@ -2627,6 +2627,12 @@ wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, ID2D1Factory* d2dFact } hr = gdiInterop->CreateFontFromLOGFONT(&logfont, &m_font); + if ( hr == DWRITE_E_NOFONT ) + { + // It was attempted to create DirectWrite font from non-TrueType GDI font. + return; + } + wxCHECK_RET( SUCCEEDED(hr), wxString::Format("Failed to create font '%s' (HRESULT = %x)", logfont.lfFaceName, hr) ); @@ -4093,13 +4099,19 @@ void wxD2DContext::GetTextExtent( wxDouble* descent, wxDouble* externalLeading) const { + wxCHECK_RET(!m_font.IsNull(), + wxS("wxD2DContext::GetTextExtent - no valid font set")); + wxD2DMeasuringContext::GetTextExtent( wxGetD2DFontData(m_font), str, width, height, descent, externalLeading); } void wxD2DContext::GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const { - return wxD2DMeasuringContext::GetPartialTextExtents( + wxCHECK_RET(!m_font.IsNull(), + wxS("wxD2DContext::GetPartialTextExtents - no valid font set")); + + wxD2DMeasuringContext::GetPartialTextExtents( wxGetD2DFontData(m_font), text, widths); } @@ -4123,7 +4135,7 @@ bool wxD2DContext::ShouldOffset() const void wxD2DContext::DoDrawText(const wxString& str, wxDouble x, wxDouble y) { wxCHECK_RET(!m_font.IsNull(), - wxT("wxGDIPlusContext::DrawText - no valid font set")); + wxS("wxD2DContext::DrawText - no valid font set")); if (m_composition == wxCOMPOSITION_DEST) return; @@ -4637,6 +4649,13 @@ wxImage wxD2DRenderer::CreateImageFromBitmap(const wxGraphicsBitmap& bmp) wxGraphicsFont wxD2DRenderer::CreateFont(const wxFont& font, const wxColour& col) { wxD2DFontData* fontData = new wxD2DFontData(this, GetD2DFactory(), font, col); + if ( !fontData->GetFont() ) + { + // Apparently a non-TrueType font is given and hence + // corresponding DirectWrite font couldn't be created. + delete fontData; + return wxNullGraphicsFont; + } wxGraphicsFont graphicsFont; graphicsFont.SetRefData(fontData);