Linux port

This commit is contained in:
Raphael Cotty 2021-10-29 15:17:40 +02:00 committed by Jakub Melka
parent 68704cd8e5
commit cbeb91fe18
58 changed files with 529 additions and 70 deletions

View File

@ -0,0 +1,9 @@
Pdf4QtApp {
name: "CodeGenerator"
files: [
"*.cpp",
"*.h",
"*.ui",
]
Depends { name: "Qt"; submodules: ["xml"] }
}

View File

@ -0,0 +1,9 @@
Pdf4QtApp {
name: "JBIG2_Viewer"
files: [
"*.cpp",
"*.h",
"*.ui",
]
Depends { name: "Qt"; submodules: ["widgets"] }
}

24
Pdf4Qt.qbs Normal file
View File

@ -0,0 +1,24 @@
import qbs
Project {
name: "Pdf4Qt"
qbsSearchPaths: ["qbs"]
references: [
"Pdf4QtLib/Pdf4QtLib.qbs",
"Pdf4QtViewer/Pdf4QtViewer.qbs",
"Pdf4QtViewerLite/Pdf4QtViewerLite.qbs",
"CodeGenerator/CodeGenerator.qbs",
"JBIG2_Viewer/JBIG2_Viewer.qbs",
"Pdf4QtDocPageOrganizer/Pdf4QtDocPageOrganizer.qbs",
"Pdf4QtDocDiff/Pdf4QtDocDiff.qbs",
"Pdf4QtViewerPlugins/AudioBookPlugin/AudioBookPlugin.qbs",
"Pdf4QtViewerPlugins/DimensionsPlugin/DimensionsPlugin.qbs",
"Pdf4QtViewerPlugins/OutputPreviewPlugin/OutputPreviewPlugin.qbs",
"Pdf4QtViewerPlugins/RedactPlugin/RedactPlugin.qbs",
"Pdf4QtViewerPlugins/SoftProofingPlugin/SoftProofingPlugin.qbs",
"Pdf4QtViewerProfi/Pdf4QtViewerProfi.qbs",
"PdfExampleGenerator/PdfExampleGenerator.qbs",
"PdfTool/PdfTool.qbs",
"UnitTests/UnitTests.qbs",
]
}

View File

@ -0,0 +1,11 @@
Pdf4QtApp {
name: "Pdf4QtDocDiff"
files: [
"*.cpp",
"*.h",
"*.ui",
"resources.qrc",
]
cpp.includePaths: ["."]
Depends { name: "Qt"; submodules: ["widgets"] }
}

View File

@ -248,7 +248,7 @@ void DifferencesDockWidget::update()
QTreeWidgetItem* parent = topItems.back();
QTreeWidgetItem* item = new QTreeWidgetItem(parent, QStringList() << m_diffResult->getMessage(i));
item->setData(0, Qt::UserRole, i);
item->setData(0, Qt::UserRole, QVariant(static_cast<qint64>(i)));
QColor color = getColorForIndex(i);

View File

@ -44,8 +44,10 @@ MainWindow::MainWindow(QWidget* parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
m_progress(new pdf::PDFProgress(this)),
#ifdef Q_OS_WIN
m_taskbarButton(new QWinTaskbarButton(this)),
m_progressTaskbarIndicator(nullptr),
#endif
m_cmsManager(nullptr),
m_pdfWidget(nullptr),
m_settingsDockWidget(nullptr),
@ -62,7 +64,9 @@ MainWindow::MainWindow(QWidget* parent) :
setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(800, 600)));
// Initialize task bar progress
#ifdef Q_OS_WIN
m_progressTaskbarIndicator = m_taskbarButton->progress();
#endif
m_settingsDockWidget = new SettingsDockWidget(&m_settings, this);
addDockWidget(Qt::LeftDockWidgetArea, m_settingsDockWidget);;
@ -186,7 +190,9 @@ MainWindow::~MainWindow()
void MainWindow::showEvent(QShowEvent* event)
{
Q_UNUSED(event);
#ifdef Q_OS_WIN
m_taskbarButton->setWindow(windowHandle());
#endif
}
void MainWindow::closeEvent(QCloseEvent* event)
@ -839,9 +845,13 @@ std::optional<pdf::PDFDocument> MainWindow::openDocument()
void MainWindow::onProgressStarted(pdf::ProgressStartupInfo info)
{
#ifdef Q_OS_WIN
m_progressTaskbarIndicator->setRange(0, 100);
m_progressTaskbarIndicator->reset();
m_progressTaskbarIndicator->show();
#else
Q_UNUSED(info);
#endif
}
void MainWindow::onProgressStep(int percentage)
@ -852,12 +862,18 @@ void MainWindow::onProgressStep(int percentage)
}
pdf::PDFTemporaryValueChange guard(&m_isChangingProgressStep, true);
#ifdef Q_OS_WIN
m_progressTaskbarIndicator->setValue(percentage);
#else
Q_UNUSED(percentage);
#endif
}
void MainWindow::onProgressFinished()
{
#ifdef Q_OS_WIN
m_progressTaskbarIndicator->hide();
#endif
}
} // namespace pdfdocdiff

View File

