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
11QT_BEGIN_NAMESPACE
12
13QSvgGlyph::QSvgGlyph(QChar unicode, const QPainterPath &path, qreal horizAdvX)
14 : m_unicode(unicode), m_path(path), m_horizAdvX(horizAdvX)
15{
16
17}
18
19
20QSvgFont::QSvgFont(qreal horizAdvX)
21 : m_horizAdvX(horizAdvX)
22{
23}
24
25
26QString QSvgFont::familyName() const
27{
28 return m_familyName;
29}
30
31
32void 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
39void 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
90void QSvgFont::setFamilyName(const QString &name)
91{
92 m_familyName = name;
93}
94
95void QSvgFont::setUnitsPerEm(qreal upem)
96{
97 m_unitsPerEm = upem;
98}
99
100QT_END_NAMESPACE
101

source code of qtsvg/src/svg/qsvgfont.cpp