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

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