Font problem with Direct2D

170 views
Skip to first unread message

Andrey Turkin

unread,
Sep 15, 2014, 9:25:38 AM9/15/14
to wx-...@googlegroups.com
Hello,

I faced another problem with Direct2D.
File graphics2d.cpp, line 2102:
{{{
hr = gdiInterop->CreateFontFromLOGFONT(&logfont, &m_font);

wxCOMPtr<IDWriteFontFamily> fontFamily;
m_font->GetFontFamily(&fontFamily);

}}}
But in some circumstances CreateFontFromLOGFONT() can return a mistake
and m_font will be 0.
Actually, I don't understend why it happens. The Font looks good for me,
but nevertheless it occurs :(

The problem can be seen in drawing sample with this patch:
{{{
Index: drawing.cpp
===================================================================
--- drawing.cpp (revision 77707)
+++ drawing.cpp (working copy)
@@ -816,7 +816,8 @@
void MyCanvas::DrawText(wxDC& dc)
{
// set underlined font for testing
- dc.SetFont( wxFontInfo(12).Family(wxFONTFAMILY_MODERN).Underlined()
);
+// dc.SetFont(
wxFontInfo(12).Family(wxFONTFAMILY_MODERN).Underlined() );
+ dc.SetFont( wxFontInfo(12).FaceName("Courier").Underlined() );
dc.DrawText( wxT("This is text"), 110, 10 );
dc.DrawRotatedText( wxT("That is text"), 20, 10, -45 );

}}}

GDI+ works fine with it.

Thank you,
Andrey


Vadim Zeitlin

unread,
Sep 15, 2014, 11:57:55 AM9/15/14
to wx-...@googlegroups.com
On Mon, 15 Sep 2014 13:25:20 +0000 (UTC) Andrey Turkin wrote:

AT> The problem can be seen in drawing sample with this patch:
AT> {{{
AT> Index: drawing.cpp
AT> ===================================================================
AT> --- drawing.cpp (revision 77707)
AT> +++ drawing.cpp (working copy)
AT> @@ -816,7 +816,8 @@
AT> void MyCanvas::DrawText(wxDC& dc)
AT> {
AT> // set underlined font for testing
AT> - dc.SetFont( wxFontInfo(12).Family(wxFONTFAMILY_MODERN).Underlined()
AT> );
AT> +// dc.SetFont(
AT> wxFontInfo(12).Family(wxFONTFAMILY_MODERN).Underlined() );
AT> + dc.SetFont( wxFontInfo(12).FaceName("Courier").Underlined() );
AT> dc.DrawText( wxT("This is text"), 110, 10 );
AT> dc.DrawRotatedText( wxT("That is text"), 20, 10, -45 );
AT>
AT> }}}

If Trac still hates you, please open an issue for this at
https://github.com/alexpana/wxWidgets/issues, I'll probably move them all
to Trac later.

Of course, if you could please debug this, it would be even better...

TIA,
VZ

Andrey Turkin

unread,
Sep 15, 2014, 12:58:38 PM9/15/14
to wx-...@googlegroups.com
Vadim Zeitlin <vadim@...> writes:

> If Trac still hates you, please open an issue for this at
> https://github.com/alexpana/wxWidgets/issues, I'll probably move them
all
> to Trac later.
>
OK, I will do it.

> Of course, if you could please debug this, it would be even better...
Sorry, but i don't understand what exactly i could debug here :(
The main problems for me is
1)why IDWriteGdiInterop::CreateFontFromLOGFONT() can't create font (hr =
0x88985002, Indicates the specified font does not exist) and
2)what to do if it happens.
For 1) i don't see a way as it can be debugged (may be you know?)
That concerning 2) i have no ideas how to choose the best font for the set
font if that doesn't exist. Because from my point of view the only correct
action in this case - to pick up the closest font.

Thank you,
Andrey


Vadim Zeitlin

unread,
Sep 15, 2014, 1:20:15 PM9/15/14
to wx-...@googlegroups.com
On Mon, 15 Sep 2014 16:58:13 +0000 (UTC) Andrey Turkin wrote:

AT> > Of course, if you could please debug this, it would be even better...
AT> Sorry, but i don't understand what exactly i could debug here :(
AT> The main problems for me is
AT> 1)why IDWriteGdiInterop::CreateFontFromLOGFONT() can't create font (hr =
AT> 0x88985002, Indicates the specified font does not exist) and

