From 6c7e09fdb57c2927c5218bf14f5e26d3aa2d8617 Mon Sep 17 00:00:00 2001 From: Anton Thomasson Date: Sun, 29 May 2022 15:54:11 +0200 Subject: [PATCH] Add SVG support --- harbour-seaprint.pro | 1 + qml/harbour-seaprint.qml | 6 ++- qml/pages/PrinterPage.qml | 2 +- qml/pages/utils.js | 20 ++++++-- src/ippprinter.cpp | 7 ++- src/mimer.cpp | 6 ++- src/mimer.h | 2 + src/printerworker.cpp | 68 ++++++++++++++++++++------ translations/harbour-seaprint-de.ts | 8 +++ translations/harbour-seaprint-es.ts | 8 +++ translations/harbour-seaprint-fr.ts | 8 +++ translations/harbour-seaprint-nl.ts | 8 +++ translations/harbour-seaprint-pl.ts | 8 +++ translations/harbour-seaprint-zh_CN.ts | 8 +++ 14 files changed, 138 insertions(+), 22 deletions(-) diff --git a/harbour-seaprint.pro b/harbour-seaprint.pro index f9b45f9..dd18274 100644 --- a/harbour-seaprint.pro +++ b/harbour-seaprint.pro @@ -26,6 +26,7 @@ INSTALLS += i18n system(lrelease $$PWD/translations/*.ts) CONFIG += sailfishapp +QT += svg PKGCONFIG += mlite5 libcurl poppler glib-2.0 cairo libjpeg LIBS += -lcurl -lglib-2.0 -lgobject-2.0 -ldl DEFINES += MADNESS=1 diff --git a/qml/harbour-seaprint.qml b/qml/harbour-seaprint.qml index 598f22e..1976b6c 100644 --- a/qml/harbour-seaprint.qml +++ b/qml/harbour-seaprint.qml @@ -75,7 +75,11 @@ ApplicationWindow } function simplifyType(mimetype) { - if(Mimer.isImage(mimetype)) + if(mimetype == Mimer.SVG) + { + return {simple: "svg", translatable: qsTr("SVGs")}; + } + else if(Mimer.isImage(mimetype)) { return {simple: "image", translatable: qsTr("images")}; } diff --git a/qml/pages/PrinterPage.qml b/qml/pages/PrinterPage.qml index 38eff0f..fb32cbb 100644 --- a/qml/pages/PrinterPage.qml +++ b/qml/pages/PrinterPage.qml @@ -148,7 +148,7 @@ Page { tag: IppMsg.Keyword name: "print-scaling" prettyName: qsTr("Scaling") - valid: _valid && Mimer.isImage(selectedFileType) + valid: _valid && Mimer.isImage(selectedFileType) && selectedFileType != Mimer.SVG DependentOn { target: transferFormatSetting values: [Mimer.JPEG, Mimer.PNG] diff --git a/qml/pages/utils.js b/qml/pages/utils.js index d796b7c..01ab4f3 100644 --- a/qml/pages/utils.js +++ b/qml/pages/utils.js @@ -46,8 +46,7 @@ function supported_formats(printer, considerAdditionalFormats) mimetypes = mimetypes.concat(Mimer.Mimer.OfficeFormats); } - if (raster || has(formats, Mimer.Mimer.JPEG) || has(formats, Mimer.Mimer.PNG) || has(formats, Mimer.Mimer.RBMP) || - has(formats, Mimer.Mimer.PDF) || has(formats, Mimer.Mimer.Postscript)) + if(pdf || has(formats, Mimer.Mimer.JPEG) || has(formats, Mimer.Mimer.PNG) || has(formats, Mimer.Mimer.RBMP)) { images = true; mimetypes.push(Mimer.Mimer.JPEG); @@ -56,6 +55,11 @@ function supported_formats(printer, considerAdditionalFormats) mimetypes.push(Mimer.Mimer.GIF); } + if(pdf) + { + mimetypes.push(Mimer.Mimer.SVG); + } + return {pdf: pdf, postscript: postscript, plaintext: plaintext, office: office, images: images, mimetypes: mimetypes}; } @@ -259,6 +263,8 @@ function ippName(name, value, printerStrings) return qsTr("JPEG"); case Mimer.Mimer.GIF: return qsTr("GIF"); + case Mimer.Mimer.SVG: + return qsTr("SVG"); case Mimer.Mimer.RBMP: return qsTr("Reverse BMP"); default: @@ -401,12 +407,16 @@ function canConvertPlaintextTo(type) return has(targets, type) } - function canConvertOfficeDocumentTo(type) { return has(pdfTargets, type) } +function canConvertSvgTo(type) +{ + return has(pdfTargets, type) +} + function canConvertImageTo(type) { var targets = [Mimer.Mimer.OctetStream, Mimer.Mimer.JPEG, Mimer.Mimer.PNG, Mimer.Mimer.RBMP, @@ -445,6 +455,10 @@ function fixupChoices(name, choices, mimeType) { return choices.filter(canConvertOfficeDocumentTo) } + else if(mimeType == Mimer.Mimer.SVG) + { + return choices.filter(canConvertSvgTo) + } else if(Mimer.Mimer.isImage(mimeType)) { return choices.filter(canConvertImageTo); diff --git a/src/ippprinter.cpp b/src/ippprinter.cpp index 8f7fa3a..5f3d62e 100644 --- a/src/ippprinter.cpp +++ b/src/ippprinter.cpp @@ -383,6 +383,11 @@ QString targetFormatIfAuto(QString documentFormat, QString mimeType, QJsonArray { return firstMatch(supportedMimeTypes, PdfPrioList); } + else if(documentFormat == Mimer::SVG) + { + QStringList SvgPrioList {Mimer::PWG, Mimer::URF, Mimer::PDF, Mimer::Postscript}; + return firstMatch(supportedMimeTypes, SvgPrioList); + } else if(Mimer::isImage(mimeType)) { QStringList ImageFormatPrioList {Mimer::PNG, Mimer::PWG, Mimer::URF, Mimer::PDF, Mimer::Postscript, Mimer::JPEG}; @@ -696,7 +701,7 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename) { // Can't process Postscript emit doJustUpload(filename, contents); } - else if(mimer->isImage(mimeType) && mimer->isImage(targetFormat)) + else if((mimeType != Mimer::SVG) && mimer->isImage(mimeType) && mimer->isImage(targetFormat)) { // Just make sure the image is in the desired format (and jpeg baseline-encoded), don't resize locally emit doPrintImageAsImage(filename, contents, targetFormat); } diff --git a/src/mimer.cpp b/src/mimer.cpp index d29a2bc..a8bf915 100644 --- a/src/mimer.cpp +++ b/src/mimer.cpp @@ -1,4 +1,5 @@ #include "mimer.h" +#include const QString Mimer::OctetStream = "application/octet-stream"; @@ -11,6 +12,7 @@ const QString Mimer::PNG = "image/png"; const QString Mimer::GIF = "image/gif"; const QString Mimer::JPEG = "image/jpeg"; const QString Mimer::TIFF = "image/tiff"; +const QString Mimer::SVG = "image/svg+xml"; const QString Mimer::RBMP = "image/reverse-encoding-bmp"; const QString Mimer::DOC = "application/msword"; @@ -51,5 +53,7 @@ Mimer* Mimer::instance() } QString Mimer::get_type(QString filename) { - return _db.mimeTypeForFile(filename).name(); + QString type = _db.mimeTypeForFile(filename).name(); + qDebug() << "MimeType:" << type; + return type; } diff --git a/src/mimer.h b/src/mimer.h index 5a6d000..de9c083 100644 --- a/src/mimer.h +++ b/src/mimer.h @@ -24,6 +24,7 @@ public: Q_PROPERTY(const QString GIF MEMBER GIF CONSTANT); Q_PROPERTY(const QString JPEG MEMBER JPEG CONSTANT); Q_PROPERTY(const QString TIFF MEMBER TIFF CONSTANT); + Q_PROPERTY(const QString SVG MEMBER SVG CONSTANT); Q_PROPERTY(const QString RBMP MEMBER RBMP CONSTANT); Q_PROPERTY(const QString DOC MEMBER DOC CONSTANT); @@ -50,6 +51,7 @@ public: static const QString GIF; static const QString JPEG; static const QString TIFF; + static const QString SVG; static const QString RBMP; static const QString DOC; diff --git a/src/printerworker.cpp b/src/printerworker.cpp index 0513e60..4b313be 100644 --- a/src/printerworker.cpp +++ b/src/printerworker.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "ippprinter.h" #include "pdf2printable.h" #include "ppm2pwg.h" @@ -258,7 +259,7 @@ catch(const ConvertFailedException& e) void PrinterWorker::convertImage(QString filename, Bytestream header, PrintParameters Params, QMargins margins) { try { - + QString mimeType = Mimer::instance()->get_type(filename); if(Params.format == PrintParameters::URF && (Params.hwResW != Params.hwResH)) { // URF only supports symmetric resolutions @@ -268,18 +269,6 @@ try { qDebug() << "Size is" << Params.getPaperSizeWInPixels() << "x" << Params.getPaperSizeHInPixels(); - QImage inImage; - if(!inImage.load(filename)) - { - qDebug() << "failed to load"; - throw ConvertFailedException(tr("Failed to load image")); - } - - if(inImage.width() > inImage.height()) - { - inImage = inImage.transformed(QMatrix().rotate(270.0)); - } - int leftMarginPx = (margins.left()/2540.0)*Params.hwResW; int rightMarginPx = (margins.right()/2540.0)*Params.hwResW; int topMarginPx = (margins.top()/2540.0)*Params.hwResH; @@ -288,8 +277,57 @@ try { int totalXMarginPx = leftMarginPx+rightMarginPx; int totalYMarginPx = topMarginPx+bottomMarginPx; - inImage = inImage.scaled(Params.getPaperSizeWInPixels()-totalXMarginPx, Params.getPaperSizeHInPixels()-totalYMarginPx, - Qt::KeepAspectRatio, Qt::SmoothTransformation); + size_t targetWidth = Params.getPaperSizeWInPixels()-totalXMarginPx; + size_t targetHeight = Params.getPaperSizeHInPixels()-totalYMarginPx; + + QImage inImage; + if(mimeType == Mimer::SVG) + { + QSvgRenderer renderer(filename); + if(!renderer.isValid()) + { + qDebug() << "failed to load svg"; + throw ConvertFailedException(tr("Failed to load image")); + } + QSize defaultSize = renderer.defaultSize(); + QSize targetSize(targetWidth, targetHeight); + + if(defaultSize.width() > defaultSize.height()) + { + targetSize.transpose(); + } + + QSize initialSize = defaultSize.scaled(targetSize, Qt::KeepAspectRatio); + + inImage = QImage(initialSize, QImage::Format_RGB32); + inImage.fill(QColor("white")); + QPainter painter(&inImage); + + renderer.render(&painter); + painter.end(); // Or else the painter segfaults on destruction if we have messed with the image + + if(inImage.width() > inImage.height()) + { + inImage = inImage.transformed(QMatrix().rotate(270.0)); + } + + } + else + { + if(!inImage.load(filename)) + { + qDebug() << "failed to load"; + throw ConvertFailedException(tr("Failed to load image")); + } + if(inImage.width() > inImage.height()) + { + inImage = inImage.transformed(QMatrix().rotate(270.0)); + } + + inImage = inImage.scaled(targetWidth, targetHeight, + Qt::KeepAspectRatio, Qt::SmoothTransformation); + } + if(Params.format == PrintParameters::PDF || Params.format == PrintParameters::Postscript) { diff --git a/translations/harbour-seaprint-de.ts b/translations/harbour-seaprint-de.ts index 98ca44a..5b6b620 100644 --- a/translations/harbour-seaprint-de.ts +++ b/translations/harbour-seaprint-de.ts @@ -611,6 +611,10 @@ auf diesem Drucker plaintext + + SVGs + + strings @@ -5505,5 +5509,9 @@ auf diesem Drucker Reverse BMP + + SVG + + diff --git a/translations/harbour-seaprint-es.ts b/translations/harbour-seaprint-es.ts index c6431ba..607e402 100644 --- a/translations/harbour-seaprint-es.ts +++ b/translations/harbour-seaprint-es.ts @@ -610,6 +610,10 @@ plaintext + + SVGs + + strings @@ -5504,5 +5508,9 @@ Reverse BMP + + SVG + + diff --git a/translations/harbour-seaprint-fr.ts b/translations/harbour-seaprint-fr.ts index 4060024..35e55a3 100644 --- a/translations/harbour-seaprint-fr.ts +++ b/translations/harbour-seaprint-fr.ts @@ -611,6 +611,10 @@ sur cette imprimante plaintext + + SVGs + + strings @@ -5505,5 +5509,9 @@ sur cette imprimante Reverse BMP + + SVG + + diff --git a/translations/harbour-seaprint-nl.ts b/translations/harbour-seaprint-nl.ts index ead528d..82fc33b 100644 --- a/translations/harbour-seaprint-nl.ts +++ b/translations/harbour-seaprint-nl.ts @@ -610,6 +610,10 @@ plaintext + + SVGs + + strings @@ -5504,5 +5508,9 @@ Reverse BMP + + SVG + + diff --git a/translations/harbour-seaprint-pl.ts b/translations/harbour-seaprint-pl.ts index 941fa83..b8eca97 100644 --- a/translations/harbour-seaprint-pl.ts +++ b/translations/harbour-seaprint-pl.ts @@ -610,6 +610,10 @@ plaintext + + SVGs + + strings @@ -5504,5 +5508,9 @@ Reverse BMP + + SVG + + diff --git a/translations/harbour-seaprint-zh_CN.ts b/translations/harbour-seaprint-zh_CN.ts index 0008ab2..4128e1d 100644 --- a/translations/harbour-seaprint-zh_CN.ts +++ b/translations/harbour-seaprint-zh_CN.ts @@ -610,6 +610,10 @@ plaintext + + SVGs + + strings @@ -5504,5 +5508,9 @@ Reverse BMP + + SVG + +