在opengl中编写阿拉伯语文本

发布于 2024-07-13 22:48:05 字数 394 浏览 4 评论 0原文

我想使用 freetype 2 在我的 opengl 程序中编写阿拉伯语文本 我该怎么做 任何人都可以向我发送源代码或向我展示方法,甚至对 nehe 第 43 课进行任何修改,以在 opengl 中编写阿拉伯语,其中解释了使用 freetype 来显示阿拉伯文本


我之前看过第 13 课和第 43 课,但问题是当我渲染它时,它只显示矩形边框,没有任何阿拉伯字母,我使用 glUseOutline ,它从左到右显示字母,但没有将它们连接在一起,阿拉伯字母的问题是有一些字母必须考虑它的位置,例如字母(乙) 当这个字母位于单词(字符串)的开头时,它有自己的形状,并且在中间和结尾,因此,如果有专门为其编写的源代码,那么它将非常好,如下所示的单词示例: 乙字以乙字开头 ea ea 字母 巴 位于中间 rib 字母 б 位于最后

I want to write arabic text in my opengl program using freetype 2 how I can do it any one can send me asource code or show me the way or even any modification on nehe lesson 43 to write arabic in opengl which explain using freetype to display the arabic text


I saw lesson 13 and lesson 43 before,but the problem is when I render it ,it shows me just rectangle borders without any arabic letter,and I used glUseOutline and it shows me the letters from left to right and without connecting it together,the problems in arabic letter is that there are some letters must consider the position of it such as letter (ب)
when this letter is at the beginning of the word(string) it has the own shape and also in the middle and the end therefore, if there is a source code specially be writen for it it'll be very good the word example as below:
بيع the letter ب is at the beginning
يبيع the letter ب is at the middle
ريب the letter ب is at the end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

孤芳又自赏 2024-07-20 22:48:05

查看有关使用 OpenGL 渲染位图字体的 NeHe 教程 13 。 如果您想表示阿拉伯文本,您可能需要使用宽字符而不是 8 位字符。 那里有几个示例,其中一些使用 Linux 和 FreeType。 Freetype 渲染 Unicode 字符应该不会有问题。 这个 FreeType 教程可能会有所帮助。

Check out the NeHe tutorial 13 about rendering Bitmap fonts with OpenGL. You probably want to use wide characters instead of 8 bit ones if you want to represent arabic text. There are a couple of examples there, some of them use Linux and FreeType. Freetype shouldn't have a problem rendering Unicode characters. This FreeType tutorial might help.

唔猫 2024-07-20 22:48:05

这看起来应该可行:
https:/ /github.com/Accorpa/Arabic-Converter-From-and-To-Arabic-Presentation-Forms-B/blob/master/ArabicConverter.m

阿拉伯字形转换为相应的表示形式 B,并且应该正确呈现,又名正确加入。 从它的外观来看,它使用了上面 jheriko 的伪代码。

编辑(2016 年 9 月 26 日):我知道这是很久以前我发布的原始答案。 虽然没有错,但与此同时,我最终使用以下代码来转换阿拉伯字母。 这是获取阿拉伯字母表示形式的非常简单的解决方案。
https://github.com/eloraiby/arabtype/blob/master/arabtype.c

This looks like something that should work:
https://github.com/Accorpa/Arabic-Converter-From-and-To-Arabic-Presentation-Forms-B/blob/master/ArabicConverter.m

Arabic glyphs are converted to their corresponding presentation forms B and should render correctly, aka correctly joined. From the looks of it, it is using jheriko's pseudocode from above.

EDIT (Sept. 26, 2016): I am aware this is a long time ago that I posted the original answer. While not wrong, in the meantime, I ended up using the following code to convert Arab letters. It is a very straightforward solution to get the presentation forms for Arabic letters.
https://github.com/eloraiby/arabtype/blob/master/arabtype.c

.

弄潮 2024-07-20 22:48:05

看看 a>(阿拉伯语),这是阿拉伯语论坛中的讨论,涵盖了在 OpenGL 中渲染阿拉伯语文本时遇到的所有问题,甚至是高级问题。

我不知道你是否会说阿拉伯语,但在第二页中,你会找到一个示例代码,它告诉你如何使用 GDI+ 编写阿拉伯文本:

