需要帮助如何绘制阿拉伯语和英语单词 Char By Char

问题描述 投票:0回答:1

我正在尝试从文本框到面板字符按字符绘制相同的文本对于阿拉伯语和英语,具有相同的字符大小和位置以及样式和颜色,如果文本是英语,但对于阿拉伯语,它打印分隔的字符,我的代码可以完美工作。 我知道如果我向前使用 DrawString 、 DrawTextBox 或 TextRenderer.DrawText 策略,我会得到结果,但它只会显示第一个可见的留置权,并且如果多行 true 则无法移动留置权,如果多行 false 则无法移动到末尾

我的问题仅在于绘制阿拉伯字符 这些是我尝试过的

  1. 逐字画
  2. 通过两个字符绘制两个字符以将连接的字符作为阿拉伯语书写,但没有按照我想要的方式工作
  3. 如果字符在将之前的字符作为一个单词处理后有空格或空白,但我遇到了阿拉伯语和英语之间的对齐以及设置每个单词的起始位置的另一个问题
  4. -也尝试过使用
    enum CaseMap { End = 0, Middle = 1, Beginning = 2, Isolated = 3 };
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Microsoft_TextBox
{
    public partial class Arabic_English_Draw_TextBox : Form
    {
        private TextBox textBox1;
        private Panel panel1;
        private Label TexeLabel;
        private Label PanelLabel;
        public Arabic_English_Draw_TextBox()
        {
            InitializeComponent();
            textBox1 = new TextBox();
            this.Controls.Add(textBox1);
            textBox1.Text = "مرحبا بالعالم Hello شكرا"+"\n"+ "I'm trying to draw the same text from textBox to Panel char By Char For Arabic & English ";
            textBox1.Font = new Font("Tahoma", 18, FontStyle.Bold);
            textBox1.Multiline = true;
            textBox1.BorderStyle = BorderStyle.Fixed3D;
            textBox1.Size = new Size(200, 150);
            textBox1.Location = new Point(50, 50);
            textBox1.TextAlign = HorizontalAlignment.Center;
            textBox1.ForeColor = Color.DeepSkyBlue;
            textBox1.TextChanged += textBox1_TextChanged;
            textBox1.KeyDown += textBox1_KeyDown;

            TexeLabel = new Label();
            this.Controls.Add(TexeLabel);
            TexeLabel.Location = new Point(50, 20);
            TexeLabel.Text = "Text Box";



            panel1 = new Panel();
            this.Controls.Add(panel1);
            panel1.BorderStyle = BorderStyle.Fixed3D;
            panel1.Size = new Size(200, 150);
            panel1.Location = new Point(textBox1.Width+ 50, 50);
            panel1.Paint += panel1_Paint; // Hook up the Paint event handler

            PanelLabel = new Label();
            this.Controls.Add(PanelLabel);
            PanelLabel.Location = new Point(panel1.Location.X, 20);
            PanelLabel.Text = "Panel To Draw";


            this.Width = 500;
            this.Height = 300;
            StartPosition = FormStartPosition.CenterScreen;


        }

       
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            panel1.Invalidate();
        }
        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            panel1.Invalidate();
        }



        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            using (SolidBrush br = new SolidBrush(textBox1.ForeColor))
            using (StringFormat sf = new StringFormat())
            {
                // Calculate the width of the text
                SizeF textSize = e.Graphics.MeasureString(textBox1.Text, textBox1.Font, textBox1.ClientSize, sf);
                // Draw each character
                int firstCharIndex = textBox1.GetCharIndexFromPosition(new Point(0, 0));
                int lastCharIndex = textBox1.GetCharIndexFromPosition(new Point(textBox1.ClientSize.Width - 1, textBox1.ClientSize.Height - 1));
                StringBuilder stringBuilder = new StringBuilder(); // Initialize StringBuilder
                int csizeH = 0;
                int csizeW = 0;
                int CCount = 0;
                List<RectangleF> charRects = new List<RectangleF>(); // Store rectangles for each character
                for (int i = firstCharIndex; i <= lastCharIndex && i < textBox1.Text.Length; i++)
                {
                    char Char = textBox1.Text[i];
                    Size charSize = TextRenderer.MeasureText(Char.ToString(), textBox1.Font);

                    // Append each character to the StringBuilder
                    stringBuilder.Append(Char);

                    csizeH = (int)charSize.Height;
                    csizeW = (int)charSize.Width;
                    RectangleF charRect = new RectangleF(
                          textBox1.GetPositionFromCharIndex(i),
                          charSize);
                    switch (textBox1.TextAlign)
                    {
                        case HorizontalAlignment.Left:
                            charRect.Offset(-(int)textBox1.Font.Size / 5f, 0);
                            break;
                        case HorizontalAlignment.Center:
                            charRect.Offset(-(int)textBox1.Font.Size / 2.8f, 0);
                            break;
                        case HorizontalAlignment.Right:
                            charRect.Offset(-(int)textBox1.Font.Size / 2.05f, 0);
                            break;
                    }
                    charRects.Add(charRect); // Store the rectangle for each character
                    CCount = charRects.Count;

                }

                // Determine the start position for drawing the concatenated string
                PointF startPosition = charRects.Count > 0 ? charRects[0].Location : PointF.Empty;
                // Draw each character individually at their respective positions
                for (int i = 0; i < stringBuilder.Length; i++)
                {
                    e.Graphics.DrawString(stringBuilder[i].ToString(), textBox1.Font, br, charRects[i], sf);
                }
            }
        }
    }
}

