File indexing completed on 2025-04-27 04:04:22
0001 /* 0002 * SPDX-FileCopyrightText: (C) 2021 Mikel Johnson <mikel5764@gmail.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "vectorimage.h" 0008 #include <QQuickWindow> 0009 0010 VectorImage::VectorImage(QQuickItem *parent) 0011 : QQuickPaintedItem(parent) 0012 , m_devicePixelRatio(0) 0013 , m_status(Null) 0014 { 0015 } 0016 0017 void VectorImage::setSourceClipRect(const QRectF &sourceClipRect) 0018 { 0019 if (m_sourceClipRect == sourceClipRect) { 0020 return; 0021 } 0022 m_sourceClipRect = sourceClipRect; 0023 Q_EMIT sourceClipRectChanged(); 0024 update(); 0025 } 0026 0027 void VectorImage::setSourceSize(const QSize &sourceSize) 0028 { 0029 if (m_sourceSize == sourceSize) { 0030 return; 0031 } 0032 m_sourceSize = sourceSize; 0033 Q_EMIT sourceSizeChanged(); 0034 } 0035 0036 void VectorImage::setStatus(Status status) 0037 { 0038 if (m_status == status) { 0039 return; 0040 } 0041 m_status = status; 0042 Q_EMIT statusChanged(m_status); 0043 } 0044 0045 void VectorImage::setSource(const QUrl &source) 0046 { 0047 if (m_source == source) { 0048 return; 0049 } 0050 m_source = source; 0051 Q_EMIT sourceChanged(); 0052 0053 if (m_source.isEmpty()) { 0054 setStatus(Null); 0055 m_viewBoxF = QRectF(); 0056 setSourceSize(QSize()); 0057 return; 0058 } 0059 0060 setStatus(Loading); 0061 0062 m_renderer = std::make_unique<QSvgRenderer>(m_source.toLocalFile()); 0063 0064 if (!m_renderer->isValid()) { 0065 setStatus(Error); 0066 m_viewBoxF = QRectF(); 0067 setSourceSize(QSize()); 0068 return; 0069 } 0070 0071 m_renderer->setAspectRatioMode(Qt::KeepAspectRatio); 0072 0073 setSourceSize(m_renderer->defaultSize()); 0074 0075 m_viewBoxF = m_renderer->viewBoxF(); 0076 0077 if (m_devicePixelRatio == 0) { 0078 m_devicePixelRatio = window()->effectiveDevicePixelRatio(); 0079 } 0080 setStatus(Ready); 0081 update(); 0082 } 0083 0084 void VectorImage::itemChange(ItemChange change, const ItemChangeData &value) 0085 { 0086 if (change == ItemDevicePixelRatioHasChanged && m_devicePixelRatio != value.realValue) { 0087 m_devicePixelRatio = value.realValue; 0088 update(); 0089 } 0090 QQuickItem::itemChange(change, value); 0091 } 0092 0093 void VectorImage::paint(QPainter *painter) 0094 { 0095 if (m_status != Ready) { 0096 return; 0097 } 0098 0099 auto scale_x = sourceSize().width() / width() / m_devicePixelRatio; 0100 auto zoom_x = sourceClipRect().width() / m_viewBoxF.width() * scale_x; 0101 0102 auto scale_y = sourceSize().height() / height() / m_devicePixelRatio; 0103 auto zoom_y = sourceClipRect().height() / m_viewBoxF.height() * scale_y; 0104 0105 QRectF clip(sourceClipRect().x() / zoom_x * scale_x + m_viewBoxF.x(), 0106 sourceClipRect().y() / zoom_y * scale_y + m_viewBoxF.y(), 0107 sourceSize().width() / zoom_x, 0108 sourceSize().height() / zoom_y); 0109 0110 m_renderer->setViewBox(clip); 0111 m_renderer->render(painter); 0112 0113 return; 0114 }