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 "qsvgfont_p.h" |
5 | |
6 | #include "qpainter.h" |
7 | #include "qpen.h" |
8 | #include "qdebug.h" |
9 | #include "qpicture.h" |
10 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | QSvgGlyph::QSvgGlyph(QChar unicode, const QPainterPath &path, qreal horizAdvX) |
14 | : m_unicode(unicode), m_path(path), m_horizAdvX(horizAdvX) |
15 | { |
16 | |
17 | } |
18 | |
19 | |
20 | QSvgFont::QSvgFont(qreal horizAdvX) |
21 | : m_horizAdvX(horizAdvX) |
22 | { |
23 | } |
24 | |
25 | |
26 | QString QSvgFont::familyName() const |
27 | { |
28 | return m_familyName; |
29 | } |
30 | |
31 | |
32 | void QSvgFont::addGlyph(QChar unicode, const QPainterPath &path, qreal horizAdvX ) |
33 | { |
34 | m_glyphs.insert(key: unicode, value: QSvgGlyph(unicode, path, |
35 | (horizAdvX==-1)?m_horizAdvX:horizAdvX)); |
36 | } |
37 | |
38 | |
39 | void QSvgFont::draw(QPainter *p, const QPointF &point, const QString &str, qreal pixelSize, Qt::Alignment alignment) const |
40 | { |
41 | p->save(); |
42 | p->translate(offset: point); |
43 | p->scale(sx: pixelSize / m_unitsPerEm, sy: -pixelSize / m_unitsPerEm); |
44 | |
45 | // Calculate the text width to be used for alignment |
46 | int textWidth = 0; |
47 | QString::const_iterator itr = str.constBegin(); |
48 | for ( ; itr != str.constEnd(); ++itr) { |
49 | QChar unicode = *itr; |
50 | if (!m_glyphs.contains(key: *itr)) { |
51 | unicode = u'\0'; |
52 | if (!m_glyphs.contains(key: unicode)) |
53 | continue; |
54 | } |
55 | textWidth += static_cast<int>(m_glyphs[unicode].m_horizAdvX); |
56 | } |
57 | |
58 | QPoint alignmentOffset(0, 0); |
59 | if (alignment == Qt::AlignHCenter) { |
60 | alignmentOffset.setX(-textWidth / 2); |
61 | } else if (alignment == Qt::AlignRight) { |
62 | alignmentOffset.setX(-textWidth); |
63 | } |
64 | |
65 | p->translate(offset: alignmentOffset); |
66 | |
67 | // since in SVG the embedded font ain't really a path |
68 | // the outline has got to stay untransformed... |
69 | qreal penWidth = p->pen().widthF(); |
70 | penWidth /= (pixelSize/m_unitsPerEm); |
71 | QPen pen = p->pen(); |
72 | pen.setWidthF(penWidth); |
73 | p->setPen(pen); |
74 | |
75 | itr = str.constBegin(); |
76 | for ( ; itr != str.constEnd(); ++itr) { |
77 | QChar unicode = *itr; |
78 | if (!m_glyphs.contains(key: *itr)) { |
79 | unicode = u'\0'; |
80 | if (!m_glyphs.contains(key: unicode)) |
81 | continue; |
82 | } |
83 | p->drawPath(path: m_glyphs[unicode].m_path); |
84 | p->translate(dx: m_glyphs[unicode].m_horizAdvX, dy: 0); |
85 | } |
86 | |
87 | p->restore(); |
88 | } |
89 | |
90 | void QSvgFont::setFamilyName(const QString &name) |
91 | { |
92 | m_familyName = name; |
93 | } |
94 | |
95 | void QSvgFont::setUnitsPerEm(qreal upem) |
96 | { |
97 | m_unitsPerEm = upem; |
98 | } |
99 | |
100 | QT_END_NAMESPACE |
101 | |