win32 bug when using HFONT with appropriate size

Submitted by Fred Beca on April 5, 2016, 11:03 a.m.

Details

Message ID CAKTSDKZBc+z-D31qEOV9f7rC1qvqj4nFnitg=KDXt9DBjvLu3Q@mail.gmail.com
State New
Headers show
Series "win32 bug when using HFONT with appropriate size" ( rev: 1 ) in Cairo

Not browsing as part of any series.

Commit Message

Fred Beca April 5, 2016, 11:03 a.m.
I have noticed a bug in the win32 font backend. When setting the font on a
win32 surface with the code below and using the same size as the original
HFONT for drawing, the resulting font size is extremely small (text is
almost invisible).

// assuming my_hfont was created with -12 for LOGFONT.lfHeight
cairo_font_face_t*
font_face=cairo_win32_font_face_create_for_hfont(my_hfont);
cairo_set_font_face(ctx,font_face);
cairo_set_font_size(ctx,12);

The reason is that in _cairo_win32_font_face_scaled_font_create, the font
matrix is checked against -font_face->logfont.lfHeight whereas if you look
in _win32_scaled_font_get_scaled_hfont, the expected height should be
multiplied by WIN32_FONT_LOGICAL_SCALE (scaled HFONT created by cairo uses
logfont.lfHeight = -scaled_font->logical_size)

This means that using anything else than 1 for WIN32_FONT_LOGICAL_SCALE as
shown in the patch below will result in a downscaled font when using a
HFONT that was created with the right size.

However, if the check mentioned above is fixed, in order to have cairo use
the original HFONT, it should be created with a much larger size
(-WIN32_FONT_LOGICAL_SCALE*size). So this defeats the purpose of being able
to mix native win32 fonts with cairo because of this scaling factor (mixing
native and cairo code would require extra scaling everywhere).

So here is my question: is the scaling applied with
WIN32_FONT_LOGICAL_SCALE still useful? From what I have been able to
experience so far, setting it to 1 makes no difference, even with very
small fonts. And it seems this is actually used by many others.

Patch hide | download patch | download mbox

Index: cairo-win32-private.h
===================================================================
--- cairo-win32-private.h (cairo-1.14.6)
+++ cairo-win32-private.h (working copy)
@@ -51,7 +51,7 @@ 
 #define SB_NONE 0
 #endif