// مثال عن كود برمجي يقوم برسم النصوص على سطوح دايركت ثري دي
// لغة البرمجة هي دوت نيت مع
// C++/CLI
// ونستخدم مكتبة
// GDI+
// لكتابة النصوص
// تقديم: وسام البهنسي
// الشبكة العربية لمطوري الألعاب
// http://www.agdn-online.com
// رداً على الموضوع:
// http://www.agdn-online.com/communities.aspx?view=posts&threadid=544

// يقوم هذا الكلاس بإدارة الموارد اللازمة لرسم النصوص العربية
private ref class ArabicTextRenderer
{
public:
 ArabicTextRenderer() :
   m_NativeData(0)
 {
  // أنشئ صورة بأبعاد تتسع لأكبر جملة نصية تتوقع كتابتها بضربة واحدة
  // لاحظ أن هيئة البكسلات مهمة جداً، ويجب أن توافق هيئة السطح في محرك الرسم
  // وذلك لتفادي أي عمليات تحويل بطيئة
  m_Bitmap = gcnew Bitmap(256, 128, PixelFormat::Format32bppRgb); // كل بكسل 32 بت. لا يهمنا قناة ألفا
  m_BitmapData = gcnew BitmapData();
  m_Graphics = Graphics::FromImage(m_Bitmap);

  // حدد خواص الكتابة. تنسيق يمين-يسار
  m_Format = gcnew StringFormat();
  m_Format->FormatFlags = StringFormatFlags::NoClip | StringFormatFlags::DirectionRightToLeft;
  m_Format->Alignment = StringAlignment::Near;
  m_Format->HotkeyPrefix = HotkeyPrefix::None;
  m_Format->LineAlignment = StringAlignment::Near;
  m_Format->Trimming = StringTrimming::None;

  // معلومات عن كيفية حفظ الصورة في الذاكرة. كي نستطيع قراءتها دون تحويلات مكلفة
  m_Stride = (m_Bitmap->Width * Bitmap::GetPixelFormatSize(m_Bitmap->PixelFormat)) / 8; // عرض الصورة بالبايت
  int iBytesCount = m_Bitmap->Height * m_Stride; // حجم الصورة ككل بالبايت
  m_NativeData = new char[iBytesCount]; // المصفوفة الوسيطة التي ستستلم القيم اللونية للصورة

  // تجهيز معلومات الصورة لإجراء القفل
  m_BitmapData->Width = m_Bitmap->Width;
  m_BitmapData->Height = m_Bitmap->Height;
  m_BitmapData->PixelFormat = m_Bitmap->PixelFormat;
  m_BitmapData->Stride = m_Stride;
  m_BitmapData->Scan0 = (IntPtr)m_NativeData;
 }

 ~ArabicTextRenderer()
 {
  // حرر الذاكرة التي حجزناها بأنفسنا
  delete [] m_NativeData;
 }

 // إجراءات لتسهيل الوصول إلى أعضاء الكلاس
 property Bitmap^ TextBitmap { Bitmap^ get(void) { return m_Bitmap; } }
 property BitmapData^ TextBitmapData { BitmapData^ get(void) { return m_BitmapData; } }
 property Graphics^ TextGraphics { Graphics^ get(void) { return m_Graphics; } }
 property StringFormat^ TextFormat { StringFormat^ get(void) { return m_Format; } }
 property int Stride { int get(void) { return m_Stride; } }
 property void* NativeData { void* get(void) { return m_NativeData; } }

private:
 Graphics ^m_Graphics; // جهاز الرسم بجي دي آي بلس
 Bitmap ^m_Bitmap; // الصورة التي سيتم الرسم عليها
 BitmapData ^m_BitmapData; // معلومات القفل والتعبئة
 StringFormat ^m_Format; // خواص الكتابة
 int m_Stride; // عرض الصورة بالبايت. انتبه، قد يكون أكبر من عدد البكسلات مضروباً بحجم كل منها
 void *m_NativeData; // مؤشر إلى القيم اللونية للصورة
};


