pdfium_render/pdf/document/page/text/
segments.rs1use crate::bindgen::FS_RECTF;
5use crate::bindings::PdfiumLibraryBindings;
6use crate::error::PdfiumError;
7use crate::pdf::document::page::text::PdfPageText;
8use crate::pdf::document::page::text::segment::PdfPageTextSegment;
9use crate::pdf::rect::PdfRect;
10use std::ops::{Range, RangeInclusive};
11use std::os::raw::c_int;
12
13#[cfg(doc)]
14use {crate::pdf::document::page::PdfPage, crate::pdf::document::page::object::text::PdfPageTextObject};
15
16pub type PdfPageTextSegmentIndex = usize;
19
20pub struct PdfPageTextSegments<'a> {
26 text: &'a PdfPageText<'a>,
27 start: i32,
28 characters: i32,
29 bindings: &'a dyn PdfiumLibraryBindings,
30}
31
32impl<'a> PdfPageTextSegments<'a> {
33 #[inline]
34 pub(crate) fn new(
35 text: &'a PdfPageText<'a>,
36 start: i32,
37 characters: i32,
38 bindings: &'a dyn PdfiumLibraryBindings,
39 ) -> Self {
40 PdfPageTextSegments {
41 text,
42 start,
43 characters,
44 bindings,
45 }
46 }
47
48 #[inline]
56 pub fn len(&self) -> PdfPageTextSegmentIndex {
57 self.bindings
58 .FPDFText_CountRects(self.text.text_page_handle(), self.start, self.characters)
59 as PdfPageTextSegmentIndex
60 }
61
62 #[inline]
64 pub fn is_empty(&self) -> bool {
65 self.len() == 0
66 }
67
68 #[inline]
70 pub fn as_range(&self) -> Range<PdfPageTextSegmentIndex> {
71 0..self.len()
72 }
73
74 #[inline]
77 pub fn as_range_inclusive(&self) -> RangeInclusive<PdfPageTextSegmentIndex> {
78 if self.is_empty() { 0..=0 } else { 0..=(self.len() - 1) }
79 }
80
81 #[inline]
83 pub fn get(&self, index: PdfPageTextSegmentIndex) -> Result<PdfPageTextSegment<'_>, PdfiumError> {
84 if index >= self.len() {
85 return Err(PdfiumError::TextSegmentIndexOutOfBounds);
86 }
87
88 let mut left = 0.0;
89
90 let mut bottom = 0.0;
91
92 let mut right = 0.0;
93
94 let mut top = 0.0;
95
96 let result = self.bindings.FPDFText_GetRect(
97 self.text.text_page_handle(),
98 index as c_int,
99 &mut left,
100 &mut top,
101 &mut right,
102 &mut bottom,
103 );
104
105 PdfRect::from_pdfium_as_result(
106 result,
107 FS_RECTF {
108 left: left as f32,
109 top: top as f32,
110 right: right as f32,
111 bottom: bottom as f32,
112 },
113 self.bindings,
114 )
115 .map(|rect| PdfPageTextSegment::from_pdfium(self.text, rect))
116 }
117
118 #[inline]
125 pub fn iter(&self) -> PdfPageTextSegmentsIterator<'_> {
126 PdfPageTextSegmentsIterator::new(self)
127 }
128}
129
130pub struct PdfPageTextSegmentsIterator<'a> {
132 segments: &'a PdfPageTextSegments<'a>,
133 next_index: PdfPageTextSegmentIndex,
134}
135
136impl<'a> PdfPageTextSegmentsIterator<'a> {
137 #[inline]
138 pub(crate) fn new(segments: &'a PdfPageTextSegments<'a>) -> Self {
139 PdfPageTextSegmentsIterator {
140 segments,
141 next_index: 0,
142 }
143 }
144}
145
146impl<'a> Iterator for PdfPageTextSegmentsIterator<'a> {
147 type Item = PdfPageTextSegment<'a>;
148
149 fn next(&mut self) -> Option<Self::Item> {
150 let next = self.segments.get(self.next_index);
151
152 self.next_index += 1;
153
154 next.ok()
155 }
156}