System.Drawing.FontFamily->IsStyleAvailable always returns true - c#

Im using a PrivateFontCollection to load a font via the AddMemoryFont. I retrieve the FontFamily, and then I query it using IsStyleAvailable to determine what the font supports as styles. However, with myriad fonts every single call to IsStyleAvailable returns true.
PrivateFontCollection pfc = new PrivateFontCollection();
var fontBuffer = Marshal.AllocCoTaskMem(dta.Length);
Marshal.Copy(dta, 0, fontBuffer, dta.Length);
pfc.AddMemoryFont(fontBuffer, dta.Length);
System.Drawing.FontFamily fam = pfc.Families[0];
if (fam.IsStyleAvailable(d.FontStyle.Bold)) //do something
Does anyone know how to get the actual style information from the FontFamily? If you look at the C:\Windows\Fonts folder you can see the supported styles. For example: Agency FB supports Bold; Regular, but when I query it in this fashion I get styles for Underline, Strikeout, and Italic, as well as Bold and Regular.
Is there a better way to go about this?

The font engine in Windows knows how to synthesize a style from the unstyled base font. It isn't particularly difficult to do on paper, just makes the stems fatter to get bold, tilt them to get italic, draw a line to get underline or strike-out. It isn't exactly as pretty as the dedicated outlines that a good designer will create but it certainly gets the job done. So when you ask "can you do that?" then you'll get a resounding "sure thing!"
Since you explicitly added the TTF files, you already know what styles are directly supported without synthesis and should not need to ask. Finding out anyway is perhaps possible with pinvoke and/or digging through the TTF tables but it is going to be ugly and certainly not directly supported by .NET. There's no winapi function I know of that tells you directly.

Related

Powerpoint "Save As Picture" from C# Microsoft.Office.Interop.PowerPoint

My question is pretty similar to this one and I'm afraid the answer is the same... I want to save all the shapes/images on a slide as a single png (or jpeg). Programmatically, I get as far as
slide.Shapes.SelectAll();
but don't see a way to save as image. Is this possible? If not, any other suggestions, hopfully w/ examples? (not VBA - I need to automate the whole conversion)
There was a reference to OpenXML in the other post, but I'm not even sure how to pull that in.
I don't know how you'd do this in C# but I'd guess that you'd make use of the same methods as you would with VBA, where you can do:
Activewindow.Selection.ShapeRange.Export( "c:\temp\delete-me.jpg",ppShapeFormatJPG)
ppShapeFormatJPG is a PowerPoint constant, a VBA Long = 1; IIRC that'd be an Integer in C#.
The method also can take two more optional parameters, scalewidth and scaleheight, which govern the width and height of the exported image in undocumented ways. By default, no parms supplied, I get exports at 72 dpi. Larger numbers result in higher pixel count exports but distorted proportions. I'm sure there's some strange logic to it, but it escapes me; all hints welcome!
There's a third optional parm, ExportMode. In my tests, it makes no difference whether you supply it or not, and if you do, which of the available values you choose.

Loading font-family from disk to PrivateFontCollection

I'm using the following code to load a font into memory for generating an image with GDI+:
var fontCollection = new PrivateFontCollection();
fontCollection.AddFontFile(Server.MapPath("~/fonts/abraham-webfont.ttf"));
fontCollection.Families.Count(); // => This line tells me, that the collection has 0 items.
There are no exceptions, but the fontCollection Families property is empty after the AddFontFile method has run without any exceptions.
I've verified that the path is valid (File.Exists returns true):
Response.Write(System.IO.File.Exists(Server.MapPath("~/fonts/abraham-webfont.ttf"))); // # => Renders "True"
The TTF-file seems to work fine, when I open the file, so it's not an invalid TTF-file:
Any suggestions?
Answer from Hans Passant solved the problem:
PrivateFontCollection is notoriously flakey. One failure mode that's pretty common today is that the font is actually an OpenType font with TrueType outlines. GDI+ only supports "pure" ones. The shoe fits, the web says that Abraham is an OpenType font. Works in WPF, not in Winforms.

How to get the maxlength of the string a specific RichTextBox control can show on the same line?

