How do I get all installed fixed-width fonts? - c#

I'm wondering if there are any simple ways to get a list of all fixed-width (monospaced) fonts installed on a user's system in C#?
I'm using .net 3.5 so have access to the WPF System.Windows.Media namespace and LINQ to get font information, but I'm not sure what I'm looking for.
I want to be able to provide a filtered list of monospaced fonts and/or pick out monospaced fonts from a larger list of fonts (as seen in the VS options dialog).

Have a look at:
http://www.pinvoke.net/default.aspx/Structures/LOGFONT.html
Use one of the structures in there, then loop over families, instantiating a Font, and getting the LogFont value and checking lfPitchAndFamily.
The following code is written on the fly and untested, but something like the following should work:
foreach (FontFamily ff in System.Drawing.FontFamily.Families)
{
if (ff.IsStyleAvailable(FontStyle.Regular))
{
Font font = new Font(ff, 10);
LOGFONT lf = new LOGFONT();
font.ToLogFont(lf);
if (lf.lfPitchAndFamily ^ 1)
{
do stuff here......
}
}
}

Unfortunately ToLogFont function does not fill lfPitchAndFamily field to correct values. In my case it's always 0.
One approximation to detect which fonts might be fixed is the following
foreach ( FontFamily ff in FontFamily.Families ) {
if ( ff.IsStyleAvailable( FontStyle.Regular ) ) {
float diff;
using ( Font font = new Font( ff, 16 ) ) {
diff = TextRenderer.MeasureText( "WWW", font ).Width - TextRenderer.MeasureText( "...", font ).Width;
}
if ( Math.Abs( diff ) < float.Epsilon * 2 ) {
Debug.WriteLine( ff.ToString() );
}
}
}
Keep in mind that they are several false positives, for example Wingdings

AFAIK you can't do it using BCL libraries only. You have to use WinAPI interop.
You need to analyze 2 lowest bits of LOGFONT.lfPitchAndFamily member. There is a constant FIXED_PITCH (means that font is fixed-width) that can be used as a bit mask for lfPitchAndFamily.
Here is a useful article:
Enumerating Fonts
Enumerating fonts can be a little
confusing, and unless you want to
enumerate all fonts on your system,
can be a little more difficult than
MSDN suggests. This article will
explain exactly the steps you need to
use to find every fixed-width font on
your system, and also enumerate every
possible size for each individual
font.

Related

Check a Font for a 32bit Unicode Glyph [duplicate]

How can I determine from the .NET runtime if, for a given font, if it has the glyph for a character? I want to switch the font to Arial Unicode MS if I have text that the specified font does not have a glyph for (very common for CJK).
Update: I'm looking for a C# (ie all managed code) solution. I think GlyphTypeface may be what I need but I can't see a way in it to ask if a given character has a glyph. You can get the entire map back, but I assume that would be an expensive call.
I've done some unicode tools and the technique I use is getting the map and chache it
for each font used.
IDictionary<int, ushort> characterMap = GlyphTypeface.CharacterToGlyphMap
will give you the defined glyph index per codepoint.
msdn ref
if (characterMap.ContainsKey(CodePoint))
glyphExists = true;
else
glyphExists = false;

C# WinForms Text size issue (actually cant understand the result)

As a part of a bigger project I wrote the terminal emulator. Everything work file except one problem. I do not understand the connection between the values properties of the font (size) and screen pixels.
Font
TermFont = new Font(FontFamily.GenericMonospace, fsize, GraphicsUnit.Pixel);
Tested with another units as well.
number of characters I can display (both methods and both do not work).
//FontSizef = tg.MeasureString(testString, TermFont);
//int xchars = (int)(p.Width / FontSizef.Width) + 1;
//int ychars = (int)(p.Height / FontSizef.Height);
int xchars = (int)(p.Width / TermFont.Size) + 1;
int ychars = (int)(p.Height / TermFont.Height);
The first measuring method (commented). I measure the size of the one character string. As it is monospaced font all letters should have the same size. Tested both methods. Result is exactly the same.
The problem
It is giving me too low number of characters
So it looks like this:
Probably I do not understand how the unit system works.
Help appreciated ::

