我在控制台应用程序内部的图像上绘制的文本格式有些轻微问题。我试图绘制的文字是:
BAS2016 = PTR = E30BAS2010 =(S20)$ W30 $ PTO2016 = N5W20N5(W20N10)(S10W20)S5W5S5E10N10(E15N5)(S5E15)S10E25 $ W25N10(W15N5)(S5W15)S10W10S15BAS2020 = S15PTO2013 = S5E20S5(E20S10)(N10E20 )N5E5N5W10S10(W15S5)(N5W15)N10W25 $ E25S10(E15S5)(N5E15)N10E10N15W65 $ $ E65N15
我的方法调用是:
RectangleF rectF = new RectangleF(0, 0, 320, 320);
graphics.DrawString(fullTrav, defaultFont, Brushes.Black, rectF);
该输出是:
此输出仅适用于Rectangle的默认 StringFormat 。它包装很好,但似乎以不同的方式处理字符并在边框之前推送换行符,具体取决于即将发生的字符。我已经尝试 StringFormatFlag.FitBlackBox 无效,但没有经历过每一面旗帜。
我想得到的是:
这个所需的输出看起来更像一个正方形/矩形,并且包含较少的自动换行格式。
答案 0 :(得分:1)
这个小例子(用LINQPad编写)演示了一种方法来包装打破任何字符的文本。您可以根据自己的需要自由定制并改进它(它会泄漏一些资源,并可能会从右侧截断几个像素)。
void Main()
{
var bmp = new Bitmap(320, 320, PixelFormat.Format32bppArgb);
using (var g = Graphics.FromImage(bmp))
{
g.Clear(Color.Gray);
var str = @"BAS2016=PTR=E30BAS2010=(S20)$W30$PTO2016=N5W20N5(W20N10)(S10W20)S5W5S5E10N10(E15N5)(S5E15)S10E25$W25N10(W15N5)(S5W15)S10W10S15BAS2020=S15PTO2013=S5E20S5(E20S10)(N10E20)N5E5N5W10S10(W15S5)(N5W15)N10W25$E25S10(E15S5)(N5E15)N10E10N15W65$E65N15$.";
var font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular, GraphicsUnit.Point);
int lineIndex=0;
double lineHeight = font.Height;
while (str.Length > 0)
{
float lineLength = 0;
int currentChar = 1;
while (lineLength < bmp.Width - 5 && currentChar <= str.Length)
{
string line= str.Substring(0, currentChar);
lineLength = g.MeasureString(line, font).Width;
currentChar++;
}
g.DrawString(str.Substring(0,currentChar-1),font,Brushes.Black,0,(float)Math.Ceiling(lineIndex*lineHeight),StringFormat.GenericDefault);
str = str.Substring(currentChar-1);
lineIndex++;
currentChar=1;
}
}
bmp.Dump();
}
它产生以下输出:
答案 1 :(得分:1)
解决此问题的唯一方法是测量字符串的每个字符,当行长度达到限制时切断行,然后单独打印每行。
代码如下:
using (var graphics = Graphics.FromImage(bmp))
{
PointF ptF = new PointF(last.textPoints.subCode.X, last.textPoints.subCode.Y + 40);
int lineIndex = 0;
double lineHeight = defaultFont.Height;
while (fullTrav.Length > 0)
{
float lineLength = 0;
int currentChar = 1;
while (lineLength < 320 && currentChar <= fullTrav.Length)
{
string line = fullTrav.Substring(0, currentChar);
lineLength = graphics.MeasureString(line, defaultFont).Width;
currentChar++;
}
//
// Optional Code Start
//
while (fullTrav[currentChar - 2].ToString().IndexOfAny("(NSEW".ToCharArray()) != -1)
{
currentChar--;
}
if (currentChar - 1 < fullTrav.Length)
{
while (fullTrav[currentChar - 1].ToString().IndexOfAny("1234567890".ToCharArray()) != -1)
{
currentChar--;
}
}
//
// Optional Code End
//
graphics.DrawString(fullTrav.Substring(0, currentChar - 1), defaultFont, Brushes.Black, ptF.X, ptF.Y + lineIndex * 20, StringFormat.GenericDefault);
fullTrav = fullTrav.Substring(currentChar - 1);
lineIndex++;
currentChar = 1;
}
}
此代码包含和我以前仅在特定字符上打破的可选区域。为了解释一下,它可以防止它分裂&#34; N4&#34;或&#34; W17&#34;在两个不同的行之间它会阻止一个开头的括号&#34;(&#34;来自一行中的最后一个字符。
成品看起来像: