Charlie Jiang pushed to branch gsoc-2022-chariri-3 at FreeType / FreeType Demo Programs
Commits:
-
80e4e581
by Charlie Jiang at 2022-08-03T00:56:39+08:00
11 changed files:
- src/ftinspect/CMakeLists.txt
- src/ftinspect/engine/charmap.cpp
- src/ftinspect/engine/charmap.hpp
- src/ftinspect/engine/engine.cpp
- src/ftinspect/engine/engine.hpp
- src/ftinspect/engine/fontfilemanager.cpp
- src/ftinspect/engine/stringrenderer.cpp
- src/ftinspect/maingui.cpp
- src/ftinspect/models/customcomboboxmodels.cpp
- src/ftinspect/panels/settingpanel.cpp
- src/ftinspect/rendering/glyphcontinuous.cpp
Changes:
... | ... | @@ -51,3 +51,13 @@ target_link_libraries(ftinspect |
51 | 51 | Qt5::Core Qt5::Widgets
|
52 | 52 | Freetype::Freetype
|
53 | 53 | )
|
54 | + |
|
55 | +# Fix for CMake prior to 3.15
|
|
56 | +string(REGEX REPLACE "/W[3|4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
57 | +if(MSVC)
|
|
58 | + target_compile_options(ftinspect PRIVATE "/W4" "/wd4100")
|
|
59 | +else(CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
|
|
60 | + OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
61 | + target_compile_options(ftinspect PRIVATE "-Wall" "-Wextra"
|
|
62 | + "-Wpedantic" "-Wno-unused-parameter")
|
|
63 | +endif() |
... | ... | @@ -53,11 +53,11 @@ CharMapInfo::CharMapInfo(int index, FT_CharMap cmap) |
53 | 53 | |
54 | 54 | |
55 | 55 | QString
|
56 | -CharMapInfo::stringifyIndex(int code, int index)
|
|
56 | +CharMapInfo::stringifyIndex(int code, int idx)
|
|
57 | 57 | {
|
58 | 58 | return QString("CharCode: %1 (glyph idx %2)")
|
59 | 59 | .arg(stringifyIndexShort(code))
|
60 | - .arg(index);
|
|
60 | + .arg(idx);
|
|
61 | 61 | }
|
62 | 62 | |
63 | 63 | |
... | ... | @@ -72,11 +72,11 @@ CharMapInfo::stringifyIndexShort(int code) |
72 | 72 | int
|
73 | 73 | CharMapInfo::computeMaxIndex()
|
74 | 74 | {
|
75 | - int maxIndex;
|
|
75 | + int result;
|
|
76 | 76 | switch (encoding)
|
77 | 77 | {
|
78 | 78 | case FT_ENCODING_UNICODE:
|
79 | - maxIndex = maxIndexForFaceAndCharMap(ptr, 0x110000) + 1;
|
|
79 | + result = maxIndexForFaceAndCharMap(ptr, 0x110000) + 1;
|
|
80 | 80 | break;
|
81 | 81 | |
82 | 82 | case FT_ENCODING_ADOBE_LATIN_1:
|
... | ... | @@ -84,28 +84,29 @@ CharMapInfo::computeMaxIndex() |
84 | 84 | case FT_ENCODING_ADOBE_EXPERT:
|
85 | 85 | case FT_ENCODING_ADOBE_CUSTOM:
|
86 | 86 | case FT_ENCODING_APPLE_ROMAN:
|
87 | - maxIndex = 0x100;
|
|
87 | + result = 0x100;
|
|
88 | 88 | break;
|
89 | 89 | |
90 | 90 | /* some fonts use range 0x00-0x100, others have 0xF000-0xF0FF */
|
91 | 91 | case FT_ENCODING_MS_SYMBOL:
|
92 | - maxIndex = maxIndexForFaceAndCharMap(ptr, 0x10000) + 1;
|
|
92 | + result = maxIndexForFaceAndCharMap(ptr, 0x10000) + 1;
|
|
93 | 93 | break;
|
94 | 94 | |
95 | 95 | default:
|
96 | 96 | // Some encodings can reach > 0x10000, e.g. GB 18030.
|
97 | - maxIndex = maxIndexForFaceAndCharMap(ptr, 0x110000) + 1;
|
|
97 | + result = maxIndexForFaceAndCharMap(ptr, 0x110000) + 1;
|
|
98 | 98 | }
|
99 | - return maxIndex;
|
|
99 | + return result;
|
|
100 | 100 | }
|
101 | 101 | |
102 | 102 | |
103 | 103 | int
|
104 | 104 | CharMapInfo::maxIndexForFaceAndCharMap(FT_CharMap charMap,
|
105 | - unsigned max)
|
|
105 | + unsigned maxIn)
|
|
106 | 106 | {
|
107 | 107 | // code adopted from `ftcommon.c`
|
108 | - FT_ULong min = 0;
|
|
108 | + // This never overflows since no format here exceeds INT_MAX...
|
|
109 | + FT_ULong min = 0, max = maxIn;
|
|
109 | 110 | FT_UInt glyphIndex;
|
110 | 111 | FT_Face face = charMap->face;
|
111 | 112 |
... | ... | @@ -26,7 +26,7 @@ struct CharMapInfo |
26 | 26 | |
27 | 27 | CharMapInfo(int index, FT_CharMap cmap);
|
28 | 28 | |
29 | - QString stringifyIndex(int code, int index);
|
|
29 | + QString stringifyIndex(int code, int idx);
|
|
30 | 30 | QString stringifyIndexShort(int code);
|
31 | 31 | |
32 | 32 |
... | ... | @@ -170,39 +170,51 @@ Engine::~Engine() |
170 | 170 | }
|
171 | 171 | |
172 | 172 | |
173 | -long
|
|
174 | -Engine::numberOfFaces(int fontIndex)
|
|
173 | +template <class Func>
|
|
174 | +void
|
|
175 | +Engine::withFace(FaceID id, Func func)
|
|
175 | 176 | {
|
176 | 177 | FT_Face face;
|
177 | - long numFaces = -1;
|
|
178 | - |
|
179 | - if (fontIndex < 0)
|
|
180 | - return -1;
|
|
181 | - |
|
182 | - auto id = FaceID(fontIndex, 0, 0);
|
|
183 | - |
|
184 | - // search triplet (fontIndex, 0, 0)
|
|
185 | - FTC_FaceID ftcFaceID = reinterpret_cast<FTC_FaceID>(faceIDMap_.value(id));
|
|
186 | - if (ftcFaceID)
|
|
178 | + // search triplet (fontIndex, faceIndex, namedInstanceIndex)
|
|
179 | + auto numId = reinterpret_cast<FTC_FaceID>(faceIDMap_.value(id));
|
|
180 | + if (numId)
|
|
187 | 181 | {
|
188 | 182 | // found
|
189 | - if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
|
|
190 | - numFaces = face->num_faces;
|
|
183 | + if (!FTC_Manager_LookupFace(cacheManager_, numId, &face))
|
|
184 | + func(face);
|
|
191 | 185 | }
|
192 | - else
|
|
186 | + else if (id.fontIndex >= 0)
|
|
193 | 187 | {
|
194 | - // not found; try to load triplet (fontIndex, 0, 0)
|
|
195 | - ftcFaceID = reinterpret_cast<FTC_FaceID>(faceCounter_);
|
|
188 | + if (faceCounter_ >= INT_MAX) // prevent overflowing
|
|
189 | + return;
|
|
190 | + |
|
191 | + // not found; try to load triplet
|
|
192 | + // (fontIndex, faceIndex, namedInstanceIndex)
|
|
193 | + numId = reinterpret_cast<FTC_FaceID>(faceCounter_);
|
|
196 | 194 | faceIDMap_.insert(id, faceCounter_++);
|
197 | 195 | |
198 | - if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
|
|
199 | - numFaces = face->num_faces;
|
|
196 | + if (!FTC_Manager_LookupFace(cacheManager_, numId, &face))
|
|
197 | + func(face);
|
|
200 | 198 | else
|
201 | 199 | {
|
202 | 200 | faceIDMap_.remove(id);
|
203 | 201 | faceCounter_--;
|
204 | 202 | }
|
205 | 203 | }
|
204 | +}
|
|
205 | + |
|
206 | + |
|
207 | +long
|
|
208 | +Engine::numberOfFaces(int fontIndex)
|
|
209 | +{
|
|
210 | + long numFaces = -1;
|
|
211 | + |
|
212 | + if (fontIndex < 0)
|
|
213 | + return -1;
|
|
214 | + |
|
215 | + // search triplet (fontIndex, 0, 0)
|
|
216 | + withFace(FaceID(fontIndex, 0, 0),
|
|
217 | + [&](FT_Face face) { numFaces = face->num_faces; });
|
|
206 | 218 | |
207 | 219 | return numFaces;
|
208 | 220 | }
|
... | ... | @@ -212,36 +224,18 @@ int |
212 | 224 | Engine::numberOfNamedInstances(int fontIndex,
|
213 | 225 | long faceIndex)
|
214 | 226 | {
|
215 | - FT_Face face;
|
|
216 | 227 | // we return `n' named instances plus one;
|
217 | 228 | // instance index 0 represents a face without a named instance selected
|
218 | 229 | int numNamedInstances = -1;
|
219 | 230 | if (fontIndex < 0)
|
220 | 231 | return -1;
|
221 | - auto id = FaceID(fontIndex, faceIndex, 0);
|
|
222 | - |
|
223 | - // search triplet (fontIndex, faceIndex, 0)
|
|
224 | - FTC_FaceID ftcFaceID = reinterpret_cast<FTC_FaceID>(faceIDMap_.value(id));
|
|
225 | - if (ftcFaceID)
|
|
226 | - {
|
|
227 | - // found
|
|
228 | - if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
|
|
229 | - numNamedInstances = static_cast<int>((face->style_flags >> 16) + 1);
|
|
230 | - }
|
|
231 | - else
|
|
232 | - {
|
|
233 | - // not found; try to load triplet (fontIndex, faceIndex, 0)
|
|
234 | - ftcFaceID = reinterpret_cast<FTC_FaceID>(faceCounter_);
|
|
235 | - faceIDMap_.insert(id, faceCounter_++);
|
|
236 | 232 | |
237 | - if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
|
|
238 | - numNamedInstances = static_cast<int>((face->style_flags >> 16) + 1);
|
|
239 | - else
|
|
240 | - {
|
|
241 | - faceIDMap_.remove(id);
|
|
242 | - faceCounter_--;
|
|
243 | - }
|
|
244 | - }
|
|
233 | + withFace(FaceID(fontIndex, faceIndex, 0),
|
|
234 | + [&](FT_Face face)
|
|
235 | + {
|
|
236 | + numNamedInstances
|
|
237 | + = static_cast<int>((face->style_flags >> 16) + 1);
|
|
238 | + });
|
|
245 | 239 | |
246 | 240 | return numNamedInstances;
|
247 | 241 | }
|
... | ... | @@ -250,41 +244,16 @@ Engine::numberOfNamedInstances(int fontIndex, |
250 | 244 | QString
|
251 | 245 | Engine::namedInstanceName(int fontIndex, long faceIndex, int index)
|
252 | 246 | {
|
253 | - FT_Face face;
|
|
254 | - QString name;
|
|
255 | - |
|
256 | 247 | if (fontIndex < 0)
|
257 | - return QString();
|
|
258 | - |
|
259 | - auto id = FaceID(fontIndex, faceIndex, index);
|
|
260 | - |
|
261 | - // search triplet (fontIndex, faceIndex, 0)
|
|
262 | - FTC_FaceID ftcFaceID = reinterpret_cast<FTC_FaceID>(faceIDMap_.value(id));
|
|
263 | - if (ftcFaceID)
|
|
264 | - {
|
|
265 | - // found
|
|
266 | - if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
|
|
267 | - name = QString("%1 %2")
|
|
268 | - .arg(face->family_name)
|
|
269 | - .arg(face->style_name);
|
|
270 | - }
|
|
271 | - else
|
|
272 | - {
|
|
273 | - // not found; try to load triplet (fontIndex, faceIndex, 0)
|
|
274 | - ftcFaceID = reinterpret_cast<FTC_FaceID>(faceCounter_);
|
|
275 | - faceIDMap_.insert(id, faceCounter_++);
|
|
276 | - |
|
277 | - if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
|
|
278 | - name = QString("%1 %2")
|
|
279 | - .arg(face->family_name)
|
|
280 | - .arg(face->style_name);
|
|
281 | - else
|
|
282 | - {
|
|
283 | - faceIDMap_.remove(id);
|
|
284 | - faceCounter_--;
|
|
285 | - }
|
|
286 | - }
|
|
248 | + return {};
|
|
287 | 249 | |
250 | + QString name;
|
|
251 | + withFace(FaceID(fontIndex, faceIndex, index),
|
|
252 | + [&](FT_Face face) {
|
|
253 | + name = QString("%1 %2")
|
|
254 | + .arg(face->family_name)
|
|
255 | + .arg(face->style_name);
|
|
256 | + });
|
|
288 | 257 | return name;
|
289 | 258 | }
|
290 | 259 | |
... | ... | @@ -322,6 +291,9 @@ Engine::loadFont(int fontIndex, |
322 | 291 | }
|
323 | 292 | else if (fontIndex >= 0)
|
324 | 293 | {
|
294 | + if (faceCounter_ >= INT_MAX) // prevent overflowing
|
|
295 | + return -1;
|
|
296 | + |
|
325 | 297 | // not found; try to load triplet
|
326 | 298 | // (fontIndex, faceIndex, namedInstanceIndex)
|
327 | 299 | scaler_.face_id = reinterpret_cast<FTC_FaceID>(faceCounter_);
|
... | ... | @@ -409,7 +381,7 @@ Engine::removeFont(int fontIndex, bool closeFile) |
409 | 381 | QMap<FaceID, FTC_IDType>::iterator iter
|
410 | 382 | = faceIDMap_.lowerBound(FaceID(fontIndex, 0, 0));
|
411 | 383 | |
412 | - for (;;)
|
|
384 | + while (true)
|
|
413 | 385 | {
|
414 | 386 | if (iter == faceIDMap_.end())
|
415 | 387 | break;
|
... | ... | @@ -418,7 +390,7 @@ Engine::removeFont(int fontIndex, bool closeFile) |
418 | 390 | if (faceID.fontIndex != fontIndex)
|
419 | 391 | break;
|
420 | 392 | |
421 | - FTC_FaceID ftcFaceID = reinterpret_cast<FTC_FaceID>(iter.value());
|
|
393 | + auto ftcFaceID = reinterpret_cast<FTC_FaceID>(iter.value());
|
|
422 | 394 | FTC_Manager_RemoveFaceID(cacheManager_, ftcFaceID);
|
423 | 395 | |
424 | 396 | iter = faceIDMap_.erase(iter);
|
... | ... | @@ -491,7 +463,7 @@ Engine::glyphName(int index) |
491 | 463 | |
492 | 464 | if (!ftSize_)
|
493 | 465 | return "";
|
494 | - |
|
466 | +
|
|
495 | 467 | if (!FTC_Manager_LookupSize(cacheManager_, &scaler_, &ftSize_))
|
496 | 468 | return name;
|
497 | 469 | |
... | ... | @@ -854,6 +826,7 @@ Engine::loadPaletteInfos() |
854 | 826 | return;
|
855 | 827 | }
|
856 | 828 | |
829 | + // size never exceeds max val of ushort.
|
|
857 | 830 | curPaletteInfos_.reserve(paletteData_.num_palettes);
|
858 | 831 | for (int i = 0; i < paletteData_.num_palettes; ++i)
|
859 | 832 | curPaletteInfos_.emplace_back(ftSize_->face, paletteData_, i);
|
... | ... | @@ -886,9 +859,12 @@ Engine::convertBitmapToQImage(FT_Bitmap* src) |
886 | 859 | auto& bmap = *src;
|
887 | 860 | bool ownBitmap = false;
|
888 | 861 | |
889 | - int width = bmap.width;
|
|
890 | - int height = bmap.rows;
|
|
891 | - QImage::Format format = QImage::Format_Indexed8; // goto crossing init
|
|
862 | + int width = INT_MAX, height = INT_MAX;
|
|
863 | + if (bmap.width < INT_MAX)
|
|
864 | + width = static_cast<int>(bmap.width);
|
|
865 | + if (bmap.rows < INT_MAX)
|
|
866 | + height = static_cast<int>(bmap.rows);
|
|
867 | + auto format = QImage::Format_Indexed8; // goto crossing init
|
|
892 | 868 | |
893 | 869 | if (bmap.pixel_mode == FT_PIXEL_MODE_GRAY2
|
894 | 870 | || bmap.pixel_mode == FT_PIXEL_MODE_GRAY4)
|
... | ... | @@ -981,8 +957,15 @@ Engine::convertGlyphToQImage(FT_Glyph src, |
981 | 957 | outRect->setTop(-bitmapGlyph->top);
|
982 | 958 | else
|
983 | 959 | outRect->setTop(bitmapGlyph->top);
|
984 | - outRect->setWidth(bitmapGlyph->bitmap.width);
|
|
985 | - outRect->setHeight(bitmapGlyph->bitmap.rows);
|
|
960 | + if (bitmapGlyph->bitmap.width < INT_MAX)
|
|
961 | + outRect->setWidth(static_cast<int>(bitmapGlyph->bitmap.width));
|
|
962 | + else
|
|
963 | + outRect->setWidth(INT_MAX);
|
|
964 | + |
|
965 | + if (bitmapGlyph->bitmap.rows < INT_MAX)
|
|
966 | + outRect->setHeight(static_cast<int>(bitmapGlyph->bitmap.rows));
|
|
967 | + else
|
|
968 | + outRect->setHeight(INT_MAX);
|
|
986 | 969 | }
|
987 | 970 | |
988 | 971 | if (ownBitmapGlyph)
|
... | ... | @@ -1006,8 +989,8 @@ Engine::computeGlyphOffset(FT_Glyph glyph, bool inverseY) |
1006 | 989 | cbox.yMax = (cbox.yMax + 63) & ~63;
|
1007 | 990 | if (inverseY)
|
1008 | 991 | cbox.yMax = -cbox.yMax;
|
1009 | - return { static_cast<int>(cbox.xMin) / 64,
|
|
1010 | - static_cast<int>(cbox.yMax / 64) };
|
|
992 | + return { static_cast<int>(cbox.xMin / 64),
|
|
993 | + static_cast<int>(cbox.yMax / 64) };
|
|
1011 | 994 | }
|
1012 | 995 | if (glyph->format == FT_GLYPH_FORMAT_BITMAP)
|
1013 | 996 | {
|
... | ... | @@ -1136,11 +1119,11 @@ Engine::tryDirectRenderColorLayers(int glyphIndex, |
1136 | 1119 | auto img = convertBitmapToQImage(&bitmap);
|
1137 | 1120 | if (outRect)
|
1138 | 1121 | {
|
1139 | - outRect->moveLeft(bitmapOffset.x >> 6);
|
|
1122 | + outRect->moveLeft(static_cast<int>(bitmapOffset.x >> 6));
|
|
1140 | 1123 | if (inverseRectY)
|
1141 | - outRect->moveTop(-bitmapOffset.y >> 6);
|
|
1124 | + outRect->moveTop(static_cast<int>(-bitmapOffset.y >> 6));
|
|
1142 | 1125 | else
|
1143 | - outRect->moveTop(bitmapOffset.y >> 6);
|
|
1126 | + outRect->moveTop(static_cast<int>(bitmapOffset.y >> 6));
|
|
1144 | 1127 | outRect->setSize(img->size());
|
1145 | 1128 | }
|
1146 | 1129 |
... | ... | @@ -254,6 +254,10 @@ private: |
254 | 254 | void queryEngine();
|
255 | 255 | void loadPaletteInfos();
|
256 | 256 | |
257 | + // Safe to put the impl to the cpp.
|
|
258 | + template <class Func>
|
|
259 | + void withFace(FaceID id, Func func);
|
|
260 | + |
|
257 | 261 | public:
|
258 | 262 | |
259 | 263 | /// Actual definition
|
... | ... | @@ -50,6 +50,8 @@ FontFileManager::append(QStringList newFileNames) |
50 | 50 | if (existing)
|
51 | 51 | continue;
|
52 | 52 | |
53 | + if (info.size() >= INT_MAX)
|
|
54 | + return; // Prevent overflowing
|
|
53 | 55 | fontFileNameList_.append(info);
|
54 | 56 | }
|
55 | 57 | }
|
... | ... | @@ -8,7 +8,6 @@ |
8 | 8 | |
9 | 9 | #include <cmath>
|
10 | 10 | |
11 | - |
|
12 | 11 | StringRenderer::StringRenderer(Engine* engine)
|
13 | 12 | : engine_(engine)
|
14 | 13 | {
|
... | ... | @@ -25,9 +24,9 @@ void |
25 | 24 | StringRenderer::setCharMapIndex(int charMapIndex,
|
26 | 25 | int limitIndex)
|
27 | 26 | {
|
28 | - auto& charmaps = engine_->currentFontCharMaps();
|
|
27 | + auto& charMaps = engine_->currentFontCharMaps();
|
|
29 | 28 | if (charMapIndex < 0
|
30 | - || static_cast<uint>(charMapIndex) >= charmaps.size())
|
|
29 | + || static_cast<unsigned>(charMapIndex) >= charMaps.size())
|
|
31 | 30 | charMapIndex = -1;
|
32 | 31 | |
33 | 32 | charMapIndex_ = charMapIndex;
|
... | ... | @@ -87,6 +86,7 @@ StringRenderer::reloadAll() |
87 | 86 | reloadGlyphIndices();
|
88 | 87 | }
|
89 | 88 | |
89 | + |
|
90 | 90 | void
|
91 | 91 | StringRenderer::reloadGlyphs()
|
92 | 92 | {
|
... | ... | @@ -108,7 +108,7 @@ StringRenderer::setUseString(QString const& string) |
108 | 108 | it.charCode = static_cast<int>(ch);
|
109 | 109 | it.glyphIndex = 0;
|
110 | 110 | ++totalCount;
|
111 | - if (totalCount >= INT_MAX)
|
|
111 | + if (totalCount >= INT_MAX) // Prevent overflow
|
|
112 | 112 | break;
|
113 | 113 | }
|
114 | 114 | reloadGlyphIndices();
|
... | ... | @@ -130,10 +130,10 @@ StringRenderer::reloadGlyphIndices() |
130 | 130 | if (!usingString_)
|
131 | 131 | return;
|
132 | 132 | int charMapIndex = charMapIndex_;
|
133 | - auto& charmaps = engine_->currentFontCharMaps();
|
|
133 | + auto& charMaps = engine_->currentFontCharMaps();
|
|
134 | 134 | if (charMapIndex < 0
|
135 | - || static_cast<uint>(charMapIndex) >= charmaps.size()
|
|
136 | - || charmaps[charMapIndex].encoding != FT_ENCODING_UNICODE)
|
|
135 | + || static_cast<unsigned>(charMapIndex) >= charMaps.size()
|
|
136 | + || charMaps[charMapIndex].encoding != FT_ENCODING_UNICODE)
|
|
137 | 137 | charMapIndex = engine_->currentFontFirstUnicodeCharMap();
|
138 | 138 | |
139 | 139 | if (charMapIndex < 0)
|
... | ... | @@ -371,7 +371,7 @@ StringRenderer::render(int width, |
371 | 371 | while (true)
|
372 | 372 | {
|
373 | 373 | ptSize += step;
|
374 | - engine_->setSizeByPoint(ptSize / 64);
|
|
374 | + engine_->setSizeByPoint(ptSize / 64.0);
|
|
375 | 375 | clearActive(true);
|
376 | 376 | prepareRendering(); // set size/face for engine, so metrics are valid
|
377 | 377 | auto& metrics = engine_->currentFontMetrics();
|
... | ... | @@ -380,9 +380,8 @@ StringRenderer::render(int width, |
380 | 380 | {
|
381 | 381 | // TODO draw a blue line
|
382 | 382 | }
|
383 | - |
|
384 | - engine_->setSizeByPoint(ptSize / 64);
|
|
385 | - y += (metrics.height >> 6) + 1;
|
|
383 | +
|
|
384 | + y += static_cast<int>(metrics.height >> 6) + 1;
|
|
386 | 385 | |
387 | 386 | if (y >= height)
|
388 | 387 | break;
|
... | ... | @@ -393,12 +392,12 @@ StringRenderer::render(int width, |
393 | 392 | }
|
394 | 393 | |
395 | 394 | loadStringGlyphs();
|
396 | - auto lcount = renderLine(x, y + (metrics.descender >> 6),
|
|
397 | - width, height,
|
|
398 | - offset);
|
|
395 | + auto lcount = renderLine(x, y + static_cast<int>(metrics.descender >> 6),
|
|
396 | + width, height,
|
|
397 | + offset);
|
|
399 | 398 | count = std::max(count, lcount);
|
400 | 399 | }
|
401 | - engine_->setSizeByPoint(originalSize / 64);
|
|
400 | + engine_->setSizeByPoint(originalSize / 64.0);
|
|
402 | 401 | |
403 | 402 | return count;
|
404 | 403 | }
|
... | ... | @@ -409,9 +408,9 @@ StringRenderer::render(int width, |
409 | 408 | |
410 | 409 | prepareRendering();
|
411 | 410 | auto& metrics = engine_->currentFontMetrics();
|
412 | - auto y = 4 + (metrics.ascender >> 6);
|
|
413 | - auto stepY = (metrics.height >> 6) + 1;
|
|
414 | - auto limitY = height + (metrics.descender >> 6);
|
|
411 | + auto y = 4 + static_cast<int>(metrics.ascender >> 6);
|
|
412 | + auto stepY = static_cast<int>(metrics.height >> 6) + 1;
|
|
413 | + auto limitY = height + static_cast<int>(metrics.descender >> 6);
|
|
415 | 414 | |
416 | 415 | // Only care about multiline when in string mode
|
417 | 416 | for (; y < limitY; y += stepY)
|
... | ... | @@ -430,8 +429,8 @@ StringRenderer::render(int width, |
430 | 429 | auto x = static_cast<int>(width * position_);
|
431 | 430 | // Anchor at top-left in vertical mode, at the center in horizontal mode
|
432 | 431 | auto y = vertical_ ? 0 : (height / 2);
|
433 | - auto stepY = (metrics.height >> 6) + 1;
|
|
434 | - y += 4 + (metrics.ascender >> 6);
|
|
432 | + auto stepY = static_cast<int>(metrics.height >> 6) + 1;
|
|
433 | + y += 4 + static_cast<int>(metrics.ascender >> 6);
|
|
435 | 434 | |
436 | 435 | while (offset < static_cast<int>(activeGlyphs_.size()))
|
437 | 436 | {
|
... | ... | @@ -542,8 +541,8 @@ StringRenderer::renderLine(int x, |
542 | 541 | |
543 | 542 | if (vertical_)
|
544 | 543 | {
|
545 | - bitmap->left += (ctx.vvector.x) >> 6;
|
|
546 | - bitmap->top += (ctx.vvector.y) >> 6;
|
|
544 | + bitmap->left += static_cast<int>(ctx.vvector.x) >> 6;
|
|
545 | + bitmap->top += static_cast<int>(ctx.vvector.y) >> 6;
|
|
547 | 546 | }
|
548 | 547 | }
|
549 | 548 |
... | ... | @@ -137,9 +137,7 @@ MainGUI::loadFonts() |
137 | 137 | void
|
138 | 138 | MainGUI::openFonts(QStringList const& fileNames)
|
139 | 139 | {
|
140 | - int oldSize = engine_->numberOfOpenedFonts();
|
|
141 | 140 | engine_->openFonts(fileNames);
|
142 | - |
|
143 | 141 | tripletSelector_->repopulateFonts();
|
144 | 142 | }
|
145 | 143 |
... | ... | @@ -123,12 +123,10 @@ int |
123 | 123 | HintingModeComboBoxModel::valueToIndexForType(int value,
|
124 | 124 | HintingEngineType type) const
|
125 | 125 | {
|
126 | - for (auto it = items_.begin();
|
|
127 | - it != items_.end();
|
|
128 | - ++it)
|
|
126 | + for (const auto& item : items_)
|
|
129 | 127 | {
|
130 | - if (it->type == type && it->value == value)
|
|
131 | - return it->key;
|
|
128 | + if (item.type == type && item.value == value)
|
|
129 | + return item.key;
|
|
132 | 130 | }
|
133 | 131 | return -1;
|
134 | 132 | }
|
... | ... | @@ -166,16 +164,14 @@ void |
166 | 164 | HintingModeComboBoxModel::setSupportedModes(QList<int> supportedTTIVersions,
|
167 | 165 | QList<int> supportedCFFModes)
|
168 | 166 | {
|
169 | - for (auto it = items_.begin();
|
|
170 | - it != items_.end();
|
|
171 | - ++it)
|
|
167 | + for (auto& item : items_)
|
|
172 | 168 | {
|
173 | - if (it->type == HintingEngineType_TrueType)
|
|
174 | - it->supported = supportedTTIVersions.contains(it->value);
|
|
175 | - else if (it->type == HintingEngineType_CFF)
|
|
176 | - it->supported = supportedCFFModes.contains(it->value);
|
|
169 | + if (item.type == HintingEngineType_TrueType)
|
|
170 | + item.supported = supportedTTIVersions.contains(item.value);
|
|
171 | + else if (item.type == HintingEngineType_CFF)
|
|
172 | + item.supported = supportedCFFModes.contains(item.value);
|
|
177 | 173 | else
|
178 | - it->supported = false;
|
|
174 | + item.supported = false;
|
|
179 | 175 | }
|
180 | 176 | }
|
181 | 177 | |
... | ... | @@ -183,10 +179,8 @@ HintingModeComboBoxModel::setSupportedModes(QList<int> supportedTTIVersions, |
183 | 179 | void
|
184 | 180 | HintingModeComboBoxModel::setCurrentEngineType(HintingEngineType type)
|
185 | 181 | {
|
186 | - for (auto it = items_.begin();
|
|
187 | - it != items_.end();
|
|
188 | - ++it)
|
|
189 | - it->enabled = it->supported && it->type == type;
|
|
182 | + for (auto& item : items_)
|
|
183 | + item.enabled = item.supported && item.type == type;
|
|
190 | 184 | }
|
191 | 185 | |
192 | 186 |
... | ... | @@ -86,10 +86,11 @@ SettingPanel::populatePalettes() |
86 | 86 | {
|
87 | 87 | auto needToReload = false;
|
88 | 88 | auto& newPalettes = engine_->currentFontPalettes();
|
89 | - if (newPalettes.size() != paletteComboBox_->count())
|
|
89 | + auto newSize = static_cast<int>(newPalettes.size()); // this never exceeds!
|
|
90 | + if (newSize != paletteComboBox_->count())
|
|
90 | 91 | needToReload = true;
|
91 | 92 | else
|
92 | - for (int i = 0; i < newPalettes.size(); ++i)
|
|
93 | + for (int i = 0; i < newSize; ++i)
|
|
93 | 94 | {
|
94 | 95 | auto oldNameVariant = paletteComboBox_->itemData(i);
|
95 | 96 | if (!oldNameVariant.canConvert<QString>())
|
... | ... | @@ -109,7 +110,7 @@ SettingPanel::populatePalettes() |
109 | 110 | {
|
110 | 111 | QSignalBlocker blocker(paletteComboBox_);
|
111 | 112 | paletteComboBox_->clear();
|
112 | - for (int i = 0; i < newPalettes.size(); ++i)
|
|
113 | + for (int i = 0; i < newSize; ++i)
|
|
113 | 114 | paletteComboBox_->addItem(
|
114 | 115 | QString("%1: %2")
|
115 | 116 | .arg(i)
|
... | ... | @@ -73,6 +73,7 @@ GlyphContinuous::setSource(Source source) |
73 | 73 | |
74 | 74 | case SRC_TextStringRepeated:
|
75 | 75 | positionDelta_ = {};
|
76 | + /* fall through */
|
|
76 | 77 | case SRC_TextString:
|
77 | 78 | updateRendererText();
|
78 | 79 | break;
|
... | ... | @@ -418,22 +419,9 @@ GlyphContinuous::saveSingleGlyph(FT_Glyph glyph, |
418 | 419 | if (!currentWritingLine_)
|
419 | 420 | return;
|
420 | 421 | |
421 | - currentWritingLine_->entries.emplace_back();
|
|
422 | - auto& entry = currentWritingLine_->entries.back();
|
|
423 | - |
|
424 | 422 | QRect rect;
|
425 | 423 | QImage* image = engine_->convertGlyphToQImage(glyph, &rect, true);
|
426 | - rect.translate(penPos.x, penPos.y);
|
|
427 | - //rect.moveTop(height() - rect.top()); // TODO Don't place this here...
|
|
428 | - |
|
429 | - entry.image = image;
|
|
430 | - entry.basePosition = rect;
|
|
431 | - entry.charCode = gctx.charCode;
|
|
432 | - entry.glyphIndex = gctx.glyphIndex;
|
|
433 | - entry.advance = glyph->advance;
|
|
434 | - entry.penPos = { penPos.x, penPos.y };
|
|
435 | - |
|
436 | - // todo more info
|
|
424 | + saveSingleGlyphImage(image, rect, penPos, glyph->advance, gctx);
|
|
437 | 425 | }
|
438 | 426 | |
439 | 427 | |
... | ... | @@ -450,14 +438,17 @@ GlyphContinuous::saveSingleGlyphImage(QImage* image, |
450 | 438 | currentWritingLine_->entries.emplace_back();
|
451 | 439 | auto& entry = currentWritingLine_->entries.back();
|
452 | 440 | |
453 | - rect.translate(penPos.x, penPos.y);
|
|
441 | + QPoint penPosPoint = { static_cast<int>(penPos.x),
|
|
442 | + static_cast<int>(penPos.y) };
|
|
443 | + |
|
444 | + rect.translate(penPosPoint);
|
|
454 | 445 | |
455 | 446 | entry.image = image;
|
456 | 447 | entry.basePosition = rect;
|
457 | 448 | entry.charCode = gctx.charCode;
|
458 | 449 | entry.glyphIndex = gctx.glyphIndex;
|
459 | 450 | entry.advance = advance;
|
460 | - entry.penPos = { penPos.x, penPos.y };
|
|
451 | + entry.penPos = penPosPoint;
|
|
461 | 452 | }
|
462 | 453 | |
463 | 454 |