Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'jb45283' into 'mer-5.6'
[qtbase] Fix inlining of images in odf documents. Contributes to JB#45283

See merge request mer-core/qtbase!43
  • Loading branch information
adenexter committed May 23, 2019
2 parents 5319e62 + 3204b51 commit eef2159
Showing 1 changed file with 64 additions and 21 deletions.
85 changes: 64 additions & 21 deletions src/gui/text/qtextodfwriter.cpp
Expand Up @@ -37,6 +37,7 @@

#include "qtextodfwriter_p.h"

#include <QImageReader>
#include <QImageWriter>
#include <QTextListFormat>
#include <QTextList>
Expand Down Expand Up @@ -351,6 +352,29 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc
writer.writeEndElement(); // list-item
}

static bool probeImageData(QIODevice *device, QImage *image, QString *mimeType, qreal *width, qreal *height)
{
QImageReader reader(device);
const QByteArray format = reader.format().toLower();
if (format == "png") {
*mimeType = QStringLiteral("image/png");
} else if (format == "jpg") {
*mimeType = QStringLiteral("image/jpg");
} else if (format == "svg") {
*mimeType = QStringLiteral("image/svg+xml");
} else {
*image = reader.read();
return false;
}

const QSize size = reader.size();

*width = size.width();
*height = size.height();

return true;
}

void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextFragment &fragment) const
{
writer.writeStartElement(drawNS, QString::fromLatin1("frame"));
Expand All @@ -361,47 +385,66 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF
QTextImageFormat imageFormat = fragment.charFormat().toImageFormat();
writer.writeAttribute(drawNS, QString::fromLatin1("name"), imageFormat.name());

// vvv Copy pasted mostly from Qt =================
QByteArray data;
QString mimeType;
qreal width = 0;
qreal height = 0;

QImage image;
QString name = imageFormat.name();
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
name.prepend(QLatin1String("qrc"));
QUrl url = QUrl(name);
const QVariant data = m_document->resource(QTextDocument::ImageResource, url);
if (data.type() == QVariant::Image) {
image = qvariant_cast<QImage>(data);
} else if (data.type() == QVariant::ByteArray) {
image.loadFromData(data.toByteArray());
}

if (image.isNull()) {
QString context;
if (image.isNull()) { // try direct loading
name = imageFormat.name(); // remove qrc:/ prefix again
image.load(name);
const QVariant variant = m_document->resource(QTextDocument::ImageResource, url);
if (variant.type() == QVariant::Image) {
image = qvariant_cast<QImage>(variant);
} else if (variant.type() == QVariant::ByteArray) {
data = variant.toByteArray();

QBuffer buffer(&data);
buffer.open(QIODevice::ReadOnly);
probeImageData(&buffer, &image, &mimeType, &width, &height);
} else {
// try direct loading
QFile file(imageFormat.name());
if (file.open(QIODevice::ReadOnly) && !probeImageData(&file, &image, &mimeType, &width, &height)) {
file.seek(0);
data = file.readAll();
}
}

// ^^^ Copy pasted mostly from Qt =================
if (! image.isNull()) {
if (!image.isNull()) {
QBuffer imageBytes;

QImageWriter imageWriter(&imageBytes, "png");
imageWriter.write(image);

data = imageBytes.data();
mimeType = QStringLiteral("image/png");
width = image.width();
height = image.height();
}

if (!data.isEmpty()) {
if (imageFormat.hasProperty(QTextFormat::ImageWidth)) {
width = imageFormat.width();
}
if (imageFormat.hasProperty(QTextFormat::ImageHeight)) {
height = imageFormat.height();
}

QString filename = m_strategy->createUniqueImageName();
m_strategy->addFile(filename, QString::fromLatin1("image/png"), imageBytes.data());

// get the width/height from the format.
qreal width = (imageFormat.hasProperty(QTextFormat::ImageWidth)) ? imageFormat.width() : image.width();
m_strategy->addFile(filename, mimeType, data);

writer.writeAttribute(svgNS, QString::fromLatin1("width"), pixelToPoint(width));
qreal height = (imageFormat.hasProperty(QTextFormat::ImageHeight)) ? imageFormat.height() : image.height();
writer.writeAttribute(svgNS, QString::fromLatin1("height"), pixelToPoint(height));

writer.writeAttribute(textNS, QStringLiteral("anchor-type"), QStringLiteral("as-char"));
writer.writeStartElement(drawNS, QString::fromLatin1("image"));
writer.writeAttribute(xlinkNS, QString::fromLatin1("href"), filename);
writer.writeEndElement(); // image
}
}

writer.writeEndElement(); // frame
}

Expand Down

0 comments on commit eef2159

Please sign in to comment.