1use crate::sys;
23#[derive(Clone, Eq, PartialEq, Debug)]
4enum FontGlyphRangeData {
5 ChineseSimplifiedCommon,
6 ChineseFull,
7 Cyrillic,
8 Default,
9 Japanese,
10 Korean,
11 Thai,
12 Vietnamese,
13 Custom(*const sys::ImWchar),
14}
1516/// A set of 16-bit Unicode codepoints
17#[derive(Clone, Eq, PartialEq, Debug)]
18pub struct FontGlyphRanges(FontGlyphRangeData);
19impl FontGlyphRanges {
20/// The default set of glyph ranges used by imgui.
21pub fn default() -> FontGlyphRanges {
22 FontGlyphRanges(FontGlyphRangeData::Default)
23 }
24/// A set of glyph ranges appropriate for use with simplified common Chinese text.
25pub fn chinese_simplified_common() -> FontGlyphRanges {
26 FontGlyphRanges(FontGlyphRangeData::ChineseSimplifiedCommon)
27 }
28/// A set of glyph ranges appropriate for use with Chinese text.
29pub fn chinese_full() -> FontGlyphRanges {
30 FontGlyphRanges(FontGlyphRangeData::ChineseFull)
31 }
32/// A set of glyph ranges appropriate for use with Cyrillic text.
33pub fn cyrillic() -> FontGlyphRanges {
34 FontGlyphRanges(FontGlyphRangeData::Cyrillic)
35 }
36/// A set of glyph ranges appropriate for use with Japanese text.
37pub fn japanese() -> FontGlyphRanges {
38 FontGlyphRanges(FontGlyphRangeData::Japanese)
39 }
40/// A set of glyph ranges appropriate for use with Korean text.
41pub fn korean() -> FontGlyphRanges {
42 FontGlyphRanges(FontGlyphRangeData::Korean)
43 }
44/// A set of glyph ranges appropriate for use with Thai text.
45pub fn thai() -> FontGlyphRanges {
46 FontGlyphRanges(FontGlyphRangeData::Thai)
47 }
48/// A set of glyph ranges appropriate for use with Vietnamese text.
49pub fn vietnamese() -> FontGlyphRanges {
50 FontGlyphRanges(FontGlyphRangeData::Vietnamese)
51 }
5253/// Creates a glyph range from a static slice. The expected format is a series of pairs of
54 /// non-zero shorts, each representing an inclusive range of codepoints, followed by a single
55 /// zero terminating the range. The ranges must not overlap.
56 ///
57 /// As the slice is expected to last as long as a font is used, and is written into global
58 /// state, it must be `'static`.
59 ///
60 /// Panics
61 /// ======
62 ///
63 /// This function will panic if the given slice is not a valid font range.
64pub fn from_slice(slice: &'static [u16]) -> FontGlyphRanges {
65assert_eq!(
66 slice.len() % 2,
671,
68"The length of a glyph range must be odd."
69);
70assert_eq!(
71 slice.last(),
72Some(&0),
73"A glyph range must be zero-terminated."
74);
7576for (i, &glyph) in slice.iter().enumerate().take(slice.len() - 1) {
77assert_ne!(
78 glyph, 0,
79"A glyph in a range cannot be zero. \
80 (Glyph is zero at index {})",
81 i
82 )
83 }
8485let mut ranges = Vec::new();
86for i in 0..slice.len() / 2 {
87let (start, end) = (slice[i * 2], slice[i * 2 + 1]);
88assert!(
89 start <= end,
90"The start of a range cannot be larger than its end. \
91 (At index {}, {} > {})",
92 i * 2,
93 start,
94 end
95 );
96 ranges.push((start, end));
97 }
98 ranges.sort_unstable_by_key(|x| x.0);
99for i in 0..ranges.len() - 1 {
100let (range_a, range_b) = (ranges[i], ranges[i + 1]);
101if range_a.1 >= range_b.0 {
102panic!(
103"The glyph ranges {:?} and {:?} overlap between {:?}.",
104 range_a,
105 range_b,
106 (range_a.1, range_b.0)
107 );
108 }
109 }
110111unsafe { FontGlyphRanges::from_slice_unchecked(slice) }
112 }
113114/// Creates a glyph range from a static slice without checking its validity.
115 ///
116 /// See [`FontGlyphRanges::from_slice`] for more information.
117 ///
118 /// # Safety
119 ///
120 /// It is up to the caller to guarantee the slice contents are valid.
121pub unsafe fn from_slice_unchecked(slice: &'static [u16]) -> FontGlyphRanges {
122 FontGlyphRanges::from_ptr(slice.as_ptr())
123 }
124125/// Creates a glyph range from a pointer, without checking its validity or enforcing its
126 /// lifetime. The memory the pointer points to must be valid for as long as the font is
127 /// in use.
128 ///
129 /// # Safety
130 ///
131 /// It is up to the caller to guarantee the pointer is not null, remains valid forever, and
132 /// points to valid data.
133pub unsafe fn from_ptr(ptr: *const u16) -> FontGlyphRanges {
134 FontGlyphRanges(FontGlyphRangeData::Custom(ptr))
135 }
136137pub(crate) unsafe fn to_ptr(&self, atlas: *mut sys::ImFontAtlas) -> *const sys::ImWchar {
138match self.0 {
139 FontGlyphRangeData::ChineseFull => sys::ImFontAtlas_GetGlyphRangesChineseFull(atlas),
140 FontGlyphRangeData::ChineseSimplifiedCommon => {
141 sys::ImFontAtlas_GetGlyphRangesChineseSimplifiedCommon(atlas)
142 }
143 FontGlyphRangeData::Cyrillic => sys::ImFontAtlas_GetGlyphRangesCyrillic(atlas),
144 FontGlyphRangeData::Default => sys::ImFontAtlas_GetGlyphRangesDefault(atlas),
145 FontGlyphRangeData::Japanese => sys::ImFontAtlas_GetGlyphRangesJapanese(atlas),
146 FontGlyphRangeData::Korean => sys::ImFontAtlas_GetGlyphRangesKorean(atlas),
147 FontGlyphRangeData::Thai => sys::ImFontAtlas_GetGlyphRangesThai(atlas),
148 FontGlyphRangeData::Vietnamese => sys::ImFontAtlas_GetGlyphRangesVietnamese(atlas),
149 FontGlyphRangeData::Custom(ptr) => ptr,
150 }
151 }
152}