@next2d/builder 0.1.7 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/cli.d.ts +59 -0
  2. package/dist/cli.js +141 -0
  3. package/dist/constants.d.ts +53 -0
  4. package/dist/constants.js +64 -0
  5. package/dist/context.d.ts +29 -0
  6. package/dist/context.js +19 -0
  7. package/dist/electron.d.ts +10 -0
  8. package/dist/electron.js +142 -0
  9. package/dist/index.js +18 -754
  10. package/dist/native.d.ts +27 -0
  11. package/dist/native.js +123 -0
  12. package/dist/utils.d.ts +27 -0
  13. package/dist/utils.js +40 -0
  14. package/dist/web.d.ts +18 -0
  15. package/dist/web.js +70 -0
  16. package/dist/xbox.d.ts +62 -0
  17. package/dist/xbox.js +426 -0
  18. package/package.json +12 -9
  19. package/templates/xbox/CMakeLists.txt +116 -11
  20. package/templates/xbox/README.md +34 -8
  21. package/templates/xbox/cmake/FetchDawn.cmake +47 -6
  22. package/templates/xbox/cmake/FindV8.cmake +15 -0
  23. package/templates/xbox/js/bootstrap.js +151 -28
  24. package/templates/xbox/js/selftest.js +740 -90
  25. package/templates/xbox/src/AssetLoader.cpp +115 -12
  26. package/templates/xbox/src/AssetLoader.h +4 -0
  27. package/templates/xbox/src/EmbeddedAssets.cpp +149 -0
  28. package/templates/xbox/src/EmbeddedAssets.h +60 -0
  29. package/templates/xbox/src/EventLoop.cpp +13 -1
  30. package/templates/xbox/src/EventLoop.h +12 -0
  31. package/templates/xbox/src/bindings/Audio.cpp +211 -31
  32. package/templates/xbox/src/bindings/Bindings.h +10 -0
  33. package/templates/xbox/src/bindings/Canvas.cpp +77 -2
  34. package/templates/xbox/src/bindings/Canvas2D.cpp +496 -43
  35. package/templates/xbox/src/bindings/Console.cpp +6 -1
  36. package/templates/xbox/src/bindings/DomShims.cpp +143 -0
  37. package/templates/xbox/src/bindings/EventTarget.cpp +11 -0
  38. package/templates/xbox/src/bindings/Fetch.cpp +2 -8
  39. package/templates/xbox/src/bindings/Image.cpp +243 -15
  40. package/templates/xbox/src/bindings/Polyfills.cpp +1226 -0
  41. package/templates/xbox/src/bindings/RasterCore.h +105 -1
  42. package/templates/xbox/src/bindings/Video.cpp +153 -10
  43. package/templates/xbox/src/bindings/webgpu/WebGPU.cpp +844 -18
  44. package/templates/xbox/src/bindings/webgpu/WebGPUCommon.h +7 -9
  45. package/templates/xbox/src/bindings/webgpu/WebGPUEnums.h +32 -0
  46. package/templates/xbox/src/gpu/DawnContext.cpp +245 -7
  47. package/templates/xbox/src/gpu/DawnContext.h +18 -0
  48. package/templates/xbox/src/main.cpp +459 -8
  49. package/templates/xbox/src/platform/AudioDecoder.cpp +121 -0
  50. package/templates/xbox/src/platform/AudioDecoder.h +18 -0
  51. package/templates/xbox/src/platform/AudioEngine.cpp +37 -6
  52. package/templates/xbox/src/platform/DecodeQueue.cpp +136 -0
  53. package/templates/xbox/src/platform/DecodeQueue.h +27 -0
  54. package/templates/xbox/src/platform/ImageDecoder.cpp +44 -0
  55. package/templates/xbox/src/platform/ImageDecoder.h +18 -0
  56. package/templates/xbox/src/platform/StbTextRasterizer.cpp +324 -0
  57. package/templates/xbox/src/platform/StbTextRasterizer.h +37 -0
  58. package/templates/xbox/src/platform/TextRasterizer.cpp +32 -0
  59. package/templates/xbox/src/platform/WicDecoder.cpp +19 -0
  60. package/templates/xbox/src/v8/CodeCache.h +223 -0
  61. package/templates/xbox/src/v8/V8Runtime.cpp +76 -11
  62. package/templates/xbox/src/v8/V8Util.h +79 -0
  63. package/templates/xbox/src/v8/WeakHandle.h +45 -0
  64. package/templates/xbox/src/worker/WorkerRuntime.cpp +432 -48
  65. package/templates/xbox/src/worker/WorkerRuntime.h +43 -13
  66. package/templates/xbox/tests/check_local.sh +7 -2
  67. package/templates/xbox/tests/gamecore_api_probe.cpp +172 -0
  68. package/templates/xbox/tests/raster_test.cpp +50 -0
  69. package/templates/xbox/tests/windows_platform_test.cpp +75 -3
  70. package/templates/xbox/third_party/LICENSES.md +14 -0
  71. package/templates/xbox/third_party/dr_mp3.h +5412 -0
  72. package/templates/xbox/third_party/dr_wav.h +9131 -0
  73. package/templates/xbox/third_party/stb_image.h +7988 -0
  74. package/templates/xbox/third_party/stb_truetype.h +5079 -0
  75. package/templates/xbox/third_party/stb_vorbis.c +5584 -0
