【HSP】縁取り文字列描画方法【いくつか】

【HSP】縁取り文字列描画方法【いくつか】

HSP で縁取り文字列を描画したくなったのでしてみました。
GDI を使う方法と、HSPの標準命令を使ってやる方法の 2つ紹介します。

1。GDI を使って描画する

#include "gdi32.as"

// 
// メイン
// 
font "MS UI Gothic", 80
string = "てすと"

mref BMSCR, 67

// ペンの作成・設定
CreatePen 0, int(0.04 * abs(BMSCR.49)), 0x000000 // PS_SOLID
SelectObject hdc, stat
hPenPrev = stat

// ブラシの作成・設定
CreateSolidBrush 0xFFFF80
SelectObject hdc, stat
hBrushPrev = stat

// 描画設定
SetBkMode hdc, 1 // TRANSPARENT

// 描画サイズ算出
dim size, 2
GetTextExtentPoint32 hdc, varptr(string), strlen(string), varptr(size)

// 描画
BeginPath hdc
TextOut hdc, ginfo_cx, ginfo_cy, varptr(string), strlen(string)
EndPath hdc
StrokeAndFillPath hdc

// ブラシの設定・削除
SelectObject hdc, hBrushPrev
DeleteObject stat

// ペンの設定・削除
SelectObject hdc, hPenPrev
DeleteObject stat

// 反映
redraw 1, ginfo_cx, ginfo_cy, size.0, size.1

参考:「その66 WindowsAPIな力でアウトラインフォントを描画する

abs(BMSCR.49) はフォントサイズの取得をしているだけで、0.04倍しているのは、テキトーに縁の線の太さを決めているだけです。(本当はファントサイズは正の時と負の時で数値の意味が違うのですが、HSP の場合は基本的に変わらないので単純に絶対値をとるだけにしました)
ポイントは、BeginPath ~ EndPath と StrokeAndFillPath を使うことで縁も描画していることろです。
HSP のシステム変数の hdc は裏画面のハンドルなので、redraw でウィンドウに反映させる必要があります。
mes 命令を使用していないので (確認してないけどたぶん) ginfo で描画サイズを得られないので、GetTextExtentPoint32 関数を使って大きさを算出しておき、redraw するとき、文字列の範囲だけ更新するようにします。
16進数の色の設定は、COLORREF型なので、RGB でなく BGR の順になっていることに注意!
なぜか font 指定しないで実行すると何も描画されない…orz
BMSCR 構造体覗けば原因わかるかもだけど、自分はこっちより次の方法でやりたいので放置。

2.文字の周りにずらして表示して縁にする

// 
// メイン
// 
font "MS UI Gothic", 80
string = "てすと"

mref BMSCR, 67

x = ginfo_cx
y = ginfo_cy

r = 0.04 * abs(BMSCR.49)
n = int(2.0 * M_PI * r)

color 0x00, 0x00, 0x00

repeat n
rad = 2.0 * M_PI * cnt / n
pos x + int(r * cos(rad)), y + int(r * sin(rad))
mes string
loop

color 0x80, 0xFF, 0xFF
pos x, y
mes string

参考:「丸文字縁取り描画テスト | Codetter(こーどったー)β

こっちの方法だと、めっちゃ無駄に描画されるからフォントサイズをデカくしたりすると恐ろしく遅くなるんだけど、簡単で、しかも角丸いから見た目的にやさしい (?) 上の画像だとあまり違いわからないかもだけど、もっとフォントサイズ大きくすると違いがはっきりする。
あと、必ず文字の周りに輪郭が出るから、文字がつぶれることがない。どういうことかと言うと、さっきの GDI を使う方法だと、フォントの種類や太字かどうかなどで、輪郭の線でつぶれてしまう (中の塗りつぶされてる部分が見えない) 可能性がある。こちらはそうはならない。
描画個数はテキトーだけど、とりあえず円の外周の長さだけ表示することに。

まとめ

あまり大きなサイズで描画しないなら後者、速度最優先なら前者、でいいと思う。
ただ、前者なら、他の Win32API も使うことでより高度な描画ができるかもしれない。(一定範囲内だけの描画、など)
今回はこのへんで、またいつか~。
↓ブログランキング投票 (クリック) お願いします~