0

I'm not used to CreateFontA, but I'm doing a mod for a game that uses this function and I have to use it too.

I managed to change the font, but I'm having some trouble to change font size.

I want to use font size 11px, how can I achieve this? I tried just setting width and height to 11 but it went terrible wrong.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
user1913644
  • 157
  • 1
  • 11
  • 2
    The standard C++ language has no facilities for font creation; it is OS or platform dependent. Please edit your post with the GUI framework or OS that you are using. – Thomas Matthews Aug 29 '18 at 20:44
  • Also, edit your post with [mcve], in which you create and use the font. – Thomas Matthews Aug 29 '18 at 20:46
  • CreateFontA is a Win32 function. – cHao Aug 29 '18 at 20:49
  • Come on guys this is a decent question. I tried to answer and realized I forgot how to do it. – Joshua Aug 29 '18 at 20:54
  • 3
    Start by reading the [documentation](https://learn.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-createfonta). The Height and Width are expressed in **logical units**, not in **pixels**. You have to calculate the units yourself. The documentation tells you how. – Remy Lebeau Aug 29 '18 at 20:56
  • 1
    Damn, sorry for asking something that I genuinly didn't know.. I guess it was a dumb question. I obviously saw the documentation, and I asked here because I didn't understand how this units worked. – user1913644 Aug 29 '18 at 21:01
  • @RemyLebeau Which units are supposed to be used to specify `PointSize` in this context? – user7860670 Aug 29 '18 at 21:02
  • Side note: This is one area in which MFC honestly did make a useful contribution. Even though the difference isn't huge, `CreatePointFont` is quite a bit easier to use. – Jerry Coffin Aug 29 '18 at 21:07

1 Answers1

6

The answer is (or at least can be) somewhat non-trivial.

First of all, there are two separate heights you can choose from: the height of the characters themselves, or the height of cell in which a "normal" character lives (but, for example, letters with descenders like y will usually extend outside the cell). So, for the same size of font, the character cell will usually be slightly larger than the size of the characters themselves.

To choose the font based on the character cell height, you pass a positive number for the height. To choose based on the height of the characters themselves, you pass a negative number (and its absolute value will be used as the height).

So let's assume that you want the characters themselves to be 11 points tall (so we'll need to pass a negative number for the height), and that you want the width to be the default for the font at hand. Let's also assume that you're dealing with MM_TEXT mode, where a logical unit is equal to one pixel.

As Windows uses the term, one point is 1/72nd of an inch (note: 72 points to the inch isn't universal--for example, some use 72.72 points to the inch instead--feel free to modify the following code if you need to comply with a different definition of a "point").

So, to compute the size, we can start by retrieving the number of pixels per inch (vertically) on the screen, then compute the number of pixels for the right number of points:

static const int points_per_inch = 72;
int pixels_per_inch = GetDeviceCaps(hDC, LOGPIXELSY);
int pixels_height = - (points * pixels_per_inch / points_per_inch);

[Microsoft has a MulDiv function to assure against an intermediate value overflowing in that computation, but unless you're using a 16-bit machine or a truly immense font, that's mostly a solution in search of a problem.]

Since we want the default width, we'll pass 0 for the width.

So, we end up with something like this:

HFONT font = CreateFont(pixels_height, 0, // size
                        0, 0, 0, // normal orientation
                        FW_NORMAL,   // normal weight--e.g., bold would be FW_BOLD
                        false, false, false, // not italic, underlined or strike out
                        DEFAULT_CHARSET,
                        OUT_OUTLINE_PRECIS, // select only outline (not bitmap) fonts
                        CLIP_DEFAULT_PRECIS,
                        CLEARTYPE_QUALITY,
                        VARIABLE_PITCH | FF_SWISS,
                        "Arial");
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Also see [DPI and Device-Independent Pixels](https://learn.microsoft.com/en-us/windows/desktop/learnwin32/dpi-and-device-independent-pixels) for a detailed explanation of units and pixels in different screen resolutions (72 PPI is not the only possibility) – Remy Lebeau Aug 29 '18 at 21:55
  • You are thinking of the traditional value of 96 pixels per inch, not the 72 points per inch. The former varies but as MS uses the term the latter does not. – SoronelHaetir Aug 30 '18 at 01:10