Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
Soreepeong committed May 27, 2022
1 parent b5bdb7b commit a4ac89c
Show file tree
Hide file tree
Showing 39 changed files with 31,373 additions and 118 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# FFXIV Font Generator

Name says it all.

29 changes: 19 additions & 10 deletions XivRes.FontGenerator/FaceElementEditorDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct App::FaceElementEditorDialog::ControlStruct {
HWND CodepointsList = GetDlgItem(Window, IDC_LIST_CODEPOINTS);
HWND CodepointsClearButton = GetDlgItem(Window, IDC_BUTTON_CODEPOINTS_CLEAR);
HWND CodepointsDeleteButton = GetDlgItem(Window, IDC_BUTTON_CODEPOINTS_DELETE);
HWND CodepointsOverwriteCheck = GetDlgItem(Window, IDC_CHECK_CODEPOINTS_OVERWRITE);
HWND CodepointsMergeModeCombo = GetDlgItem(Window, IDC_COMBO_CODEPOINTS_MERGEMODE);
HWND UnicodeBlockSearchNameEdit = GetDlgItem(Window, IDC_EDIT_UNICODEBLOCKS_SEARCH);
HWND UnicodeBlockSearchShowBlocksWithAnyOfCharactersInput = GetDlgItem(Window, IDC_CHECK_UNICODEBLOCKS_SHOWBLOCKSWITHANYOFCHARACTERSINPUT);
HWND UnicodeBlockSearchResultList = GetDlgItem(Window, IDC_LIST_UNICODEBLOCKS_SEARCHRESULTS);
Expand Down Expand Up @@ -464,9 +464,15 @@ INT_PTR App::FaceElementEditorDialog::CodepointsDeleteButton_OnCommand(uint16_t
return 0;
}

INT_PTR App::FaceElementEditorDialog::CodepointsOverwriteCheck_OnCommand(uint16_t notiCode) {
m_element.Overwrite = Button_GetCheck(m_controls->CodepointsOverwriteCheck);
OnWrappedFontChanged();
INT_PTR App::FaceElementEditorDialog::CodepointsMergeModeCombo_OnCommand(uint16_t notiCode) {
if (notiCode != CBN_SELCHANGE)
return 0;

if (const auto v = static_cast<XivRes::FontGenerator::MergedFontCodepointMode>(ComboBox_GetCurSel(m_controls->CodepointsMergeModeCombo));
v != m_element.MergeMode) {
m_element.MergeMode = v;
OnWrappedFontChanged();
}
return 0;
}

Expand Down Expand Up @@ -604,7 +610,10 @@ INT_PTR App::FaceElementEditorDialog::Dialog_OnInitDialog() {
for (int i = 0, i_ = static_cast<int>(m_element.WrapModifiers.Codepoints.size()); i < i_; i++)
AddCodepointRangeToListBox(i, m_element.WrapModifiers.Codepoints[i].first, m_element.WrapModifiers.Codepoints[i].second, charVec);

Button_SetCheck(m_controls->CodepointsOverwriteCheck, m_element.Overwrite ? TRUE : FALSE);
ComboBox_AddString(m_controls->CodepointsMergeModeCombo, L"Add new glyphs");
ComboBox_AddString(m_controls->CodepointsMergeModeCombo, L"Add all glyphs");
ComboBox_AddString(m_controls->CodepointsMergeModeCombo, L"Replace existing glyphs");
ComboBox_SetCurSel(m_controls->CodepointsMergeModeCombo, static_cast<int>(m_element.MergeMode));

SetWindowNumber(m_controls->TransformationMatrixM11Edit, m_element.TransformationMatrix.M11);
SetWindowNumber(m_controls->TransformationMatrixM12Edit, m_element.TransformationMatrix.M12);
Expand Down Expand Up @@ -946,7 +955,7 @@ void App::FaceElementEditorDialog::SetControlsEnabledOrDisabled() {
EnableWindow(m_controls->CustomRangeAdd, FALSE);
EnableWindow(m_controls->CodepointsList, FALSE);
EnableWindow(m_controls->CodepointsDeleteButton, FALSE);
EnableWindow(m_controls->CodepointsOverwriteCheck, FALSE);
EnableWindow(m_controls->CodepointsMergeModeCombo, FALSE);
EnableWindow(m_controls->UnicodeBlockSearchNameEdit, FALSE);
EnableWindow(m_controls->UnicodeBlockSearchResultList, FALSE);
EnableWindow(m_controls->UnicodeBlockSearchAddAll, FALSE);
Expand Down Expand Up @@ -983,7 +992,7 @@ void App::FaceElementEditorDialog::SetControlsEnabledOrDisabled() {
EnableWindow(m_controls->CustomRangeAdd, TRUE);
EnableWindow(m_controls->CodepointsList, TRUE);
EnableWindow(m_controls->CodepointsDeleteButton, TRUE);
EnableWindow(m_controls->CodepointsOverwriteCheck, TRUE);
EnableWindow(m_controls->CodepointsMergeModeCombo, TRUE);
EnableWindow(m_controls->UnicodeBlockSearchNameEdit, TRUE);
EnableWindow(m_controls->UnicodeBlockSearchResultList, TRUE);
EnableWindow(m_controls->UnicodeBlockSearchAddAll, TRUE);
Expand Down Expand Up @@ -1020,7 +1029,7 @@ void App::FaceElementEditorDialog::SetControlsEnabledOrDisabled() {
EnableWindow(m_controls->CustomRangeAdd, TRUE);
EnableWindow(m_controls->CodepointsList, TRUE);
EnableWindow(m_controls->CodepointsDeleteButton, TRUE);
EnableWindow(m_controls->CodepointsOverwriteCheck, TRUE);
EnableWindow(m_controls->CodepointsMergeModeCombo, TRUE);
EnableWindow(m_controls->UnicodeBlockSearchNameEdit, TRUE);
EnableWindow(m_controls->UnicodeBlockSearchResultList, TRUE);
EnableWindow(m_controls->UnicodeBlockSearchAddAll, TRUE);
Expand Down Expand Up @@ -1057,7 +1066,7 @@ void App::FaceElementEditorDialog::SetControlsEnabledOrDisabled() {
EnableWindow(m_controls->CustomRangeAdd, TRUE);
EnableWindow(m_controls->CodepointsList, TRUE);
EnableWindow(m_controls->CodepointsDeleteButton, TRUE);
EnableWindow(m_controls->CodepointsOverwriteCheck, TRUE);
EnableWindow(m_controls->CodepointsMergeModeCombo, TRUE);
EnableWindow(m_controls->UnicodeBlockSearchNameEdit, TRUE);
EnableWindow(m_controls->UnicodeBlockSearchResultList, TRUE);
EnableWindow(m_controls->UnicodeBlockSearchAddAll, TRUE);
Expand Down Expand Up @@ -1343,7 +1352,7 @@ INT_PTR App::FaceElementEditorDialog::DlgProc(UINT message, WPARAM wParam, LPARA
case IDC_LIST_CODEPOINTS: return CodepointsList_OnCommand(HIWORD(wParam));
case IDC_BUTTON_CODEPOINTS_CLEAR: return CodepointsClearButton_OnCommand(HIWORD(wParam));
case IDC_BUTTON_CODEPOINTS_DELETE: return CodepointsDeleteButton_OnCommand(HIWORD(wParam));
case IDC_CHECK_CODEPOINTS_OVERWRITE: return CodepointsOverwriteCheck_OnCommand(HIWORD(wParam));
case IDC_COMBO_CODEPOINTS_MERGEMODE: return CodepointsMergeModeCombo_OnCommand(HIWORD(wParam));
case IDC_EDIT_UNICODEBLOCKS_SEARCH: return UnicodeBlockSearchNameEdit_OnCommand(HIWORD(wParam));
case IDC_CHECK_UNICODEBLOCKS_SHOWBLOCKSWITHANYOFCHARACTERSINPUT: return UnicodeBlockSearchShowBlocksWithAnyOfCharactersInput_OnCommand(HIWORD(wParam));
case IDC_LIST_UNICODEBLOCKS_SEARCHRESULTS: return UnicodeBlockSearchResultList_OnCommand(HIWORD(wParam));
Expand Down
2 changes: 1 addition & 1 deletion XivRes.FontGenerator/FaceElementEditorDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ namespace App {

INT_PTR CodepointsDeleteButton_OnCommand(uint16_t notiCode);

INT_PTR CodepointsOverwriteCheck_OnCommand(uint16_t notiCode);
INT_PTR CodepointsMergeModeCombo_OnCommand(uint16_t notiCode);

INT_PTR UnicodeBlockSearchNameEdit_OnCommand(uint16_t notiCode);

Expand Down
69 changes: 47 additions & 22 deletions XivRes.FontGenerator/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct ListViewCols {
Gamma,
Codepoints,
GlyphCount,
Overwrite,
MergeMode,
Renderer,
Lookup,
};
Expand Down Expand Up @@ -128,7 +128,7 @@ LRESULT App::FontEditorWindow::Window_OnCreate(HWND hwnd) {
AddColumn(ListViewCols::LetterSpacing, 100, L"Letter Spacing");
AddColumn(ListViewCols::Gamma, 60, L"Gamma");
AddColumn(ListViewCols::Codepoints, 80, L"Codepoints");
AddColumn(ListViewCols::Overwrite, 70, L"Overwrite");
AddColumn(ListViewCols::MergeMode, 70, L"Overwrite");
AddColumn(ListViewCols::GlyphCount, 60, L"Glyphs");
AddColumn(ListViewCols::Renderer, 180, L"Renderer");
AddColumn(ListViewCols::Lookup, 300, L"Lookup");
Expand Down Expand Up @@ -363,7 +363,7 @@ LRESULT App::FontEditorWindow::Menu_File_Save() {
return Menu_File_SaveAs(true);

try {
const auto dump = nlohmann::json(m_fontSet).dump();
const auto dump = nlohmann::json(m_fontSet).dump(1, '\t');
std::ofstream(m_path, std::ios::binary).write(&dump[0], dump.size());
Changes_MarkFresh();
} catch (const std::exception& e) {
Expand All @@ -383,7 +383,7 @@ LRESULT App::FontEditorWindow::Menu_File_SaveAs(bool changeCurrentFile) {
const auto fileTypesSpan = std::span(fileTypes);

try {
const auto dump = nlohmann::json(m_fontSet).dump();
const auto dump = nlohmann::json(m_fontSet).dump(1, '\t');

IFileSaveDialogPtr pDialog;
DWORD dwFlags;
Expand Down Expand Up @@ -625,12 +625,12 @@ LRESULT App::FontEditorWindow::Menu_Edit_ChangeParams(int baselineShift, int hor
return 0;
}

LRESULT App::FontEditorWindow::Menu_Edit_ToggleOverwrite() {
LRESULT App::FontEditorWindow::Menu_Edit_ToggleMergeMode() {
auto any = false;
for (auto i = -1; -1 != (i = ListView_GetNextItem(m_hFaceElementsListView, i, LVNI_SELECTED));) {
any = true;
auto& e = *m_pActiveFace->Elements[i];
e.Overwrite = !e.Overwrite;
e.MergeMode = static_cast<XivRes::FontGenerator::MergedFontCodepointMode>((static_cast<int>(e.MergeMode) + 1) % static_cast<int>(XivRes::FontGenerator::MergedFontCodepointMode::Enum_Count_));
e.OnFontWrappingParametersChange();
UpdateFaceElementListViewItem(e);
}
Expand Down Expand Up @@ -870,24 +870,22 @@ LRESULT App::FontEditorWindow::Menu_Export_Raw() {
LRESULT App::FontEditorWindow::Menu_Export_TTMP(CompressionMode compressionMode) {
using namespace XivRes::FontGenerator;
static constexpr COMDLG_FILTERSPEC fileTypes[] = {
{ L"TTMP2 file (*.ttmp2)", L"*.ttmp2" },
{ L"TTMP file (*.ttmp)", L"*.ttmp" },
{ L"ZIP file (*.zip)", L"*.zip" },
{ L"All files (*.*)", L"*" },
};
const auto fileTypesSpan = std::span(fileTypes);

std::wstring tmpPath, finalPath;
try {
const auto dump = nlohmann::json(m_fontSet).dump();

IFileSaveDialogPtr pDialog;
DWORD dwFlags;
SuccessOrThrow(pDialog.CreateInstance(CLSID_FileSaveDialog, nullptr, CLSCTX_INPROC_SERVER));
SuccessOrThrow(pDialog->SetClientGuid(Guid_IFileDialog_Export));
SuccessOrThrow(pDialog->SetFileTypes(static_cast<UINT>(fileTypesSpan.size()), fileTypesSpan.data()));
SuccessOrThrow(pDialog->SetFileTypeIndex(0));
SuccessOrThrow(pDialog->SetTitle(L"Save"));
SuccessOrThrow(pDialog->SetFileName(std::format(L"{}.ttmp2", m_path.filename().replace_extension(L"").wstring()).c_str()));
SuccessOrThrow(pDialog->SetFileName(std::format(L"{}.ttmp", m_path.filename().replace_extension(L"").wstring()).c_str()));
SuccessOrThrow(pDialog->SetDefaultExtension(L"json"));
SuccessOrThrow(pDialog->GetOptions(&dwFlags));
SuccessOrThrow(pDialog->SetOptions(dwFlags | FOS_FORCEFILESYSTEM));
Expand Down Expand Up @@ -917,7 +915,7 @@ LRESULT App::FontEditorWindow::Menu_Export_TTMP(CompressionMode compressionMode)
zipFile zf = zipOpen2_64(&tmpPath[0], APPEND_STATUS_CREATE, nullptr, &ffunc);
if (!zf)
throw std::runtime_error("Failed to create target file");
auto zfclose = XivRes::Internal::CallOnDestruction([&zf, &dump]() { zipClose(zf, &dump[0]); });
auto zfclose = XivRes::Internal::CallOnDestruction([&zf]() { zipClose(zf, nullptr); });

ProgressDialog progressDialog(m_hWnd, "Exporting...");
ShowWindow(m_hWnd, SW_HIDE);
Expand All @@ -935,7 +933,7 @@ LRESULT App::FontEditorWindow::Menu_Export_TTMP(CompressionMode compressionMode)
const auto targetFileName = std::format("common/font/{}.fdt", m_fontSet.Faces[i]->Name);
progressDialog.UpdateStatusMessage(std::format("Packing file: {}", targetFileName));

XivRes::BinaryPackedFileStream packedStream(targetFileName, fdts[i], compressionMode == CompressionMode::CompressWhilePacking ? Z_BEST_COMPRESSION : Z_NO_COMPRESSION);
XivRes::CompressingPackedFileStream<XivRes::BinaryCompressingPacker> packedStream(targetFileName, fdts[i], compressionMode == CompressionMode::CompressWhilePacking ? Z_BEST_COMPRESSION : Z_NO_COMPRESSION);

const auto pos = ttmpd.size();
ttmpl << nlohmann::json::object({
Expand All @@ -959,7 +957,7 @@ LRESULT App::FontEditorWindow::Menu_Export_TTMP(CompressionMode compressionMode)
auto textureOne = std::make_shared<XivRes::TextureStream>(mip->Type, mip->Width, mip->Height, 1, 1, 1);
textureOne->SetMipmap(0, 0, mip);

XivRes::TexturePackedFileStream packedStream(targetFileName, std::move(textureOne), compressionMode == CompressionMode::CompressWhilePacking ? Z_BEST_COMPRESSION : Z_NO_COMPRESSION);
XivRes::CompressingPackedFileStream<XivRes::TextureCompressingPacker> packedStream(targetFileName, std::move(textureOne), compressionMode == CompressionMode::CompressWhilePacking ? Z_BEST_COMPRESSION : Z_NO_COMPRESSION);

const auto pos = ttmpd.size();
ttmpl << nlohmann::json::object({
Expand Down Expand Up @@ -1000,7 +998,7 @@ LRESULT App::FontEditorWindow::Menu_Export_TTMP(CompressionMode compressionMode)
0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
nullptr, crc32_z(0, reinterpret_cast<const uint8_t*>(&ttmpls[0]), ttmpls.size()), 0))
throw std::runtime_error(std::format("Failed to create TTMPL.mpl inside zip: {}", err));
std::unique_ptr<decltype(zf), decltype(zipCloseFileInZip)*> ziClose(&zf, zipCloseFileInZip);
std::unique_ptr<std::remove_pointer_t<decltype(zf)>, decltype(zipCloseFileInZip)*> ziClose(zf, zipCloseFileInZip);

for (size_t offset = 0; offset < ttmpls.size(); offset += ChunkSize) {
progressDialog.ThrowIfCancelled();
Expand All @@ -1021,7 +1019,7 @@ LRESULT App::FontEditorWindow::Menu_Export_TTMP(CompressionMode compressionMode)
0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
nullptr, crc32_z(0, reinterpret_cast<const uint8_t*>(&ttmpd[0]), ttmpd.size()), 0))
throw std::runtime_error(std::format("Failed to create TTMPD.mpd inside zip: {}", err));
std::unique_ptr<decltype(zf), decltype(zipCloseFileInZip)*> ziClose(&zf, zipCloseFileInZip);
std::unique_ptr<std::remove_pointer_t<decltype(zf)>, decltype(zipCloseFileInZip)*> ziClose(zf, zipCloseFileInZip);

for (size_t offset = 0; offset < ttmpd.size(); offset += ChunkSize) {
progressDialog.ThrowIfCancelled();
Expand All @@ -1034,7 +1032,6 @@ LRESULT App::FontEditorWindow::Menu_Export_TTMP(CompressionMode compressionMode)
progressDialog.UpdateProgress(1.f * written / totalWriteSize);
}
}
std::cout << std::endl;

zfclose.Clear();

Expand Down Expand Up @@ -1382,7 +1379,20 @@ void App::FontEditorWindow::UpdateFaceElementListViewItem(const Structs::FaceEle
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::LetterSpacing, &(buf = std::format(L"{}px", element.Renderer == Structs::RendererEnum::Empty ? 0 : element.WrapModifiers.LetterSpacing))[0]);
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::Codepoints, &(buf = element.GetRangeRepresentation())[0]);
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::GlyphCount, &(buf = std::format(L"{}", element.GetWrappedFont()->GetAllCodepoints().size()))[0]);
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::Overwrite, &(buf = element.Overwrite ? L"Yes" : L"No")[0]);
switch (element.MergeMode) {
case XivRes::FontGenerator::MergedFontCodepointMode::AddNew:
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::MergeMode, &(buf = L"Add New")[0]);
break;
case XivRes::FontGenerator::MergedFontCodepointMode::AddAll:
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::MergeMode, &(buf = L"Add All")[0]);
break;
case XivRes::FontGenerator::MergedFontCodepointMode::Replace:
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::MergeMode, &(buf = L"Replace")[0]);
break;
default:
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::MergeMode, &(buf = L"Invalid")[0]);
break;
}
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::Gamma, &(buf = std::format(L"{:g}", element.Gamma))[0]);
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::Renderer, &(buf = element.GetRendererRepresentation())[0]);
ListView_SetItemText(m_hFaceElementsListView, index, ListViewCols::Lookup, &(buf = element.GetLookupRepresentation())[0]);
Expand All @@ -1394,16 +1404,29 @@ std::pair<std::vector<std::shared_ptr<XivRes::FontdataStream>>, std::vector<std:

{
progressDialog.UpdateStatusMessage("Resolving kerning pairs...");
std::cout << "Resolving kerning pairs...\n";
XivRes::Internal::ThreadPool pool;
XivRes::Internal::ThreadPool<Structs::Face*, size_t> pool;
for (auto& pFace : m_fontSet.Faces) {
pool.Submit([pFace = pFace.get(), &progressDialog]() {
pool.Submit(pFace.get(), [pFace = pFace.get(), &progressDialog]() -> size_t {
if (progressDialog.IsCancelled())
return;
void(pFace->GetMergedFont()->GetAllKerningPairs());
return 0;
return pFace->GetMergedFont()->GetAllKerningPairs().size();
});
}
pool.SubmitDoneAndWait();

std::vector<std::string> tooManyKernings;
for (std::optional<std::pair<Structs::Face*, size_t>> res; (res = pool.GetResult());) {
const auto& [pFace, nKerns] = *res;
if (nKerns >= 65536)
tooManyKernings.emplace_back(std::format("\n{}: {}", pFace->Name, nKerns));
}
if (!tooManyKernings.empty()) {
std::ranges::sort(tooManyKernings);
std::string s = "The number of kerning entries of the following font(s) exceeds the limit of 65535.";
for (const auto& s2 : tooManyKernings)
s += s2;
throw std::runtime_error(s);
}
}
progressDialog.ThrowIfCancelled();

Expand All @@ -1422,6 +1445,8 @@ std::pair<std::vector<std::shared_ptr<XivRes::FontdataStream>>, std::vector<std:
progressDialog.UpdateStatusMessage(packer.GetProgressDescription());
progressDialog.UpdateProgress(packer.GetProgress());
}
if (const auto err = packer.GetErrorIfFailed(); !err.empty())
throw std::runtime_error(err);

const auto& fdts = packer.GetTargetFonts();
const auto& mips = packer.GetMipmapStreams();
Expand Down
4 changes: 2 additions & 2 deletions XivRes.FontGenerator/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ namespace App {
LRESULT Menu_Edit_SelectAll();
LRESULT Menu_Edit_Details();
LRESULT Menu_Edit_ChangeParams(int baselineShift, int horizontalOffset, int letterSpacing, float fontSize);
LRESULT Menu_Edit_ToggleOverwrite();
LRESULT Menu_Edit_ToggleMergeMode();
LRESULT Menu_Edit_MoveUpOrDown(int direction);
LRESULT Menu_Edit_CreateEmptyCopyFromSelection();

Expand Down Expand Up @@ -158,7 +158,7 @@ namespace App {
case ID_EDIT_INCREASEFONTSIZEBY1: return Menu_Edit_ChangeParams(0, 0, 0, +1.f);
case ID_EDIT_DECREASEFONTSIZEBY0_2: return Menu_Edit_ChangeParams(0, 0, 0, -0.2f);
case ID_EDIT_INCREASEFONTSIZEBY0_2: return Menu_Edit_ChangeParams(0, 0, 0, +0.2f);
case ID_EDIT_TOGGLEOVERWRITE: return Menu_Edit_ToggleOverwrite();
case ID_EDIT_TOGGLEMERGEMODE: return Menu_Edit_ToggleMergeMode();
case ID_EDIT_MOVEUP: return Menu_Edit_MoveUpOrDown(-1);
case ID_EDIT_MOVEDOWN: return Menu_Edit_MoveUpOrDown(+1);
case ID_EDIT_CREATEEMPTYCOPYFROMSELECTION: return Menu_Edit_CreateEmptyCopyFromSelection();
Expand Down
1 change: 0 additions & 1 deletion XivRes.FontGenerator/Presets/Comic Sans.json

This file was deleted.

1,090 changes: 1,089 additions & 1 deletion XivRes.FontGenerator/Presets/Default.json

Large diffs are not rendered by default.

Loading

0 comments on commit a4ac89c

Please sign in to comment.