Ну, я пытаюсь создать метод, который делает drawString с пользовательским пробелом.
Для 1 строки это совершенно готово, но когда у меня разрывная строка \n
, следующая строка начинается посередине, и я не знаю почему. (Этот метод должен работать в строке с 32 + символами).
И когда я ставлю formatString.Alignment = StringAlignment.Center
и formatString.LineAlignment = StringAlignment.Center
, строка не централизуется, и я не знаю, почему снова.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Collections.Generic;
namespace TryApp
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(827, 292);
this.Name = "Form1";
this.Text = "Form1";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
MeasureCharacterRangesRegions(e);
}
public void MeasureCharacterRangesRegions(PaintEventArgs e)
{
//
// Get a more convenient graphics object.
Graphics g = e.Graphics;
// Set up string.
string measureString = "This is a test string and \n We have a break line.";
int numChars = measureString.Length;
int numCharsLeft = measureString.Length;
double numRanges = Math.Ceiling((double) numChars / 32);
Font stringFont = new Font("Times New Roman", 16.0F);
List<StringFormat> stringFormats = new List<StringFormat>();
List<CharacterRange[]> characterRanges = new List<CharacterRange[]>();
for (int x = 0; x < numRanges; x++) {
characterRanges.Add(new CharacterRange[numCharsLeft <= 32 ? numCharsLeft : 32]);
numCharsLeft -= numCharsLeft <= 32 ? numCharsLeft : 32;
for (int i = 0; i < characterRanges[x].Length; i++)
characterRanges[x][i] = new CharacterRange((x * 32) + i, 1);
StringFormat stringFormat = new StringFormat();
stringFormat.FormatFlags = StringFormatFlags.NoClip; // Make sure the characters are not clipped
stringFormat.SetMeasurableCharacterRanges(characterRanges[x]);
stringFormats.Add(stringFormat);
}
SizeF size = g.MeasureString(measureString, stringFont);
RectangleF layoutRect = new RectangleF(0.0f, 0.0f, size.Width, size.Height);
List<Region[]> regions = new List<Region[]>();
for(int i = 0; i < characterRanges.Count; i++) {
regions.Add(new Region[characterRanges[i].Length]);
regions[i] = e.Graphics.MeasureCharacterRanges(
measureString,
stringFont,
layoutRect,
stringFormats[i]);
}
for ( int i = 0 ; i < numChars; i++ )
{
int block = (int) Math.Floor((double) i / 32);
Region region = regions[block][i - (32 * block)] as Region;
RectangleF rect = region.GetBounds(g);
rect.Offset( i * 10, 0);
g.DrawString( measureString.Substring(i,1), stringFont, Brushes.Black, rect, stringFormats[block]);
// g.DrawRectangle( Pens.Red, Rectangle.Round( rect ));
}
}
}
}
Я адаптирую этот код: https://www.codeproject.com/Articles/7375/Using-MeasureCharacterRanges-to-Draw-Text (Это не работает со строками, которые имеют более 32 символов)