Skip to main content

TextItem

Struct TextItem 

Source
pub struct TextItem {
Show 25 fields pub text: String, pub x: f32, pub y: f32, pub width: f32, pub height: f32, pub rotation: f32, pub advance_known: bool, pub font: String, pub font_tag: String, pub legacy_symbol_rewrite: bool, pub font_size: f32, pub page: u32, pub is_bold: bool, pub is_italic: bool, pub font_weight: Option<u16>, pub bold_source: Option<BoldSource>, pub fixed_pitch: Option<bool>, pub fill_color: Option<[u8; 3]>, pub stroke_color: Option<[u8; 3]>, pub render_mode: Option<u8>, pub is_underline: bool, pub is_strikeout: bool, pub item_type: ItemType, pub mcid: Option<i64>, pub baseline_shift: f32,
}
Expand description

A text item with position information.

x, y, width, height describe the item’s axis-aligned box in PDF points, y-up. For ordinary horizontal text the box runs from the baseline one em upward and spans the run’s advance, which is what every consumer historically assumed. A run shown with a rotated text matrix gets the bounding box of its rotated glyph run instead — tall and thin for a vertical margin stamp — and reports the angle in rotation.

§Coordinate frame

Items returned by the public position APIs (extract_text_with_positions*) are relative to the page’s visible page box — CropBox ∩ MediaBox when the page has a CropBox, else the MediaBox; a CropBox that does not overlap the MediaBox is ignored, and a page without a MediaBox is measured against US Letter (see extractor::page_box) — with the box’s lower-left corner as the origin and y growing upward. A renderer’s page image and the region APIs use the same box from its top-left corner with y growing downward, so flipping y by the box height lets items and rendered regions be intersected directly. Raw content-stream coordinates differ whenever the CropBox or MediaBox origin is not (0, 0). A page whose text is predominantly rotated has its frame turned so the text reads left-to-right (PageRotation, reported by extract_text_with_positions_and_rotations_mem) and the shift is turned the same way; /Rotate is not applied. Inside the markdown pipeline items stay in raw user space.

PositionFrame::Display (see extract_text_with_positions_mem_in_frame) reports items in the rendered page’s frame instead: the visible page box turned clockwise by the page’s inheritable /Rotate, with the turn of a rotated page undone, so the box and rotation describe the item as a renderer draws it.

Fields§

§text: String

The text content

§x: f32

Left edge of the item’s box, in PDF points from the visible page box’s left edge (see the coordinate frame note on TextItem).

§y: f32

Bottom edge of the item’s box, in PDF points from the visible page box’s bottom edge with y growing upward (see the coordinate frame note on TextItem). For horizontal text this is the baseline; descenders are not included. Image, link and form-field items carry their rect’s bottom edge.

§width: f32

Horizontal extent of the box: the advance for horizontal text, the em size for a vertical run. Zero only for a horizontal run whose font carries no width information (advance unknown).

§height: f32

Vertical extent of the box: the rendered em size for horizontal text, the advance for a vertical run.

§rotation: f32

Rotation of the run’s baseline in degrees, counter-clockwise from the page’s +x axis, normalised to [0, 360): 0 for ordinary left-to-right text, 90 for text reading bottom-to-top (a margin stamp rotated counter-clockwise), 270 for text reading top-to-bottom, 180 for upside-down text. Rotation-only matrices report exact multiples of 90; skewed matrices (deskewed OCR layers, diagonal watermarks) report fractional angles. A reflected text matrix has no rotation — its reading direction and its glyphs’ orientation differ by a half turn — and reports how its glyphs stand: 0 for the mirrored-x matrix some producers paint right-to-left text with (upright glyphs reading left), 180 for a y-flipped one. A negative Tf size turns a run around and reads as 180. 0 for items that don’t come from a text matrix (images, links, form fields, OCR). On a page whose text is predominantly rotated the extractor turns the coordinate frame so the dominant runs read as 0; upright strays then report 270 on a counter-clockwise page and 90 on a clockwise one.

§advance_known: bool

Whether the run’s advance came from font metrics. false when the font carries no width information (or, for an ActualText span, when the advance could not be recovered from the text matrix): the box’s extent along the baseline is then an estimate of half an em per painted glyph (an ActualText span counts the glyphs it covers, not its replacement text), laid in the direction the run reads, rather than a measurement. A font that reports a genuine zero advance keeps true. Items that don’t come from a text matrix (images, links, form fields, OCR) always report true.

