/// <summary> /// Start a search. /// </summary> /// <param name="text_page">Handle to a text page information structure. Returned by FPDFText_LoadPage function.</param> /// <param name="findwhat">A unicode match pattern.</param> /// <param name="flags">Option flags.</param> /// <param name="start_index">Start from this character. -1 for end of the page.</param> /// <returns>A handle for the search context. FPDFText_FindClose must be called to release this handle.</returns> /// <remarks> /// FPDF_EXPORT FPDF_SCHHANDLE FPDF_CALLCONV FPDFText_FindStart(FPDF_TEXTPAGE text_page, FPDF_WIDESTRING findwhat, unsigned long flags, int start_index);. /// </remarks> public FPDF_SCHHANDLE FPDFText_FindStart(FPDF_TEXTPAGE text_page, IntPtr findwhat, FPDF_FIND_FLAGS flags, int start_index) { lock (_syncObject) { return(FPDFText_FindStartStatic(text_page, findwhat, flags, start_index)); } }
/// <summary> /// <inheritdoc/> /// </summary> public bool FindText( string text, bool caseSensitive, bool wholeWords, Func <int, bool> progress, Func <IPDFFindPage, bool> addPage, Func <IPDFFindPage, IPDFFindPosition, bool> addPosition) { if (string.IsNullOrEmpty(text)) { return(false); } if (progress == null && addPage == null && addPosition == null) { return(false); } if (_mainComponent.PageComponent is PDFPageComponent pageComponent) { pageComponent.ClearSelectionRectangles(); } FPDF_FIND_FLAGS flags = FPDF_FIND_FLAGS.FPDF_NONE; if (caseSensitive) { flags |= FPDF_FIND_FLAGS.FPDF_MATCHCASE; } if (wholeWords) { flags |= FPDF_FIND_FLAGS.FPDF_MATCHWHOLEWORD; } var somethingFound = false; var cancelFind = false; foreach (var page in _mainComponent.PageComponent.Pages) { if (cancelFind || (progress != null && !progress(page.PageIndex))) { break; } var pageHandle = _mainComponent.PDFiumBridge.FPDF_LoadPage(_mainComponent.PDFiumDocument, page.PageIndex); var textPageHandle = _mainComponent.PDFiumBridge.FPDFText_LoadPage(pageHandle); var globalText = Marshal.StringToHGlobalUni(text); var findHandle = _mainComponent.PDFiumBridge.FPDFText_FindStart(textPageHandle, globalText, flags, 0); Marshal.FreeHGlobal(globalText); PDFFindPage findPage = null; var charsOnPage = _mainComponent.PDFiumBridge.FPDFText_CountChars(textPageHandle); while (_mainComponent.PDFiumBridge.FPDFText_FindNext(findHandle)) { somethingFound = true; if (findPage == null) { findPage = new PDFFindPage(page); if (addPage != null && !addPage(findPage)) { cancelFind = true; break; } } var contextLength = 20; var foundPosition = _mainComponent.PDFiumBridge.FPDFText_GetSchResultIndex(findHandle); var foundCount = _mainComponent.PDFiumBridge.FPDFText_GetSchCount(findHandle); int startPosition = Math.Max(foundPosition - contextLength, 0); int endPosition = Math.Min(foundPosition + foundCount + contextLength, charsOnPage); var contextGlobal = Marshal.AllocHGlobal((2 * (endPosition - startPosition)) + 2); var writtenCount = _mainComponent.PDFiumBridge.FPDFText_GetText(textPageHandle, startPosition, endPosition - startPosition, contextGlobal); var context = text; if (writtenCount > 0) { context = Marshal.PtrToStringUni(contextGlobal); } context = context.Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' '); Marshal.FreeHGlobal(contextGlobal); var position = new PDFFindPosition(findPage) { Position = foundPosition, Length = foundCount, Context = context, }; if (addPosition != null && !addPosition(findPage, position)) { cancelFind = true; break; } } _mainComponent.PDFiumBridge.FPDFText_FindClose(findHandle); _mainComponent.PDFiumBridge.FPDFText_ClosePage(textPageHandle); _mainComponent.PDFiumBridge.FPDF_ClosePage(pageHandle); } return(somethingFound); }