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