§font: String

Font name: the /BaseFont family name (“ABCDEF+CMMI10”), which identifies the actual face (see extractor::fonts::item_font_name for the CID carve-out).

§font_tag: String

The raw font resource tag (“F2”, “T22”) the item’s show operator selected. This is exactly what font carried before 1.16.0, with the same caveats: the tag’s namespace is the enclosing page or Form XObject’s /Resources (the same tag on another page may name a different face), and an item merged from multiple runs keeps the first run’s tag. Within one page it distinguishes font programs that share a family name (two subsets of the same face keep distinct tags), which family-keyed font cannot. Empty for items that don’t originate from a content-stream show operator (images, links, form fields, OCR).

§legacy_symbol_rewrite: bool

At least one source character was changed by the legacy private-use symbol cleanup. This is decoding provenance, not an OCR verdict: the rewritten value must not be assumed to be an authoritative Unicode alias. Merged items retain evidence from every contributing run; later text splits conservatively retain their source run’s evidence.

§font_size: f32

Font size

§page: u32

Page number (1-indexed)

§is_bold: bool

Whether the font is bold: a bold word in the font name, the FontDescriptor’s ForceBold flag or the embedded program’s bold selection, or text filled and stroked to look heavier. With PositionOptions::bold_from_weight it is also true when font_weight is 600 or more.

§is_italic: bool

Whether the font is italic

§font_weight: Option<u16>

The font’s weight class on the 100..=900 scale shared by CSS font-weight and the OS/2 usWeightClass field (400 regular, 700 bold), read from the embedded font program’s OS/2 table, else the FontDescriptor’s /FontWeight, else a weight word in the font name (“Light”, “Medium”, “-Md”, “Black”, “W6”). None when none of them says, and for items that don’t come from a font (images, links, form fields, OCR). Independent of is_bold, which stays as it was: a medium face reports Some(500) and is_bold: false.

§bold_source: Option<BoldSource>

Where is_bold came from, so a caller can weigh the verdict against font_weight: the font name, the font’s flags, the weight class or the way the text was painted (see BoldSource). When more than one says bold the first of them in that order is reported. None when is_bold is false, and for items that don’t come from a font. An item merged from several runs keeps its first run’s, like font and font_weight.

§fixed_pitch: Option<bool>

Whether the font is fixed-pitch (monospaced): Some(true) when the FontDescriptor’s FixedPitch flag or the embedded program’s post table says so, else measured from the font’s width table — Some(true) when at least a dozen of its glyphs share one advance, Some(false) when two of them differ. None when the font declares nothing and no two advances differ but fewer than a dozen share one, and for items that don’t come from a font. Many producers write /Flags 4 whatever the face, so the flag is only ever read as a yes. Runs are not kept apart by it: an item merged from several runs keeps its first run’s value, like font and font_weight.

§fill_color: Option<[u8; 3]>

The fill (non-stroking) colour in force when the run was shown, as 8-bit sRGB [red, green, blue]: the colour its glyphs are filled with in the render modes that fill (0, 2, 4, 6; see render_mode). DeviceRGB is read as sRGB and DeviceGray as three equal components; DeviceCMYK is converted the way the PDF specification converts it to DeviceRGB, each of red, green and blue 1 - min(1, ink + black). An ICCBased space is read as the device space of its component count (1, 3 or 4) without applying the profile, and an Indexed space (/Indexed, or its abbreviation /I) through its palette’s base space, which may be named by another colour space resource. Components outside their range are clamped to it, and selecting a space with cs/CS sets the initial colour the PDF specification gives it: black, except a four-component ICCBased space, whose components all start at 0, which reads as white. None for any other colour space (Separation, DeviceN, Pattern, CalGray, CalRGB, Lab), for a colour operator whose operands do not fit its space, and for items that don’t come from a content-stream show operator (images, links, form fields, OCR). The colour is graphics state: q/Q save and restore it and a Form XObject starts with the colour it was invoked under. Runs are not kept apart by it: an item merged from several runs keeps its first run’s value, like font.

§stroke_color: Option<[u8; 3]>

