Some Unicode characters not appearing - c#

I'm trying to replicate (not an exact replica) the CharMap program from windows in my program for inserting and adding symbols. Problem is that the symbols would work on a machine with Windows 7, 8 10 but some symbols wouldn't show on Windows XP.
Windows XP
Windows 7, 8, 10
I'm currently using the below to generate my symbols:
public static string CharToHex(char c)
{
return ((ushort)c).ToString("X4");
}
string x = CharToHex(Convert.ToChar(defaultSymbolsCollection[i]));
int value = int.Parse(x, System.Globalization.NumberStyles.HexNumber);
string symbol = char.ConvertFromUtf32(value).ToString();
AddSymbol(Convert.ToString((char)value);
Void AddSymbol(string _symbolText)
{
Button symbolButton = new Button()
{
Text = _symbolText,
Size = new Size(32, 32),
Font = new Font("Arial Unicode MS", 9),
Tag = _symbolText,
UseMnemonic = false,
};
symbolButton.Click += SymbolButton_Click;
pnl_SymbolHolder.Controls.Add(symbolButton);
}
This ends up working only on Windows 7, 8, 10 but not on Windows XP. some symbols don't show, instead is represented by a square and others do.
How do I go about solving this problem? my other alternative was to draw the symbols at the center of the button that way it's always there regardless because it was drawn but I would like to see other alternatives, perhaps a solution to this problem

The font "Arial Unicode MS" is not included with Windows XP/7/8/10, but is included with some Microsoft Office products. Windows XP is likely using "Tahoma" instead (the default UI font), which does not include glyphs for those symbols (whereas "Segoe UI", the default UI font on Windows 7/8/10, does).
For the characters to appear correctly, you will need to find/install/use a font that has glyphs for those characters.

Related

Odd behavior on specific computers when cropping with AForge

I recently built a .NET image processing application using the AForge.NET library. The program works fine on all of the 10 computers at my place of business where it is installed except for two. On these two computers, when the user attempts to crop an image, it does not crop at the proper coordinates. Everything is shifted down and to the right. The computers are a mix of Windows 7 and Windows 10 computers. The two computers exhibiting the strange behavior are both Windows 7 computers but it works on the other 5 Windows 7 computers that it is installed on. I have verified that every computer is running the latest version of the .NET Framework and tested the program on these computers with images acquired from working systems to verify that it isn't a problem with the format of their images. I am at a loss. If anyone out there has seen something like this before or has experience with AForge compatibility issues, please let me know. Thanks in advance!
I don't know how much my source code will help but here is the code for the cropping function. If additional code from other areas of the application are needed then I can provide them. Thanks again.
private void GetImage(object sender, EventArgs e)
{
int astartatX = (int)initial.X;
int astartatY = (int)initial.Y;
int aXdist1 = (int)(Final.X - initial.X);
int aYdist1 = (int)(Final.Y - initial.Y);
Crop anewcropper = new Crop(new Rectangle(astartatX * 8 - 125, astartatY * 8 - 125, aXdist1 * 8 + 250, aYdist1 * 8 + 250));
Bitmap bmpToCrop = (Bitmap)Editor.Image;
Bitmap anewcroppedImage = anewcropper.Apply(bmpToCrop);
string processedpath = Path.Combine(pictures, baseprocessedpath);
string newbaseFilename = Path.Combine(processedpath, "comic.jpg");
string anewFilename = newbaseFilename.Insert(newbaseFilename.Length - 4, number.ToString());
bmpToCrop.Dispose();
anewcroppedImage.Save(anewFilename);
Editor.Image = anewcroppedImage;
Editor.SizeMode = PictureBoxSizeMode.StretchImage;
}

How do I make the reported font em height consistent across machines

I am calculating font metrics in a rendering service using C# .Net 4.5 running on four computers, three running running Windows 8.1, one running Server 2008 R2, all are up to date with various updates.
In the service code I use the following to get some font metrics:
int emHeight = font.FontFamily.GetEmHeight(font.Style);
int lineSpacing = font.FontFamily.GetLineSpacing(font.Style);
I then use these values to calculate the height in pixels to render some text to a bitmap using GDI+ DrawString.
I'm setting the Graphics options as follows:
gfx.PageUnit = GraphicsUnit.Pixel;
gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
However the metric values being reported are different, and two machines agree it's one value and the other two agree it's a different value.
On machine 1 and machine 2 the em height is reported as 1000, on machine 3 and the server (machine 4) it is reported as 2048.
The line height on machines 1 and 2 is reported as 1213, and on machines 3 and 4 it is reported as 2371.
The resulting heights are 51 and 48, which are just different enough to cause problems.
I've been looking into font metrics and it seems you can specify the font design units per em in the font and the values are traditionally 1000 on a mac and more recently 2048 on Windows, however all machines are using the same binary font file.
Is there a way to tell the font to use design units I specify in the code rather than an arbitrary value retrieved from the operating system, OR is there a way to make this value consistent across all 4 machines by changing a system value or registry entry?
I've checked the visual DPI display settings and they are the same across devices as are the clear type settings. I'm not sure where any other settings are that will help.
Edit -
It doesn't matter what the values are, just that they are being reported inconsistently across the machines.
I'm loading the fonts using the Font and FontFamily classes and I have installed the same font files on all of the machines.
The font the issue became apparent on was FranklinGothicNew, but it affects many fonts including Eurasia, Greyhound, and Lightfoot.
I wrote a quick checking program to run on each machine to highlight the differences.
foreach (var f in fontList) {
try {
var font = new Font(f, 10, FontStyle.Regular);
int emHeight = font.FontFamily.GetEmHeight(font.Style);
Console.WriteLine("{0}: {1}", f, emHeight);
}
catch {
Console.WriteLine("{0}: {1}", f, "unknown");
}
}

POS Application Development - Receipt Printing

I've been building a POS application for a restaurant/bar. The design part is done and for the past month I've been coding it. Everything works fine except now I need to print. I have to print to a receipt printer connected to the computer running the software and later I'll try to print in a remote printer like a kitchen one.
I've searched for help in the matter only to find that the standard for printing in these types of printers is using POS for .NET. The thing is, this is now a bit outdated or at least it hasn't had any updates since a couple of years. There's a lot of questions being asked on how to use this library and most of the answers aren't quite easy to follow. So if anybody could give a step by step help on printing like a simple phrase ("Hello World") on a receipt printer i would be very grateful. I'm using visual studio 2012 running on a 64 bit windows 7 and i'm coding WPF in c#.
I know this is an old post, but for those still looking for a solution, I can tell you what I did.
After spending many hours messing with OPOS and POS for .Net, I ended up just abandoning those and just using the built-in System.Drawing.Printing libraries. The OPOS and POS for .Net ended up being a pain to get working and ultimately didn't work as well as the built-in libraries.
I'm using an Epson TM-T20II receipt printer.
Here's some code that worked well for me.
public static void PrintReceiptForTransaction()
{
PrintDocument recordDoc = new PrintDocument();
recordDoc.DocumentName = "Customer Receipt";
recordDoc.PrintPage += new PrintPageEventHandler(ReceiptPrinter.PrintReceiptPage); // function below
recordDoc.PrintController = new StandardPrintController(); // hides status dialog popup
// Comment if debugging
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = "EPSON TM-T20II Receipt";
recordDoc.PrinterSettings = ps;
recordDoc.Print();
// --------------------------------------
// Uncomment if debugging - shows dialog instead
//PrintPreviewDialog printPrvDlg = new PrintPreviewDialog();
//printPrvDlg.Document = recordDoc;
//printPrvDlg.Width = 1200;
//printPrvDlg.Height = 800;
//printPrvDlg.ShowDialog();
// --------------------------------------
recordDoc.Dispose();
}
private static void PrintReceiptPage(object sender, PrintPageEventArgs e)
{
float x = 10;
float y = 5;
float width = 270.0F; // max width I found through trial and error
float height = 0F;
Font drawFontArial12Bold = new Font("Arial", 12, FontStyle.Bold);
Font drawFontArial10Regular = new Font("Arial", 10, FontStyle.Regular);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Set format of string.
StringFormat drawFormatCenter = new StringFormat();
drawFormatCenter.Alignment = StringAlignment.Center;
StringFormat drawFormatLeft = new StringFormat();
drawFormatLeft.Alignment = StringAlignment.Near;
StringFormat drawFormatRight = new StringFormat();
drawFormatRight.Alignment = StringAlignment.Far;
// Draw string to screen.
string text = "Company Name";
e.Graphics.DrawString(text, drawFontArial12Bold, drawBrush, new RectangleF(x, y, width, height), drawFormatCenter);
y += e.Graphics.MeasureString(text, drawFontArial12Bold).Height;
text = "Address";
e.Graphics.DrawString(text, drawFontArial10Regular, drawBrush, new RectangleF(x, y, width, height), drawFormatCenter);
y += e.Graphics.MeasureString(text, drawFontArial10Regular).Height;
// ... and so on
}
Hopefully it helps someone skip all the messing around with custom drivers. :)
POS for .NET is probably the way to go.
Most receipt printer manufacturers will provide an OPOS service object.
And as this MSDN article states, POS for .NET is compatible with OPOS v1.8 service objects.
OPOS / UPOS (on which POS for .NET is based) is IMHO a poorly-designed API (designed by device manufacturers rather than application developers), but it's the best you have today.
I don't have any specific samples but the basics are the same as OPOS - you need to Open, Claim, Enable a device, then you can call its methods (such as Print). You might try looking at an OPOS sample, for example this PosPrinter1 sample, which will probably be very similar to POS for .NET.
This blog has some information about setting up POS for .NET that might be helpful.
UPDATE
Here's a VB Hello World for an OPOS printer. You first need to create a printer and add it to the registry with the required Logical Device Name = LDN. I believe the Epson ADK includes a utility to add a printer in the registry. This utility can also perform a health check on the printer to check it is installed correctly. Once you've done this, it should be easy enough to adapt the code below to POS for .NET
OPOSPOSPrinter.Open "MyPrinter" ' LDN of your printer
OPOSPOSPrinter.Claim 500 ' Timeout
OPOSPOSPrinter.DeviceEnabled = True
'- Print
OPOSPOSPrinter.PrintNormal 2, "Hello world"
'- Close the printer
If OPOSPOSPrinter.Claimed then
OPOSPOSPrinter.Release
End If
OPOSPOSPrinter.Close
.NET Printing
Printing under .NET isn't too difficult. Take a look here and on msdn.
Printing to a POS / receipt printer will be the same as printing to any other printer, assuming it is a Windows printer, network or otherwise. If you are using a serial printer, things may be a little more difficult because you will more then likely need to use manufacturer specific API's, fortunately though most good POS printers these days are fully supported by the OS.
First, you will need to add a reference to System.Printing dll to your project.
Then printing is as simple as
private void PrintText(string text)
{
var printDlg = new PrintDialog();
var doc = new FlowDocument(new Paragraph(new Run(text)));
doc.PagePadding = new Thickness(10);
printDlg.PrintDocument((doc as IDocumentPaginatorSource).DocumentPaginator, "Print Caption");
}
To use..
PrintText("Hello World");
You can also leverage the PrintDialog.PrintVisual and define your document using xaml template.
The print settings can be set using the PrintDialog properties.
Getting the printer you want to print to
private PrintQueue FindPrinter(string printerName)
{
var printers = new PrintServer().GetPrintQueues();
foreach (var printer in printers)
{
if (printer.FullName == printerName)
{
return printer;
}
}
return LocalPrintServer.GetDefaultPrintQueue();
}
A few things to keep in mind though when printing to a receipt printer, you will need to take into account formatting. More specifically you will need to consider the width of your page and how many characters you can fit on each line; this was a lot of trial and error for me, especially with different font sizes.
In most cases you don't really need to worry about paging, the printer will cut the paper automatically when it has completed your document.
If you want to print at the full speed of the printer, you will probably need to use printer-specific escape codes, and generate the "raw" output.
Have a look at Michael Buen's answer to this SO question, especially the UPDATE bit.

Why is there no exception if using not existing font? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Test if a Font is installed
let say Im using an installed font on the system:
new System.Drawing.Font("Arial", 120F);
everything is fine. Now if I would use a not existing font:
new System.Drawing.Font("IdoNotExistHaHa", 120F);
I dont get any exception. As I see, if I use a font that doesnt exist I get a standard font (arial?, not sure). Whatever, I would like to throw an exception if there is a not found font. How to?
MSDN says as following :
For more information about how to construct fonts, see How to:
Construct Font Families and Fonts. Windows Forms applications support
TrueType fonts and have limited support for OpenType fonts. If you
attempt to use a font that is not supported, or the font is not
installed on the machine that is running the application, the
Microsoft Sans Serif font will be substituted.
You can check the if the font is correct by doing as following :
var myFont = new Font(fontName)
if (myFont.Name != fontName )
{
throw new Exception()
}
You can see it in documentation itself, Font Constructor (String, Single)
Windows Forms applications support TrueType fonts and have limited
support for OpenType fonts. If the familyName parameter specifies a
font that is not installed on the machine running the application or
is not supported, Microsoft Sans Serif will be substituted.
In short, default font is Microsoft Sans Serif
You could check and see if the font is installed first.
From Jeff Hillman's answer here: Test if a Font is installed
string fontName = "Consolas";
float fontSize = 12;
Font fontTester = new Font(
fontName,
fontSize,
FontStyle.Regular,
GraphicsUnit.Pixel );
if ( fontTester.Name == fontName )
{
// Font exists
}
else
{
// Font doesn't exist
}
Obviously, you could then throw an exception if you wanted(as that is your original question), although I would recommend not to, throwing an exception is an expensive operation if you can handle the issue more gracefully without.

How to draw unicode string using C# graphics.DrawString

I'm trying to send khmer script(unicode) string to printer using PrintDocument provided by the .NET framework.
Unfortunately it seems to me that the Graphics.DrawString() does not render khmer script correctly.
Platform: Windows 7 Ultimate
IDE: VS 2010 Ultimate
Here is the sample code:
void printDoc_PrintPage(object sender, PrintPageEventArgs e)
{
var font = new Font("Khmer UI", 12);
var text = "សួស្តី"; // "Hello"
e.Graphics.DrawString(text, font, Brushes.Black, 100, 100);
}
mann,
I tested your code on a Form_Paint() handler, and I got exactly what you said.
But when I used this instead:
TextRenderer.DrawText(e.Graphics, text, font, new Point(100, 100), Color.Black);
It gave me the text the way you wanted it.
Try that on your printDoc_PrintPage().
Thanks Albin and Beemer for your active response.
After a few posts in c# google group. It's been confirmed that there is a bug in GDI+ that incorrectly show certain script ("Khmer" in this case) to a different wording.
A native win32 test application was created to verify the issue with GDI+ DrawString().
A bug report has been submitted to Microsoft Connect: http://connect.microsoft.com/VisualStudio/feedback/details/620081/

Categories