pango/auto/functions.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
5use crate::{
6 ffi, Analysis, AttrIterator, AttrList, Context, Direction, GlyphString, Item, Stretch, Style,
7 Variant, Weight,
8};
9use glib::translate::*;
10
11//#[cfg_attr(feature = "v1_44", deprecated = "Since 1.44")]
12//#[allow(deprecated)]
13//#[doc(alias = "pango_break")]
14//#[doc(alias = "break")]
15//pub fn break_(text: &str, analysis: &mut Analysis, attrs: /*Ignored*/&[LogAttr]) {
16// unsafe { TODO: call ffi:pango_break() }
17//}
18
19//#[doc(alias = "pango_default_break")]
20//pub fn default_break(text: &str, analysis: Option<&mut Analysis>, attrs: /*Ignored*/&mut LogAttr, attrs_len: i32) {
21// unsafe { TODO: call ffi:pango_default_break() }
22//}
23
24/// Searches a string the first character that has a strong
25/// direction, according to the Unicode bidirectional algorithm.
26/// ## `text`
27/// the text to process. Must be valid UTF-8
28/// ## `length`
29/// length of @text in bytes (may be -1 if @text is nul-terminated)
30///
31/// # Returns
32///
33/// The direction corresponding to the first strong character.
34/// If no such character is found, then [`Direction::Neutral`][crate::Direction::Neutral] is returned.
35#[doc(alias = "pango_find_base_dir")]
36pub fn find_base_dir(text: &str) -> Direction {
37 let length = text.len() as _;
38 unsafe { from_glib(ffi::pango_find_base_dir(text.to_glib_none().0, length)) }
39}
40
41/// Locates a paragraph boundary in @text.
42///
43/// A boundary is caused by delimiter characters, such as
44/// a newline, carriage return, carriage return-newline pair,
45/// or Unicode paragraph separator character.
46///
47/// The index of the run of delimiters is returned in
48/// @paragraph_delimiter_index. The index of the start of the
49/// next paragraph (index after all delimiters) is stored n
50/// @next_paragraph_start.
51///
52/// If no delimiters are found, both @paragraph_delimiter_index
53/// and @next_paragraph_start are filled with the length of @text
54/// (an index one off the end).
55/// ## `text`
56/// UTF-8 text
57/// ## `length`
58/// length of @text in bytes, or -1 if nul-terminated
59///
60/// # Returns
61///
62///
63/// ## `paragraph_delimiter_index`
64/// return location for index of
65/// delimiter
66///
67/// ## `next_paragraph_start`
68/// return location for start of next
69/// paragraph
70#[doc(alias = "pango_find_paragraph_boundary")]
71pub fn find_paragraph_boundary(text: &str) -> (i32, i32) {
72 let length = text.len() as _;
73 unsafe {
74 let mut paragraph_delimiter_index = std::mem::MaybeUninit::uninit();
75 let mut next_paragraph_start = std::mem::MaybeUninit::uninit();
76 ffi::pango_find_paragraph_boundary(
77 text.to_glib_none().0,
78 length,
79 paragraph_delimiter_index.as_mut_ptr(),
80 next_paragraph_start.as_mut_ptr(),
81 );
82 (
83 paragraph_delimiter_index.assume_init(),
84 next_paragraph_start.assume_init(),
85 )
86 }
87}
88
89//#[doc(alias = "pango_get_log_attrs")]
90//#[doc(alias = "get_log_attrs")]
91//pub fn log_attrs(text: &str, level: i32, language: &mut Language, attrs: /*Ignored*/&[LogAttr]) {
92// unsafe { TODO: call ffi:pango_get_log_attrs() }
93//}
94
95/// Checks if a character that should not be normally rendered.
96///
97/// This includes all Unicode characters with "ZERO WIDTH" in their name,
98/// as well as *bidi* formatting characters, and a few other ones.
99///
100/// This is totally different from `unichar_iszerowidth()` and is at best misnamed.
101/// ## `ch`
102/// a Unicode character
103///
104/// # Returns
105///
106/// [`true`] if @ch is a zero-width character, [`false`] otherwise
107#[doc(alias = "pango_is_zero_width")]
108pub fn is_zero_width(ch: char) -> bool {
109 unsafe { from_glib(ffi::pango_is_zero_width(ch.into_glib())) }
110}
111
112/// Breaks a piece of text into segments with consistent directional
113/// level and font.
114///
115/// Each byte of @text will be contained in exactly one of the items in the
116/// returned list; the generated list of items will be in logical order (the
117/// start offsets of the items are ascending).
118///
119/// @cached_iter should be an iterator over @attrs currently positioned
120/// at a range before or containing @start_index; @cached_iter will be
121/// advanced to the range covering the position just after
122/// @start_index + @length. (i.e. if itemizing in a loop, just keep passing
123/// in the same @cached_iter).
124/// ## `context`
125/// a structure holding information that affects
126/// the itemization process.
127/// ## `text`
128/// the text to itemize. Must be valid UTF-8
129/// ## `start_index`
130/// first byte in @text to process
131/// ## `length`
132/// the number of bytes (not characters) to process
133/// after @start_index. This must be >= 0.
134/// ## `attrs`
135/// the set of attributes that apply to @text.
136/// ## `cached_iter`
137/// Cached attribute iterator
138///
139/// # Returns
140///
141/// a `GList` of
142/// [`Item`][crate::Item] structures. The items should be freed using
143/// `Pango::Item::free()` in combination with `GLib::List::free_full()`.
144#[doc(alias = "pango_itemize")]
145pub fn itemize(
146 context: &Context,
147 text: &str,
148 start_index: i32,
149 length: i32,
150 attrs: &AttrList,
151 cached_iter: Option<&AttrIterator>,
152) -> Vec<Item> {
153 unsafe {
154 FromGlibPtrContainer::from_glib_full(ffi::pango_itemize(
155 context.to_glib_none().0,
156 text.to_glib_none().0,
157 start_index,
158 length,
159 attrs.to_glib_none().0,
160 mut_override(cached_iter.to_glib_none().0),
161 ))
162 }
163}
164
165/// Like `pango_itemize()`, but with an explicitly specified base direction.
166///
167/// The base direction is used when computing bidirectional levels.
168/// [`itemize()`][crate::itemize()] gets the base direction from the [`Context`][crate::Context]
169/// (see [`Context::set_base_dir()`][crate::Context::set_base_dir()]).
170/// ## `context`
171/// a structure holding information that affects
172/// the itemization process.
173/// ## `base_dir`
174/// base direction to use for bidirectional processing
175/// ## `text`
176/// the text to itemize.
177/// ## `start_index`
178/// first byte in @text to process
179/// ## `length`
180/// the number of bytes (not characters) to process
181/// after @start_index. This must be >= 0.
182/// ## `attrs`
183/// the set of attributes that apply to @text.
184/// ## `cached_iter`
185/// Cached attribute iterator
186///
187/// # Returns
188///
189/// a `GList` of
190/// [`Item`][crate::Item] structures. The items should be freed using
191/// `Pango::Item::free()` probably in combination with `GLib::List::free_full()`.
192#[doc(alias = "pango_itemize_with_base_dir")]
193pub fn itemize_with_base_dir(
194 context: &Context,
195 base_dir: Direction,
196 text: &str,
197 start_index: i32,
198 length: i32,
199 attrs: &AttrList,
200 cached_iter: Option<&AttrIterator>,
201) -> Vec<Item> {
202 unsafe {
203 FromGlibPtrContainer::from_glib_full(ffi::pango_itemize_with_base_dir(
204 context.to_glib_none().0,
205 base_dir.into_glib(),
206 text.to_glib_none().0,
207 start_index,
208 length,
209 attrs.to_glib_none().0,
210 mut_override(cached_iter.to_glib_none().0),
211 ))
212 }
213}
214
215/// Finishes parsing markup.
216///
217/// After feeding a Pango markup parser some data with [`glib::MarkupParseContext::parse()`][crate::glib::MarkupParseContext::parse()],
218/// use this function to get the list of attributes and text out of the
219/// markup. This function will not free @context, use `GLib::MarkupParseContext::free()`
220/// to do so.
221/// ## `context`
222/// A valid parse context that was returned from [`markup_parser_new()`][crate::markup_parser_new()]
223///
224/// # Returns
225///
226/// [`false`] if @error is set, otherwise [`true`]
227///
228/// ## `attr_list`
229/// address of return location for a [`AttrList`][crate::AttrList]
230///
231/// ## `text`
232/// address of return location for text with tags stripped
233///
234/// ## `accel_char`
235/// address of return location for accelerator char
236#[doc(alias = "pango_markup_parser_finish")]
237pub fn markup_parser_finish(
238 context: &glib::MarkupParseContext,
239) -> Result<(AttrList, glib::GString, char), glib::Error> {
240 unsafe {
241 let mut attr_list = std::ptr::null_mut();
242 let mut text = std::ptr::null_mut();
243 let mut accel_char = std::mem::MaybeUninit::uninit();
244 let mut error = std::ptr::null_mut();
245 let is_ok = ffi::pango_markup_parser_finish(
246 context.to_glib_none().0,
247 &mut attr_list,
248 &mut text,
249 accel_char.as_mut_ptr(),
250 &mut error,
251 );
252 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
253 if error.is_null() {
254 Ok((
255 from_glib_full(attr_list),
256 from_glib_full(text),
257 std::convert::TryFrom::try_from(accel_char.assume_init())
258 .expect("conversion from an invalid Unicode value attempted"),
259 ))
260 } else {
261 Err(from_glib_full(error))
262 }
263 }
264}
265
266/// Incrementally parses marked-up text to create a plain-text string
267/// and an attribute list.
268///
269/// See the [Pango Markup](pango_markup.html) docs for details about the
270/// supported markup.
271///
272/// If @accel_marker is nonzero, the given character will mark the
273/// character following it as an accelerator. For example, @accel_marker
274/// might be an ampersand or underscore. All characters marked
275/// as an accelerator will receive a [`Underline::Low`][crate::Underline::Low] attribute,
276/// and the first character so marked will be returned in @accel_char,
277/// when calling [`markup_parser_finish()`][crate::markup_parser_finish()]. Two @accel_marker characters
278/// following each other produce a single literal @accel_marker character.
279///
280/// To feed markup to the parser, use [`glib::MarkupParseContext::parse()`][crate::glib::MarkupParseContext::parse()]
281/// on the returned [`glib::MarkupParseContext`][crate::glib::MarkupParseContext]. When done with feeding markup
282/// to the parser, use [`markup_parser_finish()`][crate::markup_parser_finish()] to get the data out
283/// of it, and then use `GLib::MarkupParseContext::free()` to free it.
284///
285/// This function is designed for applications that read Pango markup
286/// from streams. To simply parse a string containing Pango markup,
287/// the [`parse_markup()`][crate::parse_markup()] API is recommended instead.
288/// ## `accel_marker`
289/// character that precedes an accelerator, or 0 for none
290///
291/// # Returns
292///
293/// a `GMarkupParseContext` that should be
294/// destroyed with `GLib::MarkupParseContext::free()`.
295#[doc(alias = "pango_markup_parser_new")]
296pub fn markup_parser_new(accel_marker: char) -> glib::MarkupParseContext {
297 unsafe { from_glib_none(ffi::pango_markup_parser_new(accel_marker.into_glib())) }
298}
299
300/// Parses marked-up text to create a plain-text string and an attribute list.
301///
302/// See the [Pango Markup](pango_markup.html) docs for details about the
303/// supported markup.
304///
305/// If @accel_marker is nonzero, the given character will mark the
306/// character following it as an accelerator. For example, @accel_marker
307/// might be an ampersand or underscore. All characters marked
308/// as an accelerator will receive a [`Underline::Low`][crate::Underline::Low] attribute,
309/// and the first character so marked will be returned in @accel_char.
310/// Two @accel_marker characters following each other produce a single
311/// literal @accel_marker character.
312///
313/// To parse a stream of pango markup incrementally, use [`markup_parser_new()`][crate::markup_parser_new()].
314///
315/// If any error happens, none of the output arguments are touched except
316/// for @error.
317/// ## `markup_text`
318/// markup to parse (see the [Pango Markup](pango_markup.html) docs)
319/// ## `length`
320/// length of @markup_text, or -1 if nul-terminated
321/// ## `accel_marker`
322/// character that precedes an accelerator, or 0 for none
323///
324/// # Returns
325///
326/// [`false`] if @error is set, otherwise [`true`]
327///
328/// ## `attr_list`
329/// address of return location for a [`AttrList`][crate::AttrList]
330///
331/// ## `text`
332/// address of return location for text with tags stripped
333///
334/// ## `accel_char`
335/// address of return location for accelerator char
336#[doc(alias = "pango_parse_markup")]
337pub fn parse_markup(
338 markup_text: &str,
339 accel_marker: char,
340) -> Result<(AttrList, glib::GString, char), glib::Error> {
341 let length = markup_text.len() as _;
342 unsafe {
343 let mut attr_list = std::ptr::null_mut();
344 let mut text = std::ptr::null_mut();
345 let mut accel_char = std::mem::MaybeUninit::uninit();
346 let mut error = std::ptr::null_mut();
347 let is_ok = ffi::pango_parse_markup(
348 markup_text.to_glib_none().0,
349 length,
350 accel_marker.into_glib(),
351 &mut attr_list,
352 &mut text,
353 accel_char.as_mut_ptr(),
354 &mut error,
355 );
356 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
357 if error.is_null() {
358 Ok((
359 from_glib_full(attr_list),
360 from_glib_full(text),
361 std::convert::TryFrom::try_from(accel_char.assume_init())
362 .expect("conversion from an invalid Unicode value attempted"),
363 ))
364 } else {
365 Err(from_glib_full(error))
366 }
367 }
368}
369
370/// Parses a font stretch.
371///
372/// The allowed values are
373/// "ultra_condensed", "extra_condensed", "condensed",
374/// "semi_condensed", "normal", "semi_expanded", "expanded",
375/// "extra_expanded" and "ultra_expanded". Case variations are
376/// ignored and the '_' characters may be omitted.
377/// ## `str`
378/// a string to parse.
379/// ## `warn`
380/// if [`true`], issue a g_warning() on bad input.
381///
382/// # Returns
383///
384/// [`true`] if @str was successfully parsed.
385///
386/// ## `stretch`
387/// a [`Stretch`][crate::Stretch] to store the result in.
388#[doc(alias = "pango_parse_stretch")]
389pub fn parse_stretch(str: &str, warn: bool) -> Option<Stretch> {
390 unsafe {
391 let mut stretch = std::mem::MaybeUninit::uninit();
392 let ret = from_glib(ffi::pango_parse_stretch(
393 str.to_glib_none().0,
394 stretch.as_mut_ptr(),
395 warn.into_glib(),
396 ));
397 if ret {
398 Some(from_glib(stretch.assume_init()))
399 } else {
400 None
401 }
402 }
403}
404
405/// Parses a font style.
406///
407/// The allowed values are "normal", "italic" and "oblique", case
408/// variations being
409/// ignored.
410/// ## `str`
411/// a string to parse.
412/// ## `warn`
413/// if [`true`], issue a g_warning() on bad input.
414///
415/// # Returns
416///
417/// [`true`] if @str was successfully parsed.
418///
419/// ## `style`
420/// a [`Style`][crate::Style] to store the result in.
421#[doc(alias = "pango_parse_style")]
422pub fn parse_style(str: &str, warn: bool) -> Option<Style> {
423 unsafe {
424 let mut style = std::mem::MaybeUninit::uninit();
425 let ret = from_glib(ffi::pango_parse_style(
426 str.to_glib_none().0,
427 style.as_mut_ptr(),
428 warn.into_glib(),
429 ));
430 if ret {
431 Some(from_glib(style.assume_init()))
432 } else {
433 None
434 }
435 }
436}
437
438/// Parses a font variant.
439///
440/// The allowed values are "normal", "small-caps", "all-small-caps",
441/// "petite-caps", "all-petite-caps", "unicase" and "title-caps",
442/// case variations being ignored.
443/// ## `str`
444/// a string to parse.
445/// ## `warn`
446/// if [`true`], issue a g_warning() on bad input.
447///
448/// # Returns
449///
450/// [`true`] if @str was successfully parsed.
451///
452/// ## `variant`
453/// a [`Variant`][struct@crate::Variant] to store the result in.
454#[doc(alias = "pango_parse_variant")]
455pub fn parse_variant(str: &str, warn: bool) -> Option<Variant> {
456 unsafe {
457 let mut variant = std::mem::MaybeUninit::uninit();
458 let ret = from_glib(ffi::pango_parse_variant(
459 str.to_glib_none().0,
460 variant.as_mut_ptr(),
461 warn.into_glib(),
462 ));
463 if ret {
464 Some(from_glib(variant.assume_init()))
465 } else {
466 None
467 }
468 }
469}
470
471/// Parses a font weight.
472///
473/// The allowed values are "heavy",
474/// "ultrabold", "bold", "normal", "light", "ultraleight"
475/// and integers. Case variations are ignored.
476/// ## `str`
477/// a string to parse.
478/// ## `warn`
479/// if [`true`], issue a g_warning() on bad input.
480///
481/// # Returns
482///
483/// [`true`] if @str was successfully parsed.
484///
485/// ## `weight`
486/// a [`Weight`][crate::Weight] to store the result in.
487#[doc(alias = "pango_parse_weight")]
488pub fn parse_weight(str: &str, warn: bool) -> Option<Weight> {
489 unsafe {
490 let mut weight = std::mem::MaybeUninit::uninit();
491 let ret = from_glib(ffi::pango_parse_weight(
492 str.to_glib_none().0,
493 weight.as_mut_ptr(),
494 warn.into_glib(),
495 ));
496 if ret {
497 Some(from_glib(weight.assume_init()))
498 } else {
499 None
500 }
501 }
502}
503
504/// Quantizes the thickness and position of a line to whole device pixels.
505///
506/// This is typically used for underline or strikethrough. The purpose of
507/// this function is to avoid such lines looking blurry.
508///
509/// Care is taken to make sure @thickness is at least one pixel when this
510/// function returns, but returned @position may become zero as a result
511/// of rounding.
512/// ## `thickness`
513/// pointer to the thickness of a line, in Pango units
514/// ## `position`
515/// corresponding position
516#[doc(alias = "pango_quantize_line_geometry")]
517pub fn quantize_line_geometry(thickness: &mut i32, position: &mut i32) {
518 unsafe {
519 ffi::pango_quantize_line_geometry(thickness, position);
520 }
521}
522
523/// Convert the characters in @text into glyphs.
524///
525/// Given a segment of text and the corresponding [`Analysis`][crate::Analysis] structure
526/// returned from [`itemize()`][crate::itemize()], convert the characters into glyphs. You
527/// may also pass in only a substring of the item from [`itemize()`][crate::itemize()].
528///
529/// It is recommended that you use [`shape_full()`][crate::shape_full()] instead, since
530/// that API allows for shaping interaction happening across text item
531/// boundaries.
532///
533/// Some aspects of hyphen insertion and text transformation (in particular,
534/// capitalization) require log attrs, and thus can only be handled by
535/// `shape_item()`.
536///
537/// Note that the extra attributes in the @analyis that is returned from
538/// [`itemize()`][crate::itemize()] have indices that are relative to the entire paragraph,
539/// so you need to subtract the item offset from their indices before
540/// calling [`shape()`][crate::shape()].
541/// ## `text`
542/// the text to process
543/// ## `length`
544/// the length (in bytes) of @text
545/// ## `analysis`
546/// [`Analysis`][crate::Analysis] structure from [`itemize()`][crate::itemize()]
547/// ## `glyphs`
548/// glyph string in which to store results
549#[doc(alias = "pango_shape")]
550pub fn shape(text: &str, analysis: &Analysis, glyphs: &mut GlyphString) {
551 let length = text.len() as _;
552 unsafe {
553 ffi::pango_shape(
554 text.to_glib_none().0,
555 length,
556 analysis.to_glib_none().0,
557 glyphs.to_glib_none_mut().0,
558 );
559 }
560}
561
562//#[cfg(feature = "v1_50")]
563//#[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
564//#[doc(alias = "pango_shape_item")]
565//pub fn shape_item(item: &mut Item, paragraph_text: Option<&str>, log_attrs: /*Ignored*/Option<&mut LogAttr>, glyphs: &mut GlyphString, flags: ShapeFlags) {
566// unsafe { TODO: call ffi:pango_shape_item() }
567//}
568
569//#[cfg(feature = "v1_44")]
570//#[cfg_attr(docsrs, doc(cfg(feature = "v1_44")))]
571//#[doc(alias = "pango_tailor_break")]
572//pub fn tailor_break(text: &str, analysis: &mut Analysis, offset: i32, attrs: /*Ignored*/&[LogAttr]) {
573// unsafe { TODO: call ffi:pango_tailor_break() }
574//}
575
576/// Determines the inherent direction of a character.
577///
578/// The inherent direction is either `PANGO_DIRECTION_LTR`, `PANGO_DIRECTION_RTL`,
579/// or `PANGO_DIRECTION_NEUTRAL`.
580///
581/// This function is useful to categorize characters into left-to-right
582/// letters, right-to-left letters, and everything else. If full Unicode
583/// bidirectional type of a character is needed, [`BidiType::for_unichar()`][crate::BidiType::for_unichar()]
584/// can be used instead.
585/// ## `ch`
586/// a Unicode character
587///
588/// # Returns
589///
590/// the direction of the character.
591#[doc(alias = "pango_unichar_direction")]
592pub fn unichar_direction(ch: char) -> Direction {
593 unsafe { from_glib(ffi::pango_unichar_direction(ch.into_glib())) }
594}
595
596/// Converts a floating-point number to Pango units.
597///
598/// The conversion is done by multiplying @d by `PANGO_SCALE` and
599/// rounding the result to nearest integer.
600/// ## `d`
601/// double floating-point value
602///
603/// # Returns
604///
605/// the value in Pango units.
606#[doc(alias = "pango_units_from_double")]
607pub fn units_from_double(d: f64) -> i32 {
608 unsafe { ffi::pango_units_from_double(d) }
609}
610
611/// Converts a number in Pango units to floating-point.
612///
613/// The conversion is done by dividing @i by `PANGO_SCALE`.
614/// ## `i`
615/// value in Pango units
616///
617/// # Returns
618///
619/// the double value.
620#[doc(alias = "pango_units_to_double")]
621pub fn units_to_double(i: i32) -> f64 {
622 unsafe { ffi::pango_units_to_double(i) }
623}
624
625/// Returns the encoded version of Pango available at run-time.
626///
627/// This is similar to the macro `PANGO_VERSION` except that the macro
628/// returns the encoded version available at compile-time. A version
629/// number can be encoded into an integer using PANGO_VERSION_ENCODE().
630///
631/// # Returns
632///
633/// The encoded version of Pango library available at run time.
634#[doc(alias = "pango_version")]
635pub fn version() -> i32 {
636 unsafe { ffi::pango_version() }
637}
638
639/// Checks that the Pango library in use is compatible with the
640/// given version.
641///
642/// Generally you would pass in the constants `PANGO_VERSION_MAJOR`,
643/// `PANGO_VERSION_MINOR`, `PANGO_VERSION_MICRO` as the three arguments
644/// to this function; that produces a check that the library in use at
645/// run-time is compatible with the version of Pango the application or
646/// module was compiled against.
647///
648/// Compatibility is defined by two things: first the version
649/// of the running library is newer than the version
650/// @required_major.required_minor.@required_micro. Second
651/// the running library must be binary compatible with the
652/// version @required_major.required_minor.@required_micro
653/// (same major version.)
654///
655/// For compile-time version checking use PANGO_VERSION_CHECK().
656/// ## `required_major`
657/// the required major version
658/// ## `required_minor`
659/// the required minor version
660/// ## `required_micro`
661/// the required major version
662///
663/// # Returns
664///
665/// [`None`] if the Pango library is compatible
666/// with the given version, or a string describing the version
667/// mismatch. The returned string is owned by Pango and should not
668/// be modified or freed.
669#[doc(alias = "pango_version_check")]
670pub fn version_check(
671 required_major: i32,
672 required_minor: i32,
673 required_micro: i32,
674) -> Option<glib::GString> {
675 unsafe {
676 from_glib_none(ffi::pango_version_check(
677 required_major,
678 required_minor,
679 required_micro,
680 ))
681 }
682}
683
684/// Returns the version of Pango available at run-time.
685///
686/// This is similar to the macro `PANGO_VERSION_STRING` except that the
687/// macro returns the version available at compile-time.
688///
689/// # Returns
690///
691/// A string containing the version of Pango library available
692/// at run time. The returned string is owned by Pango and should not
693/// be modified or freed.
694#[doc(alias = "pango_version_string")]
695pub fn version_string() -> glib::GString {
696 unsafe { from_glib_none(ffi::pango_version_string()) }
697}