HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2026
0312
Area39HSPにてベクトル文字の表示は可能ですか?13解決


Area39

リンク

2026/3/12(Thu) 11:19:55|NO.104819

HSPにおいて、𝕏←このような(表示されているか不安ですが・・・)
ベクトル文字といいますか、
https://monsgrax.com/wp-content/uploads/2024/11/image-77-1024x344.png
このような文字列は表示可能でしょうか?

ベクトル図を扱うプログラムを書いており、ベクトル名称をうまく表示できたらいいと思って居ます。
上記を、

mes "𝕏"
として命令を記述しても、画面上では、??となってしまい表示できません。

他の代替策として、

・ X
のような文字や、

→ X
のような文字列でもいいかと思っております。

ただし、


mes "→\n" mes "X"
のような表記や、画像を作っての貼り付けは本来の趣旨と違ってしまうので、解答外とさせていただきます。



この記事に返信する


0x0-nyan

リンク

2026/3/12(Thu) 19:51:42|NO.104820

標準のmes命令やスクリプトエディタはShift_JISしか対応していないので文字化け
してしまいますがWindows APIのDrawTextW関数またはTextOutW関数を使えば表示できます。

𝕏の文字コードはUTF-16(wchar_t)では0xD835, 0xDD4Fの4バイトです。
参考-> https://unicodeplus.com/U+1D54F

wchar_t型のサイズは2バイトですがHSPの配列のサイズは4バイトですのでエンディアンを
考慮して4バイト型にはめると0xDD4FD835となります。(Windowsは基本リトルエンディアンです)

DrawTextWまたはTextOutWに指定する文字数のパラメータは本来は実際の文字数を指定しますが
𝕏はどうやら2文字分を消費するようです。(私はこれに気付くまでに時間がかかりました)
メモ帳にペーストして選択すると選択箇所が半分に分かれていることが確認できます。



#uselib "Gdi32.dll" #func TextOutW "TextOutW" int, int, int, wptr, int #uselib "User32.dll" #func InvalidateRect "InvalidateRect" int, int, int *main // 文字コードとnull終端を代入 charCode = 0xDD4FD835, 0 // TextOutW関数の第4パラメータにcharCodeのポインタを渡してUnicode文字を出力する font "Lucida Sans Unicode", 16 TextOutW hDC, 0, 0, varptr(charCode), 2 // 通常の文字なら第4パラメータに直接指定できる TextOutW hDC, 0, 14, "wchar_t", 7 // 描画領域を更新 dim rect, 4 rect.0 = 0 rect.1 = 0 rect.2 = 64 rect.3 = 128 InvalidateRect hWnd, varptr(rect), 0



zakki

リンク

2026/3/12(Thu) 22:55:06|NO.104821

hsp3utfランタイムを使うと普通に `mes "𝕏"` 出来ますがデフォルトだと無理で、
別途テキストエディタでUTF-8のhspファイル作ってhspcmpコマンドでコンパイルする感じです。
使ってないので詳細分かりませんがこういった開発環境を使うと楽かも。
https://hsp.tv/play/pforum.php?mode=pastwch&num=93112



Area39

リンク

2026/3/12(Thu) 23:32:40|NO.104822

0x0-nyan 様

返信ありがとうございます。
プログラムの方、動作確認させていただきました。

そちらのプログラムを元にとりあえず、大文字のA〜Zまでの文字列を表示するように作ってみました。

