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

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