// إجراء الكتابة على صورة وتحويلها إلى بايتات يمكن إرسالها إلى أي محرك رسم
// البارامتر الأول هو النص المرغوب كتابته
// البارامتر الثاني هو الخط المرغوب للكتابة
// البارامتر الثالث هو كلاس الكتابة بالعربية والذي يجب أن يكون قد تم إنشاؤه من قبل
// البارامتر الأخير هو سطح دايركت ثري الذي ترغب بالرسم عليه
void SetText(String ^text, Font ^font, ArabicTextRenderer^ renderer, IDirect3DSurface9* D3DSurface)
{
 Bitmap ^bmp = renderer->TextBitmap;
 Graphics ^gfx = renderer->TextGraphics;

 // أولاً نقوم بمسح محتويات الصورة كي نتخلص من أي بقايا من المرة الماضية
 gfx->Clear(System::Drawing::Color::Transparent);

 // يجب علينا أن نقيس النص كي نستطيع توضيعه بشكل صحيح في الصورة
 SizeF sizef = gfx->MeasureString(text, font, PointF(0,0), renderer->TextFormat);
 short width = (short)sizef.Width;
 short height = (short)sizef.Height+2; // ضع هامشاً بمقدار بكسل واحد كارتفاع
 float yo = 1; // الإزاحة من أعلى الصورة

 // ارسم النص بدءاً من النقطة المحددة
 // لاحظ أن نقطة الكتابة هي الزاوية العليا اليمنى للنص لأننا نكتب بالعربية،
 // وبالتالي نحن بحاجة إلى وضع هذه النقطة على أقصى يمين الصورة
 gfx->DrawString(text, font, Brushes::White, width , yo, renderer->TextFormat);

 // يمكنك رسم إطار حول النص لو أردت التحقق من صحة الحسابات
 //gfx->DrawRectangle(Pens::White, 0, 0, width-1, height-1);

 // المستطيل الذي يحدد المنطقة التي نود قفلها من الصورة. عملياً كل الصورة
 Rectangle rc(0,0,bmp->Width,bmp->Height);

 // نقل القيم اللونية من الصورة إلى المؤشر الخاص بنا
 // هذه العملية تتم بمجرد قفل بتات الصورة، وذلك وفقاً للبارامترات التي نمررها
 // لإجراء القفل. هذه العملية سريعة نسبياً لأننا نسحب المعلومات بدون أي تحويل.
 bmp->LockBits(rc,ImageLockMode::ReadOnly|ImageLockMode::UserInputBuffer,
               bmp->PixelFormat,renderer->TextBitmapData);
 bmp->UnlockBits(renderer->TextBitmapData);

 // الآن لدينا كل ما يلزم لوضع البكسلات في محرك الرسم
 // الإجراء التالي يضع البكسلات في سطح دايركت ثري دي كمثال
 CopyImageToD3DSurface(D3DSurface, renderer->NativeData, renderer->Stride, width, height);

 //bmp->Save(L"C:\\صورة.png"); // احفظ الصورة للتحقق
}


