Non c'è alcuna informazione esplicita in un font che definisce in modo univoco se è leggibile come "Roman" o meno.
È possibile ricorrere all'analisi del glifo per vedere quale intervallo Unicode copre un carattere. Questo potrebbe darti un'idea di quali lingue è coperto da un font. Tuttavia, questo ha anche problemi, ad esempio
- Il tipo di carattere predefinito di Windows 7 è "Segoe UI". Nel tuo schema vedresti questo come un font "romano"? Il problema qui è che anche se esegui l'analisi del glifo, copre il latino ma anche altri intervalli Unicode, ad es. Arabo e tailandese. Ok, possiamo includere caratteri che almeno coprono il latino, tuttavia, e se la gamma latina non è effettivamente leggibile come latino come nel punto 3?
- L'esempio di "Baiti mongoli" include glifi che coprono la gamma latina di base, quindi può essere utilizzato per rendere il testo "romano".
- Webdings copre la gamma latina, quindi tramite analisi potrebbe passare, ma in realtà non contiene caratteri latini leggibili.
L'analisi di glifi potrebbe essere applicata per restringere le cose, forse, ma si potrebbero ottenere falsi positivi.
Aggiornamento
ho a che fare con le liste dei font nella mia propria applicazione, quindi non potevo lasciare questo uno solo! :)
In realtà è possibile derivare se un carattere è un carattere simbolo tramite la proprietà GlyphTypeface.Symbol (che è nuovo per me). Pertanto con questo e un po 'di analisi del glifo, la seguente soluzione dovrebbe fare il trucco.
Tuttavia troverà ancora "Baiti mongoli" (ed è "Baiti" non "Balti" come in stile curry :)) come questo ha glifi per caratteri latini quindi è ancora un carattere "romano" a seconda di come lo definisci. Di fatto, tutti i caratteri non Symbol sul mio sistema hanno almeno il range di caratteri latini, quindi il test del glifo latino non esclude alcun carattere.
Qual è la tua particolare obiezione a "Baiti mongoli" e come prevedi di escluderla automaticamente (senza utilizzare un elenco di esclusione gestito manualmente, ad esempio)?
[Test]
public void test()
{
var fonts = Fonts.SystemFontFamilies.OrderBy(x => x.ToString());
var latinFonts = fonts.Where(f =>
f.Source.StartsWith("Global") ||
(!IsSymbol(f) && HasLatinGlyphs(f)));
latinFonts.ToList().ForEach(Console.WriteLine);
}
private bool IsSymbol(FontFamily fontFamily)
{
GlyphTypeface glyph = GetFirstGlpyhTypeface(fontFamily);
return glyph.Symbol;
}
private bool HasLatinGlyphs(FontFamily fontFamily)
{
GlyphTypeface glyph = GetFirstGlpyhTypeface(fontFamily);
for (int i = 32; i < 127; i++)
{
if (!glyph.CharacterToGlyphMap.ContainsKey(i)) return false;
}
return true;
}
private GlyphTypeface GetFirstGlpyhTypeface(FontFamily fontFamily)
{
Typeface typeface = fontFamily.GetTypefaces().First();
GlyphTypeface glyph;
typeface.TryGetGlyphTypeface(out glyph);
return glyph;
}
Aggiornamento 2
Si potrebbe sperimentare con filtrando i font in base a ciò che hanno il supporto per i caratteri latini estesi includendo filtri per Latin Extended-A
e Latin Extended-B
gamme. Il filtro con Latin Extended-A
e Latin Extended-B
lascia ancora pochi caratteri, ma il solo filtro su Latin Extended-A
lascia ancora molti tipi di carattere. Rimuove automaticamente anche Mongolian Baiti
in quanto questo ha solo il supporto per Latin-1
e Latin-1 Supplement
.
Se questo tipo di analisi dà risultati desiderabili è altamente soggettivo. Qualcosa di sperimentare però:
private bool HasLatinGlyphs(FontFamily fontFamily)
{
GlyphTypeface glyph = GetFirstGlpyhTypeface(fontFamily);
List<Tuple<int, int>> ranges = new List<Tuple<int, int>>
{
new Tuple<int, int>(32, 126), //Latin-1
new Tuple<int, int>(160, 255), //Latin-1 Supplement
new Tuple<int, int>(256, 383), //Latin Extended-A
new Tuple<int, int>(384, 591), //Latin Extended-B
};
foreach (Tuple<int, int> range in ranges)
{
for (int i = range.Item1; i <= range.Item2; i++)
{
if (!glyph.CharacterToGlyphMap.ContainsKey(i)) return false;
}
}
return true;
}
Anche in questo caso, altamente soggettivo, ma il seguente darà font che supportano glifi latini più un sub-set di caratteri internazionali di valuta:
List<Tuple<int, int>> ranges = new List<Tuple<int, int>>
{
new Tuple<int, int>(32, 126), //Latin-1
new Tuple<int, int>(0x20A0, 0x20B5), //Currency Symbols (Partial)
};
Update 3
Oltre alla tua domanda, modifica qui è una versione che funzionerà con Windows 7. Sfrutta la funzionalità di carattere nascosto di Windows 7 (come sottolineato da @Rick Sladkey) che per impostazione predefinita nasconde i caratteri che non sono cons pensato per essere utile per le impostazioni locali dell'utente corrente. Inoltre esclude i caratteri di simbolo:
[Test]
public void test()
{
var allFonts = Fonts.SystemFontFamilies.OrderBy(x => x.Source);
var filteredFonts = allFonts.Where(f =>
IsComposite(f) || (!IsSymbol(f) && !IsHidden(f)));
filteredFonts.ToList().ForEach(Console.WriteLine);
}
private static bool IsComposite(FontFamily fontFamily)
{
return fontFamily.Source.StartsWith("Global");
}
private static bool IsSymbol(FontFamily fontFamily)
{
Typeface typeface = fontFamily.GetTypefaces().First();
GlyphTypeface glyph;
typeface.TryGetGlyphTypeface(out glyph);
return glyph.Symbol;
}
private static bool IsHidden(FontFamily fontFamily)
{
const string Key = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Font Management";
const string Value = "Inactive Fonts";
RegistryKey key = Registry.CurrentUser.OpenSubKey(Key);
IEnumerable<string> hiddenFonts = (string[])key.GetValue(Value);
return hiddenFonts.Contains(fontFamily.Source);
}
Il filtraggio può essere fatto con la 'evento filter' del' CollectionViewSource' ma immagino si sapeva che. Non ho mai visto un modo per scoprire se FontFamily è Symbol, ecc. Interessante vedere cosa ti viene in mente –
Sei sicuro che lo rende un * lotto * più difficile, o che si tratta solo di un piccolo inconveniente molto occasionale. Anche se rimuovi i caratteri "non romani" ci saranno ancora molti font. Domanda interessante però: +1. –
Gli script supportati da un font non sono disponibili tramite le classi di font correlate. Sei sicuro che questo sia costantemente disponibile tramite i metadati dei font incorporati e che MS non abbia eseguito solo un'analisi dei font per i font noti per Windows 7 per creare un DB di metadati dei font? –