Is there a way to programmatically determine if a font file has a specific Unicode Glyph?

前端 未结 6 912
花落未央
花落未央 2020-11-27 04:19

I\'m working on a project that generates PDFs that can contain fairly complex math and science formulas. The text is rendered in Times New Roman, which has pretty good Unic

6条回答
  •  南方客
    南方客 (楼主)
    2020-11-27 04:55

    I have done this with just a VB.Net Unit Test and no WIN32 API calls. It includes code to check specific characters U+2026 (ellipsis) & U+2409 (HTab), and also returns # of characters (and low and high values) that have glyphs. I was only interested in Monospace fonts, but easy enough to change ...

        Dim fnt As System.Drawing.Font, size_M As Drawing.Size, size_i As Drawing.Size, size_HTab As Drawing.Size, isMonospace As Boolean
        Dim ifc = New Drawing.Text.InstalledFontCollection
        Dim bm As Drawing.Bitmap = New Drawing.Bitmap(640, 64), gr = Drawing.Graphics.FromImage(bm)
        Dim tf As Windows.Media.Typeface, gtf As Windows.Media.GlyphTypeface = Nothing, ok As Boolean, gtfName = ""
    
        For Each item In ifc.Families
            'TestContext_WriteTimedLine($"N={item.Name}.")
            fnt = New Drawing.Font(item.Name, 24.0)
            Assert.IsNotNull(fnt)
    
            tf = New Windows.Media.Typeface(item.Name)
            Assert.IsNotNull(tf, $"item.Name={item.Name}")
    
            size_M = System.Windows.Forms.TextRenderer.MeasureText("M", fnt)
            size_i = System.Windows.Forms.TextRenderer.MeasureText("i", fnt)
            size_HTab = System.Windows.Forms.TextRenderer.MeasureText(ChrW(&H2409), fnt)
            isMonospace = size_M.Width = size_i.Width
            Assert.AreEqual(size_M.Height, size_i.Height, $"fnt={fnt.Name}")
    
            If isMonospace Then
    
                gtfName = "-"
                ok = tf.TryGetGlyphTypeface(gtf)
                If ok Then
                    Assert.AreEqual(True, ok, $"item.Name={item.Name}")
                    Assert.IsNotNull(gtf, $"item.Name={item.Name}")
                    gtfName = $"{gtf.FamilyNames(Globalization.CultureInfo.CurrentUICulture)}"
    
                    Assert.AreEqual(True, gtf.CharacterToGlyphMap().ContainsKey(AscW("M")), $"item.Name={item.Name}")
                    Assert.AreEqual(True, gtf.CharacterToGlyphMap().ContainsKey(AscW("i")), $"item.Name={item.Name}")
    
                    Dim t = 0, nMin = &HFFFF, nMax = 0
                    For n = 0 To &HFFFF
                        If gtf.CharacterToGlyphMap().ContainsKey(n) Then
                            If n < nMin Then nMin = n
                            If n > nMax Then nMax = n
                            t += 1
                        End If
                    Next
                    gtfName &= $",[x{nMin:X}-x{nMax:X}]#{t}"
    
                    ok = gtf.CharacterToGlyphMap().ContainsKey(AscW(ChrW(&H2409)))
                    If ok Then
                        gtfName &= ",U+2409"
                    End If
                    ok = gtf.CharacterToGlyphMap().ContainsKey(AscW(ChrW(&H2026)))
                    If ok Then
                        gtfName &= ",U+2026"
                    End If
                End If
    
                Debug.WriteLine($"{IIf(isMonospace, "*M*", "")} N={fnt.Name}, gtf={gtfName}.")
                gr.Clear(Drawing.Color.White)
                gr.DrawString($"Mi{ChrW(&H2409)} {fnt.Name}", fnt, New Drawing.SolidBrush(Drawing.Color.Black), 10, 10)
                bm.Save($"{fnt.Name}_MiHT.bmp")
            End If
        Next
    

    The output was

    M N=Consolas, gtf=Consolas,[x0-xFFFC]#2488,U+2026.

    M N=Courier New, gtf=Courier New,[x20-xFFFC]#3177,U+2026.

    M N=Lucida Console, gtf=Lucida Console,[x20-xFB02]#644,U+2026.

    M N=Lucida Sans Typewriter, gtf=Lucida Sans Typewriter,[x20-xF002]#240,U+2026.

    M N=MingLiU-ExtB, gtf=MingLiU-ExtB,[x0-x2122]#212.

    M N=MingLiU_HKSCS-ExtB, gtf=MingLiU_HKSCS-ExtB,[x0-x2122]#212.

    M N=MS Gothic, gtf=MS Gothic,[x0-xFFEE]#15760,U+2026.

    M N=NSimSun, gtf=NSimSun,[x20-xFFE5]#28737,U+2026.

    M N=OCR A Extended, gtf=OCR A Extended,[x20-xF003]#248,U+2026.

    M N=SimSun, gtf=SimSun,[x20-xFFE5]#28737,U+2026.

    M N=SimSun-ExtB, gtf=SimSun-ExtB,[x20-x7F]#96.

    M N=Webdings, gtf=Webdings,[x20-xF0FF]#446.

提交回复
热议问题