-#define WIN32_FONT_LOGICAL_SCALE 32
+#define ç 1

 /* Surface DC flag values */
 enum {

Comments

On 05/04/16 20:33, Fred Beca wrote:
> I have noticed a bug in the win32 font backend. When setting the font on
> a win32 surface with the code below and using the same size as the
> original HFONT for drawing, the resulting font size is extremely small
> (text is almost invisible).
> 
> // assuming my_hfont was created with -12 for LOGFONT.lfHeight
> cairo_font_face_t*
> font_face=cairo_win32_font_face_create_for_hfont(my_hfont);
> cairo_set_font_face(ctx,font_face);
> cairo_set_font_size(ctx,12);
> 
> The reason is that in _cairo_win32_font_face_scaled_font_create, the
> font matrix is checked against -font_face->logfont.lfHeight whereas if
> you look in _win32_scaled_font_get_scaled_hfont, the expected height
> should be multiplied by WIN32_FONT_LOGICAL_SCALE (scaled HFONT created
> by cairo uses logfont.lfHeight = -scaled_font->logical_size)
> 
> This means that using anything else than 1 for WIN32_FONT_LOGICAL_SCALE
> as shown in the patch below will result in a downscaled font when using
> a HFONT that was created with the right size.
> 
> However, if the check mentioned above is fixed, in order to have cairo
> use the original HFONT, it should be created with a much larger size
> (-WIN32_FONT_LOGICAL_SCALE*size). So this defeats the purpose of being
> able to mix native win32 fonts with cairo because of this scaling factor
> (mixing native and cairo code would require extra scaling everywhere).
> 
> So here is my question: is the scaling applied with
> WIN32_FONT_LOGICAL_SCALE still useful? From what I have been able to
> experience so far, setting it to 1 makes no difference, even with very
> small fonts. And it seems this is actually used by many others.

There were a couple of threads were the usefulness of
WIN32_FONT_LOGICAL_SCALE was discussed:

https://lists.freedesktop.org/archives/cairo/2007-January/009288.html
https://lists.freedesktop.org/archives/cairo/2007-February/009661.html

I don't think removing the logical scale is a good idea. We will need to
find a solution to make cairo_win32_font_face_create_for_hfont() work.

I suggest creating a bug and linking it to the 1.16 tracker (bug 84197).
I'll look at it next time I am working on the windows backend.

> 
> Index: cairo-win32-private.h
> ===================================================================
> --- cairo-win32-private.h(cairo-1.14.6)
> +++ cairo-win32-private.h(working copy)
> @@ -51,7 +51,7 @@
>  #define SB_NONE 0
>  #endif
>  
> -#define WIN32_FONT_LOGICAL_SCALE 32
> +#define ç 1
>  
>  /* Surface DC flag values */
>  enum {
> 
> 
>
Thanks for the details. If I understand well then, the code has
changed at some point, and the issue is the fact the logical scale
factor is used when creating the scaled hfont, instead of being used
in the WorldTransform.

See scaled font creation here:
static cairo_status_t
_win32_scaled_font_get_scaled_hfont (cairo_win32_scaled_font_t *scaled_font,
    HFONT *hfont_out)
{
    if (!scaled_font->scaled_hfont) {
LOGFONTW logfont = scaled_font->logfont;
logfont.lfHeight = -scaled_font->logical_size; ///< using the logicak
size to create the font

I guess this may also cause other problems if the font cannot be
created with such a large scale.

I will create a bug as suggested and will continue my investigations.

On Wed, Apr 6, 2016 at 12:40 AM, Adrian Johnson <ajohnson@redneon.com> wrote:
>
> On 05/04/16 20:33, Fred Beca wrote:
> > I have noticed a bug in the win32 font backend. When setting the font on
> > a win32 surface with the code below and using the same size as the
> > original HFONT for drawing, the resulting font size is extremely small
> > (text is almost invisible).
> >
> > // assuming my_hfont was created with -12 for LOGFONT.lfHeight
> > cairo_font_face_t*
> > font_face=cairo_win32_font_face_create_for_hfont(my_hfont);
> > cairo_set_font_face(ctx,font_face);
> > cairo_set_font_size(ctx,12);
> >
> > The reason is that in _cairo_win32_font_face_scaled_font_create, the
> > font matrix is checked against -font_face->logfont.lfHeight whereas if
> > you look in _win32_scaled_font_get_scaled_hfont, the expected height
> > should be multiplied by WIN32_FONT_LOGICAL_SCALE (scaled HFONT created
> > by cairo uses logfont.lfHeight = -scaled_font->logical_size)
> >
> > This means that using anything else than 1 for WIN32_FONT_LOGICAL_SCALE
> > as shown in the patch below will result in a downscaled font when using
> > a HFONT that was created with the right size.
> >
> > However, if the check mentioned above is fixed, in order to have cairo
> > use the original HFONT, it should be created with a much larger size
> > (-WIN32_FONT_LOGICAL_SCALE*size). So this defeats the purpose of being
> > able to mix native win32 fonts with cairo because of this scaling factor
> > (mixing native and cairo code would require extra scaling everywhere).
> >
> > So here is my question: is the scaling applied with
> > WIN32_FONT_LOGICAL_SCALE still useful? From what I have been able to
> > experience so far, setting it to 1 makes no difference, even with very
> > small fonts. And it seems this is actually used by many others.
>
> There were a couple of threads were the usefulness of
> WIN32_FONT_LOGICAL_SCALE was discussed:
>
> https://lists.freedesktop.org/archives/cairo/2007-January/009288.html
> https://lists.freedesktop.org/archives/cairo/2007-February/009661.html
>
> I don't think removing the logical scale is a good idea. We will need to
> find a solution to make cairo_win32_font_face_create_for_hfont() work.
>
> I suggest creating a bug and linking it to the 1.16 tracker (bug 84197).
> I'll look at it next time I am working on the windows backend.
>
> >
> > Index: cairo-win32-private.h
> > ===================================================================
> > --- cairo-win32-private.h(cairo-1.14.6)
> > +++ cairo-win32-private.h(working copy)
> > @@ -51,7 +51,7 @@
> >  #define SB_NONE 0
> >  #endif
> >
> > -#define WIN32_FONT_LOGICAL_SCALE 32
> > +#define ç 1
> >
> >  /* Surface DC flag values */
> >  enum {
> >
> >
> >
>
This topic is now covered by bug #94836

https://bugs.freedesktop.org/show_bug.cgi?id=94836

On Wed, Apr 6, 2016 at 10:13 AM, Fred Beca <fredbca21@gmail.com> wrote:
> Thanks for the details. If I understand well then, the code has
> changed at some point, and the issue is the fact the logical scale
> factor is used when creating the scaled hfont, instead of being used
> in the WorldTransform.
>
> See scaled font creation here:
> static cairo_status_t
> _win32_scaled_font_get_scaled_hfont (cairo_win32_scaled_font_t *scaled_font,
>     HFONT *hfont_out)
> {
>     if (!scaled_font->scaled_hfont) {
> LOGFONTW logfont = scaled_font->logfont;
> logfont.lfHeight = -scaled_font->logical_size; ///< using the logicak
> size to create the font
>
> I guess this may also cause other problems if the font cannot be
> created with such a large scale.
>
> I will create a bug as suggested and will continue my investigations.
>
> On Wed, Apr 6, 2016 at 12:40 AM, Adrian Johnson <ajohnson@redneon.com> wrote:
>>
>> On 05/04/16 20:33, Fred Beca wrote:
>> > I have noticed a bug in the win32 font backend. When setting the font on
>> > a win32 surface with the code below and using the same size as the
>> > original HFONT for drawing, the resulting font size is extremely small
>> > (text is almost invisible).
>> >
>> > // assuming my_hfont was created with -12 for LOGFONT.lfHeight
>> > cairo_font_face_t*
>> > font_face=cairo_win32_font_face_create_for_hfont(my_hfont);
>> > cairo_set_font_face(ctx,font_face);
>> > cairo_set_font_size(ctx,12);
>> >
>> > The reason is that in _cairo_win32_font_face_scaled_font_create, the
>> > font matrix is checked against -font_face->logfont.lfHeight whereas if
>> > you look in _win32_scaled_font_get_scaled_hfont, the expected height
>> > should be multiplied by WIN32_FONT_LOGICAL_SCALE (scaled HFONT created
>> > by cairo uses logfont.lfHeight = -scaled_font->logical_size)
>> >
>> > This means that using anything else than 1 for WIN32_FONT_LOGICAL_SCALE
>> > as shown in the patch below will result in a downscaled font when using
>> > a HFONT that was created with the right size.
>> >
>> > However, if the check mentioned above is fixed, in order to have cairo
>> > use the original HFONT, it should be created with a much larger size
>> > (-WIN32_FONT_LOGICAL_SCALE*size). So this defeats the purpose of being
>> > able to mix native win32 fonts with cairo because of this scaling factor
>> > (mixing native and cairo code would require extra scaling everywhere).
>> >
>> > So here is my question: is the scaling applied with
>> > WIN32_FONT_LOGICAL_SCALE still useful? From what I have been able to
>> > experience so far, setting it to 1 makes no difference, even with very
>> > small fonts. And it seems this is actually used by many others.
>>
>> There were a couple of threads were the usefulness of
>> WIN32_FONT_LOGICAL_SCALE was discussed:
>>
>> https://lists.freedesktop.org/archives/cairo/2007-January/009288.html
>> https://lists.freedesktop.org/archives/cairo/2007-February/009661.html
>>
>> I don't think removing the logical scale is a good idea. We will need to
>> find a solution to make cairo_win32_font_face_create_for_hfont() work.
>>
>> I suggest creating a bug and linking it to the 1.16 tracker (bug 84197).
>> I'll look at it next time I am working on the windows backend.
>>
>> >
>> > Index: cairo-win32-private.h
>> > ===================================================================
>> > --- cairo-win32-private.h(cairo-1.14.6)
>> > +++ cairo-win32-private.h(working copy)
>> > @@ -51,7 +51,7 @@
>> >  #define SB_NONE 0
>> >  #endif
>> >
>> > -#define WIN32_FONT_LOGICAL_SCALE 32
>> > +#define ç 1
>> >
>> >  /* Surface DC flag values */
>> >  enum {
>> >
>> >
>> >
>>