This seems pretty obvious to me: DirectWrite probably doesn't support
using non-TrueType fonts like "Courier".

AT> 2)what to do if it happens.

Clearly we need to handle errors better, I just don't know where exactly.
I.e. failure of font creation shouldn't bring down the entire application.

AT> For 1) i don't see a way as it can be debugged (may be you know?)
AT> That concerning 2) i have no ideas how to choose the best font for the set
AT> font if that doesn't exist. Because from my point of view the only correct
AT> action in this case - to pick up the closest font.

I don't think it's a good idea because we're unlikely to be able to do it
correctly. Looking at the code, I think the right thing to do would be to
check if wxD2DFontData was initialized successfully and avoid using it,
i.e. avoid changing the font completely, if it was not.

Regards,
VZ

Andrey Turkin

unread,
Sep 15, 2014, 2:24:24 PM9/15/14
to wx-...@googlegroups.com
Vadim Zeitlin <vadim@...> writes:

>
> On Mon, 15 Sep 2014 16:58:13 +0000 (UTC) Andrey Turkin wrote:
>
> AT> > Of course, if you could please debug this, it would be even
better...
> AT> Sorry, but i don't understand what exactly i could debug here :(
> AT> The main problems for me is
> AT> 1)why IDWriteGdiInterop::CreateFontFromLOGFONT() can't create font
(hr =
> AT> 0x88985002, Indicates the specified font does not exist) and
>
> This seems pretty obvious to me: DirectWrite probably doesn't support
> using non-TrueType fonts like "Courier".
Well, i assumed it also, but it is not really productive conclusion.

> AT> 2)what to do if it happens.
>
> Clearly we need to handle errors better, I just don't know where
exactly.
> I.e. failure of font creation shouldn't bring down the entire
application.
>
> AT> For 1) i don't see a way as it can be debugged (may be you know?)
> AT> That concerning 2) i have no ideas how to choose the best font for
the set
> AT> font if that doesn't exist. Because from my point of view the only
correct
> AT> action in this case - to pick up the closest font.
>
> I don't think it's a good idea because we're unlikely to be able to
do it
> correctly. Looking at the code, I think the right thing to do would be
to
> check if wxD2DFontData was initialized successfully and avoid using
it,
> i.e. avoid changing the font completely, if it was not.
I don't sure about it. Let's imagine some layout with graphics, texts
with different fonts. The user decides to change a font for some element
and chooses "wrong font". What will occur? This element will just
disappear, what will be reaction of the user?
May be a better way to substitute "wrong" face name with any "standard"
(e.g. "Arial"), if CreateFontFromLOGFONT() returns fail?

Thank you,
Andrey

PS:
> If Trac still hates you, please open an issue for this at
> https://github.com/alexpana/wxWidgets/issues
Hmm... It requires login/password. What do I have to enter?
It doesn't accept my Trac login/password :(


Vadim Zeitlin

unread,
Sep 16, 2014, 7:30:49 AM9/16/14
to wx-...@googlegroups.com
On Mon, 15 Sep 2014 18:24:03 +0000 (UTC) Andrey Turkin wrote:

AT> > AT> For 1) i don't see a way as it can be debugged (may be you know?)
AT> > AT> That concerning 2) i have no ideas how to choose the best font
AT> > AT> for the set font if that doesn't exist. Because from my point of
AT> > AT> view the only correct action in this case - to pick up the
AT> > AT> closest font.
AT> >
AT> > I don't think it's a good idea because we're unlikely to be able to
AT> > do it correctly. Looking at the code, I think the right thing to do
AT> > would be to check if wxD2DFontData was initialized successfully and
AT> > avoid using it, i.e. avoid changing the font completely, if it was
AT> > not.
AT> I don't sure about it. Let's imagine some layout with graphics, texts
AT> with different fonts. The user decides to change a font for some element
AT> and chooses "wrong font". What will occur? This element will just
AT> disappear, what will be reaction of the user?

I think there must be some misunderstanding. The element won't disappear
at all, it will just be rendered with the default (i.e. the previous
selected) font.

AT> > If Trac still hates you, please open an issue for this at
AT> > https://github.com/alexpana/wxWidgets/issues
AT> Hmm... It requires login/password. What do I have to enter?
AT> It doesn't accept my Trac login/password :(

