Commits

anatoly techtonik committed 76a5aba

Introduce CSS font families, add DEBUG parameter.

  • Participants
  • Parent commits b6daa69

Comments (0)

Files changed (1)

 any information about filenames they contained in. From two different
 files with the same font name you'll can get only one.
 
-[ ] Windows also doesn't allow getting only monospace fonts. You need
-to query all available fonts and filter them yourself.
+Windows also doesn't have a clear concept of _generic font family_
+familiar from CSS specification. To get to monospace fonts you need
+to query all available fonts and filter them by properties. Here is
+how fontquery does mapping for generic CSS font families:
+
+  serif      -   (LOGFONT.lfPitchAndFamily >> 4) == FF_ROMAN
+  sans-serif -   (LOGFONT.lfPitchAndFamily >> 4) == FF_SWISS
+  cursive    -   (LOGFONT.lfPitchAndFamily >> 4) == FF_SCRIPT
+  fantasy    -   (LOGFONT.lfPitchAndFamily >> 4) == FF_DECORATIVE
+  monospace  -   (LOGFONT.lfPitchAndFamily >> 4) == FF_MODERN
+
+NOTE: Raster 'Modern' font and OpenType 'OCR A Extended' are
+      FF_MODERN, but have VARIABLE_PITCH.
+
+      [ ] find a way to check char's pitch matches manually
+
 
 Use cases:
- [x] get the list of all system fonts available
- [ ] get the list of families available
- [ ] get the list of all fonts for specific family
+ [x] get the list of all available system font names
+ [ ] get the list of all fonts for generic family
+ [ ] get the list of all fonts for specific charset
  [ ] check if specific font is available
-   [ ] check that family matched if another font is returned
 
 Considerations:
  - performance of querying all system fonts is not measured
 on the system, the font mapper will substitute a font that has similar
 attributes but a different name.
 
+   [ ] check if font is chosen by the system has required family
+
     To get the appropriate font, call EnumFontFamiliesEx with the
 desired font characteristics in the LOGFONT structure, then retrieve the
 appropriate typeface name and create the font using CreateFont or
   if name.endswith('_CHARSET'):
     CHARSET_NAMES[value] = name
 
+# font pitch constants ('fixed pitch' means 'monospace')
+FIXED_PITCH = 1
+VARIABLE_PITCH = 2
+
+# Windows font family constants
+FF_ROMAN = 1      # with serifs, proportional
+FF_SWISS = 2      # w/out serifs, proportional
+FF_MODERN = 3     # constant stroke width
+FF_SCRIPT = 4     # handwritten
+FF_DECORATIVE = 5 # novelty
+
 
 class LOGFONT(ctypes.Structure):
   # EnumFontFamiliesEx examines only 3 fields:
       # DEFAULT_PITCH
       # FIXED_PITCH
       # VARIABLE_PITCH
-      #    stacked any of with
+      #    stacked with any of 
       # FF_DECORATIVE   - novelty
       # FF_DONTCARE     - default font
       # FF_MODERN       - monospace
                    #   RASTER_FONTTYPE 
                    #   TRUETYPE_FONTTYPE 
   wintypes.LPARAM
-);
+)
 
 _font_names = set()
 def _enum_font_names(logfont, textmetricex, fonttype, param):
   lf = logfont.contents
   _font_names.add(lf.lfFaceName)
 
+  if DEBUG:
+    # print information about fixed pitch and modern font properties
+    pitch  = lf.lfPitchAndFamily & 0b11
+    family = lf.lfPitchAndFamily >> 4
+    if pitch == FIXED_PITCH:
+      if family == FF_MODERN:
+        print(b'           ' + lf.lfFaceName)
+      else:
+        print(b'[FPNM] (%s) %s' % (family, lf.lfFaceName))
+    else:
+      if lf.lfPitchAndFamily >> 4 == FF_MODERN:
+        print(b'[VP M] [%s] %s' % (pitch, lf.lfFaceName))
+
+
   return 1   # non-0 to continue enumeration
 enum_font_names = FONTENUMPROC(_enum_font_names)
 
   return sorted(_font_names)
 
 
-if DEBUG:
+if __name__ == '__main__':
   names = query()
   for f in names:
-    print(f)
-  print("Total: %s" % len(names))
+    print('%s' % f)
+  if DEBUG:
+    print("Total: %s" % len(names))
 
 
 # x. Convert desired font size from points into logical units (pixels)