亚洲字符的显示(使用 Unicode):与使用 ExtTextOut 相比,在 RichEdit 控件中显示时字符间距存在差异

发布于 2024-10-18 16:11:08 字数 1138 浏览 2 评论 0原文

这张图说明了我的困境:

Image1

所有字符看起来大小相同,但当它们之间的间距不同时与我使用 ExtTextOut 时相比,在 RichEdit 控件中呈现。

我想以与 RichEdit 控件中相同的方式显示字符(理想情况下),以便保留换行位置。

谁能告诉我:

a) 哪种表示方式更正确?

b) 为什么 RichEdit 控件显示亚洲字符之间没有间隙的文本?

c) 有没有办法让 ExtTextOut 在绘制这些字符时重现 RichEdit 控件的行为?

d) 如果我在亚洲版本的 Windows 上工作,这会有什么不同吗?

也许我我很乐观,但如果有人能提供任何提示,我将非常有兴趣听到。

如果它有帮助:

这是我的文字:

快的棕色狐狸跳在懶惰狗1 2 3 4 5 6 7 8 9 0

向亚洲读者道歉,这只是为了测试我们的 Unicode 实现,我什至不知道这些字符来自哪种语言,更不用说是否它们意味着任何内容

为了通过将这些字符粘贴到 RichEdit 控件(例如写字板)中来查看效果,您可能会发现必须滑动它们并将字体设置为“Arial”。

我获得的富文本是:

{\rtf1\ansi\ansicpg1252\deff0\deflang2057{\fonttbl{\f0\fnil\fcharset0 Arial;}}{\colortbl ;\red0\green0\blue0;}\viewkind4\uc1\pard\sa200\sl276\slmult1\lang9\fs22\u24555?\u30340?\u26837?\u33394?\u29392?\u29432?\u36339?\u22312?\u25078?\u24816?\u29399?1 2 3 4 5 6 7 8 9 0\par\pard\'a3 $$ \'80\'80\cf1\lang2057\fs16\par}

它似乎不包含我的第一个想法的字符“音高”的值。

This picture illustrates my predicament:

Image1

All of the characters appear to be the same size, but the space between them is different when presented in a RichEdit control compared with when I use ExtTextOut.

I would like to present the characters the same as in the RichEdit control (ideally), in order to preserve wrap positions.

Can anyone tell me:

a) Which is the more correct representation?

b) Why the RichEdit control displays the text with no gaps between the Asian Characters?

c) Is there any way to make ExtTextOut reproduce the behaviour of the RichEdit control when drawing these characters?

d) Would this be any different if I was working on an Asian version of Windows?

Perhaps I'm being optimistic, but if anyone has any hints to offer, I'd be very interested to hear.

In case it helps:

Here's my text:

快的棕色狐狸跳在懶惰狗1 2 3 4 5 6 7 8 9 0

apologies to Asian readers, this is merely for testing our Unicode implemetation and I don't even know what language the characters are taken from, let alone whether they mean anything

In order to view the effect by pasting these characters into a RichEdit control (eg. Wordpad), you may find you have to swipe them and set the font to 'Arial'.

The rich text that I obtain is:

