7

Androidアプリ用の縦型(左から右への行折り返し)のモンゴル語スクリプトTextViewをどのように作成しますか?

バックグラウンド

Android は、アラビア語やヘブライ語などの RTL 言語を含め、世界中の多くの言語をかなり適切にサポートしています。ただし、伝統的なモンゴル語の​​ような上から下までの言語の組み込みサポートはありません(内モンゴルではまだ非常に生きており、キリルモンゴル語と混同しないでください)。次の図は、わかりやすくするために英語を追加したテキストの方向を示しています。

ここに画像の説明を入力

この機能は Android に組み込まれていないため、アプリ開発のほぼすべての側面が非常に困難になります。また、オンラインで入手できる情報は非常に少ないです。(関連する SO に関する数少ない質問の 1 つでさえ、適切な回答がありません。) 伝統的なモンゴル語の​​アプリ開発者は数多くいますが、商業的な理由かどうかにかかわらず、コードをオープン ソースにしていないようです。

これらの困難のため、伝統的なモンゴルのアプリ開発に関連するいくつかのより困難なプログラミングの問題に対する回答を収集するための中心的な場所として役立つ一連の StackOverflow の質問を作成したいと思います。モンゴル語の​​読み書きができなくても、コードのレビュー、コメントや質問の作成、回答の提供、さらには質問への賛成投票を手伝っていただければ幸いです。

モンゴル語の​​縦型 TextView

モンゴル語の​​ TextView には、次の要件が必要です。

  • 伝統的なモンゴル語フォントをサポート
  • テキストを上から下に垂直に表示します
  • 行の折り返しは左から右に進みます。
  • スペースで改行する(英語と同じ)

(TypeFace は後で設定できるため、TextView がモンゴル語フォントをサポートすることは絶対的な要件ではありませんが、多くの TextView が使用されている場合に便利です。)

私の答えは以下ですが、この問題を解決する他の方法を歓迎します。

このシリーズのその他の関連する質問:

iOS:

4

1 に答える 1

6

アップデート

結局、縦書きのスクリプトMongolTextViewをゼロから開発することになりました。の一部として利用できます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意識すればうまくいくがpaddinggravity行動がおかしい。そのため、 andを使用して使用wrap_contentしないようにするのが最もうまくいくようです。MongolTextView を FrameLayout に配置し、 と を使用することで、同じ効果を得ることができます。paddinggravitylayout_marginlayout_gravity
  • このソリューションは、Unicode テキストのレンダリングを扱いません。非 Unicode テキストを使用する必要があるか (非推奨)、アプリにレンダリング エンジンを含める必要があります。(現時点では、Android は OpenType スマートフォント レンダリングをサポートしていません。これが将来変更されることを願っています。比較すると、iOS は複雑なテキスト レンダリング フォントをサポートしています。) Unicode モンゴル語レンダリング エンジンの例については、このリンクを参照してください。
于 2015-04-20T05:10:19.220 に答える