From a92f49f7e2ee71b06485147da18418b2a075b6ca Mon Sep 17 00:00:00 2001 From: staphen Date: Fri, 13 Sep 2024 16:13:26 -0400 Subject: [PATCH] Add support for importing symbols from fonts as a spritesheet --- CMakeLists.txt | 1 + source/dialogs/importdialog.cpp | 120 ++++++++++ source/dialogs/importdialog.h | 44 ++++ source/dialogs/importdialog.ui | 381 ++++++++++++++++++++++++++++++++ source/mainwindow.cpp | 49 ++++ source/mainwindow.h | 4 + source/mainwindow.ui | 9 + 7 files changed, 608 insertions(+) create mode 100644 source/dialogs/importdialog.cpp create mode 100644 source/dialogs/importdialog.h create mode 100644 source/dialogs/importdialog.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index a800d801b..68a962894 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ set(PROJECT_SOURCES source/d1formats/d1til.cpp source/d1formats/d1trn.cpp source/dialogs/exportdialog.cpp + source/dialogs/importdialog.cpp source/views/view.cpp source/views/levelcelview.cpp source/widgets/leveltabframewidget.cpp diff --git a/source/dialogs/importdialog.cpp b/source/dialogs/importdialog.cpp new file mode 100644 index 000000000..04e07286e --- /dev/null +++ b/source/dialogs/importdialog.cpp @@ -0,0 +1,120 @@ +#include "importdialog.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "ui_importdialog.h" + +ImportDialog::ImportDialog(QWidget *parent) + : QDialog(parent) + , ui(new Ui::ImportDialog()) +{ + ui->setupUi(this); +} + +ImportDialog::~ImportDialog() +{ + delete ui; +} + +void ImportDialog::initialize() +{ + // - remember the last selected type + QComboBox *typeBox = this->ui->typeComboBox; + QString lastFmt = typeBox->currentText(); + if (lastFmt.isEmpty()) { + lastFmt = "Font"; + } + typeBox->clear(); + typeBox->addItem("Font"); + typeBox->setCurrentIndex(typeBox->findText(lastFmt)); + + setRenderColor(this->renderColor); +} + +void ImportDialog::setRenderColor(QColor color) +{ + QString red = QString::number(color.red()); + QString green = QString::number(color.green()); + QString blue = QString::number(color.blue()); + QString styleSheet = QString("background: rgb(") + red + QString(",") + green + QString(",") + blue + QString(")"); + ui->fontColorButton->setStyleSheet(styleSheet); + this->renderColor = color; +} + +QString ImportDialog::getFileFormatExtension() +{ + return "." + this->ui->typeComboBox->currentText().toLower(); +} + +void ImportDialog::on_inputFileBrowseButton_clicked() +{ + QString selectedDirectory = QFileDialog::getOpenFileName( + this, "Select Font File", QString(), "Fonts (*.ttf *.otf)"); + + if (selectedDirectory.isEmpty()) + return; + + ui->inputFileEdit->setText(selectedDirectory); +} + +void ImportDialog::on_fontSymbolsEdit_textChanged(const QString &text) +{ + bool ok = false; + uint test = text.toUInt(&ok, 16); + if (!ok) { + ui->fontSymbolsRangeLabel->setText("Error"); + return; + } + + QString pad = text.toLower(); + while (pad.size() < 2) + pad = "0" + pad; + + QString start = "U+" + pad + "00"; + QString end = "U+" + pad + "ff"; + ui->fontSymbolsRangeLabel->setText(start + " - " + end); +} + +void ImportDialog::on_fontColorButton_clicked() +{ + QColor color = QColorDialog::getColor(); + setRenderColor(color); +} + +void ImportDialog::on_importButton_clicked() +{ + if (ui->inputFileEdit->text() == "") { + QMessageBox::warning(this, "Warning", "Input file is missing, please choose an input folder."); + return; + } + + try { + MainWindow *mainWindow = dynamic_cast(this->parent()); + if (mainWindow == nullptr) { + QMessageBox::critical(this, "Error", "Window not found."); + return; + } + + QString filePath = ui->inputFileEdit->text(); + int pointSize = ui->fontSizeEdit->text().toInt(); + uint symbolPrefix = ui->fontSymbolsEdit->text().toUInt() << 8; + mainWindow->openFontFile(filePath, this->renderColor, pointSize, symbolPrefix); + } catch (...) { + QMessageBox::critical(this, "Error", "Import Failed."); + return; + } + + this->close(); +} + +void ImportDialog::on_importCancelButton_clicked() +{ + this->close(); +} diff --git a/source/dialogs/importdialog.h b/source/dialogs/importdialog.h new file mode 100644 index 000000000..f17bfc54f --- /dev/null +++ b/source/dialogs/importdialog.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +#include "d1formats/d1amp.h" +#include "d1formats/d1gfx.h" +#include "d1formats/d1min.h" +#include "d1formats/d1sol.h" +#include "d1formats/d1til.h" + +namespace Ui { +class ImportDialog; +} + +// subtiles per line if the output is groupped, an odd number to ensure it is not recognized as a flat tile +#define EXPORT_SUBTILES_PER_LINE 15 + +// frames per line if the output of a tileset-frames is groupped, an odd number to ensure it is not recognized as a flat tile or as subtiles +#define EXPORT_LVLFRAMES_PER_LINE 31 + +class ImportDialog : public QDialog { + Q_OBJECT + +public: + explicit ImportDialog(QWidget *parent = nullptr); + ~ImportDialog(); + + void initialize(); + +private slots: + void on_inputFileBrowseButton_clicked(); + void on_fontSymbolsEdit_textChanged(const QString &text); + void on_fontColorButton_clicked(); + void on_importButton_clicked(); + void on_importCancelButton_clicked(); + +private: + void setRenderColor(QColor color); + QString getFileFormatExtension(); + + Ui::ImportDialog *ui; + QColor renderColor = QColor::fromRgb(204, 183, 117); +}; diff --git a/source/dialogs/importdialog.ui b/source/dialogs/importdialog.ui new file mode 100644 index 000000000..255af20cb --- /dev/null +++ b/source/dialogs/importdialog.ui @@ -0,0 +1,381 @@ + + + ImportDialog + + + + 0 + 0 + 797 + 369 + + + + Import + + + true + + + + + + Input File + + + + + + true + + + + + + + Browse + + + + + + + + + + Input File Settings + + + + + + Import as: + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + Font Render Settings + + + + + + Symbols: + + + + + + + + 170 + 0 + + + + + 170 + 16777215 + + + + + 4 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + 0 + + + + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + U+0000 - U+00ff + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Size: + + + + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + 4 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + 12 + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Color: + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + 4 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 30 + 15 + + + + + 30 + 15 + + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + + 4 + + + 4 + + + 4 + + + 4 + + + 4 + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Import + + + + + + + Cancel + + + + + + + + + + + diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 81620bacb..e1c1de0a5 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -440,6 +440,12 @@ void MainWindow::on_actionOpen_triggered() // QMessageBox::information( this, "time", QString::number(timer.elapsed()) ); } +void MainWindow::on_actionImport_triggered() +{ + this->importDialog.initialize(); + this->importDialog.show(); +} + void MainWindow::dragEnterEvent(QDragEnterEvent *event) { this->dragMoveEvent(event); @@ -778,6 +784,49 @@ void MainWindow::openPalFiles(QStringList filePaths, PaletteWidget *widget) this->ui->statusBar->clearMessage(); } +void MainWindow::openFontFile(QString filePath, QColor renderColor, int pointSize, uint symbolPrefix) +{ + OpenAsParam params; + params.isTileset = OPEN_TILESET_TYPE::No; + this->openFile(params); + + int fontId = QFontDatabase::addApplicationFont(filePath); + if (fontId == -1) { + QMessageBox::critical(this, "Error", "Font could not be loaded."); + return; + } + + QStringList families = QFontDatabase::applicationFontFamilies(fontId); + if (families.size() == 0) { + QMessageBox::critical(this, "Error", "No font families loaded."); + QFontDatabase::removeApplicationFont(fontId); + return; + } + + QFont font = QFont(families[0], pointSize); + QFontMetrics metrics = QFontMetrics(font); + + uint symbolCount = 1 << 8; + for (uint i = 0; i < symbolCount; i++) { + char32_t codePoint = static_cast(symbolPrefix | i); + QString text = QString::fromUcs4(&codePoint, 1); + QSize renderSize = metrics.size(0, text); + QImage image = QImage(renderSize, QImage::Format_ARGB32); + image.fill(Qt::transparent); + + QPainter painter = QPainter(&image); + painter.setPen(renderColor); + painter.setFont(font); + painter.drawText(0, metrics.ascent(), text); + + this->gfx->insertFrame(i, image); + } + + this->celView->initialize(this->gfx); + this->celView->displayFrame(); + QFontDatabase::removeApplicationFont(fontId); +} + void MainWindow::updateStatusBar(const QString &status, const QString &styleSheet) { this->ui->statusBar->setStyleSheet(styleSheet); diff --git a/source/mainwindow.h b/source/mainwindow.h index 570358f0c..53451e516 100644 --- a/source/mainwindow.h +++ b/source/mainwindow.h @@ -14,6 +14,7 @@ #include "d1formats/d1til.h" #include "d1formats/d1trn.h" #include "dialogs/exportdialog.h" +#include "dialogs/importdialog.h" #include "dialogs/openasdialog.h" #include "dialogs/settingsdialog.h" #include "palette/d1pal.h" @@ -57,6 +58,7 @@ class MainWindow : public QMainWindow { void openFile(const OpenAsParam ¶ms); void openImageFiles(IMAGE_FILE_MODE mode, QStringList filePaths, bool append); void openPalFiles(QStringList filePaths, PaletteWidget *widget); + void openFontFile(QString filePath, QColor renderColor, int pointSize, uint symbolPrefix); void saveFile(const QString &gfxPath); void paletteWidget_callback(PaletteWidget *widget, PWIDGET_CALLBACK_TYPE type); @@ -121,6 +123,7 @@ private slots: void on_actionOpen_triggered(); void on_actionOpenAs_triggered(); + void on_actionImport_triggered(); void on_actionSave_triggered(); void on_actionSaveAs_triggered(); bool isOkToQuit(); @@ -187,6 +190,7 @@ private slots: OpenAsDialog openAsDialog = OpenAsDialog(this); SettingsDialog settingsDialog = SettingsDialog(this); + ImportDialog importDialog = ImportDialog(this); ExportDialog exportDialog = ExportDialog(this); QPointer pal; diff --git a/source/mainwindow.ui b/source/mainwindow.ui index 07cbb75c5..65a936e57 100644 --- a/source/mainwindow.ui +++ b/source/mainwindow.ui @@ -122,6 +122,7 @@ + @@ -251,6 +252,14 @@ Ctrl+Shift+O + + + Import... + + + Ctrl+I + + Save