// إجراء تعبئة سطح دايركت ثري دي بقيم لونية من مصفوفة ما. أي محرك رسم يجب أن يقدم إجراءً مماثلاً
// البارامتر الأول هو السطح المرغوب تعبئته
// البارامتر الثاني هو مصفوفة القيم اللونية التي تريد نسخها على السطح
// البارامتر الثالث هو عرض مصفوفة القيم اللونية بالبايت، وليس بالبكسل
// البارامتر الرابع والخامس هما أبعاد مصفوفة القيم اللونية بالبكسل. العرض والارتفاع على الترتيب
void CopyImageToD3DSurface(IDirect3DSurface9* D3DSurface, void* sourcePixels,
                           int stride, int width, int height)
{
 // هناك عدة افتراضات هنا لتبسيط الكود للمتعلم:
 // حجم السطح أكبر من أو يساوي أبعاد مصفوفة القيم اللونية
 // هيئة السطح هي ذاتها هيئة مصفوفة القيم اللونية. بمعنى آخر، لو كانت القيمة
 // اللونية مؤلفة من 4 بايتات، كل منها قناة لونية أحمر، أخضر، أزرق، ألفا
 // فإن سطح دايركت ثري دي يجب أن يكون من الهيئة:
 // D3DFMT_A8R8G8B8 أو D3DFMT_X8R8G8B8

 // انسخ القيم اللونية من كامل المصفوفة
 RECT srcRect = {0, 0, height, width};

 // انسخ القيم اللونية إلى الزاوية العليا اليسارية من السطح
 RECT destRect = {0, 0, height, width};

 // إجراء تعبئة السطح من مصفوفة قيم لونية مقدم من مكتبة دايركت ثري دي الإضافية
 D3DXLoadSurfaceFromMemory(
  D3DSurface, // السطح الذي يتم تعبئته
  NULL, // مصفوفة بجدول الألوان. لا نستخدم هذه الميزة
  &destRect, // المستطيل الذي سيتم تعبئته بالقيم اللونية في الصورة
  sourcePixels, // مصفوفة القيم اللونية التي سيتم النسخ منها
  D3DFMT_X8R8G8B8, // هيئة القيم اللونية. 32 بت وقناة ألفا غير مهمة
  stride, // عرض مصفوفة القيم اللونية بالبايت
  NULL, // مصفوفة بجدول الألوان في مصفوفة القيم اللونية. لا نستخدم هذه الميزة
  &srcRect, // المستطيل الذي يعبر عن مكان النسخ من مصفوفة القيم اللونية
  D3DX_FILTER_NONE, // طريقة الترشيح في حال عدم تطابق الأبعاد. لا نريد أي ترشيح
  0); // اللون المفتاحي. سيتم استبدال جميع القيم اللونية المطابقة لهذا اللون باللون الشفاف
}