@@ -15,6 +15,7 @@
15
15
 
16
16
  #include <cstdint>
17
17
  #include <deque>
18
+ #include <map>
18
19
  #include <memory>
19
20
  #include <string>
20
21
  #include <vector>
@@ -25,22 +26,30 @@ class HostContext;
25
26
  class EventLoop;
26
27
  class WorkerRuntime;
27
28
 
28
- // 1 メッセージ = ValueSerializer 出力バイト列。
29
+ // worker context の embedder slot。1 は EventLoop (kEventLoopEmbedderSlot) が使用。
30
+ // ESM の ResolveModule コールバックが context から WorkerInstance を引くために使う。
31
+ constexpr int kWorkerInstanceEmbedderSlot = 2;
32
+
33
+ // 1 メッセージ = ValueSerializer 出力バイト列 + transfer された ArrayBuffer の実体。
34
+ // transfer_list の ArrayBuffer は中身を bytes に埋め込まず所有権ごと移す
35
+ // (render キューは数十 MB になるため、コピーするとフレームレートが崩壊する)。
29
36
  struct WorkerMessage {
30
37
  std::vector<uint8_t> data;
38
+ std::vector<std::shared_ptr<v8::BackingStore>> transfers;
31
39
  };
32
40
 
33
41
  class WorkerInstance {
34
42
  public:
35
- WorkerInstance(WorkerRuntime* runtime, v8::Isolate* isolate, std::string url);
43
+ WorkerInstance(WorkerRuntime* runtime, v8::Isolate* isolate, std::string url,
44
+ bool is_module = false);
36
45
  ~WorkerInstance();
37
46
 
38
47
  bool Start(); // Context 生成 + ワーカースクリプト評価
39
48
  void Terminate();
40
49
 
41
50
  // main→worker / worker→main の投函
42
- void PostToWorker(std::vector<uint8_t> bytes);
43
- void PostToMain(std::vector<uint8_t> bytes);
51
+ void PostToWorker(WorkerMessage message);
52
+ void PostToMain(WorkerMessage message);
44
53
 
45
54
  // 配送 + タイマー/rAF 前進 (WorkerRuntime::Pump から呼ぶ)
46
55
  void Deliver(double now_ms);
@@ -59,14 +68,28 @@ private:
59
68
  void DeliverToWorker(double now_ms);
60
69
  void DeliverToMain();
61
70
 
71
+ // ESM worker (type: "module")。分類スクリプトは Script、モジュールは Module として評価。
72
+ bool EvaluateModule(v8::Local<v8::Context> context, const std::string& source);
73
+ v8::MaybeLocal<v8::Module> LoadModule(const std::string& url);
74
+ static v8::MaybeLocal<v8::Module> ResolveModule(
75
+ v8::Local<v8::Context> context,
76
+ v8::Local<v8::String> specifier,
77
+ v8::Local<v8::FixedArray> import_attributes,
78
+ v8::Local<v8::Module> referrer);
79
+
62
80
  WorkerRuntime* runtime_;
63
81
  v8::Isolate* isolate_;
64
82
  std::string url_;
83
+ bool module_ = false;
65
84
  v8::Global<v8::Context> context_;
66
85
  std::unique_ptr<EventLoop> loop_;
67
86
  std::deque<WorkerMessage> to_worker_;
68
87
  std::deque<WorkerMessage> to_main_;
69
88
  bool terminated_ = false;
89
+
90
+ // ESM 解決: url -> Module、Module identity hash -> url (referrer 特定用)。
91
+ std::map<std::string, v8::Global<v8::Module>> modules_;
92
+ std::map<int, std::string> module_paths_;
70
93
  };
