diff --git a/doc/en/html/menu/setup-additional-font.html b/doc/en/html/menu/setup-additional-font.html
index efde4c3db..3fb76c934 100644
--- a/doc/en/html/menu/setup-additional-font.html
+++ b/doc/en/html/menu/setup-additional-font.html
@@ -41,6 +41,18 @@
Additional settings / "Font" tab ([Setup] menu)
+ 描画幅に合わせてリサイズしたフォントを描画(Drawing resized font to fit cell width)
+
+ ONのとき表示したい幅と描画するフォントの幅が異なっている時、
+ フォントを縮小拡大してから描画します。
+ "©"など、表示しようとする幅は1cell,2cellのどちらの場合もあり、
+ フォントファイルによってフォントの幅も1cell,2cellのどちらの場合もあります。
+ 言語やフォントによってフォント幅は表示しようとする幅に合わない場合もあります。
+ このチェックをONにすると、cell幅に合わせて文字を描画します。
+ cell幅にあわせて文字が描画されるため文字は判別しやすくなるという利点がある一方で、
+ 描画速度が遅くなったり、デザインがフォント開発者の意図と異なってしまうという欠点があります。
+
+
Character space
Under construction.
diff --git a/doc/ja/html/menu/setup-additional-font.html b/doc/ja/html/menu/setup-additional-font.html
index 0fd7931ed..e32a5799c 100644
--- a/doc/ja/html/menu/setup-additional-font.html
+++ b/doc/ja/html/menu/setup-additional-font.html
@@ -41,6 +41,18 @@
+ 描画幅に合わせてリサイズしたフォントを描画(Drawing resized font to fit cell width)
+
+ ONのとき表示したい幅と描画するフォントの幅が異なっている時、
+ フォントを縮小拡大してから描画します。
+ "©"など、表示しようとする幅は1cell,2cellのどちらの場合もあり、
+ フォントファイルによってフォントの幅も1cell,2cellのどちらの場合もあります。
+ 言語やフォントによってフォント幅は表示しようとする幅に合わない場合もあります。
+ このチェックをONにすると、cell幅に合わせて文字を描画します。
+ cell幅にあわせて文字が描画されるため文字は判別しやすくなるという利点がある一方で、
+ 描画速度が遅くなったり、デザインがフォント開発者の意図と異なってしまうという欠点があります。
+
+
文字間スペース
工事中です。
diff --git a/teraterm/common/compat_win.cpp b/teraterm/common/compat_win.cpp
index 2519b6dee..eb874ebca 100644
--- a/teraterm/common/compat_win.cpp
+++ b/teraterm/common/compat_win.cpp
@@ -109,6 +109,10 @@ static HRESULT (WINAPI *pLoadIconWithScaleDown)(HINSTANCE hinst, PCWSTR pszName,
HRESULT (WINAPI *pDwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
HRESULT (WINAPI *pDwmGetWindowAttribute)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute);
+// msimg32.dll
+BOOL (WINAPI *pTransparentBlt)(HDC hdcDest, int xoriginDest, int yoriginDest, int wDest, int hDest, HDC hdcSrc,
+ int xoriginSrc, int yoriginSrc, int wSrc, int hSrc, UINT crTransparent);
+
class Initializer {
public:
Initializer() {
diff --git a/teraterm/common/compat_win.h b/teraterm/common/compat_win.h
index 25664fa6e..7c67ac13b 100644
--- a/teraterm/common/compat_win.h
+++ b/teraterm/common/compat_win.h
@@ -219,6 +219,10 @@ HRESULT _LoadIconWithScaleDown(HINSTANCE hinst, PCWSTR pszName, int cx, int cy,
extern HRESULT (WINAPI *pDwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
extern HRESULT (WINAPI *pDwmGetWindowAttribute)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute);
+// msimg32.dll
+extern BOOL(WINAPI *pTransparentBlt)(HDC hdcDest, int xoriginDest, int yoriginDest, int wDest, int hDest, HDC hdcSrc,
+ int xoriginSrc, int yoriginSrc, int wSrc, int hSrc, UINT crTransparent);
+
void WinCompatInit();
#ifdef __cplusplus
diff --git a/teraterm/teraterm/buffer.c b/teraterm/teraterm/buffer.c
index 98864769e..b929428ed 100644
--- a/teraterm/teraterm/buffer.c
+++ b/teraterm/teraterm/buffer.c
@@ -3356,22 +3356,24 @@ void BuffGetDrawInfoW(int SY, int IStart, int IEnd,
} else {
// UTF-16でサロゲートペア
bufW[lenW] = b->wc2[0];
- bufWW[lenW] = b->cell;
+ bufWW[lenW] = 0;
lenW++;
bufW[lenW] = b->wc2[1];
- bufWW[lenW] = 0;
+ bufWW[lenW] = b->cell;
lenW++;
}
- if (b->CombinationCharCount16 != 0)
- {
+ if (b->CombinationCharCount16 != 0) {
// コンビネーション
int i;
- for (i = 0 ; i < (int)b->CombinationCharCount16; i++) {
- bufW[lenW+i] = b->pCombinationChars16[i];
+ const char cell_tmp = bufWW[lenW - 1];
+ bufWW[lenW - 1] = 0;
+ for (i = 0; i < (int)b->CombinationCharCount16; i++) {
+ bufW[lenW + i] = b->pCombinationChars16[i];
bufWW[lenW + i] = 0;
}
+ bufWW[lenW + b->CombinationCharCount16 - 1] = cell_tmp;
lenW += b->CombinationCharCount16;
- DrawFlag = TRUE; // コンビネーションがある場合はすぐ描画
+ DrawFlag = TRUE; // コンビネーションがある場合はすぐ描画
}
// ANSI版
@@ -3451,12 +3453,12 @@ typedef struct {
int draw_y;
} disp_data_t;
-static void l_disp_strW(const wchar_t *bufW, const char *width_info, int count, void *data_)
+static void l_disp_strW(const wchar_t *bufW, const char *cells, int len, void *data_)
{
disp_data_t *data = (disp_data_t *)data_;
int x = data->draw_x;
int y = data->draw_y;
- DispStrW(bufW, width_info, count, y, &x);
+ DispStrW(bufW, cells, len, y, &x);
data->draw_x = x;
}
diff --git a/teraterm/teraterm/font_pp.cpp b/teraterm/teraterm/font_pp.cpp
index e6d6bca6f..f4fa9fdb1 100644
--- a/teraterm/teraterm/font_pp.cpp
+++ b/teraterm/teraterm/font_pp.cpp
@@ -210,6 +210,8 @@ static INT_PTR CALLBACK Proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
SetFontString(hWnd, IDC_DLGFONT_EDIT, &dlg_data->DlgFont);
+ CheckDlgButton(hWnd, IDC_RESIZED_FONT, DispIsResizedFont());
+
break;
}
case WM_NOTIFY: {
@@ -234,6 +236,8 @@ static INT_PTR CALLBACK Proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
cur == 2 ? ANTIALIASED_QUALITY :
CLEARTYPE_QUALITY;
+ DispEnableResizedFont(IsDlgButtonChecked(hWnd, IDC_RESIZED_FONT) == BST_CHECKED);
+
break;
}
case PSN_HELP: {
diff --git a/teraterm/teraterm/font_pp.rc b/teraterm/teraterm/font_pp.rc
index 966930ea7..643f9301f 100644
--- a/teraterm/teraterm/font_pp.rc
+++ b/teraterm/teraterm/font_pp.rc
@@ -65,19 +65,21 @@ BEGIN
EDITTEXT IDC_VTFONT_CODEPAGE_EDIT,44,108,40,12,ES_AUTOHSCROLL
LTEXT "&Font Quality",IDC_FONT_QUALITY_LABEL,19,129,91,8
COMBOBOX IDC_FONT_QUALITY,30,141,87,69,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "&Dialog font",IDC_DLGFONT,7,162,115,8
- EDITTEXT IDC_DLGFONT_EDIT,19,177,148,12,ES_AUTOHSCROLL | ES_READONLY
- PUSHBUTTON "Select...",IDC_DLGFONT_CHOOSE,177,176,50,14
- PUSHBUTTON "&default",IDC_DLGFONT_DEFAULT,231,176,50,14
+ LTEXT "&Dialog font",IDC_DLGFONT,7,175,115,8
+ EDITTEXT IDC_DLGFONT_EDIT,19,192,148,12,ES_AUTOHSCROLL | ES_READONLY
+ PUSHBUTTON "Select...",IDC_DLGFONT_CHOOSE,177,191,50,14
+ PUSHBUTTON "&default",IDC_DLGFONT_DEFAULT,231,191,50,14
CONTROL "List &hidden fonts in font dialog",IDC_LIST_HIDDEN_FONTS,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,194,234,10
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,211,234,10
CONTROL "List &proportional fonts in font dialog",IDC_LIST_PRO_FONTS,
- "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,209,240,10
+ "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,226,240,10
LTEXT "character space",IDC_CHARACTER_SPACE_TITLE,187,51,115,8,WS_DISABLED
EDITTEXT IDC_SPACE_TOP,224,68,40,14,ES_AUTOHSCROLL | WS_DISABLED
EDITTEXT IDC_SPACE_BOTTOM,224,87,40,14,ES_AUTOHSCROLL | WS_DISABLED
EDITTEXT IDC_SPACE_LEFT,224,105,40,14,ES_AUTOHSCROLL | WS_DISABLED
EDITTEXT IDC_SPACE_RIGHT,224,123,40,14,ES_AUTOHSCROLL | WS_DISABLED
+ CONTROL "Drawing resized font to fit cell width",IDC_RESIZED_FONT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,159,140,10
END
@@ -93,10 +95,11 @@ BEGIN
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 302
+ VERTGUIDE, 19
TOPMARGIN, 7
BOTTOMMARGIN, 260
HORZGUIDE, 33
- HORZGUIDE, 183
+ HORZGUIDE, 198
END
END
#endif // APSTUDIO_INVOKED
diff --git a/teraterm/teraterm/font_pp_res.h b/teraterm/teraterm/font_pp_res.h
index 77ee64f09..724021d73 100644
--- a/teraterm/teraterm/font_pp_res.h
+++ b/teraterm/teraterm/font_pp_res.h
@@ -24,14 +24,16 @@
#define IDC_DLGFONT_DEFAULT 1018
#define IDC_LIST_HIDDEN_FONTS 1019
#define IDC_LIST_PRO_FONTS 1020
+#define IDC_SCALED_FONT 1021
+#define IDC_RESIZED_FONT 1021
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1021
+#define _APS_NEXT_CONTROL_VALUE 1022
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/teraterm/teraterm/teraprn.cpp b/teraterm/teraterm/teraprn.cpp
index 4528eabbc..a99880aa6 100644
--- a/teraterm/teraterm/teraprn.cpp
+++ b/teraterm/teraterm/teraprn.cpp
@@ -384,7 +384,7 @@ void PrnOutTextA(const char *StrA, const char *WidthInfo, int Count, void *data)
DrawStrA(PrintDC, NULL, StrA, WidthInfo, Count, PrnFW, PrnFH, PrnY, &PrnX);
}
-void PrnOutTextW(const wchar_t *StrW, const char *WidthInfo, int Count, void *data)
+void PrnOutTextW(const wchar_t *StrW, const char *cells, int len, void *data)
{
if (PrnX+PrnFW > Margin.right) {
/* new line */
@@ -399,7 +399,7 @@ void PrnOutTextW(const wchar_t *StrW, const char *WidthInfo, int Count, void *da
PrnY = Margin.top;
}
- DrawStrW(PrintDC, NULL, StrW, WidthInfo, Count, PrnFW, PrnFH, PrnY, &PrnX);
+ DrawStrW(PrintDC, NULL, StrW, cells, len, PrnFW, PrnFH, PrnY, &PrnX);
}
void PrnNewLine()
diff --git a/teraterm/teraterm/vtdisp.c b/teraterm/teraterm/vtdisp.c
index 6f4608bbd..50269d752 100644
--- a/teraterm/teraterm/vtdisp.c
+++ b/teraterm/teraterm/vtdisp.c
@@ -176,6 +176,8 @@ typedef struct {
//
BYTE DCBackAlpha;
COLORREF DCBackColor;
+
+ BOOL font_resize_enable;
} vtdisp_work_t;
static vtdisp_work_t vtdisp_work;
@@ -1702,6 +1704,7 @@ void InitDisp(void)
w->alpha_vtback = 255;
w->debug_drawbox_text = FALSE;
w->debug_drawbox_fillrect = FALSE;
+ w->font_resize_enable = TRUE;
BGReverseTextAlpha = 255;
}
@@ -2730,57 +2733,67 @@ void DrawStrA(HDC DC, HDC BGDC, const char *StrA, const char *WidthInfo, int Cou
}
}
-/**
- * 1行描画 Unicode
- * Windows 95 にも ExtTextOutW() は存在するが
- * 動作が異なるようだ
- * TODO 文字間に対応していない?
- *
- *
- * @param DC 描画先DC
- * @param BGDC 描画先ワークDC
- * NULLの時ワークなし(=背景描画なし)
- * プリンタへの出力の時は常にNULL
- * @param StrW 出力文字 (wchar_t)
- * @param WidthInfo[] 出力文字のcell数
- * 1 半角文字
- * 0 結合文字, Nonspacing Mark
- * 2+ 全角文字, 半角 + Spacing Mark
- * @param Count 文字数
- */
-void DrawStrW(HDC DC, HDC BGDC, const wchar_t *StrW, const char *WidthInfo, int Count, int font_width, int font_height,
- int Y, int *X)
+static void DrawChar(HDC hDC, HDC BGDC, int x, int y, const wchar_t *str, size_t len, int cell)
{
- int Dx[TermWidthMax];
- int HalfCharCount = 0;
- int i;
+ SIZE char_size;
+ HDC char_dc;
+ HBITMAP bitmap;
+ HBITMAP prev_bitmap;
+ RECT rc;
+ vtdisp_work_t *w = &vtdisp_work;
+
+ GetTextExtentPoint32W(hDC, str, (int)len, &char_size);
+
+ char_dc = CreateCompatibleDC(hDC);
+ SetTextColor(char_dc, GetTextColor(hDC));
+ SetBkColor(char_dc, GetBkColor(hDC));
+ SelectObject(char_dc, GetCurrentObject(hDC, OBJ_FONT));
+ bitmap = CreateCompatibleBitmap(hDC, char_size.cx, char_size.cy);
+ prev_bitmap = SelectObject(char_dc, bitmap);
+
+ rc.top = 0;
+ rc.left = 0;
+ rc.right = char_size.cx;
+ rc.bottom = char_size.cy;
+ ExtTextOutW(char_dc, 0, 0, ETO_OPAQUE, &rc, str, (UINT)len, 0);
+
+ // 横をcell幅(cell*FontWidth pixel)に拡大/縮小して描画
+ int width = cell * FontWidth;
+ int height = char_size.cy;
+ if (pTransparentBlt == NULL || BGDC == NULL || w->DCBackAlpha == 255) {
+ // 直接描画
+ SetStretchBltMode(hDC, COLORONCOLOR);
+ StretchBlt(hDC, x, y, width, height, char_dc, 0, 0, char_size.cx, char_size.cy, SRCCOPY);
+ }
+ else {
+ // BGDCに背景画像を描画
+ const COLORREF BackColor = GetBkColor(hDC);
+ DrawTextBGImage(BGDC, x, y, width, height, BackColor, w->DCBackAlpha);
+
+ // BGDCに文字を描画
+ SetStretchBltMode(hDC, COLORONCOLOR);
+ pTransparentBlt(BGDC, 0, 0, width, height, char_dc, 0, 0, char_size.cx, char_size.cy, GetBkColor(hDC));
+
+ // BGDCに描画した文字をWindowに貼り付け
+ BitBlt(hDC, x, y, width, height, BGDC, 0, 0, SRCCOPY);
+ }
+
+ SelectObject(char_dc, prev_bitmap);
+ DeleteObject(bitmap);
+ DeleteDC(char_dc);
+}
+
+static void DrawStrWSub(HDC DC, HDC BGDC, const wchar_t *StrW, const int *Dx,
+ int Count, int cells, int font_width, int font_height,
+ int Y, int *X)
+{
+ int HalfCharCount = cells; // セル数
int width;
int height;
BOOL direct_draw;
BYTE alpha = 0;
vtdisp_work_t *w = &vtdisp_work;
- for (i = 0; i < Count; i++) {
- if (WidthInfo[i] == 1) {
- HalfCharCount++;
- Dx[i] = font_width;
- }
- else if (WidthInfo[i] == 0) {
- if (i == 0) {
- assert(FALSE); // 表示の最初に結合文字?
- Dx[i] = 0;
- }
- else {
- Dx[i] = Dx[i - 1];
- Dx[i - 1] = 0;
- }
- }
- else {
- HalfCharCount += WidthInfo[i];
- Dx[i] = font_width * WidthInfo[i];
- }
- }
-
direct_draw = FALSE;
if (BGDC == NULL) {
// ワークの指定がないと直接描画
@@ -2798,7 +2811,6 @@ void DrawStrW(HDC DC, HDC BGDC, const wchar_t *StrW, const char *WidthInfo, int
if (direct_draw) {
RECT RText;
SetRect(&RText, *X, Y, *X + width, Y + height);
-
ExtTextOutW(DC, *X + ts.FontDX, Y + ts.FontDY, ETO_CLIPPED | ETO_OPAQUE, &RText, StrW, Count, &Dx[0]);
}
else {
@@ -2821,11 +2833,121 @@ void DrawStrW(HDC DC, HDC BGDC, const wchar_t *StrW, const char *WidthInfo, int
BitBlt(DC, *X, Y, width, height, BGDC, 0, 0, SRCCOPY);
}
- if (w->debug_drawbox_text) {
- DrawBox(DC, *X, Y, width, height, RGB(0,255,0));
+ *X += width;
+}
+
+
+/**
+ * 1行描画 Unicode
+ * Windows 95 にも ExtTextOutW() は存在するが
+ * 動作が異なるようだ
+ * TODO 文字間に対応していない?
+ *
+ * @param DC 描画先DC
+ * @param BGDC 描画先ワークDC
+ * NULLの時ワークなし(=背景描画なし)
+ * プリンタへの出力の時は常にNULL
+ * @param StrW 出力文字 (wchar_t)
+ * @param cells[] 出力文字のcell数
+ * 1 半角文字
+ * 0 結合文字, Nonspacing Mark
+ * 2+ 全角文字, 半角 + Spacing Mark
+ * @param len 文字数
+ *
+ * 例
+ * len=2, L"AB"
+ * 0 1 2
+ * StrW 'A' 'B'
+ * cells 1 1
+ *
+ * len=2, U+307B U+309A (L'ほ' + L'゜')
+ * 0 1 2
+ * StrW U+307B U+309A
+ * cells 0 2
+ *
+ */
+void DrawStrW(HDC DC, HDC BGDC, const wchar_t *StrW, const char *cells, int len, int font_width, int font_height,
+ int Y, int *X)
+{
+ int Dx[TermWidthMax];
+ int cell = 0;
+ int i;
+ vtdisp_work_t *w = &vtdisp_work;
+ int sx = *X;
+
+ if (len <= 0) {
+ return;
}
- *X += width;
+ for (i = 0; i < len; i++) {
+ cell += cells[i];
+ Dx[i] = cells[i] * font_width;
+ }
+
+ if (w->font_resize_enable) {
+ int start_idx = 0;
+ int cell_count = 0;
+ int wchar_count = 0;
+ int zero_count = 0;
+ for (i = 0; i < len; i++) {
+ if (cells[i] == 0) {
+ if (cell_count != 0) {
+ DrawStrWSub(DC, BGDC, &StrW[start_idx], &Dx[start_idx], wchar_count, cell_count, font_width, font_height, Y, X);
+ start_idx = i;
+ cell_count = 0;
+ wchar_count = 0;
+ }
+ wchar_count++;
+ zero_count++;
+ }
+#if 0
+ else if (zero_count > 2) {
+ wchar_count++;
+ cell_count += cells[i];
+ DrawStrWSub(DC, BGDC, &StrW[start_idx], &Dx[start_idx], wchar_count, cell_count, font_width,
+ font_height, Y, X);
+ start_idx = i;
+ zero_count = 0;
+ cell_count = 0;
+ wchar_count = 1;
+ }
+#endif
+ else {
+ SIZE size;
+ GetTextExtentPoint32W(DC, &StrW[i - zero_count], 1 + zero_count, &size);
+ if ((size.cx == Dx[i])) {
+ wchar_count++;
+ cell_count += cells[i];
+ }
+ else {
+ if (cell_count > 0) {
+ DrawStrWSub(DC, BGDC, &StrW[start_idx], &Dx[start_idx], wchar_count, cell_count,
+ font_width, font_height, Y, X);
+ start_idx += wchar_count;
+ }
+ DrawChar(DC, BGDC, *X, Y, &StrW[i - zero_count], 1 + zero_count, cells[i]);
+ *X += cells[i] * FontWidth;
+ zero_count = 0;
+ cell_count = 0;
+ wchar_count = 0;
+ start_idx++;
+ }
+ }
+ }
+ if (cell_count != 0) {
+ DrawStrWSub(DC, BGDC, &StrW[start_idx], &Dx[start_idx], wchar_count, cell_count, font_width, font_height, Y,
+ X);
+ }
+ }
+ else {
+ DrawStrWSub(DC, BGDC, StrW, Dx, len, cell, font_width, font_height, Y, X);
+ }
+
+ if (w->debug_drawbox_text) {
+ int width = cell * font_width;
+ int height = font_height;
+ DrawBox(DC, sx, Y, width, height, RGB(0, 255, 0));
+ }
}
/**
@@ -3936,3 +4058,15 @@ BOOL ThemeIsEnabled(void)
vtdisp_work_t *w = &vtdisp_work;
return w->bg_enable;
}
+
+void DispEnableResizedFont(BOOL enable)
+{
+ vtdisp_work_t *w = &vtdisp_work;
+ w->font_resize_enable = enable;
+}
+
+BOOL DispIsResizedFont()
+{
+ vtdisp_work_t *w = &vtdisp_work;
+ return w->font_resize_enable;
+}
diff --git a/teraterm/teraterm/vtdisp.h b/teraterm/teraterm/vtdisp.h
index 2bf8fd610..b9c90f49d 100644
--- a/teraterm/teraterm/vtdisp.h
+++ b/teraterm/teraterm/vtdisp.h
@@ -133,6 +133,8 @@ void DrawStrW(HDC DC, HDC BGDC, const wchar_t *StrW, const char *WidthInfo, int
int Y, int *X);
void DrawStrA(HDC DC, HDC BGDC, const char *StrA, const char *WidthInfo, int Count, int font_width, int font_height,
int Y, int *X);
+void DispEnableResizedFont(BOOL enable);
+BOOL DispIsResizedFont();
extern int WinWidth, WinHeight;
extern HFONT VTFont[AttrFontMask+1];
diff --git a/tests/unicodebuf-combining-spacing_mark.pl b/tests/unicodebuf-combining-spacing_mark.pl
index 9325e4ec4..bb89bda27 100644
--- a/tests/unicodebuf-combining-spacing_mark.pl
+++ b/tests/unicodebuf-combining-spacing_mark.pl
@@ -8,25 +8,17 @@
#
print "Malayalam\n";
print "\N{U+0d2e}\N{U+0d32}\N{U+0d2f}\N{U+0d3e}\N{U+0d33}\N{U+0d02}\n";
+print "\N{U+0d28}\N{U+0d2e}\N{U+0d38}\N{U+0d4d}\N{U+0d15}\N{U+0d3e}\N{U+0d30}\N{U+0d02}\n";
+print "\N{U+0d28}| U+0d28 1cell\n";
print "\N{U+0d2e}| U+0d2e 1cell\n";
print "\N{U+0d32}| U+0d32 1cell\n";
print "\N{U+0d2f}\N{U+0d3e}| U+0d2f U+0d3e(Spacing Mark) 2cell\n";
print "\N{U+0d33}\N{U+0d02}| U+0d33 U+0d02(Spacing Mark) 2cell\n";
-print "\n";
-
-print "Hello (in Malayalam)\n";
-print "\N{U+0d28}\N{U+0d2e}\N{U+0d38}\N{U+0d4d}\N{U+0d15}\N{U+0d3e}\N{U+0d30}\N{U+0d02}\n";
-
-print "\N{U+0d28}| U+0d28 1cell\n";
-print "\N{U+0d2e}| U+0d2e 1cell\n";
print "\N{U+0d38}\N{U+0d4d}\N{U+0d15}\N{U+0d3e}| U+0d38 U+0d4d(Nonspacing Mark) U+0d15 U+0d3e(Spacing Mark) 3cell\n";
print "\N{U+0d30}\N{U+0d02}| U+0d30 U+0d02(Spacing Mark) 2cell\n";
print "\n";
-print "\N{U+307B}\N{U+309A}| U+307B U+309A (縺サ + 繧 = 縺ス)\n";
-print "\n";
-
# repeat spacing mark
print "repeat spacing mark\n";
for ($i = 0 ; $i < 10 + 2; $i++) {
@@ -40,8 +32,13 @@
print "| U+0d33 + U+0d02 * 10 11cell\n";
print "\n";
+# Japanese
+print "Japanese\n";
+print "\N{U+307B}\N{U+309A}| U+307B U+309A (縺サ + 繧 = 縺ス)\n";
+print "\n";
+
# virama
-print "Virama test\n";
+print "Virama\n";
# Devanagari
# wget https://raw.githubusercontent.com/emacs-mirror/emacs/master/etc/HELLO -O - --quiet | grep Devanagari