1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
// Take a look at the license at the top of the repository in the LICENSE file.
use glib::translate::*;
use crate::{LayoutLine, LayoutRun};
// rustdoc-stripper-ignore-next
/// The result of [`LayoutLine::x_to_index`].
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct HitPosition {
index: i32,
trailing: i32,
is_inside: bool,
}
impl HitPosition {
// rustdoc-stripper-ignore-next
/// The UTF-8 byte offset of the grapheme closest to the position.
///
/// This position is relative to the start of the [`Layout`]'s text.
///
/// [`Layout`]: crate::Layout
pub fn index(self) -> i32 {
self.index
}
// rustdoc-stripper-ignore-next
/// The codepoint within the grapheme of the position.
///
/// This will always be either `0`, or the number of `char`s (*not bytes!*)
/// in the grapheme. This represents whether the user clicked near the start
/// of the grapheme or near the end; this is important for things like
/// resolving cursor positions.
pub fn trailing(self) -> i32 {
self.trailing
}
// rustdoc-stripper-ignore-next
/// Whether or not the position was within the bounds of the line.
///
/// If this is `false`, then `index` and `trailing` will always resolve
/// to either the very first or the very last position in the line; this
/// behaviour is dependent on the line's resolved writing direction.
pub fn is_inside(self) -> bool {
self.is_inside
}
}
impl LayoutLine {
// rustdoc-stripper-ignore-next
/// The byte index of the start of this line into the text used to create
/// the source [`Layout`].
///
/// [`Layout`]: crate::Layout
#[cfg(not(any(feature = "v1_50", feature = "dox")))]
#[cfg_attr(feature = "dox", doc(not(cfg(feature = "v1_50"))))]
pub fn start_index(&self) -> i32 {
unsafe { (*self.as_ptr()).start_index }
}
// rustdoc-stripper-ignore-next
/// The length of this line's text, in bytes.
#[cfg(not(any(feature = "v1_50", feature = "dox")))]
#[cfg_attr(feature = "dox", doc(not(cfg(feature = "v1_50"))))]
pub fn length(&self) -> i32 {
unsafe { (*self.as_ptr()).length }
}
#[doc(alias = "pango_layout_line_runs")]
pub fn runs(&self) -> Vec<LayoutRun> {
unsafe { FromGlibPtrContainer::from_glib_none((*self.as_ptr()).runs) }
}
/// Converts from x offset to the byte index of the corresponding character
/// within the text of the layout.
///
/// If @x_pos is outside the line, @index_ and @trailing will point to the very
/// first or very last position in the line. This determination is based on the
/// resolved direction of the paragraph; for example, if the resolved direction
/// is right-to-left, then an X position to the right of the line (after it)
/// results in 0 being stored in @index_ and @trailing. An X position to the
/// left of the line results in @index_ pointing to the (logical) last grapheme
/// in the line and @trailing being set to the number of characters in that
/// grapheme. The reverse is true for a left-to-right line.
/// ## `x_pos`
/// the X offset (in Pango units) from the left edge of the line.
///
/// # Returns
///
/// [`false`] if @x_pos was outside the line, [`true`] if inside
///
/// ## `index_`
/// location to store calculated byte index for the grapheme
/// in which the user clicked
///
/// ## `trailing`
/// location to store an integer indicating where in the
/// grapheme the user clicked. It will either be zero, or the number of
/// characters in the grapheme. 0 represents the leading edge of the grapheme.
#[doc(alias = "pango_layout_line_x_to_index")]
pub fn x_to_index(&self, x_pos: i32) -> HitPosition {
let mut index = 0;
let mut trailing = 0;
let is_inside = unsafe {
from_glib(ffi::pango_layout_line_x_to_index(
self.to_glib_none().0,
x_pos,
&mut index,
&mut trailing,
))
};
HitPosition {
index,
trailing,
is_inside,
}
}
}