71
94
 
72
95
  class WorkerRuntime {
@@ -80,29 +103,36 @@ public:
80
103
  // main / worker グローバルに Worker コンストラクタ等を設置する。
81
104
  void InstallOnGlobal(v8::Local<v8::Object> global);
82
105
 
83
- // new Worker(url) の実体
84
- v8::Local<v8::Object> CreateWorker(const std::string& url);
106
+ // new Worker(url, { type }) の実体
107
+ v8::Local<v8::Object> CreateWorker(const std::string& url, bool is_module = false);
85
108
 
86
109
  // 全 worker のメッセージ配送とイベントループ前進
87
110
  void Pump(double now_ms);
88
111
 
89
112
  bool HasWorkers() const { return !workers_.empty(); }
90
113
 
114
+ // 全 WorkerInstance を破棄する。WorkerInstance は v8::Global (context_ /
115
+ // main_worker_object 等) を保持するため、Isolate::Dispose より前に必ず呼ぶこと
116
+ // (呼ばずにスタック巻き戻しで破棄されると Isolate 破棄後の Global::Reset で fail-fast)。
117
+ void Shutdown() { workers_.clear(); }
118
+
91
119
  private:
92
120
  v8::Isolate* isolate_;
93
121
  HostContext* host_;
94
122
  std::vector<std::unique_ptr<WorkerInstance>> workers_;
95
123
  };
96
124
 
97
- // ValueSerializer/Deserializer による structured clone (OffscreenCanvas transfer 対応)。
98
- // 失敗時は空を返す。source_ctx で直列化し、bytes を得る。
99
- std::vector<uint8_t> SerializeMessage(v8::Isolate* isolate, v8::Local<v8::Context> source_ctx,
100
- v8::Local<v8::Value> message,
101
- v8::Local<v8::Value> transfer_list);
125
+ // ValueSerializer/Deserializer による structured clone
126
+ // (OffscreenCanvas / ImageBitmap のホストオブジェクト対応 + ArrayBuffer transfer)。
127
+ // 失敗時は data が空の WorkerMessage を返す。transfer_list 内の ArrayBuffer は
128
+ // detach され、backing store が message.transfers へ移る。
129
+ WorkerMessage SerializeMessage(v8::Isolate* isolate, v8::Local<v8::Context> source_ctx,
130
+ v8::Local<v8::Value> message,
131
+ v8::Local<v8::Value> transfer_list);
102
132
 
103
- // bytes を target_ctx で復元する。
133
+ // message を target_ctx で復元する (transfer された ArrayBuffer は同一実体を再装着)。
104
134
  v8::MaybeLocal<v8::Value> DeserializeMessage(v8::Isolate* isolate,
105
135
  v8::Local<v8::Context> target_ctx,
106
- const std::vector<uint8_t>& bytes);
136
+ const WorkerMessage& message);
107
137
 
108
138
  } // namespace next2d
@@ -10,7 +10,7 @@
10
10
  set -euo pipefail
11
11
  cd "$(dirname "$0")/.."
12
12
 
13
- V8_TAG="13.6.233.17"
13
+ V8_TAG="13.7.152.19"
14
14
  V8INC="${1:-}"
15
15
 
16
16
  echo "== 1/3 RasterCore unit tests =="
@@ -41,14 +41,19 @@ FILES=(
41
41
  src/bindings/Console.cpp
42
42
  src/bindings/Timers.cpp
43
43
  src/bindings/EventTarget.cpp
44
+ src/bindings/Polyfills.cpp
44
45
  src/bindings/Network.cpp
45
46
  src/bindings/Fetch.cpp
46
47
  src/bindings/Canvas.cpp
47
48
  src/bindings/Audio.cpp
48
49
  src/bindings/Gamepad.cpp
50
+ src/platform/DecodeQueue.cpp
51
+ src/platform/AudioDecoder.cpp
52
+ src/platform/ImageDecoder.cpp
53
+ src/platform/StbTextRasterizer.cpp
49
54
  )
50
55
  for f in "${FILES[@]}"; do
51
- c++ -fsyntax-only -std=c++20 -Isrc -isystem "${V8INC}" \
56
+ c++ -fsyntax-only -std=c++20 -Isrc -I. -isystem "${V8INC}" \
52
57
  -DV8_COMPRESS_POINTERS "$f"
53
58
  echo "OK $f"
54
59
  done
