Fix crash when linked image is missing.

This commit is contained in:
Roman Telezhynskyi 2022-02-11 12:53:51 +02:00
parent e68e44c24b
commit 7494b05b92
4 changed files with 82 additions and 53 deletions

View File

@ -41,6 +41,34 @@
#include <ciso646> #include <ciso646>
#include <QSvgRenderer> #include <QSvgRenderer>
const QString VBackgroundPatternImage::brokenImage = QStringLiteral("://icon/svg/broken_path.svg");
namespace
{
//---------------------------------------------------------------------------------------------------------------------
auto ScaleRasterImage(const QImage &image) -> QSize
{
if (image.isNull())
{
return {};
}
const double ratioX = PrintDPI / (image.dotsPerMeterX() / 100. * 2.54);
const double ratioY = PrintDPI / (image.dotsPerMeterY() / 100. * 2.54);
const QSize imageSize = image.size();
return {qRound(imageSize.width()*ratioX), qRound(imageSize.height()*ratioY)};
}
//---------------------------------------------------------------------------------------------------------------------
auto ScaleVectorImage(const QSvgRenderer &renderer) -> QSize
{
const QSize imageSize = renderer.defaultSize();
constexpr double ratio = PrintDPI / 90.;
return {qRound(imageSize.width()*ratio), qRound(imageSize.height()*ratio)};
}
} // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VBackgroundPatternImage::FromFile(const QString &fileName, bool builtIn) -> VBackgroundPatternImage auto VBackgroundPatternImage::FromFile(const QString &fileName, bool builtIn) -> VBackgroundPatternImage
{ {
@ -244,60 +272,16 @@ auto VBackgroundPatternImage::Size() const -> QSize
if (not m_size.isValid()) if (not m_size.isValid())
{ {
auto ScaleRasterImage = [](QImageReader &imageReader)
{
const QImage image = imageReader.read();
const double ratioX = PrintDPI / (image.dotsPerMeterX() / 100. * 2.54);
const double ratioY = PrintDPI / (image.dotsPerMeterY() / 100. * 2.54);
const QSize imageSize = image.size();
return QSize(qRound(imageSize.width()*ratioX), qRound(imageSize.height()*ratioY));
};
auto ScaleVectorImage = [](const QSvgRenderer &renderer)
{
const QSize imageSize = renderer.defaultSize();
constexpr double ratio = PrintDPI / 90.;
return QSize(qRound(imageSize.width()*ratio), qRound(imageSize.height()*ratio));
};
if (not m_filePath.isEmpty()) if (not m_filePath.isEmpty())
{ {
if (Type() == PatternImage::Raster) m_size = LinkedImageSize();
{ return m_size;
QImageReader imageReader(m_filePath);
m_size = ScaleRasterImage(imageReader);
return m_size;
}
if (Type() == PatternImage::Vector)
{
QSvgRenderer renderer;
renderer.load(m_filePath);
m_size = ScaleVectorImage(renderer);
return m_size;
}
} }
if (not m_contentData.isEmpty()) if (not m_contentData.isEmpty())
{ {
QByteArray array = QByteArray::fromBase64(m_contentData); m_size = BuiltInImageSize();
return m_size;
if (Type() == PatternImage::Raster)
{
QBuffer buffer(&array);
buffer.open(QIODevice::ReadOnly);
QImageReader imageReader(&buffer);
m_size = ScaleRasterImage(imageReader);
return m_size;
}
if (Type() == PatternImage::Vector)
{
QSvgRenderer renderer;
renderer.load(array);
m_size = ScaleVectorImage(renderer);
return m_size;
}
} }
} }
@ -371,3 +355,44 @@ void VBackgroundPatternImage::SetOpacity(qreal newOpacity)
{ {
m_opacity = qBound(0.0, newOpacity, 1.0); m_opacity = qBound(0.0, newOpacity, 1.0);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VBackgroundPatternImage::LinkedImageSize() const -> QSize
{
if (Type() == PatternImage::Raster)
{
const QImage image = QImageReader(m_filePath).read();
return image.isNull() ? ScaleVectorImage(QSvgRenderer(brokenImage)) : ScaleRasterImage(image);
}
if (Type() == PatternImage::Vector)
{
QSvgRenderer renderer(m_filePath);
return not renderer.isValid() ? ScaleVectorImage(QSvgRenderer(brokenImage)) : ScaleVectorImage(renderer);
}
return {};
}
//---------------------------------------------------------------------------------------------------------------------
auto VBackgroundPatternImage::BuiltInImageSize() const -> QSize
{
QByteArray array = QByteArray::fromBase64(m_contentData);
if (Type() == PatternImage::Raster)
{
QBuffer buffer(&array);
buffer.open(QIODevice::ReadOnly);
const QImage image = QImageReader(&buffer).read();
return image.isNull() ? ScaleVectorImage(QSvgRenderer(brokenImage)) : ScaleRasterImage(image);
}
if (Type() == PatternImage::Vector)
{
QSvgRenderer renderer(array);
return not renderer.isValid() ? ScaleVectorImage(QSvgRenderer(brokenImage)) : ScaleVectorImage(renderer);
}
return {};
}

View File

@ -95,6 +95,8 @@ public:
auto Opacity() const -> qreal; auto Opacity() const -> qreal;
void SetOpacity(qreal newOpacity); void SetOpacity(qreal newOpacity);
static const QString brokenImage;
private: private:
QUuid m_id{QUuid::createUuid()}; QUuid m_id{QUuid::createUuid()};
QString m_contentType{}; QString m_contentType{};
@ -108,6 +110,9 @@ private:
bool m_visible{true}; bool m_visible{true};
qreal m_opacity{1.0}; qreal m_opacity{1.0};
mutable QSize m_size{}; mutable QSize m_size{};
auto LinkedImageSize() const -> QSize;
auto BuiltInImageSize() const -> QSize;
}; };
#endif // VBACKGROUNDPATTERNIMAGE_H #endif // VBACKGROUNDPATTERNIMAGE_H

View File

@ -39,7 +39,7 @@ namespace
{ {
auto InvalidImage() -> QPixmap auto InvalidImage() -> QPixmap
{ {
QImageReader imageReader(QStringLiteral("://icon/svg/broken_path.svg")); QImageReader imageReader(VBackgroundPatternImage::brokenImage);
return std::move(QPixmap::fromImageReader(&imageReader)); return std::move(QPixmap::fromImageReader(&imageReader));
} }
} }

View File

@ -92,8 +92,7 @@ auto VBackgroundSVGItem::Renderer() const -> QSvgRenderer *
{ {
if (Stale()) if (Stale())
{ {
const QString brokenImage = QStringLiteral("://icon/svg/broken_path.svg"); m_renderer->load(VBackgroundPatternImage::brokenImage);
m_renderer->load(brokenImage);
VBackgroundPatternImage image = Image(); VBackgroundPatternImage image = Image();
if (not image.IsValid()) if (not image.IsValid())
@ -107,7 +106,7 @@ auto VBackgroundSVGItem::Renderer() const -> QSvgRenderer *
m_renderer->load(image.FilePath()); m_renderer->load(image.FilePath());
if (not m_renderer->isValid()) if (not m_renderer->isValid())
{ {
m_renderer->load(brokenImage); m_renderer->load(VBackgroundPatternImage::brokenImage);
} }
MakeFresh(); MakeFresh();
return m_renderer; return m_renderer;
@ -118,7 +117,7 @@ auto VBackgroundSVGItem::Renderer() const -> QSvgRenderer *
m_renderer->load(QByteArray::fromBase64(image.ContentData())); m_renderer->load(QByteArray::fromBase64(image.ContentData()));
if (not m_renderer->isValid()) if (not m_renderer->isValid())
{ {
m_renderer->load(brokenImage); m_renderer->load(VBackgroundPatternImage::brokenImage);
} }
MakeFresh(); MakeFresh();
return m_renderer; return m_renderer;