1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the tools applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #ifndef DISTANCEFIELDMODEL_H
30 #define DISTANCEFIELDMODEL_H
31 
32 #include <QAbstractListModel>
33 #include <QRawFont>
34 #include <QtGui/qpainterpath.h>
35 #include <QtGui/private/qtextengine_p.h>
36 #include <QMultiHash>
37 #include <QScopedPointer>
38 #include <QMetaEnum>
39 #include <QThread>
40 
41 QT_BEGIN_NAMESPACE
42 
43 class QThread;
44 class DistanceFieldModelWorker;
45 class DistanceFieldModel : public QAbstractListModel
46 {
47     Q_OBJECT
48 public:
49     enum UnicodeRange {
50         Other                                = 0x00,
51         BasicLatin                           = 0x20,
52         Latin1Supplement                     = 0xa0,
53         LatinExtendedA                       = 0x100,
54         LatinExtendedB                       = 0x180,
55         IPAExtensions                        = 0x250,
56         SpacingModifierLetters               = 0x2b0,
57         CombiningDiacriticalMarks            = 0x300,
58         GreekAndCoptic                       = 0x370,
59         Cyrillic                             = 0x400,
60         CyrillicSupplementary                = 0x500,
61         Armenian                             = 0x530,
62         Hebrew                               = 0x590,
63         Arabic                               = 0x600,
64         Syriac                               = 0x700,
65         Thaana                               = 0x780,
66         Devanagari                           = 0x900,
67         Bengali                              = 0x980,
68         Gurmukhi                             = 0xa00,
69         Gujarati                             = 0xa80,
70         Oriya                                = 0xb00,
71         Tamil                                = 0xb80,
72         Telugu                               = 0xc00,
73         Kannada                              = 0xc80,
74         Malayalam                            = 0xd00,
75         Sinhala                              = 0xd80,
76         Thai                                 = 0xe00,
77         Lao                                  = 0xe80,
78         Tibetan                              = 0xf00,
79         Myanmar                              = 0x1000,
80         Georgian                             = 0x10a0,
81         HangulJamo                           = 0x1100,
82         Ethiopic                             = 0x1200,
83         Cherokee                             = 0x13a0,
84         UnifiedCanadianAboriginalSyllabics   = 0x1400,
85         Ogham                                = 0x1680,
86         Runic                                = 0x16a0,
87         Tagalog                              = 0x1700,
88         Hanunoo                              = 0x1720,
89         Buhid                                = 0x1740,
90         Tagbanwa                             = 0x1760,
91         Khmer                                = 0x1780,
92         Mongolian                            = 0x1800,
93         Limbu                                = 0x1900,
94         TaiLe                                = 0x1950,
95         KhmerSymbols                         = 0x19e0,
96         PhoneticExtensions                   = 0x1d00,
97         LatinExtendedAdditional              = 0x1e00,
98         GreekExtended                        = 0x1f00,
99         GeneralPunctuation                   = 0x2000,
100         SuperscriptsAndSubscripts            = 0x2070,
101         CurrencySymbols                      = 0x20a0,
102         CombiningDiacriticalMarksForSymbols  = 0x20d0,
103         LetterlikeSymbols                    = 0x2100,
104         NumberForms                          = 0x2150,
105         Arrows                               = 0x2190,
106         MathematicalOperators                = 0x2200,
107         MiscellaneousTechnical               = 0x2300,
108         ControlPictures                      = 0x2400,
109         OpticalCharacterRecognition          = 0x2440,
110         EnclosedAlphanumerics                = 0x2460,
111         BoxDrawing                           = 0x2500,
112         BlockElements                        = 0x2580,
113         GeometricShapes                      = 0x25a0,
114         MiscellaneousSymbols                 = 0x2600,
115         Dingbats                             = 0x2700,
116         MiscellaneousMathematicalSymbolsA    = 0x27c0,
117         SupplementalArrowsA                  = 0x27f0,
118         BraillePatterns                      = 0x2800,
119         SupplementalArrowsB                  = 0x2900,
120         MiscellaneousMathematicalSymbolsB    = 0x2980,
121         SupplementalMathematicalOperators    = 0x2a00,
122         MiscellaneousSymbolsAndArrows        = 0x2b00,
123         CJKRadicalsSupplement                = 0x2e80,
124         KangxiRadicals                       = 0x2f00,
125         IdeographicDescriptionCharacters     = 0x2ff0,
126         CJKSymbolsAndPunctuation             = 0x3000,
127         Hiragana                             = 0x3040,
128         Katakana                             = 0x30a0,
129         Bopomofo                             = 0x3100,
130         HangulCompatibilityJamo              = 0x3130,
131         Kanbun                               = 0x3190,
132         BopomofoExtended                     = 0x31a0,
133         KatakanaPhoneticExtensions           = 0x31f0,
134         EnclosedCJKLettersAndMonths          = 0x3200,
135         CJKCompatibility                     = 0x3300,
136         CJKUnifiedIdeographsExtensionA       = 0x3400,
137         YijingHexagramSymbols                = 0x4dc0,
138         CJKUnifiedIdeographs                 = 0x4e00,
139         YiSyllables                          = 0xa000,
140         YiRadicals                           = 0xa490,
141         HangulSyllables                      = 0xac00,
142         HighSurrogates                       = 0xd800,
143         HighPrivateUseSurrogates             = 0xdb80,
144         LowSurrogates                        = 0xdc00,
145         PrivateUseArea                       = 0xe000,
146         CJKCompatibilityIdeographs           = 0xf900,
147         AlphabeticPresentationForms          = 0xfb00,
148         ArabicPresentationFormsA             = 0xfb50,
149         VariationSelectors                   = 0xfe00,
150         CombiningHalfMarks                   = 0xfe20,
151         CJKCompatibilityForms                = 0xfe30,
152         SmallFormVariants                    = 0xfe50,
153         ArabicPresentationFormsB             = 0xfe70,
154         HalfwidthAndFullwidthForms           = 0xff00,
155         Specials                             = 0xfff0,
156         LinearBSyllabary                     = 0x10000,
157         LinearBIdeograms                     = 0x10080,
158         AegeanNumbers                        = 0x10100,
159         OldItalic                            = 0x10300,
160         Gothic                               = 0x10330,
161         Ugaritic                             = 0x10380,
162         Deseret                              = 0x10400,
163         Shavian                              = 0x10450,
164         Osmanya                              = 0x10480,
165         CypriotSyllabary                     = 0x10800,
166         ByzantineMusicalSymbols              = 0x1d000,
167         MusicalSymbols                       = 0x1d100,
168         TaiXuanJingSymbols                   = 0x1d300,
169         MathematicalAlphanumericSymbols      = 0x1d400,
170         CJKUnifiedIdeographsExtensionB       = 0x20000,
171         CJKCompatibilityIdeographsSupplement = 0x2f800,
172         Tags                                 = 0xe0000,
173         End                                  = 0xe007f
174     };
175     Q_ENUM(UnicodeRange)
176 
177     explicit DistanceFieldModel(QObject *parent = nullptr);
178     ~DistanceFieldModel() override;
179 
180     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
181 
182     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
183     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
184 
185     void setFont(const QString &fileName);
186 
187     QList<UnicodeRange> unicodeRanges() const;
188     QList<glyph_t> glyphIndexesForUnicodeRange(UnicodeRange range) const;
189     QString nameForUnicodeRange(UnicodeRange range) const;
190     glyph_t glyphIndexForUcs4(quint32 ucs4) const;
191 
distanceField(int row)192     QImage distanceField(int row) const
193     {
194         return m_distanceFields.at(row);
195     }
196 
path(int row)197     QPainterPath path(int row) const
198     {
199         return m_paths.at(row);
200     }
201 
pixelSize()202     qreal pixelSize() const { return m_pixelSize; }
doubleGlyphResolution()203     bool doubleGlyphResolution() const { return m_doubleGlyphResolution; }
204 
205 signals:
206     void startGeneration(quint16 glyphCount);
207     void stopGeneration();
208     void distanceFieldGenerated();
209     void error(const QString &errorString);
210 
211 private slots:
212     void addDistanceField(const QImage &distanceField,
213                           const QPainterPath &path,
214                           glyph_t glyphId,
215                           quint32 ucs4);
216     void reserveSpace(quint16 glyphCount,
217                       bool doubleResolution,
218                       qreal pixelSize);
219 
220 private:
221     UnicodeRange unicodeRangeForUcs4(quint32 ucs4) const;
222 
223     QRawFont m_font;
224     DistanceFieldModelWorker *m_worker;
225     QScopedPointer<QThread> m_workerThread;
226     quint16 m_glyphCount;
227     QVector<QImage> m_distanceFields;
228     QVector<QPainterPath> m_paths;
229     QMultiHash<UnicodeRange, glyph_t> m_glyphsPerUnicodeRange;
230     QHash<quint32, glyph_t> m_glyphsPerUcs4;
231     bool m_doubleGlyphResolution;
232     qreal m_pixelSize;
233     QMetaEnum m_rangeEnum;
234 };
235 
236 QT_END_NAMESPACE
237 
238 #endif // DISTANCEFIELDMODEL_H
239