@@ -0,0 +1,172 @@
1
+ // Game Core (Xbox コンソール) API パーティション監査プローブ。
2
+ //
3
+ // Windows SDK (19041+) は各 API 宣言を WINAPI_PARTITION_* でガードしており、
4
+ // `cl /DWINAPI_FAMILY=WINAPI_FAMILY_GAMES` でコンパイルすると GAMES パーティションに
5
+ // 属さない API は「未宣言」エラーになる。= NDA 資料なしで、公開 SDK だけを使って
6
+ // 「コンソールで使えない API」を正確に列挙できる (プリプロセッサが公式のゲート
7
+ // ロジックそのものを評価するため、テキスト解析より確実)。
8
+ //
9
+ // 使い方 (xbox-host-ci の gamecore-api-audit ジョブが実行):
10
+ // cl /c /DWINAPI_FAMILY=WINAPI_FAMILY_GAMES tests\gamecore_api_probe.cpp
11
+ // -> ホストがコンソールで使う API の存在検証 (エラー = 直ちに修正が必要)
12
+ // cl /c /DWINAPI_FAMILY=WINAPI_FAMILY_GAMES /DPROBE_V8 tests\gamecore_api_probe.cpp
13
+ // -> V8 の platform 層 (src/base/platform/*-win32) が使う API の存在検証
14
+ // (エラー = V8 Game Core 移植時に置換が必要な TODO リスト。情報提供扱い)
15
+ //
16
+ // 注意: これは「宣言がパーティションに含まれるか」の静的検査。実機での挙動
17
+ // (リンク先 lib の有無・実行時の権限) は devkit での検証が別途必要。
18
+ //
19
+ // WIN32_LEAN_AND_MEAN は必須: GAMES ファミリではフル Windows.h が引き込む
20
+ // 周辺ヘッダ (mmsystem/ole2/winsock 等) に GAMES 非対応部分があり
21
+ // コンパイルが壊れる (vcpkg の Xbox トリプレットも同様の前提)。
22
+ // 必要なヘッダは個別に include する。
23
+ #define WIN32_LEAN_AND_MEAN
24
+ #define NOMINMAX
25
+ #include <Windows.h>
26
+
27
+ #include <objbase.h> // CoInitializeEx (DecodeQueue のスレッド COM 初期化)
28
+ #include <bcrypt.h> // BCryptGenRandom (crypto.getRandomValues)
29
+ #include <xaudio2.h> // XAudio2Create (音声出力)
30
+
31
+ #ifdef PROBE_V8
32
+ #include <timeapi.h> // timeGetTime (V8 time.cc — GAMES 外の想定 = TODO 検出対象)
33
+ #include <psapi.h> // GetProcessMemoryInfo (V8 OS::GetPeakMemoryUsageKb)
34
+ #include <process.h> // _beginthreadex (V8 Thread)
35
+ #endif
36
+
37
+ // 関数アドレスを取るだけの配列。宣言が無ければコンパイルエラーになる。
38
+ #define PROBE(fn) reinterpret_cast<void*>(&fn)
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // ホストがコンソールビルドでも使う API (NEXT2D_XBOX_CONSOLE ガード外のもの)。
42
+ // ここのエラーはホスト側の修正が必要 (ジョブを fail させる)。
43
+ // ---------------------------------------------------------------------------
44
+ void* const g_host_apis[] = {
45
+ // ウィンドウ / メッセージループ (main.cpp。GDK コンソールサンプルも同構成)
46
+ PROBE(RegisterClassExW),
47
+ PROBE(CreateWindowExW),
48
+ PROBE(DefWindowProcW),
49
+ PROBE(PeekMessageW),
50
+ PROBE(TranslateMessage),
51
+ PROBE(DispatchMessageW),
52
+ PROBE(PostQuitMessage),
53
+ PROBE(LoadCursorW),
54
+ PROBE(GetClientRect),
55
+
56
+ // 時刻 / ペーシング (EventLoop::Now, メインループ)
57
+ PROBE(QueryPerformanceCounter),
58
+ PROBE(QueryPerformanceFrequency),
59
+ PROBE(Sleep),
60
+
61
+ // モジュール / 環境 (ExeDir, DomShims の storage パス解決)
62
+ PROBE(GetModuleFileNameW),
63
+ PROBE(GetModuleHandleW),
64
+ PROBE(GetEnvironmentVariableW),
65
+ PROBE(GetLastError),
66
+
67
+ // COM (DecodeQueue プールスレッド。コンソールでは WIC/MF は使わないが
68
+ // CoInitializeEx 自体は呼ぶ)
69
+ PROBE(CoInitializeEx),
70
+ PROBE(CoUninitialize),
71
+
72
+ // 乱数 (crypto.getRandomValues)
73
+ PROBE(BCryptGenRandom),
74
+
75
+ // 音声 (XAudio2 はコンソールでは xaudio2_9)
76
+ PROBE(XAudio2Create),
77
+
78
+ // リソース (EmbeddedAssets の RCDATA 読み込み)
79
+ PROBE(FindResourceW),
80
+ PROBE(LoadResource),
81
+ PROBE(LockResource),
82
+ PROBE(SizeofResource),
83
+ };
84
+
85
+ #ifdef PROBE_V8
86
+ // ---------------------------------------------------------------------------
87
+ // V8 13.7 の platform 層 (src/base/platform/{platform-win32,time,mutex,
88
+ // condition-variable,semaphore}.cc) から機械抽出した Win32 API。
89
+ // ここのエラー = V8 Game Core 移植時の置換 TODO (情報提供、ジョブは fail しない)。
90
+ // ---------------------------------------------------------------------------
91
+ void* const g_v8_apis[] = {
92
+ // 仮想メモリ (焦点: コンソールでは XMemVirtualAlloc への置換が推奨とされる)
93
+ PROBE(VirtualAlloc),
94
+ PROBE(VirtualFree),
95
+ PROBE(VirtualProtect),
96
+ PROBE(VirtualQuery),
97
+ PROBE(DiscardVirtualMemory),
98
+ // VirtualAlloc2 / MapViewOfFile3 / UnmapViewOfFile2 は V8 が GetProcAddress で
99
+ // 動的解決するが、宣言の有無がパーティション対応の指標になるため含める
100
+ PROBE(VirtualAlloc2),
101
+ PROBE(MapViewOfFile3),
102
+ PROBE(UnmapViewOfFile2),
103
+
104
+ // ファイルマッピング (OS::MemoryMappedFile)
105
+ PROBE(CreateFileMappingW),
106
+ PROBE(CreateFileW),
107
+ PROBE(MapViewOfFile),
108
+ PROBE(MapViewOfFileEx),
109
+ PROBE(UnmapViewOfFile),
110
+ PROBE(GetFileSize),
111
+ PROBE(GetFileType),
112
+ PROBE(DeleteFileA),
113
+ PROBE(GetTempPathA),
114
+ PROBE(GetTempFileNameA),
115
+
116
+ // スレッド / TLS / 同期
117
+ PROBE(GetCurrentThread),
118
+ PROBE(GetCurrentThreadId),
119
+ PROBE(SetThreadPriority),
120
+ PROBE(TlsAlloc),
121
+ PROBE(TlsFree),
122
+ PROBE(TlsGetValue),
123
+ PROBE(TlsSetValue),
124
+ PROBE(CreateSemaphoreA),
125
+ PROBE(ReleaseSemaphore),
126
+ PROBE(WaitForSingleObject),
127
+ PROBE(CloseHandle),
128
+ PROBE(CreateWaitableTimerExW),
129
+ PROBE(SetWaitableTimer),
130
+
131
+ // 時刻 (焦点: timeGetTime は winmm — デスクトップ専用の可能性が高い)
132
+ PROBE(timeGetTime),
133
+ PROBE(GetSystemTime),
134
+ PROBE(GetSystemTimeAsFileTime),
135
+ PROBE(SystemTimeToFileTime),
136
+ PROBE(GetThreadTimes),
137
+ PROBE(GetTimeZoneInformation),
138
+
139
+ // プロセス / システム情報
140
+ PROBE(GetCurrentProcess),
141
+ PROBE(GetCurrentProcessId),
142
+ PROBE(GetSystemInfo),
143
+ PROBE(ExitProcess),
144
+ PROBE(TerminateProcess),
145
+ PROBE(GetProcessMemoryInfo),
146
+ PROBE(SetErrorMode),
147
+ PROBE(GetStdHandle),
148
+
149
+ // 文字列変換 / デバッグ / モジュール
150
+ PROBE(MultiByteToWideChar),
151
+ PROBE(WideCharToMultiByte),
152
+ PROBE(OutputDebugStringA),
153
+ PROBE(DebugBreak),
154
+ PROBE(IsDebuggerPresent),
155
+ PROBE(LoadLibraryW),
156
+ PROBE(GetProcAddress),
157
+ PROBE(VerifyVersionInfoW), // IsWindows10OrGreater (versionhelpers) の実体
158
+
159
+ // CRT (参考: パーティション対象外のはずだが確認)
160
+ reinterpret_cast<void*>(&_beginthreadex),
161
+ };
162
+ #endif // PROBE_V8
163
+
164
+ // リンク不要 (cl /c のみ)。配列が最適化で消えないよう参照を残す。
165
+ void* GameCoreApiProbeAnchor()
166
+ {
167
+ void* acc = const_cast<void**>(g_host_apis)[0];
168
+ #ifdef PROBE_V8
169
+ acc = const_cast<void**>(g_v8_apis)[0];
170
+ #endif
171
+ return acc;
172
+ }
@@ -257,6 +257,55 @@ static void TestTransformedFill()
257
257
  CHECK(Px(s, 33, 25).a == 0);
