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 "qsgsoftwareglyphnode_p.h" |
5 | #include <QtGui/private/qrawfont_p.h> |
6 | |
7 | QT_BEGIN_NAMESPACE |
8 | |
9 | QSGSoftwareGlyphNode::QSGSoftwareGlyphNode() |
10 | : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0) |
11 | , m_style(QQuickText::Normal) |
12 | { |
13 | setMaterial((QSGMaterial*)1); |
14 | setGeometry(&m_geometry); |
15 | } |
16 | |
17 | namespace { |
18 | QRectF calculateBoundingRect(const QPointF &position, const QGlyphRun &glyphs) |
19 | { |
20 | QFixed minX; |
21 | QFixed minY; |
22 | QFixed maxX; |
23 | QFixed maxY; |
24 | |
25 | QRawFontPrivate *rawFontD = QRawFontPrivate::get(font: glyphs.rawFont()); |
26 | QFontEngine *fontEngine = rawFontD->fontEngine; |
27 | |
28 | QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : QFontEngine::Format_A32; |
29 | |
30 | int margin = fontEngine->glyphMargin(format: glyphFormat); |
31 | |
32 | const QVector<uint> glyphIndexes = glyphs.glyphIndexes(); |
33 | const QVector<QPointF> glyphPositions = glyphs.positions(); |
34 | for (int i = 0, n = qMin(a: glyphIndexes.size(), b: glyphPositions.size()); i < n; ++i) { |
35 | glyph_metrics_t gm = fontEngine->alphaMapBoundingBox(glyph: glyphIndexes.at(i), QFixedPoint(), matrix: QTransform(), glyphFormat); |
36 | |
37 | gm.x += QFixed::fromReal(r: glyphPositions.at(i).x()) - margin; |
38 | gm.y += QFixed::fromReal(r: glyphPositions.at(i).y()) - margin; |
39 | |
40 | if (i == 0) { |
41 | minX = gm.x; |
42 | minY = gm.y; |
43 | maxX = gm.x + gm.width; |
44 | maxY = gm.y + gm.height; |
45 | } else { |
46 | minX = qMin(a: gm.x, b: minX); |
47 | minY = qMin(a: gm.y, b: minY); |
48 | maxX = qMax(a: gm.x + gm.width, b: maxX); |
49 | maxY = qMax(a: gm.y + gm.height, b: maxY); |
50 | } |
51 | } |
52 | |
53 | QRectF boundingRect(QPointF(minX.toReal(), minY.toReal()), QPointF(maxX.toReal(), maxY.toReal())); |
54 | return boundingRect.translated(p: position - QPointF(0.0, glyphs.rawFont().ascent())); |
55 | } |
56 | } |
57 | |
58 | void QSGSoftwareGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs) |
59 | { |
60 | m_position = position; |
61 | m_glyphRun = glyphs; |
62 | m_bounding_rect = calculateBoundingRect(position, glyphs); |
63 | } |
64 | |
65 | void QSGSoftwareGlyphNode::setColor(const QColor &color) |
66 | { |
67 | m_color = color; |
68 | } |
69 | |
70 | void QSGSoftwareGlyphNode::setStyle(QQuickText::TextStyle style) |
71 | { |
72 | m_style = style; |
73 | } |
74 | |
75 | void QSGSoftwareGlyphNode::setStyleColor(const QColor &color) |
76 | { |
77 | m_styleColor = color; |
78 | } |
79 | |
80 | QPointF QSGSoftwareGlyphNode::baseLine() const |
81 | { |
82 | return QPointF(); |
83 | } |
84 | |
85 | void QSGSoftwareGlyphNode::setPreferredAntialiasingMode(QSGGlyphNode::AntialiasingMode) |
86 | { |
87 | } |
88 | |
89 | void QSGSoftwareGlyphNode::update() |
90 | { |
91 | } |
92 | |
93 | void QSGSoftwareGlyphNode::paint(QPainter *painter) |
94 | { |
95 | painter->setBrush(QBrush()); |
96 | QPointF pos = m_position - QPointF(0, m_glyphRun.rawFont().ascent()); |
97 | |
98 | qreal offset = 1.0; |
99 | if (painter->device()->devicePixelRatio() > 0.0) |
100 | offset = 1.0 / painter->device()->devicePixelRatio(); |
101 | |
102 | switch (m_style) { |
103 | case QQuickText::Normal: break; |
104 | case QQuickText::Outline: |
105 | painter->setPen(m_styleColor); |
106 | painter->drawGlyphRun(position: pos + QPointF(0, offset), glyphRun: m_glyphRun); |
107 | painter->drawGlyphRun(position: pos + QPointF(0, -offset), glyphRun: m_glyphRun); |
108 | painter->drawGlyphRun(position: pos + QPointF(offset, 0), glyphRun: m_glyphRun); |
109 | painter->drawGlyphRun(position: pos + QPointF(-offset, 0), glyphRun: m_glyphRun); |
110 | break; |
111 | case QQuickText::Raised: |
112 | painter->setPen(m_styleColor); |
113 | painter->drawGlyphRun(position: pos + QPointF(0, offset), glyphRun: m_glyphRun); |
114 | break; |
115 | case QQuickText::Sunken: |
116 | painter->setPen(m_styleColor); |
117 | painter->drawGlyphRun(position: pos + QPointF(0, -offset), glyphRun: m_glyphRun); |
118 | break; |
119 | } |
120 | |
121 | painter->setPen(m_color); |
122 | painter->drawGlyphRun(position: pos, glyphRun: m_glyphRun); |
123 | } |
124 | |
125 | QT_END_NAMESPACE |
126 | |