如何在C#中获取字体权重



我正在尝试获取字体的字体重量,但这似乎需要C#中的某种巫毒魔法。

我找到并转换了这个枚举来帮助解决它,我使用FontDialog来选择Font。

public enum FontWeight
{
Black = 900,
UltraBold = 800,
DemiBold = 600,
Regular = 400,
UltraLight = 200,
Heavy = 900,
ExtraBold = 800,
Bold = 700,
SemiBold = 600,
Medium = 500,
ExtraLight = 200,
Thin = 100,
DoNotCare = 0,
Normal = 400,
Light = 300
}

然而,即使FontDialog允许我选择一些相应的字体样式,FontDialog返回的字体也只包含FontStyle的C#枚举中包含的样式(粗体、斜体、正则、删除线、下划线(。

例如,如果我选择一种具有浅色样式的字体,则返回的字体将仅具有常规样式。

有没有办法在C#中获得字体的重量?我不打算在程序中使用字体,我只需要计算出另一个程序的权重。

这是我想到的,不包括设计器代码。如果我用这个套子代码冒犯了任何人,我很抱歉。这使用System.Windows.Media中的GlypTypeface类来获取大部分信息,并使用LogFont来获取高度。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;

public partial class FontPicker : Form
{
public Result ChoosenFont = new Result();
private Dictionary<string, List<GlyphTypeface>> FontCollection = new Dictionary<string, List<GlyphTypeface>>();
int[] sizes = new int[] { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 };
public class Result
{
public string Name;
public string Height;
public string Weight;
}

public FontPicker(string currentFont)
{
InitializeComponent();
foreach (int i in sizes)
{
listBoxSize.Items.Add(i);
}
int index = listBoxSize.FindStringExact("8");
listBoxSize.SelectedIndex = index;
var fontFilesPersonal = GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"MicrosoftWindowsFonts", new string[] { "*.ttf", "*.otf" }, SearchOption.TopDirectoryOnly);
var fontFilesWindows = GetFiles(@"C:WindowsFonts", new string[] { "*.ttf", "*.otf" }, SearchOption.TopDirectoryOnly);
List<string> fontFiles = new List<string>();
fontFiles.AddRange(fontFilesWindows);
fontFiles.AddRange(fontFilesPersonal);
foreach (string fontFile in fontFiles)
{
GlyphTypeface ttf = new GlyphTypeface(new Uri(fontFile));
string name = ttf.Win32FamilyNames.First().Value;
if (!FontCollection.ContainsKey(name))
{
FontCollection.Add(name, new List<GlyphTypeface>());
}
FontCollection[name].Add(ttf);
}
var fonts = FontCollection.Keys.ToList();
fonts.Sort();
foreach (string name in fonts)
{
listBoxFonts.Items.Add(name);
}
index = listBoxFonts.FindStringExact(currentFont);
if (index != -1) { listBoxFonts.SelectedIndex = index; }
else
{
index = listBoxFonts.FindStringExact("Unispace");
if (index != -1) { listBoxFonts.SelectedIndex = index; }
else
{
index = listBoxFonts.FindStringExact("Arial");
listBoxFonts.SelectedIndex = index;
}
}
}
public static IEnumerable<string> GetFiles(string path,
string[] searchPatterns,
SearchOption searchOption = SearchOption.TopDirectoryOnly)
{
return searchPatterns.AsParallel()
.SelectMany(searchPattern =>
Directory.EnumerateFiles(path, searchPattern, searchOption));
}
private void buttonAccept_Click(object sender, EventArgs e)
{
FontWeight weight = (FontWeight)listBoxStyle.SelectedItem;
string fontName = listBoxFonts.SelectedItem as string;
int size = (int)listBoxSize.SelectedItem;
LOGFONT logFont = new LOGFONT();
Font lfont = (new Font(fontName, size, System.Drawing.FontStyle.Regular));
lfont.ToLogFont(logFont);
ChoosenFont.Weight = weight.ToOpenTypeWeight().ToString();
ChoosenFont.Name = fontName;
ChoosenFont.Height = logFont.lfHeight.ToString();
DialogResult = DialogResult.OK;
Close();
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void listBoxFonts_SelectedIndexChanged(object sender, EventArgs e)
{
listBoxStyle.Items.Clear();
string fontName = listBoxFonts.SelectedItem as string;
if (FontCollection.ContainsKey(fontName))
{
foreach (var font in FontCollection[fontName])
{
if (!listBoxStyle.Items.Contains(font.Weight))
listBoxStyle.Items.Add(font.Weight);
}
}
int index = listBoxStyle.FindStringExact("Normal");
if (index == -1) { listBoxStyle.SelectedIndex = 0; }
else { listBoxStyle.SelectedIndex = index; }
}
}

