mirror of
https://github.com/Astatin3/IntroToWebAuthoring.git
synced 2026-06-08 16:18:01 -06:00
Font scale
This commit is contained in:
+7
-2
@@ -10,8 +10,13 @@ crate-type = ["cdylib"]
|
|||||||
fontdue = "0.9.3"
|
fontdue = "0.9.3"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
quick-xml = "0.38.3"
|
quick-xml = "0.38.3"
|
||||||
wasm-bindgen = {version = "0.2.104"}
|
wasm-bindgen = "0.2.105"
|
||||||
web-sys = {version = "0.3.81", features = ['CanvasRenderingContext2d', 'Document', 'Element', 'HtmlCanvasElement', 'Window', 'ImageData']}
|
# web-sys = "0.3.82"
|
||||||
|
# fontdue = "0.9.3"
|
||||||
|
# lazy_static = "1.5.0"
|
||||||
|
# quick-xml = "0.38.3"
|
||||||
|
# wasm-bindgen = {version = "0.2.104"}
|
||||||
|
web-sys = {version = "0.3.82", features = ['CanvasRenderingContext2d', 'Document', 'Element', 'HtmlCanvasElement', 'Window', 'ImageData']}
|
||||||
|
|
||||||
# [dependencies.web-sys]
|
# [dependencies.web-sys]
|
||||||
# features =
|
# features =
|
||||||
|
|||||||
+5
-5
@@ -1,8 +1,4 @@
|
|||||||
<ConstraintLayout>
|
<ConstraintLayout>
|
||||||
<BoxView margin="10" align_top_to_top="parent" align_left_to_left="parent">
|
|
||||||
<ColoredRectView r="123" g="12" b="34" />
|
|
||||||
</BoxView>
|
|
||||||
|
|
||||||
<BoxView
|
<BoxView
|
||||||
margin_left="10"
|
margin_left="10"
|
||||||
margin_right="10"
|
margin_right="10"
|
||||||
@@ -16,6 +12,10 @@
|
|||||||
<ColoredRectView r="30" g="30" b="30" />
|
<ColoredRectView r="30" g="30" b="30" />
|
||||||
</BoxView>
|
</BoxView>
|
||||||
|
|
||||||
|
<BoxView margin="10" align_top_to_top="parent" align_left_to_left="parent">
|
||||||
|
<ColoredRectView r="123" g="12" b="34" />
|
||||||
|
</BoxView>
|
||||||
|
|
||||||
<BoxView
|
<BoxView
|
||||||
margin="10"
|
margin="10"
|
||||||
align_top_to_top="parent"
|
align_top_to_top="parent"
|
||||||
@@ -23,6 +23,6 @@
|
|||||||
align_bottom_to_bottom="parent"
|
align_bottom_to_bottom="parent"
|
||||||
width="200"
|
width="200"
|
||||||
>
|
>
|
||||||
<ColoredRectView r="123" g="125" b="34" />
|
<TextView text="12345\nThis is a testing!" font_size="30." />
|
||||||
</BoxView>
|
</BoxView>
|
||||||
</ConstraintLayout>
|
</ConstraintLayout>
|
||||||
|
|||||||
+16
-9
@@ -5,7 +5,7 @@ pub use cursors::{Cursor, set_cursor};
|
|||||||
use wasm_bindgen::prelude::wasm_bindgen;
|
use wasm_bindgen::prelude::wasm_bindgen;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
log,
|
AppErr, log,
|
||||||
parser::{self, TEST_XML},
|
parser::{self, TEST_XML},
|
||||||
render::Renderer,
|
render::Renderer,
|
||||||
views::View,
|
views::View,
|
||||||
@@ -35,7 +35,7 @@ impl AppState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn new(renderer: Renderer) -> Self {
|
pub fn new(renderer: Renderer) -> Result<Self, AppErr> {
|
||||||
let (width, height) = (renderer.actual_width, renderer.actual_height);
|
let (width, height) = (renderer.actual_width, renderer.actual_height);
|
||||||
|
|
||||||
let root_view = parser::parse(TEST_XML);
|
let root_view = parser::parse(TEST_XML);
|
||||||
@@ -48,12 +48,12 @@ impl App {
|
|||||||
state: AppState::new(),
|
state: AppState::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.resize(width, height);
|
this.resize(width, height)?;
|
||||||
|
|
||||||
this
|
Ok(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&mut self) {
|
pub fn draw(&mut self) -> Result<(), AppErr> {
|
||||||
// self.renderer.img.randomize(&mut self.renderer.rand);
|
// self.renderer.img.randomize(&mut self.renderer.rand);
|
||||||
if let Some(view) = &mut self.root_view {
|
if let Some(view) = &mut self.root_view {
|
||||||
let (width, height) = (
|
let (width, height) = (
|
||||||
@@ -64,32 +64,39 @@ impl App {
|
|||||||
view.draw(&mut self.renderer, 0., 0., width, height);
|
view.draw(&mut self.renderer, 0., 0., width, height);
|
||||||
self.renderer.update();
|
self.renderer.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// App events
|
// App events
|
||||||
impl App {
|
impl App {
|
||||||
pub fn resize(&mut self, width: usize, height: usize) {
|
pub fn resize(&mut self, width: usize, height: usize) -> Result<(), AppErr> {
|
||||||
self.renderer.resize(width, height);
|
self.renderer.resize(width, height);
|
||||||
if let Some(view) = &mut self.root_view {
|
if let Some(view) = &mut self.root_view {
|
||||||
view.resize(0., 0., width as f32, height as f32);
|
view.resize(&mut self.renderer, 0., 0., width as f32, height as f32);
|
||||||
}
|
}
|
||||||
self.draw();
|
self.draw();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mouse_move(&mut self, x: f32, y: f32) {
|
pub fn mouse_move(&mut self, x: f32, y: f32) -> Result<(), AppErr> {
|
||||||
self.state.mouse_x = x;
|
self.state.mouse_x = x;
|
||||||
self.state.mouse_y = y;
|
self.state.mouse_y = y;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
// if let Some(current_activity) = self.current_activity {
|
// if let Some(current_activity) = self.current_activity {
|
||||||
// self.activities[current_activity].mouse_move(&mut self.renderer, &self.state);
|
// self.activities[current_activity].mouse_move(&mut self.renderer, &self.state);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn l_click(&mut self, x: f32, y: f32) {
|
pub fn l_click(&mut self, x: f32, y: f32) -> Result<(), AppErr> {
|
||||||
self.state.mouse_x = x;
|
self.state.mouse_x = x;
|
||||||
self.state.mouse_y = y;
|
self.state.mouse_y = y;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
// if let Some(current_activity) = self.current_activity {
|
// if let Some(current_activity) = self.current_activity {
|
||||||
// self.activities[current_activity].l_click(&mut self.renderer, &self.state);
|
// self.activities[current_activity].l_click(&mut self.renderer, &self.state);
|
||||||
// }
|
// }
|
||||||
|
|||||||
+41
-5
@@ -4,6 +4,8 @@ mod parser;
|
|||||||
mod render;
|
mod render;
|
||||||
mod views;
|
mod views;
|
||||||
|
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
use wasm_bindgen::{Clamped, prelude::*};
|
use wasm_bindgen::{Clamped, prelude::*};
|
||||||
use web_sys::ImageData;
|
use web_sys::ImageData;
|
||||||
|
|
||||||
@@ -17,6 +19,14 @@ use crate::{
|
|||||||
render::Renderer,
|
render::Renderer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum AppErr {
|
||||||
|
ParseErr(String),
|
||||||
|
RenderErr(String),
|
||||||
|
ArrangeErr(String),
|
||||||
|
RasterErr(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[wasm_bindgen(js_namespace = console)]
|
#[wasm_bindgen(js_namespace = console)]
|
||||||
@@ -35,28 +45,54 @@ pub fn init(canvas: &web_sys::HtmlCanvasElement, width: usize, height: usize) ->
|
|||||||
let mut renderer = Renderer::new(canvas, width, height);
|
let mut renderer = Renderer::new(canvas, width, height);
|
||||||
renderer.resize(width, height);
|
renderer.resize(width, height);
|
||||||
|
|
||||||
App::new(renderer)
|
match App::new(renderer) {
|
||||||
|
Ok(app) => app,
|
||||||
|
Err(e) => {
|
||||||
|
log!("Error initializing: {:?}", e);
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn resize(app: &mut App, width: usize, height: usize) {
|
pub fn resize(app: &mut App, width: usize, height: usize) {
|
||||||
app.resize(width, height);
|
match app.resize(width, height) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
log!("Error resizing: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn draw(app: &mut App) {
|
pub fn draw(app: &mut App) {
|
||||||
// app.renderer.img.randomize(&mut app.renderer.rand);
|
// app.renderer.img.randomize(&mut app.renderer.rand);
|
||||||
app.draw();
|
match app.draw() {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
log!("Error drawing: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn click(app: &mut App, x: f32, y: f32) {
|
pub fn click(app: &mut App, x: f32, y: f32) {
|
||||||
// ctx.img.randomize(&mut ctx.rand);
|
// ctx.img.randomize(&mut ctx.rand);
|
||||||
// draw::draw(ctx);
|
// draw::draw(ctx);
|
||||||
app.l_click(x, y);
|
match app.l_click(x, y) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
log!("Error on click: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn mouse_move(app: &mut App, x: f32, y: f32) {
|
pub fn mouse_move(app: &mut App, x: f32, y: f32) {
|
||||||
app.mouse_move(x, y);
|
match app.mouse_move(x, y) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
log!("Error on mouse move: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
log,
|
log,
|
||||||
views::{Bounds, BoxView, ColorRectView, ConstraintLayout, View},
|
views::{Bounds, BoxView, ColorRectView, ConstraintLayout, TextView, View},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod parser;
|
mod parser;
|
||||||
@@ -22,6 +22,7 @@ impl Tag {
|
|||||||
"ColoredRectView" => ColorRectView::from_tag(&self.attributes, &self.children),
|
"ColoredRectView" => ColorRectView::from_tag(&self.attributes, &self.children),
|
||||||
"ConstraintLayout" => ConstraintLayout::from_tag(&self.attributes, &self.children),
|
"ConstraintLayout" => ConstraintLayout::from_tag(&self.attributes, &self.children),
|
||||||
"BoxView" => BoxView::from_tag(&self.attributes, &self.children),
|
"BoxView" => BoxView::from_tag(&self.attributes, &self.children),
|
||||||
|
"TextView" => TextView::from_tag(&self.attributes, &self.children),
|
||||||
|
|
||||||
_ => panic!("Unknown tag: {}", self.name),
|
_ => panic!("Unknown tag: {}", self.name),
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-22
@@ -1,9 +1,9 @@
|
|||||||
use crate::render::rand;
|
use crate::render::rand;
|
||||||
|
|
||||||
pub struct ImgBuffer {
|
pub struct ImgBuffer {
|
||||||
pub data: Vec<u8>,
|
pub(crate) data: Vec<u8>,
|
||||||
width: usize,
|
pub(crate) width: usize,
|
||||||
height: usize,
|
pub(crate) height: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImgBuffer {
|
impl ImgBuffer {
|
||||||
@@ -24,25 +24,6 @@ impl ImgBuffer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn overlay_bitmap(&mut self, other: &Bitmap, xoffset: usize, yoffset: usize) {
|
|
||||||
let length = self.data.len();
|
|
||||||
for y in 0..other.height {
|
|
||||||
for x in 0..other.width {
|
|
||||||
// Calculate the offset for the current pixel in the buffer
|
|
||||||
// This uses bitshift instead of multiplication x4 for performance
|
|
||||||
let offset = ((y + yoffset) * self.width + (x + xoffset)) << 2;
|
|
||||||
if offset >= length {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let color = other.data[y * other.width + x];
|
|
||||||
self.data[offset] = color;
|
|
||||||
self.data[offset + 1] = color;
|
|
||||||
self.data[offset + 2] = color;
|
|
||||||
self.data[offset + 3] = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resize(&mut self, width: usize, height: usize) {
|
pub fn resize(&mut self, width: usize, height: usize) {
|
||||||
self.data = vec![0; width * height * 4];
|
self.data = vec![0; width * height * 4];
|
||||||
self.width = width;
|
self.width = width;
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
use crate::render::buffer::{Bitmap, ImgBuffer};
|
||||||
|
|
||||||
|
impl ImgBuffer {
|
||||||
|
pub fn overlay_bitmap_fg_bg(
|
||||||
|
&mut self,
|
||||||
|
other: &Bitmap,
|
||||||
|
xoffset: usize,
|
||||||
|
yoffset: usize,
|
||||||
|
foreground_color: (u8, u8, u8, u8),
|
||||||
|
background_color: (u8, u8, u8, u8),
|
||||||
|
) {
|
||||||
|
let length = self.data.len();
|
||||||
|
for y in 0..other.height {
|
||||||
|
for x in 0..other.width {
|
||||||
|
let offset = ((y + yoffset) * self.width + (x + xoffset)) << 2;
|
||||||
|
if offset >= length {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let weight = other.data[y * other.width + x];
|
||||||
|
|
||||||
|
let (mut pixel_r, mut pixel_g, mut pixel_b, mut pixel_a) = (
|
||||||
|
self.data[offset],
|
||||||
|
self.data[offset + 1],
|
||||||
|
self.data[offset + 2],
|
||||||
|
self.data[offset + 3],
|
||||||
|
);
|
||||||
|
|
||||||
|
(pixel_r, pixel_g, pixel_b, pixel_a) = Self::blend_bitmap_pixel_fg_bg(
|
||||||
|
(pixel_r, pixel_b, pixel_g, pixel_a),
|
||||||
|
weight,
|
||||||
|
foreground_color,
|
||||||
|
background_color,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.data[offset] = pixel_r;
|
||||||
|
self.data[offset + 1] = pixel_g;
|
||||||
|
self.data[offset + 2] = pixel_b;
|
||||||
|
self.data[offset + 3] = pixel_a;
|
||||||
|
|
||||||
|
// = color;
|
||||||
|
// self.data[offset + 1] = color;
|
||||||
|
// self.data[offset + 2] = color;
|
||||||
|
// self.data[offset + 3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn overlay_bitmap_fg(
|
||||||
|
&mut self,
|
||||||
|
other: &Bitmap,
|
||||||
|
xoffset: usize,
|
||||||
|
yoffset: usize,
|
||||||
|
foreground_color: (u8, u8, u8),
|
||||||
|
) {
|
||||||
|
let length = self.data.len();
|
||||||
|
for y in 0..other.height {
|
||||||
|
for x in 0..other.width {
|
||||||
|
let offset = ((y + yoffset) * self.width + (x + xoffset)) << 2;
|
||||||
|
if offset >= length {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let weight = other.data[y * other.width + x];
|
||||||
|
|
||||||
|
let (mut pixel_r, mut pixel_g, mut pixel_b, mut pixel_a) = (
|
||||||
|
self.data[offset],
|
||||||
|
self.data[offset + 1],
|
||||||
|
self.data[offset + 2],
|
||||||
|
self.data[offset + 3],
|
||||||
|
);
|
||||||
|
|
||||||
|
(pixel_r, pixel_g, pixel_b, pixel_a) = Self::blend_bitmap_pixel_fg(
|
||||||
|
(pixel_r, pixel_b, pixel_g, pixel_a),
|
||||||
|
weight,
|
||||||
|
foreground_color,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.data[offset] = pixel_r;
|
||||||
|
self.data[offset + 1] = pixel_g;
|
||||||
|
self.data[offset + 2] = pixel_b;
|
||||||
|
self.data[offset + 3] = pixel_a;
|
||||||
|
|
||||||
|
// = color;
|
||||||
|
// self.data[offset + 1] = color;
|
||||||
|
// self.data[offset + 2] = color;
|
||||||
|
// self.data[offset + 3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blend_bitmap_pixel_fg_bg(
|
||||||
|
original: (u8, u8, u8, u8),
|
||||||
|
bitmap_weight: u8,
|
||||||
|
fg_color: (u8, u8, u8, u8),
|
||||||
|
bg_color: (u8, u8, u8, u8),
|
||||||
|
) -> (u8, u8, u8, u8) {
|
||||||
|
// Step 1: Interpolate between bg_color and fg_color based on bitmap_weight
|
||||||
|
|
||||||
|
let w = bitmap_weight as u32;
|
||||||
|
let inv_w = 255u32 - w;
|
||||||
|
|
||||||
|
// Blend RGB channels using (x * 257) >> 16 approximation for /255
|
||||||
|
let br = (((bg_color.0 as u32 * inv_w + fg_color.0 as u32 * w) * 257) >> 16) as u8;
|
||||||
|
let bg = (((bg_color.1 as u32 * inv_w + fg_color.1 as u32 * w) * 257) >> 16) as u8;
|
||||||
|
let bb = (((bg_color.2 as u32 * inv_w + fg_color.2 as u32 * w) * 257) >> 16) as u8;
|
||||||
|
let ba = (((bg_color.3 as u32 * inv_w + fg_color.3 as u32 * w) * 257) >> 16) as u8;
|
||||||
|
|
||||||
|
// Step 2: Alpha blend the interpolated color over the original pixel
|
||||||
|
|
||||||
|
if ba == 0 {
|
||||||
|
// Fully transparent, return original
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ba == 255 {
|
||||||
|
// Fully opaque, return blended color
|
||||||
|
return (br, bg, bb, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
let a = ba as u32;
|
||||||
|
let inv_a = 255u32 - a;
|
||||||
|
|
||||||
|
let r = (((original.0 as u32 * inv_a + br as u32 * a) * 257) >> 16) as u8;
|
||||||
|
let g = (((original.1 as u32 * inv_a + bg as u32 * a) * 257) >> 16) as u8;
|
||||||
|
let b = (((original.2 as u32 * inv_a + bb as u32 * a) * 257) >> 16) as u8;
|
||||||
|
|
||||||
|
// Alpha channel: blend using "over" operation
|
||||||
|
let final_a = (((original.3 as u32 * inv_a) * 257) >> 16) + a;
|
||||||
|
let final_a = final_a.min(255) as u8;
|
||||||
|
|
||||||
|
(r, g, b, final_a)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blend_bitmap_pixel_fg(
|
||||||
|
original: (u8, u8, u8, u8),
|
||||||
|
bitmap_weight: u8,
|
||||||
|
fg_color: (u8, u8, u8),
|
||||||
|
) -> (u8, u8, u8, u8) {
|
||||||
|
if bitmap_weight == 0 {
|
||||||
|
// Fully transparent, return original
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
if bitmap_weight == 255 {
|
||||||
|
// Fully opaque, return foreground color
|
||||||
|
return (fg_color.0, fg_color.1, fg_color.2, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alpha blend: original + (fg - original) * weight / 255
|
||||||
|
let w = bitmap_weight as u32;
|
||||||
|
let inv_w = 255u32 - w;
|
||||||
|
|
||||||
|
let r = (((original.0 as u32 * inv_w + fg_color.0 as u32 * w) * 257) >> 16) as u8;
|
||||||
|
let g = (((original.1 as u32 * inv_w + fg_color.1 as u32 * w) * 257) >> 16) as u8;
|
||||||
|
let b = (((original.2 as u32 * inv_w + fg_color.2 as u32 * w) * 257) >> 16) as u8;
|
||||||
|
|
||||||
|
// Alpha channel: blend to full opacity based on weight
|
||||||
|
let final_a = (((original.3 as u32 * inv_w) * 257) >> 16) + w;
|
||||||
|
let final_a = final_a.min(255) as u8;
|
||||||
|
|
||||||
|
(r, g, b, final_a)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
pub mod buffer;
|
pub mod buffer;
|
||||||
|
pub mod buffer_overlay;
|
||||||
pub mod rand;
|
pub mod rand;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ pub fn calc_resolution(width: usize, height: usize) -> (usize, usize, f32, f32)
|
|||||||
|
|
||||||
let new_width = (distortion_x * RESOLUTION as f32).round() as usize;
|
let new_width = (distortion_x * RESOLUTION as f32).round() as usize;
|
||||||
let new_height = (distortion_y * RESOLUTION as f32).round() as usize;
|
let new_height = (distortion_y * RESOLUTION as f32).round() as usize;
|
||||||
|
|
||||||
(new_width, new_height, distortion_x, distortion_y)
|
(new_width, new_height, distortion_x, distortion_y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ impl View for BoxView {
|
|||||||
self.view.draw(renderer, x, y, w, h);
|
self.view.draw(renderer, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize(&mut self, x: f32, y: f32, w: f32, h: f32) {
|
fn resize(&mut self, renderer: &mut Renderer, x: f32, y: f32, w: f32, h: f32) {
|
||||||
self.view.resize(x, y, w, h);
|
self.view.resize(renderer, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_tag(
|
fn from_tag(
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ impl View for ColorRectView {
|
|||||||
// log!("Draw");
|
// log!("Draw");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize(&mut self, _x: f32, _y: f32, _w: f32, _h: f32) {}
|
fn resize(&mut self, _renderer: &mut Renderer, _x: f32, _y: f32, _w: f32, _h: f32) {}
|
||||||
|
|
||||||
fn from_tag(
|
fn from_tag(
|
||||||
attributes: &std::collections::HashMap<String, String>,
|
attributes: &std::collections::HashMap<String, String>,
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ impl View for ConstraintLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize(&mut self, x: f32, y: f32, w: f32, h: f32) {
|
fn resize(&mut self, _renderer: &mut Renderer, x: f32, y: f32, w: f32, h: f32) {
|
||||||
self.recalculate_positions(x, y, w, h);
|
self.recalculate_positions(x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-6
@@ -1,8 +1,4 @@
|
|||||||
use std::{
|
use std::{any::Any, collections::HashMap, fmt::Debug};
|
||||||
any::{Any, TypeId},
|
|
||||||
collections::HashMap,
|
|
||||||
fmt::Debug,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{parser::Tag, render::Renderer};
|
use crate::{parser::Tag, render::Renderer};
|
||||||
|
|
||||||
@@ -15,10 +11,11 @@ mod vertical_layout;
|
|||||||
pub use box_view::BoxView;
|
pub use box_view::BoxView;
|
||||||
pub use color_rect_view::ColorRectView;
|
pub use color_rect_view::ColorRectView;
|
||||||
pub use constraint_layout::ConstraintLayout;
|
pub use constraint_layout::ConstraintLayout;
|
||||||
|
pub use text_view::TextView;
|
||||||
|
|
||||||
pub trait View: Debug {
|
pub trait View: Debug {
|
||||||
fn draw(&mut self, renderer: &mut Renderer, x: f32, y: f32, w: f32, h: f32);
|
fn draw(&mut self, renderer: &mut Renderer, x: f32, y: f32, w: f32, h: f32);
|
||||||
fn resize(&mut self, x: f32, y: f32, w: f32, h: f32);
|
fn resize(&mut self, renderer: &mut Renderer, x: f32, y: f32, w: f32, h: f32);
|
||||||
|
|
||||||
fn from_tag(attributes: &HashMap<String, String>, children: &Vec<Tag>) -> Box<dyn View>
|
fn from_tag(attributes: &HashMap<String, String>, children: &Vec<Tag>) -> Box<dyn View>
|
||||||
where
|
where
|
||||||
|
|||||||
+36
-12
@@ -4,20 +4,21 @@ use std::fmt::Debug;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fonts::{FONTS, FontHandle},
|
fonts::{FONTS, FontHandle},
|
||||||
|
log,
|
||||||
parser::Tag,
|
parser::Tag,
|
||||||
render::{Renderer, buffer::Bitmap},
|
render::{RESOLUTION, Renderer, buffer::Bitmap},
|
||||||
views::{Bounds, View},
|
views::{Bounds, View},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TextView {
|
pub struct TextView {
|
||||||
layout: Layout,
|
pub layout: Layout,
|
||||||
text: String,
|
pub text: String,
|
||||||
scale: f32,
|
pub scale: f32,
|
||||||
font: FontHandle,
|
pub font: FontHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextView {
|
impl TextView {
|
||||||
pub fn new(text: String) -> Self {
|
pub fn new(text: String, scale: f32) -> Self {
|
||||||
let mut layout = Layout::new(CoordinateSystem::PositiveYDown);
|
let mut layout = Layout::new(CoordinateSystem::PositiveYDown);
|
||||||
|
|
||||||
layout.reset(&LayoutSettings {
|
layout.reset(&LayoutSettings {
|
||||||
@@ -27,7 +28,7 @@ impl TextView {
|
|||||||
let mut s = Self {
|
let mut s = Self {
|
||||||
layout,
|
layout,
|
||||||
text,
|
text,
|
||||||
scale: 20.,
|
scale,
|
||||||
font: FontHandle::AtiksonHyperlegibleRegular,
|
font: FontHandle::AtiksonHyperlegibleRegular,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -68,13 +69,24 @@ impl View for TextView {
|
|||||||
|
|
||||||
let scaled = new_bitmap.scale(renderer.ratio_x, renderer.ratio_y);
|
let scaled = new_bitmap.scale(renderer.ratio_x, renderer.ratio_y);
|
||||||
|
|
||||||
renderer.img.overlay_bitmap(&scaled, x as usize, y as usize);
|
renderer
|
||||||
|
.img
|
||||||
|
.overlay_bitmap_fg(&scaled, x as usize, y as usize, (255, 255, 255));
|
||||||
|
|
||||||
// new_bitmap
|
// new_bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize(&mut self, x: f32, y: f32, w: f32, h: f32) {
|
fn resize(&mut self, renderer: &mut Renderer, _x: f32, _y: f32, _w: f32, _h: f32) {
|
||||||
// todo!()
|
self.layout.clear();
|
||||||
|
|
||||||
|
let font = (self.font as usize).clone();
|
||||||
|
let e = (renderer.canvas_height as f32 / renderer.actual_height as f32)
|
||||||
|
* (renderer.canvas_width as f32 / renderer.actual_width as f32);
|
||||||
|
|
||||||
|
let scale = self.scale * e;
|
||||||
|
|
||||||
|
self.layout
|
||||||
|
.append(&FONTS, &TextStyle::new(&self.text, scale, font));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_tag(
|
fn from_tag(
|
||||||
@@ -85,8 +97,20 @@ impl View for TextView {
|
|||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
assert!(children.is_empty(), "TextView does not support children");
|
assert!(children.is_empty(), "TextView does not support children");
|
||||||
todo!()
|
|
||||||
// Self::new(attributes)
|
let text = attributes.get("text").unwrap();
|
||||||
|
|
||||||
|
let mut scale = 30.;
|
||||||
|
|
||||||
|
if let Some(font_size_str) = attributes.get("font_size") {
|
||||||
|
if let Some(font_size) = font_size_str.parse::<f32>().ok() {
|
||||||
|
scale = font_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let this = Self::new(text.clone(), scale);
|
||||||
|
|
||||||
|
Box::new(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
fn as_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
parser::Tag,
|
parser::Tag,
|
||||||
|
render::Renderer,
|
||||||
views::{Bounds, View, box_view::BoxView},
|
views::{Bounds, View, box_view::BoxView},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ impl View for VerticalLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn resize(&mut self, x: f32, y: f32, w: f32, h: f32) {}
|
fn resize(&mut self, renderer: &mut Renderer, x: f32, y: f32, w: f32, h: f32) {}
|
||||||
|
|
||||||
fn from_tag(attributes: &HashMap<String, String>, children: &Vec<Tag>) -> Box<dyn View>
|
fn from_tag(attributes: &HashMap<String, String>, children: &Vec<Tag>) -> Box<dyn View>
|
||||||
where
|
where
|
||||||
|
|||||||
Reference in New Issue
Block a user