How to get the exact Font out of Fontfamily? - c#

I want to create a Picturebox that adapts its shape to a string of a certain Font. I need this so that I can later create texts and lay it over an AxWindowsMediaPlayer control.
Therefore I created the following class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
namespace myProject
{
class ShapedPictureBoxes : PictureBox
{
public ShapedPictureBoxes()
{
this.Paint += this.shapedPaint;
}
void shapedPaint(object sender, PaintEventArgs e)
{
System.Drawing.Drawing2D.GraphicsPath graphicsPath = new System.Drawing.Drawing2D.GraphicsPath();
Font font = new Font("Arial", 14f);
float emSize = e.Graphics.DpiY*font.Size/72;
graphicsPath.AddString(text, new FontFamily("Arial"), (int)System.Drawing.FontStyle.Regular, emSize, new Point(0,0), new StringFormat());
e.Graphics.DrawString(text, font, Brushes.Red, new Point(0, 0));
this.Region = new Region(graphicsPath);
}
public string text = "Here comes the sun, doo da doo do";
}
}
The problem now is, that the "Graphics.DrawString" does not match the graphicspath.AddString, probably because FontFamily isn't the same as Font. How can I match them?
So: How can I convert Fontfamily to Font or viceversa?
This is how it looks like:

You need to account for the fact that the Font size is specified in units of points, but the AddString() size is specified in device units.
You can convert the units as follows:
Font font = new Font("Arial", 14f, FontStyle.Bold);
float emSize = e.Graphics.DpiY * font.Size / 72; // Here's the conversion.
graphicsPath.AddString(text, new FontFamily("Arial"), (int)System.Drawing.FontStyle.Bold, emSize, new Point(0, 0), new StringFormat());
Note that I'm passing the calculated emSize to AddString() instead of passing 14f.

Related

Bitmap.MeasureString not working as expected

I need to generate a single image, with a single character (letter) in it, which completely fills the image. I found a Bitmap.MeasureString option.
So what I tried to do was measure the size the string would be using this function, and then resizing the image to match, and then draw the letter.
But I am getting loads of white space all around the letter. I need the border of the image to be on the edges of the letter.
So a W would be a wide image, but an I would be a very narrow image.
I drew a line from the top left to bottom right to show what's happening.
Can you spot an issue with my code? Am I maybe misunderstanding this function? Or, it doesn't work as I'd hoped?
In the example image I posted, I want the top border of the image to be on the top border of the A. And the left border touching the bottom right hand of the A. And the bottom being right on the bottom edge of the A.
Here's what I am trying:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
namespace SpikeFontToImage
{
class Program
{
static void Main(string[] args)
{
Bitmap source = new Bitmap(1, 1);
Bitmap destination;
Font stringFont = new Font("Tohoma", 1024);
string text = "A";
using (var measure = Graphics.FromImage(source))
{
var size = measure.MeasureString(text, stringFont);
Console.WriteLine($"{text} is {size} in size");
destination = new Bitmap( (int)size.Width, (int)size.Height);
RectangleF rectf = new RectangleF(0, 0, destination.Width, destination.Height);
StringFormat format = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
//RectangleF rectf = new RectangleF(70, 90, 90, 50);
Graphics g = Graphics.FromImage(destination);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
g.DrawString(text, stringFont, Brushes.Black, rectf, format);
Pen pen = new Pen(Color.GreenYellow, 3);
g.DrawLine(pen, new Point(0, 0), new Point((int)size.Width, (int)size.Height));
g.Flush();
destination.Save(#"c:\temp\ccl.jpg");
}
}
}
}

Alignment in custom winforms label control

I used this answer: Alpha in ForeColor
to create a custom label element that allowed fading through ARGB unlike the default label.
using System;
using System.Drawing;
using System.Windows.Forms;
public class MyLabel : Label {
protected override void OnPaint(PaintEventArgs e) {
Rectangle rc = this.ClientRectangle;
StringFormat fmt = new StringFormat(StringFormat.GenericTypographic);
using (var br = new SolidBrush(this.ForeColor)) {
e.Graphics.DrawString(this.Text, this.Font, br, rc, fmt);
}
}
}
I was curious how I would implement TextAlign into this class allowing the text contents to be aligned correctly.
Thanks to #Aybe's comment, I worked out I needed to add the Alignment to the StringFormat var fmt like this:
fmt.Alignment = StringAlignment.Center;
Making the entire class look like this:
using System;
using System.Drawing;
using System.Windows.Forms;
public class MyLabel : Label {
protected override void OnPaint(PaintEventArgs e) {
Rectangle rc = this.ClientRectangle;
StringFormat fmt = new StringFormat(StringFormat.GenericTypographic);
fmt.Alignment = StringAlignment.Center;
using (var br = new SolidBrush(this.ForeColor))
{
e.Graphics.DrawString(this.Text, this.Font, br, rc, fmt);
}
}
}

Load font and get the characters in C#

I just need to know how I can load a font file and get the characters in an array of data and then call one particular character.
var families = Fonts.GetFontFamilies(#"C:\WINDOWS\Fonts\Arial.TTF");
foreach (FontFamily family in families)
{
}
Hopefully this will give you the idea (untested). Take care to use using or explicitly dispose your graphics objects:
using System.Drawing;
using System.Drawing.Imaging;
...
// Create your bitmap - 100x100 pixels for example
using (Bitmap b = new Bitmap(100, 100))
{
using (Graphics g = Graphics.FromImage(b))
{
g.Clear(Color.White); // White background
using (FontFamily fontFamily = new FontFamily("Arial"))
{
using (Font font = new Font(fontFamily, 24, FontStyle.Regular, GraphicsUnit.Pixel))
{
using (SolidBrush solidBrush = new SolidBrush(Color.Red)) // Red text
{
g.DrawString("A", font, solidBrush, new PointF(10, 10)); // Draw an "A" at position 10,10
}
}
}
}
b.Save(Response.OutputStream, ImageFormat.Jpeg); // return to response, for example
}
}

How to print rectangle with exact size in c#?

I am new to Dot Net, I want to print a rectangle with 20mm width and 8mm height exactly if I measure with scale. I also want to print text exactly in the middle of rectangle.Can anyone suggest me how can I achieve this?
I am really sorry for not being clear earlier. I have tried using "PageUnits" its working fine. However, I have problem with the margins.
I am able to print correct margins(8.8mm left and 22mm Top) if I am using the printer "HP LaserJet P2035n". If print using "Canon iR2020 PCL5e" I am getting incorrect margins(8.1mm left and 8.0mm Top) where I should get 8.8mm left and 22mm top margins. Can someone explain me where I am doing wrong.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Printing;
namespace ConsoleApplication6
{
class DrawShape
{
public static void DrawRec()
{
PrintDocument doc = new PrintDocument();
doc.PrintPage += doc_PrintPage;
doc.Print();
}
static void doc_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
PageSettings PageSet = new PageSettings();
float MarginX = PageSet.PrintableArea.X;
float MarginY = PageSet.PrintableArea.Y;
float x = (float)(8.8-((MarginX/100)*25.4));
float y = (float)(22-((MarginY/100)*25.4));
g.PageUnit = GraphicsUnit.Millimeter;
g.DrawRectangle(Pens.Black, x, y, 20, 8);
}
}
}
You may want to start with this:
private void button1_Click(object sender, EventArgs e)
{
using (Graphics formGraphics = this.CreateGraphics())
{
formGraphics.PageUnit = GraphicsUnit.Millimeter;
formGraphics.DrawRectangle(Pens.Blue, 0, 0, 20, 80);
}
}
You can then using DrawString on the Graphics object to draw text inside your rectangle.

Get fontsize from PDF using itextsharp

While extracting text from PDF I need to extract font-size too. First I had extracted like this:
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(
curBaseline[Vector.I1],
curBaseline[Vector.I2],
topRight[Vector.I1],
topRight[Vector.I2]);
In this I am not able to get exact font size. After that I tried using renderinfo.gs.fontsize;. In this renderinfo.gs.fontsize I will get a few text font size exact one but few I won't get exact font size. Where I will get font size has "1.0". Can anyone tell me the method I am using is correct. If NO is there any other method to extract font size using iTextSharp. I am using iTextSharp 5.4 version. Thank you in advance.
using System;
using System.Collections;
// code java to C# conversion
public void renderText(TextRenderInfo renderInfo)
{
LineSegment curBaseline = renderInfo.Baseline;
LineSegment curAscentline = renderInfo.AscentLine;
Rectangle rect = new Rectangle(curBaseline.StartPoint.get(ArrayList.I1), curBaseline.StartPoint.get(ArrayList.I2), curAscentline.EndPoint.get(ArrayList.I1), curAscentline.EndPoint.get(ArrayList.I2));
try
{
Console.Write(" [{0,6:F2}, {1,6:F2}, {2,6:F2}] \"{3}\" ({4} at {5,6:F2})\n", rect.Width, rect.Height, getEffectiveFontSize(renderInfo), renderInfo.Text, renderInfo.Font.FullFontName[0], getFontSize(renderInfo));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.Write(e.StackTrace);
}
}
float getEffectiveFontSize(TextRenderInfo renderInfo) throws System.ArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, NoSuchMethodException
{
Method convertHeight = typeof(TextRenderInfo).getDeclaredMethod("convertHeightFromTextSpaceToUserSpace", float.TYPE);
convertHeight.Accessible = true;
return (float?)convertHeight.invoke(renderInfo, getFontSize(renderInfo));
}
float getFontSize(TextRenderInfo renderInfo) throws SecurityException, NoSuchFieldException, System.ArgumentException, IllegalAccessException
{
Field gsField = typeof(TextRenderInfo).getDeclaredField("gs");
gsField.Accessible = true;
GraphicsState gs = (GraphicsState) gsField.get(renderInfo);
return gs.FontSize;
}
Hope this would be useful
`
Font arial = FontFactory.GetFont("Arial", 28, Color.GRAY);
Font verdana = FontFactory.GetFont("Verdana", 16, Font.BOLDITALIC, new Color(125, 88, 15));
Font palatino = FontFactory.GetFont("palatino linotype italique",BaseFont.CP1252, BaseFont.EMBEDDED,
10,
Font.ITALIC,
Color.GREEN
);
Font smallfont = FontFactory.GetFont("Arial", 7);
Font x = FontFactory.GetFont("nina fett");
x.Size = 10;
x.SetStyle("Italic");
x.SetColor(100, 50, 200);`
can be used to set font size

Categories

Resources