トップページ > 記事閲覧
ふりがなを表記したい
名前:BayLeaf 日時: 2018/03/04 10:07

いつもお世話になっております。 漢字などの上にふりがな(ルビ)を表記したいなと思っていたのですが、 上手く処理ができずどうすればよいのか質問しに来ました。 "DXライブラリ(ディーエックスライブラリ)"のような 表記でも良いと思ったのですが、見にくくなってしまうので ふりがな表記ができたらと思います。 理想としては DrawString などに対して該当文字とその後に特定の文字を付与することで 実現したいのですが、こういった機能または関数はありますでしょうか? 例えばプログラムなら下記のような感じです。 DrawString(0, 0, "<a--DX--><b--ディーエックス-->ライブラリ", GetColor(255,255,255));
メンテ

Page: 1 |

Re: ふりがなを表記したい ( No.1 )
名前:MOR 日時:2018/03/04 21:41

超適当コードを書いてみました。(※修正 整数だと精度が低かったので小数に一部変更, ループバグ修正) #include "DxLib.h" #include <string> using namespace std; typedef std::basic_string<TCHAR> tstring; // "<|原文|ルビ|>" 形式 int GetDrawStringWidthToHandleWithRuby(const TCHAR *String, int StrLen, int FontHandle_TEXT, int FontHandle_RUBY) { if (String == NULL) return -1; if (FontHandle_RUBY <= 0 || FontHandle_TEXT <= 0) return -1; tstring s = String, s0, ss0, t1, t2; int i = 0, j, xx=0; while (i < (int)s.length()) { int i1 = -1, i2 = -1, i3 = -1; i1 = s.find(TEXT("<|"), i); if (i1 >= 0) { i2 = s.find(TEXT("|"), i1 + 2); if (i2 > 0) { i3 = s.find(TEXT("|>"), i2 + 1); } } if (i1 >= 0 && i2 > 0 && i3 > 0) { if (i1 > i) { s0 = s.substr(i, i1 - i); j = DxLib::GetDrawStringWidthToHandle(s0.c_str(), s0.length(), FontHandle_TEXT); if (j == -1) return -1; xx += j; } t1 = s.substr(i1 + 2, i2 - 1 - (i1 + 2) + 1); t2 = s.substr(i2 + 1, i3 - 1 - (i2 + 1) + 1); int wd1, wd2; wd1 = DxLib::GetDrawStringWidthToHandle(t1.c_str(), t1.length(), FontHandle_TEXT); if (wd1 == -1) return -1; wd2 = DxLib::GetDrawStringWidthToHandle(t2.c_str(), t2.length(), FontHandle_RUBY); if (wd2 == -1) return -1; if (wd1 >= wd2) { xx += wd1; } else { xx += wd2; } i = i3 + 2; } else { ss0 = s.substr(i, s.length() - i); xx += DxLib::GetDrawStringWidthToHandle(ss0.c_str(), ss0.length(), FontHandle_TEXT); i = s.length(); } } return xx; } // "<|原文|ルビ|>" 形式 int DrawStringToHandleWithRuby(int x, int y, const TCHAR *String, unsigned int Color, int FontHandle_TEXT, int FontHandle_RUBY, unsigned int EdgeColor=0) { if (String == NULL) return -1; if (FontHandle_RUBY <= 0 || FontHandle_TEXT <= 0) return -1; tstring s = String, s0, ss0, t1, t2; int wwd, i = 0, j; double xx2, xx = x, dSPC; while (i < (int)s.length()) { int i1 = -1, i2 = -1, i3 = -1; i1 = s.find(TEXT("<|"), i); if (i1 >= 0) { i2 = s.find(TEXT("|"), i1 + 2); if (i2 > 0) { i3 = s.find(TEXT("|>"), i2 + 1); } } if (i1 >= 0 && i2 > 0 && i3 > 0) { if (i1 > i) { s0 = s.substr(i, i1 - i); if (-1 == DxLib::DrawStringToHandle((int)xx, y, s0.c_str(), Color, FontHandle_TEXT, EdgeColor)) return -1; j = DxLib::GetDrawStringWidthToHandle(s0.c_str(), s0.length(), FontHandle_TEXT); if (j == -1) return -1; xx += j; } t1 = s.substr(i1 + 2, i2 - 1 - (i1 + 2) + 1); t2 = s.substr(i2 + 1, i3 - 1 - (i2 + 1) + 1); int wd1, wd2; wd1 = DxLib::GetDrawStringWidthToHandle(t1.c_str(), t1.length(), FontHandle_TEXT); if (wd1 == -1) return -1; wd2 = DxLib::GetDrawStringWidthToHandle(t2.c_str(), t2.length(), FontHandle_RUBY); if (wd2 == -1) return -1; if (wd1 >= wd2) { if (-1 == DxLib::DrawStringToHandle((int)xx, y, t1.c_str(), Color, FontHandle_TEXT, EdgeColor)) return -1; dSPC = (double)(wd1 - wd2) / (double)(t2.length() + 1); xx2 = xx + dSPC; for (j = 0; j < (int)t2.length(); j++) { ss0 = t2[j]; if (-1 == DxLib::DrawStringToHandle((int)xx2, y - DxLib::GetFontSizeToHandle(FontHandle_RUBY), ss0.c_str(), Color, FontHandle_RUBY, EdgeColor)) return -1; wwd = DxLib::GetDrawStringWidthToHandle(ss0.c_str(), 1, FontHandle_RUBY); xx2 += wwd + dSPC; } xx += wd1; } else { dSPC = (double)(wd2 - wd1) / (double)(t1.length() + 1); xx2 = xx + dSPC; for (j = 0; j < (int)t1.length(); j++) { ss0 = t1[j]; if (-1 == DxLib::DrawStringToHandle((int)xx2, y, ss0.c_str(), Color, FontHandle_TEXT, EdgeColor)) return -1; wwd = DxLib::GetDrawStringWidthToHandle(ss0.c_str(), 1, FontHandle_TEXT); xx2 += wwd + dSPC; } if (-1 == DxLib::DrawStringToHandle((int)xx, y - DxLib::GetFontSizeToHandle(FontHandle_RUBY), t2.c_str(), Color, FontHandle_RUBY, EdgeColor)) return -1; xx += wd2; } i = i3 + 2; } else { if (-1 == DxLib::DrawStringToHandle((int)xx, y, s.substr(i, s.length() - i).c_str(), Color, FontHandle_TEXT, EdgeColor)) return -1; i = s.length(); } } return 0; } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { DxLib::ChangeWindowMode(TRUE); DxLib::SetGraphMode(640, 480, 32); if (DxLib::DxLib_Init() == -1) return -1; DxLib::SetDrawScreen(DX_SCREEN_BACK); int hFont_RUBY = DxLib::CreateFontToHandle(NULL, 8, -1, DX_FONTTYPE_ANTIALIASING_EDGE_4X4); int hFont_TEXT = DxLib::CreateFontToHandle(NULL, 20, -1, DX_FONTTYPE_ANTIALIASING_EDGE_4X4); while (DxLib::ProcessMessage() == 0 && DxLib::CheckHitKeyAll() == FALSE) { DxLib::ClearDrawScreen(); // ルビなし DrawStringToHandleWithRuby(0, 40, TEXT("あ、DXライブラリはなんと完全無料です!"), DxLib::GetColor(255, 255, 255), hFont_TEXT, hFont_RUBY); // なんちゃってモノルビ+なんちゃってグループルビ DrawStringToHandleWithRuby(0, 80, TEXT("あ、<|D|ディー|><|X|エックス|>ライブラリはなんと<|完全無料|タダ|>です!"), DxLib::GetColor(255, 255, 0), hFont_TEXT, hFont_RUBY); DxLib::ScreenFlip(); } DxLib::InitFontToHandle(); return DxLib::DxLib_End(); }
メンテ
Re: ふりがなを表記したい ( No.2 )
名前:管理人 日時:2018/03/04 22:00

> 理想としては DrawString などに対して該当文字とその後に特定の文字を付与することで > 実現したいのですが、こういった機能または関数はありますでしょうか? すみません、ありません 現在の機能でも MORさんが載せてくださったプログラムのように、ルビ用のフォントハンドルを用意して、 ルビを表示したい文字列に対して GetDrawStringWidthToHandle を使用してルビを表示すべき座標を割り出して描画する、 といった方法で実現することができます
メンテ
Re: ふりがなを表記したい ( No.3 )
名前:BayLeaf(解決) 日時:2018/03/05 21:00

> MORさん ソースコードありがとうございます。 参考にさせていただきます。 > 管理人さん 分かりました。 MORさんのコードを参考にして自作プログラムに埋め込めるよう頑張ってみます。 取り敢えず解決にしておきます。 分からないことができましたらまた聞きに来ますね。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存