C# Zxing Encode 1d EAN8

I want to generate a 1D EAN8 barcode using c# Zxing. I have only been able to find code examples and documentation for generating 2D QR-code
var writer = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new QrCodeEncodingOptions
{
Height = height,
Width = width
}
};
return writer.Write(textForEncoding);
which I can run and works fine, but there is no "1DCodeEncodingOptions" or similarly named function. I tried
var writer = new BarcodeWriter
{
Format = BarcodeFormat.EAN_8
};
return writer.Write("1234567");
but it throughs an index error.
edit: I have the syntax correct now but it is not producing a proper barcode because I do not know the size it expects, and there seems to be no default.
using ZXing;
Using ZXing.OneD
var writer = new BarcodeWriter
{
Format = BarcodeFormat.EAN_8,
Options = new ZXing.Common.EncodingOptions
{
Height = 100,
Width = 300
}
};
return writer.Write("12345678");
12345678 is not a valid EAN8 barcode. The check digit for 1234567 is 0. See EAN 8 : How to calculate checksum digit? for how to calculate checksums.
ZXing won't stop you creating invalid barcodes (at least in the version 0.11 I'm using, although the current source on Codeplex looks like it does), but they won't scan. The scanner uses the checksum to ensure that it has read the data correctly.
If you intend to use an EAN8 in commerce, you will need to get a GTIN-8 from your national GS1 Member Organization. If you only intend to sell them in your store, you should use one of the restricted distribution prefixes.
If you don't need to put your products in the retail supply chain, I'd recommend a different barcode format.
Interleaved 2 of 5 (BarcodeFormat.ITF) is very compact but can only contain digits; it doesn't have any self-checking and there's a design flaw that allows the barcode to be misread from some angles. It's recommended that you put black bars (called Bearer Bars) across the top and bottom of the barcode. I can't see an option for this in ZXing.
The next most compact format is Code 128 (BarcodeFormat.CODE_128), using Code Set C. This encodes two digits in one module (one block of six bars and spaces). The format is self-checking (there is always a check character, which is stripped off by the scanner). Some scanners don't handle Code Set C properly. To force Code Set B, use Code128EncodingOptions in place of Common.EncodingOptions and set ForceCodesetB to true.

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.

How to detect superscript with ItextSharp?

Hy
I am using ITextSharp to parse a pdf file to text output.
I want to know if I can catch if the pdf contains subscript or superscript, does anyone knows how to make the difference between a normal character and a superscript in a pdf using ITextSharp, or other library ?
Thanks
Disclaimer: I don't actually have any evidence for this but...
I would expect super/subscript to be identical to normal text. It's the same font, just smaller. If it happens to be on the same line as other text, super/sub scripts are raised and lowered - but you won't be able to detect that with some explicit meta-tag in a layout-oriented format such as PDF.
In other words, I'd guess that you need to identify super/subscripts by heuristics: finding text that's smaller and vertically displaced compared to other text on the "same" line. Whether that's easy to do or not depends on the PDF creator and the details of ITextSharp, since even identifying a "line" is not necessarily straightforward.
You are going to have to implement a bit of custom logic here. There is no tag denoting superscript/subscript in PDF, it is simply sitting upon a different baseline. In cases such as this, you will have to note your baseline (along with your height).
Some quick pseudo-code:
//input -> curText
if(curText.Baseline > previousText.Baseline &&
curText.Baseline < (prevText.Baseline + prevText.Height))
{
// This is most likely superscript //
}
else if(curText.Baseline < previousText.Baseline &&
prevText.Baseline < (curText.Baseline + curText.Height))
{
// This is most likely subscript //
}
else
{
// This is probably normal text //
}
This solution requires you to organize the thoroughly unorganized nature of a PDF file. In the past I have used List<> of a custom class meant to organize all text of a given y coordinate into arrays. Using something like this you can then compare the separate lines and do whatever work to them you might want before painting or otherwise transmitting them.

Categories