diff --git a/PdfForQtLib/sources/pdfcolorspaces.cpp b/PdfForQtLib/sources/pdfcolorspaces.cpp index b8d9817..217b2d1 100644 --- a/PdfForQtLib/sources/pdfcolorspaces.cpp +++ b/PdfForQtLib/sources/pdfcolorspaces.cpp @@ -174,42 +174,61 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData, const unsigned int imageWidth = imageData.getWidth(); const unsigned int imageHeight = imageData.getHeight(); - //for (unsigned int i = 0, rowCount = imageData.getHeight(); i < rowCount; ++i) + + QMutex exceptionMutex; + std::optional exception; + auto transformPixelLine = [&](unsigned int i) { - PDFBitReader reader(&imageData.getData(), imageData.getBitsPerComponent()); - reader.seek(i * imageData.getStride()); - - const double max = reader.max(); - const double coefficient = 1.0 / max; - unsigned char* outputLine = image.scanLine(i); - - std::vector inputColors(imageWidth * componentCount, 0.0f); - auto itInputColor = inputColors.begin(); - for (unsigned int j = 0; j < imageData.getWidth(); ++j) + try { - for (unsigned int k = 0; k < componentCount; ++k) - { - PDFReal value = reader.read(); + PDFBitReader reader(&imageData.getData(), imageData.getBitsPerComponent()); + reader.seek(i * imageData.getStride()); - // Interpolate value, if it is not empty - if (!decode.empty()) + const double max = reader.max(); + const double coefficient = 1.0 / max; + unsigned char* outputLine = image.scanLine(i); + + std::vector inputColors(imageWidth * componentCount, 0.0f); + auto itInputColor = inputColors.begin(); + for (unsigned int j = 0; j < imageData.getWidth(); ++j) + { + for (unsigned int k = 0; k < componentCount; ++k) { - *itInputColor++ = interpolate(value, 0.0, max, decode[2 * k], decode[2 * k + 1]); - } - else - { - *itInputColor++ = value * coefficient; + PDFReal value = reader.read(); + + // Interpolate value, if it is not empty + if (!decode.empty()) + { + *itInputColor++ = interpolate(value, 0.0, max, decode[2 * k], decode[2 * k + 1]); + } + else + { + *itInputColor++ = value * coefficient; + } } } - } - fillRGBBuffer(inputColors, outputLine, intent, cms, reporter); + fillRGBBuffer(inputColors, outputLine, intent, cms, reporter); + } + catch (PDFException lineException) + { + QMutexLocker lock(&exceptionMutex); + if (!exception) + { + exception = lineException; + } + } }; auto range = PDFIntegerRange(0, imageHeight); std::for_each(std::execution::parallel_policy(), range.begin(), range.end(), transformPixelLine); + if (exception) + { + throw *exception; + } + return image; } diff --git a/PdfForQtLib/sources/pdffont.cpp b/PdfForQtLib/sources/pdffont.cpp index a262d97..87fb00c 100644 --- a/PdfForQtLib/sources/pdffont.cpp +++ b/PdfForQtLib/sources/pdffont.cpp @@ -538,10 +538,17 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ } else { - reporter->reportRenderError(RenderErrorType::Warning, PDFTranslationContext::tr("Glyph for composite font character with cid '%1' not found.").arg(cid)); + if (cid > 0) + { + // Character with CID == 0 is treated as default whitespace, it hasn't glyph + reporter->reportRenderError(RenderErrorType::Warning, PDFTranslationContext::tr("Glyph for composite font character with cid '%1' not found.").arg(cid)); + } + if (glyphWidth > 0) { - textSequence.items.emplace_back(nullptr, QChar(), glyphWidth * m_pixelSize * FONT_WIDTH_MULTIPLIER); + // We do not multiply advance with font size and FONT_WIDTH_MULTIPLIER, because in the code, + // "advance" is treated as in font space. + textSequence.items.emplace_back(nullptr, QChar(), -glyphWidth); } } }