qglyphrun.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/text/qglyphrun.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 "qglobal.h"-
35-
36#if !defined(QT_NO_RAWFONT)-
37-
38#include "qglyphrun.h"-
39#include "qglyphrun_p.h"-
40#include <qdebug.h>-
41-
42QT_BEGIN_NAMESPACE-
43-
44/*!-
45 \class QGlyphRun-
46 \brief The QGlyphRun class provides direct access to the internal glyphs in a font.-
47 \since 4.8-
48 \inmodule QtGui-
49-
50 \ingroup text-
51 \ingroup shared-
52-
53 When Qt displays a string of text encoded in Unicode, it will first convert the Unicode points-
54 into a list of glyph indexes and a list of positions based on one or more fonts. The Unicode-
55 representation of the text and the QFont object will in this case serve as a convenient-
56 abstraction that hides the details of what actually takes place when displaying the text-
57 on-screen. For instance, by the time the text actually reaches the screen, it may be represented-
58 by a set of fonts in addition to the one specified by the user, e.g. in case the originally-
59 selected font did not support all the writing systems contained in the text.-
60-
61 Under certain circumstances, it can be useful as an application developer to have more low-level-
62 control over which glyphs in a specific font are drawn to the screen. This could for instance-
63 be the case in applications that use an external font engine and text shaper together with Qt.-
64 QGlyphRun provides an interface to the raw data needed to get text on the screen. It-
65 contains a list of glyph indexes, a position for each glyph and a font.-
66-
67 It is the user's responsibility to ensure that the selected font actually contains the-
68 provided glyph indexes.-
69-
70 QTextLayout::glyphRuns() or QTextFragment::glyphRuns() can be used to convert unicode encoded-
71 text into a list of QGlyphRun objects, and QPainter::drawGlyphRun() can be used to draw the-
72 glyphs.-
73-
74 \note Please note that QRawFont is considered local to the thread in which it is constructed.-
75 This in turn means that a new QRawFont will have to be created and set on the QGlyphRun if it is-
76 moved to a different thread. If the QGlyphRun contains a reference to a QRawFont from a different-
77 thread than the current, it will not be possible to draw the glyphs using a QPainter, as the-
78 QRawFont is considered invalid and inaccessible in this case.-
79*/-
80-
81/*!-
82 \enum QGlyphRun::GlyphRunFlag-
83 \since 5.0-
84-
85 This enum describes flags that alter the way the run of glyphs might be presented or behave in-
86 a visual layout. The layout which generates the glyph runs can set these flags based on relevant-
87 internal data, to retain information needed to present the text as intended by the user of the-
88 layout.-
89-
90 \value Overline Indicates that the glyphs should be visualized together with an overline.-
91 \value Underline Indicates that the glyphs should be visualized together with an underline.-
92 \value StrikeOut Indicates that the glyphs should be struck out visually.-
93 \value RightToLeft Indicates that the glyphs are ordered right to left. This can affect the-
94 positioning of other screen elements that are relative to the glyph run, such as an inline-
95 text object.-
96 \value SplitLigature Indicates that the glyph run splits a ligature glyph. This means-
97 that a ligature glyph is included in the run, but the characters represented by it corresponds-
98 only to part of that ligature. The glyph run's boundingRect() function can in this case be used-
99 to retrieve the area covered by glyphs that correspond to the characters represented by the-
100 glyph run. When visualizing the glyphs, care needs to be taken to clip to this bounding rect to-
101 ensure that only the corresponding part of the ligature is painted. In particular, this can be-
102 the case when retrieving a glyph run from a QTextLayout for a specific character range, e.g.-
103 when retrieving the selected area of a QTextLayout.-
104*/-
105-
106/*!-
107 Constructs an empty QGlyphRun object.-
108*/-
109QGlyphRun::QGlyphRun() : d(new QGlyphRunPrivate)-
110{-
111}
never executed: end of block
0
112-
113/*!-
114 Constructs a QGlyphRun object which is a copy of \a other.-
115*/-
116QGlyphRun::QGlyphRun(const QGlyphRun &other)-
117{-
118 d = other.d;-
119}
never executed: end of block
0
120-
121/*!-
122 Destroys the QGlyphRun.-
123*/-
124QGlyphRun::~QGlyphRun()-
125{-
126 // Required for QExplicitlySharedDataPointer-
127}-
128-
129/*!-
130 \internal-
131*/-
132void QGlyphRun::detach()-
133{-
134 if (d->ref.load() != 1)
d->ref.load() != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
135 d.detach();
never executed: d.detach();
0
136}
never executed: end of block
0
137-
138/*!-
139 Assigns \a other to this QGlyphRun object.-
140*/-
141QGlyphRun &QGlyphRun::operator=(const QGlyphRun &other)-
142{-
143 d = other.d;-
144 return *this;
never executed: return *this;
0
145}-
146-
147/*!-
148 \fn void QGlyphRun::swap(QGlyphRun &other)-
149 \since 5.0-
150-
151 Swaps this glyph run instance with \a other. This function is very-
152 fast and never fails.-
153*/-
154-
155/*!-
156 Compares \a other to this QGlyphRun object. Returns \c true if the list of glyph indexes,-
157 the list of positions and the font are all equal, otherwise returns \c false.-
158*/-
159bool QGlyphRun::operator==(const QGlyphRun &other) const-
160{-
161 if (d == other.d)
d == other.dDescription
TRUEnever evaluated
FALSEnever evaluated
0
162 return true;
never executed: return true;
0
163-
164 if ((d->glyphIndexDataSize != other.d->glyphIndexDataSize)
(d->glyphIndex...IndexDataSize)Description
TRUEnever evaluated
FALSEnever evaluated
0
165 || (d->glyphPositionDataSize != other.d->glyphPositionDataSize)) {
(d->glyphPosit...itionDataSize)Description
TRUEnever evaluated
FALSEnever evaluated
0
166 return false;
never executed: return false;
0
167 }-
168-
169 if (d->glyphIndexData != other.d->glyphIndexData) {
d->glyphIndexD...glyphIndexDataDescription
TRUEnever evaluated
FALSEnever evaluated
0
170 for (int i = 0; i < d->glyphIndexDataSize; ++i) {
i < d->glyphIndexDataSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
171 if (d->glyphIndexData[i] != other.d->glyphIndexData[i])
d->glyphIndexD...phIndexData[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
172 return false;
never executed: return false;
0
173 }
never executed: end of block
0
174 }
never executed: end of block
0
175 if (d->glyphPositionData != other.d->glyphPositionData) {
d->glyphPositi...phPositionDataDescription
TRUEnever evaluated
FALSEnever evaluated
0
176 for (int i = 0; i < d->glyphPositionDataSize; ++i) {
i < d->glyphPositionDataSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
177 if (d->glyphPositionData[i] != other.d->glyphPositionData[i])
d->glyphPositi...ositionData[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
178 return false;
never executed: return false;
0
179 }
never executed: end of block
0
180 }
never executed: end of block
0
181-
182 return (d->flags == other.d->flags && d->rawFont == other.d->rawFont);
never executed: return (d->flags == other.d->flags && d->rawFont == other.d->rawFont);
d->flags == other.d->flagsDescription
TRUEnever evaluated
FALSEnever evaluated
d->rawFont == other.d->rawFontDescription
TRUEnever evaluated
FALSEnever evaluated
0
183}-
184-
185/*!-
186 \fn bool QGlyphRun::operator!=(const QGlyphRun &other) const-
187-
188 Compares \a other to this QGlyphRun object. Returns \c true if any of the list of glyph-
189 indexes, the list of positions or the font are different, otherwise returns \c false.-
190*/-
191-
192/*!-
193 Returns the font selected for this QGlyphRun object.-
194-
195 \sa setRawFont()-
196*/-
197QRawFont QGlyphRun::rawFont() const-
198{-
199 return d->rawFont;
never executed: return d->rawFont;
0
200}-
201-
202/*!-
203 Sets the font in which to look up the glyph indexes to the \a rawFont-
204 specified.-
205-
206 \sa rawFont(), setGlyphIndexes()-
207*/-
208void QGlyphRun::setRawFont(const QRawFont &rawFont)-
209{-
210 detach();-
211 d->rawFont = rawFont;-
212}
never executed: end of block
0
213-
214/*!-
215 Returns the glyph indexes for this QGlyphRun object.-
216-
217 \sa setGlyphIndexes(), setPositions()-
218*/-
219QVector<quint32> QGlyphRun::glyphIndexes() const-
220{-
221 if (d->glyphIndexes.constData() == d->glyphIndexData) {
d->glyphIndexe...glyphIndexDataDescription
TRUEnever evaluated
FALSEnever evaluated
0
222 return d->glyphIndexes;
never executed: return d->glyphIndexes;
0
223 } else {-
224 QVector<quint32> indexes(d->glyphIndexDataSize);-
225 memcpy(indexes.data(), d->glyphIndexData, d->glyphIndexDataSize * sizeof(quint32));-
226 return indexes;
never executed: return indexes;
0
227 }-
228}-
229-
230/*!-
231 Set the glyph indexes for this QGlyphRun object to \a glyphIndexes. The glyph indexes must-
232 be valid for the selected font.-
233*/-
234void QGlyphRun::setGlyphIndexes(const QVector<quint32> &glyphIndexes)-
235{-
236 detach();-
237 d->glyphIndexes = glyphIndexes; // Keep a reference to the QVector to avoid copying-
238 d->glyphIndexData = glyphIndexes.constData();-
239 d->glyphIndexDataSize = glyphIndexes.size();-
240}
never executed: end of block
0
241-
242/*!-
243 Returns the position of the edge of the baseline for each glyph in this set of glyph indexes.-
244*/-
245QVector<QPointF> QGlyphRun::positions() const-
246{-
247 if (d->glyphPositions.constData() == d->glyphPositionData) {
d->glyphPositi...phPositionDataDescription
TRUEnever evaluated
FALSEnever evaluated
0
248 return d->glyphPositions;
never executed: return d->glyphPositions;
0
249 } else {-
250 QVector<QPointF> glyphPositions(d->glyphPositionDataSize);-
251 memcpy(glyphPositions.data(), d->glyphPositionData,-
252 d->glyphPositionDataSize * sizeof(QPointF));-
253 return glyphPositions;
never executed: return glyphPositions;
0
254 }-
255}-
256-
257/*!-
258 Sets the positions of the edge of the baseline for each glyph in this set of glyph indexes to-
259 \a positions.-
260*/-
261void QGlyphRun::setPositions(const QVector<QPointF> &positions)-
262{-
263 detach();-
264 d->glyphPositions = positions; // Keep a reference to the vector to avoid copying-
265 d->glyphPositionData = positions.constData();-
266 d->glyphPositionDataSize = positions.size();-
267}
never executed: end of block
0
268-
269/*!-
270 Clears all data in the QGlyphRun object.-
271*/-
272void QGlyphRun::clear()-
273{-
274 detach();-
275 d->rawFont = QRawFont();-
276 d->flags = 0;-
277-
278 setPositions(QVector<QPointF>());-
279 setGlyphIndexes(QVector<quint32>());-
280}
never executed: end of block
0
281-
282/*!-
283 Sets the glyph indexes and positions of this QGlyphRun to use the first \a size-
284 elements in the arrays \a glyphIndexArray and \a glyphPositionArray. The data is-
285 \e not copied. The caller must guarantee that the arrays are not deleted as long-
286 as this QGlyphRun and any copies of it exists.-
287-
288 \sa setGlyphIndexes(), setPositions()-
289*/-
290void QGlyphRun::setRawData(const quint32 *glyphIndexArray, const QPointF *glyphPositionArray,-
291 int size)-
292{-
293 detach();-
294 d->glyphIndexes.clear();-
295 d->glyphPositions.clear();-
296-
297 d->glyphIndexData = glyphIndexArray;-
298 d->glyphPositionData = glyphPositionArray;-
299 d->glyphIndexDataSize = d->glyphPositionDataSize = size;-
300}
never executed: end of block
0
301-
302/*!-
303 Returns \c true if this QGlyphRun should be painted with an overline decoration.-
304-
305 \sa setOverline(), flags()-
306*/-
307bool QGlyphRun::overline() const-
308{-
309 return d->flags & Overline;
never executed: return d->flags & Overline;
0
310}-
311-
312/*!-
313 Indicates that this QGlyphRun should be painted with an overline decoration if \a overline is true.-
314 Otherwise the QGlyphRun should be painted with no overline decoration.-
315-
316 \sa overline(), setFlag(), setFlags()-
317*/-
318void QGlyphRun::setOverline(bool overline)-
319{-
320 setFlag(Overline, overline);-
321}
never executed: end of block
0
322-
323/*!-
324 Returns \c true if this QGlyphRun should be painted with an underline decoration.-
325-
326 \sa setUnderline(), flags()-
327*/-
328bool QGlyphRun::underline() const-
329{-
330 return d->flags & Underline;
never executed: return d->flags & Underline;
0
331}-
332-
333/*!-
334 Indicates that this QGlyphRun should be painted with an underline decoration if \a underline is-
335 true. Otherwise the QGlyphRun should be painted with no underline decoration.-
336-
337 \sa underline(), setFlag(), setFlags()-
338*/-
339void QGlyphRun::setUnderline(bool underline)-
340{-
341 setFlag(Underline, underline);-
342}
never executed: end of block
0
343-
344/*!-
345 Returns \c true if this QGlyphRun should be painted with a strike out decoration.-
346-
347 \sa setStrikeOut(), flags()-
348*/-
349bool QGlyphRun::strikeOut() const-
350{-
351 return d->flags & StrikeOut;
never executed: return d->flags & StrikeOut;
0
352}-
353-
354/*!-
355 Indicates that this QGlyphRun should be painted with an strike out decoration if \a strikeOut is-
356 true. Otherwise the QGlyphRun should be painted with no strike out decoration.-
357-
358 \sa strikeOut(), setFlag(), setFlags()-
359*/-
360void QGlyphRun::setStrikeOut(bool strikeOut)-
361{-
362 setFlag(StrikeOut, strikeOut);-
363}
never executed: end of block
0
364-
365/*!-
366 Returns \c true if this QGlyphRun contains glyphs that are painted from the right to the left.-
367-
368 \since 5.0-
369 \sa setRightToLeft(), flags()-
370*/-
371bool QGlyphRun::isRightToLeft() const-
372{-
373 return d->flags & RightToLeft;
never executed: return d->flags & RightToLeft;
0
374}-
375-
376/*!-
377 Indicates that this QGlyphRun contains glyphs that should be ordered from the right to left-
378 if \a rightToLeft is true. Otherwise the order of the glyphs is assumed to be left to right.-
379-
380 \since 5.0-
381 \sa isRightToLeft(), setFlag(), setFlags()-
382*/-
383void QGlyphRun::setRightToLeft(bool rightToLeft)-
384{-
385 setFlag(RightToLeft, rightToLeft);-
386}
never executed: end of block
0
387-
388/*!-
389 Returns the flags set for this QGlyphRun.-
390-
391 \since 5.0-
392 \sa setFlag(), setFlag()-
393*/-
394QGlyphRun::GlyphRunFlags QGlyphRun::flags() const-
395{-
396 return d->flags;
never executed: return d->flags;
0
397}-
398-
399/*!-
400 If \a enabled is true, then \a flag is enabled; otherwise, it is disabled.-
401-
402 \since 5.0-
403 \sa flags(), setFlags()-
404*/-
405void QGlyphRun::setFlag(GlyphRunFlag flag, bool enabled)-
406{-
407 if (d->flags.testFlag(flag) == enabled)
d->flags.testF...ag) == enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
408 return;
never executed: return;
0
409-
410 detach();-
411 if (enabled)
enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
412 d->flags |= flag;
never executed: d->flags |= flag;
0
413 else-
414 d->flags &= ~flag;
never executed: d->flags &= ~flag;
0
415}-
416-
417/*!-
418 Sets the flags of this QGlyphRun to \a flags.-
419-
420 \since 5.0-
421 \sa setFlag(), flags()-
422*/-
423void QGlyphRun::setFlags(GlyphRunFlags flags)-
424{-
425 if (d->flags == flags)
d->flags == flagsDescription
TRUEnever evaluated
FALSEnever evaluated
0
426 return;
never executed: return;
0
427-
428 detach();-
429 d->flags = flags;-
430}
never executed: end of block
0
431-
432/*!-
433 Sets the bounding rect of the glyphs in this QGlyphRun to be \a boundingRect. This rectangle-
434 will be returned by boundingRect() unless it is empty, in which case the bounding rectangle of the-
435 glyphs in the glyph run will be returned instead.-
436-
437 \note Unless you are implementing text shaping, you should not have to use this function.-
438 It is used specifically when the QGlyphRun should represent an area which is smaller than the-
439 area of the glyphs it contains. This could happen e.g. if the glyph run is retrieved by calling-
440 QTextLayout::glyphRuns() and the specified range only includes part of a ligature (where two or-
441 more characters are combined to a single glyph.) When this is the case, the bounding rect should-
442 only include the appropriate part of the ligature glyph, based on a calculation of the average-
443 width of the characters in the ligature.-
444-
445 In order to support such a case (an example is selections which should be drawn with a different-
446 color than the main text color), it is necessary to clip the painting mechanism to the rectangle-
447 returned from boundingRect() to avoid drawing the entire ligature glyph.-
448-
449 \sa boundingRect()-
450-
451 \since 5.0-
452*/-
453void QGlyphRun::setBoundingRect(const QRectF &boundingRect)-
454{-
455 detach();-
456 d->boundingRect = boundingRect;-
457}
never executed: end of block
0
458-
459/*!-
460 Returns the smallest rectangle that contains all glyphs in this QGlyphRun. If a bounding rect-
461 has been set using setBoundingRect(), then this will be returned. Otherwise the bounding rect-
462 will be calculated based on the font metrics of the glyphs in the glyph run.-
463-
464 \since 5.0-
465*/-
466QRectF QGlyphRun::boundingRect() const-
467{-
468 if (!d->boundingRect.isEmpty() || !d->rawFont.isValid())
!d->boundingRect.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
!d->rawFont.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
469 return d->boundingRect;
never executed: return d->boundingRect;
0
470-
471 qreal minX, minY, maxX, maxY;-
472 minX = minY = maxX = maxY = 0;-
473-
474 for (int i = 0, n = qMin(d->glyphIndexDataSize, d->glyphPositionDataSize); i < n; ++i) {
i < nDescription
TRUEnever evaluated
FALSEnever evaluated
0
475 QRectF glyphRect = d->rawFont.boundingRect(d->glyphIndexData[i]);-
476 glyphRect.translate(d->glyphPositionData[i]);-
477-
478 if (i == 0) {
i == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
479 minX = glyphRect.left();-
480 minY = glyphRect.top();-
481 maxX = glyphRect.right();-
482 maxY = glyphRect.bottom();-
483 } else {
never executed: end of block
0
484 minX = qMin(glyphRect.left(), minX);-
485 minY = qMin(glyphRect.top(), minY);-
486 maxX = qMax(glyphRect.right(),maxX);-
487 maxY = qMax(glyphRect.bottom(), maxY);-
488 }
never executed: end of block
0
489 }-
490-
491 return QRectF(QPointF(minX, minY), QPointF(maxX, maxY));
never executed: return QRectF(QPointF(minX, minY), QPointF(maxX, maxY));
0
492}-
493-
494/*!-
495 Returns \c true if the QGlyphRun does not contain any glyphs.-
496-
497 \since 5.0-
498*/-
499bool QGlyphRun::isEmpty() const-
500{-
501 return d->glyphIndexDataSize == 0;
never executed: return d->glyphIndexDataSize == 0;
0
502}-
503-
504QT_END_NAMESPACE-
505-
506#endif // QT_NO_RAWFONT-
Source codeSwitch to Preprocessed file

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