Font does not support style 'Regular' - using Semibold fonts in C# - c#

I have a TrueType font, which is "Semibold". I try to use that in the following method:
private FontFamily GetFontFamily(string name)
{
PrivateFontCollection pfc = new PrivateFontCollection();
var path = Server.MapPath("~/Static/webfont/" + name + ".ttf");
pfc.AddFontFile(path);
return pfc.Families[0];
}
private Font GetFont(string name, int size,FontStyle style)
{
return new Font(GetFontFamily(name), size, style);
}
Where I provide a name of my font, and it finds the Sentinel-SemiboldItalic.ttf font. As a FontStyle, I have tried to provide any of the options in the .NET framework (regulary, bold, italic, underline and strikeout).
No matter what, I get the following error:
Font 'Sentinel Semibold' does not support style 'Regular'.
What should I do? How to use a semibold font as a font in C#? Also, can I somehow convert my TrueType font to a regular one (if that would fix the issue) ?

As you can read in the answer to this question, each font has its own properties (for example: enabling a Regular Style or not), as provided by the font creator.
By looking at your font (even just by looking at its name), it seems clear that it is a sub-type whose defining characteristics are precisely being (semi-)bold and italic; consequently, it does sound logical to not have the option to remove these features. If you want a non-bold, non-italic version, you should rely on the parent family (Sentinel).

I too faced the same issue like you. And found that even though we are adding the font[.ttf] file, the incorrect font is getting added in privatefontcollection. Hence i found the workaround for this case. This issue will be thrown randomly. So add the font till correct font is added in private font collection.
private FontFamily GetFontFamily(string name)
{
PrivateFontCollection pfc = new PrivateFontCollection();
var path = Server.MapPath("~/Static/webfont/" + name + ".ttf");
pfc.AddFontFile(path);
**while (pfc.FontFamilies != null && pfc.Families.Length > 0 && (pfc.FontFamilies[0] as FontFamily).Name != "YourFontName")
{
pfc.Dispose();
pfc = new PrivateFontCollection();
GetFontFamily();
}
return pfc.Families[0];
}

Related

How can I make default fontstyle be one that the font likes?

I have a small app that get a list of all the windows fonts. I can then choose one and display all its characters. All worked till I then found I had a problem, not all fonts have FontStyle:Regular. No problem I could do a check but this is where I run into a problem, when I start the system seems to have FontStyle:Regular as its default and I cannot change it so if I run the code below with text "Aharoni" selected in my combobox it falls over telling me that regular is not supported. How can I make it ignore the style or force the style to be one it uses like bold?
var cvt = new FontConverter();
Font fname = cvt.ConvertFromString(cmbobx_fontname.Text) as Font;
If I cannot do this then is it possible to get the styles that the choosen font will support?
The FontFamily class has a method to check if a style is available for the font - so rather than try to create a Font directly, first create a FontFamily instance & interate through the styles till you find one that is supported e.g.
FontFamily fontf = new FontFamily("Aharoni");
System.Drawing.FontStyle fs = System.Drawing.FontStyle.Regular;
System.Drawing.Font font;
if (fontf.IsStyleAvailable(System.Drawing.FontStyle.Regular))
fs = System.Drawing.FontStyle.Regular;
else if (fontf.IsStyleAvailable(System.Drawing.FontStyle.Bold))
fs = System.Drawing.FontStyle.Bold;
else if (fontf.IsStyleAvailable(System.Drawing.FontStyle.Italic))
fs = System.Drawing.FontStyle.Italic;
else if (fontf.IsStyleAvailable(System.Drawing.FontStyle.Strikeout))
fs = System.Drawing.FontStyle.Strikeout;
else if (fontf.IsStyleAvailable(System.Drawing.FontStyle.Underline))
fs = System.Drawing.FontStyle.Underline;
else
throw new Exception("No Font Styles Available");
font = new System.Drawing.Font(fontf, 10, fs);
You could iterate through the FontStyle enum - rather than use if/else as I have done.

List all the available / installed Fonts in the System

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);
}

Embedded resource font in C# does not work correctly