258
258
  }
259
259
 
260
+ // 任意形状クリップ (ピクセルマスク)。矩形は外接矩形、非矩形はマスクで厳密クリップ。
261
+ static void TestClipMask()
262
+ {
263
+ // 矩形パスは mask を作らない (IsAxisAlignedRect が true)。
264
+ std::vector<SubPath> rect = { MakeRectPath(2, 2, 5, 5) };
265
+ CHECK(IsAxisAlignedRect(rect));
266
+
267
+ // 左上三角 (0,0),(10,0),(0,10) — 内側は x+y<10。
268
+ std::vector<SubPath> tri(1);
269
+ tri[0].pts = { {0,0}, {10,0}, {0,10} };
270
+ tri[0].closed = true;
271
+ CHECK(!IsAxisAlignedRect(tri));
272
+
273
+ ClipRect clip;
274
+ IntersectClipMask(clip, tri, 10, 10);
275
+ CHECK(clip.mask != nullptr);
276
+ CHECK(clip.mask_w == 10 && clip.mask_h == 10);
277
+
278
+ // 全面塗りが三角形にクリップされる。
279
+ Surface s(10, 10);
280
+ std::vector<SubPath> full = { MakeRectPath(0, 0, 10, 10) };
281
+ FillPath(s, clip, full, {255, 0, 0, 255}, 1.0);
282
+ CHECK(Px(s, 1, 1).r == 255); // 深く内側
283
+ CHECK(Px(s, 1, 2).r == 255);
284
+ CHECK(Px(s, 9, 9).a == 0); // 深く外側 (x+y=18)
285
+ CHECK(Px(s, 8, 8).a == 0); // 外側 (x+y=16)
286
+
287
+ // Blend も直接マスクに従う。
288
+ Surface s2(10, 10);
289
+ Blend(s2, clip, 1, 1, {0, 255, 0, 255}, 1.0); // 内側 → 描かれる
290
+ Blend(s2, clip, 9, 9, {0, 255, 0, 255}, 1.0); // 外側 → 描かれない
291
+ CHECK(Px(s2, 1, 1).g == 255);
292
+ CHECK(Px(s2, 9, 9).a == 0);
293
+
294
+ // マスク同士の積集合: 左上三角 ∩ 右下三角 は (1,1) を除外する。
295
+ ClipRect clip2;
296
+ IntersectClipMask(clip2, tri, 10, 10);
297
+ std::vector<SubPath> tri2(1);
298
+ tri2[0].pts = { {10,0}, {10,10}, {0,10} }; // 右下三角 (内側 x+y>10)
299
+ tri2[0].closed = true;
300
+ IntersectClipMask(clip2, tri2, 10, 10);
301
+ Surface s3(10, 10);
302
+ FillPath(s3, clip2, full, {0, 0, 255, 255}, 1.0);
303
+ CHECK(Px(s3, 1, 1).a == 0); // 左上三角内だが右下三角外 → 積集合で除外
304
+
305
+ // 非矩形クリップでも外接矩形 (高速リジェクト) は反映される。
306
+ CHECK(clip.active);
307
+ }
308
+
260
309
  int main()