#uselib "Gdi32.dll" #func TextOutW "TextOutW" int, int, int, wptr, int #uselib "User32.dll" #func InvalidateRect "InvalidateRect" int, int, int *main // 文字コードとnull終端を代入 charCode(01) = 0xDD38D835,0 // A charCode(02) = 0xDD39D835,0 // B charCode(03) = 0x2102 ,0 // C charCode(04) = 0xDD3BD835,0 // D charCode(05) = 0xDD3CD835,0 // E charCode(06) = 0xDD3DD835,0 // F charCode(07) = 0xDD3ED835,0 // G charCode(08) = 0x210D ,0 // H charCode(09) = 0xDD40D835,0 // I charCode(10) = 0xDD41D835,0 // J charCode(11) = 0xDD42D835,0 // K charCode(12) = 0xDD43D835,0 // L charCode(13) = 0xDD44D835,0 // M charCode(14) = 0x2115 ,0 // N charCode(15) = 0xDD46D835,0 // O charCode(16) = 0x2119 ,0 // P charCode(17) = 0x211A ,0 // Q charCode(18) = 0x211D ,0 // R charCode(19) = 0xDD4AD835,0 // S charCode(20) = 0xDD4BD835,0 // T charCode(21) = 0xDD4CD835,0 // U charCode(22) = 0xDD4DD835,0 // V charCode(23) = 0xDD4ED835,0 // W charCode(24) = 0xDD4FD835,0 // X charCode(25) = 0xDD50D835,0 // Y charCode(26) = 0x2124 ,0 // Z screen 0,900 // TextOutW関数の第4パラメータにcharCodeのポインタを渡してUnicode文字を出力する boxf color 255,255,255 font "Lucida Sans Unicode", 30 repeat 27 TextOutW hDC, 030*cnt, 0, varptr(charCode(cnt)), 2 loop // 描画領域を更新 dim rect, 4 rect.0 = 0 rect.1 = 0 rect.2 = ginfo_winx rect.3 = ginfo_winy InvalidateRect hWnd, varptr(rect), 0

これで実行してみると分かるかと思いますが、
C,H,N,P,Q,R,Zが他と比べて大きくなってしまいます。
いただきました参考URLのほうにもこの文字列が無かったので似たような文字を拾ってきた次第です。
この問題は文字コードの問題なので本来ここでの質問とは関係なくなってしまうかもしれませんが
同じように表示する方法は何かありますでしょうか?

ご確認よろしくお願いいたします。



Area39

リンク

2026/3/12(Thu) 23:50:59|NO.104823

zakki さま

返信ありがとうございます。
こういった開発環境があるのですね。
今後の参考にさせていただきます、ありがとうございます。



沢渡

リンク

2026/3/13(Fri) 14:35:46|NO.104825

Unicodeの文字用記号ブロックと数学用英数字記号ブロックは別カテゴリ扱いで、
そのくせ「文字用記号ブロックにある文字は
数学用英数字記号ブロックには含めなくてもいいだろ」と該当する文字を
欠番にしているあたり、話がだいぶややこしくなっているようで。

フォントの問題かと思って色々試してみたところ、
Windows標準フォントの中ではCambriaがなかなか良い感じでした。
(ただし、Cambriaはロケールの問題でかShift_JISに対応しておらず、
 mes命令で日本語を表示すると文字化けするので、日本語を表示する場合は
 適宜フォントを変えるか、もしくはcnvstowでUTF-16に変換してから
 TextOutW等で表示する、といった対策が必要になります。
 以下、TextOutWで日本語出力してみた例)

#uselib "Gdi32.dll" #func TextOutW "TextOutW" int, int, int, wptr, int font "Cambria", 30 sdim buf,16 //変換後の文字数×2+2。 //(バッファ量は多くても特に問題はないので、strlenでのバイト数×2+2だけ確保すれば確実) cnvstow buf,"東京特許許可局" TextOutW hDC,0,0,varptr(buf),7 redraw 1



Area39

リンク

2026/3/13(Fri) 21:48:43|NO.104826

沢渡 さま

いつもありがとうございます。

提示していただきましたプログラム実行してみましたが、私の環境においては、
普通のゴシック文字で表示されるだけでした

https://monsgrax.com/wp-content/uploads/2024/11/image-77-1024x344.png
ここにあるような文字を表示したいと思っております。

ご確認よろしくお願いいたします。


もう少し自分で調べてみようと思います。



沢渡

リンク

2026/3/13(Fri) 22:55:51|NO.104827

すみません、説明が足りませんでした。
私が言ったのは、Area39様がNO.104822で書かれた「font "Lucida Sans Unicode", 30」の
フォント指定の部分を「"Cambria"」に置き換えたら上手くいきましたよ、という話です。

私が書いたコードは、「フォントをCambriaにしたら日本語が上手く表示されないから、
その場合はどうすればいいのか」というものであって、ちょっと横道にそれた話です。
紛らわしいことを言って申し訳ありません。



Area39

リンク

2026/3/13(Fri) 23:43:42|NO.104828

沢渡 さま、皆様


ありがとうございます。
沢渡さまが教えていただいたとおり、フォントをCambriaに変更した所、大きさの均一な
文字に変更することが出来ました。

あとは、メモリ操作のあたりで困っている部分があります。


#uselib "Gdi32.dll" #func TextOutW "TextOutW" int, int, int, wptr, int #uselib "User32.dll" #func InvalidateRect "InvalidateRect" int, int, int *main // 文字コード charCode(01) = 0xDD38D835 // A charCode(02) = 0xDD39D835 // B charCode(03) = 0x2102 // C charCode(04) = 0xDD3BD835 // D charCode(05) = 0xDD3CD835 // E charCode(06) = 0xDD3DD835 // F charCode(07) = 0xDD3ED835 // G charCode(08) = 0x210D // H charCode(09) = 0xDD40D835 // I charCode(10) = 0xDD41D835 // J charCode(11) = 0xDD42D835 // K charCode(12) = 0xDD43D835 // L charCode(13) = 0xDD44D835 // M charCode(14) = 0x2115 // N charCode(15) = 0xDD46D835 // O charCode(16) = 0x2119 // P charCode(17) = 0x211A // Q charCode(18) = 0x211D // R charCode(19) = 0xDD4AD835 // S charCode(20) = 0xDD4BD835 // T charCode(21) = 0xDD4CD835 // U charCode(22) = 0xDD4DD835 // V charCode(23) = 0xDD4ED835 // W charCode(24) = 0xDD4FD835 // X charCode(25) = 0xDD50D835 // Y charCode(26) = 0x2124 // Z dim code,1024 len = 0 repeat 26,1 getstr tmp,CharCode(cnt),0,'00' lpoke code,len,CharCode(cnt) len += strsize loop screen 0,900 redraw 0 // TextOutW関数の第4パラメータにcharCodeのポインタを渡してUnicode文字を出力する boxf color 255,255,255 font "Cambria", 30 TextOutW hDC, 0, 0, varptr(code), 1024 repeat 26,1 TextOutW hDC, 030*(cnt-1), 030, varptr(charCode(cnt)), 2 loop redraw 1

上記はみなさまに教えていただいたものをまとめたものとなります。
下の文字の方は一個ずつ並べて表示しているのに対して
上の文字の方はつなげて表示しようとしておりますが、メモリ操作がうまくないのか
失敗してしまいます。
長さを取得してやっているのですが、うまくいきません。
おかしい所ありましたら教えてください、
質問ばかりとなってしまい申し訳ございませんが、ご回答よろしくお願いいたします。



沢渡

リンク

2026/3/14(Sat) 11:21:42|NO.104832

このような形でやってみました。

#uselib "Gdi32.dll" #func TextOutW "TextOutW" int, int, int, wptr, int *main // 文字コード charCode(01) = 0xDD38D835 // A charCode(02) = 0xDD39D835 // B charCode(03) = 0x2102 // C charCode(04) = 0xDD3BD835 // D charCode(05) = 0xDD3CD835 // E charCode(06) = 0xDD3DD835 // F charCode(07) = 0xDD3ED835 // G charCode(08) = 0x210D // H charCode(09) = 0xDD40D835 // I charCode(10) = 0xDD41D835 // J charCode(11) = 0xDD42D835 // K charCode(12) = 0xDD43D835 // L charCode(13) = 0xDD44D835 // M charCode(14) = 0x2115 // N charCode(15) = 0xDD46D835 // O charCode(16) = 0x2119 // P charCode(17) = 0x211A // Q charCode(18) = 0x211D // R charCode(19) = 0xDD4AD835 // S charCode(20) = 0xDD4BD835 // T charCode(21) = 0xDD4CD835 // U charCode(22) = 0xDD4DD835 // V charCode(23) = 0xDD4ED835 // W charCode(24) = 0xDD4FD835 // X charCode(25) = 0xDD50D835 // Y charCode(26) = 0x2124 // Z sdim code,1024 len = 0 repeat 26,1 if CharCode(cnt) & 0xFFFF0000 { //上位2バイトが0でないのなら4バイト文字とみなす。 //なお、HSPでは0x80000000以上の値はマイナスとみなされるので、 //CharCode(cnt) > 0xFFFF ではダメ。 lpoke code,len,CharCode(cnt) len+=4 } else { wpoke code,len,CharCode(cnt) len+=2 } loop screen 0,900 redraw 0 // TextOutW関数の第4パラメータにcharCodeのポインタを渡してUnicode文字を出力する boxf color 255,255,255 font "Cambria", 30 TextOutW hDC, 0, 0, varptr(code), len/2 //TextOutWの第5パラには文字数をきっちり指定しないとダメな模様。 //(ヌル終端の0x0000で終了する、などという気のきいたことはやってくれない) repeat 26,1 if CharCode(cnt) & 0xFFFF0000 { size=2 } else { size=1 } TextOutW hDC, 030*(cnt-1), 030, varptr(charCode(cnt)), size loop redraw 1
UTF-16の仕様については、おおむね以下のような感じです。

・UTF-16のデータは2バイト単位で扱い、「1文字=2バイト」である。 ・ヌル終端も2バイトの0x0000である。 ・Unicodeの番号が0x10000以上の文字については、  「サロゲートペア」という形に変換した上で、  2文字分(都合4バイト)のデータを組み合わせて1文字を構成する。 ・UTF-16を取り扱うWinAPIで文字列の長さを指定する場合は、  「バイト数」ではなく「文字数」を指定することが大半。



Area39

リンク

2026/3/14(Sat) 21:16:55|NO.104838

沢渡 さま

無事にベクトル文字を出すことが出来ました。
また、自分で小文字、数字も出せるようになりました。

ありがとうございました。



Area39

リンク

2026/3/14(Sat) 21:48:09|NO.104839

すみません、後学の為にもあと一点だけお教えください。
改行したいときのコードはどのように指定すればよろしいでしょうか?
0X000D000Aなど、試してみましたが、うまく行きませんでした。
解決を押した後で申し訳ございません。



沢渡

リンク

2026/3/15(Sun) 13:56:21|NO.104847

TextOutWは改行コードに対応していないようですね。(やってみたら変な文字が出てきました)
代わりにDrawTextWを使うという方法もあります。
構造体代わりの配列を用意してその中で座標を指定しないといけない等少々面倒ですが、
綺麗に表示するための様々な機能があります。

#uselib "User32.dll" #func DrawTextW "DrawTextW" int,int,int,int,int //参考: //https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-drawtext sdim tmp,26 cnvstow tmp,"あいうえお\nかきくけこ" dim rect,4 //RECT構造体。 //表示する部分の左上のX座標、Y座標、右下のX座標、Y座標を指定する //ただし、DT_CALCRECTを用いる場合は左上の座標だけ指定すればよい。 rect=50,100 DrawTextW hdc,varptr(tmp),-1,varptr(rect),0x400 //第5パラにDT_CALCRECT(=0x400)を指定した場合は //描画は行わずにRECT構造体の内容を文字列に合わせて変更する。 DrawTextW hdc,varptr(tmp),-1,varptr(rect),0 //描画 redraw 1

あと細かい点ですが、改行コードのCR(0x000D)LF(0x000A)を4バイトでまとめて表現したい場合は
0x000A000Dとした方がいいです。
(リトルエンディアンのルールにより、下位バイトの方がメモリの先の方に来るので)
CRとLFを別々の2バイト数として扱って、連続させた方がわかりやすいかもしれません。
(wpoke hoge,0,0x000D : wpoke hoge,2,0x000A という具合に)



Area39

リンク

2026/3/15(Sun) 21:48:38|NO.104855

沢渡 さま

度々ありがとうございます。
確認させていただきます。

また機会ありましたら是非ともよろしくお願いいたします。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.104819への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

ONION software Copyright 1997-2025(c) All rights reserved.