@ -27,8 +27,10 @@
#include <QMainWindow>
#include <QSignalMapper>
#ifdef Q_OS_WIN
#include <QWinTaskbarButton>
#include <QWinTaskbarProgress>
#endif
namespace Ui
{
@ -121,8 +123,10 @@ private:
Ui::MainWindow* ui;
pdf::PDFProgress* m_progress;
#ifdef Q_OS_WIN
QWinTaskbarButton* m_taskbarButton;
QWinTaskbarProgress* m_progressTaskbarIndicator;
#endif
pdf::PDFCMSManager* m_cmsManager;
pdf::PDFWidget* m_pdfWidget;
SettingsDockWidget* m_settingsDockWidget;

View File

@ -0,0 +1,11 @@
Pdf4QtApp {
name: "Pdf4QtDocPageOrganizer"
files: [
"*.cpp",
"*.h",
"*.ui",
"resources.qrc",
]
cpp.includePaths: ["."]
Depends { name: "Qt"; submodules: ["widgets"] }
}

43
Pdf4QtLib/Pdf4QtLib.qbs Normal file
View File

@ -0,0 +1,43 @@
import qbs
Pdf4QtLibrary {
name: "Pdf4QtLib"
Depends { name: "Qt"; submodules: ["core", "gui", "widgets"] }
Depends { name: "openssl" }
Depends { name: "freetype2" }
Depends { name: "libjpeg" }
Depends { name: "libopenjp2" }
Depends { name: "lcms2" }
Depends {
condition: qbs.toolchain.contains("gcc")
name: "tbb"
}
Depends {
condition: qbs.hostOS.contains("linux")
name: "fontconfig"
}
files: [
"sources/*.cpp",
"sources/*.h",
"sources/*.ui",
"cmaps.qrc",
]
Export {
Depends { name: "cpp" }
Depends { name: "Qt"; submodules: ["core", "gui", "widgets"] }
cpp.includePaths: ["sources"]
Depends { name: "openssl" }
Depends { name: "freetype2" }
Depends { name: "libjpeg" }
Depends { name: "libopenjp2" }
Depends { name: "lcms2" }
Depends {
condition: qbs.toolchain.contains("gcc")
name: "tbb"
}
Depends {
condition: qbs.hostOS.contains("linux")
name: "fontconfig"
}
}
}

View File

@ -322,7 +322,7 @@ PDFActionPtr PDFAction::parseImpl(const PDFObjectStorage* storage, PDFObject obj
PDFFormAction::FieldScope fieldScope = PDFFormAction::FieldScope::All;
PDFFileSpecification url = PDFFileSpecification::parse(storage, dictionary->get("F"));
PDFFormAction::FieldList fieldList = PDFFormAction::parseFieldList(storage, dictionary->get("Fields"), fieldScope);
PDFActionSubmitForm::SubmitFlags flags = static_cast<PDFActionSubmitForm::SubmitFlags>(loader.readIntegerFromDictionary(dictionary, "Flags", 0));
PDFActionSubmitForm::SubmitFlags flags = static_cast<PDFActionSubmitForm::SubmitFlag>(loader.readIntegerFromDictionary(dictionary, "Flags", 0));
QByteArray charset = loader.readStringFromDictionary(dictionary, "CharSet");
if (fieldScope == PDFFormAction::FieldScope::Include &&
@ -337,7 +337,7 @@ PDFActionPtr PDFAction::parseImpl(const PDFObjectStorage* storage, PDFObject obj
{
PDFFormAction::FieldScope fieldScope = PDFFormAction::FieldScope::All;
PDFFormAction::FieldList fieldList = PDFFormAction::parseFieldList(storage, dictionary->get("Fields"), fieldScope);
PDFActionResetForm::ResetFlags flags = static_cast<PDFActionResetForm::ResetFlags>(loader.readIntegerFromDictionary(dictionary, "Flags", 0));
PDFActionResetForm::ResetFlags flags = static_cast<PDFActionResetForm::ResetFlag>(loader.readIntegerFromDictionary(dictionary, "Flags", 0));
if (fieldScope == PDFFormAction::FieldScope::Include &&
flags.testFlag(PDFActionResetForm::IncludeExclude))

View File

@ -848,7 +848,7 @@ PDFAnnotationPtr PDFAnnotation::parse(const PDFObjectStorage* storage, PDFObject
result->m_lastModifiedString = loader.readTextStringFromDictionary(dictionary, "M", QString());
}
result->m_flags = Flags(loader.readIntegerFromDictionary(dictionary, "F", 0));
result->m_flags = Flags(static_cast<Flag>(loader.readIntegerFromDictionary(dictionary, "F", 0)));
result->m_appearanceStreams = PDFAppeareanceStreams::parse(storage, dictionary->get("AP"));
result->m_appearanceState = loader.readNameFromDictionary(dictionary, "AS");

View File

@ -28,20 +28,6 @@ constexpr uint8_t operator "" _bitlength()
return sizeof...(Digits);
}
enum CCITT_2D_Code_Mode
{
Pass,
Horizontal,
Vertical_3L,
Vertical_2L,
Vertical_1L,
Vertical_0,
Vertical_1R,
Vertical_2R,
Vertical_3R,
Invalid
};
struct PDFCCITT2DModeInfo
{
CCITT_2D_Code_Mode mode;

View File

@ -72,7 +72,19 @@ struct PDFCCITTFaxDecoderParameters
PDFImageData::MaskingType maskingType = PDFImageData::MaskingType::None;
};
enum CCITT_2D_Code_Mode;
enum CCITT_2D_Code_Mode
{
Pass,
Horizontal,
Vertical_3L,
Vertical_2L,
Vertical_1L,
Vertical_0,
Vertical_1R,
Vertical_2R,
Vertical_3R,
Invalid
};
class PDFCCITTFaxDecoder
{

View File

@ -1732,7 +1732,7 @@ PDFColorProfileIdentifiers PDFCMSManager::getExternalProfilesImpl() const
QStringList directories(m_settings.profileDirectory);
#ifdef Q_OS_WIN
#if defined(Q_OS_WIN)
std::array<WCHAR, _MAX_PATH> buffer = { };
DWORD bufferSize = DWORD(buffer.size() * sizeof(WCHAR));
if (GetColorDirectoryW(NULL, buffer.data(), &bufferSize))
@ -1743,8 +1743,20 @@ PDFColorProfileIdentifiers PDFCMSManager::getExternalProfilesImpl() const
QString directory = QString::fromWCharArray(buffer.data(), int(charactersWithoutNull));
directories << QDir::fromNativeSeparators(directory);
}
#elif defined(Q_OS_UNIX)
QDir directory(QStringLiteral("/usr/share/color/icc"));
if (directory.exists())
{
QStringList colorDirectories = directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString colorDirectory : colorDirectories)
{
QString colorDirectoryName = directory.absoluteFilePath(colorDirectory);
directories << QDir::fromNativeSeparators(colorDirectoryName);
}
}
#else
static_assert(false, "Implement this for another OS!");
#endif
for (const QString& directory : directories)
{
PDFColorProfileIdentifiers externalProfiles = getExternalColorProfiles(directory);

View File

@ -731,7 +731,7 @@ bool PDFAbstractColorSpace::transform(const PDFAbstractColorSpace* source,
for (PDFColorComponent gray : input)
{
const PDFColorComponent A = clip01(gray);
const PDFColorComponent xyzColor = std::powf(A, gamma);
const PDFColorComponent xyzColor = std::pow(A, gamma);
Q_ASSERT(it != transformedInputColorsVector.end());
*it++ = xyzColor;
@ -981,7 +981,7 @@ bool PDFAbstractColorSpace::transform(const PDFAbstractColorSpace* source,
XYZ[2] = *std::next(transformedOutputIt, 2);
const PDFColorComponent gray = (XYZ[0] + XYZ[1] + XYZ[2]) * 0.333333333333333;
const PDFColorComponent grayWithGamma = std::powf(gray, gamma);
const PDFColorComponent grayWithGamma = std::pow(gray, gamma);
Q_ASSERT(outputIt != output.cend());
*outputIt++ = grayWithGamma;
}
@ -1271,7 +1271,7 @@ QColor PDFCalGrayColorSpace::getColor(const PDFColor& color, const PDFCMS* cms,
Q_UNUSED(isRange01);
const PDFColorComponent A = clip01(color[0]);
const PDFColorComponent xyzColor = std::powf(A, m_gamma);
const PDFColorComponent xyzColor = std::pow(A, m_gamma);
PDFColor3 xyzColorCMS = { xyzColor, xyzColor, xyzColor };
QColor cmsColor = cms->getColorFromXYZ(m_whitePoint, xyzColorCMS, intent, reporter);
@ -1297,7 +1297,7 @@ void PDFCalGrayColorSpace::fillRGBBuffer(const std::vector<float>& colors, unsig
auto it = xyzColors.begin();
for (float gray : colors)
{
const PDFColorComponent xyzColor = std::powf(clip01(gray), m_gamma);
const PDFColorComponent xyzColor = std::pow(clip01(gray), m_gamma);
*it++ = xyzColor;
*it++ = xyzColor;
*it++ = xyzColor;

View File

@ -533,7 +533,7 @@ protected:
PDFColor3 result = { };
for (size_t i = 0; i < color.size(); ++i)
{
result[i] = std::powf(color[i], factors[i]);
result[i] = std::pow(color[i], factors[i]);
}
return result;
}

View File

@ -19,6 +19,8 @@
#ifndef PDFCONSTANTS_H
#define PDFCONSTANTS_H
#include <cstddef>
namespace pdf
{

View File

@ -567,6 +567,12 @@ PDFObjectFactory& PDFObjectFactory::operator<<(int value)
return *this;
}
PDFObjectFactory& PDFObjectFactory::operator<<(PDFFormSubmitFlags flags)
{
*this << PDFInteger(flags);
return *this;
}
PDFObjectFactory& PDFObjectFactory::operator<<(WrapName wrapName)
{
addObject(PDFObject::createName(qMove(wrapName.name)));

View File

@ -125,6 +125,7 @@ public:
PDFObjectFactory& operator<<(FileAttachmentIcon icon);
PDFObjectFactory& operator<<(const PDFDestination& destination);
PDFObjectFactory& operator<<(PageRotation pageRotation);
PDFObjectFactory& operator<<(PDFFormSubmitFlags flags);
/// Treat containers - write them as array
template<typename Container, typename ValueType = decltype(*std::begin(std::declval<Container>()))>

View File

@ -21,6 +21,7 @@
#include <QTextCodec>
#include <cctype>
#include <cstring>
namespace pdf
{

View File

@ -133,7 +133,7 @@ public:
}
else
{
std::for_each(std::execution::sequenced_policy(), first, last, f);
std::for_each(std::execution::seq, first, last, f);
}
}
@ -143,7 +143,7 @@ public:
Q_UNUSED(scope);
// We always sort by single thread
std::sort(std::execution::sequenced_policy(), first, last, f);
std::sort(std::execution::seq, first, last, f);
}
/// Returns number of active threads for given scope

View File

@ -20,6 +20,7 @@
#include "pdfparser.h"
#include "pdfnametounicode.h"
#include "pdfexception.h"
#include "pdfutils.h"
#include <ft2build.h>
#include <freetype/freetype.h>
@ -33,17 +34,17 @@
#include <QPainterPath>
#include <QDataStream>
#include <QTreeWidgetItem>
#ifdef Q_OS_WIN
#if defined(Q_OS_WIN)
#include "Windows.h"
#pragma comment(lib, "Gdi32")
#pragma comment(lib, "User32")
#elif defined(Q_OS_UNIX)
#include <fontconfig/fontconfig.h>
#endif
namespace pdf
{
/// Storage class for system fonts
class PDFSystemFontInfoStorage
{
@ -59,6 +60,13 @@ public:
private:
explicit PDFSystemFontInfoStorage();
#ifdef Q_OS_UNIX
static void checkFontConfigError(FcBool result);
#endif
/// Create a postscript name for comparation purposes
static QString getFontPostscriptName(QString fontName);
#ifdef Q_OS_WIN
/// Callback for enumerating fonts
static int CALLBACK enumerateFontProc(const LOGFONT* font, const TEXTMETRIC* textMetrics, DWORD fontType, LPARAM lParam);
@ -66,9 +74,6 @@ private:
/// Retrieves font data for desired font
static QByteArray getFontData(const LOGFONT* font, HDC hdc);
/// Create a postscript name for comparation purposes
static QString getFontPostscriptName(QString fontName);
struct FontInfo
{
QString faceName;
@ -96,14 +101,9 @@ const PDFSystemFontInfoStorage* PDFSystemFontInfoStorage::getInstance()
QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor, StandardFontType standardFontType, PDFRenderErrorReporter* reporter) const
{
QByteArray result;
#ifdef Q_OS_WIN
HDC hdc = GetDC(NULL);
const BYTE lfItalic = (descriptor->italicAngle != 0.0 ? TRUE : FALSE);
QString fontName;
// Exact match font face name
QString fontName;
switch (standardFontType)
{
case StandardFontType::TimesRoman:
@ -147,6 +147,9 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor,
}
}
#if defined(Q_OS_WIN)
HDC hdc = GetDC(NULL);
const BYTE lfItalic = (descriptor->italicAngle != 0.0 ? TRUE : FALSE);
if (!fontName.isEmpty())
{
for (const FontInfo& fontInfo : m_fontInfos)
@ -251,7 +254,61 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor,
}
ReleaseDC(NULL, hdc);
#endif
#elif defined(Q_OS_UNIX)
FcPattern* p = FcPatternBuild(nullptr, FC_FAMILY, FcTypeString, fontName.constData(), nullptr);
if (!p)
{
throw PDFException(PDFTranslationContext::tr("FontConfig error building pattern for font %1").arg(fontName));
}
constexpr const std::array<std::pair<PDFReal, int>, 9> weights{
std::pair<PDFReal, int>{100, FC_WEIGHT_EXTRALIGHT},
std::pair<PDFReal, int>{200, FC_WEIGHT_LIGHT},
std::pair<PDFReal, int>{300, FC_WEIGHT_BOOK},
std::pair<PDFReal, int>{400, FC_WEIGHT_NORMAL},
std::pair<PDFReal, int>{500, FC_WEIGHT_MEDIUM},
std::pair<PDFReal, int>{600, FC_WEIGHT_DEMIBOLD},
std::pair<PDFReal, int>{700, FC_WEIGHT_BOLD},
std::pair<PDFReal, int>{800, FC_WEIGHT_EXTRABOLD},
std::pair<PDFReal, int>{900, FC_WEIGHT_EXTRABOLD}};
auto wit = std::lower_bound(weights.cbegin(), weights.cend(), descriptor->fontWeight, [](const std::pair<PDFReal, int>& data, PDFReal key) { return data.first < key; });
if (wit != weights.cend())
{
checkFontConfigError(FcPatternAddInteger(p, FC_WEIGHT, wit->second));
}
constexpr const std::array<std::pair<QFont::Stretch, int>, 9> stretches{
std::pair<QFont::Stretch, int>{QFont::UltraCondensed, FC_WIDTH_ULTRACONDENSED},
std::pair<QFont::Stretch, int>{QFont::ExtraCondensed, FC_WIDTH_EXTRACONDENSED},
std::pair<QFont::Stretch, int>{QFont::Condensed, FC_WIDTH_CONDENSED},
std::pair<QFont::Stretch, int>{QFont::SemiCondensed, FC_WIDTH_SEMICONDENSED},
std::pair<QFont::Stretch, int>{QFont::Unstretched, FC_WIDTH_NORMAL},
std::pair<QFont::Stretch, int>{QFont::SemiExpanded, FC_WIDTH_SEMIEXPANDED},
std::pair<QFont::Stretch, int>{QFont::Expanded, FC_WIDTH_EXPANDED},
std::pair<QFont::Stretch, int>{QFont::ExtraExpanded, FC_WIDTH_EXTRAEXPANDED},
std::pair<QFont::Stretch, int>{QFont::UltraExpanded, FC_WIDTH_ULTRAEXPANDED}};
auto sit = std::find_if(stretches.cbegin(), stretches.cend(), [&](const std::pair<QFont::Stretch, int>& item) { return item.first == descriptor->fontStretch; });
if (sit != stretches.cend())
{
checkFontConfigError(FcPatternAddInteger(p, FC_WIDTH, sit->second));
}
checkFontConfigError(FcConfigSubstitute(nullptr, p, FcMatchPattern));
FcDefaultSubstitute(p);
FcResult res = FcResultNoMatch;
FcPattern* match = FcFontMatch(nullptr, p, &res);
if (match)
{
FcChar8* s = nullptr;
if (FcPatternGetString(match, FC_FILE, 0, &s) == FcResultMatch)
{
QFile f(QString::fromUtf8(reinterpret_cast<char*>(s)));
f.open(QIODevice::ReadOnly);
result = f.readAll();
f.close();
}
}
if (result.isEmpty() && standardFontType == StandardFontType::Invalid)
{
@ -260,6 +317,7 @@ QByteArray PDFSystemFontInfoStorage::loadFont(const FontDescriptor* descriptor,
}
return result;
#endif
}
PDFSystemFontInfoStorage::PDFSystemFontInfoStorage()
@ -325,6 +383,17 @@ QByteArray PDFSystemFontInfoStorage::getFontData(const LOGFONT* font, HDC hdc)
return byteArray;
}
#endif
#ifdef Q_OS_UNIX
void PDFSystemFontInfoStorage::checkFontConfigError(FcBool result)
{
if (!result)
{
throw PDFException(PDFTranslationContext::tr("Fontconfig error"));
}
}
#endif
QString PDFSystemFontInfoStorage::getFontPostscriptName(QString fontName)
{
@ -336,8 +405,6 @@ QString PDFSystemFontInfoStorage::getFontPostscriptName(QString fontName)
return fontName.remove(QChar(' ')).remove(QChar('-')).remove(QChar(',')).trimmed();
}
#endif
PDFFont::PDFFont(FontDescriptor fontDescriptor) :
m_fontDescriptor(qMove(fontDescriptor))
{

View File

@ -523,7 +523,7 @@ PDFForm PDFForm::parse(const PDFDocument* document, PDFObject object)
form.m_formType = FormType::AcroForm;
form.m_needAppearances = loader.readBooleanFromDictionary(formDictionary, "NeedAppearances", false);
form.m_signatureFlags = static_cast<SignatureFlags>(loader.readIntegerFromDictionary(formDictionary, "SigFlags", 0));
form.m_signatureFlags = static_cast<SignatureFlags>(static_cast<int32_t>(loader.readIntegerFromDictionary(formDictionary, "SigFlags", 0)));
form.m_calculationOrder = loader.readReferenceArrayFromDictionary(formDictionary, "CO");
form.m_resources = formDictionary->get("DR");
form.m_defaultAppearance = loader.readOptionalStringFromDictionary(formDictionary, "DA");
@ -761,7 +761,7 @@ PDFFormFieldPointer PDFFormField::parse(const PDFObjectStorage* storage, PDFObje
formField->m_fieldNames[Partial] = loader.readTextStringFromDictionary(fieldDictionary, "T", QString());
formField->m_fieldNames[UserCaption] = loader.readTextStringFromDictionary(fieldDictionary, "TU", QString());
formField->m_fieldNames[Export] = loader.readTextStringFromDictionary(fieldDictionary, "TM", QString());
formField->m_fieldFlags = fieldDictionary->hasKey("Ff") ? static_cast<FieldFlags>(loader.readIntegerFromDictionary(fieldDictionary, "Ff", 0)) : parentFlags;
formField->m_fieldFlags = fieldDictionary->hasKey("Ff") ? static_cast<FieldFlags>(static_cast<int32_t>(loader.readIntegerFromDictionary(fieldDictionary, "Ff", 0))) : parentFlags;
formField->m_value = fieldDictionary->hasKey("V") ? fieldDictionary->get("V") : parentV;
formField->m_defaultValue = fieldDictionary->hasKey("DV") ? fieldDictionary->get("DV") : parentDV;
formField->m_additionalActions = PDFAnnotationAdditionalActions::parse(storage, fieldDictionary->get("AA"), fieldDictionary->get("A"));

View File

@ -248,7 +248,7 @@ class PDF4QTLIBSHARED_EXPORT PDFThumbnailsItemModel : public QAbstractItemModel
Q_OBJECT
public:
explicit inline PDFThumbnailsItemModel(const PDFDrawWidgetProxy* proxy, QObject* parent);
explicit PDFThumbnailsItemModel(const PDFDrawWidgetProxy* proxy, QObject* parent);
bool isEmpty() const;

View File

@ -28,6 +28,7 @@
#include <variant>
#include <array>
#include <initializer_list>
#include <cstring>
namespace pdf
{

View File

@ -812,18 +812,6 @@ private:
template<typename T>
T readOperand(size_t index) const;
template<>
PDFReal readOperand<PDFReal>(size_t index) const;
template<>
PDFInteger readOperand<PDFInteger>(size_t index) const;
template<>
PDFOperandName readOperand<PDFOperandName>(size_t index) const;
template<>
PDFOperandString readOperand<PDFOperandString>(size_t index) const;
template<size_t index, typename T>
inline T readOperand() const { return readOperand<T>(index); }
@ -1093,6 +1081,18 @@ private:
PDFInteger m_structuralParentKey;
};
template<>
PDFReal PDFPageContentProcessor::readOperand<PDFReal>(size_t index) const;
template<>
PDFInteger PDFPageContentProcessor::readOperand<PDFInteger>(size_t index) const;
template<>
PDFPageContentProcessor::PDFOperandName PDFPageContentProcessor::readOperand<PDFPageContentProcessor::PDFOperandName>(size_t index) const;
template<>
PDFPageContentProcessor::PDFOperandString PDFPageContentProcessor::readOperand<PDFPageContentProcessor::PDFOperandString>(size_t index) const;
} // namespace pdf
#endif // PDFPAGECONTENTPROCESSOR_H

View File

@ -356,7 +356,7 @@ class PDF4QTLIBSHARED_EXPORT PDFPrecompiledPageGenerator : public PDFPainterBase
using BaseClass = PDFPainterBase;
public:
explicit inline PDFPrecompiledPageGenerator(PDFPrecompiledPage* precompiledPage,
explicit PDFPrecompiledPageGenerator(PDFPrecompiledPage* precompiledPage,
PDFRenderer::Features features,
const PDFPage* page,
const PDFDocument* document,

View File

@ -163,7 +163,7 @@ PDFLexicalAnalyzer::Token PDFLexicalAnalyzer::fetch()
real = -real;
}
return !treatAsReal ? Token(TokenType::Integer, integer) : Token(TokenType::Real, real);
return !treatAsReal ? Token(TokenType::Integer, QVariant(static_cast<qint64>(integer))) : Token(TokenType::Real, real);
}
case CHAR_LEFT_BRACKET:

View File

@ -24,6 +24,7 @@
#include "pdfmeshqualitysettings.h"
#include <QMatrix>
#include <QPainterPath>
#include <memory>

View File

@ -1,4 +1,4 @@
// Copyright (C) 2020-2021 Jakub Melka
// Copyright (C) 2020-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
@ -35,6 +35,9 @@
#include <QFileInfo>
#include <array>
#ifdef Q_OS_UNIX
#include <time.h>
#endif
namespace pdf
{
@ -1833,7 +1836,13 @@ QDateTime PDFPublicKeySignatureHandler::getDateTimeFromASN(const ASN1_TIME* time
tm internalTime = { };
if (ASN1_TIME_to_tm(time, &internalTime) > 0)
{
#if defined(Q_OS_WIN)
time_t localTime = _mkgmtime(&internalTime);
#elif defined(Q_OS_UNIX)
time_t localTime = timegm(&internalTime);
#else
static_assert(false, "Implement this for another OS!");
#endif
result = QDateTime::fromSecsSinceEpoch(localTime, Qt::UTC);
}
}

View File

@ -1194,7 +1194,7 @@ PDFTextFlows PDFTextFlow::createTextFlows(const PDFTextLayout& layout, FlowFlags
#if defined(Q_OS_WIN)
lineBreak = QString("\r\n");
#elif defined(Q_OS_UNIX)
linebreak = QString("\n");
lineBreak = QString("\n");
#elif defined(Q_OS_MAC)
lineBreak = QString("\r");
#else

View File

@ -622,7 +622,7 @@ struct PDFTransparencyRendererSettings
Q_DECLARE_FLAGS(Flags, Flag)
/// Flags
Flags flags = DisplayImages | DisplayText | DisplayVectorGraphics | DisplayShadings | DisplayTilingPatterns;
Flags flags = static_cast<Flags>(DisplayImages | DisplayText | DisplayVectorGraphics | DisplayShadings | DisplayTilingPatterns);
/// Active color mask
uint32_t activeColorMask = PDFPixelFormat::getAllColorsMask();

View File

@ -243,7 +243,11 @@ std::vector<PDFDependentLibraryInfo> PDFDependentLibraryInfo::getLibraryInfo()
libjpegInfo.library = tr("libjpeg");
libjpegInfo.license = tr("permissive + ack.");
libjpegInfo.url = tr("https://www.ijg.org/");
#if defined(Q_OS_UNIX)
libjpegInfo.version = tr("%1").arg(JPEG_LIB_VERSION);
#else
libjpegInfo.version = tr("%1.%2").arg(JPEG_LIB_VERSION_MAJOR).arg(JPEG_LIB_VERSION_MINOR);
#endif
result.emplace_back(qMove(libjpegInfo));
// FreeType
@ -573,4 +577,18 @@ QColor PDFColorScale::map(PDFReal value) const
return QColor::fromRgbF(r, g, b);
}
QDataStream& operator<<(QDataStream& stream, long unsigned int i)
{
stream << quint64(i);
return stream;
}
QDataStream& operator>>(QDataStream& stream, long unsigned int &i)
{
quint64 value = 0;
stream >> value;
i = value;
return stream;
}
} // namespace pdf

View File

@ -735,6 +735,8 @@ QDataStream& operator>>(QDataStream& stream, std::vector<T>& vector)
return stream;
}
QDataStream& operator<<(QDataStream& stream, long unsigned int i);
template<typename T>
QDataStream& operator<<(QDataStream& stream, const std::vector<T>& vector)
{
@ -746,6 +748,8 @@ QDataStream& operator<<(QDataStream& stream, const std::vector<T>& vector)
return stream;
}
QDataStream& operator>>(QDataStream& stream, long unsigned int &i);
template<typename T, size_t Size>
QDataStream& operator>>(QDataStream& stream, std::array<T, Size>& array)
{

View File

@ -162,7 +162,7 @@ struct PDFApplyVisitorImpl<Visitor, PDFAbstractVisitor::Strategy::Parallel>
const PDFObjectStorage::PDFObjects& objects = storage.getObjects();
const PDFObject& trailerDictionary = storage.getTrailerDictionary();
std::for_each(std::execution::parallel_policy(), objects.cbegin(), objects.cend(), [visitor](const PDFObjectStorage::Entry& entry) { entry.object.accept(visitor); });
std::for_each(std::execution::par, objects.cbegin(), objects.cend(), [visitor](const PDFObjectStorage::Entry& entry) { entry.object.accept(visitor); });
trailerDictionary.accept(visitor);
}
};
@ -187,7 +187,7 @@ struct PDFApplyVisitorImpl<Visitor, PDFAbstractVisitor::Strategy::Merging>
visitor->merge(&localVisitor);
};
std::for_each(std::execution::parallel_policy(), objects.cbegin(), objects.cend(), process);
std::for_each(std::execution::par, objects.cbegin(), objects.cend(), process);
trailerDictionary.accept(visitor);
}
};
@ -201,7 +201,7 @@ struct PDFApplyVisitorImpl<Visitor, PDFAbstractVisitor::Strategy::Sequential>
const PDFObjectStorage::PDFObjects& objects = storage.getObjects();
const PDFObject& trailerDictionary = storage.getTrailerDictionary();
std::for_each(std::execution::sequenced_policy(), objects.cbegin(), objects.cend(), [](const PDFObjectStorage::Entry& entry) { entry.object.accept(visitor); });
std::for_each(std::execution::seq, objects.cbegin(), objects.cend(), [visitor](const PDFObjectStorage::Entry& entry) { entry.object.accept(visitor); });
trailerDictionary.accept(visitor);
}
};

View File

@ -0,0 +1,18 @@
Pdf4QtLibrary {
name: "Pdf4QtViewer"
files: [
"*.h",
"*.cpp",
"*.ui",
"pdf4qtviewer.qrc",
]
cpp.includePaths: ["."]
cpp.defines: ['QT_INSTALL_DIRECTORY=""']
Depends { name: "Qt"; submodules: ["printsupport", "texttospeech", "network", "xml"] }
Depends { name: "Pdf4QtLib" }
Export {
Depends { name: "cpp" }
cpp.includePaths: ["."]
Depends { name: "Pdf4QtLib" }
}
}

View File

@ -1769,9 +1769,15 @@ void PDFProgramController::updatePageLayoutActions()
void PDFProgramController::loadPlugins()
{
#if defined(Q_OS_WIN)
QDir directory(QApplication::applicationDirPath() + "/pdfplugins");
QStringList availablePlugins = directory.entryList(QStringList("*.dll"));
#elif defined(Q_OS_UNIX)
QDir directory(QApplication::applicationDirPath() + "/../pdfplugins");
QStringList availablePlugins = directory.entryList(QStringList("*.so"));
#else
static_assert(false, "Implement this for another OS!");
#endif
for (const QString& availablePlugin : availablePlugins)
{
QString pluginFileName = directory.absoluteFilePath(availablePlugin);

View File

@ -84,6 +84,9 @@ bool PDFSendMail::sendMail(QWidget* parent, QString subject, QString fileName)
return false;
}
return false;
#elif defined(Q_OS_UNIX)
// TODO
return false;
#else
static_assert(false, "Implement this for another OS!");

View File

@ -464,7 +464,7 @@ void PDFSidebarWidget::updateSignatures(const std::vector<pdf::PDFSignatureVerif
if (keyUsageFlags.testFlag(pdf::PDFCertificateInfo::KeyUsageCertSign))
{
m_certificateInfos.push_back(currentCertificateInfo);
certRoot->setData(0, Qt::UserRole, m_certificateInfos.size() - 1);
certRoot->setData(0, Qt::UserRole, QVariant(static_cast<qint64>(m_certificateInfos.size() - 1)));
}
auto addName = [certRoot, &currentCertificateInfo, &infoIcon](pdf::PDFCertificateInfo::NameEntry nameEntry, QString caption)

View File

@ -90,8 +90,10 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
m_pageZoomSpinBox(nullptr),
m_isLoadingUI(false),
m_progress(new pdf::PDFProgress(this)),
#ifdef Q_OS_WIN
m_taskbarButton(new QWinTaskbarButton(this)),
m_progressTaskbarIndicator(nullptr),
#endif
m_progressDialog(nullptr),
m_isChangingProgressStep(false)
{
@ -103,7 +105,9 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
adjustToolbar(ui->mainToolBar);
// Initialize task bar progress
#ifdef Q_OS_WIN
m_progressTaskbarIndicator = m_taskbarButton->progress();
#endif
// Initialize actions
m_actionManager->setAction(PDFActionManager::Open, ui->actionOpen);
@ -347,9 +351,11 @@ void PDFViewerMainWindow::onProgressStarted(pdf::ProgressStartupInfo info)
m_progressDialog->setCancelButton(nullptr);
}
#ifdef Q_OS_WIN
m_progressTaskbarIndicator->setRange(0, 100);
m_progressTaskbarIndicator->reset();
m_progressTaskbarIndicator->show();
#endif
m_programController->setIsBusy(true);
m_programController->updateActionsAvailability();
@ -369,7 +375,9 @@ void PDFViewerMainWindow::onProgressStep(int percentage)
m_progressDialog->setValue(percentage);
}
#ifdef Q_OS_WIN
m_progressTaskbarIndicator->setValue(percentage);
#endif
}
void PDFViewerMainWindow::onProgressFinished()
@ -380,7 +388,9 @@ void PDFViewerMainWindow::onProgressFinished()
m_progressDialog->deleteLater();
m_progressDialog = nullptr;
}
#ifdef Q_OS_WIN
m_progressTaskbarIndicator->hide();
#endif
m_programController->setIsBusy(false);
m_programController->updateActionsAvailability();
@ -507,7 +517,9 @@ void PDFViewerMainWindow::closeEvent(QCloseEvent* event)
void PDFViewerMainWindow::showEvent(QShowEvent* event)
{
Q_UNUSED(event);
#ifdef Q_OS_WIN
m_taskbarButton->setWindow(windowHandle());
#endif
}
void PDFViewerMainWindow::dragEnterEvent(QDragEnterEvent* event)

View File

@ -38,8 +38,10 @@
#include <QFuture>
#include <QTreeView>
#include <QMainWindow>
#ifdef Q_OS_WIN
#include <QWinTaskbarButton>
#include <QWinTaskbarProgress>
#endif
#include <QFutureWatcher>
#include <QProgressDialog>
@ -118,8 +120,10 @@ private:
QDoubleSpinBox* m_pageZoomSpinBox;
bool m_isLoadingUI;
pdf::PDFProgress* m_progress;
#ifdef Q_OS_WIN
QWinTaskbarButton* m_taskbarButton;
QWinTaskbarProgress* m_progressTaskbarIndicator;
#endif
QProgressDialog* m_progressDialog;
bool m_isChangingProgressStep;

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "PDFViewerMainWindowLite.h"
#include "ui_PDFViewerMainWindowLite.h"
#include "pdfviewermainwindowlite.h"
#include "ui_pdfviewermainwindowlite.h"
#include "pdfaboutdialog.h"
#include "pdfsidebarwidget.h"
@ -88,8 +88,10 @@ PDFViewerMainWindowLite::PDFViewerMainWindowLite(QWidget* parent) :
m_pageZoomSpinBox(nullptr),
m_isLoadingUI(false),
m_progress(new pdf::PDFProgress(this)),
#ifdef Q_OS_WIN
m_taskbarButton(new QWinTaskbarButton(this)),
m_progressTaskbarIndicator(nullptr),
#endif
m_progressDialog(nullptr),
m_isChangingProgressStep(false)
{
@ -101,7 +103,9 @@ PDFViewerMainWindowLite::PDFViewerMainWindowLite(QWidget* parent) :
adjustToolbar(ui->mainToolBar);
// Initialize task bar progress
#ifdef Q_OS_WIN
m_progressTaskbarIndicator = m_taskbarButton->progress();
#endif
// Initialize actions
m_actionManager->setAction(PDFActionManager::Open, ui->actionOpen);
@ -271,9 +275,11 @@ void PDFViewerMainWindowLite::onProgressStarted(pdf::ProgressStartupInfo info)
m_progressDialog->setCancelButton(nullptr);
}
#ifdef Q_OS_WIN
m_progressTaskbarIndicator->setRange(0, 100);
m_progressTaskbarIndicator->reset();
m_progressTaskbarIndicator->show();
#endif
m_programController->setIsBusy(true);
m_programController->updateActionsAvailability();
@ -293,7 +299,9 @@ void PDFViewerMainWindowLite::onProgressStep(int percentage)
m_progressDialog->setValue(percentage);
}
#ifdef Q_OS_WIN
m_progressTaskbarIndicator->setValue(percentage);
#endif
}
void PDFViewerMainWindowLite::onProgressFinished()
@ -304,7 +312,9 @@ void PDFViewerMainWindowLite::onProgressFinished()
m_progressDialog->deleteLater();
m_progressDialog = nullptr;
}
#ifdef Q_OS_WIN
m_progressTaskbarIndicator->hide();
#endif
m_programController->setIsBusy(false);
m_programController->updateActionsAvailability();
@ -410,7 +420,9 @@ void PDFViewerMainWindowLite::closeEvent(QCloseEvent* event)
void PDFViewerMainWindowLite::showEvent(QShowEvent* event)
{
Q_UNUSED(event);
#ifdef Q_OS_WIN
m_taskbarButton->setWindow(windowHandle());
#endif
}
void PDFViewerMainWindowLite::dragEnterEvent(QDragEnterEvent* event)

