Skip to main content

pango/auto/
layout.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5#[cfg(feature = "v1_46")]
6#[cfg_attr(docsrs, doc(cfg(feature = "v1_46")))]
7use crate::Direction;
8#[cfg(feature = "v1_50")]
9#[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
10use crate::LayoutSerializeFlags;
11use crate::{
12    Alignment, AttrList, Context, EllipsizeMode, FontDescription, LayoutIter, LayoutLine,
13    Rectangle, TabArray, WrapMode, ffi,
14};
15use glib::translate::*;
16
17glib::wrapper! {
18    ///
19    ///
20    /// The following images demonstrate the effect of alignment and
21    /// justification on the layout of text:
22    ///
23    /// | | |
24    /// | --- | --- |
25    /// | ![align=left](align-left.png) | ![align=left, justify](align-left-justify.png) |
26    /// | ![align=center](align-center.png) | ![align=center, justify](align-center-justify.png) |
27    /// | ![align=right](align-right.png) | ![align=right, justify](align-right-justify.png) |
28    ///
29    ///
30    /// It is possible, as well, to ignore the 2-D setup,
31    /// and simply treat the results of a [`Layout`][crate::Layout] as a list of lines.
32    #[doc(alias = "PangoLayout")]
33    pub struct Layout(Object<ffi::PangoLayout, ffi::PangoLayoutClass>);
34
35    match fn {
36        type_ => || ffi::pango_layout_get_type(),
37    }
38}
39
40impl Layout {
41    /// Create a new [`Layout`][crate::Layout] object with attributes initialized to
42    /// default values for a particular [`Context`][crate::Context].
43    /// ## `context`
44    /// a [`Context`][crate::Context]
45    ///
46    /// # Returns
47    ///
48    /// the newly allocated [`Layout`][crate::Layout]
49    #[doc(alias = "pango_layout_new")]
50    pub fn new(context: &Context) -> Layout {
51        unsafe { from_glib_full(ffi::pango_layout_new(context.to_glib_none().0)) }
52    }
53
54    /// Forces recomputation of any state in the [`Layout`][crate::Layout] that
55    /// might depend on the layout's context.
56    ///
57    /// This function should be called if you make changes to the context
58    /// subsequent to creating the layout.
59    #[doc(alias = "pango_layout_context_changed")]
60    pub fn context_changed(&self) {
61        unsafe {
62            ffi::pango_layout_context_changed(self.to_glib_none().0);
63        }
64    }
65
66    #[doc(alias = "pango_layout_copy")]
67    #[must_use]
68    pub fn copy(&self) -> Layout {
69        unsafe { from_glib_full(ffi::pango_layout_copy(self.to_glib_none().0)) }
70    }
71
72    /// Gets the alignment for the layout: how partial lines are
73    /// positioned within the horizontal space available.
74    ///
75    /// # Returns
76    ///
77    /// the alignment
78    #[doc(alias = "pango_layout_get_alignment")]
79    #[doc(alias = "get_alignment")]
80    pub fn alignment(&self) -> Alignment {
81        unsafe { from_glib(ffi::pango_layout_get_alignment(self.to_glib_none().0)) }
82    }
83
84    /// Gets the attribute list for the layout, if any.
85    ///
86    /// # Returns
87    ///
88    /// a [`AttrList`][crate::AttrList]
89    #[doc(alias = "pango_layout_get_attributes")]
90    #[doc(alias = "get_attributes")]
91    pub fn attributes(&self) -> Option<AttrList> {
92        unsafe { from_glib_none(ffi::pango_layout_get_attributes(self.to_glib_none().0)) }
93    }
94
95    /// Gets whether to calculate the base direction for the layout
96    /// according to its contents.
97    ///
98    /// See [`set_auto_dir()`][Self::set_auto_dir()].
99    ///
100    /// # Returns
101    ///
102    /// [`true`] if the bidirectional base direction
103    ///   is computed from the layout's contents, [`false`] otherwise
104    #[doc(alias = "pango_layout_get_auto_dir")]
105    #[doc(alias = "get_auto_dir")]
106    pub fn is_auto_dir(&self) -> bool {
107        unsafe { from_glib(ffi::pango_layout_get_auto_dir(self.to_glib_none().0)) }
108    }
109
110    /// Gets the Y position of baseline of the first line in @self.
111    ///
112    /// # Returns
113    ///
114    /// baseline of first line, from top of @self
115    #[doc(alias = "pango_layout_get_baseline")]
116    #[doc(alias = "get_baseline")]
117    pub fn baseline(&self) -> i32 {
118        unsafe { ffi::pango_layout_get_baseline(self.to_glib_none().0) }
119    }
120
121    /// /picture
122    /// ## `index_`
123    /// the byte index of the cursor
124    ///
125    /// # Returns
126    ///
127    ///
128    /// ## `strong_pos`
129    /// location to store the strong cursor position
130    ///
131    /// ## `weak_pos`
132    /// location to store the weak cursor position
133    #[cfg(feature = "v1_50")]
134    #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
135    #[doc(alias = "pango_layout_get_caret_pos")]
136    #[doc(alias = "get_caret_pos")]
137    pub fn caret_pos(&self, index_: i32) -> (Rectangle, Rectangle) {
138        unsafe {
139            let mut strong_pos = Rectangle::uninitialized();
140            let mut weak_pos = Rectangle::uninitialized();
141            ffi::pango_layout_get_caret_pos(
142                self.to_glib_none().0,
143                index_,
144                strong_pos.to_glib_none_mut().0,
145                weak_pos.to_glib_none_mut().0,
146            );
147            (strong_pos, weak_pos)
148        }
149    }
150
151    /// Returns the number of Unicode characters in the
152    /// the text of @self.
153    ///
154    /// # Returns
155    ///
156    /// the number of Unicode characters
157    ///   in the text of @self
158    #[doc(alias = "pango_layout_get_character_count")]
159    #[doc(alias = "get_character_count")]
160    pub fn character_count(&self) -> i32 {
161        unsafe { ffi::pango_layout_get_character_count(self.to_glib_none().0) }
162    }
163
164    /// Retrieves the [`Context`][crate::Context] used for this layout.
165    ///
166    /// # Returns
167    ///
168    /// the [`Context`][crate::Context] for the layout
169    #[doc(alias = "pango_layout_get_context")]
170    #[doc(alias = "get_context")]
171    pub fn context(&self) -> Context {
172        unsafe { from_glib_none(ffi::pango_layout_get_context(self.to_glib_none().0)) }
173    }
174
175    ///
176    ///
177    /// The strong cursor has a little arrow pointing to the right, the weak
178    /// cursor to the left. Typing a 'c' in this situation will insert the
179    /// character after the 'b', and typing another Hebrew character, like 'ג',
180    /// will insert it at the end.
181    /// ## `index_`
182    /// the byte index of the cursor
183    ///
184    /// # Returns
185    ///
186    ///
187    /// ## `strong_pos`
188    /// location to store the strong cursor position
189    ///
190    /// ## `weak_pos`
191    /// location to store the weak cursor position
192    #[doc(alias = "pango_layout_get_cursor_pos")]
193    #[doc(alias = "get_cursor_pos")]
194    pub fn cursor_pos(&self, index_: i32) -> (Rectangle, Rectangle) {
195        unsafe {
196            let mut strong_pos = Rectangle::uninitialized();
197            let mut weak_pos = Rectangle::uninitialized();
198            ffi::pango_layout_get_cursor_pos(
199                self.to_glib_none().0,
200                index_,
201                strong_pos.to_glib_none_mut().0,
202                weak_pos.to_glib_none_mut().0,
203            );
204            (strong_pos, weak_pos)
205        }
206    }
207
208    /// Gets the text direction at the given character position in @self.
209    /// ## `index`
210    /// the byte index of the char
211    ///
212    /// # Returns
213    ///
214    /// the text direction at @index
215    #[cfg(feature = "v1_46")]
216    #[cfg_attr(docsrs, doc(cfg(feature = "v1_46")))]
217    #[doc(alias = "pango_layout_get_direction")]
218    #[doc(alias = "get_direction")]
219    pub fn direction(&self, index: i32) -> Direction {
220        unsafe {
221            from_glib(ffi::pango_layout_get_direction(
222                self.to_glib_none().0,
223                index,
224            ))
225        }
226    }
227
228    /// Gets the type of ellipsization being performed for @self.
229    ///
230    /// See [`set_ellipsize()`][Self::set_ellipsize()].
231    ///
232    /// Use [`is_ellipsized()`][Self::is_ellipsized()] to query whether any
233    /// paragraphs were actually ellipsized.
234    ///
235    /// # Returns
236    ///
237    /// the current ellipsization mode for @self
238    #[doc(alias = "pango_layout_get_ellipsize")]
239    #[doc(alias = "get_ellipsize")]
240    pub fn ellipsize(&self) -> EllipsizeMode {
241        unsafe { from_glib(ffi::pango_layout_get_ellipsize(self.to_glib_none().0)) }
242    }
243
244    /// Computes the logical and ink extents of @self.
245    ///
246    /// Logical extents are usually what you want for positioning things. Note
247    /// that both extents may have non-zero x and y. You may want to use those
248    /// to offset where you render the layout. Not doing that is a very typical
249    /// bug that shows up as right-to-left layouts not being correctly positioned
250    /// in a layout with a set width.
251    ///
252    /// The extents are given in layout coordinates and in Pango units; layout
253    /// coordinates begin at the top left corner of the layout.
254    ///
255    /// # Returns
256    ///
257    ///
258    /// ## `ink_rect`
259    /// rectangle used to store the extents of the
260    ///   layout as drawn
261    ///
262    /// ## `logical_rect`
263    /// rectangle used to store the logical
264    ///   extents of the layout
265    #[doc(alias = "pango_layout_get_extents")]
266    #[doc(alias = "get_extents")]
267    pub fn extents(&self) -> (Rectangle, Rectangle) {
268        unsafe {
269            let mut ink_rect = Rectangle::uninitialized();
270            let mut logical_rect = Rectangle::uninitialized();
271            ffi::pango_layout_get_extents(
272                self.to_glib_none().0,
273                ink_rect.to_glib_none_mut().0,
274                logical_rect.to_glib_none_mut().0,
275            );
276            (ink_rect, logical_rect)
277        }
278    }
279
280    /// Gets the font description for the layout, if any.
281    ///
282    /// # Returns
283    ///
284    /// a pointer to the
285    ///   layout's font description, or [`None`] if the font description
286    ///   from the layout's context is inherited.
287    #[doc(alias = "pango_layout_get_font_description")]
288    #[doc(alias = "get_font_description")]
289    pub fn font_description(&self) -> Option<FontDescription> {
290        unsafe {
291            from_glib_none(ffi::pango_layout_get_font_description(
292                self.to_glib_none().0,
293            ))
294        }
295    }
296
297    /// Gets the height of layout used for ellipsization.
298    ///
299    /// See [`set_height()`][Self::set_height()] for details.
300    ///
301    /// # Returns
302    ///
303    /// the height, in Pango units if positive,
304    ///   or number of lines if negative.
305    #[doc(alias = "pango_layout_get_height")]
306    #[doc(alias = "get_height")]
307    pub fn height(&self) -> i32 {
308        unsafe { ffi::pango_layout_get_height(self.to_glib_none().0) }
309    }
310
311    /// Gets the paragraph indent width in Pango units.
312    ///
313    /// A negative value indicates a hanging indentation.
314    ///
315    /// # Returns
316    ///
317    /// the indent in Pango units
318    #[doc(alias = "pango_layout_get_indent")]
319    #[doc(alias = "get_indent")]
320    pub fn indent(&self) -> i32 {
321        unsafe { ffi::pango_layout_get_indent(self.to_glib_none().0) }
322    }
323
324    /// Returns an iterator to iterate over the visual extents of the layout.
325    ///
326    /// # Returns
327    ///
328    /// the new [`LayoutIter`][crate::LayoutIter]
329    #[doc(alias = "pango_layout_get_iter")]
330    #[doc(alias = "get_iter")]
331    pub fn iter(&self) -> LayoutIter {
332        unsafe { from_glib_full(ffi::pango_layout_get_iter(self.to_glib_none().0)) }
333    }
334
335    /// Gets whether each complete line should be stretched to fill the entire
336    /// width of the layout.
337    ///
338    /// # Returns
339    ///
340    /// the justify value
341    #[doc(alias = "pango_layout_get_justify")]
342    #[doc(alias = "get_justify")]
343    pub fn is_justify(&self) -> bool {
344        unsafe { from_glib(ffi::pango_layout_get_justify(self.to_glib_none().0)) }
345    }
346
347    /// Gets whether the last line should be stretched
348    /// to fill the entire width of the layout.
349    ///
350    /// # Returns
351    ///
352    /// the justify value
353    #[cfg(feature = "v1_50")]
354    #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
355    #[doc(alias = "pango_layout_get_justify_last_line")]
356    #[doc(alias = "get_justify_last_line")]
357    pub fn is_justify_last_line(&self) -> bool {
358        unsafe {
359            from_glib(ffi::pango_layout_get_justify_last_line(
360                self.to_glib_none().0,
361            ))
362        }
363    }
364
365    /// Retrieves a particular line from a [`Layout`][crate::Layout].
366    ///
367    /// Use the faster [`line_readonly()`][Self::line_readonly()] if you do not
368    /// plan to modify the contents of the line (glyphs, glyph widths, etc.).
369    /// ## `line`
370    /// the index of a line, which must be between 0 and
371    ///   `pango_layout_get_line_count(layout) - 1`, inclusive.
372    ///
373    /// # Returns
374    ///
375    /// the requested [`LayoutLine`][crate::LayoutLine],
376    ///   or [`None`] if the index is out of range. This layout line can be ref'ed
377    ///   and retained, but will become invalid if changes are made to the
378    ///   [`Layout`][crate::Layout].
379    #[doc(alias = "pango_layout_get_line")]
380    #[doc(alias = "get_line")]
381    pub fn line(&self, line: i32) -> Option<LayoutLine> {
382        unsafe { from_glib_none(ffi::pango_layout_get_line(self.to_glib_none().0, line)) }
383    }
384
385    /// Retrieves the count of lines for the @self.
386    ///
387    /// # Returns
388    ///
389    /// the line count
390    #[doc(alias = "pango_layout_get_line_count")]
391    #[doc(alias = "get_line_count")]
392    pub fn line_count(&self) -> i32 {
393        unsafe { ffi::pango_layout_get_line_count(self.to_glib_none().0) }
394    }
395
396    /// Retrieves a particular line from a [`Layout`][crate::Layout].
397    ///
398    /// This is a faster alternative to [`line()`][Self::line()],
399    /// but the user is not expected to modify the contents of the line
400    /// (glyphs, glyph widths, etc.).
401    /// ## `line`
402    /// the index of a line, which must be between 0 and
403    ///   `pango_layout_get_line_count(layout) - 1`, inclusive.
404    ///
405    /// # Returns
406    ///
407    /// the requested [`LayoutLine`][crate::LayoutLine],
408    ///   or [`None`] if the index is out of range. This layout line can be ref'ed
409    ///   and retained, but will become invalid if changes are made to the
410    ///   [`Layout`][crate::Layout]. No changes should be made to the line.
411    #[doc(alias = "pango_layout_get_line_readonly")]
412    #[doc(alias = "get_line_readonly")]
413    pub fn line_readonly(&self, line: i32) -> Option<LayoutLine> {
414        unsafe {
415            from_glib_none(ffi::pango_layout_get_line_readonly(
416                self.to_glib_none().0,
417                line,
418            ))
419        }
420    }
421
422    /// Gets the line spacing factor of @self.
423    ///
424    /// See [`set_line_spacing()`][Self::set_line_spacing()].
425    #[cfg(feature = "v1_44")]
426    #[cfg_attr(docsrs, doc(cfg(feature = "v1_44")))]
427    #[doc(alias = "pango_layout_get_line_spacing")]
428    #[doc(alias = "get_line_spacing")]
429    pub fn line_spacing(&self) -> f32 {
430        unsafe { ffi::pango_layout_get_line_spacing(self.to_glib_none().0) }
431    }
432
433    /// Returns the lines of the @self as a list.
434    ///
435    /// Use the faster [`lines_readonly()`][Self::lines_readonly()] if you do not
436    /// plan to modify the contents of the lines (glyphs, glyph widths, etc.).
437    ///
438    /// # Returns
439    ///
440    /// a `GSList`
441    ///   containing the lines in the layout. This points to internal data of the
442    ///   [`Layout`][crate::Layout] and must be used with care. It will become invalid on any
443    ///   change to the layout's text or properties.
444    #[doc(alias = "pango_layout_get_lines")]
445    #[doc(alias = "get_lines")]
446    pub fn lines(&self) -> Vec<LayoutLine> {
447        unsafe {
448            FromGlibPtrContainer::from_glib_none(ffi::pango_layout_get_lines(self.to_glib_none().0))
449        }
450    }
451
452    /// Returns the lines of the @self as a list.
453    ///
454    /// This is a faster alternative to [`lines()`][Self::lines()],
455    /// but the user is not expected to modify the contents of the lines
456    /// (glyphs, glyph widths, etc.).
457    ///
458    /// # Returns
459    ///
460    /// a `GSList`
461    ///   containing the lines in the layout. This points to internal data of the
462    ///   [`Layout`][crate::Layout] and must be used with care. It will become invalid on any
463    ///   change to the layout's text or properties. No changes should be made to
464    ///   the lines.
465    #[doc(alias = "pango_layout_get_lines_readonly")]
466    #[doc(alias = "get_lines_readonly")]
467    pub fn lines_readonly(&self) -> Vec<LayoutLine> {
468        unsafe {
469            FromGlibPtrContainer::from_glib_none(ffi::pango_layout_get_lines_readonly(
470                self.to_glib_none().0,
471            ))
472        }
473    }
474
475    //#[doc(alias = "pango_layout_get_log_attrs")]
476    //#[doc(alias = "get_log_attrs")]
477    //pub fn log_attrs(&self, attrs: /*Ignored*/Vec<LogAttr>) -> i32 {
478    //    unsafe { TODO: call ffi:pango_layout_get_log_attrs() }
479    //}
480
481    //#[doc(alias = "pango_layout_get_log_attrs_readonly")]
482    //#[doc(alias = "get_log_attrs_readonly")]
483    //pub fn log_attrs_readonly(&self) -> /*Ignored*/Vec<LogAttr> {
484    //    unsafe { TODO: call ffi:pango_layout_get_log_attrs_readonly() }
485    //}
486
487    /// Computes the logical and ink extents of @self in device units.
488    ///
489    /// This function just calls [`extents()`][Self::extents()] followed by
490    /// two [`extents_to_pixels()`][crate::extents_to_pixels()] calls, rounding @ink_rect and @logical_rect
491    /// such that the rounded rectangles fully contain the unrounded one (that is,
492    /// passes them as first argument to [`extents_to_pixels()`][crate::extents_to_pixels()]).
493    ///
494    /// # Returns
495    ///
496    ///
497    /// ## `ink_rect`
498    /// rectangle used to store the extents of the
499    ///   layout as drawn
500    ///
501    /// ## `logical_rect`
502    /// rectangle used to store the logical
503    ///   extents of the layout
504    #[doc(alias = "pango_layout_get_pixel_extents")]
505    #[doc(alias = "get_pixel_extents")]
506    pub fn pixel_extents(&self) -> (Rectangle, Rectangle) {
507        unsafe {
508            let mut ink_rect = Rectangle::uninitialized();
509            let mut logical_rect = Rectangle::uninitialized();
510            ffi::pango_layout_get_pixel_extents(
511                self.to_glib_none().0,
512                ink_rect.to_glib_none_mut().0,
513                logical_rect.to_glib_none_mut().0,
514            );
515            (ink_rect, logical_rect)
516        }
517    }
518
519    /// Determines the logical width and height of a [`Layout`][crate::Layout] in device
520    /// units.
521    ///
522    /// [`size()`][Self::size()] returns the width and height
523    /// scaled by `PANGO_SCALE`. This is simply a convenience function
524    /// around [`pixel_extents()`][Self::pixel_extents()].
525    ///
526    /// # Returns
527    ///
528    ///
529    /// ## `width`
530    /// location to store the logical width
531    ///
532    /// ## `height`
533    /// location to store the logical height
534    #[doc(alias = "pango_layout_get_pixel_size")]
535    #[doc(alias = "get_pixel_size")]
536    pub fn pixel_size(&self) -> (i32, i32) {
537        unsafe {
538            let mut width = std::mem::MaybeUninit::uninit();
539            let mut height = std::mem::MaybeUninit::uninit();
540            ffi::pango_layout_get_pixel_size(
541                self.to_glib_none().0,
542                width.as_mut_ptr(),
543                height.as_mut_ptr(),
544            );
545            (width.assume_init(), height.assume_init())
546        }
547    }
548
549    /// Returns the current serial number of @self.
550    ///
551    /// The serial number is initialized to an small number larger than zero
552    /// when a new layout is created and is increased whenever the layout is
553    /// changed using any of the setter functions, or the [`Context`][crate::Context] it
554    /// uses has changed. The serial may wrap, but will never have the value 0.
555    /// Since it can wrap, never compare it with "less than", always use "not equals".
556    ///
557    /// This can be used to automatically detect changes to a [`Layout`][crate::Layout],
558    /// and is useful for example to decide whether a layout needs redrawing.
559    /// To force the serial to be increased, use
560    /// [`context_changed()`][Self::context_changed()].
561    ///
562    /// # Returns
563    ///
564    /// The current serial number of @self.
565    #[doc(alias = "pango_layout_get_serial")]
566    #[doc(alias = "get_serial")]
567    pub fn serial(&self) -> u32 {
568        unsafe { ffi::pango_layout_get_serial(self.to_glib_none().0) }
569    }
570
571    /// Obtains whether @self is in single paragraph mode.
572    ///
573    /// See [`set_single_paragraph_mode()`][Self::set_single_paragraph_mode()].
574    ///
575    /// # Returns
576    ///
577    /// [`true`] if the layout does not break paragraphs
578    ///   at paragraph separator characters, [`false`] otherwise
579    #[doc(alias = "pango_layout_get_single_paragraph_mode")]
580    #[doc(alias = "get_single_paragraph_mode")]
581    pub fn is_single_paragraph_mode(&self) -> bool {
582        unsafe {
583            from_glib(ffi::pango_layout_get_single_paragraph_mode(
584                self.to_glib_none().0,
585            ))
586        }
587    }
588
589    /// Determines the logical width and height of a [`Layout`][crate::Layout] in Pango
590    /// units.
591    ///
592    /// This is simply a convenience function around [`extents()`][Self::extents()].
593    ///
594    /// # Returns
595    ///
596    ///
597    /// ## `width`
598    /// location to store the logical width
599    ///
600    /// ## `height`
601    /// location to store the logical height
602    #[doc(alias = "pango_layout_get_size")]
603    #[doc(alias = "get_size")]
604    pub fn size(&self) -> (i32, i32) {
605        unsafe {
606            let mut width = std::mem::MaybeUninit::uninit();
607            let mut height = std::mem::MaybeUninit::uninit();
608            ffi::pango_layout_get_size(
609                self.to_glib_none().0,
610                width.as_mut_ptr(),
611                height.as_mut_ptr(),
612            );
613            (width.assume_init(), height.assume_init())
614        }
615    }
616
617    /// Gets the amount of spacing between the lines of the layout.
618    ///
619    /// # Returns
620    ///
621    /// the spacing in Pango units
622    #[doc(alias = "pango_layout_get_spacing")]
623    #[doc(alias = "get_spacing")]
624    pub fn spacing(&self) -> i32 {
625        unsafe { ffi::pango_layout_get_spacing(self.to_glib_none().0) }
626    }
627
628    /// Gets the current [`TabArray`][crate::TabArray] used by this layout.
629    ///
630    /// If no [`TabArray`][crate::TabArray] has been set, then the default tabs are
631    /// in use and [`None`] is returned. Default tabs are every 8 spaces.
632    ///
633    /// The return value should be freed with `Pango::TabArray::free()`.
634    ///
635    /// # Returns
636    ///
637    /// a copy of the tabs for this layout
638    #[doc(alias = "pango_layout_get_tabs")]
639    #[doc(alias = "get_tabs")]
640    pub fn tabs(&self) -> Option<TabArray> {
641        unsafe { from_glib_full(ffi::pango_layout_get_tabs(self.to_glib_none().0)) }
642    }
643
644    /// Gets the text in the layout.
645    ///
646    /// The returned text should not be freed or modified.
647    ///
648    /// # Returns
649    ///
650    /// the text in the @self
651    #[doc(alias = "pango_layout_get_text")]
652    #[doc(alias = "get_text")]
653    pub fn text(&self) -> glib::GString {
654        unsafe { from_glib_none(ffi::pango_layout_get_text(self.to_glib_none().0)) }
655    }
656
657    /// Counts the number of unknown glyphs in @self.
658    ///
659    /// This function can be used to determine if there are any fonts
660    /// available to render all characters in a certain string, or when
661    /// used in combination with [`AttrType::Fallback`][crate::AttrType::Fallback], to check if a
662    /// certain font supports all the characters in the string.
663    ///
664    /// # Returns
665    ///
666    /// The number of unknown glyphs in @self
667    #[doc(alias = "pango_layout_get_unknown_glyphs_count")]
668    #[doc(alias = "get_unknown_glyphs_count")]
669    pub fn unknown_glyphs_count(&self) -> i32 {
670        unsafe { ffi::pango_layout_get_unknown_glyphs_count(self.to_glib_none().0) }
671    }
672
673    /// Gets the width to which the lines of the [`Layout`][crate::Layout] should wrap.
674    ///
675    /// # Returns
676    ///
677    /// the width in Pango units, or -1 if no width set.
678    #[doc(alias = "pango_layout_get_width")]
679    #[doc(alias = "get_width")]
680    pub fn width(&self) -> i32 {
681        unsafe { ffi::pango_layout_get_width(self.to_glib_none().0) }
682    }
683
684    /// Gets the wrap mode for the layout.
685    ///
686    /// Use [`is_wrapped()`][Self::is_wrapped()] to query whether
687    /// any paragraphs were actually wrapped.
688    ///
689    /// # Returns
690    ///
691    /// active wrap mode.
692    #[doc(alias = "pango_layout_get_wrap")]
693    #[doc(alias = "get_wrap")]
694    pub fn wrap(&self) -> WrapMode {
695        unsafe { from_glib(ffi::pango_layout_get_wrap(self.to_glib_none().0)) }
696    }
697
698    /// Converts from byte @index_ within the @self to line and X position.
699    ///
700    /// The X position is measured from the left edge of the line.
701    /// ## `index_`
702    /// the byte index of a grapheme within the layout
703    /// ## `trailing`
704    ///  0, the trailing edge of the grapheme, if 0,
705    ///   the leading of the grapheme
706    ///
707    /// # Returns
708    ///
709    ///
710    /// ## `line`
711    /// location to store resulting line index. (which will
712    ///   between 0 and pango_layout_get_line_count(layout) - 1)
713    ///
714    /// ## `x_pos`
715    /// location to store resulting position within line
716    ///   (`PANGO_SCALE` units per device unit)
717    #[doc(alias = "pango_layout_index_to_line_x")]
718    pub fn index_to_line_x(&self, index_: i32, trailing: bool) -> (i32, i32) {
719        unsafe {
720            let mut line = std::mem::MaybeUninit::uninit();
721            let mut x_pos = std::mem::MaybeUninit::uninit();
722            ffi::pango_layout_index_to_line_x(
723                self.to_glib_none().0,
724                index_,
725                trailing.into_glib(),
726                line.as_mut_ptr(),
727                x_pos.as_mut_ptr(),
728            );
729            (line.assume_init(), x_pos.assume_init())
730        }
731    }
732
733    /// width` will be negative.
734    /// ## `index_`
735    /// byte index within @self
736    ///
737    /// # Returns
738    ///
739    ///
740    /// ## `pos`
741    /// rectangle in which to store the position of the grapheme
742    #[doc(alias = "pango_layout_index_to_pos")]
743    pub fn index_to_pos(&self, index_: i32) -> Rectangle {
744        unsafe {
745            let mut pos = Rectangle::uninitialized();
746            ffi::pango_layout_index_to_pos(self.to_glib_none().0, index_, pos.to_glib_none_mut().0);
747            pos
748        }
749    }
750
751    /// Queries whether the layout had to ellipsize any paragraphs.
752    ///
753    /// This returns [`true`] if the ellipsization mode for @self
754    /// is not [`EllipsizeMode::None`][crate::EllipsizeMode::None], a positive width is set on @self,
755    /// and there are paragraphs exceeding that width that have to be
756    /// ellipsized.
757    ///
758    /// # Returns
759    ///
760    /// [`true`] if any paragraphs had to be ellipsized,
761    ///   [`false`] otherwise
762    #[doc(alias = "pango_layout_is_ellipsized")]
763    pub fn is_ellipsized(&self) -> bool {
764        unsafe { from_glib(ffi::pango_layout_is_ellipsized(self.to_glib_none().0)) }
765    }
766
767    /// Queries whether the layout had to wrap any paragraphs.
768    ///
769    /// This returns [`true`] if a positive width is set on @self,
770    /// and there are paragraphs exceeding the layout width that have
771    /// to be wrapped.
772    ///
773    /// # Returns
774    ///
775    /// [`true`] if any paragraphs had to be wrapped, [`false`]
776    ///   otherwise
777    #[doc(alias = "pango_layout_is_wrapped")]
778    pub fn is_wrapped(&self) -> bool {
779        unsafe { from_glib(ffi::pango_layout_is_wrapped(self.to_glib_none().0)) }
780    }
781
782    /// Computes a new cursor position from an old position and a direction.
783    ///
784    /// If @direction is positive, then the new position will cause the strong
785    /// or weak cursor to be displayed one position to right of where it was
786    /// with the old cursor position. If @direction is negative, it will be
787    /// moved to the left.
788    ///
789    /// In the presence of bidirectional text, the correspondence between
790    /// logical and visual order will depend on the direction of the current
791    /// run, and there may be jumps when the cursor is moved off of the end
792    /// of a run.
793    ///
794    /// Motion here is in cursor positions, not in characters, so a single
795    /// call to this function may move the cursor over multiple characters
796    /// when multiple characters combine to form a single grapheme.
797    /// ## `strong`
798    /// whether the moving cursor is the strong cursor or the
799    ///   weak cursor. The strong cursor is the cursor corresponding
800    ///   to text insertion in the base direction for the layout.
801    /// ## `old_index`
802    /// the byte index of the current cursor position
803    /// ## `old_trailing`
804    ///  0, the cursor
805    ///   was at the trailing edge.
806    /// ## `direction`
807    /// direction to move cursor. A negative
808    ///   value indicates motion to the left
809    ///
810    /// # Returns
811    ///
812    ///
813    /// ## `new_index`
814    /// location to store the new cursor byte index.
815    ///   A value of -1 indicates that the cursor has been moved off the
816    ///   beginning of the layout. A value of `G_MAXINT` indicates that
817    ///   the cursor has been moved off the end of the layout.
818    ///
819    /// ## `new_trailing`
820    /// number of characters to move forward from
821    ///   the location returned for @new_index to get the position where
822    ///   the cursor should be displayed. This allows distinguishing the
823    ///   position at the beginning of one line from the position at the
824    ///   end of the preceding line. @new_index is always on the line where
825    ///   the cursor should be displayed.
826    #[doc(alias = "pango_layout_move_cursor_visually")]
827    pub fn move_cursor_visually(
828        &self,
829        strong: bool,
830        old_index: i32,
831        old_trailing: i32,
832        direction: i32,
833    ) -> (i32, i32) {
834        unsafe {
835            let mut new_index = std::mem::MaybeUninit::uninit();
836            let mut new_trailing = std::mem::MaybeUninit::uninit();
837            ffi::pango_layout_move_cursor_visually(
838                self.to_glib_none().0,
839                strong.into_glib(),
840                old_index,
841                old_trailing,
842                direction,
843                new_index.as_mut_ptr(),
844                new_trailing.as_mut_ptr(),
845            );
846            (new_index.assume_init(), new_trailing.assume_init())
847        }
848    }
849
850    /// Serializes the @self for later deserialization via `Pango::Layout::deserialize()`.
851    ///
852    /// There are no guarantees about the format of the output across different
853    /// versions of Pango and `Pango::Layout::deserialize()` will reject data
854    /// that it cannot parse.
855    ///
856    /// The intended use of this function is testing, benchmarking and debugging.
857    /// The format is not meant as a permanent storage format.
858    /// ## `flags`
859    /// [`LayoutSerializeFlags`][crate::LayoutSerializeFlags]
860    ///
861    /// # Returns
862    ///
863    /// a `GBytes` containing the serialized form of @self
864    #[cfg(feature = "v1_50")]
865    #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
866    #[doc(alias = "pango_layout_serialize")]
867    pub fn serialize(&self, flags: LayoutSerializeFlags) -> glib::Bytes {
868        unsafe {
869            from_glib_full(ffi::pango_layout_serialize(
870                self.to_glib_none().0,
871                flags.into_glib(),
872            ))
873        }
874    }
875
876    /// Sets the alignment for the layout: how partial lines are
877    /// positioned within the horizontal space available.
878    ///
879    /// The default alignment is [`Alignment::Left`][crate::Alignment::Left].
880    /// ## `alignment`
881    /// the alignment
882    #[doc(alias = "pango_layout_set_alignment")]
883    pub fn set_alignment(&self, alignment: Alignment) {
884        unsafe {
885            ffi::pango_layout_set_alignment(self.to_glib_none().0, alignment.into_glib());
886        }
887    }
888
889    /// Sets the text attributes for a layout object.
890    ///
891    /// References @attrs, so the caller can unref its reference.
892    /// ## `attrs`
893    /// a [`AttrList`][crate::AttrList]
894    #[doc(alias = "pango_layout_set_attributes")]
895    pub fn set_attributes(&self, attrs: Option<&AttrList>) {
896        unsafe {
897            ffi::pango_layout_set_attributes(self.to_glib_none().0, attrs.to_glib_none().0);
898        }
899    }
900
901    /// Sets whether to calculate the base direction
902    /// for the layout according to its contents.
903    ///
904    /// When this flag is on (the default), then paragraphs in @self that
905    /// begin with strong right-to-left characters (Arabic and Hebrew principally),
906    /// will have right-to-left layout, paragraphs with letters from other scripts
907    /// will have left-to-right layout. Paragraphs with only neutral characters
908    /// get their direction from the surrounding paragraphs.
909    ///
910    /// When [`false`], the choice between left-to-right and right-to-left
911    /// layout is done according to the base direction of the layout's
912    /// [`Context`][crate::Context]. (See [`Context::set_base_dir()`][crate::Context::set_base_dir()]).
913    ///
914    /// When the auto-computed direction of a paragraph differs from the
915    /// base direction of the context, the interpretation of
916    /// [`Alignment::Left`][crate::Alignment::Left] and [`Alignment::Right`][crate::Alignment::Right] are swapped.
917    /// ## `auto_dir`
918    /// if [`true`], compute the bidirectional base direction
919    ///   from the layout's contents
920    #[doc(alias = "pango_layout_set_auto_dir")]
921    pub fn set_auto_dir(&self, auto_dir: bool) {
922        unsafe {
923            ffi::pango_layout_set_auto_dir(self.to_glib_none().0, auto_dir.into_glib());
924        }
925    }
926
927    /// Sets the type of ellipsization being performed for @self.
928    ///
929    /// Depending on the ellipsization mode @ellipsize text is
930    /// removed from the start, middle, or end of text so they
931    /// fit within the width and height of layout set with
932    /// [`set_width()`][Self::set_width()] and [`set_height()`][Self::set_height()].
933    ///
934    /// If the layout contains characters such as newlines that
935    /// force it to be layed out in multiple paragraphs, then whether
936    /// each paragraph is ellipsized separately or the entire layout
937    /// is ellipsized as a whole depends on the set height of the layout.
938    ///
939    /// The default value is [`EllipsizeMode::None`][crate::EllipsizeMode::None].
940    ///
941    /// See [`set_height()`][Self::set_height()] for details.
942    /// ## `ellipsize`
943    /// the new ellipsization mode for @self
944    #[doc(alias = "pango_layout_set_ellipsize")]
945    pub fn set_ellipsize(&self, ellipsize: EllipsizeMode) {
946        unsafe {
947            ffi::pango_layout_set_ellipsize(self.to_glib_none().0, ellipsize.into_glib());
948        }
949    }
950
951    /// Sets the default font description for the layout.
952    ///
953    /// If no font description is set on the layout, the
954    /// font description from the layout's context is used.
955    /// ## `desc`
956    /// the new [`FontDescription`][crate::FontDescription]
957    ///   to unset the current font description
958    #[doc(alias = "pango_layout_set_font_description")]
959    pub fn set_font_description(&self, desc: Option<&FontDescription>) {
960        unsafe {
961            ffi::pango_layout_set_font_description(self.to_glib_none().0, desc.to_glib_none().0);
962        }
963    }
964
965    /// Sets the height to which the [`Layout`][crate::Layout] should be ellipsized at.
966    ///
967    /// There are two different behaviors, based on whether @height is positive
968    /// or negative.
969    ///
970    /// If @height is positive, it will be the maximum height of the layout. Only
971    /// lines would be shown that would fit, and if there is any text omitted,
972    /// an ellipsis added. At least one line is included in each paragraph regardless
973    /// of how small the height value is. A value of zero will render exactly one
974    /// line for the entire layout.
975    ///
976    /// If @height is negative, it will be the (negative of) maximum number of lines
977    /// per paragraph. That is, the total number of lines shown may well be more than
978    /// this value if the layout contains multiple paragraphs of text.
979    /// The default value of -1 means that the first line of each paragraph is ellipsized.
980    /// This behavior may be changed in the future to act per layout instead of per
981    /// paragraph. File a bug against pango at
982    /// [https://gitlab.gnome.org/gnome/pango](https://gitlab.gnome.org/gnome/pango)
983    /// if your code relies on this behavior.
984    ///
985    /// Height setting only has effect if a positive width is set on
986    /// @self and ellipsization mode of @self is not [`EllipsizeMode::None`][crate::EllipsizeMode::None].
987    /// The behavior is undefined if a height other than -1 is set and
988    /// ellipsization mode is set to [`EllipsizeMode::None`][crate::EllipsizeMode::None], and may change in the
989    /// future.
990    /// ## `height`
991    /// the desired height of the layout in Pango units if positive,
992    ///   or desired number of lines if negative.
993    #[doc(alias = "pango_layout_set_height")]
994    pub fn set_height(&self, height: i32) {
995        unsafe {
996            ffi::pango_layout_set_height(self.to_glib_none().0, height);
997        }
998    }
999
1000    /// Sets the width in Pango units to indent each paragraph.
1001    ///
1002    /// A negative value of @indent will produce a hanging indentation.
1003    /// That is, the first line will have the full width, and subsequent
1004    /// lines will be indented by the absolute value of @indent.
1005    ///
1006    /// The indent setting is ignored if layout alignment is set to
1007    /// [`Alignment::Center`][crate::Alignment::Center].
1008    ///
1009    /// The default value is 0.
1010    /// ## `indent`
1011    /// the amount by which to indent
1012    #[doc(alias = "pango_layout_set_indent")]
1013    pub fn set_indent(&self, indent: i32) {
1014        unsafe {
1015            ffi::pango_layout_set_indent(self.to_glib_none().0, indent);
1016        }
1017    }
1018
1019    /// Sets whether each complete line should be stretched to fill the
1020    /// entire width of the layout.
1021    ///
1022    /// Stretching is typically done by adding whitespace, but for some scripts
1023    /// (such as Arabic), the justification may be done in more complex ways,
1024    /// like extending the characters.
1025    ///
1026    /// Note that this setting is not implemented and so is ignored in
1027    /// Pango older than 1.18.
1028    ///
1029    /// Note that tabs and justification conflict with each other:
1030    /// Justification will move content away from its tab-aligned
1031    /// positions.
1032    ///
1033    /// The default value is [`false`].
1034    ///
1035    /// Also see [`set_justify_last_line()`][Self::set_justify_last_line()].
1036    /// ## `justify`
1037    /// whether the lines in the layout should be justified
1038    #[doc(alias = "pango_layout_set_justify")]
1039    pub fn set_justify(&self, justify: bool) {
1040        unsafe {
1041            ffi::pango_layout_set_justify(self.to_glib_none().0, justify.into_glib());
1042        }
1043    }
1044
1045    /// Sets whether the last line should be stretched to fill the
1046    /// entire width of the layout.
1047    ///
1048    /// This only has an effect if [`set_justify()`][Self::set_justify()] has
1049    /// been called as well.
1050    ///
1051    /// The default value is [`false`].
1052    /// ## `justify`
1053    /// whether the last line in the layout should be justified
1054    #[cfg(feature = "v1_50")]
1055    #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
1056    #[doc(alias = "pango_layout_set_justify_last_line")]
1057    pub fn set_justify_last_line(&self, justify: bool) {
1058        unsafe {
1059            ffi::pango_layout_set_justify_last_line(self.to_glib_none().0, justify.into_glib());
1060        }
1061    }
1062
1063    /// Sets a factor for line spacing.
1064    ///
1065    /// Typical values are: 0, 1, 1.5, 2. The default values is 0.
1066    ///
1067    /// If @factor is non-zero, lines are placed so that
1068    ///
1069    ///     baseline2 = baseline1 + factor * height2
1070    ///
1071    /// where height2 is the line height of the second line
1072    /// (as determined by the font(s)). In this case, the spacing
1073    /// set with [`set_spacing()`][Self::set_spacing()] is ignored.
1074    ///
1075    /// If @factor is zero (the default), spacing is applied as before.
1076    ///
1077    /// Note: for semantics that are closer to the CSS line-height
1078    /// property, see `attr_line_height_new()`.
1079    /// ## `factor`
1080    /// the new line spacing factor
1081    #[cfg(feature = "v1_44")]
1082    #[cfg_attr(docsrs, doc(cfg(feature = "v1_44")))]
1083    #[doc(alias = "pango_layout_set_line_spacing")]
1084    pub fn set_line_spacing(&self, factor: f32) {
1085        unsafe {
1086            ffi::pango_layout_set_line_spacing(self.to_glib_none().0, factor);
1087        }
1088    }
1089
1090    /// Sets the layout text and attribute list from marked-up text.
1091    ///
1092    /// See [Pango Markup](pango_markup.html)).
1093    ///
1094    /// Replaces the current text and attribute list.
1095    ///
1096    /// This is the same as [`set_markup_with_accel()`][Self::set_markup_with_accel()],
1097    /// but the markup text isn't scanned for accelerators.
1098    /// ## `markup`
1099    /// marked-up text
1100    /// ## `length`
1101    /// length of marked-up text in bytes, or -1 if @markup is
1102    ///   `NUL`-terminated
1103    #[doc(alias = "pango_layout_set_markup")]
1104    pub fn set_markup(&self, markup: &str) {
1105        let length = markup.len() as _;
1106        unsafe {
1107            ffi::pango_layout_set_markup(self.to_glib_none().0, markup.to_glib_none().0, length);
1108        }
1109    }
1110
1111    /// Sets the layout text and attribute list from marked-up text.
1112    ///
1113    /// See [Pango Markup](pango_markup.html)).
1114    ///
1115    /// Replaces the current text and attribute list.
1116    ///
1117    /// If @accel_marker is nonzero, the given character will mark the
1118    /// character following it as an accelerator. For example, @accel_marker
1119    /// might be an ampersand or underscore. All characters marked
1120    /// as an accelerator will receive a [`Underline::Low`][crate::Underline::Low] attribute,
1121    /// and the first character so marked will be returned in @accel_char.
1122    /// Two @accel_marker characters following each other produce a single
1123    /// literal @accel_marker character.
1124    /// ## `markup`
1125    /// marked-up text (see [Pango Markup](pango_markup.html))
1126    /// ## `length`
1127    /// length of marked-up text in bytes, or -1 if @markup is
1128    ///   `NUL`-terminated
1129    /// ## `accel_marker`
1130    /// marker for accelerators in the text
1131    ///
1132    /// # Returns
1133    ///
1134    ///
1135    /// ## `accel_char`
1136    /// return location
1137    ///   for first located accelerator
1138    #[doc(alias = "pango_layout_set_markup_with_accel")]
1139    pub fn set_markup_with_accel(&self, markup: &str, accel_marker: char) -> char {
1140        let length = markup.len() as _;
1141        unsafe {
1142            let mut accel_char = std::mem::MaybeUninit::uninit();
1143            ffi::pango_layout_set_markup_with_accel(
1144                self.to_glib_none().0,
1145                markup.to_glib_none().0,
1146                length,
1147                accel_marker.into_glib(),
1148                accel_char.as_mut_ptr(),
1149            );
1150            std::convert::TryFrom::try_from(accel_char.assume_init())
1151                .expect("conversion from an invalid Unicode value attempted")
1152        }
1153    }
1154
1155    /// Sets the single paragraph mode of @self.
1156    ///
1157    /// If @setting is [`true`], do not treat newlines and similar characters
1158    /// as paragraph separators; instead, keep all text in a single paragraph,
1159    /// and display a glyph for paragraph separator characters. Used when
1160    /// you want to allow editing of newlines on a single text line.
1161    ///
1162    /// The default value is [`false`].
1163    /// ## `setting`
1164    /// new setting
1165    #[doc(alias = "pango_layout_set_single_paragraph_mode")]
1166    pub fn set_single_paragraph_mode(&self, setting: bool) {
1167        unsafe {
1168            ffi::pango_layout_set_single_paragraph_mode(self.to_glib_none().0, setting.into_glib());
1169        }
1170    }
1171
1172    /// Sets the amount of spacing in Pango units between
1173    /// the lines of the layout.
1174    ///
1175    /// When placing lines with spacing, Pango arranges things so that
1176    ///
1177    ///     line2.top = line1.bottom + spacing
1178    ///
1179    /// The default value is 0.
1180    ///
1181    /// Note: Since 1.44, Pango is using the line height (as determined
1182    /// by the font) for placing lines when the line spacing factor is set
1183    /// to a non-zero value with [`set_line_spacing()`][Self::set_line_spacing()].
1184    /// In that case, the @spacing set with this function is ignored.
1185    ///
1186    /// Note: for semantics that are closer to the CSS line-height
1187    /// property, see `attr_line_height_new()`.
1188    /// ## `spacing`
1189    /// the amount of spacing
1190    #[doc(alias = "pango_layout_set_spacing")]
1191    pub fn set_spacing(&self, spacing: i32) {
1192        unsafe {
1193            ffi::pango_layout_set_spacing(self.to_glib_none().0, spacing);
1194        }
1195    }
1196
1197    /// Sets the tabs to use for @self, overriding the default tabs.
1198    ///
1199    /// [`Layout`][crate::Layout] will place content at the next tab position
1200    /// whenever it meets a Tab character (U+0009).
1201    ///
1202    /// By default, tabs are every 8 spaces. If @tabs is [`None`], the
1203    /// default tabs are reinstated. @tabs is copied into the layout;
1204    /// you must free your copy of @tabs yourself.
1205    ///
1206    /// Note that tabs and justification conflict with each other:
1207    /// Justification will move content away from its tab-aligned
1208    /// positions. The same is true for alignments other than
1209    /// [`Alignment::Left`][crate::Alignment::Left].
1210    /// ## `tabs`
1211    /// a [`TabArray`][crate::TabArray]
1212    #[doc(alias = "pango_layout_set_tabs")]
1213    pub fn set_tabs(&self, tabs: Option<&TabArray>) {
1214        unsafe {
1215            ffi::pango_layout_set_tabs(self.to_glib_none().0, mut_override(tabs.to_glib_none().0));
1216        }
1217    }
1218
1219    /// Sets the text of the layout.
1220    ///
1221    /// This function validates @text and renders invalid UTF-8
1222    /// with a placeholder glyph.
1223    ///
1224    /// Note that if you have used [`set_markup()`][Self::set_markup()] or
1225    /// [`set_markup_with_accel()`][Self::set_markup_with_accel()] on @self before, you
1226    /// may want to call [`set_attributes()`][Self::set_attributes()] to clear the
1227    /// attributes set on the layout from the markup as this function does
1228    /// not clear attributes.
1229    /// ## `text`
1230    /// the text
1231    /// ## `length`
1232    /// maximum length of @text, in bytes. -1 indicates that
1233    ///   the string is nul-terminated and the length should be calculated.
1234    ///   The text will also be truncated on encountering a nul-termination
1235    ///   even when @length is positive.
1236    #[doc(alias = "pango_layout_set_text")]
1237    pub fn set_text(&self, text: &str) {
1238        let length = text.len() as _;
1239        unsafe {
1240            ffi::pango_layout_set_text(self.to_glib_none().0, text.to_glib_none().0, length);
1241        }
1242    }
1243
1244    /// Sets the width to which the lines of the [`Layout`][crate::Layout] should wrap or
1245    /// get ellipsized.
1246    ///
1247    /// The default value is -1: no width set.
1248    /// ## `width`
1249    /// the desired width in Pango units, or -1 to indicate that no
1250    ///   wrapping or ellipsization should be performed.
1251    #[doc(alias = "pango_layout_set_width")]
1252    pub fn set_width(&self, width: i32) {
1253        unsafe {
1254            ffi::pango_layout_set_width(self.to_glib_none().0, width);
1255        }
1256    }
1257
1258    /// Sets the wrap mode.
1259    ///
1260    /// The wrap mode only has effect if a width is set on the layout
1261    /// with [`set_width()`][Self::set_width()]. To turn off wrapping,
1262    /// set the width to -1.
1263    ///
1264    /// The default value is [`WrapMode::Word`][crate::WrapMode::Word].
1265    /// ## `wrap`
1266    /// the wrap mode
1267    #[doc(alias = "pango_layout_set_wrap")]
1268    pub fn set_wrap(&self, wrap: WrapMode) {
1269        unsafe {
1270            ffi::pango_layout_set_wrap(self.to_glib_none().0, wrap.into_glib());
1271        }
1272    }
1273
1274    /// A convenience method to serialize a layout to a file.
1275    ///
1276    /// It is equivalent to calling [`serialize()`][Self::serialize()]
1277    /// followed by `file_set_contents()`.
1278    ///
1279    /// See those two functions for details on the arguments.
1280    ///
1281    /// It is mostly intended for use inside a debugger to quickly dump
1282    /// a layout to a file for later inspection.
1283    /// ## `flags`
1284    /// [`LayoutSerializeFlags`][crate::LayoutSerializeFlags]
1285    /// ## `filename`
1286    /// the file to save it to
1287    ///
1288    /// # Returns
1289    ///
1290    /// [`true`] if saving was successful
1291    #[cfg(feature = "v1_50")]
1292    #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
1293    #[doc(alias = "pango_layout_write_to_file")]
1294    pub fn write_to_file(
1295        &self,
1296        flags: LayoutSerializeFlags,
1297        filename: impl AsRef<std::path::Path>,
1298    ) -> Result<(), glib::Error> {
1299        unsafe {
1300            let mut error = std::ptr::null_mut();
1301            let is_ok = ffi::pango_layout_write_to_file(
1302                self.to_glib_none().0,
1303                flags.into_glib(),
1304                filename.as_ref().to_glib_none().0,
1305                &mut error,
1306            );
1307            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1308            if error.is_null() {
1309                Ok(())
1310            } else {
1311                Err(from_glib_full(error))
1312            }
1313        }
1314    }
1315
1316    /// Converts from X and Y position within a layout to the byte index to the
1317    /// character at that logical position.
1318    ///
1319    /// If the Y position is not inside the layout, the closest position is
1320    /// chosen (the position will be clamped inside the layout). If the X position
1321    /// is not within the layout, then the start or the end of the line is
1322    /// chosen as described for [`LayoutLine::x_to_index()`][crate::LayoutLine::x_to_index()]. If either
1323    /// the X or Y positions were not inside the layout, then the function returns
1324    /// [`false`]; on an exact hit, it returns [`true`].
1325    /// ## `x`
1326    /// the X offset (in Pango units) from the left edge of the layout
1327    /// ## `y`
1328    /// the Y offset (in Pango units) from the top edge of the layout
1329    ///
1330    /// # Returns
1331    ///
1332    /// [`true`] if the coordinates were inside text, [`false`] otherwise
1333    ///
1334    /// ## `index_`
1335    /// location to store calculated byte index
1336    ///
1337    /// ## `trailing`
1338    /// location to store a integer indicating where
1339    ///   in the grapheme the user clicked. It will either be zero, or the
1340    ///   number of characters in the grapheme. 0 represents the leading edge
1341    ///   of the grapheme.
1342    #[doc(alias = "pango_layout_xy_to_index")]
1343    pub fn xy_to_index(&self, x: i32, y: i32) -> (bool, i32, i32) {
1344        unsafe {
1345            let mut index_ = std::mem::MaybeUninit::uninit();
1346            let mut trailing = std::mem::MaybeUninit::uninit();
1347            let ret = from_glib(ffi::pango_layout_xy_to_index(
1348                self.to_glib_none().0,
1349                x,
1350                y,
1351                index_.as_mut_ptr(),
1352                trailing.as_mut_ptr(),
1353            ));
1354            (ret, index_.assume_init(), trailing.assume_init())
1355        }
1356    }
1357}