gpt4 book ai didi

unicode - 节省空间的日语字符编码?

转载 作者:行者123 更新时间:2023-12-04 14:51:45 25 4
gpt4 key购买 nike

在我看来,一个常见的问题是:字符编码与位图字体相结合。大多数多语言编码在不同字符类型之间都有很大的空间,甚至还有很多未使用的代码点。因此,如果我想使用它们,我会浪费大量内存(不仅用于保存多字节文本 - 我的意思是专门用于位图字体中的空格) - 而且 VRAM 非常有值(value)......所以唯一合理的事情似乎是:在我的纹理上使用自定义映射,即 UTF-8 字符(这样就不会浪费空间)。但是:这项工作似乎与使用自己的专有字符编码相同(所以我的纹理中的字符顺序也是如此)。在我的特殊情况下,我获得了 4096 个不同字符的纹理空间,并且需要字符来显示拉丁语和日语(它与仅支持通用 cjk 代码页的 utf-8 困惑)。有没有人遇到过类似的问题(我真的很想知道,如果没有)?如果已经有任何方法?

编辑:此处描述了相同的问题 http://www.tonypottier.info/Unicode_And_Japanese_Kanji/但它没有提供如何将这些位图字体映射保存到 utf-8 空间效率的真正解决方案。因此,欢迎任何进一步的帮助!

编辑2:

非常感谢您的回答。对不起,我的问题描述得不够清楚。

我真正想解决的是:CJK Unicode 范围超过 20000 个字符。但是只有大约 2000 个字符的子集才能正确显示日语文本。这些字符分布在从 U+4E00 到 U+9FA5 的范围内。所以我需要以某种方式将这些 Unicode 代码点(日语只有 2000)转换为我创建的纹理的坐标(我可以在其中订购我想要的字符)。

即 U+4E03 是日文字符,但 U+4E04、U+4E05、U+4E06 不是。那么 U+4E07 也是一个日文字符。所以最简单的解决方案,我可以看到:在字符 U+4E03 之后在我的纹理中留下三个空格(或者在那里写下不需要的字符 U+4E04、U+4E05、U+4E06)然后写 U+4E07。但这会浪费太多纹理空间(20000 个字符,即使只需要 2000 个字符)。所以我希望能够只放入我的纹理:“...U+4E03, U+4E07...”。但是我不知道如何编写我的 displayText 函数 - 因为我不知道我想要显示的字形的纹理坐标在哪里。会有一个哈希图或类似的东西是必要的,但我不知道如何存储这些数据(为每个字符编写类似...{U+4E03, 128}, {U+4E07, 129}...填充hasmap)。

对于问题:
1)没有特定的格式——所以我会自己写displayText函数。
2) 没有理由反对 unicode - 它只是我的位图字体的 CJK 范围问题。
3)我认为,这通常与平台和语言无关,但在我的情况下,我在 Mac OS X/iOS 上使用 C++ 和 OpenGL。

非常感谢您的帮助!如果您对此有任何进一步的想法,那真的会对我有很大帮助!

最佳答案

你想解决的真正问题是什么?

是不是 UTF-8 编码的字符串每个字符占用三个字节?如果是,请切换到 UTF-16。否则不要责怪UTF-8。 (解释:UTF-8 只是一种将整数序列转换为字节序列的算法。它与代码页中的字符分组无关。这反过来又是 Unicode 代码点的用途。)

Unicode 代码点是否分布在许多“代码页”上(其中“代码页”表示 256 个相邻 Unicode 代码点的块)?如果是,请创建从 Unicode 代码点 (0x000000 - 0x10FFFF) 到较小整数集的映射。就内存而言,这不应超过您真正需要的字符数的 4 个字节。查找时间大约为 24 次内存访问、24 次整数比较和 24 条分支指令。 (实际上,这将是树映射中的二分搜索。)如果这太昂贵,您可以使用基于哈希表的映射。

是别的吗?然后请给我们一些例子,以更好地理解您的问题。

据我了解,您可能应该编写一个小型实用程序,该程序将一组您希望在应用程序中使用的 Unicode 代码点作为输入,然后生成用于显示文本的代码和数据。这就提出了以下问题:

  • 你必须使用特定的位图字体格式还是你会写displayText自己发挥作用?
  • 是否有任何理由反对对所有字符串使用 Unicode 并仅在渲染文本时将它们转换为位图优化编码?编码转换当然会在 displayText 内部进行。方法并且对正常的应用程序代码不可见。
  • 只是出于兴趣:问题是否特定于某种编程语言或环境?

  • 更新 :

    我假设您的主要问题是这样的功能:
    Rectangle position(int codepoint)

    如果我必须这样做,我会首先为每个字符创建一个位图。位图的文件名将是代码点,以便可以轻松地重新生成“大图”,以防万一您找到更多需要的字符。制备包括以下步骤:
  • 加载所有位图并确定它们的尺寸。这一步的结果是一个从整数到(宽度,高度)对的映射。
  • 为大图中的字符图像计算一个好的布局,并记住每个字符的放置位置。保存大图。将代码点到 (x, y, width, height) 的映射保存到另一个文件。这可以是文本文件,或者如果您没有磁盘空间,则可以是二进制文件。细节不重要。
  • displayText函数将按如下方式工作:
    void displayText(int x, int y, String s) {
    for (char c : s.toCharArray()) { // TODO: handle code points correctly
    int codepoint = c;
    Rectangle position = positions.get(codepoint);
    if (position != null) {
    // draw bitmap
    x += position.width;
    }
    }
    }

    Map<Integer, Rectangle> positions = loadPositionsFromFile();

    现在剩下的唯一问题是如何使用尽可能少的内存在内存中表示该映射,并且仍然足够快。当然,这取决于您的编程语言。

    内存中的表示可能是一些包含 x、y、宽度、高度的数组。对于每个元素,一个 16 位整数就足够了。无论如何,您可能只需要 8 位的宽度和高度。然后另一个数组会将代码点映射到 positionData 中的索引。 (或一些特殊值,如果代码点不可用)。这将是一个包含 20000 个 16 位整数的数组,因此总而言之,您有:
  • 2000 * (2 + 2 + 1 + 1) = 12000 字节 positionX , positionY , positionWidthpositionHeight
  • 20000 * 2 = 40000 字节 codepointToIndexInPositionArrays , 如果您使用数组而不是 map 。

  • 与位图本身的大小相比,这应该足够小。并且由于数组不会更改,因此它们可以位于只读内存中。

    关于unicode - 节省空间的日语字符编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4507254/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com