폰트와 스타일
필요한 문자를 로드한 뒤 네이티브 소유권을 지키면서 간격과 색을 조절합니다. 완전한 workbench는 선택적으로 폰트 경로를 받습니다.
node packages/sfml.js-imgui/examples/workbench.cjs /absolute/path/to/font.ttf실제 TTF 경로로 바꾸세요. 이 명령은 기본 라틴 글리프 범위를 20 px로 표시합니다. 패키지는 폰트 파일을 제공하지 않습니다. 중국어·일본어·한국어에는 해당 범위와 실제 문자를 포함한 폰트가 필요합니다.
첫 프레임 전에 CJK 폰트 로드
빠른 시작의 import에 다음을 추가합니다. SFML.Init 성공 후 루프 전에 로드합니다. font와 ranges는 앱 범위에 선언해 프레임에서 참조하고 범위 배열의 수명을 유지합니다.
const {
getFontAtlas, getGlyphRangesChineseSimplifiedCommon,
} = require('sfml.js-imgui');
let font = null;
let ranges = null;
function loadFont(path) {
const atlas = getFontAtlas(ImGui.GetIO());
if (!atlas) {
throw new Error('Missing font atlas');
}
const pairs = getGlyphRangesChineseSimplifiedCommon(atlas);
ranges = new Uint16Array(pairs.length + 1);
ranges.set(pairs);
font = ImGui.ImFontAtlas_AddFontFromFileTTF(
atlas,
path,
20,
null,
ranges
);
if (!font || !SFML.UpdateFontTexture()) {
throw new Error('Font loading failed');
}
}초기화 후 loadFont('/absolute/path/to/cjk-font.ttf')를 한 번 호출합니다. 범위 도우미는 양 끝을 포함한 쌍을 반환하지만 네이티브 종료 0은 포함하지 않습니다. 0으로 초기화된 추가 원소가 필요합니다. 적어도 아틀라스 구축 완료까지 유지하고 나중에 다시 구축하려면 폰트와 함께 보관합니다.
getFontAtlas는 ImGui.GetIO의 네이티브 핸들을 받습니다. SFML.GetIO의 편의 필드 뷰로 대체할 수 없습니다. 폰트 파일 로드는 동기적이므로 초기화 단계에서 처리하며 Update와 Render 사이에는 아틀라스를 수정하지 않습니다.
로드한 폰트 선택
매 프레임 필요한 위젯을 PushFont와 PopFont로 감쌉니다.
ImGui.PushFont(font);
try {
if (ImGui.Begin('Font preview')) {
ImGui.TextUnformatted('场景设置');
ImGui.TextUnformatted('Player speed: 1.0');
}
ImGui.End();
} finally {
ImGui.PopFont();
}빠른 시작의 drawControls 호출을 이 코드로 바꾸어 Update 뒤, 그리기·Render 전에 실행합니다. 공통 예제는 중국어와 라틴 문자를 표시합니다. 아틀라스에 추가한 것만으로 모든 위젯의 폰트가 바뀌지 않으므로 PushFont로 선택합니다.
일본어는 getGlyphRangesJapanese, 한국어는 getGlyphRangesKorean, 전체 중국어는 getGlyphRangesChineseFull을 사용할 수 있습니다. 모두 종료 0과 해당 폰트가 필요합니다. 전체 중국어 범위는 아틀라스 크기와 구축 비용을 늘립니다. 실제 UI에 필요한 최소 범위를 고르세요. 범위 설정은 번역이나 폰트 설치를 수행하지 않습니다.
전역 간격과 색 지정
초기화 후 지속되는 기본 스타일을 설정합니다.
const { getStyleColors } = require('sfml.js-imgui');
const style = SFML.GetStyle();
style.windowPaddingX = 12;
style.windowPaddingY = 12;
style.itemSpacingX = 8;
style.itemSpacingY = 8;
style.frameRounding = 4;
const colors = getStyleColors(ImGui.GetStyle());
colors.set([ 0.20, 0.55, 0.70, 1 ], ImGui.ImGuiCol.Button * 4);ImGuiCol 항목마다 연속된 RGBA 네 원소를 사용하며 값은 0–1입니다. 실시간 뷰이므로 대입은 네이티브 상태를 즉시 바꿉니다. 컨텍스트가 유효한 동안만 캐시합니다.
일시적인 변경은 Push/Pop으로 범위를 제한합니다.
ImGui.PushStyleVar(ImGui.ImGuiStyleVar.FrameRounding, 8);
try {
ImGui.Button('Rounded action');
} finally {
ImGui.PopStyleVar();
}PushStyleVar는 스칼라, PushStyleVarVec2는 두 성분 값입니다. 매 프레임 전역 크기에 배율을 곱하지 마세요. DPI가 바뀌면 안정된 기준에서 크기를 계산하고 적절한 폰트 픽셀 크기를 골라 활성 프레임 밖에서 텍스처를 재구축합니다. fontGlobalScale은 기존 아틀라스를 확대하므로 글자가 흐려질 수 있습니다.
문제 확인
| 증상 | 주요 원인 |
|---|---|
| 문자가 네모로 표시됨 | 폰트에 글리프가 없거나 범위에서 빠짐 |
| 로드했지만 변화 없음 | PushFont로 선택하지 않음 |
| 구축 실패 | 잘못된 파일·범위, 종료 0 누락, 과도한 아틀라스 |
| 확대 후 흐림 | 실제 표시보다 작은 크기로 래스터화 |
| 다른 위젯에도 스타일 적용 | Pop 누락 또는 전역 스타일 변경 |
| 창을 닫은 뒤 충돌 | 폰트·스타일 핸들이 소유 컨텍스트 수명을 초과 |
API: getFontAtlas, getGlyphRangesChineseSimplifiedCommon, UpdateFontTexture, getStyleColors.