View File

@ -38,8 +38,10 @@
#include <QFuture>
#include <QTreeView>
#include <QMainWindow>
#ifdef Q_OS_WIN
#include <QWinTaskbarButton>
#include <QWinTaskbarProgress>
#endif
#include <QFutureWatcher>
#include <QProgressDialog>
@ -114,8 +116,10 @@ private:
QDoubleSpinBox* m_pageZoomSpinBox;
bool m_isLoadingUI;
pdf::PDFProgress* m_progress;
#ifdef Q_OS_WIN
QWinTaskbarButton* m_taskbarButton;
QWinTaskbarProgress* m_progressTaskbarIndicator;
#endif
QProgressDialog* m_progressDialog;
bool m_isChangingProgressStep;

View File

@ -0,0 +1,7 @@
Pdf4QtApp {
name: "Pdf4QtViewerLite"
files: [
"*.cpp"
]
Depends { name: "Pdf4QtViewer" }
}

View File

@ -0,0 +1,11 @@
import qbs
Pdf4QtPlugin {
name: "AudioBookPlugin"
files: [
"*.h",
"*.cpp",
"*.ui",
"icons.qrc",
]
}

View File

@ -0,0 +1,11 @@
import qbs
Pdf4QtPlugin {
name: "DimensionsPlugin"
files: [
"*.h",
"*.cpp",
"*.ui",
"icons.qrc",
]
}

