r23525 by jghali - #16069: PDF import distorts images
scribus-commit
scribus-commit at lists.scribus.net
Sun Mar 22 15:08:24 UTC 2020
Author: jghali
Date: Sun Mar 22 15:08:24 2020
New Revision: 23525
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=23525
Log:
#16069: PDF import distorts images
Modified:
trunk/Scribus/scribus/pdf_analyzer.cpp
trunk/Scribus/scribus/pdf_analyzer.h
trunk/Scribus/scribus/pdflib_core.cpp
trunk/Scribus/scribus/plugins/import/pdf/slaoutput.cpp
trunk/Scribus/scribus/plugins/import/pdf/slaoutput.h
trunk/Scribus/scribus/scribusdoc.cpp
Modified: trunk/Scribus/scribus/pdf_analyzer.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23525&path=/trunk/Scribus/scribus/pdf_analyzer.cpp
==============================================================================
--- trunk/Scribus/scribus/pdf_analyzer.cpp (original)
+++ trunk/Scribus/scribus/pdf_analyzer.cpp Sun Mar 22 15:08:24 2020
@@ -66,6 +66,7 @@
PDFAnalyzer::PDFAnalyzer(QString & filename)
+ : m_filename(filename)
{
static bool nameMapInited = false;
if (!nameMapInited)
@@ -82,7 +83,7 @@
}
catch (PdfError & e)
{
- qDebug() << "Can't open the file";
+ qDebug() << "Can't open PDF file" << filename;
e.PrintErrorMsg();
return;
}
@@ -152,7 +153,7 @@
}
catch (PdfError & e)
{
- qDebug() << "Error in identifying the color type";
+ qDebug() << "Error in identifying the color type. File:" << m_filename;
e.PrintErrorMsg();
return CS_Unknown;
}
@@ -211,7 +212,7 @@
}
catch (PdfError & e)
{
- qDebug() << "Error in analyzing stream's resources.";
+ qDebug() << "Error in analyzing stream's resources. File:" << m_filename;
e.PrintErrorMsg();
return false;
}
@@ -384,7 +385,7 @@
}
else
{
- qDebug() << "Supplied colorspace is undefined!";
+ qDebug() << "Supplied colorspace is undefined! File:" << m_filename;
return false;
}
}
@@ -392,7 +393,7 @@
}
else
{
- qDebug() << "Wrong syntax in specifying color space!";
+ qDebug() << "Wrong syntax in specifying color space! File:" << m_filename;
return false;
}
}
@@ -453,7 +454,7 @@
}
else
{
- qDebug() << "Supplied colorspace is undefined!";
+ qDebug() << "Supplied colorspace is undefined! File:" << m_filename;
return false;
}
}
@@ -461,7 +462,7 @@
}
else
{
- qDebug() << "Wrong syntax in specifying color space!";
+ qDebug() << "Wrong syntax in specifying color space! File:" << m_filename;
return false;
}
}
@@ -530,14 +531,14 @@
}
else
{
- qDebug() << "Supplied external object is undefined!";
+ qDebug() << "Supplied external object is undefined! File:" << m_filename;
return false;
}
processedNamedXObj.append(args[0].GetName());
}
else
{
- qDebug() << "Wrong syntax for Do operator or there's no XObject defined!";
+ qDebug() << "Wrong syntax for Do operator or there's no XObject defined! File:" << m_filename;
return false;
}
@@ -617,14 +618,14 @@
}
else
{
- qDebug() << "Named graphic state used with gs operator is undefined in current ExtGState";
+ qDebug() << "Named graphic state used with gs operator is undefined in current ExtGState. File:" << m_filename;
return false;
}
processedNamedGS.append(args[0].GetName());
}
else
{
- qDebug() << "Wrong syntax in applying extended graphic state (gs operator) or there's no ExtGState defined!";
+ qDebug() << "Wrong syntax in applying extended graphic state (gs operator) or there's no ExtGState defined! File:" << m_filename;
return false;
}
}
@@ -652,13 +653,13 @@
}
else
{
- qDebug() << "The specified font cannot be found in current Resources!";
+ qDebug() << "The specified font cannot be found in current Resources! File:" << m_filename;
return false;
}
}
else
{
- qDebug() << "Wrong syntax in use of Tf operator or there's no Font defined in current Resources dictionary!";
+ qDebug() << "Wrong syntax in use of Tf operator or there's no Font defined in current Resources dictionary! File:" << m_filename;
return false;
}
}
@@ -674,7 +675,7 @@
}
catch (PdfError & e)
{
- qDebug() << "Error in parsing content stream";
+ qDebug() << "Error in parsing content stream File:" << m_filename;
e.PrintErrorMsg();
return false;
}
Modified: trunk/Scribus/scribus/pdf_analyzer.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23525&path=/trunk/Scribus/scribus/pdf_analyzer.h
==============================================================================
--- trunk/Scribus/scribus/pdf_analyzer.h (original)
+++ trunk/Scribus/scribus/pdf_analyzer.h Sun Mar 22 15:08:24 2020
@@ -164,6 +164,9 @@
// pointer to the PoDoFo Pdf's object
PoDoFo::PdfMemDocument* m_doc;
+ // Path to the analyzed file
+ QString m_filename;
+
// Call to this method to inspect a PdfCanvas (either a PdfPage or PdfXObject of subtype Form). This method will be called by inspectPDF
// to start inspecting a PDF's page; it could well be called recursively to continue analyzing further in case form XObjects are painted
// onto the page.
Modified: trunk/Scribus/scribus/pdflib_core.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23525&path=/trunk/Scribus/scribus/pdflib_core.cpp
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.cpp (original)
+++ trunk/Scribus/scribus/pdflib_core.cpp Sun Mar 22 15:08:24 2020
@@ -10349,7 +10349,7 @@
"Please disable experimental PDF and PS embedding and try again.").arg(pdfFile) );
return false;
}
- qDebug() << "Failed to embed the PDF file";
+ qDebug() << "Failed to embed the PDF file: " << pdfFile;
}
// no embedded PDF:
if (!imageLoaded)
Modified: trunk/Scribus/scribus/plugins/import/pdf/slaoutput.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23525&path=/trunk/Scribus/scribus/plugins/import/pdf/slaoutput.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/import/pdf/slaoutput.cpp (original)
+++ trunk/Scribus/scribus/plugins/import/pdf/slaoutput.cpp Sun Mar 22 15:08:24 2020
@@ -1513,7 +1513,7 @@
tmpSel->clear();
}
-void SlaOutputDev::setSoftMask(GfxState * /*state*/, POPPLER_CONST_070 double * /*bbox*/, GBool alpha, Function *transferFunc, GfxColor * /*backdropColor*/)
+void SlaOutputDev::setSoftMask(GfxState * /*state*/, POPPLER_CONST_070 double * bbox, GBool alpha, Function *transferFunc, GfxColor * /*backdropColor*/)
{
if (m_groupStack.count() <= 0)
return;
@@ -1529,6 +1529,8 @@
else
m_groupStack.top().inverted = true;
m_groupStack.top().maskName = m_currentMask;
+ // Remember the mask's bounding box as it might not align with the image to which the mask is later assigned.
+ m_groupStack.top().maskBBox = QRectF(QPointF(bbox[0], m_doc->currentPage()->height() - bbox[1]), QPointF(bbox[2], m_doc->currentPage()->height() - bbox[3]));
m_groupStack.top().alpha = alpha;
if (m_groupStack.top().Items.count() != 0)
applyMask(m_groupStack.top().Items.last());
@@ -2459,94 +2461,10 @@
t++;
}
}
- const double *ctm = state->getCTM();
- double xCoor = m_doc->currentPage()->xOffset();
- double yCoor = m_doc->currentPage()->yOffset();
- QRectF crect = QRectF(0, 0, width, height);
- m_ctm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, ctm[2] + ctm[4], ctm[3] + ctm[5]);
- QLineF cline = QLineF(0, 0, width, 0);
- QLineF tline = m_ctm.map(cline);
- QRectF trect = m_ctm.mapRect(crect);
- double sx = m_ctm.m11();
- double sy = m_ctm.m22();
- QTransform mm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, 0, 0);
- if ((mm.type() == QTransform::TxShear) || (mm.type() == QTransform::TxRotate))
- {
- mm.reset();
- mm.rotate(-tline.angle());
- res = res.transformed(mm);
- }
- else
- {
- if ((sx < 0) || (sy < 0))
- {
- mm.reset();
- if (sx < 0)
- mm.scale(-1, 1);
- if (sy < 0)
- mm.scale(1, -1);
- res = res.transformed(mm);
- }
- }
- if (res.isNull())
- {
- delete imgStr;
- delete image;
- return;
- }
- int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, xCoor + trect.x(), yCoor + trect.y(), trect.width(), trect.height(), 0, CommonStrings::None, CommonStrings::None);
- PageItem* ite = m_doc->Items->at(z);
- ite->ClipEdited = true;
- ite->FrameType = 3;
- m_doc->setRedrawBounding(ite);
- ite->Clip = flattenPath(ite->PoLine, ite->Segments);
- ite->setTextFlowMode(PageItem::TextFlowDisabled);
- ite->setFillShade(100);
- ite->setLineShade(100);
- ite->setFillEvenOdd(false);
- m_doc->adjustItemSize(ite);
- QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pdf_XXXXXX.png");
- tempFile->setAutoRemove(false);
- if (tempFile->open())
- {
- QString fileName = getLongPathName(tempFile->fileName());
- if (!fileName.isEmpty())
- {
- tempFile->close();
- ite->isInlineImage = true;
- ite->isTempFile = true;
- res.save(fileName, "PNG");
- m_doc->loadPict(fileName, ite);
- ite->setImageScalingMode(false, false);
- m_Elements->append(ite);
- if (m_groupStack.count() != 0)
- {
- m_groupStack.top().Items.append(ite);
- applyMask(ite);
- }
- if ((checkClip()) && (inPattern == 0))
- {
- FPointArray out = m_currentClipPath.copy();
- out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
- out.translate(-ite->xPos(), -ite->yPos());
- ite->PoLine = out.copy();
- FPoint wh = getMaxClipF(&ite->PoLine);
- ite->setWidthHeight(wh.x(), wh.y());
- ite->setTextFlowMode(PageItem::TextFlowDisabled);
- ite->ScaleType = true;
- m_doc->adjustItemSize(ite);
- ite->OldB2 = ite->width();
- ite->OldH2 = ite->height();
- ite->updateClip();
- }
- }
- else
- m_doc->Items->removeAll(ite);
- }
- else
- m_doc->Items->removeAll(ite);
+
+ createImageFrame(res, state, 3);
+
imgStr->close();
- delete tempFile;
delete imgStr;
delete image;
}
@@ -2554,7 +2472,7 @@
void SlaOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool interpolate, Stream *maskStr, int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap, GBool maskInterpolate)
{
-// qDebug() << "Masked Image Components" << colorMap->getNumPixelComps();
+// qDebug() << "SlaOutputDev::drawSoftMaskedImage Masked Image Components" << colorMap->getNumPixelComps();
ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
imgStr->reset();
unsigned int *dest = nullptr;
@@ -2604,35 +2522,191 @@
t++;
}
}
+
+ createImageFrame(res, state, 3);
+
+ delete imgStr;
+ delete[] buffer;
+ delete image;
+ delete mskStr;
+ delete[] mbuffer;
+}
+
+void SlaOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GBool maskInvert, GBool maskInterpolate)
+{
+// qDebug() << "SlaOutputDev::drawMaskedImage";
+ ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
+ imgStr->reset();
+ unsigned int *dest = nullptr;
+ unsigned char * buffer = new unsigned char[width * height * 4];
+ QImage * image = nullptr;
+ for (int y = 0; y < height; y++)
+ {
+ dest = (unsigned int *)(buffer + y * 4 * width);
+ Guchar * pix = imgStr->getLine();
+ colorMap->getRGBLine(pix, dest, width);
+ }
+ image = new QImage(buffer, width, height, QImage::Format_RGB32);
+ if (image == nullptr || image->isNull())
+ {
+ delete imgStr;
+ delete[] buffer;
+ delete image;
+ return;
+ }
+ ImageStream *mskStr = new ImageStream(maskStr, maskWidth, 1, 1);
+ mskStr->reset();
+ Guchar *mdest = nullptr;
+ int invert_bit = maskInvert ? 1 : 0;
+ unsigned char * mbuffer = new unsigned char[maskWidth * maskHeight];
+ memset(mbuffer, 0, maskWidth * maskHeight);
+ for (int y = 0; y < maskHeight; y++)
+ {
+ mdest = (Guchar *)(mbuffer + y * maskWidth);
+ Guchar * pix = mskStr->getLine();
+ for (int x = 0; x < maskWidth; x++)
+ {
+ if (pix[x] ^ invert_bit)
+ *mdest++ = 0;
+ else
+ *mdest++ = 255;
+ }
+ }
+ if ((maskWidth != width) || (maskHeight != height))
+ *image = image->scaled(maskWidth, maskHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ QImage res = image->convertToFormat(QImage::Format_ARGB32);
+ unsigned char cc, cm, cy, ck;
+ int s = 0;
+ for (int yi=0; yi < res.height(); ++yi)
+ {
+ QRgb *t = (QRgb*)(res.scanLine( yi ));
+ for (int xi=0; xi < res.width(); ++xi)
+ {
+ cc = qRed(*t);
+ cm = qGreen(*t);
+ cy = qBlue(*t);
+ ck = mbuffer[s];
+ (*t) = qRgba(cc, cm, cy, ck);
+ s++;
+ t++;
+ }
+ }
+
+ createImageFrame(res, state, colorMap->getNumPixelComps());
+
+ delete imgStr;
+ delete[] buffer;
+ delete image;
+ delete mskStr;
+ delete[] mbuffer;
+}
+
+void SlaOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool interpolate, POPPLER_CONST_082 int* maskColors, GBool inlineImg)
+{
+ ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
+// qDebug() << "SlaOutputDev::drawImage Image Components" << colorMap->getNumPixelComps() << "Mask" << maskColors;
+ imgStr->reset();
+ QImage* image = nullptr;
+ if (maskColors)
+ {
+ image = new QImage(width, height, QImage::Format_ARGB32);
+ for (int y = 0; y < height; y++)
+ {
+ QRgb *s = (QRgb*)(image->scanLine(y));
+ Guchar *pix = imgStr->getLine();
+ for (int x = 0; x < width; x++)
+ {
+ GfxRGB rgb;
+ colorMap->getRGB(pix, &rgb);
+ int Rc = qRound(colToDbl(rgb.r) * 255);
+ int Gc = qRound(colToDbl(rgb.g) * 255);
+ int Bc = qRound(colToDbl(rgb.b) * 255);
+ *s = qRgba(Rc, Gc, Bc, 255);
+ for (int i = 0; i < colorMap->getNumPixelComps(); ++i)
+ {
+ if (pix[i] < maskColors[2*i] * 255 || pix[i] > maskColors[2*i+1] * 255)
+ {
+ *s = *s | 0xff000000;
+ break;
+ }
+ }
+ s++;
+ pix += colorMap->getNumPixelComps();
+ }
+ }
+ }
+ else
+ {
+ image = new QImage(width, height, QImage::Format_ARGB32);
+ for (int y = 0; y < height; y++)
+ {
+ QRgb *s = (QRgb*)(image->scanLine(y));
+ Guchar *pix = imgStr->getLine();
+ for (int x = 0; x < width; x++)
+ {
+ if (colorMap->getNumPixelComps() == 4)
+ {
+ GfxCMYK cmyk;
+ colorMap->getCMYK(pix, &cmyk);
+ int Cc = qRound(colToDbl(cmyk.c) * 255);
+ int Mc = qRound(colToDbl(cmyk.m) * 255);
+ int Yc = qRound(colToDbl(cmyk.y) * 255);
+ int Kc = qRound(colToDbl(cmyk.k) * 255);
+ *s = qRgba(Yc, Mc, Cc, Kc);
+ }
+ else
+ {
+ GfxRGB rgb;
+ colorMap->getRGB(pix, &rgb);
+ int Rc = qRound(colToDbl(rgb.r) * 255);
+ int Gc = qRound(colToDbl(rgb.g) * 255);
+ int Bc = qRound(colToDbl(rgb.b) * 255);
+ *s = qRgba(Rc, Gc, Bc, 255);
+ }
+ s++;
+ pix += colorMap->getNumPixelComps();
+ }
+ }
+ }
+
+ if (image != nullptr && !image->isNull()) {
+ createImageFrame(*image, state, colorMap->getNumPixelComps());
+ }
+
+ delete imgStr;
+ delete image;
+}
+
+void SlaOutputDev::createImageFrame(QImage& image, GfxState *state, int numColorComponents)
+{
const double *ctm = state->getCTM();
double xCoor = m_doc->currentPage()->xOffset();
double yCoor = m_doc->currentPage()->yOffset();
- QRectF crect = QRectF(0, 0, width, height);
- m_ctm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, ctm[2] + ctm[4], ctm[3] + ctm[5]);
- QLineF cline = QLineF(0, 0, width, 0);
- QLineF tline = m_ctm.map(cline);
- QRectF trect = m_ctm.mapRect(crect);
- double sx = m_ctm.m11();
- double sy = m_ctm.m22();
- QTransform mm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, 0, 0);
- if ((mm.type() == QTransform::TxShear) || (mm.type() == QTransform::TxRotate))
- {
- mm.reset();
- mm.rotate(-tline.angle());
- res = res.transformed(mm);
- }
- else
- {
- if ((sx < 0) || (sy < 0))
- {
- if (sx < 0)
- mm.scale(-1, 1);
- if (sy < 0)
- mm.scale(1, -1);
- res = res.transformed(mm);
- }
- }
- int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, xCoor + trect.x(), yCoor + trect.y(), trect.width(), trect.height(), 0, CommonStrings::None, CommonStrings::None);
+
+ m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
+ double angle = m_ctm.map(QLineF(0, 0, 1, 0)).angle();
+ QPointF torigin;
+ // In PDF all images considered squares with unit length that are transformed into the proper
+ // dimensions by ctm.
+ // A positive determinant retains orientation. Thus orientation is the same as in the PDF
+ // coordinate system (y-axis increases upwards). As Scribus uses the inverse orientation the
+ // image needs to be flipped (a horizontal flip is applied later). For a flipped image the
+ // corner that will be origin in Scribus is the upper right corner (1, 1) of the image.
+ // A negative determinant changes the orientation such that the image is already in the Scribus
+ // coordinate orientation and no flip is necessary. The origin will be the upper left corner (0, 1).
+ if (m_ctm.determinant() > 0) {
+ torigin = m_ctm.map(QPointF(1, 1));
+ } else {
+ torigin = m_ctm.map(QPointF(0, 1));
+ }
+
+ // Determine the width and height of the image by undoing the rotation part
+ // of the CTM and applying the result to the unit square.
+ QTransform without_rotation;
+ without_rotation = m_ctm * without_rotation.rotate(angle);
+ QRectF trect_wr = without_rotation.mapRect(QRectF(0, 0, 1, 1));
+
+ int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Rectangle, xCoor + torigin.x(), yCoor + torigin.y(), trect_wr.width(), trect_wr.height(), 0, CommonStrings::None, CommonStrings::None);
PageItem* ite = m_doc->Items->at(z);
ite->ClipEdited = true;
ite->FrameType = 3;
@@ -2644,327 +2718,16 @@
ite->setFillEvenOdd(false);
ite->setFillTransparency(1.0 - state->getFillOpacity());
ite->setFillBlendmode(getBlendMode(state));
+ if (m_ctm.determinant() > 0)
+ {
+ ite->setRotation(-(angle - 180));
+ ite->setImageFlippedH(true);
+ }
+ else
+ ite->setRotation(-angle);
m_doc->adjustItemSize(ite);
- QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pdf_XXXXXX.png");
- tempFile->setAutoRemove(false);
- if (tempFile->open())
- {
- QString fileName = getLongPathName(tempFile->fileName());
- if (!fileName.isEmpty())
- {
- tempFile->close();
- ite->isInlineImage = true;
- ite->isTempFile = true;
- ite->AspectRatio = false;
- ite->ScaleType = false;
- res.save(fileName, "PNG");
- m_doc->loadPict(fileName, ite);
- // ite->setImageScalingMode(false, false);
- m_Elements->append(ite);
- if (m_groupStack.count() != 0)
- {
- m_groupStack.top().Items.append(ite);
- // applyMask(ite);
- }
- if ((checkClip()) && (inPattern == 0))
- {
- FPointArray out = m_currentClipPath.copy();
- out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
- out.translate(-ite->xPos(), -ite->yPos());
- ite->PoLine = out.copy();
- FPoint wh = getMaxClipF(&ite->PoLine);
- ite->setWidthHeight(wh.x(), wh.y());
- ite->setTextFlowMode(PageItem::TextFlowDisabled);
- ite->ScaleType = true;
- m_doc->adjustItemSize(ite);
- ite->OldB2 = ite->width();
- ite->OldH2 = ite->height();
- ite->updateClip();
- }
- }
- else
- m_doc->Items->removeAll(ite);
- }
- else
- m_doc->Items->removeAll(ite);
- delete tempFile;
- delete imgStr;
- delete[] buffer;
- delete image;
- delete mskStr;
- delete[] mbuffer;
-}
-
-void SlaOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GBool maskInvert, GBool maskInterpolate)
-{
- ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
- imgStr->reset();
- unsigned int *dest = nullptr;
- unsigned char * buffer = new unsigned char[width * height * 4];
- QImage * image = nullptr;
- for (int y = 0; y < height; y++)
- {
- dest = (unsigned int *)(buffer + y * 4 * width);
- Guchar * pix = imgStr->getLine();
- colorMap->getRGBLine(pix, dest, width);
- }
- image = new QImage(buffer, width, height, QImage::Format_RGB32);
- if (image == nullptr || image->isNull())
- {
- delete imgStr;
- delete[] buffer;
- delete image;
- return;
- }
- ImageStream *mskStr = new ImageStream(maskStr, maskWidth, 1, 1);
- mskStr->reset();
- Guchar *mdest = nullptr;
- int invert_bit = maskInvert ? 1 : 0;
- unsigned char * mbuffer = new unsigned char[maskWidth * maskHeight];
- memset(mbuffer, 0, maskWidth * maskHeight);
- for (int y = 0; y < maskHeight; y++)
- {
- mdest = (Guchar *)(mbuffer + y * maskWidth);
- Guchar * pix = mskStr->getLine();
- for (int x = 0; x < maskWidth; x++)
- {
- if (pix[x] ^ invert_bit)
- *mdest++ = 0;
- else
- *mdest++ = 255;
- }
- }
- if ((maskWidth != width) || (maskHeight != height))
- *image = image->scaled(maskWidth, maskHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- QImage res = image->convertToFormat(QImage::Format_ARGB32);
- unsigned char cc, cm, cy, ck;
- int s = 0;
- for (int yi=0; yi < res.height(); ++yi)
- {
- QRgb *t = (QRgb*)(res.scanLine( yi ));
- for (int xi=0; xi < res.width(); ++xi)
- {
- cc = qRed(*t);
- cm = qGreen(*t);
- cy = qBlue(*t);
- ck = mbuffer[s];
- (*t) = qRgba(cc, cm, cy, ck);
- s++;
- t++;
- }
- }
- const double *ctm = state->getCTM();
- double xCoor = m_doc->currentPage()->xOffset();
- double yCoor = m_doc->currentPage()->yOffset();
- QRectF crect = QRectF(0, 0, width, height);
- m_ctm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, ctm[2] + ctm[4], ctm[3] + ctm[5]);
- QLineF cline = QLineF(0, 0, width, 0);
- QLineF tline = m_ctm.map(cline);
- QRectF trect = m_ctm.mapRect(crect);
- double sx = m_ctm.m11();
- double sy = m_ctm.m22();
- QTransform mm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, 0, 0);
- if ((mm.type() == QTransform::TxShear) || (mm.type() == QTransform::TxRotate))
- {
- mm.reset();
- mm.rotate(-tline.angle());
- res = res.transformed(mm);
- }
- else
- {
- if ((sx < 0) || (sy < 0))
- {
- if (sx < 0)
- mm.scale(-1, 1);
- if (sy < 0)
- mm.scale(1, -1);
- res = res.transformed(mm);
- }
- }
- int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, xCoor + trect.x(), yCoor + trect.y(), trect.width(), trect.height(), 0, CommonStrings::None, CommonStrings::None);
- PageItem* ite = m_doc->Items->at(z);
- ite->ClipEdited = true;
- ite->FrameType = 3;
- m_doc->setRedrawBounding(ite);
- ite->Clip = flattenPath(ite->PoLine, ite->Segments);
- ite->setTextFlowMode(PageItem::TextFlowDisabled);
- ite->setFillShade(100);
- ite->setLineShade(100);
- ite->setFillEvenOdd(false);
- ite->setFillTransparency(1.0 - state->getFillOpacity());
- ite->setFillBlendmode(getBlendMode(state));
- m_doc->adjustItemSize(ite);
- QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pdf_XXXXXX.png");
- tempFile->setAutoRemove(false);
- if (tempFile->open())
- {
- QString fileName = getLongPathName(tempFile->fileName());
- if (!fileName.isEmpty())
- {
- tempFile->close();
- ite->isInlineImage = true;
- ite->isTempFile = true;
- ite->AspectRatio = false;
- ite->ScaleType = false;
- res.save(fileName, "PNG");
- m_doc->loadPict(fileName, ite);
- // ite->setImageScalingMode(false, false);
- m_Elements->append(ite);
- if (m_groupStack.count() != 0)
- {
- m_groupStack.top().Items.append(ite);
- // applyMask(ite);
- }
- if ((checkClip()) && (inPattern == 0))
- {
- FPointArray out = m_currentClipPath.copy();
- out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
- out.translate(-ite->xPos(), -ite->yPos());
- ite->PoLine = out.copy();
- FPoint wh = getMaxClipF(&ite->PoLine);
- ite->setWidthHeight(wh.x(), wh.y());
- ite->setTextFlowMode(PageItem::TextFlowDisabled);
- ite->ScaleType = true;
- m_doc->adjustItemSize(ite);
- ite->OldB2 = ite->width();
- ite->OldH2 = ite->height();
- ite->updateClip();
- }
- }
- else
- m_doc->Items->removeAll(ite);
- }
- else
- m_doc->Items->removeAll(ite);
- delete tempFile;
- delete imgStr;
- delete[] buffer;
- delete image;
- delete mskStr;
- delete[] mbuffer;
-}
-
-void SlaOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool interpolate, POPPLER_CONST_082 int* maskColors, GBool inlineImg)
-{
- ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
-// qDebug() << "Image Components" << colorMap->getNumPixelComps() << "Mask" << maskColors;
- imgStr->reset();
- QImage* image = nullptr;
- if (maskColors)
- {
- image = new QImage(width, height, QImage::Format_ARGB32);
- for (int y = 0; y < height; y++)
- {
- QRgb *s = (QRgb*)(image->scanLine(y));
- Guchar *pix = imgStr->getLine();
- for (int x = 0; x < width; x++)
- {
- GfxRGB rgb;
- colorMap->getRGB(pix, &rgb);
- int Rc = qRound(colToDbl(rgb.r) * 255);
- int Gc = qRound(colToDbl(rgb.g) * 255);
- int Bc = qRound(colToDbl(rgb.b) * 255);
- *s = qRgba(Rc, Gc, Bc, 255);
- for (int i = 0; i < colorMap->getNumPixelComps(); ++i)
- {
- if (pix[i] < maskColors[2*i] * 255 || pix[i] > maskColors[2*i+1] * 255)
- {
- *s = *s | 0xff000000;
- break;
- }
- }
- s++;
- pix += colorMap->getNumPixelComps();
- }
- }
- }
- else
- {
- image = new QImage(width, height, QImage::Format_ARGB32);
- for (int y = 0; y < height; y++)
- {
- QRgb *s = (QRgb*)(image->scanLine(y));
- Guchar *pix = imgStr->getLine();
- for (int x = 0; x < width; x++)
- {
- if (colorMap->getNumPixelComps() == 4)
- {
- GfxCMYK cmyk;
- colorMap->getCMYK(pix, &cmyk);
- int Cc = qRound(colToDbl(cmyk.c) * 255);
- int Mc = qRound(colToDbl(cmyk.m) * 255);
- int Yc = qRound(colToDbl(cmyk.y) * 255);
- int Kc = qRound(colToDbl(cmyk.k) * 255);
- *s = qRgba(Yc, Mc, Cc, Kc);
- }
- else
- {
- GfxRGB rgb;
- colorMap->getRGB(pix, &rgb);
- int Rc = qRound(colToDbl(rgb.r) * 255);
- int Gc = qRound(colToDbl(rgb.g) * 255);
- int Bc = qRound(colToDbl(rgb.b) * 255);
- *s = qRgba(Rc, Gc, Bc, 255);
- }
- s++;
- pix += colorMap->getNumPixelComps();
- }
- }
- }
- if (image == nullptr || image->isNull())
- {
- delete imgStr;
- delete image;
- return;
- }
- const double *ctm = state->getCTM();
- double xCoor = m_doc->currentPage()->xOffset();
- double yCoor = m_doc->currentPage()->yOffset();
- QRectF crect = QRectF(0, 0, width, height);
- m_ctm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, ctm[2] + ctm[4], ctm[3] + ctm[5]);
- QLineF cline = QLineF(0, 0, width, 0);
- QLineF tline = m_ctm.map(cline);
- QRectF trect = m_ctm.mapRect(crect);
- double sx = m_ctm.m11();
- double sy = m_ctm.m22();
- QImage img = image->copy();
- QTransform mm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, 0, 0);
- int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Rectangle, xCoor + trect.x(), yCoor + trect.y(), trect.width(), trect.height(), 0, CommonStrings::None, CommonStrings::None);
- PageItem* ite = m_doc->Items->at(z);
- ite->ClipEdited = true;
- ite->FrameType = 3;
- m_doc->setRedrawBounding(ite);
- ite->Clip = flattenPath(ite->PoLine, ite->Segments);
- ite->setTextFlowMode(PageItem::TextFlowDisabled);
- ite->setFillShade(100);
- ite->setLineShade(100);
- ite->setFillEvenOdd(false);
- ite->setFillTransparency(1.0 - state->getFillOpacity());
- ite->setFillBlendmode(getBlendMode(state));
- m_doc->adjustItemSize(ite);
- if ((mm.type() == QTransform::TxShear) || (mm.type() == QTransform::TxRotate))
- {
- ite->setImageRotation(-tline.angle());
- /*QTransform rotMat;
- rotMat.rotate(tline.angle());
- QTransform imgMat = m_ctm * rotMat.inverted();
- double scaleX = sqrt(imgMat.m11() * imgMat.m11() + imgMat.m12() * imgMat.m12());
- double scaleY = sqrt(imgMat.m21() * imgMat.m21() + imgMat.m22() * imgMat.m22());
- imgMat.scale(1.0 / scaleX, 1.0 / scaleY);
- if (!imgMat.isIdentity())
- img = img.transformed(imgMat);*/
- }
- else
- {
- if ((sx < 0) || (sy < 0))
- {
- if (sx < 0)
- ite->setImageFlippedH(true);
- if (sy < 0)
- ite->setImageFlippedV(true);
- }
- }
- if (colorMap->getNumPixelComps() == 4)
+
+ if (numColorComponents == 4)
{
QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pdf_XXXXXX.tif");
tempFile->setAutoRemove(false);
@@ -2981,16 +2744,16 @@
TIFF* tif = TIFFOpen(fileName.toLocal8Bit().data(), "w");
if (tif)
{
- TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, img.width());
- TIFFSetField(tif, TIFFTAG_IMAGELENGTH, img.height());
+ TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, image.width());
+ TIFFSetField(tif, TIFFTAG_IMAGELENGTH, image.height());
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
- for (int y = 0; y < img.height(); ++y)
+ for (int y = 0; y < image.height(); ++y)
{
- TIFFWriteScanline(tif, img.scanLine(y), y);
+ TIFFWriteScanline(tif, image.scanLine(y), y);
}
TIFFClose(tif);
m_doc->loadPict(fileName, ite);
@@ -3021,7 +2784,7 @@
ite->isTempFile = true;
ite->AspectRatio = false;
ite->ScaleType = false;
- img.save(fileName, "PNG");
+ image.save(fileName, "PNG");
m_doc->loadPict(fileName, ite);
m_Elements->append(ite);
if (m_groupStack.count() != 0)
@@ -3038,13 +2801,19 @@
if ((checkClip()) && (inPattern == 0))
{
FPointArray out = m_currentClipPath.copy();
+ QTransform mm;
+ mm.rotate(-ite->rotation());
out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
out.translate(-ite->xPos(), -ite->yPos());
+ // Undo the rotation of the clipping path as it is rotated together with the iamge.
+ for (int i = 0; i != out.size(); ++i)
+ {
+ QPointF p = mm.map(out.pointQF(i));
+ out.setPoint(i, p.x(), p.y());
+ }
ite->PoLine = out.copy();
ite->ClipEdited = true;
ite->FrameType = 3;
- FPoint wh = getMaxClipF(&ite->PoLine);
- ite->setWidthHeight(wh.x(), wh.y());
ite->setTextFlowMode(PageItem::TextFlowDisabled);
ite->ScaleType = true;
m_doc->adjustItemSize(ite);
@@ -3052,8 +2821,6 @@
ite->OldH2 = ite->height();
ite->updateClip();
}
- delete imgStr;
- delete image;
}
void SlaOutputDev::beginMarkedContent(POPPLER_CONST char *name, Object *dictRef)
@@ -3911,6 +3678,10 @@
if (!m_groupStack.top().maskName.isEmpty())
{
ite->setPatternMask(m_groupStack.top().maskName);
+ QRectF bbox = m_groupStack.top().maskBBox;
+ double sx, sy, px, py, r, shx, shy;
+ ite->maskTransform(sx, sy, px, py, r, shx, shy);
+ ite->setMaskTransform(sx, sy, bbox.x() - (ite->xPos() - m_doc->currentPage()->xOffset()) , bbox.y() - (ite->yPos() - m_doc->currentPage()->yOffset()) , r, shx, shy);
if (m_groupStack.top().alpha)
{
if (m_groupStack.top().inverted)
Modified: trunk/Scribus/scribus/plugins/import/pdf/slaoutput.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23525&path=/trunk/Scribus/scribus/plugins/import/pdf/slaoutput.h
==============================================================================
--- trunk/Scribus/scribus/plugins/import/pdf/slaoutput.h (original)
+++ trunk/Scribus/scribus/plugins/import/pdf/slaoutput.h Sun Mar 22 15:08:24 2020
@@ -295,6 +295,9 @@
QString UnicodeParsedString(POPPLER_CONST GooString *s1);
QString UnicodeParsedString(const std::string& s1);
bool checkClip();
+
+ void createImageFrame(QImage& image, GfxState *state, int numColorComponents);
+
bool pathIsClosed {false};
QString CurrColorFill;
int CurrFillShade {100};
@@ -314,6 +317,7 @@
GBool isolated;
GBool alpha;
QString maskName;
+ QRectF maskBBox;
bool inverted;
};
QStack<groupEntry> m_groupStack;
Modified: trunk/Scribus/scribus/scribusdoc.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23525&path=/trunk/Scribus/scribus/scribusdoc.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.cpp (original)
+++ trunk/Scribus/scribus/scribusdoc.cpp Sun Mar 22 15:08:24 2020
@@ -14565,7 +14565,7 @@
currItem->moveImageInFrame(-tp2.x() / currItem->imageXScale(), 0);
if (!currItem->imageFlippedV())
currItem->moveImageInFrame(0, -tp2.y() / currItem->imageYScale());
- FPoint tp(clipRect.width(), clipRect.height());
+ FPoint tp(clipRect.right(), clipRect.bottom());
if (currItem->imageFlippedH())
currItem->moveImageInFrame((currItem->width() - tp.x())/currItem->imageXScale(), 0);
if (currItem->imageFlippedV())
More information about the scribus-commit
mailing list