另一位成员更改了代码以使用 OpenGL,结果是成功的:
替代文本
(来源:agdn-online.com

您可以在此处下载代码。

Take a look at نصوص عربية في أوبن جي إل (Arabic), that's a discussion in an Arabic forum which covers all the issues you'll face when rendering Arabic text in OpenGL, even the advanced ones.

I don't know if you speak Arabic or not, but in the second page, you'll find a sample code, which tells how to write Arabic text using GDI+:

// مثال عن كود برمجي يقوم برسم النصوص على سطوح دايركت ثري دي
// لغة البرمجة هي دوت نيت مع
// C++/CLI
// ونستخدم مكتبة
// GDI+
// لكتابة النصوص
// تقديم: وسام البهنسي
// الشبكة العربية لمطوري الألعاب
// http://www.agdn-online.com
// رداً على الموضوع:
// http://www.agdn-online.com/communities.aspx?view=posts&threadid=544

// يقوم هذا الكلاس بإدارة الموارد اللازمة لرسم النصوص العربية
private ref class ArabicTextRenderer
{
public:
 ArabicTextRenderer() :
   m_NativeData(0)
 {
  // أنشئ صورة بأبعاد تتسع لأكبر جملة نصية تتوقع كتابتها بضربة واحدة
  // لاحظ أن هيئة البكسلات مهمة جداً، ويجب أن توافق هيئة السطح في محرك الرسم
  // وذلك لتفادي أي عمليات تحويل بطيئة
  m_Bitmap = gcnew Bitmap(256, 128, PixelFormat::Format32bppRgb); // كل بكسل 32 بت. لا يهمنا قناة ألفا
  m_BitmapData = gcnew BitmapData();
  m_Graphics = Graphics::FromImage(m_Bitmap);

  // حدد خواص الكتابة. تنسيق يمين-يسار
  m_Format = gcnew StringFormat();
  m_Format->FormatFlags = StringFormatFlags::NoClip | StringFormatFlags::DirectionRightToLeft;
  m_Format->Alignment = StringAlignment::Near;
  m_Format->HotkeyPrefix = HotkeyPrefix::None;
  m_Format->LineAlignment = StringAlignment::Near;
  m_Format->Trimming = StringTrimming::None;

  // معلومات عن كيفية حفظ الصورة في الذاكرة. كي نستطيع قراءتها دون تحويلات مكلفة
  m_Stride = (m_Bitmap->Width * Bitmap::GetPixelFormatSize(m_Bitmap->PixelFormat)) / 8; // عرض الصورة بالبايت
  int iBytesCount = m_Bitmap->Height * m_Stride; // حجم الصورة ككل بالبايت
  m_NativeData = new char[iBytesCount]; // المصفوفة الوسيطة التي ستستلم القيم اللونية للصورة

  // تجهيز معلومات الصورة لإجراء القفل
  m_BitmapData->Width = m_Bitmap->Width;
  m_BitmapData->Height = m_Bitmap->Height;
  m_BitmapData->PixelFormat = m_Bitmap->PixelFormat;
  m_BitmapData->Stride = m_Stride;
  m_BitmapData->Scan0 = (IntPtr)m_NativeData;
 }

 ~ArabicTextRenderer()
 {
  // حرر الذاكرة التي حجزناها بأنفسنا
  delete [] m_NativeData;
 }

 // إجراءات لتسهيل الوصول إلى أعضاء الكلاس
 property Bitmap^ TextBitmap { Bitmap^ get(void) { return m_Bitmap; } }
 property BitmapData^ TextBitmapData { BitmapData^ get(void) { return m_BitmapData; } }
 property Graphics^ TextGraphics { Graphics^ get(void) { return m_Graphics; } }
 property StringFormat^ TextFormat { StringFormat^ get(void) { return m_Format; } }
 property int Stride { int get(void) { return m_Stride; } }
 property void* NativeData { void* get(void) { return m_NativeData; } }

private:
 Graphics ^m_Graphics; // جهاز الرسم بجي دي آي بلس
 Bitmap ^m_Bitmap; // الصورة التي سيتم الرسم عليها
 BitmapData ^m_BitmapData; // معلومات القفل والتعبئة
 StringFormat ^m_Format; // خواص الكتابة
 int m_Stride; // عرض الصورة بالبايت. انتبه، قد يكون أكبر من عدد البكسلات مضروباً بحجم كل منها
 void *m_NativeData; // مؤشر إلى القيم اللونية للصورة
};


// إجراء الكتابة على صورة وتحويلها إلى بايتات يمكن إرسالها إلى أي محرك رسم
// البارامتر الأول هو النص المرغوب كتابته
// البارامتر الثاني هو الخط المرغوب للكتابة
// البارامتر الثالث هو كلاس الكتابة بالعربية والذي يجب أن يكون قد تم إنشاؤه من قبل
// البارامتر الأخير هو سطح دايركت ثري الذي ترغب بالرسم عليه
void SetText(String ^text, Font ^font, ArabicTextRenderer^ renderer, IDirect3DSurface9* D3DSurface)
{
 Bitmap ^bmp = renderer->TextBitmap;
 Graphics ^gfx = renderer->TextGraphics;

 // أولاً نقوم بمسح محتويات الصورة كي نتخلص من أي بقايا من المرة الماضية
 gfx->Clear(System::Drawing::Color::Transparent);

 // يجب علينا أن نقيس النص كي نستطيع توضيعه بشكل صحيح في الصورة
 SizeF sizef = gfx->MeasureString(text, font, PointF(0,0), renderer->TextFormat);
 short width = (short)sizef.Width;
 short height = (short)sizef.Height+2; // ضع هامشاً بمقدار بكسل واحد كارتفاع
 float yo = 1; // الإزاحة من أعلى الصورة

 // ارسم النص بدءاً من النقطة المحددة
 // لاحظ أن نقطة الكتابة هي الزاوية العليا اليمنى للنص لأننا نكتب بالعربية،
 // وبالتالي نحن بحاجة إلى وضع هذه النقطة على أقصى يمين الصورة
 gfx->DrawString(text, font, Brushes::White, width , yo, renderer->TextFormat);

 // يمكنك رسم إطار حول النص لو أردت التحقق من صحة الحسابات
 //gfx->DrawRectangle(Pens::White, 0, 0, width-1, height-1);

 // المستطيل الذي يحدد المنطقة التي نود قفلها من الصورة. عملياً كل الصورة
 Rectangle rc(0,0,bmp->Width,bmp->Height);

 // نقل القيم اللونية من الصورة إلى المؤشر الخاص بنا
 // هذه العملية تتم بمجرد قفل بتات الصورة، وذلك وفقاً للبارامترات التي نمررها
 // لإجراء القفل. هذه العملية سريعة نسبياً لأننا نسحب المعلومات بدون أي تحويل.
 bmp->LockBits(rc,ImageLockMode::ReadOnly|ImageLockMode::UserInputBuffer,
               bmp->PixelFormat,renderer->TextBitmapData);
 bmp->UnlockBits(renderer->TextBitmapData);

 // الآن لدينا كل ما يلزم لوضع البكسلات في محرك الرسم
 // الإجراء التالي يضع البكسلات في سطح دايركت ثري دي كمثال
 CopyImageToD3DSurface(D3DSurface, renderer->NativeData, renderer->Stride, width, height);

 //bmp->Save(L"C:\\صورة.png"); // احفظ الصورة للتحقق
}


// إجراء تعبئة سطح دايركت ثري دي بقيم لونية من مصفوفة ما. أي محرك رسم يجب أن يقدم إجراءً مماثلاً
// البارامتر الأول هو السطح المرغوب تعبئته
// البارامتر الثاني هو مصفوفة القيم اللونية التي تريد نسخها على السطح
// البارامتر الثالث هو عرض مصفوفة القيم اللونية بالبايت، وليس بالبكسل
// البارامتر الرابع والخامس هما أبعاد مصفوفة القيم اللونية بالبكسل. العرض والارتفاع على الترتيب
void CopyImageToD3DSurface(IDirect3DSurface9* D3DSurface, void* sourcePixels,
                           int stride, int width, int height)
{
 // هناك عدة افتراضات هنا لتبسيط الكود للمتعلم:
 // حجم السطح أكبر من أو يساوي أبعاد مصفوفة القيم اللونية
 // هيئة السطح هي ذاتها هيئة مصفوفة القيم اللونية. بمعنى آخر، لو كانت القيمة
 // اللونية مؤلفة من 4 بايتات، كل منها قناة لونية أحمر، أخضر، أزرق، ألفا
 // فإن سطح دايركت ثري دي يجب أن يكون من الهيئة:
 // D3DFMT_A8R8G8B8 أو D3DFMT_X8R8G8B8

 // انسخ القيم اللونية من كامل المصفوفة
 RECT srcRect = {0, 0, height, width};

 // انسخ القيم اللونية إلى الزاوية العليا اليسارية من السطح
 RECT destRect = {0, 0, height, width};

 // إجراء تعبئة السطح من مصفوفة قيم لونية مقدم من مكتبة دايركت ثري دي الإضافية
 D3DXLoadSurfaceFromMemory(
  D3DSurface, // السطح الذي يتم تعبئته
  NULL, // مصفوفة بجدول الألوان. لا نستخدم هذه الميزة
  &destRect, // المستطيل الذي سيتم تعبئته بالقيم اللونية في الصورة
  sourcePixels, // مصفوفة القيم اللونية التي سيتم النسخ منها
  D3DFMT_X8R8G8B8, // هيئة القيم اللونية. 32 بت وقناة ألفا غير مهمة
  stride, // عرض مصفوفة القيم اللونية بالبايت
  NULL, // مصفوفة بجدول الألوان في مصفوفة القيم اللونية. لا نستخدم هذه الميزة
  &srcRect, // المستطيل الذي يعبر عن مكان النسخ من مصفوفة القيم اللونية
  D3DX_FILTER_NONE, // طريقة الترشيح في حال عدم تطابق الأبعاد. لا نريد أي ترشيح
  0); // اللون المفتاحي. سيتم استبدال جميع القيم اللونية المطابقة لهذا اللون باللون الشفاف
}

Another member changed the code to work with OpenGL, and the result was successful:
alt text
(source: agdn-online.com)

You can download the code here.

〆凄凉。 2024-07-20 22:48:05

您可能想要使用中间表示,以便所有四种形式的字符在输入时都转换为一种形式。 然后,如果您创建一个类/结构数组,其中包含对四种形式正确字符代码中每一种的引用,您可以修改文本渲染器读取的字符串,以便它使用某种逻辑选择正确的字符串,如下伪代码:

for each character in the input string

  find its entry in the array containing the character codes for the four forms

  if this is the first character
    if the next character is a space then 
      use the isolated form in the output string
    else
      use the initial form in the output string
  else
    if the preceeding character is a space and the next character is a space then
      use the isolated form in the output string
    else if the preceeding character is a space then use
      the initial form in the output string
    else if the next character is a space then
      use the terminal form in the output string
    else
      use the medial form in the output string

You might want to use an intermediary representation, so that all of the four forms of characters are converted to just one form on input. Then if you make an array of classes/structs containing references to each of the four forms correct character codes you can modify the string as read by the text renderer so that it chooses the correct one with some kind of logic like this psuedocode:

for each character in the input string

  find its entry in the array containing the character codes for the four forms

  if this is the first character
    if the next character is a space then 
      use the isolated form in the output string
    else
      use the initial form in the output string
  else
    if the preceeding character is a space and the next character is a space then
      use the isolated form in the output string
    else if the preceeding character is a space then use
      the initial form in the output string
    else if the next character is a space then
      use the terminal form in the output string
    else
      use the medial form in the output string
吃素的狼 2024-07-20 22:48:05

如何在此代码中添加阿拉伯语支持?

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)
    Call SaveSetting(My.Application.Info.ProductName, "Base", "LastText", Me.RichTextBox1.Rtf)
