Android如何制作传统蒙文字体TextView
How to make a traditional Mongolian script TextView in Android
如何为 Android 应用制作垂直(从左到右换行)蒙古文字 TextView?
背景
Android 对世界上的许多语言都有很好的支持,甚至包括阿拉伯语和希伯来语等 RTL 语言。但是,没有内置对像 traditional Mongolian (which is still very much alive in Inner Mongolia and not to be confused with Cyrillic Mongolian 这样的自上而下语言的支持。下图显示了为清楚起见添加了英文的文本方向。
由于 Android 中未内置此功能,这使得应用程序开发的几乎每个方面都变得极其困难。网上的信息也非常非常少。 (其中一个few related SO questions连一个好的答案都没有。) 有不少传统蒙语的app开发者,但不管是出于商业原因还是其他原因,他们似乎都没有将自己的代码开源。
由于这些困难,我想提出一系列 Whosebug 问题,这些问题可以作为收集与传统蒙古语应用程序开发相关的一些较难编程问题的答案的中心位置。即使您不懂蒙古语,您帮助审查代码、提出评论和问题、给出答案甚至对问题进行投票也将不胜感激。
蒙古语垂直 TextView
一个蒙文TextView需要具备以下条件:
- 支持传统蒙古文字体
- 从上到下垂直显示文本
- 换行从左到右。
- 换行出现在space(与英文相同)
(TextView支持蒙古文字体不是绝对要求,TypeFace可以稍后设置,但在使用多个TextView时方便。)
我的答案如下,但我欢迎其他解决此问题的方法。
本系列其他相关问题:
- How to make a traditional Mongolian script EditText in Android
- 更多内容...(吐司、对话框、菜单)
iOS:
- How do you make a vertical text UILabel and UITextView for iOS in Swift?
更新
我最终开发了一个垂直脚本 MongolTextView
from scratch. It is available as a part of mongol-library
。
以下解决方案的问题是镜像字体中未包含的任何字符(尤其是中文)将显示为反向。
旧答案
蒙文字体的字形方向都与英文相同,即从左到右。这允许将蒙古语单词添加到英语、中文或西里尔文字中(唯一的问题是这些单词是“躺下”而不是它们应该“站立”的)。
顺时针旋转 TextView 90 度会使其垂直,但换行方向错误(旋转后从右到左而不是从左到右)。换行方向问题可以通过水平翻转或镜像 TextView 来解决,但是所有的字形都被镜像了。最后一个问题可以通过从垂直镜像字体开始解决(可以通过使用 FontForge 等开源软件编辑现有字体来实现)。下图说明了该过程:
旋转和翻转可以通过扩展 TextView 并覆盖 onDraw()
和 onMeasure()
方法来完成:
public class MongolTextView extends TextView {
private TextPaint textPaint;
// Constructors
public MongolTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public MongolTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MongolTextView(Context context) {
super(context);
init();
}
// This class requires the mirrored Mongolian font to be in the assets/fonts folder
private void init() {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
"fonts/MongolFontMirrored.ttf");
setTypeface(tf);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// swap the height and width
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
@Override
protected void onDraw(Canvas canvas) {
textPaint = getPaint();
textPaint.setColor(getCurrentTextColor());
textPaint.drawableState = getDrawableState();
canvas.save();
// flip and rotate the canvas
canvas.translate(getWidth(), 0);
canvas.rotate(90);
canvas.translate(0, getWidth());
canvas.scale(1, -1);
canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());
getLayout().draw(canvas);
canvas.restore();
}
}
在您的 xml 布局中使用扩展 TextView 的全名:
<com.example.MongolTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/title_string" />
已知问题:
layout_margin
和 layout_gravity
如果您牢记旋转,则可以正常工作,但是 padding
和 gravity
的行为很奇怪。因此,使用 wrap_content
并避免使用 padding
和 gravity
似乎效果最好。通过将 MongolTextView 放在 FrameLayout 中并使用 layout_margin
和 layout_gravity
. 可以实现相同的效果
- 此解决方案不处理呈现 Unicode 文本。您要么需要使用非 Unicode 文本(不鼓励),要么需要在您的应用程序中包含渲染引擎。 (Android 目前不支持 OpenType smartfont 渲染。希望这会在未来改变。iOS,相比之下确实支持复杂的文本渲染字体。)参见 this link Unicode 蒙古文渲染引擎示例。
如何为 Android 应用制作垂直(从左到右换行)蒙古文字 TextView?
背景
Android 对世界上的许多语言都有很好的支持,甚至包括阿拉伯语和希伯来语等 RTL 语言。但是,没有内置对像 traditional Mongolian (which is still very much alive in Inner Mongolia and not to be confused with Cyrillic Mongolian 这样的自上而下语言的支持。下图显示了为清楚起见添加了英文的文本方向。
由于 Android 中未内置此功能,这使得应用程序开发的几乎每个方面都变得极其困难。网上的信息也非常非常少。 (其中一个few related SO questions连一个好的答案都没有。) 有不少传统蒙语的app开发者,但不管是出于商业原因还是其他原因,他们似乎都没有将自己的代码开源。
由于这些困难,我想提出一系列 Whosebug 问题,这些问题可以作为收集与传统蒙古语应用程序开发相关的一些较难编程问题的答案的中心位置。即使您不懂蒙古语,您帮助审查代码、提出评论和问题、给出答案甚至对问题进行投票也将不胜感激。
蒙古语垂直 TextView
一个蒙文TextView需要具备以下条件:
- 支持传统蒙古文字体
- 从上到下垂直显示文本
- 换行从左到右。
- 换行出现在space(与英文相同)
(TextView支持蒙古文字体不是绝对要求,TypeFace可以稍后设置,但在使用多个TextView时方便。)
我的答案如下,但我欢迎其他解决此问题的方法。
本系列其他相关问题:
- How to make a traditional Mongolian script EditText in Android
- 更多内容...(吐司、对话框、菜单)
iOS:
- How do you make a vertical text UILabel and UITextView for iOS in Swift?
更新
我最终开发了一个垂直脚本 MongolTextView
from scratch. It is available as a part of mongol-library
。
以下解决方案的问题是镜像字体中未包含的任何字符(尤其是中文)将显示为反向。
旧答案
蒙文字体的字形方向都与英文相同,即从左到右。这允许将蒙古语单词添加到英语、中文或西里尔文字中(唯一的问题是这些单词是“躺下”而不是它们应该“站立”的)。
顺时针旋转 TextView 90 度会使其垂直,但换行方向错误(旋转后从右到左而不是从左到右)。换行方向问题可以通过水平翻转或镜像 TextView 来解决,但是所有的字形都被镜像了。最后一个问题可以通过从垂直镜像字体开始解决(可以通过使用 FontForge 等开源软件编辑现有字体来实现)。下图说明了该过程:
旋转和翻转可以通过扩展 TextView 并覆盖 onDraw()
和 onMeasure()
方法来完成:
public class MongolTextView extends TextView {
private TextPaint textPaint;
// Constructors
public MongolTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public MongolTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MongolTextView(Context context) {
super(context);
init();
}
// This class requires the mirrored Mongolian font to be in the assets/fonts folder
private void init() {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
"fonts/MongolFontMirrored.ttf");
setTypeface(tf);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// swap the height and width
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
@Override
protected void onDraw(Canvas canvas) {
textPaint = getPaint();
textPaint.setColor(getCurrentTextColor());
textPaint.drawableState = getDrawableState();
canvas.save();
// flip and rotate the canvas
canvas.translate(getWidth(), 0);
canvas.rotate(90);
canvas.translate(0, getWidth());
canvas.scale(1, -1);
canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());
getLayout().draw(canvas);
canvas.restore();
}
}
在您的 xml 布局中使用扩展 TextView 的全名:
<com.example.MongolTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/title_string" />
已知问题:
layout_margin
和layout_gravity
如果您牢记旋转,则可以正常工作,但是padding
和gravity
的行为很奇怪。因此,使用wrap_content
并避免使用padding
和gravity
似乎效果最好。通过将 MongolTextView 放在 FrameLayout 中并使用layout_margin
和layout_gravity
. 可以实现相同的效果
- 此解决方案不处理呈现 Unicode 文本。您要么需要使用非 Unicode 文本(不鼓励),要么需要在您的应用程序中包含渲染引擎。 (Android 目前不支持 OpenType smartfont 渲染。希望这会在未来改变。iOS,相比之下确实支持复杂的文本渲染字体。)参见 this link Unicode 蒙古文渲染引擎示例。