Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/vcl/source/graphic/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 8 kB image not shown  

Quelle  VectorGraphicSearch.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */


#include <utility>
#include <vcl/VectorGraphicSearch.hxx>

#include <vcl/filter/PDFiumLibrary.hxx>
#include <tools/UnitConversion.hxx>

#include <sal/config.h>

namespace
{
class SearchContext
{
private:
    std::unique_ptr<vcl::pdf::PDFiumDocument>& mpPdfDocument;
    std::unique_ptr<vcl::pdf::PDFiumPage> mpPage;
    std::unique_ptr<vcl::pdf::PDFiumTextPage> mpTextPage;
    std::unique_ptr<vcl::pdf::PDFiumSearchHandle> mpSearchHandle;

public:
    sal_Int32 mnPageIndex;
    int mnCurrentIndex;
    OUString maSearchString;
    VectorGraphicSearchOptions maOptions;

    SearchContext(std::unique_ptr<vcl::pdf::PDFiumDocument>& pPdfDocument, sal_Int32 nPageIndex)
        : mpPdfDocument(pPdfDocument)
        , mnPageIndex(nPageIndex)
        , mnCurrentIndex(-1)
    {
    }

    ~SearchContext()
    {
        if (mpSearchHandle)
            mpSearchHandle.reset();
        if (mpTextPage)
            mpTextPage.reset();
        if (mpPage)
            mpPage.reset();
    }

    basegfx::B2DSize getPageSize()
    {
        basegfx::B2DSize aSize;
        if (!mpPdfDocument)
            return aSize;

        basegfx::B2DSize aPDFSize = mpPdfDocument->getPageSize(mnPageIndex);
        aSize = basegfx::B2DSize(convertPointToMm100(aPDFSize.getWidth()),
                                 convertPointToMm100(aPDFSize.getHeight()));
        return aSize;
    }

    bool initialize(OUString const& rSearchString, VectorGraphicSearchOptions const&&nbsp;rOptions)
    {
        if (!mpPdfDocument)
            return false;

        if (rSearchString == maSearchString)
            return true;

        if (mpSearchHandle)
            mpSearchHandle.reset();

        if (mpTextPage)
            mpTextPage.reset();

        if (mpPage)
            mpPage.reset();

        maSearchString = rSearchString;
        maOptions = rOptions;

        mpPage = mpPdfDocument->openPage(mnPageIndex);
        if (!mpPage)
            return false;

        mpTextPage = mpPage->getTextPage();
        if (!mpTextPage)
            return false;

        // Index where to start to search. -1 => at the end
        int nStartIndex = maOptions.meStartPosition == SearchStartPosition::End ? -1 : 0;

        if (mnCurrentIndex >= 0)
            nStartIndex = mnCurrentIndex;

        // vcl::pdf::PDFFindFlags::MatchCase, vcl::pdf::PDFFindFlags::MatchWholeWord, vcl::pdf::PDFFindFlags::Consecutive
        // vcl::pdf::PDFFindFlags::MatchCase - If not set, it will not match case by default.
        // vcl::pdf::PDFFindFlags::MatchWholeWord - If not set, it will not match the whole word by default.
        // vcl::pdf::PDFFindFlags::Consecutive - If not set, it will skip past the current match to look for the next match.
        vcl::pdf::PDFFindFlags nSearchFlags{};
        if (maOptions.mbMatchCase)
            nSearchFlags |= vcl::pdf::PDFFindFlags::MatchCase;
        if (maOptions.mbMatchWholeWord)
            nSearchFlags |= vcl::pdf::PDFFindFlags::MatchWholeWord;

        mpSearchHandle = mpTextPage->findStart(maSearchString, nSearchFlags, nStartIndex);

        return mpSearchHandle != nullptr;
    }

    bool next()
    {
        if (mpSearchHandle && mpSearchHandle->findNext())
        {
            mnCurrentIndex = index();
            return true;
        }
        return false;
    }

    bool previous()
    {
        if (mpSearchHandle && mpSearchHandle->findPrev())
        {
            mnCurrentIndex = index();
            return true;
        }
        return false;
    }

    int index()
    {
        if (mpSearchHandle)
            return mpSearchHandle->getSearchResultIndex();
        return -1;
    }

    int size()
    {
        if (mpSearchHandle)
            return mpSearchHandle->getSearchCount();
        return -1;
    }

