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