261
310
  {
262
311
  TestParseColor();
@@ -272,6 +321,7 @@ int main()
272
321
  TestFlattenCurves();
273
322
  TestPathBounds();
274
323
  TestTransformedFill();
324
+ TestClipMask();
275
325
 
276
326
  std::printf("%s: %d checks, %d failures\n",
277
327
  failures ? "FAILED" : "ok", checks, failures);
@@ -3,9 +3,10 @@
3
3
  // windows-latest ランナーで実行して「Windows 上で実際に動く」ことを検証する。
4
4
  //
5
5
  // ビルド (Developer Command Prompt / CI):
6
- // cl /std:c++17 /EHsc /Isrc tests\windows_platform_test.cpp ^
6
+ // cl /std:c++17 /EHsc /Isrc /I. tests\windows_platform_test.cpp ^
7
7
  // src\platform\WicDecoder.cpp src\platform\TextRasterizer.cpp ^
8
8
  // src\platform\AudioEngine.cpp ^
9
+ // src\platform\ImageDecoder.cpp src\platform\AudioDecoder.cpp ^
9
10
  // ole32.lib windowscodecs.lib d2d1.lib dwrite.lib ^
10
11
  // mfplat.lib mfreadwrite.lib mfuuid.lib xaudio2.lib shlwapi.lib
11
12
  //
@@ -16,9 +17,14 @@
16
17
  #endif
17
18
 
18
19
  #include "../src/platform/WicDecoder.h"
20
+ #include "../src/platform/ImageDecoder.h"
21
+ #include "../src/platform/AudioDecoder.h"
19
22
  #include "../src/platform/TextRasterizer.h"
23
+ #include "../src/platform/StbTextRasterizer.h"
20
24
  #include "../src/platform/AudioEngine.h"
21
25
 
26
+ #include <fstream>
27
+
22
28
  #include <Windows.h>
23
29
  #include <mfapi.h>
24
30
 
@@ -89,6 +95,24 @@ static void TestWicDecode()
89
95
  CHECK(!next2d::DecodeImageWithWIC(garbage, bad));
90
96
  }
