Artlet2D モジュール(以下 a2d)だけでは出来ないみたいですね。
少し調べてみると a2d 内で使用している GDI+ の API には、
文字列の輪郭をパスにして描画する機能があったので a2d モジュールを拡張すれば出来そうです。
そこで a2d を参考にそれを拡張するモジュールを作ってみました、
正確に言えば、拡張というよりも a2d におんぶにだっこで当該機能だけを記述したものですが。
(命令名やモジュール名など適当なネーミングなので不自然だったら変えてください)
必要最小限の機能しかありませんが a2d の力を借りることで
ペンや色の設定などを一応適用できています(全ては試してないですが)。
使い方は、
a2d.hsp をインクルードした後に、この拡張モジュールをインクルードすることで
新たに、文字の輪郭を描画する alDrawTextPath 命令が追加されるので、
後はそれを使ってテキストを描画してください。
alDrawTextPath 命令の使用法は alDrawText 命令と同じです
(ただ、なにか必要な工程が足りてないのか、表示場所が alDrawText と比べ数ピクセルずれる現象があるので
alDrawText と alDrawTextPath を組み合わせて使う場合は位置の微調整が必要です)。
# a2d も GDI+ もそんなに私は理解して無いので
# 何かしら間違いがあるかもしれません。突っ込み歓迎。
拡張モジュール。
ファイル名は仮として "a2d_add_textpath.hsp" としておきます。
#ifndef alInitModule_add_textpath
#module a2d_add_textpath
#uselib "gdiplus.dll"
#func GdipGetFontStyle "GdipGetFontStyle" sptr,sptr
#func GdipGetFontSize "GdipGetFontSize" sptr,sptr
#func GdipCreatePath "GdipCreatePath" sptr,sptr
#func GdipGetFamily "GdipGetFamily" sptr,sptr
#func GdipAddPathStringI "GdipAddPathStringI" sptr,wstr,sptr,sptr,sptr,sptr,sptr,sptr
#func GdipAddPathString "GdipAddPathString" sptr,wptr,sptr,sptr,sptr,sptr,sptr,sptr
#func GdipDrawPath "GdipDrawPath" sptr,sptr,sptr
#func GdipFillPath "GdipFillPath" sptr,sptr,sptr
#func GdipGetSolidFillColor "GdipGetSolidFillColor" sptr,sptr
#func GdipSetSolidFillColor "GdipSetSolidFillColor" sptr,sptr
#func GdipDeleteFontFamily "GdipDeleteFontFamily" sptr
#func GdipDeletePath "GdipDeletePath" sptr
#func GdipGetBrushType "GdipGetBrushType" sptr,sptr
#enum FillModeAlternate = 0
#enum FillModeWinding
; 文字列のパスを描画する(いわゆる袋文字、wikiによると白抜き文字、縁取り文字、アウトライン文字とも呼ぶらしい)
#deffunc alDrawTextPath_ str p1, int px, int py, int pw, int ph, int pah, int pav
if imgFont@a2d {
GdipGetFontSize imgFont@a2d, varptr(fontSize)
GdipGetFontStyle imgFont@a2d, varptr(fontStyle)
GdipCreatePath FillModeAlternate, varptr(pPath)
GdipGetFamily imgFont@a2d, varptr(pFontFamily)
GdipCreateStringFormat@a2d 0, 0, varptr(tmpFormat)
GdipSetStringFormatAlign@a2d tmpFormat, pah
GdipSetStringFormatLineAlign@a2d tmpFormat, pav
rectf = px, py, pw, ph
GdipAddPathStringI pPath, p1, -1, pFontFamily, fontStyle, fontSize, varptr(rectf), tmpFormat
if stat = 0 {
GdipDrawPath imgGraphics@a2d, imgPen@a2d, pPath ; パスの描画
}
// 開放
GdipDeleteStringFormat@a2d tmpFormat
GdipDeleteFontFamily pFontFamily
GdipDeletePath pPath
}
return
#define global alDrawTextPath(%1="", %2=0, %3=0, %4=9999, %5=9999, %6=0, %7=0) alDrawTextPath_ %1, %2, %3, %4, %5, %6, %7
#global
上記のモジュールを保存し、同じフォルダーで以下のサンプルを実行してください。
サンプルその1
#include "a2d.hsp"
#include "a2d_add_textpath.hsp"
alCreateImage 0, GINFO_WINX, GINFO_WINY
alPenWidth 2 ; ←枠線の太さを変えられる
alPenStyle DashStyleSolid ; ←点線にも出来る
// 適当な背景を描画
size = 20
repeat 480 / size + 1
alColor 180, 255, 220 :alFillRect 0, cnt * size, 640, size / 2
loop
// テキストのフォントと色
fsize = 55
alFont "メイリオ", fsize, 1
alColor 0, 0, 0, 255
// a2d モジュールの命令でテキストを描画
text = "★通常の文字"
alDrawText text, 0, 0
// 独自に拡張した命令で、テキストの枠線を描画
text = "★縁取り文字"
alDrawTextPath text, 0, fsize * 1
// 枠線を点線にしてみる
text = "★枠線を点線に"
alPenWidth 1
alPenStyle DashStyleDash
alDrawTextPath text, 0, fsize * 2
alPenWidth 2
alPenStyle DashStyleSolid
// 中を塗る
text = "★中を塗り潰す"
alColor 255, 255, 255 :alDrawText text, 0, fsize * 3
alColor 0, 0 ,0 :alDrawTextPath text, -2, fsize * 3
// 枠にグラデーションを適用
text = "★枠をグラデーション"
alPenWidth 4
alGradientColor 0, 0, 20, 20, RGBA(255, 127, 255), RGBA(255, 200, 0), WrapModeTileFlipX
alDrawTextPath text, 0, fsize * 4
// 中身と輪郭にそれぞれ別のグラデーションを適用
text = "★中と枠グラデーション"
alPenWidth 4
alGradientColor 0, 0, 0, 44, RGBA(200, 0, 0), RGBA(255, 220, 50), WrapModeTileFlipXY
alDrawText text, 2, fsize * 5
alGradientColor 0, 0, 0, 44, RGBA(60, 50, 30), RGBA(180, 150, 0), WrapModeTileFlipXY
alDrawTextPath text, 0, fsize * 5
// 枠にテクスチャーを適用
text = "★枠をテクスチャー"
alCreateImageByFile 1, DIR_EXE + "\\sample\\Artlet2D\\texture.jpg"
alSelectImage 0
alTextureImage 1, WrapModeTileFlipXY
alDrawTextPath text, 0, fsize * 6
// 中身と輪郭にそれぞれ別のテクスチャーを適用
text = "★中と枠テクスチャー"
alPenWidth 5
alCreateImageByFile 2, DIR_EXE + "\\sample\\game\\bg.bmp"
alSelectImage 0
alTextureImage 1, WrapModeTileFlipXY
alDrawText text, 1, fsize * 7
alTextureImage 2, WrapModeTileFlipXY
alDrawTextPath text, 0, fsize * 7
// 最後に HSP のウィンドウに画面をコピー
alCopyImageToScreen 0, 0
redraw 1 ; 画面更新
サンプルその2
#include "a2d.hsp"
#include "a2d_add_textpath.hsp"
alCreateImage 0, GINFO_WINX, GINFO_WINY
alGradientColor 0, 0, GINFO_WINX, 0, RGBA(255, 255, 255), RGBA(160, 220, 255), WrapModeTileFlipX
alFillRect 0, 0, GINFO_WINX, GINFO_WINY
// フォントと色
fsize = 51 :margin = 6
alFont "メイリオ", fsize, 1
alPenWidth 1
text = "☆あかさたなabcXYZ㍻"
y = 0
// 文字の中を塗った後に縁を描く
alColor 255, 255, 255 :alDrawText text, 0, y
alColor 0, 0, 0 :alDrawTextPath text, -1, y
y += fsize + margin
// 文字の縁を描いた後に中を塗る
alColor 0, 0, 0 :alDrawTextPath text, -1, y
alColor 255, 255, 255 :alDrawText text, 0, y
y += fsize + margin
// 少しずらして表示するとちょっと立体的に見える?の術。影が白・文字が黒
alColor 255, 255, 255 :alDrawText text, 2, y
alColor 0, 0, 0 :alDrawTextPath text, 1, y
:alDrawText text, 0, y
y += fsize + margin
// 少しずらして表示するとちょっと立体的に見える?の術。影が黒・文字が白
alColor 0, 0, 0 :alDrawText text, 3, y
alColor 255, 255, 255 :alDrawText text, 0, y
alColor 0, 0, 0 :alDrawTextPath text, -1, y
y += fsize + margin
// 枠線を複数あるように見せる。黒・白・黒
alPenWidth 6 :alColor 0, 0, 0 :alDrawTextPath text, -1, y
alPenWidth 4 :alColor 255, 255, 255 :alDrawTextPath text, -1, y
:alColor 0, 0, 0 :alDrawText text, 0, y
y += fsize + margin
// 枠線を複数あるように見せる。黒・白・緑・黄色
alPenWidth 8 :alColor 0, 0, 0 :alDrawTextPath text, -1, y
alPenWidth 6 :alColor 255, 255, 255 :alDrawTextPath text, -1, y
alPenWidth 2 :alColor 0, 255, 0 :alDrawTextPath text, -1, y
:alColor 255, 255, 0 :alDrawText text, 0, y
y += fsize + margin
// 後ろをぼかした風の橙色・白
alColor 255, 120, 0, 30
repeat 12
alPenWidth cnt :alDrawTextPath text, -1, y
loop
alPenWidth 1 :alColor 255, 255, 255 :alDrawText text, 0, y
y += fsize + margin
// 後ろをぼかした風のピンク・白・ピンク
alColor 255, 130, 200, 30
repeat 12
alPenWidth cnt :alDrawTextPath text, 0, y
loop
alPenWidth 3 :alColor 255, 255, 255 :alDrawTextPath text, -1, y
:alColor 255, 120, 200 :alDrawText text, 0, y
y += fsize + margin
// 最後に HSP のウィンドウに画面をコピー
alCopyImageToScreen 0, 0
redraw 1 ; 画面更新
簡単な拡張ですが、工夫しだいでは色々できそうではあります。