Sorry, I honestly didn't realize there could be still be people without a
Gibhub account. You do need to create an account there to submit issues,
this web site is completely unrelated to wxWidgets (we just use it, too),
so Trac credentials won't work there.

Regards,
VZ

Andrey Turkin

unread,
Sep 16, 2014, 8:37:45 AM9/16/14
to wx-...@googlegroups.com
Vadim Zeitlin <vadim@...> writes:

> I think there must be some misunderstanding. The element won't disappear
> at all, it will just be rendered with the default (i.e. the previous
> selected) font.
Sorry, but i don'understand what way it could happen.
What is "previous font"?
There are many possible scenarios for arising this problem. E.g., it is
possible not to change at all fonts, just to switch over on direct2d from
other renderer (and "the bad font" already was there). What in this case will
be the previous font? Or we are constructing our layout from scratch, using
some saved settings (including wrong fonts).
What way it is possible to discover the "previous font" at all (i mean on
direct2d level)? Or i miss something?

> Sorry, I honestly didn't realize there could be still be people without a
> Gibhub account. You do need to create an account there to submit issues,
> this web site is completely unrelated to wxWidgets (we just use it, too),
> so Trac credentials won't work there.
Thank you, i will try that.

Andrey





Vadim Zeitlin

unread,
Sep 16, 2014, 8:39:59 AM9/16/14
to wx-...@googlegroups.com
On Tue, 16 Sep 2014 12:37:28 +0000 (UTC) Andrey Turkin wrote:

AT> What is "previous font"?

The font being currently used by wxGraphicsContext. It always uses some
font, right? I.e. if you don't call SetFont() some default font is used, if
you do call it, the font passed to SetFont() is used. Calling SetFont()
with a font which can't be used with Direct2D should just do nothing, i.e.
return an error and continue using the same font as before.

This seems pretty simple to me, but perhaps I'm missing something?
VZ

Andrey Turkin

unread,
Sep 16, 2014, 9:06:42 AM9/16/14
to wx-...@googlegroups.com
Vadim Zeitlin <vadim@...> writes:

>
> On Tue, 16 Sep 2014 12:37:28 +0000 (UTC) Andrey Turkin wrote:
>
> AT> What is "previous font"?
>
> The font being currently used by wxGraphicsContext. It always uses some
> font, right? I.e. if you don't call SetFont() some default font is used, if
> you do call it, the font passed to SetFont() is used. Calling SetFont()
> with a font which can't be used with Direct2D should just do nothing, i.e.
> return an error and continue using the same font as before.
OK, i see your point :)
But one moment. Let's imagine that the current(last used) font was a huge font
for heading, and right after it we want a small font for any note. How much it
will be correct?
As I already wrote, it is desirable to use the correct font the closest to the
requested. May be better only change for this purpose the facename of a
required font (leaving its other attributes - the size, underlining, etc.)?

Andrey

Vadim Zeitlin

unread,
Sep 16, 2014, 9:10:36 AM9/16/14
to wx-...@googlegroups.com
On Tue, 16 Sep 2014 13:06:26 +0000 (UTC) Andrey Turkin wrote:

AT> But one moment. Let's imagine that the current(last used) font was a huge font
AT> for heading, and right after it we want a small font for any note. How much it
AT> will be correct?
AT> As I already wrote, it is desirable to use the correct font the closest to the
AT> requested. May be better only change for this purpose the facename of a
AT> required font (leaving its other attributes - the size, underlining, etc.)?

This is the general problem of font matching and it's complicated. If you
preserve the size but not the face, someone will ask for fallback mechanism
for the face names too anyhow. So I'd rather keep things simple and state
upfront that we don't do any font matching at all.

The only real solution is to not use non-TrueType fonts with Direct2D and
it's really not that difficult and should be done to completely avoid the
problem instead of complicating our code trying to deal with it.

Regards,
VZ

Andrey Turkin

unread,
Sep 16, 2014, 10:38:31 AM9/16/14
to wx-...@googlegroups.com
Vadim Zeitlin <vadim@...> writes:

