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