1#[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 #[doc(alias = "PangoLayout")]
19 pub struct Layout(Object<ffi::PangoLayout, ffi::PangoLayoutClass>);
20
21 match fn {
22 type_ => || ffi::pango_layout_get_type(),
23 }
24}
25
26impl Layout {
27 #[doc(alias = "pango_layout_new")]
28 pub fn new(context: &Context) -> Layout {
29 unsafe { from_glib_full(ffi::pango_layout_new(context.to_glib_none().0)) }
30 }
31
32 #[doc(alias = "pango_layout_context_changed")]
33 pub fn context_changed(&self) {
34 unsafe {
35 ffi::pango_layout_context_changed(self.to_glib_none().0);
36 }
37 }
38
39 #[doc(alias = "pango_layout_copy")]
40 #[must_use]
41 pub fn copy(&self) -> Layout {
42 unsafe { from_glib_full(ffi::pango_layout_copy(self.to_glib_none().0)) }
43 }
44
45 #[doc(alias = "pango_layout_get_alignment")]
46 #[doc(alias = "get_alignment")]
47 pub fn alignment(&self) -> Alignment {
48 unsafe { from_glib(ffi::pango_layout_get_alignment(self.to_glib_none().0)) }
49 }
50
51 #[doc(alias = "pango_layout_get_attributes")]
52 #[doc(alias = "get_attributes")]
53 pub fn attributes(&self) -> Option<AttrList> {
54 unsafe { from_glib_none(ffi::pango_layout_get_attributes(self.to_glib_none().0)) }
55 }
56
57 #[doc(alias = "pango_layout_get_auto_dir")]
58 #[doc(alias = "get_auto_dir")]
59 pub fn is_auto_dir(&self) -> bool {
60 unsafe { from_glib(ffi::pango_layout_get_auto_dir(self.to_glib_none().0)) }
61 }
62
63 #[doc(alias = "pango_layout_get_baseline")]
64 #[doc(alias = "get_baseline")]
65 pub fn baseline(&self) -> i32 {
66 unsafe { ffi::pango_layout_get_baseline(self.to_glib_none().0) }
67 }
68
69 #[cfg(feature = "v1_50")]
70 #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
71 #[doc(alias = "pango_layout_get_caret_pos")]
72 #[doc(alias = "get_caret_pos")]
73 pub fn caret_pos(&self, index_: i32) -> (Rectangle, Rectangle) {
74 unsafe {
75 let mut strong_pos = Rectangle::uninitialized();
76 let mut weak_pos = Rectangle::uninitialized();
77 ffi::pango_layout_get_caret_pos(
78 self.to_glib_none().0,
79 index_,
80 strong_pos.to_glib_none_mut().0,
81 weak_pos.to_glib_none_mut().0,
82 );
83 (strong_pos, weak_pos)
84 }
85 }
86
87 #[doc(alias = "pango_layout_get_character_count")]
88 #[doc(alias = "get_character_count")]
89 pub fn character_count(&self) -> i32 {
90 unsafe { ffi::pango_layout_get_character_count(self.to_glib_none().0) }
91 }
92
93 #[doc(alias = "pango_layout_get_context")]
94 #[doc(alias = "get_context")]
95 pub fn context(&self) -> Context {
96 unsafe { from_glib_none(ffi::pango_layout_get_context(self.to_glib_none().0)) }
97 }
98
99 #[doc(alias = "pango_layout_get_cursor_pos")]
100 #[doc(alias = "get_cursor_pos")]
101 pub fn cursor_pos(&self, index_: i32) -> (Rectangle, Rectangle) {
102 unsafe {
103 let mut strong_pos = Rectangle::uninitialized();
104 let mut weak_pos = Rectangle::uninitialized();
105 ffi::pango_layout_get_cursor_pos(
106 self.to_glib_none().0,
107 index_,
108 strong_pos.to_glib_none_mut().0,
109 weak_pos.to_glib_none_mut().0,
110 );
111 (strong_pos, weak_pos)
112 }
113 }
114
115 #[cfg(feature = "v1_46")]
116 #[cfg_attr(docsrs, doc(cfg(feature = "v1_46")))]
117 #[doc(alias = "pango_layout_get_direction")]
118 #[doc(alias = "get_direction")]
119 pub fn direction(&self, index: i32) -> Direction {
120 unsafe {
121 from_glib(ffi::pango_layout_get_direction(
122 self.to_glib_none().0,
123 index,
124 ))
125 }
126 }
127
128 #[doc(alias = "pango_layout_get_ellipsize")]
129 #[doc(alias = "get_ellipsize")]
130 pub fn ellipsize(&self) -> EllipsizeMode {
131 unsafe { from_glib(ffi::pango_layout_get_ellipsize(self.to_glib_none().0)) }
132 }
133
134 #[doc(alias = "pango_layout_get_extents")]
135 #[doc(alias = "get_extents")]
136 pub fn extents(&self) -> (Rectangle, Rectangle) {
137 unsafe {
138 let mut ink_rect = Rectangle::uninitialized();
139 let mut logical_rect = Rectangle::uninitialized();
140 ffi::pango_layout_get_extents(
141 self.to_glib_none().0,
142 ink_rect.to_glib_none_mut().0,
143 logical_rect.to_glib_none_mut().0,
144 );
145 (ink_rect, logical_rect)
146 }
147 }
148
149 #[doc(alias = "pango_layout_get_font_description")]
150 #[doc(alias = "get_font_description")]
151 pub fn font_description(&self) -> Option<FontDescription> {
152 unsafe {
153 from_glib_none(ffi::pango_layout_get_font_description(
154 self.to_glib_none().0,
155 ))
156 }
157 }
158
159 #[doc(alias = "pango_layout_get_height")]
160 #[doc(alias = "get_height")]
161 pub fn height(&self) -> i32 {
162 unsafe { ffi::pango_layout_get_height(self.to_glib_none().0) }
163 }
164
165 #[doc(alias = "pango_layout_get_indent")]
166 #[doc(alias = "get_indent")]
167 pub fn indent(&self) -> i32 {
168 unsafe { ffi::pango_layout_get_indent(self.to_glib_none().0) }
169 }
170
171 #[doc(alias = "pango_layout_get_iter")]
172 #[doc(alias = "get_iter")]
173 pub fn iter(&self) -> LayoutIter {
174 unsafe { from_glib_full(ffi::pango_layout_get_iter(self.to_glib_none().0)) }
175 }
176
177 #[doc(alias = "pango_layout_get_justify")]
178 #[doc(alias = "get_justify")]
179 pub fn is_justify(&self) -> bool {
180 unsafe { from_glib(ffi::pango_layout_get_justify(self.to_glib_none().0)) }
181 }
182
183 #[cfg(feature = "v1_50")]
184 #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
185 #[doc(alias = "pango_layout_get_justify_last_line")]
186 #[doc(alias = "get_justify_last_line")]
187 pub fn is_justify_last_line(&self) -> bool {
188 unsafe {
189 from_glib(ffi::pango_layout_get_justify_last_line(
190 self.to_glib_none().0,
191 ))
192 }
193 }
194
195 #[doc(alias = "pango_layout_get_line")]
196 #[doc(alias = "get_line")]
197 pub fn line(&self, line: i32) -> Option<LayoutLine> {
198 unsafe { from_glib_none(ffi::pango_layout_get_line(self.to_glib_none().0, line)) }
199 }
200
201 #[doc(alias = "pango_layout_get_line_count")]
202 #[doc(alias = "get_line_count")]
203 pub fn line_count(&self) -> i32 {
204 unsafe { ffi::pango_layout_get_line_count(self.to_glib_none().0) }
205 }
206
207 #[doc(alias = "pango_layout_get_line_readonly")]
208 #[doc(alias = "get_line_readonly")]
209 pub fn line_readonly(&self, line: i32) -> Option<LayoutLine> {
210 unsafe {
211 from_glib_none(ffi::pango_layout_get_line_readonly(
212 self.to_glib_none().0,
213 line,
214 ))
215 }
216 }
217
218 #[cfg(feature = "v1_44")]
219 #[cfg_attr(docsrs, doc(cfg(feature = "v1_44")))]
220 #[doc(alias = "pango_layout_get_line_spacing")]
221 #[doc(alias = "get_line_spacing")]
222 pub fn line_spacing(&self) -> f32 {
223 unsafe { ffi::pango_layout_get_line_spacing(self.to_glib_none().0) }
224 }
225
226 #[doc(alias = "pango_layout_get_lines")]
227 #[doc(alias = "get_lines")]
228 pub fn lines(&self) -> Vec<LayoutLine> {
229 unsafe {
230 FromGlibPtrContainer::from_glib_none(ffi::pango_layout_get_lines(self.to_glib_none().0))
231 }
232 }
233
234 #[doc(alias = "pango_layout_get_lines_readonly")]
235 #[doc(alias = "get_lines_readonly")]
236 pub fn lines_readonly(&self) -> Vec<LayoutLine> {
237 unsafe {
238 FromGlibPtrContainer::from_glib_none(ffi::pango_layout_get_lines_readonly(
239 self.to_glib_none().0,
240 ))
241 }
242 }
243
244 #[doc(alias = "pango_layout_get_pixel_extents")]
257 #[doc(alias = "get_pixel_extents")]
258 pub fn pixel_extents(&self) -> (Rectangle, Rectangle) {
259 unsafe {
260 let mut ink_rect = Rectangle::uninitialized();
261 let mut logical_rect = Rectangle::uninitialized();
262 ffi::pango_layout_get_pixel_extents(
263 self.to_glib_none().0,
264 ink_rect.to_glib_none_mut().0,
265 logical_rect.to_glib_none_mut().0,
266 );
267 (ink_rect, logical_rect)
268 }
269 }
270
271 #[doc(alias = "pango_layout_get_pixel_size")]
272 #[doc(alias = "get_pixel_size")]
273 pub fn pixel_size(&self) -> (i32, i32) {
274 unsafe {
275 let mut width = std::mem::MaybeUninit::uninit();
276 let mut height = std::mem::MaybeUninit::uninit();
277 ffi::pango_layout_get_pixel_size(
278 self.to_glib_none().0,
279 width.as_mut_ptr(),
280 height.as_mut_ptr(),
281 );
282 (width.assume_init(), height.assume_init())
283 }
284 }
285
286 #[doc(alias = "pango_layout_get_serial")]
287 #[doc(alias = "get_serial")]
288 pub fn serial(&self) -> u32 {
289 unsafe { ffi::pango_layout_get_serial(self.to_glib_none().0) }
290 }
291
292 #[doc(alias = "pango_layout_get_single_paragraph_mode")]
293 #[doc(alias = "get_single_paragraph_mode")]
294 pub fn is_single_paragraph_mode(&self) -> bool {
295 unsafe {
296 from_glib(ffi::pango_layout_get_single_paragraph_mode(
297 self.to_glib_none().0,
298 ))
299 }
300 }
301
302 #[doc(alias = "pango_layout_get_size")]
303 #[doc(alias = "get_size")]
304 pub fn size(&self) -> (i32, i32) {
305 unsafe {
306 let mut width = std::mem::MaybeUninit::uninit();
307 let mut height = std::mem::MaybeUninit::uninit();
308 ffi::pango_layout_get_size(
309 self.to_glib_none().0,
310 width.as_mut_ptr(),
311 height.as_mut_ptr(),
312 );
313 (width.assume_init(), height.assume_init())
314 }
315 }
316
317 #[doc(alias = "pango_layout_get_spacing")]
318 #[doc(alias = "get_spacing")]
319 pub fn spacing(&self) -> i32 {
320 unsafe { ffi::pango_layout_get_spacing(self.to_glib_none().0) }
321 }
322
323 #[doc(alias = "pango_layout_get_tabs")]
324 #[doc(alias = "get_tabs")]
325 pub fn tabs(&self) -> Option<TabArray> {
326 unsafe { from_glib_full(ffi::pango_layout_get_tabs(self.to_glib_none().0)) }
327 }
328
329 #[doc(alias = "pango_layout_get_text")]
330 #[doc(alias = "get_text")]
331 pub fn text(&self) -> glib::GString {
332 unsafe { from_glib_none(ffi::pango_layout_get_text(self.to_glib_none().0)) }
333 }
334
335 #[doc(alias = "pango_layout_get_unknown_glyphs_count")]
336 #[doc(alias = "get_unknown_glyphs_count")]
337 pub fn unknown_glyphs_count(&self) -> i32 {
338 unsafe { ffi::pango_layout_get_unknown_glyphs_count(self.to_glib_none().0) }
339 }
340
341 #[doc(alias = "pango_layout_get_width")]
342 #[doc(alias = "get_width")]
343 pub fn width(&self) -> i32 {
344 unsafe { ffi::pango_layout_get_width(self.to_glib_none().0) }
345 }
346
347 #[doc(alias = "pango_layout_get_wrap")]
348 #[doc(alias = "get_wrap")]
349 pub fn wrap(&self) -> WrapMode {
350 unsafe { from_glib(ffi::pango_layout_get_wrap(self.to_glib_none().0)) }
351 }
352
353 #[doc(alias = "pango_layout_index_to_line_x")]
354 pub fn index_to_line_x(&self, index_: i32, trailing: bool) -> (i32, i32) {
355 unsafe {
356 let mut line = std::mem::MaybeUninit::uninit();
357 let mut x_pos = std::mem::MaybeUninit::uninit();
358 ffi::pango_layout_index_to_line_x(
359 self.to_glib_none().0,
360 index_,
361 trailing.into_glib(),
362 line.as_mut_ptr(),
363 x_pos.as_mut_ptr(),
364 );
365 (line.assume_init(), x_pos.assume_init())
366 }
367 }
368
369 #[doc(alias = "pango_layout_index_to_pos")]
370 pub fn index_to_pos(&self, index_: i32) -> Rectangle {
371 unsafe {
372 let mut pos = Rectangle::uninitialized();
373 ffi::pango_layout_index_to_pos(self.to_glib_none().0, index_, pos.to_glib_none_mut().0);
374 pos
375 }
376 }
377
378 #[doc(alias = "pango_layout_is_ellipsized")]
379 pub fn is_ellipsized(&self) -> bool {
380 unsafe { from_glib(ffi::pango_layout_is_ellipsized(self.to_glib_none().0)) }
381 }
382
383 #[doc(alias = "pango_layout_is_wrapped")]
384 pub fn is_wrapped(&self) -> bool {
385 unsafe { from_glib(ffi::pango_layout_is_wrapped(self.to_glib_none().0)) }
386 }
387
388 #[doc(alias = "pango_layout_move_cursor_visually")]
389 pub fn move_cursor_visually(
390 &self,
391 strong: bool,
392 old_index: i32,
393 old_trailing: i32,
394 direction: i32,
395 ) -> (i32, i32) {
396 unsafe {
397 let mut new_index = std::mem::MaybeUninit::uninit();
398 let mut new_trailing = std::mem::MaybeUninit::uninit();
399 ffi::pango_layout_move_cursor_visually(
400 self.to_glib_none().0,
401 strong.into_glib(),
402 old_index,
403 old_trailing,
404 direction,
405 new_index.as_mut_ptr(),
406 new_trailing.as_mut_ptr(),
407 );
408 (new_index.assume_init(), new_trailing.assume_init())
409 }
410 }
411
412 #[cfg(feature = "v1_50")]
413 #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
414 #[doc(alias = "pango_layout_serialize")]
415 pub fn serialize(&self, flags: LayoutSerializeFlags) -> glib::Bytes {
416 unsafe {
417 from_glib_full(ffi::pango_layout_serialize(
418 self.to_glib_none().0,
419 flags.into_glib(),
420 ))
421 }
422 }
423
424 #[doc(alias = "pango_layout_set_alignment")]
425 pub fn set_alignment(&self, alignment: Alignment) {
426 unsafe {
427 ffi::pango_layout_set_alignment(self.to_glib_none().0, alignment.into_glib());
428 }
429 }
430
431 #[doc(alias = "pango_layout_set_attributes")]
432 pub fn set_attributes(&self, attrs: Option<&AttrList>) {
433 unsafe {
434 ffi::pango_layout_set_attributes(self.to_glib_none().0, attrs.to_glib_none().0);
435 }
436 }
437
438 #[doc(alias = "pango_layout_set_auto_dir")]
439 pub fn set_auto_dir(&self, auto_dir: bool) {
440 unsafe {
441 ffi::pango_layout_set_auto_dir(self.to_glib_none().0, auto_dir.into_glib());
442 }
443 }
444
445 #[doc(alias = "pango_layout_set_ellipsize")]
446 pub fn set_ellipsize(&self, ellipsize: EllipsizeMode) {
447 unsafe {
448 ffi::pango_layout_set_ellipsize(self.to_glib_none().0, ellipsize.into_glib());
449 }
450 }
451
452 #[doc(alias = "pango_layout_set_font_description")]
453 pub fn set_font_description(&self, desc: Option<&FontDescription>) {
454 unsafe {
455 ffi::pango_layout_set_font_description(self.to_glib_none().0, desc.to_glib_none().0);
456 }
457 }
458
459 #[doc(alias = "pango_layout_set_height")]
460 pub fn set_height(&self, height: i32) {
461 unsafe {
462 ffi::pango_layout_set_height(self.to_glib_none().0, height);
463 }
464 }
465
466 #[doc(alias = "pango_layout_set_indent")]
467 pub fn set_indent(&self, indent: i32) {
468 unsafe {
469 ffi::pango_layout_set_indent(self.to_glib_none().0, indent);
470 }
471 }
472
473 #[doc(alias = "pango_layout_set_justify")]
474 pub fn set_justify(&self, justify: bool) {
475 unsafe {
476 ffi::pango_layout_set_justify(self.to_glib_none().0, justify.into_glib());
477 }
478 }
479
480 #[cfg(feature = "v1_50")]
481 #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
482 #[doc(alias = "pango_layout_set_justify_last_line")]
483 pub fn set_justify_last_line(&self, justify: bool) {
484 unsafe {
485 ffi::pango_layout_set_justify_last_line(self.to_glib_none().0, justify.into_glib());
486 }
487 }
488
489 #[cfg(feature = "v1_44")]
490 #[cfg_attr(docsrs, doc(cfg(feature = "v1_44")))]
491 #[doc(alias = "pango_layout_set_line_spacing")]
492 pub fn set_line_spacing(&self, factor: f32) {
493 unsafe {
494 ffi::pango_layout_set_line_spacing(self.to_glib_none().0, factor);
495 }
496 }
497
498 #[doc(alias = "pango_layout_set_markup")]
499 pub fn set_markup(&self, markup: &str) {
500 let length = markup.len() as _;
501 unsafe {
502 ffi::pango_layout_set_markup(self.to_glib_none().0, markup.to_glib_none().0, length);
503 }
504 }
505
506 #[doc(alias = "pango_layout_set_markup_with_accel")]
507 pub fn set_markup_with_accel(&self, markup: &str, accel_marker: char) -> char {
508 let length = markup.len() as _;
509 unsafe {
510 let mut accel_char = std::mem::MaybeUninit::uninit();
511 ffi::pango_layout_set_markup_with_accel(
512 self.to_glib_none().0,
513 markup.to_glib_none().0,
514 length,
515 accel_marker.into_glib(),
516 accel_char.as_mut_ptr(),
517 );
518 std::convert::TryFrom::try_from(accel_char.assume_init())
519 .expect("conversion from an invalid Unicode value attempted")
520 }
521 }
522
523 #[doc(alias = "pango_layout_set_single_paragraph_mode")]
524 pub fn set_single_paragraph_mode(&self, setting: bool) {
525 unsafe {
526 ffi::pango_layout_set_single_paragraph_mode(self.to_glib_none().0, setting.into_glib());
527 }
528 }
529
530 #[doc(alias = "pango_layout_set_spacing")]
531 pub fn set_spacing(&self, spacing: i32) {
532 unsafe {
533 ffi::pango_layout_set_spacing(self.to_glib_none().0, spacing);
534 }
535 }
536
537 #[doc(alias = "pango_layout_set_tabs")]
538 pub fn set_tabs(&self, tabs: Option<&TabArray>) {
539 unsafe {
540 ffi::pango_layout_set_tabs(self.to_glib_none().0, mut_override(tabs.to_glib_none().0));
541 }
542 }
543
544 #[doc(alias = "pango_layout_set_text")]
545 pub fn set_text(&self, text: &str) {
546 let length = text.len() as _;
547 unsafe {
548 ffi::pango_layout_set_text(self.to_glib_none().0, text.to_glib_none().0, length);
549 }
550 }
551
552 #[doc(alias = "pango_layout_set_width")]
553 pub fn set_width(&self, width: i32) {
554 unsafe {
555 ffi::pango_layout_set_width(self.to_glib_none().0, width);
556 }
557 }
558
559 #[doc(alias = "pango_layout_set_wrap")]
560 pub fn set_wrap(&self, wrap: WrapMode) {
561 unsafe {
562 ffi::pango_layout_set_wrap(self.to_glib_none().0, wrap.into_glib());
563 }
564 }
565
566 #[cfg(feature = "v1_50")]
567 #[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
568 #[doc(alias = "pango_layout_write_to_file")]
569 pub fn write_to_file(
570 &self,
571 flags: LayoutSerializeFlags,
572 filename: impl AsRef<std::path::Path>,
573 ) -> Result<(), glib::Error> {
574 unsafe {
575 let mut error = std::ptr::null_mut();
576 let is_ok = ffi::pango_layout_write_to_file(
577 self.to_glib_none().0,
578 flags.into_glib(),
579 filename.as_ref().to_glib_none().0,
580 &mut error,
581 );
582 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
583 if error.is_null() {
584 Ok(())
585 } else {
586 Err(from_glib_full(error))
587 }
588 }
589 }
590
591 #[doc(alias = "pango_layout_xy_to_index")]
592 pub fn xy_to_index(&self, x: i32, y: i32) -> (bool, i32, i32) {
593 unsafe {
594 let mut index_ = std::mem::MaybeUninit::uninit();
595 let mut trailing = std::mem::MaybeUninit::uninit();
596 let ret = from_glib(ffi::pango_layout_xy_to_index(
597 self.to_glib_none().0,
598 x,
599 y,
600 index_.as_mut_ptr(),
601 trailing.as_mut_ptr(),
602 ));
603 (ret, index_.assume_init(), trailing.assume_init())
604 }
605 }
606}