> This is the general problem of font matching and it's complicated. If
you
> preserve the size but not the face, someone will ask for fallback
mechanism
> for the face names too anyhow. So I'd rather keep things simple and
state
> upfront that we don't do any font matching at all.
I see that too :(

> The only real solution is to not use non-TrueType fonts with Direct2D
and
> it's really not that difficult and should be done to completely avoid
the
> problem instead of complicating our code trying to deal with it.
It is clear, but there is a couple problems
1. There are too many users of my software who have wrong fonts settings
by now.
2. What way to prevent a choice the user not TrueType font?

Both problems are easily solved, whether if there is a way to define is
the wxFont TrueType is or not. Could you give a hint such way?

Thank you,
Andrey

Vadim Zeitlin

unread,
Sep 16, 2014, 10:45:42 AM9/16/14
to wx-...@googlegroups.com
On Tue, 16 Sep 2014 14:38:16 +0000 (UTC) Andrey Turkin wrote:

AT> Both problems are easily solved, whether if there is a way to define is
AT> the wxFont TrueType is or not. Could you give a hint such way?

I'm not sure. I think LOGFONT::lfOutPrecision could be used for this, see
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037.aspx

But perhaps the best would be to add a method testing for this explicitly,
e.g. wxGraphicsContext::IsFontSupported(wxFont). It could return true by
default but would be overridden in wxGraphicsContextD2D to do the same
thing as wxGetD2DFontData ctor does (of course, this code would need to be
refactored to avoid duplicating it).

Regards,
VZ

Andrey Turkin

unread,
Sep 17, 2014, 5:05:20 AM9/17/14
to wx-...@googlegroups.com
Vadim, i opened an issue for this at
https://github.com/alexpana/wxWidgets/issues

I tried to make a patch for this purpose.
The patch handled the font creation error (with assert in debug), and with
that it is already possible to live :)
But if it is desirable to implement in addition your idea about adding of a
new method to wxGraphicsContext, I could add also it as code refactoring is
already made in this patch.

{{{
Index: src/common/graphcmn.cpp
===================================================================
--- src/common/graphcmn.cpp (revision 77707)
+++ src/common/graphcmn.cpp (working copy)
@@ -621,7 +621,12 @@
void wxGraphicsContext::SetFont( const wxFont& font, const wxColour& colour
)
{
if ( font.IsOk() )
- SetFont( CreateFont( font, colour ) );
+ {
+ wxGraphicsFont &gfont = CreateFont( font, colour );
+ wxASSERT_MSG(gfont.GetRefData() != 0, wxT("Font isn't
supported!"));
+ if( gfont.GetRefData() )
+ SetFont( gfont );
+ }
else
SetFont( wxNullGraphicsFont );
}
Index: src/msw/graphicsd2d.cpp
===================================================================
--- src/msw/graphicsd2d.cpp (revision 77707)
+++ src/msw/graphicsd2d.cpp (working copy)
@@ -2063,6 +2063,8 @@

wxCOMPtr<IDWriteFont> GetFont() { return m_font; };

+ static bool CreateFontFromwxFont(const wxFont& font, IDWriteFont**
d2dfont=0);
+
private:
// The native, device-independent font object
wxCOMPtr<IDWriteFont> m_font;
@@ -2078,12 +2080,11 @@
bool m_strikethrough;
};

-wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, ID2D1Factory*
d2dFactory, const wxFont& font, const wxColor& color) :
- wxGraphicsObjectRefData(renderer), m_brushData(renderer,
wxBrush(color)),
- m_underlined(font.GetUnderlined()),
m_strikethrough(font.GetStrikethrough())
+bool wxD2DFontData::CreateFontFromwxFont(const wxFont& font, IDWriteFont**
pd2dfont)
{
HRESULT hr;

+ wxCOMPtr<IDWriteFont> d2dfont;
wxCOMPtr<IDWriteGdiInterop> gdiInterop;
hr = wxDWriteFactory()->GetGdiInterop(&gdiInterop);

@@ -2098,9 +2099,24 @@
logfont.lfFaceName[i] = font.GetFaceName().GetChar(i);
}
}
+ hr = gdiInterop->CreateFontFromLOGFONT(&logfont, &d2dfont);
+ if ( pd2dfont )
+ {
+ if ( d2dfont ) d2dfont->AddRef();
+ *pd2dfont = d2dfont;
+ }
+ return d2dfont != 0;
+}

- hr = gdiInterop->CreateFontFromLOGFONT(&logfont, &m_font);
+wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, ID2D1Factory*
d2dFactory, const wxFont& font, const wxColor& color) :
+ wxGraphicsObjectRefData(renderer), m_font(0), m_brushData(renderer,
wxBrush(color)),
+ m_underlined(font.GetUnderlined()),
m_strikethrough(font.GetStrikethrough())
+{
+ HRESULT hr;

+ if ( !CreateFontFromwxFont(font, &m_font) )
+ return; // Font isn't supported
+
wxCOMPtr<IDWriteFontFamily> fontFamily;
m_font->GetFontFamily(&fontFamily);

@@ -3666,7 +3682,9 @@
wxD2DFontData* fontData = new wxD2DFontData(this, GetD2DFactory(),
font, col);

wxGraphicsFont graphicsFont;
- graphicsFont.SetRefData(fontData);
+ if ( !fontData->GetFont() ) // Fail
+ wxDELETE(fontData);
+ graphicsFont.SetRefData(fontData); // 0 if it fails

return graphicsFont;
}
}}}