End Sub


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Me.RichTextBox1.Rtf = GetSetting(My.Application.Info.ProductName, "Base", "LastText", "")
    If Me.RichTextBox1.TextLength = 0 Then Me.RichTextBox1.LoadFile("info.rtf")

End Sub


Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs)
    Me.Timer1.Enabled = True
End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Me.Timer1.Enabled = False


    Dim b As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)
    Me.PictureBox1.Image = b
    Me.PictureBox1.Image = Image.FromFile(CurDir() & "\allpic\OperaDe1AFace.jpg")
    Rtb.RichTextBoxToBitmap(Me.RichTextBox1, Me.PictureBox1.Image)


End Sub

Private Sub RichTextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RichTextBox1.TextChanged
    Me.Timer1.Enabled = True
End Sub

Private Sub Form1_Load_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

End Sub

Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

End Sub

Private Sub PictureBox2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

End Sub

Private Sub PictureBox1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs)

End Sub

Private Sub NewToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NewToolStripMenuItem.Click

End Sub





Private Sub PictureBox1_Click_2(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click

End Sub

Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
    StartPoint = PictureBox1.PointToScreen(New Point(e.X, e.Y))
    IsDragging = True
End Sub

Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    If IsDragging Then
        Dim EndPoint As Point = PictureBox1.PointToScreen(New Point(e.X, e.Y))
        PictureBox1.Left += (EndPoint.X - StartPoint.X)
        PictureBox1.Top += (EndPoint.Y - StartPoint.Y)
        StartPoint = EndPoint
    End If
End Sub

Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
    IsDragging = False
End Sub

结束类

How to put Arabic support in this code?

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)
    Call SaveSetting(My.Application.Info.ProductName, "Base", "LastText", Me.RichTextBox1.Rtf)
