qharfbuzzng.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/text/qharfbuzzng.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Copyright (C) 2013 Konstantin Ritt-
5** Contact: https://www.qt.io/licensing/-
6**-
7** This file is part of the QtGui module of the Qt Toolkit.-
8**-
9** $QT_BEGIN_LICENSE:LGPL$-
10** Commercial License Usage-
11** Licensees holding valid commercial Qt licenses may use this file in-
12** accordance with the commercial license agreement provided with the-
13** Software or, alternatively, in accordance with the terms contained in-
14** a written agreement between you and The Qt Company. For licensing terms-
15** and conditions see https://www.qt.io/terms-conditions. For further-
16** information use the contact form at https://www.qt.io/contact-us.-
17**-
18** GNU Lesser General Public License Usage-
19** Alternatively, this file may be used under the terms of the GNU Lesser-
20** General Public License version 3 as published by the Free Software-
21** Foundation and appearing in the file LICENSE.LGPL3 included in the-
22** packaging of this file. Please review the following information to-
23** ensure the GNU Lesser General Public License version 3 requirements-
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
25**-
26** GNU General Public License Usage-
27** Alternatively, this file may be used under the terms of the GNU-
28** General Public License version 2.0 or (at your option) the GNU General-
29** Public license version 3 or any later version approved by the KDE Free-
30** Qt Foundation. The licenses are as published by the Free Software-
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
32** included in the packaging of this file. Please review the following-
33** information to ensure the GNU General Public License requirements will-
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
35** https://www.gnu.org/licenses/gpl-3.0.html.-
36**-
37** $QT_END_LICENSE$-
38**-
39****************************************************************************/-
40-
41#include "qharfbuzzng_p.h"-
42-
43#include <qstring.h>-
44#include <qvector.h>-
45-
46#include <private/qstringiterator_p.h>-
47-
48#include "qfontengine_p.h"-
49-
50QT_BEGIN_NAMESPACE-
51-
52// Unicode routines-
53-
54static const hb_script_t _qtscript_to_hbscript[] = {-
55 HB_SCRIPT_UNKNOWN,-
56 HB_SCRIPT_INHERITED,-
57 HB_SCRIPT_COMMON,-
58-
59 HB_SCRIPT_LATIN,-
60 HB_SCRIPT_GREEK,-
61 HB_SCRIPT_CYRILLIC,-
62 HB_SCRIPT_ARMENIAN,-
63 HB_SCRIPT_HEBREW,-
64 HB_SCRIPT_ARABIC,-
65 HB_SCRIPT_SYRIAC,-
66 HB_SCRIPT_THAANA,-
67 HB_SCRIPT_DEVANAGARI,-
68 HB_SCRIPT_BENGALI,-
69 HB_SCRIPT_GURMUKHI,-
70 HB_SCRIPT_GUJARATI,-
71 HB_SCRIPT_ORIYA,-
72 HB_SCRIPT_TAMIL,-
73 HB_SCRIPT_TELUGU,-
74 HB_SCRIPT_KANNADA,-
75 HB_SCRIPT_MALAYALAM,-
76 HB_SCRIPT_SINHALA,-
77 HB_SCRIPT_THAI,-
78 HB_SCRIPT_LAO,-
79 HB_SCRIPT_TIBETAN,-
80 HB_SCRIPT_MYANMAR,-
81 HB_SCRIPT_GEORGIAN,-
82 HB_SCRIPT_HANGUL,-
83 HB_SCRIPT_ETHIOPIC,-
84 HB_SCRIPT_CHEROKEE,-
85 HB_SCRIPT_CANADIAN_ABORIGINAL,-
86 HB_SCRIPT_OGHAM,-
87 HB_SCRIPT_RUNIC,-
88 HB_SCRIPT_KHMER,-
89 HB_SCRIPT_MONGOLIAN,-
90 HB_SCRIPT_HIRAGANA,-
91 HB_SCRIPT_KATAKANA,-
92 HB_SCRIPT_BOPOMOFO,-
93 HB_SCRIPT_HAN,-
94 HB_SCRIPT_YI,-
95 HB_SCRIPT_OLD_ITALIC,-
96 HB_SCRIPT_GOTHIC,-
97 HB_SCRIPT_DESERET,-
98 HB_SCRIPT_TAGALOG,-
99 HB_SCRIPT_HANUNOO,-
100 HB_SCRIPT_BUHID,-
101 HB_SCRIPT_TAGBANWA,-
102 HB_SCRIPT_COPTIC,-
103-
104 // Unicode 4.0 additions-
105 HB_SCRIPT_LIMBU,-
106 HB_SCRIPT_TAI_LE,-
107 HB_SCRIPT_LINEAR_B,-
108 HB_SCRIPT_UGARITIC,-
109 HB_SCRIPT_SHAVIAN,-
110 HB_SCRIPT_OSMANYA,-
111 HB_SCRIPT_CYPRIOT,-
112 HB_SCRIPT_BRAILLE,-
113-
114 // Unicode 4.1 additions-
115 HB_SCRIPT_BUGINESE,-
116 HB_SCRIPT_NEW_TAI_LUE,-
117 HB_SCRIPT_GLAGOLITIC,-
118 HB_SCRIPT_TIFINAGH,-
119 HB_SCRIPT_SYLOTI_NAGRI,-
120 HB_SCRIPT_OLD_PERSIAN,-
121 HB_SCRIPT_KHAROSHTHI,-
122-
123 // Unicode 5.0 additions-
124 HB_SCRIPT_BALINESE,-
125 HB_SCRIPT_CUNEIFORM,-
126 HB_SCRIPT_PHOENICIAN,-
127 HB_SCRIPT_PHAGS_PA,-
128 HB_SCRIPT_NKO,-
129-
130 // Unicode 5.1 additions-
131 HB_SCRIPT_SUNDANESE,-
132 HB_SCRIPT_LEPCHA,-
133 HB_SCRIPT_OL_CHIKI,-
134 HB_SCRIPT_VAI,-
135 HB_SCRIPT_SAURASHTRA,-
136 HB_SCRIPT_KAYAH_LI,-
137 HB_SCRIPT_REJANG,-
138 HB_SCRIPT_LYCIAN,-
139 HB_SCRIPT_CARIAN,-
140 HB_SCRIPT_LYDIAN,-
141 HB_SCRIPT_CHAM,-
142-
143 // Unicode 5.2 additions-
144 HB_SCRIPT_TAI_THAM,-
145 HB_SCRIPT_TAI_VIET,-
146 HB_SCRIPT_AVESTAN,-
147 HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,-
148 HB_SCRIPT_SAMARITAN,-
149 HB_SCRIPT_LISU,-
150 HB_SCRIPT_BAMUM,-
151 HB_SCRIPT_JAVANESE,-
152 HB_SCRIPT_MEETEI_MAYEK,-
153 HB_SCRIPT_IMPERIAL_ARAMAIC,-
154 HB_SCRIPT_OLD_SOUTH_ARABIAN,-
155 HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,-
156 HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,-
157 HB_SCRIPT_OLD_TURKIC,-
158 HB_SCRIPT_KAITHI,-
159-
160 // Unicode 6.0 additions-
161 HB_SCRIPT_BATAK,-
162 HB_SCRIPT_BRAHMI,-
163 HB_SCRIPT_MANDAIC,-
164-
165 // Unicode 6.1 additions-
166 HB_SCRIPT_CHAKMA,-
167 HB_SCRIPT_MEROITIC_CURSIVE,-
168 HB_SCRIPT_MEROITIC_HIEROGLYPHS,-
169 HB_SCRIPT_MIAO,-
170 HB_SCRIPT_SHARADA,-
171 HB_SCRIPT_SORA_SOMPENG,-
172 HB_SCRIPT_TAKRI,-
173-
174 // Unicode 7.0 additions-
175 HB_SCRIPT_CAUCASIAN_ALBANIAN,-
176 HB_SCRIPT_BASSA_VAH,-
177 HB_SCRIPT_DUPLOYAN,-
178 HB_SCRIPT_ELBASAN,-
179 HB_SCRIPT_GRANTHA,-
180 HB_SCRIPT_PAHAWH_HMONG,-
181 HB_SCRIPT_KHOJKI,-
182 HB_SCRIPT_LINEAR_A,-
183 HB_SCRIPT_MAHAJANI,-
184 HB_SCRIPT_MANICHAEAN,-
185 HB_SCRIPT_MENDE_KIKAKUI,-
186 HB_SCRIPT_MODI,-
187 HB_SCRIPT_MRO,-
188 HB_SCRIPT_OLD_NORTH_ARABIAN,-
189 HB_SCRIPT_NABATAEAN,-
190 HB_SCRIPT_PALMYRENE,-
191 HB_SCRIPT_PAU_CIN_HAU,-
192 HB_SCRIPT_OLD_PERMIC,-
193 HB_SCRIPT_PSALTER_PAHLAVI,-
194 HB_SCRIPT_SIDDHAM,-
195 HB_SCRIPT_KHUDAWADI,-
196 HB_SCRIPT_TIRHUTA,-
197 HB_SCRIPT_WARANG_CITI,-
198-
199 // Unicode 8.0 additions-
200 HB_SCRIPT_AHOM,-
201 HB_SCRIPT_ANATOLIAN_HIEROGLYPHS,-
202 HB_SCRIPT_HATRAN,-
203 HB_SCRIPT_MULTANI,-
204 HB_SCRIPT_OLD_HUNGARIAN,-
205 HB_SCRIPT_SIGNWRITING-
206};-
207Q_STATIC_ASSERT(QChar::ScriptCount == sizeof(_qtscript_to_hbscript) / sizeof(_qtscript_to_hbscript[0]));-
208-
209hb_script_t hb_qt_script_to_script(QChar::Script script)-
210{-
211 return _qtscript_to_hbscript[script];
never executed: return _qtscript_to_hbscript[script];
0
212}-
213-
214QChar::Script hb_qt_script_from_script(hb_script_t script)-
215{-
216 uint i = QChar::ScriptCount - 1;-
217 while (i > QChar::Script_Unknown && _qtscript_to_hbscript[i] != script)
i > QChar::Script_UnknownDescription
TRUEnever evaluated
FALSEnever evaluated
_qtscript_to_h...t[i] != scriptDescription
TRUEnever evaluated
FALSEnever evaluated
0
218 --i;
never executed: --i;
0
219 return QChar::Script(i);
never executed: return QChar::Script(i);
0
220}-
221-
222-
223static hb_unicode_combining_class_t-
224_hb_qt_unicode_combining_class(hb_unicode_funcs_t * /*ufuncs*/,-
225 hb_codepoint_t unicode,-
226 void * /*user_data*/)-
227{-
228 return hb_unicode_combining_class_t(QChar::combiningClass(unicode));
never executed: return hb_unicode_combining_class_t(QChar::combiningClass(unicode));
0
229}-
230-
231static unsigned int-
232_hb_qt_unicode_eastasian_width(hb_unicode_funcs_t * /*ufuncs*/,-
233 hb_codepoint_t /*unicode*/,-
234 void * /*user_data*/)-
235{-
236 qCritical("hb_qt_unicode_eastasian_width: not implemented!");-
237 return 1;
never executed: return 1;
0
238}-
239-
240static const hb_unicode_general_category_t _qtcategory_to_hbcategory[] = {-
241 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK, // Mn-
242 HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK, // Mc-
243 HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK, // Me-
244-
245 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER, // Nd-
246 HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER, // Nl-
247 HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER, // No-
248-
249 HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR, // Zs-
250 HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR, // Zl-
251 HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR, // Zp-
252-
253 HB_UNICODE_GENERAL_CATEGORY_CONTROL, // Cc-
254 HB_UNICODE_GENERAL_CATEGORY_FORMAT, // Cf-
255 HB_UNICODE_GENERAL_CATEGORY_SURROGATE, // Cs-
256 HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE, // Co-
257 HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED, // Cn-
258-
259 HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER, // Lu-
260 HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER, // Ll-
261 HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER, // Lt-
262 HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER, // Lm-
263 HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER, // Lo-
264-
265 HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION, // Pc-
266 HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION, // Pd-
267 HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION, // Ps-
268 HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION, // Pe-
269 HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION, // Pi-
270 HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION, // Pf-
271 HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION, // Po-
272-
273 HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL, // Sm-
274 HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL, // Sc-
275 HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL, // Sk-
276 HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL // So-
277};-
278-
279static hb_unicode_general_category_t-
280_hb_qt_unicode_general_category(hb_unicode_funcs_t * /*ufuncs*/,-
281 hb_codepoint_t unicode,-
282 void * /*user_data*/)-
283{-
284 return _qtcategory_to_hbcategory[QChar::category(unicode)];
never executed: return _qtcategory_to_hbcategory[QChar::category(unicode)];
0
285}-
286-
287static hb_codepoint_t-
288_hb_qt_unicode_mirroring(hb_unicode_funcs_t * /*ufuncs*/,-
289 hb_codepoint_t unicode,-
290 void * /*user_data*/)-
291{-
292 return QChar::mirroredChar(unicode);
never executed: return QChar::mirroredChar(unicode);
0
293}-
294-
295static hb_script_t-
296_hb_qt_unicode_script(hb_unicode_funcs_t * /*ufuncs*/,-
297 hb_codepoint_t unicode,-
298 void * /*user_data*/)-
299{-
300 return _qtscript_to_hbscript[QChar::script(unicode)];
never executed: return _qtscript_to_hbscript[QChar::script(unicode)];
0
301}-
302-
303static hb_bool_t-
304_hb_qt_unicode_compose(hb_unicode_funcs_t * /*ufuncs*/,-
305 hb_codepoint_t a, hb_codepoint_t b,-
306 hb_codepoint_t *ab,-
307 void * /*user_data*/)-
308{-
309 // ### optimize-
310 QString s = QString::fromUcs4(&a, 1) + QString::fromUcs4(&b, 1);-
311 QString normalized = s.normalized(QString::NormalizationForm_C);-
312-
313 QStringIterator it(normalized);-
314 Q_ASSERT(it.hasNext()); // size>0-
315 *ab = it.next();-
316-
317 return !it.hasNext(); // size==1
never executed: return !it.hasNext();
0
318}-
319-
320static hb_bool_t-
321_hb_qt_unicode_decompose(hb_unicode_funcs_t * /*ufuncs*/,-
322 hb_codepoint_t ab,-
323 hb_codepoint_t *a, hb_codepoint_t *b,-
324 void * /*user_data*/)-
325{-
326 // ### optimize-
327 if (QChar::decompositionTag(ab) != QChar::Canonical) // !NFD
QChar::decompo...har::CanonicalDescription
TRUEnever evaluated
FALSEnever evaluated
0
328 return false;
never executed: return false;
0
329-
330 QString normalized = QChar::decomposition(ab);-
331 if (normalized.isEmpty())
normalized.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
332 return false;
never executed: return false;
0
333-
334 QStringIterator it(normalized);-
335 Q_ASSERT(it.hasNext()); // size>0-
336 *a = it.next();-
337-
338 if (!it.hasNext()) { // size==1
!it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
339 *b = 0;-
340 return *a != ab;
never executed: return *a != ab;
0
341 }-
342-
343 // size>1-
344 *b = it.next();-
345 if (!it.hasNext()) { // size==2
!it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
346 // Here's the ugly part: if ab decomposes to a single character and-
347 // that character decomposes again, we have to detect that and undo-
348 // the second part :-(-
349 const QString recomposed = normalized.normalized(QString::NormalizationForm_C);-
350 QStringIterator jt(recomposed);-
351 Q_ASSERT(jt.hasNext()); // size>0-
352 const hb_codepoint_t c = jt.next();-
353 if (c != *a && c != ab) {
c != *aDescription
TRUEnever evaluated
FALSEnever evaluated
c != abDescription
TRUEnever evaluated
FALSEnever evaluated
0
354 *a = c;-
355 *b = 0;-
356 }
never executed: end of block
0
357 return true;
never executed: return true;
0
358 }-
359-
360 // size>2-
361 // If decomposed to more than two characters, take the last one,-
362 // and recompose the rest to get the first component-
363 do {-
364 *b = it.next();-
365 } while (it.hasNext());
never executed: end of block
it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
366 normalized.chop(QChar::requiresSurrogates(*b) ? 2 : 1);-
367 const QString recomposed = normalized.normalized(QString::NormalizationForm_C);-
368 QStringIterator jt(recomposed);-
369 Q_ASSERT(jt.hasNext()); // size>0-
370 // We expect that recomposed has exactly one character now-
371 *a = jt.next();-
372 return true;
never executed: return true;
0
373}-
374-
375static unsigned int-
376_hb_qt_unicode_decompose_compatibility(hb_unicode_funcs_t * /*ufuncs*/,-
377 hb_codepoint_t u,-
378 hb_codepoint_t *decomposed,-
379 void * /*user_data*/)-
380{-
381 const QString normalized = QChar::decomposition(u);-
382-
383 uint outlen = 0;-
384 QStringIterator it(normalized);-
385 while (it.hasNext()) {
it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
386 Q_ASSERT(outlen < HB_UNICODE_MAX_DECOMPOSITION_LEN);-
387 decomposed[outlen++] = it.next();-
388 }
never executed: end of block
0
389-
390 return outlen;
never executed: return outlen;
0
391}-
392-
393-
394struct _hb_unicode_funcs_t {-
395 _hb_unicode_funcs_t()-
396 {-
397 funcs = hb_unicode_funcs_create(NULL);-
398 hb_unicode_funcs_set_combining_class_func(funcs, _hb_qt_unicode_combining_class, NULL, NULL);-
399 hb_unicode_funcs_set_eastasian_width_func(funcs, _hb_qt_unicode_eastasian_width, NULL, NULL);-
400 hb_unicode_funcs_set_general_category_func(funcs, _hb_qt_unicode_general_category, NULL, NULL);-
401 hb_unicode_funcs_set_mirroring_func(funcs, _hb_qt_unicode_mirroring, NULL, NULL);-
402 hb_unicode_funcs_set_script_func(funcs, _hb_qt_unicode_script, NULL, NULL);-
403 hb_unicode_funcs_set_compose_func(funcs, _hb_qt_unicode_compose, NULL, NULL);-
404 hb_unicode_funcs_set_decompose_func(funcs, _hb_qt_unicode_decompose, NULL, NULL);-
405 hb_unicode_funcs_set_decompose_compatibility_func(funcs, _hb_qt_unicode_decompose_compatibility, NULL, NULL);-
406 }
never executed: end of block
0
407 ~_hb_unicode_funcs_t()-
408 {-
409 hb_unicode_funcs_destroy(funcs);-
410 }
never executed: end of block
0
411-
412 hb_unicode_funcs_t *funcs;-
413};-
414-
415Q_GLOBAL_STATIC(_hb_unicode_funcs_t, qt_ufuncs)
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
416-
417hb_unicode_funcs_t *hb_qt_get_unicode_funcs()-
418{-
419 return qt_ufuncs()->funcs;
never executed: return qt_ufuncs()->funcs;
0
420}-
421-
422-
423// Font routines-
424-
425static hb_bool_t-
426_hb_qt_font_get_glyph(hb_font_t * /*font*/, void *font_data,-
427 hb_codepoint_t unicode, hb_codepoint_t /*variation_selector*/,-
428 hb_codepoint_t *glyph,-
429 void * /*user_data*/)-
430{-
431 QFontEngine *fe = static_cast<QFontEngine *>(font_data);-
432 Q_ASSERT(fe);-
433-
434 *glyph = fe->glyphIndex(unicode);-
435-
436 return true;
never executed: return true;
0
437}-
438-
439static hb_position_t-
440_hb_qt_font_get_glyph_h_advance(hb_font_t *font, void *font_data,-
441 hb_codepoint_t glyph,-
442 void * /*user_data*/)-
443{-
444 QFontEngine *fe = static_cast<QFontEngine *>(font_data);-
445 Q_ASSERT(fe);-
446-
447 QFixed advance;-
448-
449 QGlyphLayout g;-
450 g.numGlyphs = 1;-
451 g.glyphs = &glyph;-
452 g.advances = &advance;-
453-
454 fe->recalcAdvances(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font)));-
455-
456 return advance.value();
never executed: return advance.value();
0
457}-
458-
459static hb_position_t-
460_hb_qt_font_get_glyph_v_advance(hb_font_t * /*font*/, void * /*font_data*/,-
461 hb_codepoint_t /*glyph*/,-
462 void * /*user_data*/)-
463{-
464 qCritical("hb_qt_font_get_glyph_v_advance: vertical writing isn't supported!");-
465 return 0;
never executed: return 0;
0
466}-
467-
468static hb_bool_t-
469_hb_qt_font_get_glyph_h_origin(hb_font_t * /*font*/, void * /*font_data*/,-
470 hb_codepoint_t /*glyph*/,-
471 hb_position_t * /*x*/, hb_position_t * /*y*/,-
472 void * /*user_data*/)-
473{-
474 return true; // we always work in the horizontal coordinates
never executed: return true;
0
475}-
476-
477static hb_bool_t-
478_hb_qt_font_get_glyph_v_origin(hb_font_t * /*font*/, void * /*font_data*/,-
479 hb_codepoint_t /*glyph*/,-
480 hb_position_t * /*x*/, hb_position_t * /*y*/,-
481 void * /*user_data*/)-
482{-
483 qCritical("hb_qt_get_glyph_v_origin: vertical writing isn't supported!");-
484 return false;
never executed: return false;
0
485}-
486-
487static hb_position_t-
488_hb_qt_font_get_glyph_h_kerning(hb_font_t *font, void *font_data,-
489 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,-
490 void * /*user_data*/)-
491{-
492 QFontEngine *fe = static_cast<QFontEngine *>(font_data);-
493 Q_ASSERT(fe);-
494-
495 glyph_t glyphs[2] = { first_glyph, second_glyph };-
496 QFixed advance;-
497-
498 QGlyphLayout g;-
499 g.numGlyphs = 2;-
500 g.glyphs = glyphs;-
501 g.advances = &advance;-
502-
503 fe->doKerning(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font)));-
504-
505 return advance.value();
never executed: return advance.value();
0
506}-
507-
508static hb_position_t-
509_hb_qt_font_get_glyph_v_kerning(hb_font_t * /*font*/, void * /*font_data*/,-
510 hb_codepoint_t /*first_glyph*/, hb_codepoint_t /*second_glyph*/,-
511 void * /*user_data*/)-
512{-
513 qCritical("hb_qt_get_glyph_v_kerning: vertical writing isn't supported!");-
514 return 0;
never executed: return 0;
0
515}-
516-
517static hb_bool_t-
518_hb_qt_font_get_glyph_extents(hb_font_t * /*font*/, void *font_data,-
519 hb_codepoint_t glyph,-
520 hb_glyph_extents_t *extents,-
521 void * /*user_data*/)-
522{-
523 QFontEngine *fe = static_cast<QFontEngine *>(font_data);-
524 Q_ASSERT(fe);-
525-
526 glyph_metrics_t gm = fe->boundingBox(glyph);-
527-
528 extents->x_bearing = gm.x.value();-
529 extents->y_bearing = gm.y.value();-
530 extents->width = gm.width.value();-
531 extents->height = gm.height.value();-
532-
533 return true;
never executed: return true;
0
534}-
535-
536static hb_bool_t-
537_hb_qt_font_get_glyph_contour_point(hb_font_t * /*font*/, void *font_data,-
538 hb_codepoint_t glyph,-
539 unsigned int point_index, hb_position_t *x, hb_position_t *y,-
540 void * /*user_data*/)-
541{-
542 QFontEngine *fe = static_cast<QFontEngine *>(font_data);-
543 Q_ASSERT(fe);-
544-
545 QFixed xpos, ypos;-
546 quint32 numPoints = 1;-
547 if (Q_LIKELY(fe->getPointInOutline(glyph, 0, point_index, &xpos, &ypos, &numPoints) == 0)) {
__builtin_expe...) == 0), true)Description
TRUEnever evaluated
FALSEnever evaluated
0
548 *x = xpos.value();-
549 *y = ypos.value();-
550 return true;
never executed: return true;
0
551 }-
552-
553 *x = *y = 0;-
554 return false;
never executed: return false;
0
555}-
556-
557static hb_bool_t-
558_hb_qt_font_get_glyph_name(hb_font_t * /*font*/, void * /*font_data*/,-
559 hb_codepoint_t /*glyph*/,-
560 char *name, unsigned int size,-
561 void * /*user_data*/)-
562{-
563 qCritical("hb_qt_font_get_glyph_name: not implemented!");-
564 if (size)
sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
565 *name = '\0';
never executed: *name = '\0';
0
566 return false;
never executed: return false;
0
567}-
568-
569static hb_bool_t-
570_hb_qt_font_get_glyph_from_name(hb_font_t * /*font*/, void * /*font_data*/,-
571 const char * /*name*/, int /*len*/,-
572 hb_codepoint_t *glyph,-
573 void * /*user_data*/)-
574{-
575 qCritical("hb_qt_font_get_glyph_from_name: not implemented!");-
576 *glyph = 0;-
577 return false;
never executed: return false;
0
578}-
579-
580-
581static hb_user_data_key_t _useDesignMetricsKey;-
582-
583void hb_qt_font_set_use_design_metrics(hb_font_t *font, uint value)-
584{-
585 hb_font_set_user_data(font, &_useDesignMetricsKey, (void *)quintptr(value), NULL, true);-
586}
never executed: end of block
0
587-
588uint hb_qt_font_get_use_design_metrics(hb_font_t *font)-
589{-
590 return quintptr(hb_font_get_user_data(font, &_useDesignMetricsKey));
never executed: return quintptr(hb_font_get_user_data(font, &_useDesignMetricsKey));
0
591}-
592-
593-
594struct _hb_qt_font_funcs_t {-
595 _hb_qt_font_funcs_t()-
596 {-
597 funcs = hb_font_funcs_create();-
598 hb_font_funcs_set_glyph_func(funcs, _hb_qt_font_get_glyph, NULL, NULL);-
599 hb_font_funcs_set_glyph_h_advance_func(funcs, _hb_qt_font_get_glyph_h_advance, NULL, NULL);-
600 hb_font_funcs_set_glyph_v_advance_func(funcs, _hb_qt_font_get_glyph_v_advance, NULL, NULL);-
601 hb_font_funcs_set_glyph_h_origin_func(funcs, _hb_qt_font_get_glyph_h_origin, NULL, NULL);-
602 hb_font_funcs_set_glyph_v_origin_func(funcs, _hb_qt_font_get_glyph_v_origin, NULL, NULL);-
603 hb_font_funcs_set_glyph_h_kerning_func(funcs, _hb_qt_font_get_glyph_h_kerning, NULL, NULL);-
604 hb_font_funcs_set_glyph_v_kerning_func(funcs, _hb_qt_font_get_glyph_v_kerning, NULL, NULL);-
605 hb_font_funcs_set_glyph_extents_func(funcs, _hb_qt_font_get_glyph_extents, NULL, NULL);-
606 hb_font_funcs_set_glyph_contour_point_func(funcs, _hb_qt_font_get_glyph_contour_point, NULL, NULL);-
607 hb_font_funcs_set_glyph_name_func(funcs, _hb_qt_font_get_glyph_name, NULL, NULL);-
608 hb_font_funcs_set_glyph_from_name_func(funcs, _hb_qt_font_get_glyph_from_name, NULL, NULL);-
609 }
never executed: end of block
0
610 ~_hb_qt_font_funcs_t()-
611 {-
612 hb_font_funcs_destroy(funcs);-
613 }
never executed: end of block
0
614-
615 hb_font_funcs_t *funcs;-
616};-
617-
618Q_GLOBAL_STATIC(_hb_qt_font_funcs_t, qt_ffuncs)
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
619-
620hb_font_funcs_t *hb_qt_get_font_funcs()-
621{-
622 return qt_ffuncs()->funcs;
never executed: return qt_ffuncs()->funcs;
0
623}-
624-
625-
626static hb_blob_t *-
627_hb_qt_reference_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data)-
628{-
629 QFontEngine::FaceData *data = static_cast<QFontEngine::FaceData *>(user_data);-
630 Q_ASSERT(data);-
631-
632 qt_get_font_table_func_t get_font_table = data->get_font_table;-
633 Q_ASSERT(get_font_table);-
634-
635 uint length = 0;-
636 if (Q_UNLIKELY(!get_font_table(data->user_data, tag, 0, &length)))
__builtin_expe...ngth)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
637 return hb_blob_get_empty();
never executed: return hb_blob_get_empty();
0
638-
639 char *buffer = static_cast<char *>(malloc(length));-
640 Q_CHECK_PTR(buffer);
never executed: qt_check_pointer(__FILE__,640);
!(buffer)Description
TRUEnever evaluated
FALSEnever evaluated
0
641-
642 if (Q_UNLIKELY(!get_font_table(data->user_data, tag, reinterpret_cast<uchar *>(buffer), &length)))
__builtin_expe...ngth)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
643 length = 0;
never executed: length = 0;
0
644-
645 return hb_blob_create(const_cast<const char *>(buffer), length,
never executed: return hb_blob_create(const_cast<const char *>(buffer), length, HB_MEMORY_MODE_READONLY, buffer, free);
0
646 HB_MEMORY_MODE_READONLY,
never executed: return hb_blob_create(const_cast<const char *>(buffer), length, HB_MEMORY_MODE_READONLY, buffer, free);
0
647 buffer, free);
never executed: return hb_blob_create(const_cast<const char *>(buffer), length, HB_MEMORY_MODE_READONLY, buffer, free);
0
648}-
649-
650static inline hb_face_t *-
651_hb_qt_face_create(QFontEngine *fe)-
652{-
653 QFontEngine::FaceData *data = static_cast<QFontEngine::FaceData *>(malloc(sizeof(QFontEngine::FaceData)));-
654 Q_CHECK_PTR(data);
never executed: qt_check_pointer(__FILE__,654);
!(data)Description
TRUEnever evaluated
FALSEnever evaluated
0
655 data->user_data = fe->faceData.user_data;-
656 data->get_font_table = fe->faceData.get_font_table;-
657-
658 hb_face_t *face = hb_face_create_for_tables(_hb_qt_reference_table, (void *)data, free);-
659 if (Q_UNLIKELY(hb_face_is_immutable(face))) {
__builtin_expe...face)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
660 hb_face_destroy(face);-
661 return NULL;
never executed: return __null;
0
662 }-
663-
664 hb_face_set_index(face, fe->faceId().index);-
665 hb_face_set_upem(face, fe->emSquareSize().truncate());-
666-
667 return face;
never executed: return face;
0
668}-
669-
670static void-
671_hb_qt_face_release(void *user_data)-
672{-
673 if (Q_LIKELY(user_data))
__builtin_expe...r_data), true)Description
TRUEnever evaluated
FALSEnever evaluated
0
674 hb_face_destroy(static_cast<hb_face_t *>(user_data));
never executed: hb_face_destroy(static_cast<hb_face_t *>(user_data));
0
675}
never executed: end of block
0
676-
677hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe)-
678{-
679 Q_ASSERT(fe && fe->type() != QFontEngine::Multi);-
680-
681 if (Q_UNLIKELY(!fe->face_))
__builtin_expe...face_), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
682 fe->face_ = QFontEngine::Holder(_hb_qt_face_create(fe), _hb_qt_face_release);
never executed: fe->face_ = QFontEngine::Holder(_hb_qt_face_create(fe), _hb_qt_face_release);
0
683-
684 return static_cast<hb_face_t *>(fe->face_.get());
never executed: return static_cast<hb_face_t *>(fe->face_.get());
0
685}-
686-
687-
688static inline hb_font_t *-
689_hb_qt_font_create(QFontEngine *fe)-
690{-
691 hb_face_t *face = hb_qt_face_get_for_engine(fe);-
692 if (Q_UNLIKELY(!face))
__builtin_expe...!face), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
693 return NULL;
never executed: return __null;
0
694-
695 hb_font_t *font = hb_font_create(face);-
696-
697 if (Q_UNLIKELY(hb_font_is_immutable(font))) {
__builtin_expe...font)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
698 hb_font_destroy(font);-
699 return NULL;
never executed: return __null;
0
700 }-
701-
702 const int y_ppem = fe->fontDef.pixelSize;-
703 const int x_ppem = (fe->fontDef.pixelSize * fe->fontDef.stretch) / 100;-
704-
705 hb_font_set_funcs(font, hb_qt_get_font_funcs(), (void *)fe, NULL);-
706#ifdef Q_OS_MAC-
707 hb_font_set_scale(font, QFixed(x_ppem).value(), QFixed(y_ppem).value());-
708#else-
709 hb_font_set_scale(font, QFixed(x_ppem).value(), -QFixed(y_ppem).value());-
710#endif-
711 hb_font_set_ppem(font, x_ppem, y_ppem);-
712-
713 return font;
never executed: return font;
0
714}-
715-
716static void-
717_hb_qt_font_release(void *user_data)-
718{-
719 if (Q_LIKELY(user_data))
__builtin_expe...r_data), true)Description
TRUEnever evaluated
FALSEnever evaluated
0
720 hb_font_destroy(static_cast<hb_font_t *>(user_data));
never executed: hb_font_destroy(static_cast<hb_font_t *>(user_data));
0
721}
never executed: end of block
0
722-
723hb_font_t *hb_qt_font_get_for_engine(QFontEngine *fe)-
724{-
725 Q_ASSERT(fe && fe->type() != QFontEngine::Multi);-
726-
727 if (Q_UNLIKELY(!fe->font_))
__builtin_expe...font_), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
728 fe->font_ = QFontEngine::Holder(_hb_qt_font_create(fe), _hb_qt_font_release);
never executed: fe->font_ = QFontEngine::Holder(_hb_qt_font_create(fe), _hb_qt_font_release);
0
729-
730 return static_cast<hb_font_t *>(fe->font_.get());
never executed: return static_cast<hb_font_t *>(fe->font_.get());
0
731}-
732-
733QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

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