Thank you,
Andrey

Vadim Zeitlin

unread,
Sep 17, 2014, 6:23:36 AM9/17/14
to wx-...@googlegroups.com
On Wed, 17 Sep 2014 09:05:06 +0000 (UTC) Andrey Turkin wrote:

AT> Vadim, i opened an issue for this at
AT> https://github.com/alexpana/wxWidgets/issues
AT>
AT> I tried to make a patch for this purpose.

Thanks!

AT> But if it is desirable to implement in addition your idea about adding of a
AT> new method to wxGraphicsContext,

I think it could be useful.

AT> I could add also it as code refactoring is
AT> already made in this patch.
AT>
AT> {{{
AT> Index: src/common/graphcmn.cpp
AT> ===================================================================
AT> --- src/common/graphcmn.cpp (revision 77707)
AT> +++ src/common/graphcmn.cpp (working copy)
AT> @@ -621,7 +621,12 @@
AT> void wxGraphicsContext::SetFont( const wxFont& font, const wxColour& colour
AT> )
AT> {
AT> if ( font.IsOk() )
AT> - SetFont( CreateFont( font, colour ) );
AT> + {
AT> + wxGraphicsFont &gfont = CreateFont( font, colour );

I don't understand how does this compile. You're binding a non-const
reference to a temporary object here, this really can't work.

AT> + static bool CreateFontFromwxFont(const wxFont& font, IDWriteFont** d2dfont=0);

This is a bit unreadable, perhaps CreateFromGDIFont() might be better?

AT> + wxCOMPtr<IDWriteFont> d2dfont;
AT> wxCOMPtr<IDWriteGdiInterop> gdiInterop;
AT> hr = wxDWriteFactory()->GetGdiInterop(&gdiInterop);
AT>
AT> @@ -2098,9 +2099,24 @@
AT> logfont.lfFaceName[i] = font.GetFaceName().GetChar(i);
AT> }
AT> }
AT> + hr = gdiInterop->CreateFontFromLOGFONT(&logfont, &d2dfont);
AT> + if ( pd2dfont )
AT> + {
AT> + if ( d2dfont ) d2dfont->AddRef();
AT> + *pd2dfont = d2dfont;
AT> + }

It would be even nicer to avoid dealing with references completely and
just return wxCOMPtr<IDWriteFont> from this function instead of taking
IDWriteFont** parameter.

TIA,
VZ

Andrey Turkin

unread,
Sep 17, 2014, 7:49:58 AM9/17/14
to wx-...@googlegroups.com
Vadim Zeitlin <vadim@...> writes:

> AT> But if it is desirable to implement in addition your idea about adding
of a
> AT> new method to wxGraphicsContext,
>
> I think it could be useful.
OK, I will try to implement it.

> AT> + wxGraphicsFont &gfont = CreateFont( font, colour );
>
> I don't understand how does this compile. You're binding a non-const
> reference to a temporary object here, this really can't work.
Sorry, i overlooked it :( VC (2010) just warning about it, as nonstandard
extention :(

> AT> + static bool CreateFontFromwxFont(const wxFont& font, IDWriteFont**
d2dfont=0);
>
> This is a bit unreadable, perhaps CreateFromGDIFont() might be better?
Yes, it is certain better

> It would be even nicer to avoid dealing with references completely and
> just return wxCOMPtr<IDWriteFont> from this function instead of taking
> IDWriteFont** parameter.
I will look at it.

Many hanks for your notes, it was really useful
Andrey


Andrey Turkin

unread,
Sep 17, 2014, 9:23:04 AM9/17/14
to wx-...@googlegroups.com
Vadim Zeitlin <vadim@...> writes:

New version of the patch
{{{
Index: src/common/graphcmn.cpp
===================================================================
--- src/common/graphcmn.cpp (revision 77707)
+++ src/common/graphcmn.cpp (working copy)
@@ -621,7 +621,12 @@
void wxGraphicsContext::SetFont( const wxFont& font, const wxColour& colour
)
{
if ( font.IsOk() )
- SetFont( CreateFont( font, colour ) );
+ {
+ const wxGraphicsFont &gfont = CreateFont( font, colour );
+ wxASSERT_MSG(gfont.GetRefData() != 0, wxT("Font isn't
supported!"));
+ if( gfont.GetRefData() )
+ SetFont( gfont );
+ }
else
SetFont( wxNullGraphicsFont );
}
Index: src/msw/graphicsd2d.cpp
===================================================================
--- src/msw/graphicsd2d.cpp (revision 77707)
+++ src/msw/graphicsd2d.cpp (working copy)
@@ -2063,6 +2063,8 @@

wxCOMPtr<IDWriteFont> GetFont() { return m_font; };

+ static bool CreateFontFromGDIFont(const wxFont& font,
wxCOMPtr<IDWriteFont>* d2dfont=0);
+
private:
// The native, device-independent font object
wxCOMPtr<IDWriteFont> m_font;
@@ -2078,12 +2080,11 @@
bool m_strikethrough;
};

-wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, ID2D1Factory*
d2dFactory, const wxFont& font, const wxColor& color) :
- wxGraphicsObjectRefData(renderer), m_brushData(renderer,
wxBrush(color)),
- m_underlined(font.GetUnderlined()),
m_strikethrough(font.GetStrikethrough())
+bool wxD2DFontData::CreateFontFromGDIFont(const wxFont& font,
wxCOMPtr<IDWriteFont>* pd2dfont)
{
HRESULT hr;

+ wxCOMPtr<IDWriteFont> d2dfont;
wxCOMPtr<IDWriteGdiInterop> gdiInterop;
hr = wxDWriteFactory()->GetGdiInterop(&gdiInterop);

@@ -2098,9 +2099,23 @@
logfont.lfFaceName[i] = font.GetFaceName().GetChar(i);
}
}
+ hr = gdiInterop->CreateFontFromLOGFONT(&logfont, &d2dfont);
+ if ( pd2dfont )
+ {
+ *pd2dfont = d2dfont;
+ }
+ return d2dfont != 0;
+}

- hr = gdiInterop->CreateFontFromLOGFONT(&logfont, &m_font);
+wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, ID2D1Factory*
d2dFactory, const wxFont& font, const wxColor& color) :
+ wxGraphicsObjectRefData(renderer), m_font(0), m_brushData(renderer,
wxBrush(color)),
+ m_underlined(font.GetUnderlined()),
m_strikethrough(font.GetStrikethrough())
+{
+ HRESULT hr;

+ if ( !CreateFontFromGDIFont(font,
reinterpret_cast<wxCOMPtr<IDWriteFont>*>(&m_font)) )
+ return; // Font isn't supported
+
wxCOMPtr<IDWriteFontFamily> fontFamily;
m_font->GetFontFamily(&fontFamily);

@@ -3666,7 +3681,9 @@
wxD2DFontData* fontData = new wxD2DFontData(this, GetD2DFactory(),
font, col);

wxGraphicsFont graphicsFont;
- graphicsFont.SetRefData(fontData);
+ if ( !fontData->GetFont() ) // Fail
+ wxDELETE(fontData);
+ graphicsFont.SetRefData(fontData); // 0 if it fails

return graphicsFont;
}
}}}
BTW, CreateFontFromGDIFont certainly nicer, but not quite correct by sense.

And using wxCOMPtr requires ugly reinterpret_cast. May be you know better
way?

Andrey


Vadim Zeitlin

unread,
Sep 17, 2014, 8:12:02 PM9/17/14
to wx-...@googlegroups.com
On Wed, 17 Sep 2014 13:22:46 +0000 (UTC) Andrey Turkin wrote:

AT> Vadim Zeitlin <vadim@...> writes:
AT>
AT> New version of the patch

It's really problematic to get patches via email like this, this one got
all wrapped and I can't even apply it automatically (i.e. without editing
it manually). If you still can't login into Trac, perhaps you could make a
Github PR (exceptionally, usually we ask people to use Trac, but this just
doesn't seem to be an option in your case...)?

AT> +wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, ID2D1Factory*
AT> d2dFactory, const wxFont& font, const wxColor& color) :
AT> + wxGraphicsObjectRefData(renderer), m_font(0), m_brushData(renderer,
AT> wxBrush(color)),
AT> + m_underlined(font.GetUnderlined()),
AT> m_strikethrough(font.GetStrikethrough())
AT> +{
AT> + HRESULT hr;
AT>
AT> + if ( !CreateFontFromGDIFont(font,
AT> reinterpret_cast<wxCOMPtr<IDWriteFont>*>(&m_font)) )

Sorry, why is this needed exactly? The type of m_font seems to already be
exactly wxCOMPtr<IDWriteFont>, isn't it?

VZ

Andrey Turkin

unread,
Sep 17, 2014, 11:00:35 PM9/17/14
to wx-...@googlegroups.com
It is, but wxCOMPtr has overloaded operator &
BTW, this variant I also thought to use initially, but reinterpret_cast
wasn't pleasant to me more, than using of IDWriteFont directly.

Andrey

Vadim Zeitlin

unread,
Sep 18, 2014, 7:44:02 AM9/18/14
to wx-...@googlegroups.com
On Thu, 18 Sep 2014 03:00:17 +0000 (UTC) Andrey Turkin wrote:

AT> Vadim Zeitlin <vadim@...> writes:
AT>
AT> > AT> + if ( !CreateFontFromGDIFont(font,
AT> > AT> reinterpret_cast<wxCOMPtr<IDWriteFont>*>(&m_font)) )
AT> >
AT> > Sorry, why is this needed exactly? The type of m_font seems to already
AT> be
AT> > exactly wxCOMPtr<IDWriteFont>, isn't it?
AT> It is, but wxCOMPtr has overloaded operator &

I see, thanks. Why not just pass it by reference instead? It's pretty
obvious that it is the output of the function. Alternative could be to
return it from the function.

Regards,
VZ

Andrey Turkin

unread,
Sep 18, 2014, 8:11:44 AM9/18/14
to wx-...@googlegroups.com
Vadim Zeitlin <vadim@...> writes:

> I see, thanks. Why not just pass it by reference instead? It's pretty
> obvious that it is the output of the function. Alternative could be to
> return it from the function.
I just assumed to use also this function for font checking like this:
{{{
wxGraphicsD2D::IsFontSupported(const wxFont& font)
{
return wxD2DFontData::CreateFontFromGDIFont(font);
}
}}}
In this case the font isn't needed, then the second argument by default is 0
It is possible such using isn't obvious by name of this function, but i
thought it is mostly private interface and it is not so important here.

Andrey

Vadim Zeitlin

unread,
Sep 18, 2014, 8:22:07 AM9/18/14
to wx-...@googlegroups.com
On Thu, 18 Sep 2014 12:11:31 +0000 (UTC) Andrey Turkin wrote:

AT> Vadim Zeitlin <vadim@...> writes:
AT>
AT> > I see, thanks. Why not just pass it by reference instead? It's pretty
AT> > obvious that it is the output of the function. Alternative could be to
AT> > return it from the function.
AT> I just assumed to use also this function for font checking like this:
AT> {{{
AT> wxGraphicsD2D::IsFontSupported(const wxFont& font)
AT> {
AT> return wxD2DFontData::CreateFontFromGDIFont(font);
AT> }
AT> }}}
AT> In this case the font isn't needed, then the second argument by default is 0

We could pass it by reference to CreateFontFromGDIFont() itself and then
have

bool
wxGraphicsD2D::IsFontSupported(const wxFont& font) const
{
wxD2DFontData dummy;
return wxD2DFontData::CreateFontFromGDIFont(font, dummy);
}

Regards,
VZ

Andrey Turkin

unread,
Sep 18, 2014, 8:48:40 AM9/18/14
to wx-...@googlegroups.com
Vadim Zeitlin <vadim@...> writes:

> We could pass it by reference to CreateFontFromGDIFont() itself and then
> have
>
> bool
> wxGraphicsD2D::IsFontSupported(const wxFont& font) const
> {
> wxD2DFontData dummy;
> return wxD2DFontData::CreateFontFromGDIFont(font, dummy);
> }
It is possible of course, it seemed to me nicely. This matter of taste.
And it is little more optimal i think ;)
Generally, it has no essential value, you can make as you it is pleasant more

Andrey



Reply all
Reply to author
Forward
0 new messages