From b8025d002c042b4644dcabe0df1dec0f1d0a17f4 Mon Sep 17 00:00:00 2001 From: wangrong Date: Sat, 24 May 2025 14:40:16 +0800 Subject: [PATCH] feat: Added log to track internal state and operations. Introduces extensive debug logging across various classes related to PDF annotations, documents, and pages. This includes logging for setting and getting properties, loading files, and managing annotations, enhancing traceability and debugging capabilities. Log: Added log to track internal state and operations. --- src/dpdfannot.cpp | 39 ++++++++++++++++--- src/dpdfdoc.cpp | 89 +++++++++++++++++++++++++++++++++---------- src/dpdfglobal.cpp | 13 +++++++ src/dpdfpage.cpp | 95 +++++++++++++++++++++++++++++++++++++++------- 4 files changed, 199 insertions(+), 37 deletions(-) diff --git a/src/dpdfannot.cpp b/src/dpdfannot.cpp index a517c61..082ec5d 100644 --- a/src/dpdfannot.cpp +++ b/src/dpdfannot.cpp @@ -3,19 +3,23 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "dpdfannot.h" +#include DPdfAnnot::AnnotType DPdfAnnot::type() { + qDebug() << "Getting annotation type:" << m_type; return m_type; } void DPdfAnnot::setText(QString text) { + qDebug() << "Setting annotation text:" << text; m_text = text; } QString DPdfAnnot::text() { + qDebug() << "Getting annotation text:" << m_text; return m_text; } @@ -31,6 +35,7 @@ bool DPdfTextAnnot::pointIn(QPointF pos) QList DPdfTextAnnot::boundaries() { + qDebug() << "Getting text annotation boundaries"; QList list; list << m_rect; @@ -40,6 +45,7 @@ QList DPdfTextAnnot::boundaries() void DPdfTextAnnot::setRectF(const QRectF &rectf) { + qDebug() << "Setting text annotation rectangle:" << rectf; m_rect = rectf; } @@ -55,11 +61,13 @@ bool DPdfSquareAnnot::pointIn(QPointF pos) QList DPdfSquareAnnot::boundaries() { + qDebug() << "Getting square annotation boundaries"; return QList() << m_rect; } void DPdfSquareAnnot::setRectF(const QRectF &rectf) { + qDebug() << "Setting square annotation rectangle:" << rectf; m_rect = rectf; } @@ -80,21 +88,25 @@ bool DPdfHightLightAnnot::pointIn(QPointF pos) void DPdfHightLightAnnot::setColor(QColor color) { + qDebug() << "Setting highlight annotation color:" << color; m_color = color; } QColor DPdfHightLightAnnot::color() { + qDebug() << "Getting highlight annotation color:" << m_color; return m_color; } void DPdfHightLightAnnot::setBoundaries(QList rectList) { + qDebug() << "Setting highlight annotation boundaries, count:" << rectList.size(); m_rectList = rectList; } QList DPdfHightLightAnnot::boundaries() { + qDebug() << "Getting highlight annotation boundaries"; return m_rectList; } @@ -134,6 +146,7 @@ bool DPdfLinkAnnot::pointIn(QPointF pos) QList DPdfLinkAnnot::boundaries() { + qDebug() << "Getting link annotation boundaries"; QList list; list << m_rect; @@ -143,34 +156,42 @@ QList DPdfLinkAnnot::boundaries() void DPdfLinkAnnot::setRectF(const QRectF &rect) { + qDebug() << "Setting link annotation rectangle:" << rect; m_rect = rect; } void DPdfLinkAnnot::setUrl(QString url) { + qDebug() << "Setting link annotation URL:" << url; m_url = url; - if (!m_url.contains("http://") && !m_url.contains("https://")) + if (!m_url.contains("http://") && !m_url.contains("https://")) { + qDebug() << "Prepending http:// to URL"; m_url.prepend("http://"); + } } QString DPdfLinkAnnot::url() const { + qDebug() << "Getting link annotation URL:" << m_url; return m_url; } void DPdfLinkAnnot::setFilePath(QString filePath) { + qDebug() << "Setting link annotation file path:" << filePath; m_filePath = filePath; } QString DPdfLinkAnnot::filePath() const { + qDebug() << "Getting link annotation file path:" << m_filePath; return m_filePath; } void DPdfLinkAnnot::setPage(int index, float left, float top) { + qDebug() << "Setting link annotation page properties - index:" << index << "left:" << left << "top:" << top; m_index = index; m_left = left; m_top = top; @@ -178,6 +199,7 @@ void DPdfLinkAnnot::setPage(int index, float left, float top) int DPdfLinkAnnot::pageIndex() const { + qDebug() << "Getting link annotation page index:" << m_index; return m_index; } @@ -188,20 +210,21 @@ QPointF DPdfLinkAnnot::offset() const void DPdfLinkAnnot::setLinkType(int type) { + qDebug() << "Setting link annotation type:" << type; m_linkType = type; } int DPdfLinkAnnot::linkType() const { + qDebug() << "Getting link annotation type:" << m_linkType; return m_linkType; } bool DPdfLinkAnnot::isValid() const { - if (Goto == m_linkType) - return m_index != -1; - - return true; + bool valid = (Goto == m_linkType) ? (m_index != -1) : true; + qDebug() << "Checking link annotation validity:" << valid; + return valid; } DPdfCIRCLEAnnot::DPdfCIRCLEAnnot() @@ -216,16 +239,19 @@ bool DPdfCIRCLEAnnot::pointIn(QPointF pos) QList DPdfCIRCLEAnnot::boundaries() { + qDebug() << "Getting circle annotation boundaries"; return QList() << m_rect; } void DPdfCIRCLEAnnot::setRectF(const QRectF &rectf) { + qDebug() << "Setting circle annotation rectangle:" << rectf; m_rect = rectf; } void DPdfCIRCLEAnnot::setBoundaries(QList rectList) { + qDebug() << "Setting circle annotation boundaries, count:" << rectList.size(); m_rectList = rectList; } @@ -241,11 +267,13 @@ bool DPdfUnderlineAnnot::pointIn(QPointF pos) QList DPdfUnderlineAnnot::boundaries() { + qDebug() << "Getting underline annotation boundaries"; return QList() << m_rect; } void DPdfUnderlineAnnot::setRectF(const QRectF &rectf) { + qDebug() << "Setting underline annotation rectangle:" << rectf; m_rect = rectf; } @@ -262,5 +290,6 @@ bool DPdfWidgetAnnot::pointIn(QPointF pos) QList DPdfWidgetAnnot::boundaries() { + qDebug() << "Getting widget annotation boundaries"; return QList(); } diff --git a/src/dpdfdoc.cpp b/src/dpdfdoc.cpp index fb2a46f..c5d68fb 100755 --- a/src/dpdfdoc.cpp +++ b/src/dpdfdoc.cpp @@ -24,6 +24,7 @@ #include #include #include +#include /** * @brief The PDFIumLoader class for FPDF_FILEACCESS @@ -70,7 +71,9 @@ static bool isRemoteFile(const QString &filePath) QString fsType = storage.fileSystemType().toLower(); - return (fsType == "cifs" || fsType == "smb" || fsType == "smbfs"); + bool isRemote = (fsType == "cifs" || fsType == "smb" || fsType == "smbfs"); + qDebug() << filePath << "isRemote:" << isRemote; + return isRemote; } DPdfDoc::Status parseError(int error) @@ -94,6 +97,7 @@ DPdfDoc::Status parseError(int error) err_code = DPdfDoc::HANDLER_ERROR; break; } + qDebug() << "Parsed error code:" << error << "to status:" << err_code; return err_code; } @@ -128,11 +132,14 @@ DPdfDocPrivate::DPdfDocPrivate() DPdfDocPrivate::~DPdfDocPrivate() { DPdfMutexLocker locker("DPdfDocPrivate::~DPdfDocPrivate()"); + qDebug() << "Cleaning up DPdfDocPrivate resources"; qDeleteAll(m_pages); - if (nullptr != m_docHandler) + if (nullptr != m_docHandler) { + qDebug() << "Closing PDF document handler"; FPDF_CloseDocument(reinterpret_cast(m_docHandler)); + } if (!m_tempFilePath.isEmpty() && QFile::exists(m_tempFilePath)) { QFile::remove(m_tempFilePath); @@ -142,12 +149,14 @@ DPdfDocPrivate::~DPdfDocPrivate() DPdfDoc::Status DPdfDocPrivate::loadFile(const QString &filePath, const QString &password) { + qDebug() << "Loading PDF file:" << filePath; m_filePath = filePath; m_tempFilePath.clear(); m_isRemoteFile = false; m_pages.clear(); if (!QFile::exists(m_filePath)) { + qWarning() << "File not found:" << m_filePath; m_status = DPdfDoc::FILE_NOT_FOUND_ERROR; return m_status; } @@ -203,6 +212,7 @@ DPdfDoc::Status DPdfDocPrivate::loadFile(const QString &filePath, const QString if (m_docHandler) { m_pageCount = FPDF_GetPageCount(reinterpret_cast(m_docHandler)); + qDebug() << "Document loaded successfully with" << m_pageCount << "pages"; m_pages.fill(nullptr, m_pageCount); } @@ -223,23 +233,30 @@ DPdfDoc::~DPdfDoc() bool DPdfDoc::isValid() const { - return d_func()->m_docHandler != nullptr; + bool valid = d_func()->m_docHandler != nullptr; + qDebug() << "Checking document validity:" << valid; + return valid; } bool DPdfDoc::isEncrypted() const { - if (!isValid()) + if (!isValid()) { + qDebug() << "Document is not valid, cannot check encryption"; return false; + } DPdfMutexLocker locker("DPdfDoc::isEncrypted()"); - - return FPDF_GetDocPermissions(reinterpret_cast(d_func()->m_docHandler)) != 0xFFFFFFFF; + bool encrypted = FPDF_GetDocPermissions(reinterpret_cast(d_func()->m_docHandler)) != 0xFFFFFFFF; + qDebug() << "Document encryption status:" << encrypted; + return encrypted; } DPdfDoc::Status DPdfDoc::tryLoadFile(const QString &filename, const QString &password) { + qDebug() << "Attempting to load file:" << filename; Status status = NOT_LOADED; if (!QFile::exists(filename)) { + qWarning() << "File not found:" << filename; status = FILE_NOT_FOUND_ERROR; return status; } @@ -251,8 +268,10 @@ DPdfDoc::Status DPdfDoc::tryLoadFile(const QString &filename, const QString &pas DPdfDocHandler *docHandler = static_cast(ptr); status = docHandler ? SUCCESS : parseError(static_cast(FPDF_GetLastError())); + qDebug() << "File load attempt status:" << status; if (docHandler) { + qDebug() << "Closing test document handler"; FPDF_CloseDocument(reinterpret_cast(docHandler)); } @@ -261,6 +280,7 @@ DPdfDoc::Status DPdfDoc::tryLoadFile(const QString &filename, const QString &pas bool DPdfDoc::isLinearized(const QString &fileName) { + qDebug() << "Checking if file is linearized:" << fileName; QFile file(fileName); if (!file.open(QFile::ReadOnly)) { qInfo() << "file open failed when isLinearized" << fileName; @@ -287,7 +307,9 @@ bool DPdfDoc::isLinearized(const QString &fileName) FPDF_AVAIL m_PdfAvail; m_PdfAvail = FPDFAvail_Create(&m_fileAvail, &m_fileAccess); - return FPDFAvail_IsLinearized(m_PdfAvail) > 0; + bool linearized = FPDFAvail_IsLinearized(m_PdfAvail) > 0; + qDebug() << "File linearization status:" << linearized; + return linearized; } static QFile saveWriter; @@ -300,11 +322,13 @@ int writeFile(struct FPDF_FILEWRITE_* pThis, const void *pData, unsigned long si bool DPdfDoc::saveRemoteFile() { + qDebug() << "Saving remote file:" << d_func()->m_filePath; return saveAs(d_func()->m_filePath); } bool DPdfDoc::saveLocalFile() { + qDebug() << "Saving local file:" << d_func()->m_filePath; FPDF_FILEWRITE write; write.WriteBlock = writeFile; @@ -314,9 +338,12 @@ bool DPdfDoc::saveLocalFile() QString tempFilePath = tempDir.path() + "/" + QUuid::createUuid().toString(); saveWriter.setFileName(tempFilePath); + qDebug() << "Using temporary file for save:" << tempFilePath; - if (!saveWriter.open(QIODevice::WriteOnly)) + if (!saveWriter.open(QIODevice::WriteOnly)) { + qWarning() << "Failed to open temporary file for writing"; return false; + } DPdfMutexLocker locker("DPdfDoc::save"); bool result = FPDF_SaveAsCopy(reinterpret_cast(d_func()->m_docHandler), &write, FPDF_NO_INCREMENTAL); @@ -325,9 +352,10 @@ bool DPdfDoc::saveLocalFile() saveWriter.close(); QFile tempFile(tempFilePath); - - if (!tempFile.open(QIODevice::ReadOnly)) + if (!tempFile.open(QIODevice::ReadOnly)) { + qWarning() << "Failed to open temporary file for reading"; return false; + } QByteArray array = tempFile.readAll(); @@ -337,21 +365,27 @@ bool DPdfDoc::saveLocalFile() file.remove(); //不remove会出现第二次导出丢失数据问题 (保存动作完成之后,如果当前文档是当初打开那个,下一次导出会出错) - if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + qWarning() << "Failed to open target file for writing"; return false; + } - if (array.size() != file.write(array)) + if (array.size() != file.write(array)) { + qWarning() << "Failed to write all data to target file"; result = false; + } file.flush();//函数将用户缓存中的内容写入内核缓冲区 fsync(file.handle());//将内核缓冲写入文件(磁盘) file.close(); + + qDebug() << "Local file save completed with status:" << result; return result; } bool DPdfDoc::save() { - + qDebug() << "Saving document, isRemoteFile:" << d_func()->m_isRemoteFile; if (d_func()->m_isRemoteFile) { return saveRemoteFile(); } else { @@ -361,21 +395,24 @@ bool DPdfDoc::save() bool DPdfDoc::saveAs(const QString &filePath) { + qDebug() << "Saving document as:" << filePath; FPDF_FILEWRITE write; write.WriteBlock = writeFile; saveWriter.setFileName(filePath); - if (!saveWriter.open(QIODevice::ReadWrite)) + if (!saveWriter.open(QIODevice::ReadWrite)) { + qWarning() << "Failed to open file for saving:" << filePath; return false; + } DPdfMutexLocker locker("DPdfDoc::saveAs"); bool result = FPDF_SaveAsCopy(reinterpret_cast(d_func()->m_docHandler), &write, FPDF_NO_INCREMENTAL); locker.unlock(); saveWriter.close(); - + qDebug() << "Save as completed with status:" << result; return result; } @@ -396,10 +433,14 @@ DPdfDoc::Status DPdfDoc::status() const DPdfPage *DPdfDoc::page(int i, qreal xRes, qreal yRes) { - if (i < 0 || i >= d_func()->m_pageCount) + qDebug() << "Getting page" << i << "with resolution" << xRes << "x" << yRes; + if (i < 0 || i >= d_func()->m_pageCount) { + qWarning() << "Invalid page index:" << i; return nullptr; + } if (!d_func()->m_pages[i]) { + qDebug() << "Creating new page object for index:" << i; d_func()->m_pages[i] = new DPdfPage(d_func()->m_docHandler, i, xRes, yRes); } @@ -436,20 +477,24 @@ void collectBookmarks(DPdfDoc::Outline &outline, const CPDF_BookmarkTree &tree, DPdfDoc::Outline DPdfDoc::outline(qreal xRes, qreal yRes) { + qDebug() << "Getting document outline with resolution" << xRes << "x" << yRes; DPdfMutexLocker locker("DPdfDoc::outline"); Outline outline; CPDF_BookmarkTree tree(reinterpret_cast(d_func()->m_docHandler)); CPDF_Bookmark cBookmark; const CPDF_Bookmark &firstRootChild = tree.GetFirstChild(&cBookmark); - if (firstRootChild.GetDict() != nullptr) + if (firstRootChild.GetDict() != nullptr) { + qDebug() << "Collecting bookmarks from document"; collectBookmarks(outline, tree, firstRootChild, xRes, yRes); + } return outline; } DPdfDoc::Properies DPdfDoc::proeries() { + qDebug() << "Getting document properties"; DPdfMutexLocker locker("DPdfDoc::proeries"); Properies properies; @@ -468,6 +513,7 @@ DPdfDoc::Properies DPdfDoc::proeries() const CPDF_Dictionary *pInfo = pDoc->GetInfo(); if (pInfo) { + qDebug() << "Reading document metadata from info dictionary"; const WideString &KeyWords = pInfo->GetUnicodeTextFor("KeyWords"); properies.insert("KeyWords", QString::fromWCharArray(KeyWords.c_str())); @@ -492,11 +538,16 @@ DPdfDoc::Properies DPdfDoc::proeries() QString DPdfDoc::label(int index) const { + qDebug() << "Getting page label for index:" << index; DPdfMutexLocker locker("DPdfDoc::label index = " + QString::number(index)); CPDF_PageLabel label(reinterpret_cast(d_func()->m_docHandler)); const Optional &str = label.GetLabel(index); - if (str.has_value()) - return QString::fromWCharArray(str.value().c_str(), static_cast(str.value().GetLength())); + if (str.has_value()) { + QString result = QString::fromWCharArray(str.value().c_str(), static_cast(str.value().GetLength())); + qDebug() << "Found page label:" << result; + return result; + } + qDebug() << "No page label found for index:" << index; return QString(); } diff --git a/src/dpdfglobal.cpp b/src/dpdfglobal.cpp index 524654a..3e28f9a 100755 --- a/src/dpdfglobal.cpp +++ b/src/dpdfglobal.cpp @@ -16,35 +16,48 @@ const static DPdfGlobal instance = DPdfGlobal(); void DPdfGlobal::init() { + qDebug() << "Initializing PDF library"; if (!initialized) { FPDF_InitLibrary(); initialized = true; + qDebug() << "PDF library initialized successfully"; + } else { + qDebug() << "PDF library already initialized"; } } void DPdfGlobal::destory() { + qDebug() << "Destroying PDF library"; if (initialized) { FPDF_DestroyLibrary(); initialized = false; + qDebug() << "PDF library destroyed successfully"; + } else { + qDebug() << "PDF library was not initialized"; } } DPdfGlobal::DPdfGlobal() { + qDebug() << "Creating DPdfGlobal instance"; init(); } DPdfGlobal::~DPdfGlobal() { + qDebug() << "Destroying DPdfGlobal instance"; destory(); } QString DPdfGlobal::textCodeType(const char *text) { + qDebug() << "Detecting text encoding"; DetectObj *obj = detect_obj_init(); detect(text, &obj); const QString &encodeind = QString(obj->encoding).toLower(); + qDebug() << "Detected encoding:" << encodeind; + detect_obj_free(&obj); return encodeind; } diff --git a/src/dpdfpage.cpp b/src/dpdfpage.cpp index 445e7bf..aa1394d 100755 --- a/src/dpdfpage.cpp +++ b/src/dpdfpage.cpp @@ -5,6 +5,7 @@ #include "dpdfdoc.h" #include "dpdfpage.h" #include "dpdfannot.h" +#include #include "public/fpdfview.h" #include "public/fpdf_text.h" @@ -134,22 +135,30 @@ DPdfPagePrivate::DPdfPagePrivate(DPdfDocHandler *handler, int index, qreal xRes, m_doc(reinterpret_cast(handler)), m_index(index), m_xRes(xRes), m_yRes(yRes) { DPdfMutexLocker locker("DPdfPagePrivate::DPdfPagePrivate index = " + QString::number(index)); + qDebug() << "Creating page private object for index:" << index << "with resolution:" << xRes << "x" << yRes; //宽高会受自身旋转值影响 单位:point 1/72inch 高分屏上要乘以系数 FPDF_GetPageSizeByIndex(m_doc, index, &m_width_pt, &m_height_pt); + qDebug() << "Page size:" << m_width_pt << "x" << m_height_pt << "points"; FPDF_PAGE page = FPDF_LoadNoParsePage(m_doc, m_index); m_isValid = (page != nullptr); + qDebug() << "Page validity:" << m_isValid; FPDF_ClosePage(page); } DPdfPagePrivate::~DPdfPagePrivate() { - if (m_textPage) + qDebug() << "Destroying page private object for index:" << m_index; + if (m_textPage) { + qDebug() << "Closing text page"; FPDFText_ClosePage(m_textPage); + } - if (m_page) + if (m_page) { + qDebug() << "Closing PDF page"; FPDF_ClosePage(m_page); + } qDeleteAll(m_dAnnots); } @@ -168,7 +177,9 @@ void DPdfPagePrivate::loadPage() { if (nullptr == m_page) { DPdfMutexLocker locker("DPdfPagePrivate::loadPage() index = " + QString::number(m_index));//即使其他文档的page在加载时,多线程调用此函数也会崩溃,非常线程不安全,此处需要加锁 + qDebug() << "Loading page:" << m_index; m_page = FPDF_LoadPage(m_doc, m_index); + qDebug() << "Page loaded:" << (m_page != nullptr); } } @@ -178,7 +189,9 @@ void DPdfPagePrivate::loadTextPage() if (nullptr == m_textPage) { DPdfMutexLocker locker("DPdfPagePrivate::loadTextPage() index = " + QString::number(m_index)); + qDebug() << "Loading text page:" << m_index; m_textPage = FPDFText_LoadPage(m_page); + qDebug() << "Text page loaded:" << (m_textPage != nullptr); } } @@ -204,23 +217,29 @@ int DPdfPagePrivate::oriRotation() bool DPdfPagePrivate::loadAnnots() { DPdfMutexLocker locker("DPdfPagePrivate::allAnnots"); + qDebug() << "Loading annotations for page:" << m_index; //使用临时page,不完全加载,防止刚开始消耗时间过长 FPDF_PAGE page = m_page; - if (page == nullptr) + if (page == nullptr) { + qDebug() << "Page loaded without parsing"; page = FPDF_LoadNoParsePage(m_doc, m_index); //不调用ParseContent,目前观察不会导致多线程崩溃 + } if (nullptr == page) { + qWarning() << "Failed to load page for annotations"; return false; } CPDF_Page *pPage = CPDFPageFromFPDFPage(page); int rotation = pPage->GetPageRotation(); + qDebug() << "Page rotation:" << rotation; //获取当前注释 int annotCount = FPDFPage_GetAnnotCount(page); + qDebug() << "Found" << annotCount << "annotations"; for (int i = 0; i < annotCount; ++i) { FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, i); @@ -426,8 +445,10 @@ bool DPdfPagePrivate::loadAnnots() FPDFPage_CloseAnnot(annot); } - if (m_page == nullptr) + if (m_page == nullptr) { + qDebug() << "Closing temporary page used for annotation loading"; FPDF_ClosePage(page); + } m_isLoadAnnots = true; @@ -436,6 +457,7 @@ bool DPdfPagePrivate::loadAnnots() bool DPdfPagePrivate::initAnnot(DPdfAnnot *dAnnot) { + qDebug() << "Initializing annotation"; if (DPdfAnnot::ALink != dAnnot->type()) return true; @@ -581,16 +603,23 @@ int DPdfPage::index() const QImage DPdfPage::image(int width, int height, QRect slice) { - if (nullptr == d_func()->m_doc) + qDebug() << "Rendering page image:" << width << "x" << height << "slice:" << slice; + if (nullptr == d_func()->m_doc) { + qWarning() << "Document is null"; return QImage(); + } - if (!slice.isValid()) + if (!slice.isValid()) { + qDebug() << "Using full page slice"; slice = QRect(0, 0, width, height); + } QImage image(slice.width(), slice.height(), QImage::Format_ARGB32); - if (image.isNull()) + if (image.isNull()) { + qWarning() << "Failed to create image buffer"; return QImage(); + } image.fill(0xFFFFFFFF); @@ -598,22 +627,26 @@ QImage DPdfPage::image(int width, int height, QRect slice) FPDF_PAGE page = FPDF_LoadPage(d_func()->m_doc, d_func()->m_index); - if (nullptr == page) + if (nullptr == page) { + qWarning() << "Failed to load page for rendering"; return QImage(); + } FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(image.width(), image.height(), FPDFBitmap_BGRA, image.scanLine(0), image.bytesPerLine()); if (nullptr != bitmap) { + qDebug() << "Rendering page to bitmap"; FPDF_RenderPageBitmap(bitmap, page, slice.x(), slice.y(), slice.width(), slice.height(), width, height, 0, FPDF_ANNOT); if (slice.width() == width && slice.height() == height) { + qDebug() << "Rendering form fields"; FPDF_FORMFILLINFO info; info.version = 1; FPDF_FORMHANDLE firmHandle = FPDFDOC_InitFormFillEnvironment(d_func()->m_doc, &info); - FPDF_FFLDraw(firmHandle, bitmap, page, 0, 0, width, height, 0, FPDF_ANNOT); + FPDF_FFLDraw(firmHandle, bitmap, page, 0, 0, width, height, 0, FPDF_ANNOT); } FPDFBitmap_Destroy(bitmap); @@ -633,6 +666,7 @@ QImage DPdfPage::image(int width, int height, QRect slice) // } // } + qDebug() << "Page image rendered successfully"; return image; } @@ -760,6 +794,7 @@ bool DPdfPage::textRect(int index, QRectF &textrect) QString DPdfPage::text(const QRectF &rect) { + qDebug() << "Getting text from rectangle:" << rect; d_func()->loadTextPage(); QRectF pointRect = d_func()->transPixelToPoint(rect); @@ -775,22 +810,26 @@ QString DPdfPage::text(const QRectF &rect) auto text = reinterpret_cast(d_func()->m_textPage)->GetTextByRect(fxRect); + qDebug() << "Text retrieved successfully"; return QString::fromWCharArray(text.c_str(), static_cast(text.GetLength())); } QString DPdfPage::text(int index, int charCount) { + qDebug() << "Getting text from index:" << index << "count:" << charCount; d_func()->loadTextPage(); DPdfMutexLocker locker("DPdfPage::text(int index, int charCount) index = " + QString::number(this->index())); auto text = reinterpret_cast(d_func()->m_textPage)->GetPageText(index, charCount); + qDebug() << "Text retrieved successfully"; return QString::fromWCharArray(text.c_str(), static_cast(text.GetLength())); } DPdfAnnot *DPdfPage::createTextAnnot(QPointF pos, QString text) { + qDebug() << "Creating text annotation at position:" << pos; d_func()->loadPage(); QPointF pointPos = d_func()->transPixelToPoint(pos); @@ -802,6 +841,7 @@ DPdfAnnot *DPdfPage::createTextAnnot(QPointF pos, QString text) FPDF_ANNOTATION annot = FPDFPage_CreateAnnot(d_func()->m_page, subType); if (!FPDFAnnot_SetStringValue(annot, "Contents", text.utf16())) { + qWarning() << "Failed to set annotation text"; FPDFPage_CloseAnnot(annot); return nullptr; } @@ -809,6 +849,7 @@ DPdfAnnot *DPdfPage::createTextAnnot(QPointF pos, QString text) FS_RECTF fs_rect = d_func()->transRect(d_func()->oriRotation(), QRectF(pointPos.x() - 10, pointPos.y() - 10, 20, 20)); if (!FPDFAnnot_SetRect(annot, &fs_rect)) { + qWarning() << "Failed to set annotation rectangle"; FPDFPage_CloseAnnot(annot); return nullptr; } @@ -835,12 +876,15 @@ DPdfAnnot *DPdfPage::createTextAnnot(QPointF pos, QString text) bool DPdfPage::updateTextAnnot(DPdfAnnot *dAnnot, QString text, QPointF pos) { + qDebug() << "Updating text annotation"; d_func()->loadPage(); DPdfTextAnnot *textAnnot = static_cast(dAnnot); - if (nullptr == textAnnot) + if (nullptr == textAnnot) { + qWarning() << "Text annotation is null"; return false; + } int index = d_func()->allAnnots().indexOf(dAnnot); @@ -849,6 +893,7 @@ bool DPdfPage::updateTextAnnot(DPdfAnnot *dAnnot, QString text, QPointF pos) FPDF_ANNOTATION annot = FPDFPage_GetAnnot(d_func()->m_page, index); if (!FPDFAnnot_SetStringValue(annot, "Contents", text.utf16())) { + qWarning() << "Failed to set annotation text"; FPDFPage_CloseAnnot(annot); return false; } @@ -862,6 +907,7 @@ bool DPdfPage::updateTextAnnot(DPdfAnnot *dAnnot, QString text, QPointF pos) FS_RECTF fs_rect = d_func()->transRect(d_func()->oriRotation(), QRectF(pointPos.x() - pointSize.width() / 2, pointPos.y() - pointSize.height() / 2, pointSize.width(), pointSize.height())); if (!FPDFAnnot_SetRect(annot, &fs_rect)) { + qWarning() << "Failed to set annotation rectangle"; FPDFPage_CloseAnnot(annot); return false; } @@ -875,11 +921,13 @@ bool DPdfPage::updateTextAnnot(DPdfAnnot *dAnnot, QString text, QPointF pos) emit annotUpdated(dAnnot); + qDebug() << "Text annotation updated successfully"; return true; } DPdfAnnot *DPdfPage::createHightLightAnnot(const QList &rects, QString text, QColor color) { + qDebug() << "Creating highlight annotation:" << rects << text << color; d_func()->loadPage(); FPDF_ANNOTATION_SUBTYPE subType = FPDF_ANNOT_HIGHLIGHT; @@ -893,6 +941,7 @@ DPdfAnnot *DPdfPage::createHightLightAnnot(const QList &rects, QString t static_cast(color.green()), static_cast(color.blue()), static_cast(color.alpha()))) { + qWarning() << "Failed to set annotation color"; FPDFPage_CloseAnnot(annot); return nullptr; } @@ -915,6 +964,7 @@ DPdfAnnot *DPdfPage::createHightLightAnnot(const QList &rects, QString t } if (!FPDFAnnot_SetStringValue(annot, "Contents", text.utf16())) { + qWarning() << "Failed to set annotation text"; FPDFPage_CloseAnnot(annot); return nullptr; } @@ -942,12 +992,15 @@ DPdfAnnot *DPdfPage::createHightLightAnnot(const QList &rects, QString t bool DPdfPage::updateHightLightAnnot(DPdfAnnot *dAnnot, QColor color, QString text) { + qDebug() << "Updating highlight annotation:" << color << text; d_func()->loadPage(); DPdfHightLightAnnot *hightLightAnnot = static_cast(dAnnot); - if (nullptr == hightLightAnnot) + if (nullptr == hightLightAnnot) { + qWarning() << "Highlight annotation is null"; return false; + } int index = d_func()->allAnnots().indexOf(dAnnot); @@ -961,6 +1014,7 @@ bool DPdfPage::updateHightLightAnnot(DPdfAnnot *dAnnot, QColor color, QString te static_cast(color.green()), static_cast(color.blue()), static_cast(color.alpha()))) { + qWarning() << "Failed to set annotation color"; FPDFPage_CloseAnnot(annot); return false; } @@ -968,6 +1022,7 @@ bool DPdfPage::updateHightLightAnnot(DPdfAnnot *dAnnot, QColor color, QString te } if (!FPDFAnnot_SetStringValue(annot, "Contents", text.utf16())) { + qWarning() << "Failed to set annotation text"; FPDFPage_CloseAnnot(annot); return false; } @@ -982,23 +1037,29 @@ bool DPdfPage::updateHightLightAnnot(DPdfAnnot *dAnnot, QColor color, QString te bool DPdfPage::removeAnnot(DPdfAnnot *dAnnot) { + qDebug() << "Removing annotation"; d_func()->loadPage(); int index = d_func()->allAnnots().indexOf(dAnnot); - if (index < 0) + if (index < 0) { + qWarning() << "Annotation not found"; return false; + } DPdfMutexLocker locker("DPdfPage::removeAnnot index = " + QString::number(this->index())); - if (!FPDFPage_RemoveAnnot(d_func()->m_page, index)) + if (!FPDFPage_RemoveAnnot(d_func()->m_page, index)) { + qWarning() << "Failed to remove annotation"; return false; + } const QList &dAnnots = d_func()->allAnnots(); //only Load Q_UNUSED(dAnnots); d_func()->m_dAnnots.removeAll(dAnnot); emit annotRemoved(dAnnot); + qDebug() << "Annotation removed successfully"; delete dAnnot; @@ -1007,6 +1068,7 @@ bool DPdfPage::removeAnnot(DPdfAnnot *dAnnot) QVector DPdfPage::search(const QString &text, bool matchCase, bool wholeWords) { + qDebug() << "Searching for text:" << text << "matchCase:" << matchCase << "wholeWords:" << wholeWords; d_func()->loadTextPage(); DPdfMutexLocker locker("DPdfPage::search index = " + QString::number(this->index())); @@ -1023,11 +1085,15 @@ QVector DPdfPage::search(const QString &text, bool matc FPDF_SCHHANDLE schandle = FPDFText_FindStart(d_func()->m_textPage, text.utf16(), flags, 0); if (schandle) { + qDebug() << "Search started successfully"; int page = d_func()->m_index; FPDF_PAGE pdfPage = FPDF_LoadPage(d_func()->m_doc, page); double pageHeight = FPDF_GetPageHeight(pdfPage); FPDF_TEXTPAGE textPage = d_func()->m_textPage; + + int matchCount = 0; while (FPDFText_FindNext(schandle)) { + matchCount++; FPDF_SCHHANDLE sh = schandle; QVector region;//一个section对应的region int idx = FPDFText_GetSchResultIndex(sh); @@ -1056,6 +1122,9 @@ QVector DPdfPage::search(const QString &text, bool matc } sections.append(section); } + qDebug() << "Found" << matchCount << "matches"; + } else { + qWarning() << "Failed to start search"; } FPDFText_FindClose(schandle);