超適当コードを書いてみました。(※修正 整数だと精度が低かったので小数に一部変更, ループバグ修正)
#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();
}