View File

@ -0,0 +1,12 @@
import qbs
Pdf4QtPlugin {
name: "OutputPreviewPlugin.qbs"
files: [
"*.h",
"*.cpp",
"*.ui",
"icons.qrc",
]
cpp.includePaths: ["."]
}

View File

@ -0,0 +1,12 @@
import qbs
Pdf4QtPlugin {
name: "RedactPlugin.qbs"
files: [
"*.h",
"*.cpp",
"*.ui",
"icons.qrc",
]
cpp.includePaths: ["."]
}

View File

@ -0,0 +1,12 @@
import qbs
Pdf4QtPlugin {
name: "SoftProofingPlugin.qbs"
files: [
"*.h",
"*.cpp",
"*.ui",
"icons.qrc",
]
cpp.includePaths: ["."]
}

View File

@ -0,0 +1,8 @@
Pdf4QtApp {
name: "Pdf4QtViewerProfi"
files: [
"*.cpp",
"app-icon.ico"
]
Depends { name: "Pdf4QtViewer" }
}

View File

@ -0,0 +1,7 @@
Pdf4QtApp {
name: "PdfExampleGenerator"
files: [
"*.cpp",
"*.h",
]
}

7
PdfTool/PdfTool.qbs Normal file
View File

@ -0,0 +1,7 @@
Pdf4QtApp {
name: "PdfTool"
files: [
"*.h",
"*.cpp",
]
}

