1

When I try to get the count of fonts in a font family by using DirectWrite, I get the wrong result. For example, when I look at the system font folder, Arial font family has 9 fonts but, GetFontCount returns 14. What is that surplus number 5? How that happens? Is that a bug or is there something I dont know or that the documentation doesn't mention? Here is a minimal repro-example.

 #include <stdio.h>
 #include <stdlib.h>
 #include <wchar.h>
    
 #include <dwrite.h>
    
 #pragma comment(lib, "dwrite")
    
 IDWriteFactory* pDWriteFactory = NULL;
 IDWriteFontCollection* pFontCollection = NULL;
 IDWriteFontFamily* pFontFamily = NULL;
 IDWriteFont* pFont = NULL;
 IDWriteFontFace* pFontFace = NULL;
    
 int main()
 {
  HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, &pDWriteFactory);
  if (FAILED(hr))
  return -1;
    
  hr = pDWriteFactory->GetSystemFontCollection(&pFontCollection, FALSE);
    
  if (FAILED(hr))
  return -2;
    
  UINT index = 0;
  BOOL exists;
  hr = pFontCollection->FindFamilyName(L"Arial", &index, &exists);
  if (FAILED(hr))
  return -3;
  hr = pFontCollection->GetFontFamily(index, &pFontFamily);
  if (FAILED(hr))
  return -4;
  UINT count;
    
  count = pFontFamily->GetFontCount();
  if (FAILED(hr))
  return -5;
  DWRITE_FONT_METRICS metrics;
  for (int i = 0; i < count; i++)
  {
  hr = pFontFamily->GetFont(i, &pFont);
  pFont->GetMetrics(&metrics);
    
  printf("%d %d %d %d\n", metrics.designUnitsPerEm, metrics.ascent, metrics.descent, metrics.lineGap);
  }
  return 0;
 }
jtxkopt
  • 916
  • 1
  • 8
  • 21

1 Answers1

1

DirectWrite simulates "oblique" fonts (that are not in the physical files).

For Oblique, the slant is achieved by performing a shear transformation on the characters from a normal font. When a true italic font is not available on a computer or printer, an oblique style can be generated from the normal font and used to simulate an italic font.

So you'll get 'Oblique', 'Narrow Oblique', 'Bold Oblique', 'Narrow Bold Oblique', 'Black Oblique' simulated fonts for a total of 14.

If italic is available, oblique should not be used.

You can check that using the IDWriteFontFace::GetSimulations method, on each font, which will get you back DWRITE_FONT_SIMULATIONS_OBLIQUE for those fonts.

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • 1
    Using newer API (IDWriteFactory6::GetSystemFontCollection method) you have a choice of family model, that controls how fonts are grouped in families. This will also affect returned font count, comparing to what example code is doing. – bunglehead Dec 12 '21 at 10:26
  • The IDWriteFactory6::GetSystemFontCollection method using the typographic family is particularly recommended when using variable fonts. A variable font might have a variation axis that's not weight, stretch or style (i.e., italic or slant), and using the older WSS family model, some of the named instances could appear in the WSS model as separate families, which probably doesn't make sense. – Peter Constable Dec 17 '21 at 17:46