End Sub


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Me.RichTextBox1.Rtf = GetSetting(My.Application.Info.ProductName, "Base", "LastText", "")
    If Me.RichTextBox1.TextLength = 0 Then Me.RichTextBox1.LoadFile("info.rtf")

End Sub


Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs)
    Me.Timer1.Enabled = True
End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Me.Timer1.Enabled = False


    Dim b As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)
    Me.PictureBox1.Image = b
    Me.PictureBox1.Image = Image.FromFile(CurDir() & "\allpic\OperaDe1AFace.jpg")
    Rtb.RichTextBoxToBitmap(Me.RichTextBox1, Me.PictureBox1.Image)


End Sub

Private Sub RichTextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RichTextBox1.TextChanged
    Me.Timer1.Enabled = True
End Sub

Private Sub Form1_Load_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

End Sub

Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

End Sub

Private Sub PictureBox2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

End Sub

Private Sub PictureBox1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs)

End Sub

Private Sub NewToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NewToolStripMenuItem.Click

End Sub





Private Sub PictureBox1_Click_2(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click

End Sub

Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
    StartPoint = PictureBox1.PointToScreen(New Point(e.X, e.Y))
    IsDragging = True
End Sub

Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    If IsDragging Then
        Dim EndPoint As Point = PictureBox1.PointToScreen(New Point(e.X, e.Y))
        PictureBox1.Left += (EndPoint.X - StartPoint.X)
        PictureBox1.Top += (EndPoint.Y - StartPoint.Y)
        StartPoint = EndPoint
    End If
End Sub

Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
    IsDragging = False
End Sub

End Class

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文