7
UnitTests/UnitTests.qbs Normal file
View File

@ -0,0 +1,7 @@
Pdf4QtApp {
name: "UnitTests"
files: [
"*.cpp",
]
Depends { name: "Qt"; submodules: ["test"] }
}

17
qbs/imports/Pdf4QtApp.qbs Normal file
View File

@ -0,0 +1,17 @@
import qbs.FileInfo
Pdf4QtProduct {
Depends { name: "cpp" }
type: "application"
cpp.rpaths: FileInfo.joinPaths(cpp.rpathOrigin, "..", "lib")
Depends { name: "Pdf4QtLib" }
Group {
fileTagsFilter: product.type
qbs.install: true
qbs.installDir: targetInstallDir
qbs.installSourceBase: buildDirectory
}
targetInstallDir: pdf4qtbuildconfig.appInstallDir
}

View File

@ -0,0 +1,16 @@
Pdf4QtProduct {
Depends { name: "cpp" }
property stringList libType: "dynamiclibrary"
type: libType
cpp.sonamePrefix: qbs.targetOS.contains("macos") ? "@rpath" : undefined
cpp.rpaths: cpp.rpathOrigin
Group {
fileTagsFilter: "dynamiclibrary"
qbs.install: install
qbs.installDir: targetInstallDir
qbs.installSourceBase: buildDirectory
}
targetInstallDir: pdf4qtbuildconfig.libInstallDir
}

View File

@ -0,0 +1,11 @@
Pdf4QtLibrary {
Depends { name: "Pdf4QtLib" }
Group {
fileTagsFilter: "dynamiclibrary"
qbs.install: install
qbs.installDir: "pdfplugins"
qbs.installSourceBase: buildDirectory
}
}

View File

@ -0,0 +1,9 @@
Product {
Depends { name: "pdf4qtbuildconfig" }
Depends { name: "cpp" }
Depends { name: "Qt.core" }
cpp.cxxLanguageVersion: "c++2a"
property bool install: true
property string targetInstallDir
}

View File

@ -0,0 +1,6 @@
Module {
property string libDirName: "lib"
property string appInstallDir: "bin"
property string libInstallDir: qbs.targetOS.contains("windows") ? "bin" : libDirName
}