I've tried using Open Type Fonts both for labels, textboxes and when drawing in a paint-event. But it doesn't work. Is there any way to make Open Type Font work?
This isn't possible in Winforms, GDI+ only supports TrueType fonts. You'll have to move to WPF to get OpenType support.
You can use the System.Windows.Media namespace as you would do in WPF, here you have an example:
public static string GetFontList(String ElementSeparator)
{
string r = "";
// WPF incl Adobe and OpenType
foreach (System.Windows.Media.FontFamily fontFam in System.Windows.Media.Fonts.SystemFontFamilies)
{
r += fontFam.Source;
r += ElementSeparator;
}
// True type, incl Type face names e.g. Arial Rounded MT Bold
foreach (System.Drawing.FontFamily f in System.Drawing.FontFamily.Families)
{
if(!r.Contains(f.Name))
{
r += f.Name;
r += ElementSeparator;
}
}
return r;
}
Related
I'm inserting variable text from a *.html file into a Word document and have to adapt the font(name and size) of the inserted text to the rest of the document.
I have a working solution but I don't like the way I did it, so I'm searching another way to get the standard font name and size from Word application.
Another problem is that NameLocal can be in different languages. So I also need another way to find the Headers. I already tried Style.Type but it has always value "1"
My code so far:
foreach (Word.Style style in Globals.ThisAddIn.Application.ActiveDocument.Styles)
{
if (style.NameLocal.Equals("Normal")) // find correct style object
{
float size = style.Font.Size;
string font = style.Font.Name;
foreach (Word.Paragraph paragraph in Globals.ThisAddIn.Application.ActiveDocument.Paragraphs)
{
if (paragraph.Range.get_Style().NameLocal.Contains("Heading")) // find all headers
{
paragraph.Range.Font.Size = size;
paragraph.Range.Font.Name = font;
}
}
break;
}
}
The reason why I'm not simply changing the style is so the headers are still marked as headers.
I'm pretty clueless atm
For built-in styles, the Word object model provides the enumeration WdBuiltinStyle. Using this instead of a string value (the local name of a style) makes specifying a style language-independent. In addition, the built-in styles will always be present in a document so there's no need to loop the Styles collection of a document to get a particular style.
So, for example:
Word.Document doc = Globals.ThisAddin.Application.ActiveDocument;
Word.Style style = doc.Styles[Word.WdBuildinStyle.wdStyleNormal];
float size = style.Size;
string font = style.Font.Name;
foreach (Word.Paragraph paragraph in doc)
{
if (paragraph.Range.get_Style() = Word.WdBuildinStyle.wdStyleHeading1)
{
paragraph.Range.Font.Size = size;
paragraph.Range.Font.Name = font;
}
}
I am trying to list all the available Fonts in the system with dropdown list. Mainly, I got to show Arial Bold font in the dropdown list and I have installed the same in my system. But the problem is, My Font Arial Bold is not getting populated in the list of available fonts.
Code
InstalledFontCollection installedFontCollection = new InstalledFontCollection();
var fontFamilies = installedFontCollection.Families;
foreach (FontFamily font in fontFamilies)
{
ddllblFontFamilyHead.Items.Add(font.Name);
}
I am using the above fonts to apply to iTextSharp PDF library to design my pdf content.
Code for applying Fonts to PDF file
var fontHeader = FontFactory.GetFont(_label.SFontName == null ? "Arial" : _label.SFontName, BaseFont.CP1250, true, _label.SFontSize == null ? 10 : _label.SFontSize.Value, 0);
Any help to this issue will be highly appreciated.
tested solution
InstalledFontCollection fontCol = new InstalledFontCollection();
for (int x = 0; x <= fontCol.Families.Length-1;x++ )
{
listBox1.Items.Add(fontCol.Families[x].Name);
}
There's a class named FontFactory in iTextSharp. This class only contains the standard Type 1 fonts by default, but you can register font directories to add more fonts.
For instance:
FontFactory.RegisterDirectories();
The RegisterDirectories() method will look at all the usual directories where your operating system stores fonts. This won't capture all the fonts, but you can add additional directories where you know there are fonts:
FontFactory.RegisterDirectory(myFontFolder);
You can then get all the names of the registered fonts like this:
foreach (String f in FontFactory.RegisteredFonts) {
listBox1.Items.Add(f);
}
I am aware that in DataGridview, we can bind a ImageColumn to image data to display icon such as. Normally I would use icons from Microsoft's MsoImage.
It occurs to me that from symbol font, we can have many nice icons. Is it possible to bind the column to text instead, with fonts taken into account, so that we can make use of symbol font and display the result of text + font that looks like icons.
If text binding is not possible, is there another way of extracting/converting the symbol font into images?
All you need is to set the Font for the Column. Here is am example:
List<daz> dazz = new List<daz>() { new daz("♻", "267B"), new daz("⚔", "2694") };
Font f = new Font("Segue UI Symbol", 12f);
dataGridView1.DataSource = dazz;
dataGridView1.Columns[0].DefaultCellStyle.Font = f;
Ignore the example class:
class daz
{
public string code { get; set; }
public string text { get; set; }
public daz (string c, string t) { code = c; text = t; }
}
So, I know there are multiple thread on how to do the conversion between the aforementioned systems. And I know they're not 1-to-1. However, I'm hoping there's a way to be able to get things to work.
The fonts specifically in question are just examples, as I'm sure others have the same issue, Segoe UI just happens to be my default font. What's not working though, is when I select Segoe UI Semibold Italic or some other in-between font.
Here's my conversion code:
// Font family
FontFamilyConverter ffc = new FontFamilyConverter();
TextContent.FontFamily = (System.Windows.Media.FontFamily)
ffc.ConvertFromString(fontDialog.Font.Name);
// Font size
TextContent.FontSize = fontDialog.Font.Size;
// Bold?
TextContent.FontWeight = (fontDialog.Font.Bold ? FontWeights.Bold : FontWeights.Normal);
// Italic?
TextContent.FontStyle = (fontDialog.Font.Italic ? FontStyles.Italic : FontStyles.Normal);
// Underline and strikethrough?
TextContent.TextDecorations = new TextDecorationCollection();
if (fontDialog.Font.Strikeout) {
TextContent.TextDecorations.Add(TextDecorations.Strikethrough);
}
if (fontDialog.Font.Underline) {
TextContent.TextDecorations.Add(TextDecorations.Underline);
}
// Color
TextContent.Foreground = new SolidColorBrush(
System.Windows.Media.Color.FromArgb(fontDialog.Color.A,
fontDialog.Color.R,
fontDialog.Color.G,
fontDialog.Color.B)
);
From using the debugger, I know that the Italic property is being properly set, but the font isn't coming through as Semibold Italic it's just coming through as Semibold. If (when in the debugger) I change the FontFamily to "Segoe UI Semibold Italic" then it works.
Is there something I'm missing to be able to get all the styles to come across correctly?
Thanks.
Note: I know size isn't working correctly. Just haven't fixed it yet
Here is what I ended up with:
After the dialog returns OK:
FontFamilyConverter ffc = new FontFamilyConverter();
TextContent.FontFamily = (System.Windows.Media.FontFamily) ffc.ConvertFromString(getFontName(fontDialog.Font));
A helper method:
private List<string> limitFontList(List<string> fontList, string word) {
// Create a new list
var newFontList = new List<string>();
// Go through each element in the list
foreach (var fontFamily in fontList) {
// If the elment contains the word
if (fontFamily.ToLower().Contains(word.ToLower())) {
// Add it to the new list
newFontList.Add(fontFamily);
}
}
// Return the new list if anything was put in it, otherwise the original list.
return newFontList.Count > 0 ? newFontList : fontList;
}
getFontName:
private string getFontName(Font font) {
// Holds the font we want to return. This will be the original name if
// a better one cannot be found
string fontWanted = font.FontFamily.Name;
// Create a new Media.FontFamily
var family = new System.Windows.Media.FontFamily(fontWanted);
/// Get the base font name
string baseFont = ""; // Holds the name
/* FamilyNames.Values will holds the base name, but it's in a collection
** and the easiest way to get it is to use a foreach. To the best of my
** knowledge, there is only ever one value in Values.
** E.g. If the font set is Segoe UI SemiBold Italc, gets Segoe UI.
*/
foreach(var baseF in family.FamilyNames.Values){
baseFont = baseF;
}
// If the baseFont is what we were passed in, then just return
if(baseFont == fontWanted) {
return fontWanted;
}
// Get the typeface by extracting the basefont from the name.
// Trim removes any preceeeding spaces.
string fontTypeface = fontWanted.Substring(baseFont.Length).Trim();
// Will hold all of the font names to be checked.
var fontNames = new List<string>();
// Go through all of the available typefaces, and add them to the list
foreach (var typeface in family.FamilyTypefaces) {
foreach(var fn in typeface.AdjustedFaceNames) {
fontNames.Add(baseFont + " " + fn.Value);
}
}
// Limit the list to elements which contain the specified typeface
fontNames = limitFontList(fontNames, fontTypeface);
// If the font is bold, and the original name doesn't have bold in it (semibold?)
if(!baseFont.ToLower().Contains("bold") && font.Bold) {
fontNames = limitFontList(fontNames, "bold");
}
// In a similar manner for italics
if (!baseFont.ToLower().Contains("italic") && font.Italic) {
fontNames = limitFontList(fontNames, "italic");
}
// If we have only one result left
if(fontNames.Count == 1) {
return fontNames[0];
}
// Otherwise, we can't accurately determine what the long name is,
// So hope whatever the short name is will work.
return fontWanted;
}
I am creating a control in WPF that shows units using a System.Windows.Control.RichTextBox.
The problem is the RichTextBox control shows a plain text instead of a formatted text.
I guess the RichTextBox control has a bug and I don't know how to do it, because it works depending on the computer.
The XAML code is,
<RichTextBox x:FieldModifier="private"
x:Name="TxtItem1"
IsReadOnly="True"
IsHitTestVisible="False"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center" />
And part of the code behind is:
private static void UpdateDocument(RichTextBox control, DependencyPropertyChangedEventArgs e)
{
string content = e.NewValue as string;
control.Document = content.Html1ToFlowDocument();
}
The function Html1ToFlowDocument converts a string into a FlowDocument. The following image is in a computer that the code goes fine (Windows 7 64 bits):
And the next one does not work (Windows 7 64 bits):
Another approach was using a RTF text but I have the problem.
The code of the function Html1ToFlowDocument,
public static class Html1ToDocument
{
public static FlowDocument Html1ToFlowDocument(this string text)
{
var mcFlowDoc = new FlowDocument();
XmlDocument doc = new XmlDocument();
doc.LoadXml(string.Format("<P>{0}</P>", text));
XmlElement root = doc.GetElementsByTagName("P")[0] as XmlElement;
IEnumerable<Inline> children;
try
{
children = ParseChildren(root);
}
catch (Exception ex)
{
throw new FormatException("Unsupported text.", ex);
}
var paragraph = new Paragraph();
paragraph.Inlines.AddRange(children);
mcFlowDoc.Blocks.Add(paragraph);
return mcFlowDoc;
}
private static IEnumerable<Inline> ParseChildren(XmlElement root)
{
Span sitem;
List<Inline> children;
foreach (XmlNode element in root.ChildNodes)
{
Inline item = null;
if (element is XmlElement)
{
XmlElement xelement = (XmlElement)element;
switch (xelement.Name.ToUpper())
{
case "SUB":
children = ParseChildren(xelement).ToList();
if (children.Count == 1 && children.First() is Run)
{
item = children.First();
item.Typography.Variants = FontVariants.Subscript;
}
else
{
sitem = new Span();
sitem.Typography.Variants = FontVariants.Subscript;
sitem.Inlines.AddRange(children);
item = sitem;
}
break;
case "SUPER":
children = ParseChildren(xelement).ToList();
if (children.Count == 1 && children.First() is Run)
{
item = children.First();
item.Typography.Variants = FontVariants.Superscript;
}
else
{
sitem = new Span();
sitem.Typography.Variants = FontVariants.Superscript;
sitem.Inlines.AddRange(children);
item = sitem;
}
break;
}
yield return item;
}
else if (element is XmlText)
{
item = new Run(element.InnerText);
yield return item;
}
}
}
}
If most things on the surface between the two computers seem the same (i.e. OS version, locale, framework installed) then I'd wager it's an issue with fonts. You're essentially getting the same text in both cases, but you're hitting a wall with superscripts and subscripts. A quick little googling showed me that other people are having similar problems:
http://www.grumpydev.com/2009/11/05/wpf-richtextbox-subscript-and-superscript-without-font-restrictions/
superscripts are not coming in wpf richtext box
Looks like the font in question needs to be:
Open Type
Have both superscript and subscript variants
Here's some information on checking for fonts:
Detect whether a font supports variants (like superscript and subscript)
My recommendation might be to try out a different font to see if it fixes it, and if so, find out how you can ensure you'll get the fonts you need on both (meaning, all that you intend to deploy to) machines.
I have used a tricky solution. The characters of the controls in WPF are based on the Unicode Standard 6.3 and there is a table in this standard with special characters, specifically subscript and superscript. And the most amazing is that it works in a simple TextBox.
⁰ i ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁺ ⁻ ⁼ ⁽ ⁾ ⁿ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₊ ₋ ₌ ₍ ₎ ₐ ₑ ₒ ₓ ₔ
You can download the specification here:
http://www.unicode.org/charts/PDF/U2070.pdf
And there are more special characters here: http://www.unicode.org/charts/