91
97
 
98
+ // --- ImageDecoder: 本番の第一経路 (stb_image。コンソールでも同一コード) --------
99
+ static void TestImageDecoder()
100
+ {
101
+ std::vector<uint8_t> png(kTestPng, kTestPng + sizeof(kTestPng));
102
+ next2d::DecodedImage img;
103
+ CHECK(next2d::DecodeImage(png, img));
104
+ CHECK(img.width == 2 && img.height == 2);
105
+ CHECK(img.rgba.size() == 16);
106
+ CHECK(img.rgba[0] == 255 && img.rgba[1] == 0 && img.rgba[2] == 0 && img.rgba[3] == 255);
107
+ CHECK(img.rgba[4] == 0 && img.rgba[5] == 255 && img.rgba[6] == 0);
108
+ CHECK(img.rgba[8] == 0 && img.rgba[9] == 0 && img.rgba[10] == 255);
109
+ CHECK(img.rgba[15] == 128);
110
+
111
+ std::vector<uint8_t> garbage(32, 0xAB);
112
+ next2d::DecodedImage bad;
113
+ CHECK(!next2d::DecodeImage(garbage, bad));
114
+ }
115
+
92
116
  // --- DirectWrite: メトリクスとグリフラスタライズ (fillText の実体) ----------
93
117
  static void TestTextRasterizer()
94
118
  {
@@ -131,7 +155,43 @@ static void TestTextRasterizer()
131
155
  CHECK(!next2d::RasterizeTextWithDWrite("24px Segoe UI", L"", 0, 0, 0, empty));
132
156
  }
133
157
 
