mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
remove dependency on blitstr v1 entirely
This commit is contained in:
parent
afd525002d
commit
2b46f21ae8
28 changed files with 224 additions and 143 deletions
21
Cargo.lock
generated
21
Cargo.lock
generated
|
|
@ -140,7 +140,6 @@ name = "benchmark"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"benchmark-target",
|
||||
"blitstr-ref",
|
||||
"graphics-server",
|
||||
"log",
|
||||
"log-server",
|
||||
|
|
@ -210,22 +209,6 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "blitstr"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/betrusted-io/blitstr.git?rev=89675bf468fa51baaf0de94e806b85c92466ae64#89675bf468fa51baaf0de94e806b85c92466ae64"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rkyv",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blitstr-ref"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"blitstr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.9.0"
|
||||
|
|
@ -881,7 +864,6 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||
name = "gam"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"blitstr-ref",
|
||||
"com",
|
||||
"content-plugin-api",
|
||||
"enum_dispatch",
|
||||
|
|
@ -974,7 +956,6 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
|||
name = "graphics-server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"blitstr-ref",
|
||||
"keyboard",
|
||||
"log",
|
||||
"log-server",
|
||||
|
|
@ -1037,7 +1018,6 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
|||
name = "ime-frontend"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"blitstr-ref",
|
||||
"gam",
|
||||
"graphics-server",
|
||||
"ime-plugin-api",
|
||||
|
|
@ -2218,7 +2198,6 @@ checksum = "a260c96bf26273969f360c2fc2e2c7732acc2ce49d939c7243c7230c2ad179d0"
|
|||
name = "status"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"blitstr-ref",
|
||||
"chrono",
|
||||
"com",
|
||||
"content-plugin-api",
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ default-members = [
|
|||
"services/trng",
|
||||
"services/gam",
|
||||
"services/status",
|
||||
"imports/blitstr-ref",
|
||||
"imports/com_rs-ref",
|
||||
"services/ime-plugin-api",
|
||||
"services/benchmark",
|
||||
|
|
@ -63,7 +62,6 @@ members = [
|
|||
"svd2repl",
|
||||
"svd2utra",
|
||||
"xtask",
|
||||
"imports/blitstr-ref",
|
||||
"imports/com_rs-ref",
|
||||
"services/ime-plugin-api",
|
||||
"services/content-plugin-api",
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
[package]
|
||||
name = "blitstr-ref"
|
||||
version = "0.1.0"
|
||||
authors = ["bunnie <bunnie@kosagi.com>"]
|
||||
edition = "2018"
|
||||
description = "blitstr import package"
|
||||
|
||||
# Dependency policy: fully specify dependencies to the minor version number
|
||||
[dependencies]
|
||||
blitstr = { git = "https://github.com/betrusted-io/blitstr.git", rev = "89675bf468fa51baaf0de94e806b85c92466ae64" }
|
||||
# blitstr = { path = "../blitstr" }
|
||||
|
||||
# targeting hardware
|
||||
[target.'cfg(not(any(windows,unix)))'.dependencies]
|
||||
|
||||
# targeting hosted mode
|
||||
[target.'cfg(any(windows,unix))'.dependencies]
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#![cfg_attr(target_os = "none", no_std)]
|
||||
|
||||
pub use blitstr::*;
|
||||
|
|
@ -13,7 +13,6 @@ ticktimer-server = { path = "../ticktimer-server" }
|
|||
xous-names = { path = "../xous-names" }
|
||||
log-server = { path = "../log-server" }
|
||||
log = "0.4.14"
|
||||
blitstr-ref = { path = "../../imports/blitstr-ref" }
|
||||
benchmark-target = { path = "../benchmark-target" }
|
||||
|
||||
xous-ipc = {path = "../../xous-ipc"}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ version = "0.1.0"
|
|||
|
||||
# Dependency policy: fully specify dependencies to the minor version number
|
||||
[dependencies]
|
||||
blitstr-ref = {path = "../../imports/blitstr-ref"}
|
||||
com = {path = "../com"} # used by the backlight setting on the main menu thread
|
||||
content-plugin-api = {path = "../content-plugin-api"}
|
||||
graphics-server = {path = "../graphics-server"}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::Canvas;
|
||||
use crate::{Canvas, GlyphStyle};
|
||||
|
||||
use blitstr_ref as blitstr;
|
||||
use blitstr::GlyphStyle;
|
||||
use graphics_server::*;
|
||||
|
||||
use crate::{LayoutApi, LayoutBehavior};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::Canvas;
|
||||
use crate::{Canvas, GlyphStyle};
|
||||
|
||||
use blitstr_ref as blitstr;
|
||||
use blitstr::GlyphStyle;
|
||||
use graphics_server::*;
|
||||
|
||||
use crate::{LayoutApi, LayoutBehavior};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::Canvas;
|
||||
use crate::{Canvas, GlyphStyle};
|
||||
|
||||
use blitstr_ref as blitstr;
|
||||
use blitstr::GlyphStyle;
|
||||
use graphics_server::*;
|
||||
|
||||
use crate::{LayoutApi, LayoutBehavior};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ version = "0.1.0"
|
|||
|
||||
# Dependency policy: fully specify dependencies to the minor version number
|
||||
[dependencies]
|
||||
blitstr-ref = {path = "../../imports/blitstr-ref"}
|
||||
keyboard = {path = "../keyboard"}
|
||||
log = "0.4.14"
|
||||
log-server = {path = "../log-server"}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,14 @@ pub mod text;
|
|||
pub use text::*;
|
||||
pub mod glyphstyle;
|
||||
pub use glyphstyle::*;
|
||||
pub mod blitstr2;
|
||||
pub use blitstr2::*;
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
pub const LINES: usize = 536;
|
||||
pub const WIDTH: usize = 336;
|
||||
|
||||
//////////////// IPC APIs
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
|
||||
pub struct Gid {
|
||||
|
|
|
|||
54
services/graphics-server/src/api/blitstr2.rs
Normal file
54
services/graphics-server/src/api/blitstr2.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
mod cliprect;
|
||||
pub use cliprect::*;
|
||||
mod cursor;
|
||||
pub use cursor::*;
|
||||
mod pt;
|
||||
pub use pt::*;
|
||||
|
||||
// Font data is stored as CODEPOINTS and GLYPHS arrays. CODEPOINTS holds sorted
|
||||
// Unicode codepoints for characters included in the font, and GLYPHS holds
|
||||
// 16*16px sprites (pixels packed in row-major order, LSB of first word is top
|
||||
// left pixel of sprite). The order of codepoints and glyphs is the same, but,
|
||||
// each codepoint is one u32 word long while each glyph is eight u32 words
|
||||
// long. So, to find a glyph we do:
|
||||
// 1. Binary search CODEPOINTS for the codepoint of interest
|
||||
// 2. Multiply the codepoint index by 8, yielding an offset into GLYPHS
|
||||
// 3. Slice 8 u32 words from GLYPHS starting at the offset
|
||||
|
||||
/// Struct to hold sprite pixel reference and associated metadata for glyphs
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct GlyphSprite {
|
||||
pub glyph: &'static [u32],
|
||||
pub wide: u8,
|
||||
pub high: u8,
|
||||
pub kern: u8,
|
||||
// the original character
|
||||
pub ch: char,
|
||||
// invert rendering for the character - for copy/paste selection regions
|
||||
pub invert: bool,
|
||||
// drawn an insertion point after this character
|
||||
pub insert: bool,
|
||||
// 2x flag for the back-end rendering (wide/high should be pre-computed to match this)
|
||||
pub double: bool,
|
||||
}
|
||||
|
||||
/// A TypesetWord is a Word that has beet turned into sprites and placed at a specific location on the canvas,
|
||||
/// defined by its `bb` record. The intention is that this abstract representation can be passed directly to
|
||||
/// a rasterizer for rendering.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TypesetWord {
|
||||
/// glyph data to directly render the word
|
||||
pub gs: Vec::<GlyphSprite>,
|
||||
/// top left origin point for rendering of the glyphs
|
||||
pub origin: Pt,
|
||||
/// width of the word
|
||||
pub width: usize,
|
||||
/// overall height for the word
|
||||
pub height: usize,
|
||||
/// set if this `word` is not drawable, e.g. a newline placeholder.
|
||||
/// *however* the Vec<GlyphSprite> should still be checked for an insertion point, so that
|
||||
/// successive newlines properly get their insertion point drawn
|
||||
pub non_drawable: bool,
|
||||
/// the position in the originating abstract string of the first character in the word
|
||||
pub strpos: usize,
|
||||
}
|
||||
132
services/graphics-server/src/api/blitstr2/cliprect.rs
Normal file
132
services/graphics-server/src/api/blitstr2/cliprect.rs
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
// Copyright (c) 2022 Sam Blenny
|
||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
//
|
||||
use crate::api::{LINES, WIDTH};
|
||||
use crate::api::Pt;
|
||||
|
||||
/// ClipRect specifies a region of pixels. X and y pixel ranges are inclusive of
|
||||
/// min and exclusive of max (i.e. it's min.x..max.x rather than min.x..=max.x)
|
||||
/// Coordinate System Notes:
|
||||
/// - (0,0) is top left
|
||||
/// - Increasing Y moves downward on the screen, increasing X moves right
|
||||
#[derive(Copy, Clone, Debug, PartialEq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
|
||||
pub struct ClipRect {
|
||||
pub min: Pt,
|
||||
pub max: Pt,
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
impl ClipRect {
|
||||
/// Initialize a rectangle using automatic min/max fixup for corner points
|
||||
pub fn new(min_x: usize, min_y: usize, max_x: usize, max_y: usize) -> ClipRect {
|
||||
// Make sure min_x <= max_x && min_y <= max_y
|
||||
let mut min = Pt { x: min_x, y: min_y };
|
||||
let mut max = Pt { x: max_x, y: max_y };
|
||||
if min_x > max_x {
|
||||
min.x = max_x;
|
||||
max.x = min_x;
|
||||
}
|
||||
if min_y > max_y {
|
||||
min.y = max_y;
|
||||
max.y = min_y;
|
||||
}
|
||||
ClipRect { min, max }
|
||||
}
|
||||
pub fn to_rect(&self) -> crate::api::Rectangle {
|
||||
crate::api::Rectangle::new_coords(
|
||||
self.min.x as i16,
|
||||
self.min.y as i16,
|
||||
self.max.x as i16,
|
||||
self.max.y as i16
|
||||
)
|
||||
}
|
||||
|
||||
/// Make a rectangle of the full screen size (0,0)..(WIDTH,LINES)
|
||||
pub fn full_screen() -> ClipRect {
|
||||
ClipRect::new(0, 0, WIDTH, LINES)
|
||||
}
|
||||
|
||||
/// Make a rectangle of the screen size minus padding (6,6)..(WIDTH-6,LINES-6)
|
||||
pub fn padded_screen() -> ClipRect {
|
||||
let pad = 6;
|
||||
ClipRect::new(pad, pad, WIDTH - pad, LINES - pad)
|
||||
}
|
||||
|
||||
pub fn intersects(&self, other: ClipRect) -> bool {
|
||||
!(self.max.x < other.min.x
|
||||
|| self.min.y > other.max.y
|
||||
|| self.max.y < other.min.y
|
||||
|| self.min.x > other.max.x)
|
||||
}
|
||||
pub fn intersects_point(&self, point: Pt) -> bool {
|
||||
((point.x >= self.min.x) && (point.x <= self.max.x))
|
||||
&& ((point.y >= self.min.y) && (point.y <= self.max.y))
|
||||
}
|
||||
/// takes the current Rectangle, and clips it with a clipping Rectangle; returns a new rectangle as the result
|
||||
pub fn clip_with(&self, clip: ClipRect) -> Option<ClipRect> {
|
||||
// check to see if we even overlap; if not, don't do any computation
|
||||
if !self.intersects(clip) {
|
||||
return None;
|
||||
}
|
||||
let tl: Pt = Pt::new(
|
||||
if self.min.x < clip.min.x {
|
||||
clip.min.x
|
||||
} else {
|
||||
self.min.x
|
||||
},
|
||||
if self.min.y < clip.min.y {
|
||||
clip.min.y
|
||||
} else {
|
||||
self.min.y
|
||||
},
|
||||
);
|
||||
let br: Pt = Pt::new(
|
||||
if self.max.x > clip.max.x {
|
||||
clip.max.x
|
||||
} else {
|
||||
self.max.x
|
||||
},
|
||||
if self.max.y > clip.max.y {
|
||||
clip.max.y
|
||||
} else {
|
||||
self.max.y
|
||||
},
|
||||
);
|
||||
Some(ClipRect::new(tl.x, tl.y, br.x, br.y))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_cliprect_equivalence() {
|
||||
let cr1 = ClipRect {
|
||||
min: Pt { x: 1, y: 2 },
|
||||
max: Pt { x: 8, y: 9 },
|
||||
};
|
||||
// Called properly:
|
||||
let cr2 = ClipRect::new(1, 2, 8, 9);
|
||||
// Called with mixed up corners that should get auto-corrected
|
||||
let cr3 = ClipRect::new(8, 2, 1, 9);
|
||||
let cr4 = ClipRect::new(1, 9, 8, 2);
|
||||
assert_eq!(cr1, cr2);
|
||||
assert_eq!(cr2, cr3);
|
||||
assert_eq!(cr3, cr4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cliprect_full_screen() {
|
||||
let clip = ClipRect::full_screen();
|
||||
assert_eq!(clip.min, Pt::new(0, 0));
|
||||
assert_eq!(clip.max, Pt::new(WIDTH, LINES));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cliprect_padded_screen() {
|
||||
let c1 = ClipRect::full_screen();
|
||||
let c2 = ClipRect::padded_screen();
|
||||
assert!(c2.min > c1.min);
|
||||
assert!(c2.max < c1.max);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,12 +4,12 @@
|
|||
use super::cliprect::ClipRect;
|
||||
use super::pt::Pt;
|
||||
use super::GlyphSprite;
|
||||
use crate::wordwrap::TypesetWord;
|
||||
use super::TypesetWord;
|
||||
|
||||
/// Cursor specifies a drawing position along a line of text. Lines of text can
|
||||
/// be different heights. Line_height is for keeping track of the tallest
|
||||
/// character that has been drawn so far on the current line.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
|
||||
pub struct Cursor {
|
||||
pub pt: Pt,
|
||||
pub line_height: usize,
|
||||
|
|
@ -37,7 +37,7 @@ impl Cursor {
|
|||
self.line_height = self.line_height.max(glyph.high as usize);
|
||||
}
|
||||
|
||||
pub fn update_word(&mut self, word: &TypesetWord) {
|
||||
pub(crate) fn update_word(&mut self, word: &TypesetWord) {
|
||||
self.pt.x += word.width;
|
||||
self.line_height = self.line_height.max(word.height);
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
|
||||
/// Point specifies a pixel coordinate
|
||||
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
|
||||
pub struct Pt {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
use crate::api::{DrawStyle, Point};
|
||||
use crate::api::{DrawStyle, Point, ClipRect};
|
||||
use crate::op::{HEIGHT, WIDTH};
|
||||
use blitstr::ClipRect;
|
||||
use blitstr_ref as blitstr;
|
||||
use core::cmp::{max, min};
|
||||
|
||||
#[derive(Debug, Clone, Copy, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
use crate::api::{Gid, Point, Rectangle, GlyphStyle};
|
||||
use blitstr::Cursor;
|
||||
use blitstr_ref as blitstr;
|
||||
use crate::api::{Gid, Point, Rectangle, GlyphStyle, Cursor};
|
||||
use xous_ipc::String;
|
||||
use core::ops::Add;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,15 @@ use crate::api::Point;
|
|||
use susres::{ManagedMem, RegManager, RegOrField, SuspendResume};
|
||||
use utralib::generated::*;
|
||||
use xous::MemoryRange;
|
||||
use crate::api::{LINES, WIDTH};
|
||||
|
||||
pub const FB_WIDTH_WORDS: usize = 11;
|
||||
pub const FB_WIDTH_PIXELS: usize = 336;
|
||||
pub const FB_LINES: usize = 536;
|
||||
pub const FB_WIDTH_PIXELS: usize = WIDTH;
|
||||
pub const FB_LINES: usize = LINES;
|
||||
pub const FB_SIZE: usize = FB_WIDTH_WORDS * FB_LINES; // 44 bytes by 536 lines
|
||||
const CONFIG_CLOCK_FREQUENCY: u32 = 100_000_000;
|
||||
|
||||
|
||||
pub struct XousDisplay {
|
||||
fb: MemoryRange,
|
||||
hwfb: MemoryRange,
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
use crate::api::Point;
|
||||
use minifb::{Key, Window, WindowOptions};
|
||||
use crate::api::{LINES, WIDTH};
|
||||
|
||||
const WIDTH: usize = 336;
|
||||
const HEIGHT: usize = 536;
|
||||
const HEIGHT: usize = LINES;
|
||||
|
||||
/// Width of the screen in 32-bit words
|
||||
const WIDTH_WORDS: usize = 11;
|
||||
pub const FB_WIDTH_WORDS: usize = WIDTH_WORDS;
|
||||
pub const FB_WIDTH_PIXELS: usize = 336;
|
||||
pub const FB_WIDTH_PIXELS: usize = WIDTH;
|
||||
pub const FB_LINES: usize = HEIGHT;
|
||||
pub const FB_SIZE: usize = WIDTH_WORDS * HEIGHT; // 44 bytes by 536 lines
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,6 @@ mod cliprect;
|
|||
pub use cliprect::*;
|
||||
pub(crate) mod fonts;
|
||||
pub(crate) use fonts::*;
|
||||
mod cursor;
|
||||
pub use cursor::*;
|
||||
mod pt;
|
||||
pub use pt::*;
|
||||
|
||||
const LINES: usize = crate::backend::FB_LINES;
|
||||
const WIDTH: usize = crate::backend::FB_WIDTH_PIXELS;
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
//
|
||||
use super::cliprect::ClipRect;
|
||||
use super::fonts;
|
||||
use crate::GlyphSprite;
|
||||
#[allow(unused_imports)]
|
||||
use super::{LINES, WORDS_PER_LINE, WIDTH, FrBuf};
|
||||
use crate::api::Point;
|
||||
|
||||
/// Null glyph to use when everything else fails
|
||||
pub const NULL_GLYPH: [u32; 8] = [0, 0x5500AA, 0x5500AA, 0x5500AA, 0x5500AA, 0x5500AA, 0, 0];
|
||||
pub const NULL_GLYPH_SPRITE: fonts::GlyphSprite = fonts::GlyphSprite {
|
||||
pub const NULL_GLYPH_SPRITE: GlyphSprite = GlyphSprite {
|
||||
glyph: &NULL_GLYPH,
|
||||
wide: 8u8,
|
||||
high: 12u8,
|
||||
|
|
@ -29,7 +29,7 @@ pub const REPLACEMENT: char = '\u{FFFD}';
|
|||
/// 1. Fits in word: xr:1..7 => (data[0].bit_30)->(data[0].bit_26), mask:0x7c00_0000
|
||||
/// 2. Spans words: xr:30..36 => (data[0].bit_01)->(data[1].bit_29), mask:[0x0000_0003,0xe000_000]
|
||||
///
|
||||
pub fn xor_glyph(fb: &mut FrBuf, p: &Point, gs: fonts::GlyphSprite, xor: bool, cr: ClipRect) {
|
||||
pub fn xor_glyph(fb: &mut FrBuf, p: &Point, gs: GlyphSprite, xor: bool, cr: ClipRect) {
|
||||
const SPRITE_PX: i16 = 16;
|
||||
const SPRITE_WORDS: i16 = 8;
|
||||
if gs.glyph.len() < SPRITE_WORDS as usize {
|
||||
|
|
@ -119,7 +119,7 @@ pub fn xor_glyph(fb: &mut FrBuf, p: &Point, gs: fonts::GlyphSprite, xor: bool, c
|
|||
/// This is similar to xor_glyph(). But, instead of using 16px sprites for input
|
||||
/// and output, this takes 16px sprites as input and blits 32px sprites as output.
|
||||
///
|
||||
pub fn xor_glyph_2x(fb: &mut FrBuf, p: &Point, gs: fonts::GlyphSprite, xor: bool, cr: ClipRect) {
|
||||
pub fn xor_glyph_2x(fb: &mut FrBuf, p: &Point, gs: GlyphSprite, xor: bool, cr: ClipRect) {
|
||||
const SPRITE_PX: i16 = 16;
|
||||
const SPRITE_WORDS: i16 = 8;
|
||||
if gs.glyph.len() < SPRITE_WORDS as usize {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
//
|
||||
use super::{LINES, WIDTH};
|
||||
use super::pt::Pt;
|
||||
use crate::api::Pt;
|
||||
|
||||
/// ClipRect specifies a region of pixels. X and y pixel ranges are inclusive of
|
||||
/// min and exclusive of max (i.e. it's min.x..max.x rather than min.x..=max.x)
|
||||
|
|
|
|||
|
|
@ -11,35 +11,10 @@ pub mod regular;
|
|||
pub mod small;
|
||||
pub mod zh;
|
||||
|
||||
use crate::GlyphSprite;
|
||||
|
||||
const DEFAULT_KERN: u8 = 1;
|
||||
|
||||
// Font data is stored as CODEPOINTS and GLYPHS arrays. CODEPOINTS holds sorted
|
||||
// Unicode codepoints for characters included in the font, and GLYPHS holds
|
||||
// 16*16px sprites (pixels packed in row-major order, LSB of first word is top
|
||||
// left pixel of sprite). The order of codepoints and glyphs is the same, but,
|
||||
// each codepoint is one u32 word long while each glyph is eight u32 words
|
||||
// long. So, to find a glyph we do:
|
||||
// 1. Binary search CODEPOINTS for the codepoint of interest
|
||||
// 2. Multiply the codepoint index by 8, yielding an offset into GLYPHS
|
||||
// 3. Slice 8 u32 words from GLYPHS starting at the offset
|
||||
|
||||
/// Struct to hold sprite pixel reference and associated metadata for glyphs
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct GlyphSprite {
|
||||
pub glyph: &'static [u32],
|
||||
pub wide: u8,
|
||||
pub high: u8,
|
||||
pub kern: u8,
|
||||
// the original character
|
||||
pub ch: char,
|
||||
// invert rendering for the character - for copy/paste selection regions
|
||||
pub invert: bool,
|
||||
// drawn an insertion point after this character
|
||||
pub insert: bool,
|
||||
// 2x flag for the back-end rendering (wide/high should be pre-computed to match this)
|
||||
pub double: bool,
|
||||
}
|
||||
|
||||
pub fn small_glyph(ch: char) -> Result<GlyphSprite, usize> {
|
||||
match small::CODEPOINTS.binary_search(&(ch as u32)) {
|
||||
Ok(n) => {
|
||||
|
|
|
|||
|
|
@ -4,10 +4,8 @@
|
|||
pub mod api;
|
||||
pub use api::{
|
||||
Circle, ClipObject, ClipObjectType, DrawStyle, Gid, Line, PixelColor, Point, Rectangle,
|
||||
RoundedRectangle, TextBounds, TextOp, TextView, TokenClaim,
|
||||
RoundedRectangle, TextBounds, TextOp, TextView, TokenClaim, ClipRect, Cursor, GlyphStyle
|
||||
};
|
||||
pub use blitstr::{ClipRect, Cursor, GlyphStyle};
|
||||
use blitstr_ref as blitstr;
|
||||
pub mod op;
|
||||
|
||||
pub mod fontmap;
|
||||
|
|
|
|||
|
|
@ -218,15 +218,15 @@ fn xmain() -> ! {
|
|||
|
||||
let typeset_extent = match tv.bounds_hint {
|
||||
TextBounds::BoundingBox(r) =>
|
||||
blitstr2::Pt::new((r.br().x - r.tl().x - tv.margin.x * 2) as usize, (r.br().y - r.tl().y - tv.margin.y * 2) as usize),
|
||||
Pt::new((r.br().x - r.tl().x - tv.margin.x * 2) as usize, (r.br().y - r.tl().y - tv.margin.y * 2) as usize),
|
||||
TextBounds::GrowableFromBr(br, width) =>
|
||||
blitstr2::Pt::new(width as usize - tv.margin.x as usize * 2, br.y as usize - tv.margin.y as usize * 2),
|
||||
Pt::new(width as usize - tv.margin.x as usize * 2, br.y as usize - tv.margin.y as usize * 2),
|
||||
TextBounds::GrowableFromBl(bl, width) =>
|
||||
blitstr2::Pt::new(width as usize - tv.margin.x as usize * 2, bl.y as usize - tv.margin.y as usize * 2),
|
||||
Pt::new(width as usize - tv.margin.x as usize * 2, bl.y as usize - tv.margin.y as usize * 2),
|
||||
TextBounds::GrowableFromTl(tl, width) =>
|
||||
blitstr2::Pt::new(width as usize - tv.margin.x as usize * 2, (clip_rect.br().y - clip_rect.tl().y - tl.y) as usize - tv.margin.y as usize * 2),
|
||||
Pt::new(width as usize - tv.margin.x as usize * 2, (clip_rect.br().y - clip_rect.tl().y - tl.y) as usize - tv.margin.y as usize * 2),
|
||||
TextBounds::GrowableFromTr(tr, width) =>
|
||||
blitstr2::Pt::new(width as usize - tv.margin.x as usize * 2, (clip_rect.br().y - clip_rect.tl().y - tr.y) as usize - tv.margin.y as usize * 2),
|
||||
Pt::new(width as usize - tv.margin.x as usize * 2, (clip_rect.br().y - clip_rect.tl().y - tr.y) as usize - tv.margin.y as usize * 2),
|
||||
};
|
||||
let mut typesetter = Typesetter::setup(
|
||||
tv.to_str(),
|
||||
|
|
@ -326,9 +326,9 @@ fn xmain() -> ! {
|
|||
composition.render(display.native_buffer(), composition_top_left, tv.invert, smallest_rect);
|
||||
}
|
||||
// type mismatch for now, replace this with a simple equals once we sort that out
|
||||
tv.cursor.pt.x = composition.final_cursor().pt.x as i32;
|
||||
tv.cursor.pt.y = composition.final_cursor().pt.y as i32;
|
||||
tv.cursor.line_height = composition.final_cursor().line_height as i32;
|
||||
tv.cursor.pt.x = composition.final_cursor().pt.x;
|
||||
tv.cursor.pt.y = composition.final_cursor().pt.y;
|
||||
tv.cursor.line_height = composition.final_cursor().line_height;
|
||||
|
||||
tv.bounds_computed = Some(
|
||||
clear_rect
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::api::{Point, Rectangle, GlyphStyle, glyph_to_height_hint};
|
||||
use crate::api::{Point, Rectangle, GlyphStyle, glyph_to_height_hint, GlyphSprite, TypesetWord, Pt, Cursor};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use crate::backend::{FB_SIZE, FB_WIDTH_PIXELS, FB_LINES};
|
||||
|
|
@ -31,26 +31,6 @@ use crate::backend::{FB_SIZE, FB_WIDTH_PIXELS, FB_LINES};
|
|||
use crate::blitstr2::{self, *};
|
||||
use crate::style_macros::*;
|
||||
|
||||
/// A TypesetWord is a Word that has beet turned into sprites and placed at a specific location on the canvas,
|
||||
/// defined by its `bb` record. The intention is that this abstract representation can be passed directly to
|
||||
/// a rasterizer for rendering.
|
||||
#[derive(Debug)]
|
||||
pub struct TypesetWord {
|
||||
/// glyph data to directly render the word
|
||||
pub gs: Vec::<GlyphSprite>,
|
||||
/// top left origin point for rendering of the glyphs
|
||||
pub origin: Pt,
|
||||
/// width of the word
|
||||
pub width: usize,
|
||||
/// overall height for the word
|
||||
pub height: usize,
|
||||
/// set if this `word` is not drawable, e.g. a newline placeholder.
|
||||
/// *however* the Vec<GlyphSprite> should still be checked for an insertion point, so that
|
||||
/// successive newlines properly get their insertion point drawn
|
||||
pub non_drawable: bool,
|
||||
/// the position in the originating abstract string of the first character in the word
|
||||
pub strpos: usize,
|
||||
}
|
||||
impl TypesetWord {
|
||||
pub fn new(origin: Pt, strpos: usize) -> Self {
|
||||
TypesetWord {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ version = "0.1.0"
|
|||
|
||||
# Dependency policy: fully specify dependencies to the minor version number
|
||||
[dependencies]
|
||||
blitstr-ref = {path = "../../imports/blitstr-ref"}
|
||||
gam = {path = "../gam"}
|
||||
graphics-server = {path = "../graphics-server"}
|
||||
ime-plugin-api = {path = "../ime-plugin-api"}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ version = "0.1.0"
|
|||
|
||||
# Dependency policy: fully specify dependencies to the minor version number
|
||||
[dependencies]
|
||||
blitstr-ref = {path = "../../imports/blitstr-ref"}
|
||||
com = {path = "../com"}
|
||||
content-plugin-api = {path = "../content-plugin-api"}
|
||||
log = "0.4.14"
|
||||
|
|
|
|||
Loading…
Reference in a new issue