I embedded a .ttf font file ("Amatic Bold", specifically) in my resources and I'm using this code below to get the Font.
I tried the code fom this post: How do I Embed a font with my C# application? (using Visual Studio 2005)
This is my implementation:
static public Font GetCustomFont (byte[] fontData, float size, FontStyle style)
{
if (_fontCollection == null) _fontCollection = new PrivateFontCollection();
IntPtr fontPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(fontData.Length);
System.Runtime.InteropServices.Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
_fontCollection.AddMemoryFont(fontPtr, fontData.Length);
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr);
return new Font(_fontCollection.Families[0], size, style);
}
Im using it like that:
Font font = GetCustomFont(Properties.MainResources.Amatic_Bold, 25, System.Drawing.FontStyle.Bold);
The font should look like:
The problem is the font is loading but not correctly showing when used; it looks like an "Arial" or other standard font instead of what it should be.
If I install the font in Windows, it works (I suppose is obvious...)
I searched for an existing answer but could'nt find my exact problem...
Any help will be appreciated.
Thanks in advance.
Well, then... I think I got it!
I'll explain what I've "discovered" (whether it can be obvious or not):
First: Application.SetCompatibleTextRenderingDefault must be set to true for Memory fonts to be rendered in the controls.
(Also Control.UseCompatibleTextRendering can be used)
It's perfectly specified in Microsoft documentation but I've missed that :-(
Second: PrivateFontCollection.Families return an array of added fonts, but.. Surprise! It's alphabetically ordered!
No matter what's the order you add the fonts or the method you use (AddMemoryFont/AddFontFile), you'll get it alphabetically ordered!
So if you're adding more than one font and then trying to get the last font you've added, you'll probably getting the wrong one.
Third: I've also tried doing FreeCoTaskMem() after adding the font in the collection or doing it on form closing. Both were working for me!
I don't know the exact implications of this...
This is my final code:
//This list is used to properly dispose PrivateFontCollection after usage
static private List<PrivateFontCollection> _fontCollections;
[STAThread]
private static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(true); //Mandatory in order to have Memory fonts rendered in the controls.
//Dispose all used PrivateFontCollections when exiting
Application.ApplicationExit += delegate {
if (_fontCollections != null) {
foreach (var fc in _fontCollections) if (fc != null) fc.Dispose();
_fontCollections = null;
}
};
Application.Run(new frmMain());
}
void frmMain_Load(object sender, EventArgs e)
{
Font font1 = GetCustomFont(Properties.Resources.Amatic_Bold, 25, FontStyle.Bold);
//or...
Font font1 = GetCustomFont("Amatic-Bold.ttf", 25, FontStyle.Bold);
labelTestFont1.Font = font1;
Font font2 = GetCustomFont(Properties.Resources.<font_resource>, 25, FontStyle.Bold);
//or...
Font font2 = GetCustomFont("<font_filename>", 25, FontStyle.Bold);
labelTestFont2.Font = font2;
//...
}
static public Font GetCustomFont (byte[] fontData, float size, FontStyle style)
{
if (_fontCollections == null) _fontCollections = new List<PrivateFontCollection>();
PrivateFontCollection fontCol = new PrivateFontCollection();
IntPtr fontPtr = Marshal.AllocCoTaskMem(fontData.Length);
Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
fontCol.AddMemoryFont(fontPtr, fontData.Length);
Marshal.FreeCoTaskMem(fontPtr); //<-- It works!
_fontCollections.Add (fontCol);
return new Font(fontCol.Families[0], size, style);
}
static public Font GetCustomFont (string fontFile, float size, FontStyle style)
{
if (_fontCollections == null) _fontCollections = new List<PrivateFontCollection>();
PrivateFontCollection fontCol = new PrivateFontCollection();
fontCol.AddFontFile (fontFile);
_fontCollections.Add (fontCol);
return new Font(fontCol.Families[0], size, style);
}
As you can see, I've decided to create an exclusive PrivateFontCollection for each font, then store it to a List for a final disposal on application end.
This was tested in 3 different PC's (both with Windows 7, 32 and 64 bits) and 3 different .ttf fonts.
An example of the result:
I don't know if my approach is good enough, but I expect it could be useful for others!
One more detail:
Unlike what I expected, AddMemoryFont is slower then AddFontFile (21ms vs. 15 ms)
Again, thanks to all comments!
The problem might be since fontfamily exact font needs to be specified while using a fontfile, compiler switches to default font.
You can get the basic idea from the following two methods on what you are missing.
var fontFile = new FontFamily("pack://application:,,,/Resources/#YourFont");
var typeface = new Typeface(new FontFamily(new Uri("pack://application:,,,/"), "/Resources/#YourFont"), FontStyles.Normal, FontWeights.Regular, FontStretches.Normal);
var cultureinfo = new CultureInfo("en-us");
var ft = new FormattedText("YourText", cultureinfo, FlowDirection.LeftToRight,
typeface, 28, Brushes.White)
dc.DrawText(ft, new Point(0,0));
Install font on client system by using resource path.
PrivateFontCollection yourfont = new PrivateFontCollection();
yourfont.AddFontFile("Your font Path");
label1.Font = new Font(yourfont.Families[0], 16, FontStyle.Regular);

