Skip to content

Commit

Permalink
add QSvg rendering fixups and apply to both SelectFiles and Image Rep…
Browse files Browse the repository at this point in the history
…orts [deploy]
  • Loading branch information
kevinhendricks committed Dec 6, 2023
1 parent 2d34cdc commit c43fee0
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 21 deletions.
31 changes: 25 additions & 6 deletions src/Dialogs/ReportsWidgets/ImageFilesWidget.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/************************************************************************
**
** Copyright (C) 2015-2022 Kevin Hendricks, Statford, ON
** Copyright (C) 2015-2023 Kevin Hendricks, Statford, ON
** Copyright (C) 2012 Dave Heiland
** Copyright (C) 2012 John Schember <[email protected]>
**
Expand All @@ -26,6 +26,10 @@
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QPushButton>
#include <QImage>
#include <QPainter>
#include <QPixmap>
#include <QtSvg/QSvgRenderer>

#include "sigil_exception.h"
#include "BookManipulation/FolderKeeper.h"
Expand Down Expand Up @@ -107,9 +111,26 @@ void ImageFilesWidget::SetupTable(int sort_column, Qt::SortOrder sort_order)
int total_links = 0;
QHash<QString, QStringList> image_html_files_hash = m_Book->GetHTMLFilesUsingImages();
foreach(Resource * resource, m_AllImageResources) {
Resource::ResourceType rt = resource->Type();
QString filepath = resource->GetRelativePath();
QString path = resource->GetFullPath();
QImage image(path);
QImage image;
if (resource->Type() == Resource::SVGResourceType) {
QString svgdata = Utility::ReadUnicodeTextFile(path);
// QtSvg has many issues with desc, title, and flowRoot tags
svgdata = Utility::FixupSvgForRendering(svgdata);
QSvgRenderer renderer(this);
renderer.load(svgdata.toUtf8());
QSize sz = renderer.defaultSize();
QImage svgimage(sz, QImage::Format_ARGB32);
// **must** fill it with tranparent pixels BEFORE trying to render anything
svgimage.fill(qRgba(0,0,0,0));
QPainter painter(&svgimage);
renderer.render(&painter);
image = svgimage;
} else {
image.load(path);
}
QList<QStandardItem *> rowItems;
// Filename
QStandardItem *name_item = new QStandardItem();
Expand Down Expand Up @@ -157,15 +178,13 @@ void ImageFilesWidget::SetupTable(int sort_column, Qt::SortOrder sort_order)
rowItems << color_item;

// Thumbnail
QPixmap pixmap = QPixmap::fromImage(image);
if (m_ThumbnailSize) {
QPixmap pixmap(resource->GetFullPath());

if (pixmap.height() > m_ThumbnailSize || pixmap.width() > m_ThumbnailSize) {
pixmap = pixmap.scaled(QSize(m_ThumbnailSize, m_ThumbnailSize), Qt::KeepAspectRatio);
}

QStandardItem *icon_item = new QStandardItem();
icon_item->setIcon(QIcon(pixmap));
icon_item->setData(QVariant(pixmap), Qt::DecorationRole);
rowItems << icon_item;
}

Expand Down
26 changes: 12 additions & 14 deletions src/Dialogs/SelectFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,31 +203,29 @@ void SelectFiles::SetImages()

// Do not show thumbnail if file is not an image
if ((type == Resource::ImageResourceType || type == Resource::SVGResourceType) && m_ThumbnailSize) {
QPixmap pixmap;
QImage image;
if (type == Resource::ImageResourceType) {
pixmap = QPixmap(resource->GetFullPath());
image.load(resource->GetFullPath());
} else { // Svg
QSvgRenderer renderer(resource->GetFullPath());
QString svgdata = Utility::ReadUnicodeTextFile(resource->GetFullPath());
// QtSvg has many issues with desc, title, and flowRoot tags
svgdata = Utility::FixupSvgForRendering(svgdata);
QSvgRenderer renderer(this);
renderer.load(svgdata.toUtf8());
QSize sz = renderer.defaultSize();
#if 1
QImage image(sz, QImage::Format_ARGB32);
QImage svgimage(sz, QImage::Format_ARGB32);
// **must** fill it with tranparent pixels BEFORE trying to render anything
image.fill(qRgba(0,0,0,0));
QPainter painter(&image);
svgimage.fill(qRgba(0,0,0,0));
QPainter painter(&svgimage);
renderer.render(&painter);
pixmap = QPixmap::fromImage(image);
#else
// or use this approach which seems to work although svg is not a documented format
pixmap = QPixmap(sz);
pixmap.load(resource->GetFullPath());
#endif
image = svgimage;
}
QPixmap pixmap = QPixmap::fromImage(image);
if (pixmap.height() > m_ThumbnailSize || pixmap.width() > m_ThumbnailSize) {
pixmap = pixmap.scaled(QSize(m_ThumbnailSize, m_ThumbnailSize), Qt::KeepAspectRatio);
}
QStandardItem *icon_item = new QStandardItem();
icon_item->setData(QVariant(pixmap), Qt::DecorationRole);
// icon_item->setIcon(QIcon(pixmap));
icon_item->setEditable(false);
rowItems << icon_item;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Dialogs/SelectFiles.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/************************************************************************
**
** Copyright (C) 2015-2021 Kevin B. Hendricks, Stratford Ontario Canada
** Copyright (C) 2015-2023 Kevin B. Hendricks, Stratford Ontario Canada
** Copyright (C) 2012-2013 John Schember <[email protected]>
** Copyright (C) 2012-2013 Dave Heiland
**
Expand Down
31 changes: 31 additions & 0 deletions src/Misc/Utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "Misc/SettingsStore.h"
#include "Misc/SleepFunctions.h"
#include "MainUI/MainApplication.h"
#include "Parsers/QuickParser.h"

#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
#define QT_ENUM_SKIPEMPTYPARTS Qt::SkipEmptyParts
Expand Down Expand Up @@ -1497,3 +1498,33 @@ QMessageBox::StandardButton Utility::critical(QWidget* parent, const QString &ti
#endif
return result;
}


// QtSvg is broken with respect to desc and title tags used
// inside text tags and does not support flowRoot and its children
// so strip them all out before trying to render using QSvgRenderer
QString Utility::FixupSvgForRendering(const QString& data)
{
QStringList svgdata;
QuickParser qp(data);
bool skip = false;
while(true) {
QuickParser::MarkupInfo mi = qp.parse_next();
if (mi.pos < 0) break;
if (mi.tname == "desc" || mi.tname == "title" || mi.tname == "flowRoot") {
if (mi.ttype == "single") {
continue;
} else if (mi.ttype == "begin") {
skip = true;
continue;
} else if (mi.ttype == "end") {
skip = false;
continue;
}
}
if (!skip) {
svgdata << qp.serialize_markup(mi);
}
}
return svgdata.join("");
}
3 changes: 3 additions & 0 deletions src/Misc/Utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ class Utility
static QMessageBox::StandardButton critical(QWidget *parent, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);

static QString FixupSvgForRendering(const QString& data);

};
#endif // UTILITY_H

Expand Down

0 comments on commit c43fee0

Please sign in to comment.