Announcement

Collapse
No announcement yet.

Enumerate font styles..

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Semen Matusovski
    replied
    Borje --
    1) I ran your code under Win2000 and received enough strange results.
    2) Enumeration (at least, under Win2000) gives 100% correct results.
    Another question, what means "correct" ...

    Completely sure that windows simply takes information from font files' headers.
    Three or four years ago I made own font (regular & bold).
    I honestly marked Weight, but didn't worry about other fields.
    If I marked a font as "Italic" (it could be), both (EnumFont & CreateFont) will accept a font as "Italic".

    You talk - "Arial Rounded MT also says Weight 700 Italic 0, but can only be bold+italic".
    Don't understand. Do you want to say that tm.tmItalic of created font will be non-zero ?
    Guess, that it will be zero - Windows has no eyes



    ------------------
    E-MAIL: [email protected]

    Leave a comment:


  • Borje Hagsten
    replied
    Because, enumeration only does not give 100% correct result for all fonts.
    Like, Abilene font says Weight 400 Italic 0, Bart font says Weight 700 and
    Italic 0, but nothing tells me what other styles they can have. Both can
    have all styles. Another font, Arial Rounded MT also says Weight 700 Italic 0,
    but can only be bold+italic. How to tell, without actually testing..?

    ------------------
    BTW, for eventual lurkers: EnumFontFamiliesEx does not work in Win95, so
    must test what system it is and use EnumFontFamilies in old system..
    (only extra is scripts - can usually do without those)


    [This message has been edited by Borje Hagsten (edited October 15, 2001).]

    Leave a comment:


  • Semen Matusovski
    replied
    Borje --
    Can't understand, why do you create hFont.
    Code:
       #Compile Exe
       #Include "WIN32API.INC"
       
       Function EnumFontFamExProc(lpelfe As  ENUMLOGFONTEX, lpntme As NEWTEXTMETRICEX, ByVal FontType As Dword, lParam As String Ptr) As Long
          @lParam = @lParam + lpelfe.elfLogFont.lfFaceName + " " + _
                    lpelfe.elfStyle + " Charset =" + Str$(lpelfe.elfLogFont.lfCharset) + _
                    " Weight = " + Str$(lpelfe.elfLogFont.lfWeight) + " " + _
                    " Italic =" + Str$(lpelfe.elfLogFont.lfItalic) + $CRLF
          Function = 1
       End Function
      
      Function PbMain
         Dim hDC As Long, lf As LOGFONT, s As String
         hDC = GetDC (0)
         lf.lfFaceName = "Times New Roman"
         lf.lfCharset = %DEFAULT_CHARSET
         EnumFontFamiliesEx hDC, lf, CodePtr(EnumFontFamExProc), VarPtr(s), 0
         ReleaseDC 0, hDC
         MsgBox s
      End Function
    ------------------
    E-MAIL: [email protected]

    Leave a comment:


  • Borje Hagsten
    replied
    Wrapped up a mix of my code and Gafny's. The "GetFontStyle" function
    is only way I have found that gives correct available styles. Maybe
    useful in case someone else also want to do own font dialog..
    Code:
    #COMPILE EXE
    #INCLUDE "WIN32API.INC"
     
    DECLARE CALLBACK FUNCTION DlgProc
    DECLARE SUB GetFontStyles(BYVAL hWnd AS LONG, BYVAL sFontName AS STRING)
    DECLARE FUNCTION MakeFontEx(BYVAL sFont AS STRING, BYVAL PointSize AS LONG, _
                                BYVAL fBold AS LONG, BYVAL fItalic AS LONG, BYVAL fUnderline AS LONG) AS LONG
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Main entrance
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    FUNCTION PBMAIN()  AS LONG
      LOCAL hDlg  AS LONG
     
      DIALOG NEW 0, "Font Test" ,,, 180, 50, %DS_CENTER OR %WS_CAPTION OR %WS_SYSMENU TO hDlg
      CONTROL ADD COMBOBOX, hDlg, 101, , 1, 2, 120, 100, _
                            %CBS_DROPDOWNLIST OR %WS_VSCROLL OR %WS_TABSTOP OR %CBS_SORT
      CONTROL ADD LISTBOX, hDlg, 102, , 123, 2, 55, 45, _
                            %LBS_NOINTEGRALHEIGHT OR %WS_TABSTOP, %WS_EX_CLIENTEDGE
      
      DIALOG SHOW MODAL hDlg CALL DlgProc
    END FUNCTION
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Main dialog's callback procedure
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    CALLBACK FUNCTION DlgProc
      LOCAL hDc  AS LONG, hDlg AS LONG, txt AS STRING
     
      SELECT CASE CBMSG
          CASE %WM_INITDIALOG
             hDlg = CBHNDL
             hDC = GetDC(%HWND_DESKTOP)
               EnumFontFamilies hDC, BYVAL %NULL, CODEPTR(EnumFontNames), BYVAL VARPTR(hDlg)
             ReleaseDC %HWND_DESKTOP, hDC
             CONTROL SEND CBHNDL, 101, %CB_SETCURSEL, 0, 0
             COMBOBOX GET TEXT CBHNDL, 101 TO txt
             CALL GetFontStyles(CBHNDL, txt)
     
          CASE %WM_COMMAND
             IF CBCTLMSG = %BN_CLICKED AND CBCTL = %IDCANCEL THEN
                DIALOG END CBHNDL
             ELSEIF CBCTLMSG = %CBN_SELENDOK AND CBCTL = 101 THEN
                COMBOBOX GET TEXT CBHNDL, 101 TO txt
                CALL GetFontStyles(CBHNDL, txt)
             END IF
     
      END SELECT
    END FUNCTION
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Get available font styles by testing if they can be created
    ' Seems to be only 100% sure way to get working styles..
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    SUB GetFontStyles(BYVAL hWnd AS LONG, BYVAL sFontName AS STRING)
      LOCAL hDc AS LONG, hFont AS LONG, tm AS TEXTMETRIC
      LISTBOX RESET hWnd, 102
     
      hDC = GetDc(hWnd)
     
      hFont = SelectObject(hDC, MakeFontEx(sFontName, 10, 0, 0, 0))
      GetTextMetrics hDC, tm
      IF tm.tmWeight < 500 And tm.tmItalic = 0 Then
         LISTBOX ADD hWnd, 102, "Normal"
      END IF
      DeleteObject SelectObject(hDC, hFont)
     
      hFont = SelectObject(hDC, MakeFontEx(sFontName, 10, 0, 1, 0))
      GetTextMetrics hDC, tm
      IF tm.tmWeight < 500 And tm.tmItalic Then
         LISTBOX ADD hWnd, 102, "Italic"
      END IF
      DeleteObject SelectObject(hDC, hFont)
     
      hFont = SelectObject(hDC, MakeFontEx(sFontName, 10, %FW_BOLD, 0, 0))
      GetTextMetrics hDC, tm
      IF tm.tmWeight  > 499 And tm.tmItalic = 0 Then
         LISTBOX ADD hWnd, 102, "Bold"
      END IF
      DeleteObject SelectObject(hDC, hFont)
     
      hFont = SelectObject(hDC, MakeFontEx(sFontName, 10, %FW_BOLD, 1, 0))
      GetTextMetrics hDC, tm
      IF tm.tmWeight  > 499 And tm.tmItalic Then
         LISTBOX ADD hWnd, 102, "Bold Italic"
      END IF
      DeleteObject SelectObject(hDC, hFont)
     
      ReleaseDc hWnd, hDC
     
    END SUB
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Create a desirable font and return its handle. Original code by Dave Navarro
    ' NOTE: enhanced with proper enumeration of character set via EnumCharSet
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    FUNCTION MakeFontEx(BYVAL sFont AS STRING, BYVAL PointSize AS LONG, _
                        BYVAL fBold AS LONG, BYVAL fItalic AS LONG, BYVAL fUnderline AS LONG) AS LONG
      LOCAL hDC AS LONG, CharSet AS LONG, CyPixels AS LONG, lf AS LOGFONT
     
      hDC = GetDC(%HWND_DESKTOP)
        CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
        EnumFontFamilies hDC, BYVAL STRPTR(sFont), CODEPTR(EnumCharSet), BYVAL VARPTR(CharSet)
      ReleaseDC %HWND_DESKTOP, hDC
      PointSize = 0 - (PointSize * CyPixels) \ 72
     
      FUNCTION = CreateFont(PointSize, 0, _  'height, width(default=0)
                 0, 0, _                     'escapement(angle), orientation
                 fBold, _                    'weight (%FW_DONTCARE = 0, %FW_NORMAL = 400, %FW_BOLD = 700)
                 fItalic, _                  'Italic
                 fUnderline, _               'Underline
                 %FALSE, _                   'StrikeThru
                 CharSet, %OUT_TT_PRECIS, _
                 %CLIP_DEFAULT_PRECIS, %DEFAULT_QUALITY, _
                 %FF_DONTCARE , BYCOPY sFont)
     
    END FUNCTION
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Enumerate fonts - here TrueType fonts only
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    FUNCTION EnumFontNames (elf AS ENUMLOGFONT, ntm AS NEWTEXTMETRIC, _
                            BYVAL FontType AS LONG, hWnd AS LONG) AS LONG
      IF (FontType AND %TRUETYPE_FONTTYPE) THEN
         COMBOBOX ADD hWnd, 101, elf.elfLogFont.lfFaceName
      END IF
      FUNCTION = 1
    END FUNCTION
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Get type of character set - ansi, symbol.. a must for some fonts.
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    FUNCTION EnumCharSet (elf AS ENUMLOGFONT, ntm AS NEWTEXTMETRIC, _
                          BYVAL FontType AS LONG, CharSet AS LONG) AS LONG
      CharSet = elf.elfLogFont.lfCharSet
      FUNCTION = 0 'break action - only needed charset
    END FUNCTION
    ------------------
    had to correct some comments..



    [This message has been edited by Borje Hagsten (edited October 15, 2001).]

    Leave a comment:


  • Borje Hagsten
    replied
    Thank you Gafny. Yes, I have also tried EnumFontFamiliesEx to get
    eventual scripts, etc, but none of these gives 100% result. Talked
    to a fellow who's done a lot of work with fonts and he says, "only
    sure way is by physically testing each style. Reason is, some fonts
    are old, others are simply not created in proper way - they work,
    but don't give out correct info. Only thing that is sure, is that
    you can never be sure when it comes to Windows' font handling.."

    Can see that here. Some fonts only says "bold". Okay, but can they
    be bold+italic? No way to tell without testing. Some can, some can't.
    Many says "Regular" or "Normal", but when tested, some of them can't
    be bold, or italic, or whatever. Inconsistent, so I'll stick to my
    ugly code, because it works..


    ------------------

    Leave a comment:


  • Gafny Jacob
    replied
    Include is a short sample to find fonts attributes

    Code:
    $COMPILE  EXE
    $INCLUDE  "WIN32API.INC"
    
    FUNCTION EnumFontFam(ef AS ENUMLOGFONT, tm AS NEWTEXTMETRIC, BYVAL FontType AS LONG, lpData AS LONG) AS LONG
        LISTBOX ADD lpData, 102, ef.elfStyle
        FUNCTION = 1
    END FUNCTION
       
    SUB SetFontAttribute(hDlg AS LONG)
        LOCAL hDc      AS LONG
        LOCAL i        AS LONG
        LOCAL FntName  AS ASCIIZ * 33
        LOCAL pSize    AS LONG
    
        CONTROL SEND hDlg, 101, %CB_GETCURSEL ,0, 0, TO i
        CONTROL SEND hDlg, 101, %CB_GETLBTEXT ,i, VARPTR(Fntname)
        hDC = GetDC(%HWND_DESKTOP)
        LISTBOX RESET hDlg, 102
        EnumFontFamilies hDC,  FntName, CODEPTR(EnumFontFam), BYVAL VARPTR(hDlg)
        ReleaseDC %HWND_DESKTOP, hDC
    END SUB
    
    FUNCTION EnumFontName(lf AS LOGFONT, tm AS NEWTEXTMETRIC, BYVAL FontType AS LONG, lpData AS LONG) AS LONG
      LOCAL zText AS ASCIIZ * 256
      IF (Tm.tmPitchAndFamily AND %TMPF_TRUETYPE) = %TMPF_TRUETYPE THEN
         zText = lf.lfFaceName
         CONTROL SEND lpData, 101, %CB_ADDSTRING, 0, VARPTR(zText)
      END IF
      FUNCTION = 1
    END FUNCTION
    
    CALLBACK FUNCTION DlgProc
        LOCAL hDc  AS LONG
        LOCAL hDlg AS LONG
    
        SELECT CASE CBMSG
            CASE %WM_INITDIALOG
               hDC = GetDC(%HWND_DESKTOP)
               hDlg = CBHNDL
               EnumFonts hDC,  BYVAL %NULL, CODEPTR(EnumFontName), BYVAL VARPTR(hDlg)
               ReleaseDC %HWND_DESKTOP, hDC
               CONTROL SEND CBHNDL, 101, %CB_SETCURSEL, 0, 0
               CALL SetFontAttribute(CBHNDL)
            CASE %WM_COMMAND
               IF (HIWRD(CBWPARAM) = %CBN_SELENDOK) AND (LOWRD(CBWPARAM) = 101) THEN
                  CALL SetFontAttribute(CBHNDL)
               END IF
        END SELECT
    END FUNCTION
    
    FUNCTION PBMAIN()  AS LONG
       LOCAL hDlg  AS LONG
       DIALOG NEW 0, "Font Test" ,,, 180, 50, %DS_CENTER OR %WS_CAPTION OR %WS_SYSMENU TO hDlg
       CONTROL ADD COMBOBOX, hDlg, 101, , 1, 2, 120, 100, %CBS_DROPDOWNLIST OR %WS_VSCROLL OR %WS_TABSTOP
       CONTROL ADD LISTBOX, hDlg, 102, , 123, 2, 55, 45,%WS_BORDER OR %LBS_NOINTEGRALHEIGHT, %WS_EX_CLIENTEDGE
       DIALOG SHOW MODAL hDlg CALL DlgProc
    END FUNCTION

    ------------------

    Leave a comment:


  • Borje Hagsten
    replied
    Yes Gafny, I tried, but some fonts says "bold italic", but no way to
    tell how these styles can be combined. I have some fonts that can be
    bold and bold+italic, but not italic. Other can be bold or italic, but
    not both, etc. Some fonts says nothing at all.

    Think reason is because some fonts are old and don't have all proper
    flags and structure members set. Only sure way so far, seems to be by
    physically try the fonts. Can do like MS and probably use enumeration
    way, but also get same inconsistent result. Like MS font dialog tells
    me some fonts can have all styles, when in reality, they can't..

    Have it working here, but thought there may be some easier way out.
    After many tests, don't think there is.


    ------------------

    Leave a comment:


  • Gafny Jacob
    replied
    Call EnumFontFamilies and define an callback function EnumFontFamProc

    The second parameter of the callback proc point to a Struct NEWTEXTMETRIC

    From that Struct you can obtain the physical attributes of the font
    HTH



    [This message has been edited by Gafny Jacob (edited October 14, 2001).]

    Leave a comment:


  • Borje Hagsten
    started a topic Enumerate font styles..

    Enumerate font styles..

    Does anyone know of a good way to find out all possible font styles for
    a TrueType font? Found that enumerating the fonts isn't enough - some
    can be bold and italic, but can't be both at same time, etc.

    Found a working solution by creating a font of each desired style, select
    into a DC, look at textmetric members and then de-select/delete. If they
    match what I wanted to create, add to list, else font can't be this style.

    Means I have to do this at least four times for each font name, FW_NORMAL
    and FW_BOLD, both with tmItalic on/off. For more exact table, would have
    to run through all tmWeigth possibilites, from FW_DONTCARE to FW_BLACK, but..

    Is fast enough though - instant, but code looks terrible. Maybe I have missed
    some clever little API that returns all valid styles for a font name in one take..?


    ------------------
Working...
X