Update non-sys code to handle 32-bit characters

This commit is contained in:
Thom Chiovoloni 2021-04-05 15:50:46 -07:00
parent 083139e4e6
commit b739b9380b
4 changed files with 39 additions and 10 deletions

View File

@ -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);

View File

@ -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 {}

View File

@ -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 {
@ -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
@ -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,
@ -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();
@ -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())
}
@ -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))
}

View File

@ -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 {