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 /// |  |  |
50 /// |  |  |
51 /// |  |  |
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}