mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Support wide characters in TextViews
Added some japanese paragraphs to the lorem example.
This commit is contained in:
parent
cc72aa4ddc
commit
4498d206f5
@ -37,3 +37,23 @@ Sed vitae rhoncus velit. Proin eu luctus libero. Interdum et malesuada fames ac
|
|||||||
Ιυς ιν διαμ μαλυισετ σορρυμπιθ. Οδιο σπλενδιδε σιθ ατ, νες εραθ λατινε ατ. Νες εξ ποσιμ δεσερυισε. Ευμ εξ τιβικυε νωμιναφι αππαρεατ, ωφφενδιθ ευριπιδις ιδ ιυς, σιθ σαεπε μολεστιε εα. Φις χαρυμ κυοδσι ευ. Περτινασια λιβεραφισε σεα ιδ. Φιξ ηαβεο εραντ φιθαε υθ, δολορ δοσθυς ιν κυι, φιξ ατ σινθ σεμπερ δεφινιθιονεμ.
|
Ιυς ιν διαμ μαλυισετ σορρυμπιθ. Οδιο σπλενδιδε σιθ ατ, νες εραθ λατινε ατ. Νες εξ ποσιμ δεσερυισε. Ευμ εξ τιβικυε νωμιναφι αππαρεατ, ωφφενδιθ ευριπιδις ιδ ιυς, σιθ σαεπε μολεστιε εα. Φις χαρυμ κυοδσι ευ. Περτινασια λιβεραφισε σεα ιδ. Φιξ ηαβεο εραντ φιθαε υθ, δολορ δοσθυς ιν κυι, φιξ ατ σινθ σεμπερ δεφινιθιονεμ.
|
||||||
|
|
||||||
Ταντας νομινατι σωνσεθεθυρ ει ναμ. Ιδ φιξ πωσε λαβιθυρ νομινατι, πρινσιπες ιρασυνδια υσυ υθ, ποπυλω σονσλυσιονεμκυε φελ ιν. Αλικυανδο νεσεσιταθιβυς μελ θε, συμ ετ πριμα ρεφορμιδανς, κυοδσι περσεκυερις ετ νες. Εκυιδεμ φιφενδω πρωβατυς ηας ετ. Νε σεδ ταντας σολυτα ανιμαλ.
|
Ταντας νομινατι σωνσεθεθυρ ει ναμ. Ιδ φιξ πωσε λαβιθυρ νομινατι, πρινσιπες ιρασυνδια υσυ υθ, ποπυλω σονσλυσιονεμκυε φελ ιν. Αλικυανδο νεσεσιταθιβυς μελ θε, συμ ετ πριμα ρεφορμιδανς, κυοδσι περσεκυερις ετ νες. Εκυιδεμ φιφενδω πρωβατυς ηας ετ. Νε σεδ ταντας σολυτα ανιμαλ.
|
||||||
|
|
||||||
|
私は十一月きっとそうした注意通りという事の時が云ったませ。
|
||||||
|
|
||||||
|
けっしてその間を話地ももうこの話なななどのなっていますには自失しですませて、ちょっとにはしなましでだ。がたが解らたのはもう今日をほとんどたますましょ。ちょうど大森さんをふり徳義また指導からしない尻馬その博奕私か返事からというご反対ですたましですが、どんな将来はそれか去就自己からつかて、大森さんの方へ我の私に勢いご矛盾と炙っがこれ三つにお危くにあっようによくご任命になっますんて、ようやくことに入会がするたて行くますものをなくなっですでし。だからだからごいくらをしのはこう低級と掘りうで、その人をは突き破るなてという英語にやっば下さいたです。どんな一方がたの時その個人も彼ら中に上げでかと木下さんを返っでん、相手の直接ですというご焦燥うでたけれども、本立の後が他人が当時かもの壁がたくさんおくからみるて、ずいぶんの以前に見えるてそんなついでにもちろん比べるうでとなるたらのましし、ないたですて全くお漫然考えでのなですまし。
|
||||||
|
|
||||||
|
そうして個人か新たか留学がするますて、昨日中嚢をしからならた後がご参考の事実をかかるだまし。今にはたしか飽いが云いありないだならて、もしちゃんとせよと妨害もとてもありがたいませはずなら。しかし肝#「を云っては来ならものましば、教場では、けっしてあなたかさからなりれるないたいうられるたでと見えるて、別はもつてもらいたなけれ。もしとうていはいよいよ同年輩といういるたて、私からも将来上ぐらいあなたのお意味はなく立てるいるなけれな。
|
||||||
|
|
||||||
|
彼らはもし享有の点からご話はあるているですだたでて、四二の比喩にどう会っましといった教育だろて、しかしながらその申の文章に云われば、あなたかを私の権力を影響をしてくれたものないないと評見るて独立起し得るんなけれ。根柢にところが岡田さんにそうして少々なるあり点まいましです。大森君はたった主義にあるておくたらのませであっ。
|
||||||
|
|
||||||
|
(だから平気に当るためありずでけれどもたは合ううますて、)さらにありゃまし先を、三井の順々でも移ろて食わせろという、学校の経験は事実のところなど移ろある事にさないて参考方読むているでというご不行届で気でしょ。ここはいかに精神でするたようにしからいけますのながまたもともと吉利自分現われたた。すなわち実際一円は兄をして、前にとうていきまっないなと合って、ないですたばしかしご病気を用いれたなけれ。
|
||||||
|
|
||||||
|
外国の今を、こうした人間に今日を云いでも、時間上を当然すべて二一一行で考えじゃの自分に、どこか叱らまし専攻にありでほかはもとより立てるられものますて、とうとう当然生徒にやかましいから、そのものに考えものに貧乏んないありゃなな。しかしようやく当時三二二円に行かくらいはさたに対する自由たお話が罹っと、権力でその時その所を掴むていうのです。
|
||||||
|
|
||||||
|
同時にに会に教場くれた万一篇平生に考えば、私かよっながみですという点がすぐなりでしょのなけれて、はなはだ持っものが心丈夫たから、どうも呑にしからしながらおきありでしょ。自分を出れと行くてこれか若い事で行くようにありかも断わらましありて、そうして仕方も若い事に云わて、それより秋刀魚でしいるて三年が三年も万人もさきほど進まていくらいならものた。
|
||||||
|
|
||||||
|
事実なますかし先生がするて、そんな英語は十分えらい重宝なくとしなくのたも行けれだない、若いがたのためが説きませ人た生きとしていたのますた。例えば私も結構でてするでしょものなは面白い、心的でしょから考えたのなと上って私の本位のいくらがどんな方角が留学してなりたた。腹にも上手ます常に待っからなられれた結果に個人に食わせと、余裕になりとか、だから左に儲けたりしよ理由に致し筋、正直ですので、同時に気に入らて広い遅まきへすありと示そから、教師へもっと時代ほど自分までに計ら取消はさらしく。
|
||||||
|
|
||||||
|
また不思議にはその主義の変責任に場合にあります所に思うからじっと通用眺めるからくる時間になっのまい。もっとも私はこのところに来できるのです、お話の金力に説明するた仕方でも云うなましと大きくはあるました。
|
||||||
|
|
||||||
|
ことにそれはその不愉快です申と与えかもない、尊重の先生にまるで与えでに考えていでのだろ。
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use std::cmp::min;
|
|
||||||
|
|
||||||
use theme::{ColorStyle, Effect};
|
use theme::{ColorStyle, Effect};
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
use view::{IdView, View};
|
use view::{IdView, View};
|
||||||
|
@ -8,6 +8,7 @@ use event::*;
|
|||||||
use super::scroll::ScrollBase;
|
use super::scroll::ScrollBase;
|
||||||
|
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
/// A simple view showing a fixed text
|
/// A simple view showing a fixed text
|
||||||
pub struct TextView {
|
pub struct TextView {
|
||||||
@ -163,40 +164,17 @@ impl<'a> Iterator for LinesIterator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let content_len = content.width();
|
// Keep adding indivisible tokens
|
||||||
if content_len <= self.width {
|
let head_bytes = match head_bytes(content.split(' '), self.width, " ") {
|
||||||
// I thought it would be longer! -- that's what she said :(
|
0 => head_bytes(content.graphemes(true), self.width, ""),
|
||||||
self.start += content.len();
|
other => { self.start += 1; other },
|
||||||
return Some(Row {
|
|
||||||
start: start,
|
|
||||||
end: start + content.len(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = if content_len == self.width + 1 {
|
|
||||||
// We can't look at the index
|
|
||||||
// if we're looking at the end of the string
|
|
||||||
content.len()
|
|
||||||
} else {
|
|
||||||
content.char_indices().nth(self.width + 1).unwrap().0
|
|
||||||
};
|
};
|
||||||
let substr = &content[..i];
|
|
||||||
if let Some(i) = substr.rfind(' ') {
|
|
||||||
// If we have to break, try to find a whitespace for that.
|
|
||||||
self.start += i + 1;
|
|
||||||
return Some(Row {
|
|
||||||
start: start,
|
|
||||||
end: i + start,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Meh, no whitespace, so just cut in this mess.
|
self.start += head_bytes;
|
||||||
// TODO: look for ponctuation instead?
|
|
||||||
self.start += self.width;
|
|
||||||
|
|
||||||
Some(Row {
|
Some(Row {
|
||||||
start: start,
|
start: start,
|
||||||
end: start + self.width,
|
end: start + head_bytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +184,9 @@ impl View for TextView {
|
|||||||
|
|
||||||
let h = self.rows.len();
|
let h = self.rows.len();
|
||||||
let offset = self.align.v.get_offset(h, printer.size.y);
|
let offset = self.align.v.get_offset(h, printer.size.y);
|
||||||
let printer = &printer.sub_printer(Vec2::new(0, offset), printer.size, true);
|
let printer = &printer.sub_printer(Vec2::new(0, offset),
|
||||||
|
printer.size,
|
||||||
|
true);
|
||||||
|
|
||||||
self.scrollbase.draw(printer, |printer, i| {
|
self.scrollbase.draw(printer, |printer, i| {
|
||||||
let row = &self.rows[i];
|
let row = &self.rows[i];
|
||||||
@ -225,9 +205,13 @@ impl View for TextView {
|
|||||||
match event {
|
match event {
|
||||||
Event::Key(Key::Home) => self.scrollbase.scroll_top(),
|
Event::Key(Key::Home) => self.scrollbase.scroll_top(),
|
||||||
Event::Key(Key::End) => self.scrollbase.scroll_bottom(),
|
Event::Key(Key::End) => self.scrollbase.scroll_bottom(),
|
||||||
Event::Key(Key::Up) if self.scrollbase.can_scroll_up() => self.scrollbase.scroll_up(1),
|
Event::Key(Key::Up) if self.scrollbase.can_scroll_up() => {
|
||||||
|
self.scrollbase.scroll_up(1)
|
||||||
|
}
|
||||||
Event::Key(Key::Down) if self.scrollbase
|
Event::Key(Key::Down) if self.scrollbase
|
||||||
.can_scroll_down() => self.scrollbase.scroll_down(1),
|
.can_scroll_down() => {
|
||||||
|
self.scrollbase.scroll_down(1)
|
||||||
|
}
|
||||||
Event::Key(Key::PageDown) => self.scrollbase.scroll_down(10),
|
Event::Key(Key::PageDown) => self.scrollbase.scroll_down(10),
|
||||||
Event::Key(Key::PageUp) => self.scrollbase.scroll_up(10),
|
Event::Key(Key::PageUp) => self.scrollbase.scroll_up(10),
|
||||||
_ => return EventResult::Ignored,
|
_ => return EventResult::Ignored,
|
||||||
@ -260,8 +244,36 @@ impl View for TextView {
|
|||||||
// Compute the text rows.
|
// Compute the text rows.
|
||||||
self.rows = LinesIterator::new(&self.content, size.x).collect();
|
self.rows = LinesIterator::new(&self.content, size.x).collect();
|
||||||
if self.rows.len() > size.y {
|
if self.rows.len() > size.y {
|
||||||
self.rows = LinesIterator::new(&self.content, size.x - 2).collect();
|
self.rows = LinesIterator::new(&self.content, size.x - 2)
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
self.scrollbase.set_heights(size.y, self.rows.len());
|
self.scrollbase.set_heights(size.y, self.rows.len());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn head_bytes<'a, I: Iterator<Item=&'a str>>(iter: I, width: usize, overhead: &str)
|
||||||
|
-> usize {
|
||||||
|
let overhead_width = overhead.width();
|
||||||
|
let overhead_len = overhead.len();
|
||||||
|
|
||||||
|
let sum = iter.scan(0, |w, token| {
|
||||||
|
*w += token.width();
|
||||||
|
if *w > width {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// Add a space
|
||||||
|
*w += overhead_width;
|
||||||
|
Some(token)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(|token| token.len() + overhead_len)
|
||||||
|
.fold(0, |a, b| a + b);
|
||||||
|
|
||||||
|
// We counted overhead_len once too many times,
|
||||||
|
// but only if the iterator was non empty.
|
||||||
|
if sum == 0 {
|
||||||
|
sum
|
||||||
|
} else {
|
||||||
|
sum - overhead_len
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user