    std::vector<basegfx::B2DRectangle> getTextRectangles()
    {
        std::vector<basegfx::B2DRectangle> aRectangles;

        if (!mpTextPage || !mpSearchHandle)
            return aRectangles;

        int nIndex = index();
        if (nIndex < 0)
            return aRectangles;

        int nSize = size();
        if (nSize <= 0)
            return aRectangles;

        double fPageHeight = getPageSize().getHeight();

        for (int nCount = 0; nCount < nSize; nCount++)
        {
            basegfx::B2DRectangle aRectangle = mpTextPage->getCharBox(nIndex + nCount, fPageHeight);
            if (!aRectangle.isEmpty())
            {
                aRectangles.push_back(aRectangle);
            }
        }

        return aRectangles;
    }
};

// end anonymous namespace

class VectorGraphicSearch::Implementation
{
public:
    std::shared_ptr<vcl::pdf::PDFium> mpPDFium;
    std::unique_ptr<vcl::pdf::PDFiumDocument> mpPdfDocument;

    std::unique_ptr<SearchContext> mpSearchContext;

    Implementation()
        : mpPDFium(vcl::pdf::PDFiumLibrary::get())
    {
    }

    ~Implementation() { mpSearchContext.reset(); }
};

VectorGraphicSearch::VectorGraphicSearch(Graphic aGraphic)
    : mpImplementation(std::make_unique<VectorGraphicSearch::Implementation>())
    , maGraphic(std::move(aGraphic))
{
}

VectorGraphicSearch::~VectorGraphicSearch() { mpImplementation.reset(); }

bool VectorGraphicSearch::search(OUString const& rSearchString,
                                 VectorGraphicSearchOptions const& rOptions)
{
    if (!mpImplementation->mpPDFium)
    {
        return false;
    }

    if (!mpImplementation->mpSearchContext)
    {
        auto pData = maGraphic.getVectorGraphicData();

        if (pData && pData->getType() == VectorGraphicDataType::Pdf)
        {
            if (searchPDF(pData))
            {
                return mpImplementation->mpSearchContext->initialize(rSearchString, rOptions);
            }
        }
        return false;
    }
    return mpImplementation->mpSearchContext->initialize(rSearchString, rOptions);
}

bool VectorGraphicSearch::searchPDF(std::shared_ptr<VectorGraphicData> const& rData)
{
    if (!mpImplementation->mpPDFium)
    {
        return false;
    }

    mpImplementation->mpPdfDocument = mpImplementation->mpPDFium->openDocument(
        rData->getBinaryDataContainer().getData(), rData->getBinaryDataContainer().getSize(),
        OString());

    if (!mpImplementation->mpPdfDocument)
    {
        //TODO: Handle failure to load.
        switch (mpImplementation->mpPDFium->getLastErrorCode())
        {
            case vcl::pdf::PDFErrorType::Success:
                break;
            case vcl::pdf::PDFErrorType::Unknown:
                break;
            case vcl::pdf::PDFErrorType::File:
                break;
            case vcl::pdf::PDFErrorType::Format:
                break;
            case vcl::pdf::PDFErrorType::Password:
                break;
            case vcl::pdf::PDFErrorType::Security:
                break;
            case vcl::pdf::PDFErrorType::Page:
                break;
            default:
                break;
        }
        return false;
    }

    sal_Int32 nPageIndex = std::max(rData->getPageIndex(), sal_Int32(0));

    mpImplementation->mpSearchContext.reset(
        new SearchContext(mpImplementation->mpPdfDocument, nPageIndex));
    return true;
}

basegfx::B2DSize VectorGraphicSearch::pageSize()
{
    basegfx::B2DSize aSize;
    if (mpImplementation->mpSearchContext)
        aSize = mpImplementation->mpSearchContext->getPageSize();
    return aSize;
}

bool VectorGraphicSearch::next()
{
    if (mpImplementation->mpSearchContext)
        return mpImplementation->mpSearchContext->next();
    return false;
}

bool VectorGraphicSearch::previous()
{
    if (mpImplementation->mpSearchContext)
        return mpImplementation->mpSearchContext->previous();
    return false;
}

int VectorGraphicSearch::index()
{
    if (mpImplementation->mpSearchContext)
        return mpImplementation->mpSearchContext->index();
    return -1;
}

std::vector<basegfx::B2DRectangle> VectorGraphicSearch::getTextRectangles()
{
    if (mpImplementation->mpSearchContext)
        return mpImplementation->mpSearchContext->getTextRectangles();

    return std::vector<basegfx::B2DRectangle>();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=95 H=99 G=96

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.