I'm using the regular System.Windows.Form.RichTextBox control for a WinForm application running on the .NET Framework 2.0 to show a status log. Since the Form and several other child controls, have AutoSize=True, the application does not always look the same way on different setups. I have no way to know in advance the exact size of the control and anyway I guess there are some implications related to the ratio (font appearence)/(gui dimensions) of each particular configuration.
So now let's depict the most dynamic scenario. I want to know what's the exact maximum length of the string, a given RichTextBox can show on the same line (without exceeding the border nor word wrapping) where such a RichTextBox is using a generic and known, monospaced font and size.
In case there's no any straightforward way to accomplish this result, does anyway know if I may use any kind of trick like injecting an incrementally growing test string till some weird event gets fired?
That's what I got till now. I used the TextRenderer class and the strategy I anticipated on my question above. Of course it makes sense only if the control uses a monospaced font. Despite it works for my problem, I'm still curious to know if anyone knows a better way to reach the same goal. So the question will still be open for a while.
int maxStringLength = GetMaxStringLengthPerLine(myRichTextBox);
int GetMaxStringLengthPerLine(RichTextBox textbox) {
return GetMaxStringLength(textbox.Size.Width, textbox.Font);
}
int GetMaxStringLength(int width, Font font) {
int i = 0;
while(TextRenderer.MeasureText(new string('A',++i), font).Width<=width);
return --i;
}

Using Imageresizer Watermark plugin to write text: Centered, width and line feeds

I'm trying to use the watermark plugin to write text on images for my project. Right now I'm trying to find out how to set a "width" for a writing box so I can get automatic line returns. Is there a way to do this with the watermark plugin?
Also I'm trying to see if I can get a "text-align: center" effect when I'm writing my text (possibliy in relation to that set width), how could I get that setup?
I'm thinking that the alternative to this would be to have code driven line returns and centering, but this would mean that I would have to count the width of my characters and this seems like a world of pain hehe
Here is a code sample that shows what I'm doing (this currently works):
var c = Config.Current;
var wp = c.Plugins.Get<WatermarkPlugin>();
var t = new TextLayer();
t.Text = panty.Message;
t.TextColor = (System.Drawing.Color) color;
t.Font = fonts[myFunObject.Font];
t.FontSize = fontSize[myFunObject.LogoPosition];
t.Left = new DistanceUnit(5, DistanceUnit.Units.Pixels);
t.Top = new DistanceUnit(5, DistanceUnit.Units.Pixels);
wp.NamedWatermarks["myFunObjectMessage"] = new Layer[] { t };
EDIT: I also have to mention that the text I'm writing is user submitted so it's different everytime. If you want a similar case, think about thos funny cat images with funny text captions on them. This project is quite similar to that. (Minus the cats)
Thanks for the help!
Basically, System.Drawing (and therefore the current version of Watermark) are very primitive about line wrapping.
As you mentioned, you can do hacky stuff with character counting and separate MeasureString calls with loops, but the results are only barely acceptable.
You may try to fork the Watermark source code and hack support for your use case. I don't see a way to improve Watermark in a generic way without replacing the underlying graphics engine first (which may happen anyway).
System.Drawing has unsurpassed image resampling quality. Text wrapping, though, it kind of stinks at.

handling pixels in xsl fo

I have a Web front end and I am trying to handle layout with tables, because my tables all contain a col with a width- in pixels, what is the best way to handle it inside the pdf to get a consistent layout...?
I am using fo.net and the code I use to convert pixels to in is: However on different machines I am getting inconsistent results...
<xsl:value-of disable-output-escaping="yes" select="floor(#width div 72)"/>
<xsl:text>in</xsl:text>
Is there a way using c# to get the screen resolution and any other info to get a more accurate result?
To answer my own question... use % with a fixed max width on the table, that way I can get the Xsl to work out the % of each column based on the total width of a table. This workaround seems like the best and most felxible way to handle my situation, the biggest problem is, pixels cannot be translated into xsl fo - if a person is working on a page then moves onto a different machine the outputted pdf could be drastically different.
On the note: I would like for mm to be supported alongside pixels in WYSIWYG editors... as I am using jquery client side I will most likely enhance my tables therefore requiring me to create this plugin. I hope this info helps anyone else who wants to create pdfs from client side WYSIWYG editors, I am sure this info can be applicable for other scenarios too... :)
In the class 'System.Windows.Forms.Screen' there are several functions and values concerning the screen.

Categories