qfontengine.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/text/qfontengine.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
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 http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include <qdebug.h>-
35#include <private/qfontengine_p.h>-
36#include <private/qfontengineglyphcache_p.h>-
37#include <private/qguiapplication_p.h>-
38-
39#include <qpa/qplatformfontdatabase.h>-
40#include <qpa/qplatformintegration.h>-
41-
42#include "qbitmap.h"-
43#include "qpainter.h"-
44#include "qpainterpath.h"-
45#include "qvarlengtharray.h"-
46#include <qmath.h>-
47#include <qendian.h>-
48#include <private/qstringiterator_p.h>-
49-
50#ifdef QT_ENABLE_HARFBUZZ_NG-
51# include "qharfbuzzng_p.h"-
52# include <harfbuzz/hb-ot.h>-
53#endif-
54#include <private/qharfbuzz_p.h>-
55-
56#include <algorithm>-
57#include <limits.h>-
58-
59QT_BEGIN_NAMESPACE-
60-
61static inline bool qtransform_equals_no_translate(const QTransform &a, const QTransform &b)-
62{-
63 if (a.type() <= QTransform::TxTranslate && b.type() <= QTransform::TxTranslate) {
a.type() <= QT...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
b.type() <= QT...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
64 return true;
never executed: return true;
0
65 } else {-
66 // We always use paths for perspective text anyway, so no-
67 // point in checking the full matrix...-
68 Q_ASSERT(a.type() < QTransform::TxProject);-
69 Q_ASSERT(b.type() < QTransform::TxProject);-
70-
71 return a.m11() == b.m11()
never executed: return a.m11() == b.m11() && a.m12() == b.m12() && a.m21() == b.m21() && a.m22() == b.m22();
a.m11() == b.m11()Description
TRUEnever evaluated
FALSEnever evaluated
0
72 && a.m12() == b.m12()
never executed: return a.m11() == b.m11() && a.m12() == b.m12() && a.m21() == b.m21() && a.m22() == b.m22();
a.m12() == b.m12()Description
TRUEnever evaluated
FALSEnever evaluated
0
73 && a.m21() == b.m21()
never executed: return a.m11() == b.m11() && a.m12() == b.m12() && a.m21() == b.m21() && a.m22() == b.m22();
a.m21() == b.m21()Description
TRUEnever evaluated
FALSEnever evaluated
0
74 && a.m22() == b.m22();
never executed: return a.m11() == b.m11() && a.m12() == b.m12() && a.m21() == b.m21() && a.m22() == b.m22();
a.m22() == b.m22()Description
TRUEnever evaluated
FALSEnever evaluated
0
75 }-
76}-
77-
78template<typename T>-
79static inline bool qSafeFromBigEndian(const uchar *source, const uchar *end, T *output)-
80{-
81 if (source + sizeof(T) > end)
source + sizeof(T) > endDescription
TRUEnever evaluated
FALSEnever evaluated
0
82 return false;
never executed: return false;
0
83-
84 *output = qFromBigEndian<T>(source);-
85 return true;
never executed: return true;
0
86}-
87-
88// Harfbuzz helper functions-
89-
90#ifdef QT_ENABLE_HARFBUZZ_NG-
91Q_GLOBAL_STATIC_WITH_ARGS(bool, useHarfbuzzNG,(qgetenv("QT_HARFBUZZ") != "old"))
never executed: end of block
never executed: guard.store(QtGlobalStatic::Destroyed);
never executed: return &holder.value;
guard.load() =...c::InitializedDescription
TRUEnever evaluated
FALSEnever evaluated
0
92-
93bool qt_useHarfbuzzNG()-
94{-
95 return *useHarfbuzzNG();
never executed: return *useHarfbuzzNG();
0
96}-
97#endif-
98-
99Q_STATIC_ASSERT(sizeof(HB_Glyph) == sizeof(glyph_t));-
100Q_STATIC_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed));-
101-
102static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft)-
103{-
104 QFontEngine *fe = (QFontEngine *)font->userData;-
105-
106 const QChar *str = reinterpret_cast<const QChar *>(string);-
107-
108 QGlyphLayout qglyphs;-
109 qglyphs.numGlyphs = *numGlyphs;-
110 qglyphs.glyphs = glyphs;-
111 int nGlyphs = *numGlyphs;-
112 bool result = fe->stringToCMap(str, length, &qglyphs, &nGlyphs, QFontEngine::GlyphIndicesOnly);-
113 *numGlyphs = nGlyphs;-
114-
115 if (rightToLeft && result && !fe->symbol) {
rightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
resultDescription
TRUEnever evaluated
FALSEnever evaluated
!fe->symbolDescription
TRUEnever evaluated
FALSEnever evaluated
0
116 QStringIterator it(str, str + length);-
117 while (it.hasNext()) {
it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
118 const uint ucs4 = it.next();-
119 const uint mirrored = QChar::mirroredChar(ucs4);-
120 if (Q_UNLIKELY(mirrored != ucs4))
__builtin_expe... ucs4), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
121 *glyphs = fe->glyphIndex(mirrored);
never executed: *glyphs = fe->glyphIndex(mirrored);
0
122 ++glyphs;-
123 }
never executed: end of block
0
124 }
never executed: end of block
0
125-
126 return result;
never executed: return result;
0
127}-
128-
129static void hb_getAdvances(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGlyphs, HB_Fixed *advances, int flags)-
130{-
131 QFontEngine *fe = (QFontEngine *)font->userData;-
132-
133 QGlyphLayout qglyphs;-
134 qglyphs.numGlyphs = numGlyphs;-
135 qglyphs.glyphs = const_cast<glyph_t *>(glyphs);-
136 qglyphs.advances = reinterpret_cast<QFixed *>(advances);-
137-
138 fe->recalcAdvances(&qglyphs, (flags & HB_ShaperFlag_UseDesignMetrics) ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlags(0));-
139}
never executed: end of block
0
140-
141static HB_Bool hb_canRender(HB_Font font, const HB_UChar16 *string, hb_uint32 length)-
142{-
143 QFontEngine *fe = (QFontEngine *)font->userData;-
144 return fe->canRender(reinterpret_cast<const QChar *>(string), length);
never executed: return fe->canRender(reinterpret_cast<const QChar *>(string), length);
0
145}-
146-
147static void hb_getGlyphMetrics(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics)-
148{-
149 QFontEngine *fe = (QFontEngine *)font->userData;-
150 glyph_metrics_t m = fe->boundingBox(glyph);-
151 metrics->x = m.x.value();-
152 metrics->y = m.y.value();-
153 metrics->width = m.width.value();-
154 metrics->height = m.height.value();-
155 metrics->xOffset = m.xoff.value();-
156 metrics->yOffset = m.yoff.value();-
157}
never executed: end of block
0
158-
159static HB_Fixed hb_getFontMetric(HB_Font font, HB_FontMetric metric)-
160{-
161 if (metric == HB_FontAscent) {
metric == HB_FontAscentDescription
TRUEnever evaluated
FALSEnever evaluated
0
162 QFontEngine *fe = (QFontEngine *)font->userData;-
163 return fe->ascent().value();
never executed: return fe->ascent().value();
0
164 }-
165 return 0;
never executed: return 0;
0
166}-
167-
168int QFontEngine::getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints)-
169{-
170 Q_UNUSED(glyph)-
171 Q_UNUSED(flags)-
172 Q_UNUSED(point)-
173 Q_UNUSED(xpos)-
174 Q_UNUSED(ypos)-
175 Q_UNUSED(nPoints)-
176 return Err_Not_Covered;
never executed: return Err_Not_Covered;
0
177}-
178-
179static HB_Error hb_getPointInOutline(HB_Font font, HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)-
180{-
181 QFontEngine *fe = (QFontEngine *)font->userData;-
182 return (HB_Error)fe->getPointInOutline(glyph, flags, point, (QFixed *)xpos, (QFixed *)ypos, (quint32 *)nPoints);
never executed: return (HB_Error)fe->getPointInOutline(glyph, flags, point, (QFixed *)xpos, (QFixed *)ypos, (quint32 *)nPoints);
0
183}-
184-
185static const HB_FontClass hb_fontClass = {-
186 hb_stringToGlyphs, hb_getAdvances, hb_canRender, hb_getPointInOutline,-
187 hb_getGlyphMetrics, hb_getFontMetric-
188};-
189-
190static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length)-
191{-
192 QFontEngine::FaceData *data = (QFontEngine::FaceData *)font;-
193 Q_ASSERT(data);-
194-
195 qt_get_font_table_func_t get_font_table = data->get_font_table;-
196 Q_ASSERT(get_font_table);-
197-
198 if (!get_font_table(data->user_data, tableTag, buffer, length))
!get_font_tabl...uffer, length)Description
TRUEnever evaluated
FALSEnever evaluated
0
199 return HB_Err_Invalid_Argument;
never executed: return HB_Err_Invalid_Argument;
0
200 return HB_Err_Ok;
never executed: return HB_Err_Ok;
0
201}-
202-
203static void hb_freeFace(void *face)-
204{-
205 qHBFreeFace((HB_Face)face);-
206}
never executed: end of block
0
207-
208-
209static bool qt_get_font_table_default(void *user_data, uint tag, uchar *buffer, uint *length)-
210{-
211 QFontEngine *fe = (QFontEngine *)user_data;-
212 return fe->getSfntTableData(tag, buffer, length);
never executed: return fe->getSfntTableData(tag, buffer, length);
0
213}-
214-
215-
216#ifdef QT_BUILD_INTERNAL-
217// for testing purpose only, not thread-safe!-
218static QList<QFontEngine *> *enginesCollector = 0;-
219-
220Q_AUTOTEST_EXPORT void QFontEngine_startCollectingEngines()-
221{-
222 delete enginesCollector;-
223 enginesCollector = new QList<QFontEngine *>();-
224}
never executed: end of block
0
225-
226Q_AUTOTEST_EXPORT QList<QFontEngine *> QFontEngine_stopCollectingEngines()-
227{-
228 Q_ASSERT(enginesCollector);-
229 QList<QFontEngine *> ret = *enginesCollector;-
230 delete enginesCollector;-
231 enginesCollector = 0;-
232 return ret;
never executed: return ret;
0
233}-
234#endif // QT_BUILD_INTERNAL-
235-
236-
237// QFontEngine-
238-
239#define kBearingNotInitialized std::numeric_limits<qreal>::max()-
240-
241QFontEngine::QFontEngine(Type type)-
242 : m_type(type), ref(0),-
243 font_(0), font_destroy_func(0),-
244 face_(0), face_destroy_func(0),-
245 m_minLeftBearing(kBearingNotInitialized),-
246 m_minRightBearing(kBearingNotInitialized)-
247{-
248 faceData.user_data = this;-
249 faceData.get_font_table = qt_get_font_table_default;-
250-
251 cache_cost = 0;-
252 fsType = 0;-
253 symbol = false;-
254 isSmoothlyScalable = false;-
255-
256 glyphFormat = Format_None;-
257 m_subPixelPositionCount = 0;-
258-
259#ifdef QT_BUILD_INTERNAL-
260 if (enginesCollector)
enginesCollectorDescription
TRUEnever evaluated
FALSEnever evaluated
0
261 enginesCollector->append(this);
never executed: enginesCollector->append(this);
0
262#endif-
263}
never executed: end of block
0
264-
265QFontEngine::~QFontEngine()-
266{-
267 m_glyphCaches.clear();-
268-
269 if (font_ && font_destroy_func) {
font_Description
TRUEnever evaluated
FALSEnever evaluated
font_destroy_funcDescription
TRUEnever evaluated
FALSEnever evaluated
0
270 font_destroy_func(font_);-
271 font_ = 0;-
272 }
never executed: end of block
0
273 if (face_ && face_destroy_func) {
face_Description
TRUEnever evaluated
FALSEnever evaluated
face_destroy_funcDescription
TRUEnever evaluated
FALSEnever evaluated
0
274 face_destroy_func(face_);-
275 face_ = 0;-
276 }
never executed: end of block
0
277-
278#ifdef QT_BUILD_INTERNAL-
279 if (enginesCollector)
enginesCollectorDescription
TRUEnever evaluated
FALSEnever evaluated
0
280 enginesCollector->removeOne(this);
never executed: enginesCollector->removeOne(this);
0
281#endif-
282}
never executed: end of block
0
283-
284QFixed QFontEngine::lineThickness() const-
285{-
286 // ad hoc algorithm-
287 int score = fontDef.weight * fontDef.pixelSize;-
288 int lw = score / 700;-
289-
290 // looks better with thicker line for small pointsizes-
291 if (lw < 2 && score >= 1050) lw = 2;
never executed: lw = 2;
lw < 2Description
TRUEnever evaluated
FALSEnever evaluated
score >= 1050Description
TRUEnever evaluated
FALSEnever evaluated
0
292 if (lw == 0) lw = 1;
never executed: lw = 1;
lw == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
293-
294 return lw;
never executed: return lw;
0
295}-
296-
297QFixed QFontEngine::underlinePosition() const-
298{-
299 return ((lineThickness() * 2) + 3) / 6;
never executed: return ((lineThickness() * 2) + 3) / 6;
0
300}-
301-
302void *QFontEngine::harfbuzzFont() const-
303{-
304 Q_ASSERT(type() != QFontEngine::Multi);-
305#ifdef QT_ENABLE_HARFBUZZ_NG-
306 if (qt_useHarfbuzzNG())
qt_useHarfbuzzNG()Description
TRUEnever evaluated
FALSEnever evaluated
0
307 return hb_qt_font_get_for_engine(const_cast<QFontEngine *>(this));
never executed: return hb_qt_font_get_for_engine(const_cast<QFontEngine *>(this));
0
308#endif-
309 if (!font_) {
!font_Description
TRUEnever evaluated
FALSEnever evaluated
0
310 HB_Face hbFace = (HB_Face)harfbuzzFace();-
311 if (hbFace->font_for_init) {
hbFace->font_for_initDescription
TRUEnever evaluated
FALSEnever evaluated
0
312 void *data = hbFace->font_for_init;-
313 q_check_ptr(qHBLoadFace(hbFace));-
314 free(data);-
315 }
never executed: end of block
0
316-
317 HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec));-
318 Q_CHECK_PTR(hbFont);
never executed: qt_check_pointer(__FILE__,318);
!(hbFont)Description
TRUEnever evaluated
FALSEnever evaluated
0
319 hbFont->klass = &hb_fontClass;-
320 hbFont->userData = const_cast<QFontEngine *>(this);-
321-
322 qint64 emSquare = emSquareSize().truncate();-
323 Q_ASSERT(emSquare == emSquareSize().toInt()); // ensure no truncation-
324 if (emSquare == 0)
emSquare == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
325 emSquare = 1000; // a fallback value suitable for Type1 fonts
never executed: emSquare = 1000;
0
326 hbFont->y_ppem = fontDef.pixelSize;-
327 hbFont->x_ppem = fontDef.pixelSize * fontDef.stretch / 100;-
328 // same as QFixed(x)/QFixed(emSquare) but without int32 overflow for x-
329 hbFont->x_scale = (((qint64)hbFont->x_ppem << 6) * 0x10000L + (emSquare >> 1)) / emSquare;-
330 hbFont->y_scale = (((qint64)hbFont->y_ppem << 6) * 0x10000L + (emSquare >> 1)) / emSquare;-
331-
332 font_ = (void *)hbFont;-
333 font_destroy_func = free;-
334 }
never executed: end of block
0
335 return font_;
never executed: return font_;
0
336}-
337-
338void *QFontEngine::harfbuzzFace() const-
339{-
340 Q_ASSERT(type() != QFontEngine::Multi);-
341#ifdef QT_ENABLE_HARFBUZZ_NG-
342 if (qt_useHarfbuzzNG())
qt_useHarfbuzzNG()Description
TRUEnever evaluated
FALSEnever evaluated
0
343 return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this));
never executed: return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this));
0
344#endif-
345 if (!face_) {
!face_Description
TRUEnever evaluated
FALSEnever evaluated
0
346 QFontEngine::FaceData *data = (QFontEngine::FaceData *)malloc(sizeof(QFontEngine::FaceData));-
347 Q_CHECK_PTR(data);
never executed: qt_check_pointer(__FILE__,347);
!(data)Description
TRUEnever evaluated
FALSEnever evaluated
0
348 data->user_data = faceData.user_data;-
349 data->get_font_table = faceData.get_font_table;-
350-
351 HB_Face hbFace = qHBNewFace(data, hb_getSFntTable);-
352 Q_CHECK_PTR(hbFace);
never executed: qt_check_pointer(__FILE__,352);
!(hbFace)Description
TRUEnever evaluated
FALSEnever evaluated
0
353 hbFace->isSymbolFont = symbol;-
354-
355 face_ = (void *)hbFace;-
356 face_destroy_func = hb_freeFace;-
357 }
never executed: end of block
0
358 return face_;
never executed: return face_;
0
359}-
360-
361bool QFontEngine::supportsScript(QChar::Script script) const-
362{-
363 if (type() <= QFontEngine::Multi)
type() <= QFontEngine::MultiDescription
TRUEnever evaluated
FALSEnever evaluated
0
364 return true;
never executed: return true;
0
365-
366 // ### TODO: This only works for scripts that require OpenType. More generally-
367 // for scripts that do not require OpenType we should just look at the list of-
368 // supported writing systems in the font's OS/2 table.-
369 if (!((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala)
script >= QChar::Script_SyriacDescription
TRUEnever evaluated
FALSEnever evaluated
script <= QCha...Script_SinhalaDescription
TRUEnever evaluated
FALSEnever evaluated
0
370 || script == QChar::Script_Khmer || script == QChar::Script_Nko)) {
script == QChar::Script_KhmerDescription
TRUEnever evaluated
FALSEnever evaluated
script == QChar::Script_NkoDescription
TRUEnever evaluated
FALSEnever evaluated
0
371 return true;
never executed: return true;
0
372 }-
373-
374#ifdef QT_ENABLE_HARFBUZZ_NG-
375 if (qt_useHarfbuzzNG()) {
qt_useHarfbuzzNG()Description
TRUEnever evaluated
FALSEnever evaluated
0
376#if defined(Q_OS_DARWIN)-
377 // in AAT fonts, 'gsub' table is effectively replaced by 'mort'/'morx' table-
378 uint len;-
379 if (getSfntTableData(MAKE_TAG('m','o','r','t'), 0, &len) || getSfntTableData(MAKE_TAG('m','o','r','x'), 0, &len))-
380 return true;-
381#endif-
382-
383 bool ret = false;-
384 if (hb_face_t *face = hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this))) {
hb_face_t *fac...gine *>(this))Description
TRUEnever evaluated
FALSEnever evaluated
0
385 hb_tag_t script_tag_1, script_tag_2;-
386 hb_ot_tags_from_script(hb_qt_script_to_script(script), &script_tag_1, &script_tag_2);-
387-
388 unsigned int script_index;-
389 ret = hb_ot_layout_table_find_script(face, HB_OT_TAG_GSUB, script_tag_1, &script_index);-
390 if (!ret) {
!retDescription
TRUEnever evaluated
FALSEnever evaluated
0
391 ret = hb_ot_layout_table_find_script(face, HB_OT_TAG_GSUB, script_tag_2, &script_index);-
392 if (!ret && script_tag_2 != HB_OT_TAG_DEFAULT_SCRIPT)
!retDescription
TRUEnever evaluated
FALSEnever evaluated
script_tag_2 !...nt8_t)('T'))))Description
TRUEnever evaluated
FALSEnever evaluated
0
393 ret = hb_ot_layout_table_find_script(face, HB_OT_TAG_GSUB, HB_OT_TAG_DEFAULT_SCRIPT, &script_index);
never executed: ret = hb_ot_layout_table_find_script(face, ((hb_tag_t)((((uint8_t)('G'))<<24)|(((uint8_t)('S'))<<16)|(((uint8_t)('U'))<<8)|((uint8_t)('B')))), ((hb_tag_t)((((uint8_t)('D'))<<24)|(((uint8_t)('F'))<<16)|(((uint8_t)('L'))<<8)|((uint8_t)('T')))), &script_index);
0
394 }
never executed: end of block
0
395 }
never executed: end of block
0
396 return ret;
never executed: return ret;
0
397 }-
398#endif-
399 HB_Face hbFace = (HB_Face)harfbuzzFace();-
400 if (hbFace->font_for_init) {
hbFace->font_for_initDescription
TRUEnever evaluated
FALSEnever evaluated
0
401 void *data = hbFace->font_for_init;-
402 q_check_ptr(qHBLoadFace(hbFace));-
403 free(data);-
404 }
never executed: end of block
0
405 return hbFace->supported_scripts[script_to_hbscript(script)];
never executed: return hbFace->supported_scripts[script_to_hbscript(script)];
0
406}-
407-
408bool QFontEngine::canRender(const QChar *str, int len) const-
409{-
410 QStringIterator it(str, str + len);-
411 while (it.hasNext()) {
it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
412 if (glyphIndex(it.next()) == 0)
glyphIndex(it.next()) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
413 return false;
never executed: return false;
0
414 }
never executed: end of block
0
415-
416 return true;
never executed: return true;
0
417}-
418-
419glyph_metrics_t QFontEngine::boundingBox(glyph_t glyph, const QTransform &matrix)-
420{-
421 glyph_metrics_t metrics = boundingBox(glyph);-
422-
423 if (matrix.type() > QTransform::TxTranslate) {
matrix.type() ...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
424 return metrics.transformed(matrix);
never executed: return metrics.transformed(matrix);
0
425 }-
426 return metrics;
never executed: return metrics;
0
427}-
428-
429QFixed QFontEngine::xHeight() const-
430{-
431 const glyph_t glyph = glyphIndex('x');-
432 glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyph);-
433 return bb.height;
never executed: return bb.height;
0
434}-
435-
436QFixed QFontEngine::averageCharWidth() const-
437{-
438 const glyph_t glyph = glyphIndex('x');-
439 glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyph);-
440 return bb.xoff;
never executed: return bb.xoff;
0
441}-
442-
443bool QFontEngine::supportsTransformation(const QTransform &transform) const-
444{-
445 return transform.type() < QTransform::TxProject;
never executed: return transform.type() < QTransform::TxProject;
0
446}-
447-
448void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags,-
449 QVarLengthArray<glyph_t> &glyphs_out, QVarLengthArray<QFixedPoint> &positions)-
450{-
451 QFixed xpos;-
452 QFixed ypos;-
453-
454 const bool transform = matrix.m11() != 1.
matrix.m11() != 1.Description
TRUEnever evaluated
FALSEnever evaluated
0
455 || matrix.m12() != 0.
matrix.m12() != 0.Description
TRUEnever evaluated
FALSEnever evaluated
0
456 || matrix.m21() != 0.
matrix.m21() != 0.Description
TRUEnever evaluated
FALSEnever evaluated
0
457 || matrix.m22() != 1.;
matrix.m22() != 1.Description
TRUEnever evaluated
FALSEnever evaluated
0
458 if (!transform) {
!transformDescription
TRUEnever evaluated
FALSEnever evaluated
0
459 xpos = QFixed::fromReal(matrix.dx());-
460 ypos = QFixed::fromReal(matrix.dy());-
461 }
never executed: end of block
0
462-
463 int current = 0;-
464 if (flags & QTextItem::RightToLeft) {
flags & QTextItem::RightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
465 int i = glyphs.numGlyphs;-
466 int totalKashidas = 0;-
467 while(i--) {
i--Description
TRUEnever evaluated
FALSEnever evaluated
0
468 if (glyphs.attributes[i].dontPrint)
glyphs.attributes[i].dontPrintDescription
TRUEnever evaluated
FALSEnever evaluated
0
469 continue;
never executed: continue;
0
470 xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);-
471 totalKashidas += glyphs.justifications[i].nKashidas;-
472 }
never executed: end of block
0
473 positions.resize(glyphs.numGlyphs+totalKashidas);-
474 glyphs_out.resize(glyphs.numGlyphs+totalKashidas);-
475-
476 i = 0;-
477 while(i < glyphs.numGlyphs) {
i < glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
478 if (glyphs.attributes[i].dontPrint) {
glyphs.attributes[i].dontPrintDescription
TRUEnever evaluated
FALSEnever evaluated
0
479 ++i;-
480 continue;
never executed: continue;
0
481 }-
482 xpos -= glyphs.advances[i];-
483-
484 QFixed gpos_x = xpos + glyphs.offsets[i].x;-
485 QFixed gpos_y = ypos + glyphs.offsets[i].y;-
486 if (transform) {
transformDescription
TRUEnever evaluated
FALSEnever evaluated
0
487 QPointF gpos(gpos_x.toReal(), gpos_y.toReal());-
488 gpos = gpos * matrix;-
489 gpos_x = QFixed::fromReal(gpos.x());-
490 gpos_y = QFixed::fromReal(gpos.y());-
491 }
never executed: end of block
0
492 positions[current].x = gpos_x;-
493 positions[current].y = gpos_y;-
494 glyphs_out[current] = glyphs.glyphs[i];-
495 ++current;-
496 if (glyphs.justifications[i].nKashidas) {
glyphs.justifi...s[i].nKashidasDescription
TRUEnever evaluated
FALSEnever evaluated
0
497 QChar ch(0x640); // Kashida character-
498-
499 glyph_t kashidaGlyph = glyphIndex(ch.unicode());-
500 QFixed kashidaWidth;-
501-
502 QGlyphLayout g;-
503 g.numGlyphs = 1;-
504 g.glyphs = &kashidaGlyph;-
505 g.advances = &kashidaWidth;-
506 recalcAdvances(&g, 0);-
507-
508 for (uint k = 0; k < glyphs.justifications[i].nKashidas; ++k) {
k < glyphs.jus...s[i].nKashidasDescription
TRUEnever evaluated
FALSEnever evaluated
0
509 xpos -= kashidaWidth;-
510-
511 QFixed gpos_x = xpos + glyphs.offsets[i].x;-
512 QFixed gpos_y = ypos + glyphs.offsets[i].y;-
513 if (transform) {
transformDescription
TRUEnever evaluated
FALSEnever evaluated
0
514 QPointF gpos(gpos_x.toReal(), gpos_y.toReal());-
515 gpos = gpos * matrix;-
516 gpos_x = QFixed::fromReal(gpos.x());-
517 gpos_y = QFixed::fromReal(gpos.y());-
518 }
never executed: end of block
0
519 positions[current].x = gpos_x;-
520 positions[current].y = gpos_y;-
521 glyphs_out[current] = kashidaGlyph;-
522 ++current;-
523 }
never executed: end of block
0
524 } else {
never executed: end of block
0
525 xpos -= QFixed::fromFixed(glyphs.justifications[i].space_18d6);-
526 }
never executed: end of block
0
527 ++i;-
528 }
never executed: end of block
0
529 } else {
never executed: end of block
0
530 positions.resize(glyphs.numGlyphs);-
531 glyphs_out.resize(glyphs.numGlyphs);-
532 int i = 0;-
533 if (!transform) {
!transformDescription
TRUEnever evaluated
FALSEnever evaluated
0
534 while (i < glyphs.numGlyphs) {
i < glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
535 if (!glyphs.attributes[i].dontPrint) {
!glyphs.attrib...s[i].dontPrintDescription
TRUEnever evaluated
FALSEnever evaluated
0
536 positions[current].x = xpos + glyphs.offsets[i].x;-
537 positions[current].y = ypos + glyphs.offsets[i].y;-
538 glyphs_out[current] = glyphs.glyphs[i];-
539 xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);-
540 ++current;-
541 }
never executed: end of block
0
542 ++i;-
543 }
never executed: end of block
0
544 } else {
never executed: end of block
0
545 while (i < glyphs.numGlyphs) {
i < glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
546 if (!glyphs.attributes[i].dontPrint) {
!glyphs.attrib...s[i].dontPrintDescription
TRUEnever evaluated
FALSEnever evaluated
0
547 QFixed gpos_x = xpos + glyphs.offsets[i].x;-
548 QFixed gpos_y = ypos + glyphs.offsets[i].y;-
549 QPointF gpos(gpos_x.toReal(), gpos_y.toReal());-
550 gpos = gpos * matrix;-
551 positions[current].x = QFixed::fromReal(gpos.x());-
552 positions[current].y = QFixed::fromReal(gpos.y());-
553 glyphs_out[current] = glyphs.glyphs[i];-
554 xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);-
555 ++current;-
556 }
never executed: end of block
0
557 ++i;-
558 }
never executed: end of block
0
559 }
never executed: end of block
0
560 }-
561 positions.resize(current);-
562 glyphs_out.resize(current);-
563 Q_ASSERT(positions.size() == glyphs_out.size());-
564}
never executed: end of block
0
565-
566void QFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)-
567{-
568 glyph_metrics_t gi = boundingBox(glyph);-
569 if (leftBearing != 0)
leftBearing != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
570 *leftBearing = gi.leftBearing().toReal();
never executed: *leftBearing = gi.leftBearing().toReal();
0
571 if (rightBearing != 0)
rightBearing != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
572 *rightBearing = gi.rightBearing().toReal();
never executed: *rightBearing = gi.rightBearing().toReal();
0
573}
never executed: end of block
0
574-
575qreal QFontEngine::minLeftBearing() const-
576{-
577 if (m_minLeftBearing == kBearingNotInitialized)
m_minLeftBeari...<qreal>::max()Description
TRUEnever evaluated
FALSEnever evaluated
0
578 minRightBearing(); // Initializes both (see below)
never executed: minRightBearing();
0
579-
580 return m_minLeftBearing;
never executed: return m_minLeftBearing;
0
581}-
582-
583#define q16Dot16ToFloat(i) ((i) / 65536.0)-
584-
585#define kMinLeftSideBearingOffset 12-
586#define kMinRightSideBearingOffset 14-
587-
588qreal QFontEngine::minRightBearing() const-
589{-
590 if (m_minRightBearing == kBearingNotInitialized) {
m_minRightBear...<qreal>::max()Description
TRUEnever evaluated
FALSEnever evaluated
0
591-
592 // Try the 'hhea' font table first, which covers the entire font-
593 QByteArray hheaTable = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a'));-
594 if (hheaTable.size() >= int(kMinRightSideBearingOffset + sizeof(qint16))) {
hheaTable.size...izeof(qint16))Description
TRUEnever evaluated
FALSEnever evaluated
0
595 const uchar *tableData = reinterpret_cast<const uchar *>(hheaTable.constData());-
596 Q_ASSERT(q16Dot16ToFloat(qFromBigEndian<quint32>(tableData)) == 1.0);-
597-
598 qint16 minLeftSideBearing = qFromBigEndian<qint16>(tableData + kMinLeftSideBearingOffset);-
599 qint16 minRightSideBearing = qFromBigEndian<qint16>(tableData + kMinRightSideBearingOffset);-
600-
601 // The table data is expressed as FUnits, meaning we have to take the number-
602 // of units per em into account. Since pixelSize already has taken DPI into-
603 // account we can use that directly instead of the point size.-
604 int unitsPerEm = emSquareSize().toInt();-
605 qreal funitToPixelFactor = fontDef.pixelSize / unitsPerEm;-
606-
607 // Some fonts on OS X (such as Gurmukhi Sangam MN, Khmer MN, Lao Sangam MN, etc.), have-
608 // invalid values for their NBSPACE left bearing, causing the 'hhea' minimum bearings to-
609 // be way off. We detect this by assuming that the minimum bearsings are within a certain-
610 // range of the em square size.-
611 static const int largestValidBearing = 4 * unitsPerEm;-
612-
613 if (qAbs(minLeftSideBearing) < largestValidBearing)
qAbs(minLeftSi...stValidBearingDescription
TRUEnever evaluated
FALSEnever evaluated
0
614 m_minLeftBearing = minLeftSideBearing * funitToPixelFactor;
never executed: m_minLeftBearing = minLeftSideBearing * funitToPixelFactor;
0
615 if (qAbs(minRightSideBearing) < largestValidBearing)
qAbs(minRightS...stValidBearingDescription
TRUEnever evaluated
FALSEnever evaluated
0
616 m_minRightBearing = minRightSideBearing * funitToPixelFactor;
never executed: m_minRightBearing = minRightSideBearing * funitToPixelFactor;
0
617 }
never executed: end of block
0
618-
619 // Fallback in case of missing 'hhea' table (bitmap fonts e.g.) or broken 'hhea' values-
620 if (m_minLeftBearing == kBearingNotInitialized || m_minRightBearing == kBearingNotInitialized) {
m_minLeftBeari...<qreal>::max()Description
TRUEnever evaluated
FALSEnever evaluated
m_minRightBear...<qreal>::max()Description
TRUEnever evaluated
FALSEnever evaluated
0
621-
622 // To balance performance and correctness we only look at a subset of the-
623 // possible glyphs in the font, based on which characters are more likely-
624 // to have a left or right bearing.-
625 static const ushort characterSubset[] = {-
626 '(', 'C', 'F', 'K', 'V', 'X', 'Y', ']', '_', 'f', 'r', '|',-
627 127, 205, 645, 884, 922, 1070, 12386-
628 };-
629-
630 // The font may have minimum bearings larger than 0, so we have to start at the max-
631 m_minLeftBearing = m_minRightBearing = std::numeric_limits<qreal>::max();-
632-
633 for (uint i = 0; i < (sizeof(characterSubset) / sizeof(ushort)); ++i) {
i < (sizeof(ch...izeof(ushort))Description
TRUEnever evaluated
FALSEnever evaluated
0
634 const glyph_t glyph = glyphIndex(characterSubset[i]);-
635 if (!glyph)
!glyphDescription
TRUEnever evaluated
FALSEnever evaluated
0
636 continue;
never executed: continue;
0
637-
638 glyph_metrics_t glyphMetrics = const_cast<QFontEngine *>(this)->boundingBox(glyph);-
639-
640 // Glyphs with no contours shouldn't contribute to bearings-
641 if (!glyphMetrics.width || !glyphMetrics.height)
!glyphMetrics.widthDescription
TRUEnever evaluated
FALSEnever evaluated
!glyphMetrics.heightDescription
TRUEnever evaluated
FALSEnever evaluated
0
642 continue;
never executed: continue;
0
643-
644 m_minLeftBearing = qMin(m_minLeftBearing, glyphMetrics.leftBearing().toReal());-
645 m_minRightBearing = qMin(m_minRightBearing, glyphMetrics.rightBearing().toReal());-
646 }
never executed: end of block
0
647 }
never executed: end of block
0
648-
649 if (m_minLeftBearing == kBearingNotInitialized || m_minRightBearing == kBearingNotInitialized)
m_minLeftBeari...<qreal>::max()Description
TRUEnever evaluated
FALSEnever evaluated
m_minRightBear...<qreal>::max()Description
TRUEnever evaluated
FALSEnever evaluated
0
650 qWarning() << "Failed to compute left/right minimum bearings for" << fontDef.family;
never executed: QMessageLogger(__FILE__, 650, __PRETTY_FUNCTION__).warning() << "Failed to compute left/right minimum bearings for" << fontDef.family;
0
651 }
never executed: end of block
0
652-
653 return m_minRightBearing;
never executed: return m_minRightBearing;
0
654}-
655-
656glyph_metrics_t QFontEngine::tightBoundingBox(const QGlyphLayout &glyphs)-
657{-
658 glyph_metrics_t overall;-
659-
660 QFixed ymax = 0;-
661 QFixed xmax = 0;-
662 for (int i = 0; i < glyphs.numGlyphs; i++) {
i < glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
663 glyph_metrics_t bb = boundingBox(glyphs.glyphs[i]);-
664 QFixed x = overall.xoff + glyphs.offsets[i].x + bb.x;-
665 QFixed y = overall.yoff + glyphs.offsets[i].y + bb.y;-
666 overall.x = qMin(overall.x, x);-
667 overall.y = qMin(overall.y, y);-
668 xmax = qMax(xmax, x + bb.width);-
669 ymax = qMax(ymax, y + bb.height);-
670 overall.xoff += bb.xoff;-
671 overall.yoff += bb.yoff;-
672 }
never executed: end of block
0
673 overall.height = qMax(overall.height, ymax - overall.y);-
674 overall.width = xmax - overall.x;-
675-
676 return overall;
never executed: return overall;
0
677}-
678-
679-
680void QFontEngine::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path,-
681 QTextItem::RenderFlags flags)-
682{-
683 if (!glyphs.numGlyphs)
!glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
684 return;
never executed: return;
0
685-
686 QVarLengthArray<QFixedPoint> positions;-
687 QVarLengthArray<glyph_t> positioned_glyphs;-
688 QTransform matrix = QTransform::fromTranslate(x, y);-
689 getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions);-
690 addGlyphsToPath(positioned_glyphs.data(), positions.data(), positioned_glyphs.size(), path, flags);-
691}
never executed: end of block
0
692-
693#define GRID(x, y) grid[(y)*(w+1) + (x)]-
694#define SET(x, y) (*(image_data + (y)*bpl + ((x) >> 3)) & (0x80 >> ((x) & 7)))-
695-
696enum { EdgeRight = 0x1,-
697 EdgeDown = 0x2,-
698 EdgeLeft = 0x4,-
699 EdgeUp = 0x8-
700};-
701-
702static void collectSingleContour(qreal x0, qreal y0, uint *grid, int x, int y, int w, int h, QPainterPath *path)-
703{-
704 Q_UNUSED(h);-
705-
706 path->moveTo(x + x0, y + y0);-
707 while (GRID(x, y)) {
grid[(y)*(w+1) + (x)]Description
TRUEnever evaluated
FALSEnever evaluated
0
708 if (GRID(x, y) & EdgeRight) {
grid[(y)*(w+1)...)] & EdgeRightDescription
TRUEnever evaluated
FALSEnever evaluated
0
709 while (GRID(x, y) & EdgeRight) {
grid[(y)*(w+1)...)] & EdgeRightDescription
TRUEnever evaluated
FALSEnever evaluated
0
710 GRID(x, y) &= ~EdgeRight;-
711 ++x;-
712 }
never executed: end of block
0
713 Q_ASSERT(x <= w);-
714 path->lineTo(x + x0, y + y0);-
715 continue;
never executed: continue;
0
716 }-
717 if (GRID(x, y) & EdgeDown) {
grid[(y)*(w+1)...x)] & EdgeDownDescription
TRUEnever evaluated
FALSEnever evaluated
0
718 while (GRID(x, y) & EdgeDown) {
grid[(y)*(w+1)...x)] & EdgeDownDescription
TRUEnever evaluated
FALSEnever evaluated
0
719 GRID(x, y) &= ~EdgeDown;-
720 ++y;-
721 }
never executed: end of block
0
722 Q_ASSERT(y <= h);-
723 path->lineTo(x + x0, y + y0);-
724 continue;
never executed: continue;
0
725 }-
726 if (GRID(x, y) & EdgeLeft) {
grid[(y)*(w+1)...x)] & EdgeLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
727 while (GRID(x, y) & EdgeLeft) {
grid[(y)*(w+1)...x)] & EdgeLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
728 GRID(x, y) &= ~EdgeLeft;-
729 --x;-
730 }
never executed: end of block
0
731 Q_ASSERT(x >= 0);-
732 path->lineTo(x + x0, y + y0);-
733 continue;
never executed: continue;
0
734 }-
735 if (GRID(x, y) & EdgeUp) {
grid[(y)*(w+1) + (x)] & EdgeUpDescription
TRUEnever evaluated
FALSEnever evaluated
0
736 while (GRID(x, y) & EdgeUp) {
grid[(y)*(w+1) + (x)] & EdgeUpDescription
TRUEnever evaluated
FALSEnever evaluated
0
737 GRID(x, y) &= ~EdgeUp;-
738 --y;-
739 }
never executed: end of block
0
740 Q_ASSERT(y >= 0);-
741 path->lineTo(x + x0, y + y0);-
742 continue;
never executed: continue;
0
743 }-
744 }
never executed: end of block
0
745 path->closeSubpath();-
746}
never executed: end of block
0
747-
748Q_GUI_EXPORT void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data, int bpl, int w, int h, QPainterPath *path)-
749{-
750 uint *grid = new uint[(w+1)*(h+1)];-
751 // set up edges-
752 for (int y = 0; y <= h; ++y) {
y <= hDescription
TRUEnever evaluated
FALSEnever evaluated
0
753 for (int x = 0; x <= w; ++x) {
x <= wDescription
TRUEnever evaluated
FALSEnever evaluated
0
754 bool topLeft = (x == 0)|(y == 0) ? false : SET(x - 1, y - 1);
(x == 0)|(y == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
755 bool topRight = (x == w)|(y == 0) ? false : SET(x, y - 1);
(x == w)|(y == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
756 bool bottomLeft = (x == 0)|(y == h) ? false : SET(x - 1, y);
(x == 0)|(y == h)Description
TRUEnever evaluated
FALSEnever evaluated
0
757 bool bottomRight = (x == w)|(y == h) ? false : SET(x, y);
(x == w)|(y == h)Description
TRUEnever evaluated
FALSEnever evaluated
0
758-
759 GRID(x, y) = 0;-
760 if ((!topRight) & bottomRight)
(!topRight) & bottomRightDescription
TRUEnever evaluated
FALSEnever evaluated
0
761 GRID(x, y) |= EdgeRight;
never executed: grid[(y)*(w+1) + (x)] |= EdgeRight;
0
762 if ((!bottomRight) & bottomLeft)
(!bottomRight) & bottomLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
763 GRID(x, y) |= EdgeDown;
never executed: grid[(y)*(w+1) + (x)] |= EdgeDown;
0
764 if ((!bottomLeft) & topLeft)
(!bottomLeft) & topLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
765 GRID(x, y) |= EdgeLeft;
never executed: grid[(y)*(w+1) + (x)] |= EdgeLeft;
0
766 if ((!topLeft) & topRight)
(!topLeft) & topRightDescription
TRUEnever evaluated
FALSEnever evaluated
0
767 GRID(x, y) |= EdgeUp;
never executed: grid[(y)*(w+1) + (x)] |= EdgeUp;
0
768 }
never executed: end of block
0
769 }
never executed: end of block
0
770-
771 // collect edges-
772 for (int y = 0; y < h; ++y) {
y < hDescription
TRUEnever evaluated
FALSEnever evaluated
0
773 for (int x = 0; x < w; ++x) {
x < wDescription
TRUEnever evaluated
FALSEnever evaluated
0
774 if (!GRID(x, y))
!grid[(y)*(w+1) + (x)]Description
TRUEnever evaluated
FALSEnever evaluated
0
775 continue;
never executed: continue;
0
776 // found start of a contour, follow it-
777 collectSingleContour(x0, y0, grid, x, y, w, h, path);-
778 }
never executed: end of block
0
779 }
never executed: end of block
0
780 delete [] grid;-
781}
never executed: end of block
0
782-
783#undef GRID-
784#undef SET-
785-
786-
787void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyphs,-
788 QPainterPath *path, QTextItem::RenderFlags flags)-
789{-
790// TODO what to do with 'flags' ??-
791 Q_UNUSED(flags);-
792 QFixed advanceX = QFixed::fromReal(x);-
793 QFixed advanceY = QFixed::fromReal(y);-
794 for (int i=0; i < glyphs.numGlyphs; ++i) {
i < glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
795 glyph_metrics_t metrics = boundingBox(glyphs.glyphs[i]);-
796 if (metrics.width.value() == 0 || metrics.height.value() == 0) {
metrics.width.value() == 0Description
TRUEnever evaluated
FALSEnever evaluated
metrics.height.value() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
797 advanceX += glyphs.advances[i];-
798 continue;
never executed: continue;
0
799 }-
800 const QImage alphaMask = alphaMapForGlyph(glyphs.glyphs[i]);-
801-
802 const int w = alphaMask.width();-
803 const int h = alphaMask.height();-
804 const int srcBpl = alphaMask.bytesPerLine();-
805 QImage bitmap;-
806 if (alphaMask.depth() == 1) {
alphaMask.depth() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
807 bitmap = alphaMask;-
808 } else {
never executed: end of block
0
809 bitmap = QImage(w, h, QImage::Format_Mono);-
810 const uchar *imageData = alphaMask.bits();-
811 const int destBpl = bitmap.bytesPerLine();-
812 uchar *bitmapData = bitmap.bits();-
813-
814 for (int yi = 0; yi < h; ++yi) {
yi < hDescription
TRUEnever evaluated
FALSEnever evaluated
0
815 const uchar *src = imageData + yi*srcBpl;-
816 uchar *dst = bitmapData + yi*destBpl;-
817 for (int xi = 0; xi < w; ++xi) {
xi < wDescription
TRUEnever evaluated
FALSEnever evaluated
0
818 const int byte = xi / 8;-
819 const int bit = xi % 8;-
820 if (bit == 0)
bit == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
821 dst[byte] = 0;
never executed: dst[byte] = 0;
0
822 if (src[xi])
src[xi]Description
TRUEnever evaluated
FALSEnever evaluated
0
823 dst[byte] |= 128 >> bit;
never executed: dst[byte] |= 128 >> bit;
0
824 }
never executed: end of block
0
825 }
never executed: end of block
0
826 }
never executed: end of block
0
827 const uchar *bitmap_data = bitmap.constBits();-
828 QFixedPoint offset = glyphs.offsets[i];-
829 advanceX += offset.x;-
830 advanceY += offset.y;-
831 qt_addBitmapToPath((advanceX + metrics.x).toReal(), (advanceY + metrics.y).toReal(), bitmap_data, bitmap.bytesPerLine(), w, h, path);-
832 advanceX += glyphs.advances[i];-
833 }
never executed: end of block
0
834}
never executed: end of block
0
835-
836void QFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs,-
837 QPainterPath *path, QTextItem::RenderFlags flags)-
838{-
839 qreal x = positions[0].x.toReal();-
840 qreal y = positions[0].y.toReal();-
841 QVarLengthGlyphLayoutArray g(nGlyphs);-
842-
843 for (int i = 0; i < nGlyphs - 1; ++i) {
i < nGlyphs - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
844 g.glyphs[i] = glyphs[i];-
845 g.advances[i] = positions[i + 1].x - positions[i].x;-
846 }
never executed: end of block
0
847 g.glyphs[nGlyphs - 1] = glyphs[nGlyphs - 1];-
848 g.advances[nGlyphs - 1] = QFixed::fromReal(maxCharWidth());-
849-
850 addBitmapFontToPath(x, y, g, path, flags);-
851}
never executed: end of block
0
852-
853QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/)-
854{-
855 // For font engines don't support subpixel positioning-
856 return alphaMapForGlyph(glyph);
never executed: return alphaMapForGlyph(glyph);
0
857}-
858-
859QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &t)-
860{-
861 QImage i = alphaMapForGlyph(glyph);-
862 if (t.type() > QTransform::TxTranslate)
t.type() > QTr...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
863 i = i.transformed(t).convertToFormat(QImage::Format_Alpha8);
never executed: i = i.transformed(t).convertToFormat(QImage::Format_Alpha8);
0
864 Q_ASSERT(i.depth() <= 8); // To verify that transformed didn't change the format...-
865-
866 return i;
never executed: return i;
0
867}-
868-
869QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)-
870{-
871 if (! supportsSubPixelPositions())
! supportsSubPixelPositions()Description
TRUEnever evaluated
FALSEnever evaluated
0
872 return alphaMapForGlyph(glyph, t);
never executed: return alphaMapForGlyph(glyph, t);
0
873-
874 QImage i = alphaMapForGlyph(glyph, subPixelPosition);-
875 if (t.type() > QTransform::TxTranslate)
t.type() > QTr...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
876 i = i.transformed(t).convertToFormat(QImage::Format_Alpha8);
never executed: i = i.transformed(t).convertToFormat(QImage::Format_Alpha8);
0
877 Q_ASSERT(i.depth() <= 8); // To verify that transformed didn't change the format...-
878-
879 return i;
never executed: return i;
0
880}-
881-
882QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &t)-
883{-
884 const QImage alphaMask = alphaMapForGlyph(glyph, t);-
885 QImage rgbMask(alphaMask.width(), alphaMask.height(), QImage::Format_RGB32);-
886-
887 for (int y=0; y<alphaMask.height(); ++y) {
y<alphaMask.height()Description
TRUEnever evaluated
FALSEnever evaluated
0
888 uint *dst = (uint *) rgbMask.scanLine(y);-
889 const uchar *src = alphaMask.constScanLine(y);-
890 for (int x=0; x<alphaMask.width(); ++x) {
x<alphaMask.width()Description
TRUEnever evaluated
FALSEnever evaluated
0
891 int val = src[x];-
892 dst[x] = qRgb(val, val, val);-
893 }
never executed: end of block
0
894 }
never executed: end of block
0
895-
896 return rgbMask;
never executed: return rgbMask;
0
897}-
898-
899QImage QFontEngine::bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform&)-
900{-
901 Q_UNUSED(subPixelPosition);-
902-
903 return QImage();
never executed: return QImage();
0
904}-
905-
906QFixed QFontEngine::subPixelPositionForX(QFixed x) const-
907{-
908 if (m_subPixelPositionCount <= 1 || !supportsSubPixelPositions())
m_subPixelPositionCount <= 1Description
TRUEnever evaluated
FALSEnever evaluated
!supportsSubPixelPositions()Description
TRUEnever evaluated
FALSEnever evaluated
0
909 return QFixed();
never executed: return QFixed();
0
910-
911 QFixed subPixelPosition;-
912 if (x != 0) {
x != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
913 subPixelPosition = x - x.floor();-
914 QFixed fraction = (subPixelPosition / QFixed::fromReal(1.0 / m_subPixelPositionCount)).floor();-
915-
916 // Compensate for precision loss in fixed point to make sure we are always drawing at a subpixel position over-
917 // the lower boundary for the selected rasterization by adding 1/64.-
918 subPixelPosition = fraction / QFixed(m_subPixelPositionCount) + QFixed::fromReal(0.015625);-
919 }
never executed: end of block
0
920 return subPixelPosition;
never executed: return subPixelPosition;
0
921}-
922-
923QImage *QFontEngine::lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition,-
924 QFontEngine::GlyphFormat neededFormat,-
925 const QTransform &t, QPoint *offset)-
926{-
927 Q_ASSERT(currentlyLockedAlphaMap.isNull());-
928 if (neededFormat == Format_None)
neededFormat == Format_NoneDescription
TRUEnever evaluated
FALSEnever evaluated
0
929 neededFormat = Format_A32;
never executed: neededFormat = Format_A32;
0
930-
931 if (neededFormat != Format_A32)
neededFormat != Format_A32Description
TRUEnever evaluated
FALSEnever evaluated
0
932 currentlyLockedAlphaMap = alphaMapForGlyph(glyph, subPixelPosition, t);
never executed: currentlyLockedAlphaMap = alphaMapForGlyph(glyph, subPixelPosition, t);
0
933 else-
934 currentlyLockedAlphaMap = alphaRGBMapForGlyph(glyph, subPixelPosition, t);
never executed: currentlyLockedAlphaMap = alphaRGBMapForGlyph(glyph, subPixelPosition, t);
0
935-
936 if (offset != 0)
offset != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
937 *offset = QPoint(0, 0);
never executed: *offset = QPoint(0, 0);
0
938-
939 return &currentlyLockedAlphaMap;
never executed: return &currentlyLockedAlphaMap;
0
940}-
941-
942void QFontEngine::unlockAlphaMapForGlyph()-
943{-
944 Q_ASSERT(!currentlyLockedAlphaMap.isNull());-
945 currentlyLockedAlphaMap = QImage();-
946}
never executed: end of block
0
947-
948QImage QFontEngine::alphaMapForGlyph(glyph_t glyph)-
949{-
950 glyph_metrics_t gm = boundingBox(glyph);-
951 int glyph_x = qFloor(gm.x.toReal());-
952 int glyph_y = qFloor(gm.y.toReal());-
953 int glyph_width = qCeil((gm.x + gm.width).toReal()) - glyph_x;-
954 int glyph_height = qCeil((gm.y + gm.height).toReal()) - glyph_y;-
955-
956 if (glyph_width <= 0 || glyph_height <= 0)
glyph_width <= 0Description
TRUEnever evaluated
FALSEnever evaluated
glyph_height <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
957 return QImage();
never executed: return QImage();
0
958 QFixedPoint pt;-
959 pt.x = -glyph_x;-
960 pt.y = -glyph_y; // the baseline-
961 QPainterPath path;-
962 path.setFillRule(Qt::WindingFill);-
963 QImage im(glyph_width, glyph_height, QImage::Format_ARGB32_Premultiplied);-
964 im.fill(Qt::transparent);-
965 QPainter p(&im);-
966 p.setRenderHint(QPainter::Antialiasing);-
967 addGlyphsToPath(&glyph, &pt, 1, &path, 0);-
968 p.setPen(Qt::NoPen);-
969 p.setBrush(Qt::black);-
970 p.drawPath(path);-
971 p.end();-
972-
973 QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8);-
974-
975 for (int y=0; y<im.height(); ++y) {
y<im.height()Description
TRUEnever evaluated
FALSEnever evaluated
0
976 uchar *dst = (uchar *) alphaMap.scanLine(y);-
977 const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y));-
978 for (int x=0; x<im.width(); ++x)
x<im.width()Description
TRUEnever evaluated
FALSEnever evaluated
0
979 dst[x] = qAlpha(src[x]);
never executed: dst[x] = qAlpha(src[x]);
0
980 }
never executed: end of block
0
981-
982 return alphaMap;
never executed: return alphaMap;
0
983}-
984-
985void QFontEngine::removeGlyphFromCache(glyph_t)-
986{-
987}-
988-
989QFontEngine::Properties QFontEngine::properties() const-
990{-
991 Properties p;-
992 QByteArray psname = QFontEngine::convertToPostscriptFontFamilyName(fontDef.family.toUtf8());-
993 psname += '-';-
994 psname += QByteArray::number(fontDef.style);-
995 psname += '-';-
996 psname += QByteArray::number(fontDef.weight);-
997-
998 p.postscriptName = psname;-
999 p.ascent = ascent();-
1000 p.descent = descent();-
1001 p.leading = leading();-
1002 p.emSquare = p.ascent;-
1003 p.boundingBox = QRectF(0, -p.ascent.toReal(), maxCharWidth(), (p.ascent + p.descent).toReal());-
1004 p.italicAngle = 0;-
1005 p.capHeight = p.ascent;-
1006 p.lineWidth = lineThickness();-
1007 return p;
never executed: return p;
0
1008}-
1009-
1010void QFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)-
1011{-
1012 *metrics = boundingBox(glyph);-
1013 QFixedPoint p;-
1014 p.x = 0;-
1015 p.y = 0;-
1016 addGlyphsToPath(&glyph, &p, 1, path, QFlag(0));-
1017}
never executed: end of block
0
1018-
1019/*!-
1020 Returns \c true if the font table idetified by \a tag exists in the font;-
1021 returns \c false otherwise.-
1022-
1023 If \a buffer is NULL, stores the size of the buffer required for the font table data,-
1024 in bytes, in \a length. If \a buffer is not NULL and the capacity-
1025 of the buffer, passed in \a length, is sufficient to store the font table data,-
1026 also copies the font table data to \a buffer.-
1027-
1028 Note: returning \c false when the font table exists could lead to an undefined behavior.-
1029*/-
1030bool QFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const-
1031{-
1032 Q_UNUSED(tag)-
1033 Q_UNUSED(buffer)-
1034 Q_UNUSED(length)-
1035 return false;
never executed: return false;
0
1036}-
1037-
1038QByteArray QFontEngine::getSfntTable(uint tag) const-
1039{-
1040 QByteArray table;-
1041 uint len = 0;-
1042 if (!getSfntTableData(tag, 0, &len))
!getSfntTableD...(tag, 0, &len)Description
TRUEnever evaluated
FALSEnever evaluated
0
1043 return table;
never executed: return table;
0
1044 table.resize(len);-
1045 if (!getSfntTableData(tag, reinterpret_cast<uchar *>(table.data()), &len))
!getSfntTableD...data()), &len)Description
TRUEnever evaluated
FALSEnever evaluated
0
1046 return QByteArray();
never executed: return QByteArray();
0
1047 return table;
never executed: return table;
0
1048}-
1049-
1050void QFontEngine::clearGlyphCache(const void *context)-
1051{-
1052 m_glyphCaches.remove(context);-
1053}
never executed: end of block
0
1054-
1055void QFontEngine::setGlyphCache(const void *context, QFontEngineGlyphCache *cache)-
1056{-
1057 Q_ASSERT(cache);-
1058-
1059 GlyphCaches &caches = m_glyphCaches[context];-
1060 for (GlyphCaches::const_iterator it = caches.constBegin(), end = caches.constEnd(); it != end; ++it) {
it != endDescription
TRUEnever evaluated
FALSEnever evaluated
0
1061 if (cache == it->cache.data())
cache == it->cache.data()Description
TRUEnever evaluated
FALSEnever evaluated
0
1062 return;
never executed: return;
0
1063 }
never executed: end of block
0
1064-
1065 // Limit the glyph caches to 4 per context. This covers all 90 degree rotations,-
1066 // and limits memory use when there is continuous or random rotation-
1067 if (caches.size() == 4)
caches.size() == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1068 caches.removeLast();
never executed: caches.removeLast();
0
1069-
1070 GlyphCacheEntry entry;-
1071 entry.cache = cache;-
1072 caches.push_front(entry);-
1073-
1074}
never executed: end of block
0
1075-
1076QFontEngineGlyphCache *QFontEngine::glyphCache(const void *context, GlyphFormat format, const QTransform &transform) const-
1077{-
1078 const QHash<const void*, GlyphCaches>::const_iterator caches = m_glyphCaches.constFind(context);-
1079 if (caches == m_glyphCaches.cend())
caches == m_glyphCaches.cend()Description
TRUEnever evaluated
FALSEnever evaluated
0
1080 return Q_NULLPTR;
never executed: return nullptr;
0
1081-
1082 for (GlyphCaches::const_iterator it = caches->begin(), end = caches->end(); it != end; ++it) {
it != endDescription
TRUEnever evaluated
FALSEnever evaluated
0
1083 QFontEngineGlyphCache *cache = it->cache.data();-
1084 if (format == cache->glyphFormat() && qtransform_equals_no_translate(cache->m_transform, transform))
format == cache->glyphFormat()Description
TRUEnever evaluated
FALSEnever evaluated
qtransform_equ...rm, transform)Description
TRUEnever evaluated
FALSEnever evaluated
0
1085 return cache;
never executed: return cache;
0
1086 }
never executed: end of block
0
1087-
1088 return Q_NULLPTR;
never executed: return nullptr;
0
1089}-
1090-
1091static inline QFixed kerning(int left, int right, const QFontEngine::KernPair *pairs, int numPairs)-
1092{-
1093 uint left_right = (left << 16) + right;-
1094-
1095 left = 0, right = numPairs - 1;-
1096 while (left <= right) {
left <= rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1097 int middle = left + ( ( right - left ) >> 1 );-
1098-
1099 if(pairs[middle].left_right == left_right)
pairs[middle].... == left_rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1100 return pairs[middle].adjust;
never executed: return pairs[middle].adjust;
0
1101-
1102 if (pairs[middle].left_right < left_right)
pairs[middle]....t < left_rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1103 left = middle + 1;
never executed: left = middle + 1;
0
1104 else-
1105 right = middle - 1;
never executed: right = middle - 1;
0
1106 }-
1107 return 0;
never executed: return 0;
0
1108}-
1109-
1110void QFontEngine::doKerning(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const-
1111{-
1112 int numPairs = kerning_pairs.size();-
1113 if(!numPairs)
!numPairsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1114 return;
never executed: return;
0
1115-
1116 const KernPair *pairs = kerning_pairs.constData();-
1117-
1118 if (flags & DesignMetrics) {
flags & DesignMetricsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1119 for(int i = 0; i < glyphs->numGlyphs - 1; ++i)
i < glyphs->numGlyphs - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1120 glyphs->advances[i] += kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs);
never executed: glyphs->advances[i] += kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs);
0
1121 } else {
never executed: end of block
0
1122 for(int i = 0; i < glyphs->numGlyphs - 1; ++i)
i < glyphs->numGlyphs - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1123 glyphs->advances[i] += qRound(kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs));
never executed: glyphs->advances[i] += qRound(kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs));
0
1124 }
never executed: end of block
0
1125}-
1126-
1127void QFontEngine::loadKerningPairs(QFixed scalingFactor)-
1128{-
1129 kerning_pairs.clear();-
1130-
1131 QByteArray tab = getSfntTable(MAKE_TAG('k', 'e', 'r', 'n'));-
1132 if (tab.isEmpty())
tab.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1133 return;
never executed: return;
0
1134-
1135 const uchar *table = reinterpret_cast<const uchar *>(tab.constData());-
1136 const uchar *end = table + tab.size();-
1137-
1138 quint16 version;-
1139 if (!qSafeFromBigEndian(table, end, &version))
!qSafeFromBigE...end, &version)Description
TRUEnever evaluated
FALSEnever evaluated
0
1140 return;
never executed: return;
0
1141-
1142 if (version != 0) {
version != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1143// qDebug("wrong version");-
1144 return;
never executed: return;
0
1145 }-
1146-
1147 quint16 numTables;-
1148 if (!qSafeFromBigEndian(table + 2, end, &numTables))
!qSafeFromBigE...d, &numTables)Description
TRUEnever evaluated
FALSEnever evaluated
0
1149 return;
never executed: return;
0
1150-
1151 {-
1152 int offset = 4;-
1153 for(int i = 0; i < numTables; ++i) {
i < numTablesDescription
TRUEnever evaluated
FALSEnever evaluated
0
1154 const uchar *header = table + offset;-
1155-
1156 quint16 version;-
1157 if (!qSafeFromBigEndian(header, end, &version))
!qSafeFromBigE...end, &version)Description
TRUEnever evaluated
FALSEnever evaluated
0
1158 goto end;
never executed: goto end;
0
1159-
1160 quint16 length;-
1161 if (!qSafeFromBigEndian(header + 2, end, &length))
!qSafeFromBigE... end, &length)Description
TRUEnever evaluated
FALSEnever evaluated
0
1162 goto end;
never executed: goto end;
0
1163-
1164 quint16 coverage;-
1165 if (!qSafeFromBigEndian(header + 4, end, &coverage))
!qSafeFromBigE...nd, &coverage)Description
TRUEnever evaluated
FALSEnever evaluated
0
1166 goto end;
never executed: goto end;
0
1167-
1168// qDebug("subtable: version=%d, coverage=%x",version, coverage);-
1169 if(version == 0 && coverage == 0x0001) {
version == 0Description
TRUEnever evaluated
FALSEnever evaluated
coverage == 0x0001Description
TRUEnever evaluated
FALSEnever evaluated
0
1170 if (offset + length > tab.size()) {
offset + length > tab.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1171// qDebug("length ouf ot bounds");-
1172 goto end;
never executed: goto end;
0
1173 }-
1174 const uchar *data = table + offset + 6;-
1175-
1176 quint16 nPairs;-
1177 if (!qSafeFromBigEndian(data, end, &nPairs))
!qSafeFromBigE... end, &nPairs)Description
TRUEnever evaluated
FALSEnever evaluated
0
1178 goto end;
never executed: goto end;
0
1179-
1180 if(nPairs * 6 + 8 > length - 6) {
nPairs * 6 + 8 > length - 6Description
TRUEnever evaluated
FALSEnever evaluated
0
1181// qDebug("corrupt table!");-
1182 // corrupt table-
1183 goto end;
never executed: goto end;
0
1184 }-
1185-
1186 int off = 8;-
1187 for(int i = 0; i < nPairs; ++i) {
i < nPairsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1188 QFontEngine::KernPair p;-
1189-
1190 quint16 tmp;-
1191 if (!qSafeFromBigEndian(data + off, end, &tmp))
!qSafeFromBigE...ff, end, &tmp)Description
TRUEnever evaluated
FALSEnever evaluated
0
1192 goto end;
never executed: goto end;
0
1193-
1194 p.left_right = uint(tmp) << 16;-
1195 if (!qSafeFromBigEndian(data + off + 2, end, &tmp))
!qSafeFromBigE... 2, end, &tmp)Description
TRUEnever evaluated
FALSEnever evaluated
0
1196 goto end;
never executed: goto end;
0
1197-
1198 p.left_right |= tmp;-
1199-
1200 if (!qSafeFromBigEndian(data + off + 4, end, &tmp))
!qSafeFromBigE... 4, end, &tmp)Description
TRUEnever evaluated
FALSEnever evaluated
0
1201 goto end;
never executed: goto end;
0
1202-
1203 p.adjust = QFixed(int(short(tmp))) / scalingFactor;-
1204 kerning_pairs.append(p);-
1205 off += 6;-
1206 }
never executed: end of block
0
1207 }
never executed: end of block
0
1208 offset += length;-
1209 }
never executed: end of block
0
1210 }-
1211end:
code before this statement never executed: end:
0
1212 std::sort(kerning_pairs.begin(), kerning_pairs.end());-
1213// for (int i = 0; i < kerning_pairs.count(); ++i)-
1214// qDebug() << 'i' << i << "left_right" << hex << kerning_pairs.at(i).left_right;-
1215}
never executed: end of block
0
1216-
1217-
1218int QFontEngine::glyphCount() const-
1219{-
1220 QByteArray maxpTable = getSfntTable(MAKE_TAG('m', 'a', 'x', 'p'));-
1221 if (maxpTable.size() < 6)
maxpTable.size() < 6Description
TRUEnever evaluated
FALSEnever evaluated
0
1222 return 0;
never executed: return 0;
0
1223-
1224 const uchar *source = reinterpret_cast<const uchar *>(maxpTable.constData() + 4);-
1225 const uchar *end = source + maxpTable.size();-
1226-
1227 quint16 count = 0;-
1228 qSafeFromBigEndian(source, end, &count);-
1229 return count;
never executed: return count;
0
1230}-
1231-
1232Qt::HANDLE QFontEngine::handle() const-
1233{-
1234 return Q_NULLPTR;
never executed: return nullptr;
0
1235}-
1236-
1237const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize)-
1238{-
1239 const uchar *header = table;-
1240 const uchar *endPtr = table + tableSize;-
1241-
1242 // version check-
1243 quint16 version;-
1244 if (!qSafeFromBigEndian(header, endPtr, &version) || version != 0)
!qSafeFromBigE...Ptr, &version)Description
TRUEnever evaluated
FALSEnever evaluated
version != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1245 return 0;
never executed: return 0;
0
1246-
1247 quint16 numTables;-
1248 if (!qSafeFromBigEndian(header + 2, endPtr, &numTables))
!qSafeFromBigE...r, &numTables)Description
TRUEnever evaluated
FALSEnever evaluated
0
1249 return 0;
never executed: return 0;
0
1250-
1251 const uchar *maps = table + 4;-
1252-
1253 enum {-
1254 Invalid,-
1255 AppleRoman,-
1256 Symbol,-
1257 Unicode11,-
1258 Unicode,-
1259 MicrosoftUnicode,-
1260 MicrosoftUnicodeExtended-
1261 };-
1262-
1263 int symbolTable = -1;-
1264 int tableToUse = -1;-
1265 int score = Invalid;-
1266 for (int n = 0; n < numTables; ++n) {
n < numTablesDescription
TRUEnever evaluated
FALSEnever evaluated
0
1267 quint16 platformId;-
1268 if (!qSafeFromBigEndian(maps + 8 * n, endPtr, &platformId))
!qSafeFromBigE..., &platformId)Description
TRUEnever evaluated
FALSEnever evaluated
0
1269 return 0;
never executed: return 0;
0
1270-
1271 quint16 platformSpecificId;-
1272 if (!qSafeFromBigEndian(maps + 8 * n + 2, endPtr, &platformSpecificId))
!qSafeFromBigE...ormSpecificId)Description
TRUEnever evaluated
FALSEnever evaluated
0
1273 return 0;
never executed: return 0;
0
1274-
1275 switch (platformId) {-
1276 case 0: // Unicode
never executed: case 0:
0
1277 if (score < Unicode &&
score < UnicodeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1278 (platformSpecificId == 0 ||
platformSpecificId == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1279 platformSpecificId == 2 ||
platformSpecificId == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1280 platformSpecificId == 3)) {
platformSpecificId == 3Description
TRUEnever evaluated
FALSEnever evaluated
0
1281 tableToUse = n;-
1282 score = Unicode;-
1283 } else if (score < Unicode11 && platformSpecificId == 1) {
never executed: end of block
score < Unicode11Description
TRUEnever evaluated
FALSEnever evaluated
platformSpecificId == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1284 tableToUse = n;-
1285 score = Unicode11;-
1286 }
never executed: end of block
0
1287 break;
never executed: break;
0
1288 case 1: // Apple
never executed: case 1:
0
1289 if (score < AppleRoman && platformSpecificId == 0) { // Apple Roman
score < AppleRomanDescription
TRUEnever evaluated
FALSEnever evaluated
platformSpecificId == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1290 tableToUse = n;-
1291 score = AppleRoman;-
1292 }
never executed: end of block
0
1293 break;
never executed: break;
0
1294 case 3: // Microsoft
never executed: case 3:
0
1295 switch (platformSpecificId) {-
1296 case 0:
never executed: case 0:
0
1297 symbolTable = n;-
1298 if (score < Symbol) {
score < SymbolDescription
TRUEnever evaluated
FALSEnever evaluated
0
1299 tableToUse = n;-
1300 score = Symbol;-
1301 }
never executed: end of block
0
1302 break;
never executed: break;
0
1303 case 1:
never executed: case 1:
0
1304 if (score < MicrosoftUnicode) {
score < MicrosoftUnicodeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1305 tableToUse = n;-
1306 score = MicrosoftUnicode;-
1307 }
never executed: end of block
0
1308 break;
never executed: break;
0
1309 case 0xa:
never executed: case 0xa:
0
1310 if (score < MicrosoftUnicodeExtended) {
score < Micros...nicodeExtendedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1311 tableToUse = n;-
1312 score = MicrosoftUnicodeExtended;-
1313 }
never executed: end of block
0
1314 break;
never executed: break;
0
1315 default:
never executed: default:
0
1316 break;
never executed: break;
0
1317 }-
1318 default:
code before this statement never executed: default:
never executed: default:
0
1319 break;
never executed: break;
0
1320 }-
1321 }-
1322 if(tableToUse < 0)
tableToUse < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1323 return 0;
never executed: return 0;
0
1324-
1325resolveTable:
code before this statement never executed: resolveTable:
0
1326 *isSymbolFont = (symbolTable > -1);-
1327-
1328 quint32 unicode_table;-
1329 if (!qSafeFromBigEndian(maps + 8 * tableToUse + 4, endPtr, &unicode_table))
!qSafeFromBigE...unicode_table)Description
TRUEnever evaluated
FALSEnever evaluated
0
1330 return 0;
never executed: return 0;
0
1331-
1332 if (!unicode_table)
!unicode_tableDescription
TRUEnever evaluated
FALSEnever evaluated
0
1333 return 0;
never executed: return 0;
0
1334-
1335 // get the header of the unicode table-
1336 header = table + unicode_table;-
1337-
1338 quint16 format;-
1339 if (!qSafeFromBigEndian(header, endPtr, &format))
!qSafeFromBigE...dPtr, &format)Description
TRUEnever evaluated
FALSEnever evaluated
0
1340 return 0;
never executed: return 0;
0
1341-
1342 quint32 length;-
1343 if (format < 8) {
format < 8Description
TRUEnever evaluated
FALSEnever evaluated
0
1344 quint16 tmp;-
1345 if (!qSafeFromBigEndian(header + 2, endPtr, &tmp))
!qSafeFromBigE... endPtr, &tmp)Description
TRUEnever evaluated
FALSEnever evaluated
0
1346 return 0;
never executed: return 0;
0
1347 length = tmp;-
1348 } else {
never executed: end of block
0
1349 if (!qSafeFromBigEndian(header + 4, endPtr, &length))
!qSafeFromBigE...dPtr, &length)Description
TRUEnever evaluated
FALSEnever evaluated
0
1350 return 0;
never executed: return 0;
0
1351 }
never executed: end of block
0
1352-
1353 if (table + unicode_table + length > endPtr)
table + unicod...ength > endPtrDescription
TRUEnever evaluated
FALSEnever evaluated
0
1354 return 0;
never executed: return 0;
0
1355 *cmapSize = length;-
1356-
1357 // To support symbol fonts that contain a unicode table for the symbol area-
1358 // we check the cmap tables and fall back to symbol font unless that would-
1359 // involve losing information from the unicode table-
1360 if (symbolTable > -1 && ((score == Unicode) || (score == Unicode11))) {
symbolTable > -1Description
TRUEnever evaluated
FALSEnever evaluated
(score == Unicode)Description
TRUEnever evaluated
FALSEnever evaluated
(score == Unicode11)Description
TRUEnever evaluated
FALSEnever evaluated
0
1361 const uchar *selectedTable = table + unicode_table;-
1362-
1363 // Check that none of the latin1 range are in the unicode table-
1364 bool unicodeTableHasLatin1 = false;-
1365 for (int uc=0x00; uc<0x100; ++uc) {
uc<0x100Description
TRUEnever evaluated
FALSEnever evaluated
0
1366 if (getTrueTypeGlyphIndex(selectedTable, length, uc) != 0) {
getTrueTypeGly...ngth, uc) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1367 unicodeTableHasLatin1 = true;-
1368 break;
never executed: break;
0
1369 }-
1370 }
never executed: end of block
0
1371-
1372 // Check that at least one symbol char is in the unicode table-
1373 bool unicodeTableHasSymbols = false;-
1374 if (!unicodeTableHasLatin1) {
!unicodeTableHasLatin1Description
TRUEnever evaluated
FALSEnever evaluated
0
1375 for (int uc=0xf000; uc<0xf100; ++uc) {
uc<0xf100Description
TRUEnever evaluated
FALSEnever evaluated
0
1376 if (getTrueTypeGlyphIndex(selectedTable, length, uc) != 0) {
getTrueTypeGly...ngth, uc) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1377 unicodeTableHasSymbols = true;-
1378 break;
never executed: break;
0
1379 }-
1380 }
never executed: end of block
0
1381 }
never executed: end of block
0
1382-
1383 // Fall back to symbol table-
1384 if (!unicodeTableHasLatin1 && unicodeTableHasSymbols) {
!unicodeTableHasLatin1Description
TRUEnever evaluated
FALSEnever evaluated
unicodeTableHasSymbolsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1385 tableToUse = symbolTable;-
1386 score = Symbol;-
1387 goto resolveTable;
never executed: goto resolveTable;
0
1388 }-
1389 }
never executed: end of block
0
1390-
1391 return table + unicode_table;
never executed: return table + unicode_table;
0
1392}-
1393-
1394quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode)-
1395{-
1396 const uchar *end = cmap + cmapSize;-
1397 quint16 format;-
1398 if (!qSafeFromBigEndian(cmap, end, &format))
!qSafeFromBigE... end, &format)Description
TRUEnever evaluated
FALSEnever evaluated
0
1399 return 0;
never executed: return 0;
0
1400-
1401 if (format == 0) {
format == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1402 const uchar *ptr = cmap + 6 + unicode;-
1403 if (unicode < 256 && ptr < end)
unicode < 256Description
TRUEnever evaluated
FALSEnever evaluated
ptr < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
1404 return quint32(*ptr);
never executed: return quint32(*ptr);
0
1405 } else if (format == 4) {
never executed: end of block
format == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1406 /* some fonts come with invalid cmap tables, where the last segment-
1407 specified end = start = rangeoffset = 0xffff, delta = 0x0001-
1408 Since 0xffff is never a valid Unicode char anyway, we just get rid of the issue-
1409 by returning 0 for 0xffff-
1410 */-
1411 if(unicode >= 0xffff)
unicode >= 0xffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
1412 return 0;
never executed: return 0;
0
1413-
1414 quint16 segCountX2;-
1415 if (!qSafeFromBigEndian(cmap + 6, end, &segCountX2))
!qSafeFromBigE..., &segCountX2)Description
TRUEnever evaluated
FALSEnever evaluated
0
1416 return 0;
never executed: return 0;
0
1417-
1418 const unsigned char *ends = cmap + 14;-
1419-
1420 int i = 0;-
1421 for (; i < segCountX2/2; ++i) {
i < segCountX2/2Description
TRUEnever evaluated
FALSEnever evaluated
0
1422 quint16 codePoint;-
1423 if (!qSafeFromBigEndian(ends + 2 * i, end, &codePoint))
!qSafeFromBigE...d, &codePoint)Description
TRUEnever evaluated
FALSEnever evaluated
0
1424 return 0;
never executed: return 0;
0
1425 if (codePoint >= unicode)
codePoint >= unicodeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1426 break;
never executed: break;
0
1427 }
never executed: end of block
0
1428-
1429 const unsigned char *idx = ends + segCountX2 + 2 + 2*i;-
1430-
1431 quint16 startIndex;-
1432 if (!qSafeFromBigEndian(idx, end, &startIndex))
!qSafeFromBigE..., &startIndex)Description
TRUEnever evaluated
FALSEnever evaluated
0
1433 return 0;
never executed: return 0;
0
1434 if (startIndex > unicode)
startIndex > unicodeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1435 return 0;
never executed: return 0;
0
1436-
1437 idx += segCountX2;-
1438-
1439 quint16 tmp;-
1440 if (!qSafeFromBigEndian(idx, end, &tmp))
!qSafeFromBigE...dx, end, &tmp)Description
TRUEnever evaluated
FALSEnever evaluated
0
1441 return 0;
never executed: return 0;
0
1442 qint16 idDelta = qint16(tmp);-
1443-
1444 idx += segCountX2;-
1445-
1446 quint16 idRangeoffset_t;-
1447 if (!qSafeFromBigEndian(idx, end, &idRangeoffset_t))
!qSafeFromBigE...Rangeoffset_t)Description
TRUEnever evaluated
FALSEnever evaluated
0
1448 return 0;
never executed: return 0;
0
1449-
1450 quint16 glyphIndex;-
1451 if (idRangeoffset_t) {
idRangeoffset_tDescription
TRUEnever evaluated
FALSEnever evaluated
0
1452 quint16 id;-
1453 if (!qSafeFromBigEndian(idRangeoffset_t + 2 * (unicode - startIndex) + idx, end, &id))
!qSafeFromBigE...idx, end, &id)Description
TRUEnever evaluated
FALSEnever evaluated
0
1454 return 0;
never executed: return 0;
0
1455-
1456 if (id)
idDescription
TRUEnever evaluated
FALSEnever evaluated
0
1457 glyphIndex = (idDelta + id) % 0x10000;
never executed: glyphIndex = (idDelta + id) % 0x10000;
0
1458 else-
1459 glyphIndex = 0;
never executed: glyphIndex = 0;
0
1460 } else {-
1461 glyphIndex = (idDelta + unicode) % 0x10000;-
1462 }
never executed: end of block
0
1463 return glyphIndex;
never executed: return glyphIndex;
0
1464 } else if (format == 6) {
format == 6Description
TRUEnever evaluated
FALSEnever evaluated
0
1465 quint16 tableSize;-
1466 if (!qSafeFromBigEndian(cmap + 2, end, &tableSize))
!qSafeFromBigE...d, &tableSize)Description
TRUEnever evaluated
FALSEnever evaluated
0
1467 return 0;
never executed: return 0;
0
1468-
1469 quint16 firstCode6;-
1470 if (!qSafeFromBigEndian(cmap + 6, end, &firstCode6))
!qSafeFromBigE..., &firstCode6)Description
TRUEnever evaluated
FALSEnever evaluated
0
1471 return 0;
never executed: return 0;
0
1472 if (unicode < firstCode6)
unicode < firstCode6Description
TRUEnever evaluated
FALSEnever evaluated
0
1473 return 0;
never executed: return 0;
0
1474-
1475 quint16 entryCount6;-
1476 if (!qSafeFromBigEndian(cmap + 8, end, &entryCount6))
!qSafeFromBigE... &entryCount6)Description
TRUEnever evaluated
FALSEnever evaluated
0
1477 return 0;
never executed: return 0;
0
1478 if (entryCount6 * 2 + 10 > tableSize)
entryCount6 * ...10 > tableSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1479 return 0;
never executed: return 0;
0
1480-
1481 quint16 sentinel6 = firstCode6 + entryCount6;-
1482 if (unicode >= sentinel6)
unicode >= sentinel6Description
TRUEnever evaluated
FALSEnever evaluated
0
1483 return 0;
never executed: return 0;
0
1484-
1485 quint16 entryIndex6 = unicode - firstCode6;-
1486-
1487 quint16 index = 0;-
1488 qSafeFromBigEndian(cmap + 10 + (entryIndex6 * 2), end, &index);-
1489 return index;
never executed: return index;
0
1490 } else if (format == 12) {
format == 12Description
TRUEnever evaluated
FALSEnever evaluated
0
1491 quint32 nGroups;-
1492 if (!qSafeFromBigEndian(cmap + 12, end, &nGroups))
!qSafeFromBigE...end, &nGroups)Description
TRUEnever evaluated
FALSEnever evaluated
0
1493 return 0;
never executed: return 0;
0
1494-
1495 cmap += 16; // move to start of groups-
1496-
1497 int left = 0, right = nGroups - 1;-
1498 while (left <= right) {
left <= rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1499 int middle = left + ( ( right - left ) >> 1 );-
1500-
1501 quint32 startCharCode;-
1502 if (!qSafeFromBigEndian(cmap + 12 * middle, end, &startCharCode))
!qSafeFromBigE...startCharCode)Description
TRUEnever evaluated
FALSEnever evaluated
0
1503 return 0;
never executed: return 0;
0
1504-
1505 if(unicode < startCharCode)
unicode < startCharCodeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1506 right = middle - 1;
never executed: right = middle - 1;
0
1507 else {-
1508 quint32 endCharCode;-
1509 if (!qSafeFromBigEndian(cmap + 12 * middle + 4, end, &endCharCode))
!qSafeFromBigE... &endCharCode)Description
TRUEnever evaluated
FALSEnever evaluated
0
1510 return 0;
never executed: return 0;
0
1511-
1512 if (unicode <= endCharCode) {
unicode <= endCharCodeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1513 quint32 index;-
1514 if (!qSafeFromBigEndian(cmap + 12 * middle + 8, end, &index))
!qSafeFromBigE..., end, &index)Description
TRUEnever evaluated
FALSEnever evaluated
0
1515 return 0;
never executed: return 0;
0
1516-
1517 return index + unicode - startCharCode;
never executed: return index + unicode - startCharCode;
0
1518 }-
1519 left = middle + 1;-
1520 }
never executed: end of block
0
1521 }-
1522 } else {
never executed: end of block
0
1523 qDebug("cmap table of format %d not implemented", format);-
1524 }
never executed: end of block
0
1525-
1526 return 0;
never executed: return 0;
0
1527}-
1528-
1529QByteArray QFontEngine::convertToPostscriptFontFamilyName(const QByteArray &family)-
1530{-
1531 QByteArray f = family;-
1532 f.replace(' ', "");-
1533 f.replace('(', "");-
1534 f.replace(')', "");-
1535 f.replace('<', "");-
1536 f.replace('>', "");-
1537 f.replace('[', "");-
1538 f.replace(']', "");-
1539 f.replace('{', "");-
1540 f.replace('}', "");-
1541 f.replace('/', "");-
1542 f.replace('%', "");-
1543 return f;
never executed: return f;
0
1544}-
1545-
1546// Allow font engines (e.g. Windows) that can not reliably create-
1547// outline paths for distance-field rendering to switch the scene-
1548// graph over to native text rendering.-
1549bool QFontEngine::hasUnreliableGlyphOutline() const-
1550{-
1551 // Color glyphs (Emoji) are generally not suited for outlining-
1552 return glyphFormat == QFontEngine::Format_ARGB;
never executed: return glyphFormat == QFontEngine::Format_ARGB;
0
1553}-
1554-
1555QFixed QFontEngine::lastRightBearing(const QGlyphLayout &glyphs, bool round)-
1556{-
1557 if (glyphs.numGlyphs >= 1) {
glyphs.numGlyphs >= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1558 glyph_t glyph = glyphs.glyphs[glyphs.numGlyphs - 1];-
1559 glyph_metrics_t gi = boundingBox(glyph);-
1560 if (gi.isValid())
gi.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1561 return round ? qRound(gi.rightBearing()) : gi.rightBearing();
never executed: return round ? qRound(gi.rightBearing()) : gi.rightBearing();
roundDescription
TRUEnever evaluated
FALSEnever evaluated
0
1562 }
never executed: end of block
0
1563 return 0;
never executed: return 0;
0
1564}-
1565-
1566-
1567QFontEngine::GlyphCacheEntry::GlyphCacheEntry()-
1568{-
1569}-
1570-
1571QFontEngine::GlyphCacheEntry::GlyphCacheEntry(const GlyphCacheEntry &o)-
1572 : cache(o.cache)-
1573{-
1574}
never executed: end of block
0
1575-
1576QFontEngine::GlyphCacheEntry::~GlyphCacheEntry()-
1577{-
1578}-
1579-
1580QFontEngine::GlyphCacheEntry &QFontEngine::GlyphCacheEntry::operator=(const GlyphCacheEntry &o)-
1581{-
1582 cache = o.cache;-
1583 return *this;
never executed: return *this;
0
1584}-
1585-
1586// -------------------------------------------------------------------
1587// The box font engine-
1588// -------------------------------------------------------------------
1589-
1590QFontEngineBox::QFontEngineBox(int size)-
1591 : QFontEngine(Box),-
1592 _size(size)-
1593{-
1594 cache_cost = sizeof(QFontEngineBox);-
1595}
never executed: end of block
0
1596-
1597QFontEngineBox::QFontEngineBox(Type type, int size)-
1598 : QFontEngine(type),-
1599 _size(size)-
1600{-
1601 cache_cost = sizeof(QFontEngineBox);-
1602}
never executed: end of block
0
1603-
1604QFontEngineBox::~QFontEngineBox()-
1605{-
1606}-
1607-
1608glyph_t QFontEngineBox::glyphIndex(uint ucs4) const-
1609{-
1610 Q_UNUSED(ucs4)-
1611 return 0;
never executed: return 0;
0
1612}-
1613-
1614bool QFontEngineBox::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const-
1615{-
1616 Q_ASSERT(glyphs->numGlyphs >= *nglyphs);-
1617 if (*nglyphs < len) {
*nglyphs < lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1618 *nglyphs = len;-
1619 return false;
never executed: return false;
0
1620 }-
1621-
1622 int ucs4Length = 0;-
1623 QStringIterator it(str, str + len);-
1624 while (it.hasNext()) {
it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
1625 it.advance();-
1626 glyphs->glyphs[ucs4Length++] = 0;-
1627 }
never executed: end of block
0
1628-
1629 *nglyphs = ucs4Length;-
1630 glyphs->numGlyphs = ucs4Length;-
1631-
1632 if (!(flags & GlyphIndicesOnly))
!(flags & GlyphIndicesOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
1633 recalcAdvances(glyphs, flags);
never executed: recalcAdvances(glyphs, flags);
0
1634-
1635 return true;
never executed: return true;
0
1636}-
1637-
1638void QFontEngineBox::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const-
1639{-
1640 for (int i = 0; i < glyphs->numGlyphs; i++)
i < glyphs->numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1641 glyphs->advances[i] = _size;
never executed: glyphs->advances[i] = _size;
0
1642}
never executed: end of block
0
1643-
1644void QFontEngineBox::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)-
1645{-
1646 if (!glyphs.numGlyphs)
!glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1647 return;
never executed: return;
0
1648-
1649 QVarLengthArray<QFixedPoint> positions;-
1650 QVarLengthArray<glyph_t> positioned_glyphs;-
1651 QTransform matrix = QTransform::fromTranslate(x, y - _size);-
1652 getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions);-
1653-
1654 QSize s(_size - 3, _size - 3);-
1655 for (int k = 0; k < positions.size(); k++)
k < positions.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1656 path->addRect(QRectF(positions[k].toPointF(), s));
never executed: path->addRect(QRectF(positions[k].toPointF(), s));
0
1657}
never executed: end of block
0
1658-
1659glyph_metrics_t QFontEngineBox::boundingBox(const QGlyphLayout &glyphs)-
1660{-
1661 glyph_metrics_t overall;-
1662 overall.width = _size*glyphs.numGlyphs;-
1663 overall.height = _size;-
1664 overall.xoff = overall.width;-
1665 return overall;
never executed: return overall;
0
1666}-
1667-
1668void QFontEngineBox::draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &ti)-
1669{-
1670 if (!ti.glyphs.numGlyphs)
!ti.glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1671 return;
never executed: return;
0
1672-
1673 // any fixes here should probably also be done in QPaintEnginePrivate::drawBoxTextItem-
1674 QSize s(_size - 3, _size - 3);-
1675-
1676 QVarLengthArray<QFixedPoint> positions;-
1677 QVarLengthArray<glyph_t> glyphs;-
1678 QTransform matrix = QTransform::fromTranslate(x, y - _size);-
1679 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);-
1680 if (glyphs.size() == 0)
glyphs.size() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1681 return;
never executed: return;
0
1682-
1683-
1684 QPainter *painter = p->painter();-
1685 painter->save();-
1686 painter->setBrush(Qt::NoBrush);-
1687 QPen pen = painter->pen();-
1688 pen.setWidthF(lineThickness().toReal());-
1689 painter->setPen(pen);-
1690 for (int k = 0; k < positions.size(); k++)
k < positions.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1691 painter->drawRect(QRectF(positions[k].toPointF(), s));
never executed: painter->drawRect(QRectF(positions[k].toPointF(), s));
0
1692 painter->restore();-
1693}
never executed: end of block
0
1694-
1695glyph_metrics_t QFontEngineBox::boundingBox(glyph_t)-
1696{-
1697 return glyph_metrics_t(0, -_size, _size, _size, _size, 0);
never executed: return glyph_metrics_t(0, -_size, _size, _size, _size, 0);
0
1698}-
1699-
1700QFontEngine *QFontEngineBox::cloneWithSize(qreal pixelSize) const-
1701{-
1702 QFontEngineBox *fe = new QFontEngineBox(pixelSize);-
1703 return fe;
never executed: return fe;
0
1704}-
1705-
1706QFixed QFontEngineBox::ascent() const-
1707{-
1708 return _size;
never executed: return _size;
0
1709}-
1710-
1711QFixed QFontEngineBox::descent() const-
1712{-
1713 return 0;
never executed: return 0;
0
1714}-
1715-
1716QFixed QFontEngineBox::leading() const-
1717{-
1718 QFixed l = _size * QFixed::fromReal(qreal(0.15));-
1719 return l.ceil();
never executed: return l.ceil();
0
1720}-
1721-
1722qreal QFontEngineBox::maxCharWidth() const-
1723{-
1724 return _size;
never executed: return _size;
0
1725}-
1726-
1727bool QFontEngineBox::canRender(const QChar *, int) const-
1728{-
1729 return true;
never executed: return true;
0
1730}-
1731-
1732QImage QFontEngineBox::alphaMapForGlyph(glyph_t)-
1733{-
1734 QImage image(_size, _size, QImage::Format_Alpha8);-
1735 image.fill(0);-
1736-
1737 // FIXME: use qpainter-
1738 for (int i=2; i <= _size-3; ++i) {
i <= _size-3Description
TRUEnever evaluated
FALSEnever evaluated
0
1739 image.setPixel(i, 2, 255);-
1740 image.setPixel(i, _size-3, 255);-
1741 image.setPixel(2, i, 255);-
1742 image.setPixel(_size-3, i, 255);-
1743 }
never executed: end of block
0
1744 return image;
never executed: return image;
0
1745}-
1746-
1747// -------------------------------------------------------------------
1748// Multi engine-
1749// -------------------------------------------------------------------
1750-
1751static inline uchar highByte(glyph_t glyph)-
1752{
never executed: return glyph >> 24;
return glyph >> 24; }
never executed: return glyph >> 24;
0
1753-
1754// strip high byte from glyph-
1755static inline glyph_t stripped(glyph_t glyph)-
1756{
never executed: return glyph & 0x00ffffff;
return glyph & 0x00ffffff; }
never executed: return glyph & 0x00ffffff;
0
1757-
1758QFontEngineMulti::QFontEngineMulti(QFontEngine *engine, int script, const QStringList &fallbackFamilies)-
1759 : QFontEngine(Multi),-
1760 m_fallbackFamilies(fallbackFamilies),-
1761 m_script(script),-
1762 m_fallbackFamiliesQueried(!m_fallbackFamilies.isEmpty())-
1763{-
1764 Q_ASSERT(engine && engine->type() != QFontEngine::Multi);-
1765-
1766 if (m_fallbackFamilies.isEmpty()) {
m_fallbackFamilies.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1767 // defer obtaining the fallback families until loadEngine(1)-
1768 m_fallbackFamilies << QString();-
1769 }
never executed: end of block
0
1770-
1771 m_engines.resize(m_fallbackFamilies.size() + 1);-
1772-
1773 engine->ref.ref();-
1774 m_engines[0] = engine;-
1775-
1776 fontDef = engine->fontDef;-
1777 cache_cost = engine->cache_cost;-
1778}
never executed: end of block
0
1779-
1780QFontEngineMulti::~QFontEngineMulti()-
1781{-
1782 for (int i = 0; i < m_engines.size(); ++i) {
i < m_engines.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1783 QFontEngine *fontEngine = m_engines.at(i);-
1784 if (fontEngine && !fontEngine->ref.deref())
fontEngineDescription
TRUEnever evaluated
FALSEnever evaluated
!fontEngine->ref.deref()Description
TRUEnever evaluated
FALSEnever evaluated
0
1785 delete fontEngine;
never executed: delete fontEngine;
0
1786 }
never executed: end of block
0
1787}
never executed: end of block
0
1788-
1789QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script);-
1790-
1791void QFontEngineMulti::ensureFallbackFamiliesQueried()-
1792{-
1793 QFont::StyleHint styleHint = QFont::StyleHint(fontDef.styleHint);-
1794 if (styleHint == QFont::AnyStyle && fontDef.fixedPitch)
styleHint == QFont::AnyStyleDescription
TRUEnever evaluated
FALSEnever evaluated
fontDef.fixedPitchDescription
TRUEnever evaluated
FALSEnever evaluated
0
1795 styleHint = QFont::TypeWriter;
never executed: styleHint = QFont::TypeWriter;
0
1796-
1797 setFallbackFamiliesList(qt_fallbacksForFamily(fontDef.family, QFont::Style(fontDef.style), styleHint, QChar::Script(m_script)));-
1798}
never executed: end of block
0
1799-
1800void QFontEngineMulti::setFallbackFamiliesList(const QStringList &fallbackFamilies)-
1801{-
1802 Q_ASSERT(!m_fallbackFamiliesQueried);-
1803-
1804 m_fallbackFamilies = fallbackFamilies;-
1805 if (m_fallbackFamilies.isEmpty()) {
m_fallbackFamilies.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1806 // turns out we lied about having any fallback at all-
1807 Q_ASSERT(m_engines.size() == 2); // see c-tor for details-
1808 QFontEngine *engine = m_engines.at(0);-
1809 engine->ref.ref();-
1810 m_engines[1] = engine;-
1811 m_fallbackFamilies << fontDef.family;-
1812 } else {
never executed: end of block
0
1813 m_engines.resize(m_fallbackFamilies.size() + 1);-
1814 }
never executed: end of block
0
1815-
1816 m_fallbackFamiliesQueried = true;-
1817}
never executed: end of block
0
1818-
1819void QFontEngineMulti::ensureEngineAt(int at)-
1820{-
1821 if (!m_fallbackFamiliesQueried)
!m_fallbackFamiliesQueriedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1822 ensureFallbackFamiliesQueried();
never executed: ensureFallbackFamiliesQueried();
0
1823 Q_ASSERT(at < m_engines.size());-
1824 if (!m_engines.at(at)) {
!m_engines.at(at)Description
TRUEnever evaluated
FALSEnever evaluated
0
1825 QFontEngine *engine = loadEngine(at);-
1826 if (!engine)
!engineDescription
TRUEnever evaluated
FALSEnever evaluated
0
1827 engine = new QFontEngineBox(fontDef.pixelSize);
never executed: engine = new QFontEngineBox(fontDef.pixelSize);
0
1828 Q_ASSERT(engine && engine->type() != QFontEngine::Multi);-
1829 engine->ref.ref();-
1830 m_engines[at] = engine;-
1831 }
never executed: end of block
0
1832}
never executed: end of block
0
1833-
1834QFontEngine *QFontEngineMulti::loadEngine(int at)-
1835{-
1836 QFontDef request(fontDef);-
1837 request.styleStrategy |= QFont::NoFontMerging;-
1838 request.family = fallbackFamilyAt(at - 1);-
1839-
1840 if (QFontEngine *engine = QFontDatabase::findFont(request, m_script)) {
QFontEngine *e...est, m_script)Description
TRUEnever evaluated
FALSEnever evaluated
0
1841 engine->fontDef.weight = request.weight;-
1842 if (request.style > QFont::StyleNormal)
request.style ...t::StyleNormalDescription
TRUEnever evaluated
FALSEnever evaluated
0
1843 engine->fontDef.style = request.style;
never executed: engine->fontDef.style = request.style;
0
1844 return engine;
never executed: return engine;
0
1845 }-
1846-
1847 return 0;
never executed: return 0;
0
1848}-
1849-
1850glyph_t QFontEngineMulti::glyphIndex(uint ucs4) const-
1851{-
1852 glyph_t glyph = engine(0)->glyphIndex(ucs4);-
1853 if (glyph == 0 && ucs4 != QChar::LineSeparator) {
glyph == 0Description
TRUEnever evaluated
FALSEnever evaluated
ucs4 != QChar::LineSeparatorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1854 if (!m_fallbackFamiliesQueried)
!m_fallbackFamiliesQueriedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1855 const_cast<QFontEngineMulti *>(this)->ensureFallbackFamiliesQueried();
never executed: const_cast<QFontEngineMulti *>(this)->ensureFallbackFamiliesQueried();
0
1856 for (int x = 1, n = qMin(m_engines.size(), 256); x < n; ++x) {
x < nDescription
TRUEnever evaluated
FALSEnever evaluated
0
1857 QFontEngine *engine = m_engines.at(x);-
1858 if (!engine) {
!engineDescription
TRUEnever evaluated
FALSEnever evaluated
0
1859 if (!shouldLoadFontEngineForCharacter(x, ucs4))
!shouldLoadFon...acter(x, ucs4)Description
TRUEnever evaluated
FALSEnever evaluated
0
1860 continue;
never executed: continue;
0
1861 const_cast<QFontEngineMulti *>(this)->ensureEngineAt(x);-
1862 engine = m_engines.at(x);-
1863 }
never executed: end of block
0
1864 Q_ASSERT(engine != 0);-
1865 if (engine->type() == Box)
engine->type() == BoxDescription
TRUEnever evaluated
FALSEnever evaluated
0
1866 continue;
never executed: continue;
0
1867-
1868 glyph = engine->glyphIndex(ucs4);-
1869 if (glyph != 0) {
glyph != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1870 // set the high byte to indicate which engine the glyph came from-
1871 glyph |= (x << 24);-
1872 break;
never executed: break;
0
1873 }-
1874 }
never executed: end of block
0
1875 }
never executed: end of block
0
1876-
1877 return glyph;
never executed: return glyph;
0
1878}-
1879-
1880bool QFontEngineMulti::stringToCMap(const QChar *str, int len,-
1881 QGlyphLayout *glyphs, int *nglyphs,-
1882 QFontEngine::ShaperFlags flags) const-
1883{-
1884 if (!engine(0)->stringToCMap(str, len, glyphs, nglyphs, flags))
!engine(0)->st...glyphs, flags)Description
TRUEnever evaluated
FALSEnever evaluated
0
1885 return false;
never executed: return false;
0
1886-
1887 int glyph_pos = 0;-
1888 QStringIterator it(str, str + len);-
1889 while (it.hasNext()) {
it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
1890 const uint ucs4 = it.peekNext();-
1891 if (glyphs->glyphs[glyph_pos] == 0 && ucs4 != QChar::LineSeparator) {
glyphs->glyphs[glyph_pos] == 0Description
TRUEnever evaluated
FALSEnever evaluated
ucs4 != QChar::LineSeparatorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1892 if (!m_fallbackFamiliesQueried)
!m_fallbackFamiliesQueriedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1893 const_cast<QFontEngineMulti *>(this)->ensureFallbackFamiliesQueried();
never executed: const_cast<QFontEngineMulti *>(this)->ensureFallbackFamiliesQueried();
0
1894 for (int x = 1, n = qMin(m_engines.size(), 256); x < n; ++x) {
x < nDescription
TRUEnever evaluated
FALSEnever evaluated
0
1895 QFontEngine *engine = m_engines.at(x);-
1896 if (!engine) {
!engineDescription
TRUEnever evaluated
FALSEnever evaluated
0
1897 if (!shouldLoadFontEngineForCharacter(x, ucs4))
!shouldLoadFon...acter(x, ucs4)Description
TRUEnever evaluated
FALSEnever evaluated
0
1898 continue;
never executed: continue;
0
1899 const_cast<QFontEngineMulti *>(this)->ensureEngineAt(x);-
1900 engine = m_engines.at(x);-
1901 if (!engine)
!engineDescription
TRUEnever evaluated
FALSEnever evaluated
0
1902 continue;
never executed: continue;
0
1903 }
never executed: end of block
0
1904 Q_ASSERT(engine != 0);-
1905 if (engine->type() == Box)
engine->type() == BoxDescription
TRUEnever evaluated
FALSEnever evaluated
0
1906 continue;
never executed: continue;
0
1907-
1908 glyph_t glyph = engine->glyphIndex(ucs4);-
1909 if (glyph != 0) {
glyph != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1910 glyphs->glyphs[glyph_pos] = glyph;-
1911 if (!(flags & GlyphIndicesOnly)) {
!(flags & GlyphIndicesOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
1912 QGlyphLayout g = glyphs->mid(glyph_pos, 1);-
1913 engine->recalcAdvances(&g, flags);-
1914 }
never executed: end of block
0
1915 // set the high byte to indicate which engine the glyph came from-
1916 glyphs->glyphs[glyph_pos] |= (x << 24);-
1917 break;
never executed: break;
0
1918 }-
1919 }
never executed: end of block
0
1920 }
never executed: end of block
0
1921-
1922 it.advance();-
1923 ++glyph_pos;-
1924 }
never executed: end of block
0
1925-
1926 *nglyphs = glyph_pos;-
1927 glyphs->numGlyphs = glyph_pos;-
1928-
1929 return true;
never executed: return true;
0
1930}-
1931-
1932bool QFontEngineMulti::shouldLoadFontEngineForCharacter(int at, uint ucs4) const-
1933{-
1934 Q_UNUSED(at);-
1935 Q_UNUSED(ucs4);-
1936 return true;
never executed: return true;
0
1937}-
1938-
1939glyph_metrics_t QFontEngineMulti::boundingBox(const QGlyphLayout &glyphs)-
1940{-
1941 if (glyphs.numGlyphs <= 0)
glyphs.numGlyphs <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1942 return glyph_metrics_t();
never executed: return glyph_metrics_t();
0
1943-
1944 glyph_metrics_t overall;-
1945-
1946 int which = highByte(glyphs.glyphs[0]);-
1947 int start = 0;-
1948 int end, i;-
1949 for (end = 0; end < glyphs.numGlyphs; ++end) {
end < glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1950 const int e = highByte(glyphs.glyphs[end]);-
1951 if (e == which)
e == whichDescription
TRUEnever evaluated
FALSEnever evaluated
0
1952 continue;
never executed: continue;
0
1953-
1954 // set the high byte to zero-
1955 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
1956 glyphs.glyphs[i] = stripped(glyphs.glyphs[i]);
never executed: glyphs.glyphs[i] = stripped(glyphs.glyphs[i]);
0
1957-
1958 // merge the bounding box for this run-
1959 const glyph_metrics_t gm = engine(which)->boundingBox(glyphs.mid(start, end - start));-
1960-
1961 overall.x = qMin(overall.x, gm.x);-
1962 overall.y = qMin(overall.y, gm.y);-
1963 overall.width = overall.xoff + gm.width;-
1964 overall.height = qMax(overall.height + overall.y, gm.height + gm.y) --
1965 qMin(overall.y, gm.y);-
1966 overall.xoff += gm.xoff;-
1967 overall.yoff += gm.yoff;-
1968-
1969 // reset the high byte for all glyphs-
1970 const int hi = which << 24;-
1971 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
1972 glyphs.glyphs[i] = hi | glyphs.glyphs[i];
never executed: glyphs.glyphs[i] = hi | glyphs.glyphs[i];
0
1973-
1974 // change engine-
1975 start = end;-
1976 which = e;-
1977 }
never executed: end of block
0
1978-
1979 // set the high byte to zero-
1980 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
1981 glyphs.glyphs[i] = stripped(glyphs.glyphs[i]);
never executed: glyphs.glyphs[i] = stripped(glyphs.glyphs[i]);
0
1982-
1983 // merge the bounding box for this run-
1984 const glyph_metrics_t gm = engine(which)->boundingBox(glyphs.mid(start, end - start));-
1985-
1986 overall.x = qMin(overall.x, gm.x);-
1987 overall.y = qMin(overall.y, gm.y);-
1988 overall.width = overall.xoff + gm.width;-
1989 overall.height = qMax(overall.height + overall.y, gm.height + gm.y) --
1990 qMin(overall.y, gm.y);-
1991 overall.xoff += gm.xoff;-
1992 overall.yoff += gm.yoff;-
1993-
1994 // reset the high byte for all glyphs-
1995 const int hi = which << 24;-
1996 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
1997 glyphs.glyphs[i] = hi | glyphs.glyphs[i];
never executed: glyphs.glyphs[i] = hi | glyphs.glyphs[i];
0
1998-
1999 return overall;
never executed: return overall;
0
2000}-
2001-
2002void QFontEngineMulti::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)-
2003{-
2004 int which = highByte(glyph);-
2005 ensureEngineAt(which);-
2006 engine(which)->getGlyphBearings(stripped(glyph), leftBearing, rightBearing);-
2007}
never executed: end of block
0
2008-
2009void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,-
2010 QPainterPath *path, QTextItem::RenderFlags flags)-
2011{-
2012 if (glyphs.numGlyphs <= 0)
glyphs.numGlyphs <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2013 return;
never executed: return;
0
2014-
2015 int which = highByte(glyphs.glyphs[0]);-
2016 int start = 0;-
2017 int end, i;-
2018 if (flags & QTextItem::RightToLeft) {
flags & QTextItem::RightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
2019 for (int gl = 0; gl < glyphs.numGlyphs; gl++)
gl < glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2020 x += glyphs.advances[gl].toReal();
never executed: x += glyphs.advances[gl].toReal();
0
2021 }
never executed: end of block
0
2022 for (end = 0; end < glyphs.numGlyphs; ++end) {
end < glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2023 const int e = highByte(glyphs.glyphs[end]);-
2024 if (e == which)
e == whichDescription
TRUEnever evaluated
FALSEnever evaluated
0
2025 continue;
never executed: continue;
0
2026-
2027 if (flags & QTextItem::RightToLeft) {
flags & QTextItem::RightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
2028 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2029 x -= glyphs.advances[i].toReal();
never executed: x -= glyphs.advances[i].toReal();
0
2030 }
never executed: end of block
0
2031-
2032 // set the high byte to zero-
2033 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2034 glyphs.glyphs[i] = stripped(glyphs.glyphs[i]);
never executed: glyphs.glyphs[i] = stripped(glyphs.glyphs[i]);
0
2035 engine(which)->addOutlineToPath(x, y, glyphs.mid(start, end - start), path, flags);-
2036 // reset the high byte for all glyphs and update x and y-
2037 const int hi = which << 24;-
2038 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2039 glyphs.glyphs[i] = hi | glyphs.glyphs[i];
never executed: glyphs.glyphs[i] = hi | glyphs.glyphs[i];
0
2040-
2041 if (!(flags & QTextItem::RightToLeft)) {
!(flags & QTex...::RightToLeft)Description
TRUEnever evaluated
FALSEnever evaluated
0
2042 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2043 x += glyphs.advances[i].toReal();
never executed: x += glyphs.advances[i].toReal();
0
2044 }
never executed: end of block
0
2045-
2046 // change engine-
2047 start = end;-
2048 which = e;-
2049 }
never executed: end of block
0
2050-
2051 if (flags & QTextItem::RightToLeft) {
flags & QTextItem::RightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
2052 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2053 x -= glyphs.advances[i].toReal();
never executed: x -= glyphs.advances[i].toReal();
0
2054 }
never executed: end of block
0
2055-
2056 // set the high byte to zero-
2057 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2058 glyphs.glyphs[i] = stripped(glyphs.glyphs[i]);
never executed: glyphs.glyphs[i] = stripped(glyphs.glyphs[i]);
0
2059-
2060 engine(which)->addOutlineToPath(x, y, glyphs.mid(start, end - start), path, flags);-
2061-
2062 // reset the high byte for all glyphs-
2063 const int hi = which << 24;-
2064 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2065 glyphs.glyphs[i] = hi | glyphs.glyphs[i];
never executed: glyphs.glyphs[i] = hi | glyphs.glyphs[i];
0
2066}
never executed: end of block
0
2067-
2068void QFontEngineMulti::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const-
2069{-
2070 if (glyphs->numGlyphs <= 0)
glyphs->numGlyphs <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2071 return;
never executed: return;
0
2072-
2073 int which = highByte(glyphs->glyphs[0]);-
2074 int start = 0;-
2075 int end, i;-
2076 for (end = 0; end < glyphs->numGlyphs; ++end) {
end < glyphs->numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2077 const int e = highByte(glyphs->glyphs[end]);-
2078 if (e == which)
e == whichDescription
TRUEnever evaluated
FALSEnever evaluated
0
2079 continue;
never executed: continue;
0
2080-
2081 // set the high byte to zero-
2082 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2083 glyphs->glyphs[i] = stripped(glyphs->glyphs[i]);
never executed: glyphs->glyphs[i] = stripped(glyphs->glyphs[i]);
0
2084-
2085 QGlyphLayout offs = glyphs->mid(start, end - start);-
2086 engine(which)->recalcAdvances(&offs, flags);-
2087-
2088 // reset the high byte for all glyphs and update x and y-
2089 const int hi = which << 24;-
2090 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2091 glyphs->glyphs[i] = hi | glyphs->glyphs[i];
never executed: glyphs->glyphs[i] = hi | glyphs->glyphs[i];
0
2092-
2093 // change engine-
2094 start = end;-
2095 which = e;-
2096 }
never executed: end of block
0
2097-
2098 // set the high byte to zero-
2099 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2100 glyphs->glyphs[i] = stripped(glyphs->glyphs[i]);
never executed: glyphs->glyphs[i] = stripped(glyphs->glyphs[i]);
0
2101-
2102 QGlyphLayout offs = glyphs->mid(start, end - start);-
2103 engine(which)->recalcAdvances(&offs, flags);-
2104-
2105 // reset the high byte for all glyphs-
2106 const int hi = which << 24;-
2107 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2108 glyphs->glyphs[i] = hi | glyphs->glyphs[i];
never executed: glyphs->glyphs[i] = hi | glyphs->glyphs[i];
0
2109}
never executed: end of block
0
2110-
2111void QFontEngineMulti::doKerning(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const-
2112{-
2113 if (glyphs->numGlyphs <= 0)
glyphs->numGlyphs <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2114 return;
never executed: return;
0
2115-
2116 int which = highByte(glyphs->glyphs[0]);-
2117 int start = 0;-
2118 int end, i;-
2119 for (end = 0; end < glyphs->numGlyphs; ++end) {
end < glyphs->numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2120 const int e = highByte(glyphs->glyphs[end]);-
2121 if (e == which)
e == whichDescription
TRUEnever evaluated
FALSEnever evaluated
0
2122 continue;
never executed: continue;
0
2123-
2124 // set the high byte to zero-
2125 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2126 glyphs->glyphs[i] = stripped(glyphs->glyphs[i]);
never executed: glyphs->glyphs[i] = stripped(glyphs->glyphs[i]);
0
2127-
2128 QGlyphLayout offs = glyphs->mid(start, end - start);-
2129 engine(which)->doKerning(&offs, flags);-
2130-
2131 // reset the high byte for all glyphs and update x and y-
2132 const int hi = which << 24;-
2133 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2134 glyphs->glyphs[i] = hi | glyphs->glyphs[i];
never executed: glyphs->glyphs[i] = hi | glyphs->glyphs[i];
0
2135-
2136 // change engine-
2137 start = end;-
2138 which = e;-
2139 }
never executed: end of block
0
2140-
2141 // set the high byte to zero-
2142 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2143 glyphs->glyphs[i] = stripped(glyphs->glyphs[i]);
never executed: glyphs->glyphs[i] = stripped(glyphs->glyphs[i]);
0
2144-
2145 QGlyphLayout offs = glyphs->mid(start, end - start);-
2146 engine(which)->doKerning(&offs, flags);-
2147-
2148 // reset the high byte for all glyphs-
2149 const int hi = which << 24;-
2150 for (i = start; i < end; ++i)
i < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
2151 glyphs->glyphs[i] = hi | glyphs->glyphs[i];
never executed: glyphs->glyphs[i] = hi | glyphs->glyphs[i];
0
2152}
never executed: end of block
0
2153-
2154glyph_metrics_t QFontEngineMulti::boundingBox(glyph_t glyph)-
2155{-
2156 const int which = highByte(glyph);-
2157 return engine(which)->boundingBox(stripped(glyph));
never executed: return engine(which)->boundingBox(stripped(glyph));
0
2158}-
2159-
2160QFixed QFontEngineMulti::ascent() const-
2161{
never executed: return engine(0)->ascent();
return engine(0)->ascent(); }
never executed: return engine(0)->ascent();
0
2162-
2163QFixed QFontEngineMulti::descent() const-
2164{
never executed: return engine(0)->descent();
return engine(0)->descent(); }
never executed: return engine(0)->descent();
0
2165-
2166QFixed QFontEngineMulti::leading() const-
2167{-
2168 return engine(0)->leading();
never executed: return engine(0)->leading();
0
2169}-
2170-
2171QFixed QFontEngineMulti::xHeight() const-
2172{-
2173 return engine(0)->xHeight();
never executed: return engine(0)->xHeight();
0
2174}-
2175-
2176QFixed QFontEngineMulti::averageCharWidth() const-
2177{-
2178 return engine(0)->averageCharWidth();
never executed: return engine(0)->averageCharWidth();
0
2179}-
2180-
2181QFixed QFontEngineMulti::lineThickness() const-
2182{-
2183 return engine(0)->lineThickness();
never executed: return engine(0)->lineThickness();
0
2184}-
2185-
2186QFixed QFontEngineMulti::underlinePosition() const-
2187{-
2188 return engine(0)->underlinePosition();
never executed: return engine(0)->underlinePosition();
0
2189}-
2190-
2191qreal QFontEngineMulti::maxCharWidth() const-
2192{-
2193 return engine(0)->maxCharWidth();
never executed: return engine(0)->maxCharWidth();
0
2194}-
2195-
2196qreal QFontEngineMulti::minLeftBearing() const-
2197{-
2198 return engine(0)->minLeftBearing();
never executed: return engine(0)->minLeftBearing();
0
2199}-
2200-
2201qreal QFontEngineMulti::minRightBearing() const-
2202{-
2203 return engine(0)->minRightBearing();
never executed: return engine(0)->minRightBearing();
0
2204}-
2205-
2206bool QFontEngineMulti::canRender(const QChar *string, int len) const-
2207{-
2208 if (engine(0)->canRender(string, len))
engine(0)->can...r(string, len)Description
TRUEnever evaluated
FALSEnever evaluated
0
2209 return true;
never executed: return true;
0
2210-
2211 int nglyphs = len;-
2212-
2213 QVarLengthArray<glyph_t> glyphs(nglyphs);-
2214-
2215 QGlyphLayout g;-
2216 g.numGlyphs = nglyphs;-
2217 g.glyphs = glyphs.data();-
2218 if (!stringToCMap(string, len, &g, &nglyphs, GlyphIndicesOnly))
!stringToCMap(...phIndicesOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
2219 Q_UNREACHABLE();
never executed: end of block
0
2220-
2221 for (int i = 0; i < nglyphs; i++) {
i < nglyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2222 if (glyphs[i] == 0)
glyphs[i] == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2223 return false;
never executed: return false;
0
2224 }
never executed: end of block
0
2225-
2226 return true;
never executed: return true;
0
2227}-
2228-
2229/* Implement alphaMapForGlyph() which is called by Lighthouse/Windows code.-
2230 * Ideally, that code should be fixed to correctly handle QFontEngineMulti. */-
2231-
2232QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph)-
2233{-
2234 const int which = highByte(glyph);-
2235 return engine(which)->alphaMapForGlyph(stripped(glyph));
never executed: return engine(which)->alphaMapForGlyph(stripped(glyph));
0
2236}-
2237-
2238QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)-
2239{-
2240 const int which = highByte(glyph);-
2241 return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition);
never executed: return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition);
0
2242}-
2243-
2244QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, const QTransform &t)-
2245{-
2246 const int which = highByte(glyph);-
2247 return engine(which)->alphaMapForGlyph(stripped(glyph), t);
never executed: return engine(which)->alphaMapForGlyph(stripped(glyph), t);
0
2248}-
2249-
2250QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)-
2251{-
2252 const int which = highByte(glyph);-
2253 return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition, t);
never executed: return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition, t);
0
2254}-
2255-
2256QImage QFontEngineMulti::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)-
2257{-
2258 const int which = highByte(glyph);-
2259 return engine(which)->alphaRGBMapForGlyph(stripped(glyph), subPixelPosition, t);
never executed: return engine(which)->alphaRGBMapForGlyph(stripped(glyph), subPixelPosition, t);
0
2260}-
2261-
2262/*-
2263 This is used indirectly by Qt WebKit when using QTextLayout::setRawFont-
2264-
2265 The purpose of this is to provide the necessary font fallbacks when drawing complex-
2266 text. Since Qt WebKit ends up repeatedly creating QTextLayout instances and passing them-
2267 the same raw font over and over again, we want to cache the corresponding multi font engine-
2268 as it may contain fallback font engines already.-
2269*/-
2270QFontEngine *QFontEngineMulti::createMultiFontEngine(QFontEngine *fe, int script)-
2271{-
2272 QFontEngine *engine = 0;-
2273 QFontCache::Key key(fe->fontDef, script, /*multi = */true);-
2274 QFontCache *fc = QFontCache::instance();-
2275 // We can't rely on the fontDef (and hence the cache Key)-
2276 // alone to distinguish webfonts, since these should not be-
2277 // accidentally shared, even if the resulting fontcache key-
2278 // is strictly identical. See:-
2279 // http://www.w3.org/TR/css3-fonts/#font-face-rule-
2280 const bool faceIsLocal = !fe->faceId().filename.isEmpty();-
2281 QFontCache::EngineCache::Iterator it = fc->engineCache.find(key),-
2282 end = fc->engineCache.end();-
2283 while (it != end && it.key() == key) {
it != endDescription
TRUEnever evaluated
FALSEnever evaluated
it.key() == keyDescription
TRUEnever evaluated
FALSEnever evaluated
0
2284 Q_ASSERT(it.value().data->type() == QFontEngine::Multi);-
2285 QFontEngineMulti *cachedEngine = static_cast<QFontEngineMulti *>(it.value().data);-
2286 if (fe == cachedEngine->engine(0) || (faceIsLocal && fe->faceId().filename == cachedEngine->engine(0)->faceId().filename)) {
fe == cachedEngine->engine(0)Description
TRUEnever evaluated
FALSEnever evaluated
faceIsLocalDescription
TRUEnever evaluated
FALSEnever evaluated
fe->faceId().f...eId().filenameDescription
TRUEnever evaluated
FALSEnever evaluated
0
2287 engine = cachedEngine;-
2288 fc->updateHitCountAndTimeStamp(it.value());-
2289 break;
never executed: break;
0
2290 }-
2291 ++it;-
2292 }
never executed: end of block
0
2293 if (!engine) {
!engineDescription
TRUEnever evaluated
FALSEnever evaluated
0
2294 engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script));-
2295 fc->insertEngine(key, engine, /* insertMulti */ !faceIsLocal);-
2296 }
never executed: end of block
0
2297 Q_ASSERT(engine);-
2298 return engine;
never executed: return engine;
0
2299}-
2300-
2301QTestFontEngine::QTestFontEngine(int size)-
2302 : QFontEngineBox(TestFontEngine, size)-
2303{}
never executed: end of block
0
2304-
2305QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9