The stroking colour in force when the run was shown, as 8-bit sRGB, read like fill_color: the colour the glyph outlines are stroked with in the render modes that stroke (1, 2, 5, 6). None when unknown or not from a show operator, as for fill_color, and an item merged from several runs keeps its first run’s value.

§render_mode: Option<u8>

The text render mode (Tr) the run was shown with, 0..=7: 0 fill, 1 stroke, 2 fill then stroke, 3 neither (invisible text, the mode OCR text layers use), 4 to 6 as 0 to 2 while also adding the glyphs to the clipping path, 7 clipping only. Runs in modes 3 and 7 put no glyphs on the page, so callers can tell visible text from invisible text by it. The mode is graphics state: it holds across text objects, q/Q save and restore it, and a Form XObject starts with the mode it was invoked under; a Tr whose operand is not an integer in 0..=7 is ignored, as renderers ignore it. Reporting the mode leaves which runs are extracted exactly as before: invisible text is neither dropped nor added because of it. None for items that don’t come from a content-stream show operator (images, links, form fields, OCR); an item merged from several runs keeps its first run’s value.

§is_underline: bool

Whether the text is underlined (drawn rule/thin rect under the baseline — PDFs have no underline font flag, so this is detected geometrically after extraction; see extractor::underline).

§is_strikeout: bool

Whether the text is struck out (drawn rule/thin rect crossing the glyphs at mid x-height). Same geometric detection as underline, different vertical window; see extractor::underline.

§item_type: ItemType

Type of item (text, image, link)

§mcid: Option<i64>

Marked Content ID from the content stream’s BDC/BMC operator. Used to link this item to the PDF structure tree for tagged PDFs.

§baseline_shift: f32

Signed baseline offset, in points, of a superscript/subscript glyph run from the baseline of the body text it is attached to. Zero for normal text. Positive = raised above the anchor’s baseline (superscript: footnote and affiliation markers, exponents), negative = lowered (subscript: chemistry indices, math). Extraction sets it when a short run is small relative to a tightly adjacent larger neighbor and sits at a real baseline offset from it; a digit-only run beside a word is instead fused into that word as Unicode super/subscript characters (“H₂O”, “word²”) and never carries a shift. y stays the glyph’s own baseline; TextItem::line_y gives the anchor’s.

Implementations§

Source§

impl TextItem

Source

pub fn line_y(&self) -> f32

Baseline of the visual line this item belongs to: the glyphs’ baseline for normal text, the anchor’s baseline for a super/subscript glyph run (baseline_shift below it). Line grouping compares this instead of y so raised and lowered markers stay on their body line and upside-down runs of different sizes share theirs.

Source

pub fn baseline_y(&self) -> f32

The y of the edge the glyphs stand on or hang from: y (the box’s bottom edge) for a run within 45° of upright, y + height (the top edge) for one within 45° of upside-down (is_upside_down(), glyph orientation included for reflected matrices). Exact for level runs; for oblique ones the baseline is not horizontal and the edge is only an approximation of it, which is what line grouping then compares. Vertical runs return the box bottom y.

Source

pub fn is_script(&self) -> bool

true for a glyph run flagged as a super- or subscript of a larger neighbor (non-zero baseline_shift).

Source§

impl TextItem

Source

pub fn is_horizontal(&self) -> bool

Whether the run reads along the page’s x axis rather than its y axis: rotation closer to 0/180 than to 90/270, the same 45° split the extractor uses to vote on page rotation. Layout heuristics that reason about baselines, word gaps, and column spans walk the x axis and assume this; rotated runs (margin stamps, chart axis titles, rotated table headers) return false and are kept out of them. Oblique runs (diagonal watermarks, deskewed OCR lines) are deliberately still true: the x-axis heuristics are the closest fit the pipeline has for them, exactly as before rotation existed, and callers needing the precise angle read rotation directly.

Source

pub fn is_upright(&self) -> bool

Whether the run reads along +x: rotation within 45° of 0. The x-ascending walks (item merging, line assembly) assume this; an upside-down run is is_horizontal() but reads towards -x.

Source

pub fn is_upside_down(&self) -> bool

Whether the run reads towards -x: rotation within 45° of 180.

Trait Implementations§

Source§

impl Clone for TextItem

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TextItem

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.