Add an SVG export option to store pictures smaller

An SVG keeps every picture at full resolution, whatever size it is
drawn at: a folio with 22 phone photos shown at a tenth of their size
gave a 270 MB SVG and took 65 s to write, most of it compressing the
photos again.

The export dialog gets "SVG: smaller pictures" (off by default, kept
with the other export settings), and --export-svg gets
--svg-small-pictures. With it, a picture is stored at four times the
size it is drawn at when that is smaller than the picture; smaller
pictures stay whole. Four times is about 375 dpi on a printed folio.

The exporter sets Diagram::smallPictures() for its own drawing only,
so screen, print, PDF and PNG are unchanged. It is not part of
applyProperties(), which every format uses.

On that project: --export-svg 84.9 s -> 34.5 s (opening is 20 s of
both), 270 MB -> 57 MB, peak memory 2.45 -> 1.86 GB. Rendered at twice
the folio size, the two SVGs differ by more than 32/255 on 0.23 % of
pixels, along photo detail.

tst_svgsmallpictures: an 800x600 picture drawn at 0.1 is stored at
320x240 with the option, through --export-svg and through the
dialog's QPicture route, and at 800x600 without it; a 40x30 picture
stays whole. It fails when the factor is changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-14 13:12:38 +13:00
parent 8b680af938
commit da6eb83035
12 changed files with 252 additions and 4 deletions
+7 -2
View File
@@ -283,7 +283,8 @@ int exportPdf(QETProject &project, const QString &output,
}
int exportImages(QETProject &project, const QString &format,
const QString &out_dir, bool showTerminals = false)
const QString &out_dir, bool showTerminals = false,
bool svgSmallPictures = false)
{
const QList<Diagram *> diagrams = project.diagrams();
if (diagrams.isEmpty()) {
@@ -306,8 +307,10 @@ int exportImages(QETProject &project, const QString &format,
gen.setViewBox(QRect(0, 0, r.width(), r.height()));
gen.setTitle(diagram->title());
QPainter painter(&gen);
diagram->setSmallPictures(svgSmallPictures);
renderDiagram(diagram, painter, QRectF(QPointF(0, 0), r.size()),
showTerminals);
diagram->setSmallPictures(false);
painter.end();
} else { // png
QImage image(r.size(), QImage::Format_ARGB32);
@@ -1014,6 +1017,7 @@ int run(const QStringList &args)
const bool showTerminals = filtered.removeAll("--show-terminals") > 0;
const bool dxfBlocks = filtered.removeAll("--dxf-blocks") > 0;
const bool dxfAttributes = filtered.removeAll("--dxf-attributes") > 0;
const bool svgSmallPictures = filtered.removeAll("--svg-small-pictures") > 0;
// --no-slaves and --no-junctions leave rows out of --export-bom.
const bool includeSlaves = filtered.removeAll("--no-slaves") == 0;
const bool includeJunctions = filtered.removeAll("--no-junctions") == 0;
@@ -1085,7 +1089,8 @@ int run(const QStringList &args)
return resaveProject(project, output);
if (format == "settb")
return setTitleBlock(project, output, rest.mid(2));
return exportImages(project, format, output, showTerminals);
return exportImages(project, format, output, showTerminals,
svgSmallPictures);
}
} // namespace CLIExport