Commits

anatoly techtonik  committed 76a5aba

Introduce CSS font families, add DEBUG parameter.

  • Participants
  • Parent commits b6daa69

Comments (0)

Files changed (1)

File fontquery.py

 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)