public enum FontCharSet : byte
{
ANSI_CHARSET = 0,
DEFAULT_CHARSET = 1,
SYMBOL_CHARSET = 2,
SHIFTJIS_CHARSET = 128,
HANGEUL_CHARSET = 129,
HANGUL_CHARSET = 129,
GB2312_CHARSET = 134,
CHINESEBIG5_CHARSET = 136,
OEM_CHARSET = 255,
JOHAB_CHARSET = 130,
HEBREW_CHARSET = 177,
ARABIC_CHARSET = 178,
GREEK_CHARSET = 161,
TURKISH_CHARSET = 162,
VIETNAMESE_CHARSET = 163,
THAI_CHARSET = 222,
EASTEUROPE_CHARSET = 238,
RUSSIAN_CHARSET = 204,
MAC_CHARSET = 77,
BALTIC_CHARSET = 186,
}
public enum FontPrecision : byte
{
OUT_DEFAULT_PRECIS = 0,
OUT_STRING_PRECIS = 1,
OUT_CHARACTER_PRECIS = 2,
OUT_STROKE_PRECIS = 3,
OUT_TT_PRECIS = 4,
OUT_DEVICE_PRECIS = 5,
OUT_RASTER_PRECIS = 6,
OUT_TT_ONLY_PRECIS = 7,
OUT_OUTLINE_PRECIS = 8,
OUT_SCREEN_OUTLINE_PRECIS = 9,
OUT_PS_ONLY_PRECIS = 10,
}
public enum FontClipPrecision : byte
{
CLIP_DEFAULT_PRECIS = 0,
CLIP_CHARACTER_PRECIS = 1,
CLIP_STROKE_PRECIS = 2,
CLIP_MASK = 0xf,
CLIP_LH_ANGLES = (1 << 4),
CLIP_TT_ALWAYS = (2 << 4),
CLIP_DFA_DISABLE = (4 << 4),
CLIP_EMBEDDED = (8 << 4),
}
public enum FontQuality : byte
{
DEFAULT_QUALITY = 0,
DRAFT_QUALITY = 1,
PROOF_QUALITY = 2,
NONANTIALIASED_QUALITY = 3,
ANTIALIASED_QUALITY = 4,
CLEARTYPE_QUALITY = 5,
CLEARTYPE_NATURAL_QUALITY = 6,
}
[Flags]
public enum FontPitchAndFamily : byte
{
DEFAULT_PITCH = 0,
FIXED_PITCH = 1,
VARIABLE_PITCH = 2,
FF_DONTCARE = (0 << 4),
FF_ROMAN = (1 << 4),
FF_SWISS = (2 << 4),
FF_MODERN = (3 << 4),
FF_SCRIPT = (4 << 4),
FF_DECORATIVE = (5 << 4),
}
// if we specify CharSet.Auto instead of CharSet.Ansi, then the string will be unreadable
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class LOGFONT
{
public int lfHeight;
public int lfWidth;
public int lfEscapement;
public int lfOrientation;
public FontWeight lfWeight;
[MarshalAs(UnmanagedType.U1)]
public bool lfItalic;
[MarshalAs(UnmanagedType.U1)]
public bool lfUnderline;
[MarshalAs(UnmanagedType.U1)]
public bool lfStrikeOut;
public FontCharSet lfCharSet;
public FontPrecision lfOutPrecision;
public FontClipPrecision lfClipPrecision;
public FontQuality lfQuality;
public FontPitchAndFamily lfPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string lfFaceName;
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("LOGFONTn");
sb.AppendFormat("   lfHeight: {0}n", lfHeight);
sb.AppendFormat("   lfWidth: {0}n", lfWidth);
sb.AppendFormat("   lfEscapement: {0}n", lfEscapement);
sb.AppendFormat("   lfOrientation: {0}n", lfOrientation);
sb.AppendFormat("   lfWeight: {0}n", lfWeight);
sb.AppendFormat("   lfItalic: {0}n", lfItalic);
sb.AppendFormat("   lfUnderline: {0}n", lfUnderline);
sb.AppendFormat("   lfStrikeOut: {0}n", lfStrikeOut);
sb.AppendFormat("   lfCharSet: {0}n", lfCharSet);
sb.AppendFormat("   lfOutPrecision: {0}n", lfOutPrecision);
sb.AppendFormat("   lfClipPrecision: {0}n", lfClipPrecision);
sb.AppendFormat("   lfQuality: {0}n", lfQuality);
sb.AppendFormat("   lfPitchAndFamily: {0}n", lfPitchAndFamily);
sb.AppendFormat("   lfFaceName: {0}n", lfFaceName);
return sb.ToString();
}
}

编辑:修复了代码中的一些错误。

最新更新