Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions doclib/hsp3dish_js.htm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ <h1>hsp3dish.js (WebGL/html5版)<br><br>プログラミングガイド</h1>
<li><a href="#MEDIA">メディアファイルの再生</a></li>
<li><a href="#EXEC">exec,dialog命令によるブラウザ制御</a></li>
<li><a href="#SENSOR">センサー情報の取得<span class="new">(New!)</span></a></li>
<li><a href="#STORAGE">データ保存</a></li>
<li><a href="#NOTICE">制限事項・既知の問題点</a></li>
<li><a href="#FUTURE">今後の予定</a></li>
<li><a href="#LICENSE">ライセンス・謝辞</a></li>
Expand Down Expand Up @@ -184,6 +185,9 @@ <h2 id="SCRSIZE">表示サイズのスケーリング</h2>
ENV.HSP_AUTOSCALE = "0";//スケーリングモード
ENV.HSP_FPS = "0";//フレームレート
ENV.HSP_LIMIT_STEP = "15000";//ブラウザに処理を返すまでの実行ステップ数
ENV.HSP_FONT_LEADING = "1.1";//フォントの行間調整(1.0=余白無し,1.1=標準,1.2=少し広め)
ENV.HSP_KEYBOARD_ELEMENT = null;//キーボード入力対象要素(null=ウィンドウ全体,または要素IDを"#canvas"などのように指定)
ENV.HSP_SYNC_DIR = null;//IndexDBで永続化するディレクトリ
});
</pre></ul>
<p>
Expand Down Expand Up @@ -283,6 +287,15 @@ <h2 id="SENSOR">センサー情報の取得</h2>
</p>


<h2 id="STORAGE">データ保存</h2>
<p>
基本的にはhsp3dish.jsでは、notesave命令やbsave命令などはメモリ上でエミュレートされ、ブラウザを閉じると消えてしまいます。<br>
hsp3dish.jsでの拡張としてIndexDBを使用して、データを永続化することも可能です。
ENV.HSP_SYNC_DIRに保存するディレクトリ名を指定し、<code>devcontrol "syncfs"</code>を呼び出すことで、指定したディレクトリ以下のデータをIndexedDBに保存することができます。
保存されたデータは、ブラウザを閉じても残りますので、次回起動時に復元されます。
</p>


<h2 id="NOTICE">制限事項・既知の問題点</h2>
<p>
現在のバージョンでは、以下の制限事項があります。
Expand Down
12 changes: 12 additions & 0 deletions doclib_en/hsp3dish_js.htm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ <h1>hsp3dish.js (WebGL/html5 Version)<br><br>Programming Guide</h1>
<li><a href="#MEDIA">Media File Playback</a></li>
<li><a href="#EXEC">Browser Control with exec, dialog Commands</a></li>
<li><a href="#SENSOR">Acquiring Sensor Information <span class="new">(New!)</span></a></li>
<li><a href="#STORAGE">Data Storage</a></li>
<li><a href="#NOTICE">Restrictions/Known Issues</a></li>
<li><a href="#FUTURE">Future Plans</a></li>
<li><a href="#LICENSE">License/Acknowledgements</a></li>
Expand Down Expand Up @@ -184,6 +185,8 @@ <h2 id="SCRSIZE">Scaling Display Size</h2>
ENV.HSP_AUTOSCALE = "0";//Scaling mode
ENV.HSP_FPS = "0";//Frame rate
ENV.HSP_LIMIT_STEP = "15000";//Number of execution steps before returning processing to the browser
ENV.HSP_FONT_LEADING = "1.1";//Font line spacing adjustment (1.0=No margin, 1.1=Standard, 1.2=A little wider)
ENV.HSP_KEYBOARD_ELEMENT = null;//Keyboard input target element (null=whole window, or specify an element ID like "#canvas")
});
</pre></ul>
<p>
Expand Down Expand Up @@ -281,6 +284,15 @@ <h2 id="SENSOR">Acquiring Sensor Information</h2>
</p>


<h2 id="STORAGE">Data Storage</h2>
<p>
Basically, in hsp3dish.js, commands such as notesave and bsave are emulated in memory and will disappear when the browser is closed.<br>
As an extension in hsp3dish.js, it is also possible to persist data using IndexedDB.
By specifying the directory name to save in ENV.HSP_SYNC_DIR and calling <code>devcontrol "syncfs"</code>, you can save data under the specified directory to IndexedDB.
The saved data will remain even after closing the browser, so it will be restored the next time you start up.
</p>


<h2 id="NOTICE">Restrictions and Known Issues</h2>
<p>
The current version has the following restrictions.
Expand Down
129 changes: 62 additions & 67 deletions src/hsp3dish/emscripten/fontsystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#define USE_JAVA_FONT
#define FONT_TEX_SX 512
#define FONT_TEX_SY 128
#define FONT_PADDING 1
#endif

#if defined(HSPLINUX) || defined(HSPEMSCRIPTEN)
Expand Down Expand Up @@ -741,12 +742,14 @@ int hgio_fontsystem_exec(char* msg, unsigned char* buffer, int pitch, int* out_s

#if defined(HSPEMSCRIPTEN)
#ifndef USE_TTFFONT
#define HSPJS_DEFAULT_FONTNAME "sans-serif"
static int fontsystem_flag = 0;
static int fontsystem_sx; // 横のサイズ
static int fontsystem_sy; // 縦のサイズ
static unsigned char *fontdata_pix;
static int fontdata_size;
static int fontdata_color;
static std::string fontsystem_fontname = HSPJS_DEFAULT_FONTNAME;
static int fontsystem_size;
static int fontsystem_style;
static int fontsystem_texid;
Expand Down Expand Up @@ -775,6 +778,9 @@ void hgio_fontsystem_init(char* fontname, int size, int style)
// フォントレンダリング初期化
//
hgio_fontsystem_term();
if (fontname != NULL && *fontname != 0) {
fontsystem_fontname = fontname;
}
fontsystem_flag = 1;
fontsystem_size = size;
fontsystem_style = style;
Expand All @@ -786,56 +792,50 @@ int hgio_fontsystem_exec(char* msg, unsigned char* buffer, int pitch, int* out_s
// (bufferがNULLの場合はサイズだけを取得する)
//

EM_ASM_({
let canvas = document.getElementById('hsp3dishFontCanvas');
if (!canvas) {
canvas = document.createElement("canvas");
canvas.id = 'hsp3dishFontCanvas';
canvas.style.setProperty("visibility", "hidden");
canvas.style.setProperty("position", "absolute");
canvas.style.setProperty("top", "0");
canvas.style.setProperty("left", "0");
document.body.appendChild(canvas);
}
});

if (buffer == NULL) {
EM_ASM_({
let d = document.getElementById('hsp3dishFontDiv');
if (!d) {
d = document.createElement("div");
d.id = 'hsp3dishFontDiv';
d.style.setProperty("width", "auto");
d.style.setProperty("height", "auto");
d.style.setProperty("position", "absolute");
d.style.setProperty("visibility", "hidden");
d.style.setProperty("top", "0");
d.style.setProperty("left", "0");
document.body.appendChild(d);
}
d.style.setProperty("font", $1 + "px 'sans-serif'");

//const t = document.createTextNode(UTF8ToString($0));
//if (d.hasChildNodes())
// d.removeChild(d.firstChild);
//d.appendChild(t);
d.innerText = UTF8ToString($0);
HEAP32[$2 >> 2] = d.clientWidth | 0;
HEAP32[$3 >> 2] = d.clientHeight | 0;

let canvas = document.getElementById('hsp3dishFontCanvas');
if (!canvas) {
canvas = document.createElement("canvas");
canvas.id = 'hsp3dishFontCanvas';
canvas.style.setProperty("visibility", "hidden");
document.body.appendChild(canvas);
}

if ($4 != 0) {
const context = canvas.getContext("2d");
context.font = $1 + "px 'sans-serif'";

const msg = UTF8ToString($0);
const metrics = context.measureText(msg);
const canvas = document.getElementById('hsp3dishFontCanvas');
const context = canvas.getContext("2d", { willReadFrequently: true });
const msg = UTF8ToString($0);
const fontname = UTF8ToString($1);
const fontsize = $2;

let fontStyle = "";
if ($3 & 1) fontStyle += "bold ";
if ($3 & 2) fontStyle += "italic ";
const leading_scale = Number(ENV.HSP_FONT_LEADING) || 1.1;
fontStyle += Math.round($2 / leading_scale) + "px " + fontname;
context.font = fontStyle;
// console.log("measure char", fontStyle);

const metrics = context.measureText(msg);
HEAP32[$4 >> 2] = Math.ceil(Math.max(metrics.width, metrics.actualBoundingBoxRight) - Math.min(0, metrics.actualBoundingBoxLeft)) + 1;
HEAP32[$5 >> 2] = fontsize * 2;

if ($6 !== 0) {
//console.log({msg, metrics});
const arr = Array.from(msg);
for (let i = 0; i < msg.length; i++) {
const sub = arr.slice(0, i + 1).join("");
const m = context.measureText(sub);
//console.log({i, sub, m});
HEAP16[($4 >> 1) + i + 1] = m.width | 0; //(m.actualBoundingBoxRight - m.actualBoundingBoxLeft) | 0;
HEAP16[($6 >> 1) + i + 1] = m.width | 0; //(m.actualBoundingBoxRight - m.actualBoundingBoxLeft) | 0;
}
}
}, msg, fontsystem_size, & fontsystem_sx, & fontsystem_sy, info ? info->pos : nullptr);

//Alertf("text %s %d %d\n", msg, fontsystem_sx, fontsystem_sy);
}, msg, fontsystem_fontname.c_str(), fontsystem_size, fontsystem_style, &fontsystem_sx, &fontsystem_sy, info ? info->pos : nullptr);

*out_sx = fontsystem_sx;
*out_sy = fontsystem_sy;
Expand All @@ -847,38 +847,33 @@ int hgio_fontsystem_exec(char* msg, unsigned char* buffer, int pitch, int* out_s
int sy = Get2N(fontsystem_sy);

EM_ASM_({
var canvas = document.getElementById('hsp3dishFontCanvas');
if (!canvas) {
//document.body.removeChild(canvas);
canvas = document.createElement("canvas");
canvas.id = 'hsp3dishFontCanvas';
canvas.style.setProperty("visibility", "hidden");
canvas.style.setProperty("position", "absolute");
canvas.style.setProperty("top", "0");
canvas.style.setProperty("left", "0");
canvas.width = $2;
canvas.height = $3;
document.body.appendChild(canvas);
}
if (canvas.width < $2)
canvas.width = $2;
if (canvas.height < $3)
canvas.height = $3;

var context = canvas.getContext("2d", { willReadFrequently: true });
context.font = $1 + "px 'sans-serif'";

var msg = UTF8ToString($0);
context.clearRect(0, 0, Math.min(canvas.width, $2 + 1), Math.min(canvas.height, $3 + 1));
const canvas = document.getElementById('hsp3dishFontCanvas');
if (canvas.width < $4)
canvas.width = $4;
if (canvas.height < $5)
canvas.height = $5;
const context = canvas.getContext("2d", { willReadFrequently: true });
const msg = UTF8ToString($0);
const fontname = UTF8ToString($1);
const fontsize = $2;

let fontStyle = "";
if ($3 & 1) fontStyle += "bold ";
if ($3 & 2) fontStyle += "italic ";
const leading_scale = Number(ENV.HSP_FONT_LEADING) || 1.1;
fontStyle += Math.round($2 / leading_scale) + "px " + fontname;
context.font = fontStyle;

context.clearRect(0, 0, Math.min(canvas.width, $4 + 1), Math.min(canvas.height, $5 + 1));
context.fillStyle = 'rgba(255, 255, 255, 255)';
context.fillText(msg, 0, $1);
context.fillText(msg, 0, Math.floor(fontsize * 1.5));
//console.log(msg);

//GLctx.texImage2D(GLctx.TEXTURE_2D, 0, GLctx.RGBA, GLctx.RGBA, GLctx.UNSIGNED_BYTE, context.getImageData(0, 0, $2, $3));
var imageData = context.getImageData(0, 0, $2, $3);
HEAPU8.set(imageData.data, $4);
var imageData = context.getImageData(0, 0, $4, $5);
HEAPU8.set(imageData.data, $6);

}, msg, fontsystem_size, sx, sy, buffer);
}, msg, fontsystem_fontname.c_str(), fontsystem_size, fontsystem_style, sx, sy, buffer);

//Alertf( "Init:Surface(%d,%d) %d destpitch%d",fontsystem_sx,fontsystem_sy,fontdata_color,pitch );
*out_sx = fontsystem_sx;
Expand Down
15 changes: 15 additions & 0 deletions src/hsp3dish/emscripten/hgiox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
#ifdef HSPWIN
#define STRICT
#include <windows.h>
#define FONT_PADDING 0
#endif

#ifdef HSPNDK
#define USE_JAVA_FONT
#define FONT_TEX_SX 512
#define FONT_TEX_SY 128
#define FONT_PADDING 0
#include "../../appengine.h"
#include "../../javafunc.h"
#include "font_data.h"
Expand All @@ -37,6 +39,7 @@
#include <CoreFoundation/CoreFoundation.h>
#include "iOSBridge.h"
#include "hsp3dish/ios/appengine.h"
#define FONT_PADDING 0
#endif


Expand All @@ -46,6 +49,7 @@
#define USE_JAVA_FONT
#define FONT_TEX_SX 512
#define FONT_TEX_SY 128
#define FONT_PADDING 0
//#include "font_data.h"
#endif

Expand All @@ -58,6 +62,7 @@
#define USE_JAVA_FONT
#define FONT_TEX_SX 512
#define FONT_TEX_SY 128
#define FONT_PADDING 1
#endif

#if defined(HSPLINUX) || defined(HSPEMSCRIPTEN)
Expand Down Expand Up @@ -2021,6 +2026,8 @@ int hgio_mes(BMSCR* bm, char* msg)
return 0;
}

int fontsize = tmes._fontsize;

int id;
texmes* tex;
id = tmes.texmesRegist(msg);
Expand All @@ -2046,11 +2053,19 @@ int hgio_mes(BMSCR* bm, char* msg)
bm->printoffsety = 0;
}

#if FONT_PADDING == 0
hgio_fontcopy(bm, bm->cx, bm->cy, tex->ratex, tex->ratey, xsize, ysize, tex->_texture, 0, 0);

if (xsize > bm->printsizex) bm->printsizex = xsize;
bm->printsizey += ysize;
bm->cy += ysize;
#else
hgio_fontcopy(bm, bm->cx, bm->cy - fontsize / 2, tex->ratex, tex->ratey, xsize, ysize, tex->_texture, 0, 0);

if (xsize > bm->printsizex) bm->printsizex = xsize;
bm->printsizey += fontsize;
bm->cy += fontsize;
#endif
return 0;
}

Expand Down
4 changes: 3 additions & 1 deletion src/hsp3dish/texmes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ void texmes::reset(int width, int height, int p_texsx, int p_texsy, void* data)
life = TEXMES_CACHE_DEFAULT;
font_size = 0;
font_style = 0;
fontname = "";
if (text != NULL) text[0] = 0;
buf[0] = 0;
texmespos = NULL;
Expand Down Expand Up @@ -246,7 +247,7 @@ int texmesManager::texmesGetCache(char* msg, short mycache, texmesPos* info)
for (i = 0; i < _maxtexmes; i++) {
if (t->flag) { // 使用中だった時
if (t->hash == mycache) { // まずハッシュを比べる
if (t->font_size == _fontsize && t->font_style == _fontstyle) { // サイズ・スタイルを比べる
if (t->font_size == _fontsize && t->font_style == _fontstyle && t->fontname == _fontname) { // サイズ・スタイル・フォントを比べる
bool found = true;
if (info) {
if (info != t->texmespos) { // 異なるtexmesPosはキャッシュしない
Expand Down Expand Up @@ -372,6 +373,7 @@ int texmesManager::texmesRegist(char* msg, texmesPos *info)
tex->hash = mycache;
tex->font_size = _fontsize;
tex->font_style = _fontstyle;
tex->fontname = _fontname;
tex->texmespos = info;

return tex->entry;
Expand Down
1 change: 1 addition & 0 deletions src/hsp3dish/texmes.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class texmes {
int hash; // Text Hashcode
int life; // Text Cache life
char* text; // Long Text Message
std::string fontname; // Fontname
int textsize; // Long Text Message size
int font_size; // Text font size
int font_style; // Text font style
Expand Down