Skip to main content

pdfium_render/pdf/font/
glyph.rs

1//! Defines the [PdfFontGlyph] struct, exposing functionality related to a single
2//! font glyph in a `PdfFontGlyphs` collection.
3
4use crate::bindgen::{FPDF_FONT, FPDF_GLYPHPATH};
5use crate::bindings::PdfiumLibraryBindings;
6use crate::error::{PdfiumError, PdfiumInternalError};
7use crate::pdf::font::glyphs::PdfFontGlyphIndex;
8use crate::pdf::path::segment::PdfPathSegment;
9use crate::pdf::path::segments::{PdfPathSegmentIndex, PdfPathSegments, PdfPathSegmentsIterator};
10use crate::pdf::points::PdfPoints;
11use std::convert::TryInto;
12use std::os::raw::{c_float, c_int, c_uint};
13
14/// A single font glyph in a `PdfFontGlyphs` collection.
15pub struct PdfFontGlyph<'a> {
16    handle: FPDF_FONT,
17    index: PdfFontGlyphIndex,
18    bindings: &'a dyn PdfiumLibraryBindings,
19}
20
21impl<'a> PdfFontGlyph<'a> {
22    #[inline]
23    pub(crate) fn from_pdfium(
24        handle: FPDF_FONT,
25        index: PdfFontGlyphIndex,
26        bindings: &'a dyn PdfiumLibraryBindings,
27    ) -> Self {
28        Self {
29            handle,
30            index,
31            bindings,
32        }
33    }
34
35    /// Returns the [PdfiumLibraryBindings] used by this [PdfFontGlyph].
36    #[inline]
37    pub fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
38        self.bindings
39    }
40
41    /// Returns the width of this [PdfFontGlyph] when rendered at the given font size.
42    pub fn width_at_font_size(&self, size: PdfPoints) -> PdfPoints {
43        let mut width = 0.0;
44
45        if self.bindings.is_true(self.bindings.FPDFFont_GetGlyphWidth(
46            self.handle,
47            self.index as c_uint,
48            size.value as c_float,
49            &mut width,
50        )) {
51            PdfPoints::new(width)
52        } else {
53            PdfPoints::ZERO
54        }
55    }
56
57    /// Returns the path segments of this [PdfFontGlyph] when rendered at the given font size.
58    pub fn segments_at_font_size(&self, size: PdfPoints) -> Result<PdfFontGlyphPath<'_>, PdfiumError> {
59        let handle = self
60            .bindings()
61            .FPDFFont_GetGlyphPath(self.handle, self.index as c_uint, size.value as c_float);
62
63        if handle.is_null() {
64            Err(PdfiumError::PdfiumLibraryInternalError(PdfiumInternalError::Unknown))
65        } else {
66            Ok(PdfFontGlyphPath::from_pdfium(handle, self.bindings()))
67        }
68    }
69}
70
71/// The collection of [PdfPathSegment] objects inside a font glyph path.
72pub struct PdfFontGlyphPath<'a> {
73    handle: FPDF_GLYPHPATH,
74    bindings: &'a dyn PdfiumLibraryBindings,
75}
76
77impl<'a> PdfFontGlyphPath<'a> {
78    #[inline]
79    pub(crate) fn from_pdfium(handle: FPDF_GLYPHPATH, bindings: &'a dyn PdfiumLibraryBindings) -> Self {
80        Self { handle, bindings }
81    }
82}
83
84impl<'a> PdfPathSegments<'a> for PdfFontGlyphPath<'a> {
85    #[inline]
86    fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
87        self.bindings
88    }
89
90    #[inline]
91    fn len(&self) -> PdfPathSegmentIndex {
92        self.bindings()
93            .FPDFGlyphPath_CountGlyphSegments(self.handle)
94            .try_into()
95            .unwrap_or(0)
96    }
97
98    fn get(&self, index: PdfPathSegmentIndex) -> Result<PdfPathSegment<'a>, PdfiumError> {
99        let handle = self
100            .bindings()
101            .FPDFGlyphPath_GetGlyphPathSegment(self.handle, index as c_int);
102
103        if handle.is_null() {
104            Err(PdfiumError::PdfiumLibraryInternalError(PdfiumInternalError::Unknown))
105        } else {
106            Ok(PdfPathSegment::from_pdfium(handle, None, self.bindings()))
107        }
108    }
109
110    #[inline]
111    fn iter(&'a self) -> PdfPathSegmentsIterator<'a> {
112        PdfPathSegmentsIterator::new(self)
113    }
114}