How to set Textbox.Font.Size in C#?

I load font.size in a file that this format is string and i want to set textbox.font.size by
this value but say "this value is readonly not set"
how i can set font.size in coding?
By Using this it is possible to programmatically choose the best font. This also allows you to set different sizes on the various alternative fonts.
Font font = new Font("Times New Roman", 16.0f,
FontStyle.Bold | FontStyle.Italic | FontStyle.Underline);
textBox1.Font = font;
For more details, check here
You can Set the Font Property of TextBox Control.
Font Property of TextBox Control Expects Font Class Object.
you can create the Font class oject with different styles by passing different parameters to its constructors.
Font Class Constructor Description :
FontFamily - FontFamily (EnumType) : used to specify Font name
ex:Arial,Times New Roman etc.,
FontSize - float(DataType) : it's a float value of font size.
FontStyle - FontStyle (EnumType) : it is a FontStyle of different
types ex: FontStyle.Regular,FontStyle.Bold,FontStyle.Italic etc.,
Now See sample Example:
Font fnt=new Font(textBox1.Font.FontFamily,12.0F);//Edit your size asper your requirement. it's float value
textBox1.Font = fnt;
Create new font from current font (use it as prototype) and provide font size (parse your string to float):
textBox1.Font = new Font(textBox1.Font, Single.Parse(sizeString));
You have to set it at start of the Initialization of textbox
like
var textbox = new TextBox()
{
FontFamily = "Segoe WP",
FontSize = 18
};
Font.Size is read only. You must set the Font object itself.

Remove FontStyle Bold from a Control's Font

I feel like a real noob posting this, but I can't seem to find anything for this...
I have a control that I'm basically trying to toggle the fontstyle between bold and not bold. This should be simple...
However, you can't acccess the Control.Font.Bold property as it is read only, therefore, you need to change the Font property.
To make it bold, I just do this:
this.btn_buttonBolding.Font = new Font(this.btn_buttonBolding.Font, FontStyle.Bold);
Not ideal, but it works. However, how do I go about removing this bold style (once it is bold already)?
I looked hard for duplicates; closest I could find was this, but it doesn't quite answer my situation:
Substract Flag From FontStyle (Toggling FontStyles) [C#]
And this which gives how to set it, but not remove it: Change a font programmatically
Am I missing a simple constructor for the font that could do this? Or am I just missing something easier?
I know this is a bit old, but I was faced with the exact same problem and came up with this:
Font opFont = this.btn_buttonBolding.Font;
if(value)
{
this.btn_buttonBolding.Font = new Font(opFont, opFont.Style | FontStyle.Bold);
}
else
{
this.btn_buttonBolding.Font = new Font(opFont, opFont.Style & ~FontStyle.Bold);
}
The magic is in the "~" which is the bitwise NOT. (See the MSDN KB article "~Operator")
VB.NET version:
Dim opFont As Font = me.btn_buttonBolding.Font
If (value)
me.btn_buttonBolding.Font = new Font(opFont, opFont.Style Or FontStyle.Bold)
Else
me.btn_buttonBolding.Font = new Font(opFont, opFont.Style And Not FontStyle.Bold)
End if
The FontStyle enum contains 5 distinct values.
The one that reset your previous set is FontStyle.Regular
Regular Normal text.
Bold Bold text.
Italic Italic text.
Underline Underlined text.
Strikeout Text with a line through the middle.
It's a bitwise enum where Regular is 0. So setting this value alone reset all other flags
Try this:
private void btn_buttonBolding_Click(object sender, EventArgs e)
{
var style = btn_buttonBolding.Font.Bold ? FontStyle.Regular : FontStyle.Bold;
btn_buttonBolding.Font = new Font(this.Font, style);
}

Categories

Resources