c# winforms draw system.drawing
1个回答
0
投票

好吧,有两件事,一个 TextBox 忽略了“ “性格。如果你把” " 然后它将创建一个新行。

绘制方法:

 private void panel1_Paint(object sender, PaintEventArgs e)
 {
     using (SolidBrush br = new SolidBrush(textBox1.ForeColor))
     using (StringFormat sf = new StringFormat())
     {
         //sf.Alignment = StringAlignment.Center;
         sf.Trimming = StringTrimming.EllipsisCharacter;
         
         sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces ;
         
         // Draw each character
         int firstCharIndex = textBox1.GetCharIndexFromPosition(new Point(1, 1));
         
         int lastCharIndex = textBox1.GetCharIndexFromPosition(new Point(textBox1.ClientSize.Width - 1, textBox1.ClientSize.Height - 1));
         StringBuilder stringBuilder = new StringBuilder(); // Initialize StringBuilder
         
         List<RectangleF> charRects = new List<RectangleF>(); // Store rectangles for each character
         for (int i = firstCharIndex; i <= lastCharIndex && i < textBox1.Text.Length; i++)
         {
             char Char = textBox1.Text[i];
             Size charSize = TextRenderer.MeasureText(Char.ToString(), textBox1.Font);
             var isCharVisible = textBox1.GetPositionFromCharIndex(i);
             if (isCharVisible.Y < 0 || isCharVisible.Y > (textBox1.Height-charSize.Height/2))
             {
                 continue;
             }
             // Append each character to the StringBuilder
             stringBuilder.Append(Char);
             RectangleF charRect = new RectangleF(
                   textBox1.GetPositionFromCharIndex(i),
                   charSize);
            
             charRects.Add(charRect); // Store the rectangle for each character
         }

         int j = 0;
         int count = 0;
         var LineRect = charRects[0];

         for (int i = 1; i < charRects.Count; i++)
         {
             
             if (charRects[i-1].Y != charRects[i].Y || i == charRects.Count-1)
             {
                 // last char
                 if(i == charRects.Count - 1)
                 {
                     // set the location for the minimum X
                     // set the line Rectangel
                     if (LineRect.X < charRects[i].X)
                     {
                         LineRect = new RectangleF(LineRect.X, LineRect.Y, LineRect.Width + charRects[i].Width, LineRect.Height);
                     }
                     else
                     {
                         LineRect = new RectangleF(charRects[i].X, LineRect.Y, LineRect.Width + charRects[i].Width, LineRect.Height);
                     }
                     count++;
                 }
                 // Drawstring line by line
                 e.Graphics.DrawString(stringBuilder.ToString().Substring(j,count), textBox1.Font, br, LineRect, sf);
                 j = i;
                 count = 0;
                 LineRect = charRects[i];
             }
             else
             {
                 // set the location for the minimum X
                 // set the line Rectangel
                 if (LineRect.X < charRects[i].X)
                 {
                     LineRect = new RectangleF(LineRect.X, LineRect.Y, LineRect.Width + charRects[i].Width, LineRect.Height);
                 }
                 else
                 {
                     LineRect = new RectangleF(charRects[i].X, LineRect.Y, LineRect.Width + charRects[i].Width, LineRect.Height);
                 }
                 
             }
             count++;
         }
             
     }
 }

这会从文本框中逐行绘制文本。不完美,但我认为 99% 都很好。

© www.soinside.com 2019 - 2024. All rights reserved.