134
- // --- Media Foundation: 音声デコード (decodeAudioData の実体) -----------------
158
+ // --- stb_truetype: コンソールのテキスト経路 (TextRasterizer の #else 分岐実体) --
159
+ // コンソールでは DirectWrite が無く StbTextRasterizer が fillText/measureText を
160
+ // 担う。Windows の実フォント (arial.ttf) で同一コードを検証する。
161
+ static void TestStbText()
162
+ {
163
+ // フォント未登録では false
164
+ next2d::TextMetricsInfo none;
165
+ CHECK(!next2d::stbtext::MeasureText("24px Arial", L"Hi", none));
166
+
167
+ wchar_t windir[MAX_PATH] = {};
168
+ GetEnvironmentVariableW(L"WINDIR", windir, MAX_PATH);
169
+ std::wstring font_path = std::wstring(windir) + L"\\Fonts\\arial.ttf";
170
+ std::ifstream ifs(font_path.c_str(), std::ios::binary);
171
+ std::vector<uint8_t> font((std::istreambuf_iterator<char>(ifs)),
172
+ std::istreambuf_iterator<char>());
173
+ CHECK(!font.empty());
174
+ CHECK(next2d::stbtext::RegisterFont("Arial", std::move(font)));
175
+
176
+ next2d::TextMetricsInfo m;
177
+ CHECK(next2d::stbtext::MeasureText("24px Arial", L"Hello", m));
178
+ CHECK(m.width > 10.0 && m.width < 200.0);
179
+ CHECK(m.ascent > 5.0 && m.ascent < 40.0);
180
+
181
+ next2d::TextBitmap bmp;
182
+ CHECK(next2d::stbtext::RasterizeText("24px Arial", L"A", 255, 0, 0, bmp));
183
+ CHECK(bmp.width > 0 && bmp.height > 0 && bmp.baseline > 0);
184
+ int opaque = 0;
185
+ for (size_t i = 3; i < bmp.rgba.size(); i += 4) if (bmp.rgba[i] > 200) ++opaque;
186
+ CHECK(opaque > 5);
187
+
188
+ next2d::TextBitmap empty;
189
+ CHECK(!next2d::stbtext::RasterizeText("24px Arial", L"", 0, 0, 0, empty));
190
+ }
191
+
192
+ // --- 音声デコード (decodeAudioData の実体) -----------------------------------
193
+ // AudioEngine::Decode は第一経路 dr_wav/dr_mp3/stb_vorbis (コンソールでも同一)、
194
+ // フォールバックが Media Foundation。両経路を検証する。
135
195
  static void TestAudioDecode()
136
196
  {
137
197
  std::vector<uint8_t> wav(kTestWav, kTestWav + sizeof(kTestWav));
@@ -139,11 +199,21 @@ static void TestAudioDecode()
139
199
  CHECK(next2d::AudioEngine::Decode(wav, pcm));
140
200
  CHECK(pcm.sample_rate == 48000);
141
201
  CHECK(pcm.channels == 1);
142
- CHECK(pcm.samples.size() >= 40); // 48 サンプル前後 (MF は端数調整あり)
202
+ CHECK(pcm.samples.size() >= 40); // 48 サンプル前後
143
203
  // 振幅 0.5 の矩形波 → ピーク絶対値が 0.4〜0.6
144
204
  float peak = 0;
145
205
  for (float s : pcm.samples) peak = std::max(peak, std::fabs(s));
146
206
  CHECK(peak > 0.4f && peak < 0.6f);
207
+
208
+ // ポータブルデコーダ単体 (本番の第一経路) も直接検証
209
+ next2d::PcmBuffer pcm2;
210
+ CHECK(next2d::DecodeAudio(wav, pcm2));
211
+ CHECK(pcm2.sample_rate == 48000 && pcm2.channels == 1);
212
+ CHECK(pcm2.samples.size() >= 40);
213
+
214
+ std::vector<uint8_t> garbage(32, 0xAB);
215
+ next2d::PcmBuffer bad;
216
+ CHECK(!next2d::DecodeAudio(garbage, bad));
147
217
  }
148
218
 
149
219
  // --- XAudio2: 初期化 (ヘッドレス CI では音声デバイスが無く失敗し得る → warn) --
@@ -175,7 +245,9 @@ int main()
175
245
  MFStartup(MF_VERSION);
176
246
 
177
247
  TestWicDecode();
248
+ TestImageDecoder();
178
249
  TestTextRasterizer();
250
+ TestStbText();
179
251
  TestAudioDecode();
180
252
  TestAudioEngineInit();
181
253
 
@@ -0,0 +1,14 @@
1
+ # third_party ライセンス
2
+
3
+ コンソール (Game Core OS) には WIC / Media Foundation / DirectWrite が存在しないため、
4
+ 画像・音声デコードはヘッダオンリーのポータブルデコーダを第一経路として使用する。
5
+
6
+ | ファイル | 提供元 | ライセンス |
7
+ |---|---|---|
8
+ | stb_image.h | https://github.com/nothings/stb | public domain (Unlicense) / MIT のデュアル |
9
+ | stb_truetype.h | https://github.com/nothings/stb | public domain (Unlicense) / MIT のデュアル |
10
+ | stb_vorbis.c | https://github.com/nothings/stb | public domain (Unlicense) / MIT のデュアル |
11
+ | dr_mp3.h | https://github.com/mackron/dr_libs | public domain (Unlicense) / MIT-0 のデュアル |
12
+ | dr_wav.h | https://github.com/mackron/dr_libs | public domain (Unlicense) / MIT-0 のデュアル |
13
+
14
+ いずれも各ファイル末尾に原文のライセンス条文が含まれる。