File indexing completed on 2025-02-02 04:11:28

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #pragma once
0008 
0009 #include <set>
0010 #include <memory>
0011 #include <unordered_map>
0012 
0013 #include <QAbstractTableModel>
0014 #include <QUrl>
0015 #include <QRawFont>
0016 
0017 #include "app/utils/qstring_hash.hpp"
0018 #include "model/assets/embedded_font.hpp"
0019 
0020 
0021 namespace glaxnimate::gui::font {
0022 
0023 class GoogleFontsModel : public QAbstractTableModel
0024 {
0025     Q_OBJECT
0026 
0027 public:
0028     static constexpr int SortRole = Qt::UserRole;
0029 
0030     struct GoogleFont
0031     {
0032         enum Category
0033         {
0034             Any,
0035             Display,
0036             Handwriting,
0037             Monospace,
0038             SansSerif,
0039             Serif,
0040         };
0041 
0042         enum DownloadStatus
0043         {
0044             InProgress,
0045             Broken,
0046             Downloaded,
0047             Available,
0048         };
0049 
0050         struct Style
0051         {
0052             QUrl url;
0053             int weight = 400;
0054             bool italic = false;
0055             model::CustomFont font;
0056 
0057             int score(int weight, bool italic) const
0058             {
0059                 return 1000 - std::abs(weight - this->weight) + (italic == this->italic ? 100 : 0);
0060             }
0061 
0062             bool operator< (const Style& other) const
0063             {
0064                 return weight < other.weight || (weight == other.weight && italic < other.italic);
0065             }
0066         };
0067 
0068         QString css_url(const Style& style) const;
0069 
0070         using StyleList = std::vector<Style>;
0071 
0072         QString family;
0073         StyleList styles;
0074         Category category;
0075         int popularity_index = 0;
0076         DownloadStatus status = Available;
0077         std::set<QString> subsets;
0078     };
0079 
0080     enum Column
0081     {
0082         Family,
0083         Category,
0084         Popularity,
0085         Status,
0086 
0087         Count
0088     };
0089 
0090     GoogleFontsModel();
0091     ~GoogleFontsModel();
0092 
0093     void refresh();
0094     bool has_token() const;
0095 
0096     int columnCount(const QModelIndex & parent = {}) const override;
0097     int rowCount(const QModelIndex & parent = {}) const override;
0098     QVariant data(const QModelIndex & index, int role) const override;
0099     QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
0100     Qt::ItemFlags flags(const QModelIndex & index) const override;
0101 
0102     static QString category_name(GoogleFontsModel::GoogleFont::Category category);
0103 
0104     const GoogleFont* font(int row) const;
0105     void download_font(int row);
0106 
0107     const std::set<QString>& subsets() const;
0108     bool has_subset(const QModelIndex& index, const QString& subset) const;
0109     bool has_category(const QModelIndex& index, GoogleFont::Category cat) const;
0110 
0111 Q_SIGNALS:
0112     void max_progress_changed(int progress);
0113     void progress_changed(int progress);
0114     void error(const QString& message);
0115     void download_finished(int row);
0116     void refresh_finished();
0117 
0118 private:
0119     void response_progress(qint64 received, qint64 total);
0120 
0121     class Private;
0122     std::unique_ptr<Private> d;
0123 };
0124 
0125 } // namespace glaxnimate::gui::font