Skip to content

Commit

Permalink
Update non-sys code to handle 32-bit characters
Browse files Browse the repository at this point in the history
  • Loading branch information
thomcc committed Apr 6, 2021
1 parent 083139e commit b739b93
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 10 deletions.
3 changes: 2 additions & 1 deletion imgui/src/fonts/atlas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,8 @@ impl FontConfig {
raw.GlyphMaxAdvanceX = self.glyph_max_advance_x;
raw.FontBuilderFlags = self.font_builder_flags;
raw.RasterizerMultiply = self.rasterizer_multiply;
raw.EllipsisChar = self.ellipsis_char.map(|x| x as u16).unwrap_or(0xffff);
// char is used as "unset" for EllipsisChar
raw.EllipsisChar = self.ellipsis_char.map(|c| c as u32).unwrap_or(!0);
if let Some(name) = self.name.as_ref() {
let bytes = name.as_bytes();
let mut len = bytes.len().min(raw.Name.len() - 1);
Expand Down
2 changes: 1 addition & 1 deletion imgui/src/fonts/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct Font {
pub ascent: f32,
pub descent: f32,
pub metrics_total_surface: c_int,
pub used_4k_pages_map: [u8; 2],
pub used_4k_pages_map: [u8; 34],
}

unsafe impl RawCast<sys::ImFont> for Font {}
Expand Down
24 changes: 18 additions & 6 deletions imgui/src/fonts/glyph_ranges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ enum FontGlyphRangeData {
Custom(*const sys::ImWchar),
}

/// A set of 16-bit Unicode codepoints
/// A set of Unicode codepoints
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct FontGlyphRanges(FontGlyphRangeData);
impl FontGlyphRanges {
Expand Down Expand Up @@ -51,7 +51,7 @@ impl FontGlyphRanges {
}

/// Creates a glyph range from a static slice. The expected format is a series of pairs of
/// non-zero shorts, each representing an inclusive range of codepoints, followed by a single
/// non-zero codepoints, each representing an inclusive range, followed by a single
/// zero terminating the range. The ranges must not overlap.
///
/// As the slice is expected to last as long as a font is used, and is written into global
Expand All @@ -61,7 +61,12 @@ impl FontGlyphRanges {
/// ======
///
/// This function will panic if the given slice is not a valid font range.
pub fn from_slice(slice: &'static [u16]) -> FontGlyphRanges {
// TODO(thom): This takes `u32` for now, since I believe it's fine for it to
// contain surrogates? (It seems plausible that font data can describe what
// to show for unpaired surrogates) Would be nice to be sure, if so, this
// should accept `char` (we'd still have to check that the range doesn't
// fully contain the surrogate range though)
pub fn from_slice(slice: &'static [u32]) -> FontGlyphRanges {
assert_eq!(
slice.len() % 2,
1,
Expand All @@ -79,7 +84,14 @@ impl FontGlyphRanges {
"A glyph in a range cannot be zero. \
(Glyph is zero at index {})",
i
)
);
assert!(
glyph <= core::char::MAX as u32,
"A glyph in a range cannot exceed the maximum codepoint. \
(Glyph is {:#x} at index {})",
glyph,
i,
);
}

let mut ranges = Vec::new();
Expand Down Expand Up @@ -118,7 +130,7 @@ impl FontGlyphRanges {
/// # Safety
///
/// It is up to the caller to guarantee the slice contents are valid.
pub unsafe fn from_slice_unchecked(slice: &'static [u16]) -> FontGlyphRanges {
pub unsafe fn from_slice_unchecked(slice: &'static [u32]) -> FontGlyphRanges {
FontGlyphRanges::from_ptr(slice.as_ptr())
}

Expand All @@ -130,7 +142,7 @@ impl FontGlyphRanges {
///
/// It is up to the caller to guarantee the pointer is not null, remains valid forever, and
/// points to valid data.
pub unsafe fn from_ptr(ptr: *const u16) -> FontGlyphRanges {
pub unsafe fn from_ptr(ptr: *const u32) -> FontGlyphRanges {
FontGlyphRanges(FontGlyphRangeData::Custom(ptr))
}

Expand Down
20 changes: 18 additions & 2 deletions imgui/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,25 @@ impl Io {
}
/// Peek character input buffer, return a copy of entire buffer
pub fn peek_input_characters(&self) -> String {
let c16_slice = self.input_queue_characters.as_slice();
String::from_utf16(c16_slice).unwrap()
self.input_queue_characters().collect()
}

/// Returns a view of the data in the input queue (without copying it).
///
/// The returned iterator is a simple mapping over a slice more or less what
/// you need for random access to the data (Rust has no
/// `RandomAccessIterator`, or we'd use that).
pub fn input_queue_characters(
&self,
) -> impl Iterator<Item = char> + DoubleEndedIterator + ExactSizeIterator + Clone + '_ {
self.input_queue_characters
.as_slice()
.iter()
// TODO: are the values in the buffer guaranteed to be valid unicode
// scalar values? if so we can just expose this as a `&[char]`...
.map(|c| core::char::from_u32(*c).unwrap_or(core::char::REPLACEMENT_CHARACTER))
}

pub fn update_delta_time(&mut self, delta: Duration) {
let delta_s = delta.as_secs() as f32 + delta.subsec_nanos() as f32 / 1_000_000_000.0;
if delta_s > 0.0 {
Expand Down

0 comments on commit b739b93

Please sign in to comment.