{\rtf1\ansi\ansicpg1252\deff0\deflang2057{\fonttbl{\f0\fnil\fcharset0 Arial;}}{\colortbl ;\red0\green0\blue0;}\viewkind4\uc1\pard\sa200\sl276\slmult1\lang9\fs22\u24555?\u30340?\u26837?\u33394?\u29392?\u29432?\u36339?\u22312?\u25078?\u24816?\u29399?1 2 3 4 5 6 7 8 9 0\par\pard\'a3 $ \'80\'80\cf1\lang2057\fs16\par}

It doesn't appear to contain a value for character 'pitch' which was my first thought.

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

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

发布评论

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

评论(3

南笙 2024-10-25 16:11:08

我不知道答案,但有几件事值得怀疑:

  • Rich Edit 控件有多个版本。也许您使用的是较旧的版本,它没有所有最新的排版改进。
  • 有许多样式和标志会影响丰富的编辑控件的行为,因此您可能想要探索设置了哪些样式和标志以及它们的作用。例如,请查看 EM_GETEDITSTYLE
  • 许多亚洲字体在 Windows 上有两个版本。一种针对水平布局进行优化,另一种针对垂直布局进行优化。后者通常具有相同的名称,但前面有 @。也许您在丰富的编辑控件中使用了错误的控件。

更新:通过摆弄写字板,我能够重现富编辑控件中拥挤文本的问题。

  1. 在 Windows 7 上的写字板中打开一个新文档。请注意,所选字体是 Calibri。
  2. 将示例文本粘贴到文档中。
  3. 文本显示正确,但写字板将字体更改为 SimSun。
  4. 选择文本并将字体更改回 Calibri 或 Arial。

文本现在将变得拥挤,与您的示例非常相似。因此,根本问题似乎在于字体链接和后备。 ExtTextOut 可能会自动为脚本选择合适的字体。您的挑战是弄清楚如何识别脚本的正确字体并在丰富的编辑控件中设置该字体。

I don't know the answer, but there are several things to suspect:

  • There are several versions of the rich edit control. Perhaps you're using an older one that doesn't have all the latest typographic improvements.
  • There are many styles and flags that affect the behavior of a rich editcontrol, so you might want to explore which ones are set and what they do. For example, look at EM_GETEDITSTYLE.
  • Many Asian fonts come in two versions on Windows. One is optimized for horizontal layout, and the other for vertical layout. That latter usually has the same name, but has @ prepended to it. Perhaps you are using the wrong one in the rich edit control.

UPDATE: By messing around with Wordpad, I was able to reproduce the problem with the crowded text in the rich edit control.

  1. Open a new document in Wordpad on Windows 7. Note that the selected font is Calibri.
  2. Paste the sample text into the document.
  3. Text appears correct, but Wordpad changed the font to SimSun.
  4. Select the text and change the font back to Calibri or Arial.

The text will now be overcrowded, very similar to your example. Thus it appears the fundamental problem is with font linking and fallback. ExtTextOut is probably selecting an appropriate font for the script automatically. Your challenge is to figure out how to identify the right font for the script and set that font in the rich edit control.

逆光下的微笑 2024-10-25 16:11:08

这只能帮助解决部分问题,但有一种方法可以将文本绘制到 DC,其外观与 RichEdit 完全相同:即所谓的无窗口 RichEdit 控件。它不太容易使用:几年来我写了一篇关于它的 CodeProject 文章后退。我用它来解决文本块可滚动显示的问题,每个文本块都可以通过单击来编辑:普通绘图是使用无窗口的 RichEdit 完成的,而编辑则是通过在它的顶部。

这至少会让你的文本在两种情况下看起来都一样,但不幸的是两种情况都会显示太小的字符间距。

进一步的想法是:如果您可以依赖正在安装的 Microsoft Office,您还可以尝试 Office 附带的更高版本的 RichEdit。 Murray Sargent 的博客上有更多关于这些内容的信息,以及一些关于字体绑定的有趣文章,这些文章也可能帮助。

This will only help with part of your problem, but there is a way to draw text to a DC that will look exactly the same as it does with RichEdit: what's called the windowless RichEdit control. It not exactly easy to use: I wrote a CodeProject article on it a few years back. I used this to solve the problem of a scrollable display of blocks of text, each one of which can be edited by clicking on it: the normal drawing is done with the windowless RichEdit, and the editing by showing a "real" RichEdit control on the top of it.

That would at least get you the text looking the same in both cases, though unfortunately both cases would show too little character spacing.

One further thought: if you could rely on Microsoft Office being installed, you could also try later versions of RichEdit that come with office. There's more about these on Murray Sargent's blog, as well as some interesting articles on font binding that might also help.

三生殊途 2024-10-25 16:11:08

ExtTextOut 允许您指定记录之间的逻辑间距。它具有参数lpDx 是一个常量指针,指向一个值数组,该数组指示相邻字符单元的原点之间的距离。 Microsoft API 文档指出,如果您不设置它,那么它会设置自己的默认间距。我不得不说这就是 ExtTextOut 工作正常的原因。

特别是,当您在 EMF 中构造 EMR_EXTTEXTOUTW 记录时,它会使用此 DX 数组填充 EMR_TEXT 结构 - 该数组查看您的注释之一,允许 RichEdit 插入带有记录中包含的信息的 EMF,因此如果您没有设置字体绑定,然后 RTF 记录会进行一些匹配以确定要使用的字体。

就 RichEdit 控件而言, 以下文章可能有用:

在 Rich Edit 控件中使用字体绑定

指定字符集后,Rich Edit 会扫描字符集周围的文本
向前和向后插入点以查找最接近的字体
已用于字符集。如果没有找到字体
字符集,Rich Edit 使用客户端为此选择的字体
字符集。如果客户端没有指定字符的字体
设置时,Rich Edit 使用该字符集的默认字体。如果
客户想要其他字体,客户可以随时更改它,但是
这种方法在大多数情况下都有效。当前默认字体
选择基于下表。注意默认字体
是按进程设置的,并且有单独的 UI 使用列表和
非 UI 使用。

如果您还没有设置字符集,那么它进一步说明它会回退到 ANSI_CHARSET。然而,它绝对要复杂得多正如默里·萨金特(微软程序员)的博客文章所示,远不止如此。

ExtTextOut allows you to specify the logical spacing between records. It has the parameter lpDx which is a const pointer to an array of values that indicate the distance between origins of adjacent character cells. The Microsoft API documentation notes that if you don't set it, then it sets it's own default spacing. I would have to say that's why ExtTextOut is working fine.

In particular, when you construct a EMR_EXTTEXTOUTW record in EMF, it populates an EMR_TEXT structure with this DX array - which looking at one of your comments, allowed the RichEdit to insert the EMF with the information contained in the record, whereby if you didn't set a font binding then the RTF record does some matching to work out what font to use.

In terms of the RichEdit control, the following article might be useful:

Use Font Binding in a Rich Edit Control

After character sets are assigned, Rich Edit scans the text around the
insertion point forward and backward to find the nearest fonts that
have been used for the character sets. If no font is found for a
character set, Rich Edit uses the font chosen by the client for that
character set. If the client hasn't specified a font for the character
set, Rich Edit uses the default font for that character set. If the
client wants some other font, the client can always change it, but
this approach will work most of the time. The current default font
choices are based on the following table. Note that the default fonts
are set per-process, and there are separate lists for UI usage and for
non-UI usage.

If you haven't set the characterset, then it further explains that it falls back to ANSI_CHARSET. However, it's most definitely a lot more complicated than that, as that blog article by Murray Sargent (a programmer at Microsoft) shows.

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