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 QtQuick 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 "qsgsoftwareglyphnode_p.h"
41#include <QtGui/private/qrawfont_p.h>
42
43QT_BEGIN_NAMESPACE
44
45QSGSoftwareGlyphNode::QSGSoftwareGlyphNode()
46 : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
47 , m_style(QQuickText::Normal)
48{
49 setMaterial((QSGMaterial*)1);
50 setGeometry(&m_geometry);
51}
52
53namespace {
54QRectF calculateBoundingRect(const QPointF &position, const QGlyphRun &glyphs)
55{
56 QFixed minX;
57 QFixed minY;
58 QFixed maxX;
59 QFixed maxY;
60
61 QRawFontPrivate *rawFontD = QRawFontPrivate::get(font: glyphs.rawFont());
62 QFontEngine *fontEngine = rawFontD->fontEngine;
63
64 QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : QFontEngine::Format_A32;
65
66 int margin = fontEngine->glyphMargin(format: glyphFormat);
67
68 const QVector<uint> glyphIndexes = glyphs.glyphIndexes();
69 const QVector<QPointF> glyphPositions = glyphs.positions();
70 for (int i = 0, n = qMin(a: glyphIndexes.size(), b: glyphPositions.size()); i < n; ++i) {
71 glyph_metrics_t gm = fontEngine->alphaMapBoundingBox(glyph: glyphIndexes.at(i), QFixed(), matrix: QTransform(), glyphFormat);
72
73 gm.x += QFixed::fromReal(r: glyphPositions.at(i).x()) - margin;
74 gm.y += QFixed::fromReal(r: glyphPositions.at(i).y()) - margin;
75
76 if (i == 0) {
77 minX = gm.x;
78 minY = gm.y;
79 maxX = gm.x + gm.width;
80 maxY = gm.y + gm.height;
81 } else {
82 minX = qMin(a: gm.x, b: minX);
83 minY = qMin(a: gm.y, b: minY);
84 maxX = qMax(a: gm.x + gm.width, b: maxX);
85 maxY = qMax(a: gm.y + gm.height, b: maxY);
86 }
87 }
88
89 QRectF boundingRect(QPointF(minX.toReal(), minY.toReal()), QPointF(maxX.toReal(), maxY.toReal()));
90 return boundingRect.translated(p: position - QPointF(0.0, glyphs.rawFont().ascent()));
91}
92}
93
94void QSGSoftwareGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs)
95{
96 m_position = position;
97 m_glyphRun = glyphs;
98 m_bounding_rect = calculateBoundingRect(position, glyphs);
99}
100
101void QSGSoftwareGlyphNode::setColor(const QColor &color)
102{
103 m_color = color;
104}
105
106void QSGSoftwareGlyphNode::setStyle(QQuickText::TextStyle style)
107{
108 m_style = style;
109}
110
111void QSGSoftwareGlyphNode::setStyleColor(const QColor &color)
112{
113 m_styleColor = color;
114}
115
116QPointF QSGSoftwareGlyphNode::baseLine() const
117{
118 return QPointF();
119}
120
121void QSGSoftwareGlyphNode::setPreferredAntialiasingMode(QSGGlyphNode::AntialiasingMode)
122{
123}
124
125void QSGSoftwareGlyphNode::update()
126{
127}
128
129void QSGSoftwareGlyphNode::paint(QPainter *painter)
130{
131 painter->setBrush(QBrush());
132 QPointF pos = m_position - QPointF(0, m_glyphRun.rawFont().ascent());
133
134 qreal offset = 1.0;
135 if (painter->device()->devicePixelRatioF() > 0.0)
136 offset = 1.0 / painter->device()->devicePixelRatioF();
137
138 switch (m_style) {
139 case QQuickText::Normal: break;
140 case QQuickText::Outline:
141 painter->setPen(m_styleColor);
142 painter->drawGlyphRun(position: pos + QPointF(0, offset), glyphRun: m_glyphRun);
143 painter->drawGlyphRun(position: pos + QPointF(0, -offset), glyphRun: m_glyphRun);
144 painter->drawGlyphRun(position: pos + QPointF(offset, 0), glyphRun: m_glyphRun);
145 painter->drawGlyphRun(position: pos + QPointF(-offset, 0), glyphRun: m_glyphRun);
146 break;
147 case QQuickText::Raised:
148 painter->setPen(m_styleColor);
149 painter->drawGlyphRun(position: pos + QPointF(0, offset), glyphRun: m_glyphRun);
150 break;
151 case QQuickText::Sunken:
152 painter->setPen(m_styleColor);
153 painter->drawGlyphRun(position: pos + QPointF(0, -offset), glyphRun: m_glyphRun);
154 break;
155 }
156
157 painter->setPen(m_color);
158 painter->drawGlyphRun(position: pos, glyphRun: m_glyphRun);
159}
160
161QT_END_NAMESPACE
162

source code of qtdeclarative/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp