fixed clippy warnings, ui refactor

This commit is contained in:
Dmitry
2019-08-15 19:38:56 +03:00
parent 6a3f5295d9
commit a2224bbb66
11 changed files with 501 additions and 297 deletions
+25 -11
View File
@@ -6,19 +6,16 @@
<component name="ChangeListManager">
<list default="true" id="1932b2c4-d6ff-413c-9558-19959667326b" name="Default Changelist" comment="scene graph">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/engine/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/engine/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/game/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/game/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/game/player.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/game/player.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/gui/draw.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/gui/draw.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/gui/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/gui/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/math/mat4.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/mat4.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/physics/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/physics/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/resource/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/resource/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/resource/model.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/resource/model.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/resource/texture.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/resource/texture.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/scene/animation.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/scene/animation.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/scene/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/scene/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/scene/node.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/scene/node.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/utils/pool.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/pool.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/utils/rcpool.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/rcpool.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/math/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/math/ray.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/ray.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/math/triangulator.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/triangulator.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/renderer/renderer.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/renderer/renderer.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/resource/fbx/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/resource/fbx/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/resource/ttf.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/resource/ttf.rs" afterDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
@@ -70,6 +67,17 @@
</option>
</component>
<component name="RunManager" selected="Cargo Command.Release">
<configuration name="Clippy" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="clippy" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="emulateTerminal" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<method v="2" />
</configuration>
<configuration name="Debug" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="run --package rg3d --bin rg3d" />
@@ -103,6 +111,12 @@
<envs />
<method v="2" />
</configuration>
<list>
<item itemvalue="Cargo Command.Release" />
<item itemvalue="Cargo Command.Clippy" />
<item itemvalue="Cargo Command.Test" />
<item itemvalue="Cargo Command.Debug" />
</list>
</component>
<component name="RustProjectSettings">
<option name="toolchainHomeDirectory" value="$USER_HOME$/.cargo/bin" />
+7
View File
@@ -30,6 +30,7 @@ use std::{
time::Instant,
rc::Rc,
};
use crate::gui::ScrollViewerBuilder;
pub struct MenuState {
save_game: Option<()>,
@@ -80,6 +81,12 @@ impl Game {
.with_height(200.0)
.build(ui);
ScrollViewerBuilder::new()
.with_desired_position(Vec2::make(550.0, 300.0))
.with_width(300.0)
.with_height(200.0)
.build(ui);
GridBuilder::new()
.add_column(Column::stretch())
.add_row(Row::strict(50.0))
+5 -7
View File
@@ -3,16 +3,16 @@ use crate::{
math::{
vec2::*,
vec3::*,
quat::*
quat::*,
},
scene::{
node::*,
*
*,
},
physics::Body,
game::{
weapon::{Weapon, WeaponKind},
GameTime
GameTime,
},
engine::State,
};
@@ -128,10 +128,8 @@ impl Player {
}
pub fn next_weapon(&mut self) {
if !self.weapons.is_empty() {
if self.current_weapon < self.weapons.len() - 1 {
self.current_weapon += 1;
}
if !self.weapons.is_empty() && self.current_weapon < self.weapons.len() - 1 {
self.current_weapon += 1;
}
}
+8 -17
View File
@@ -387,11 +387,6 @@ impl DrawingContext {
self.current_nesting = 0;
}
#[inline]
pub fn get_command_buffer(&self) -> &[Command] {
self.command_buffer.as_slice()
}
#[inline]
pub fn get_vertices(&self) -> &[Vertex] {
self.vertex_buffer.as_slice()
@@ -508,7 +503,7 @@ impl DrawingContext {
}
}
return false;
false
}
pub fn push_line(&mut self, a: &Vec2, b: &Vec2, thickness: f32, color: Color) {
@@ -574,7 +569,7 @@ impl DrawingContext {
self.push_triangle(index, index + 2, index + 3);
}
pub fn commit(&mut self, kind: CommandKind, texture: u32) -> Option<usize> {
pub fn commit(&mut self, kind: CommandKind, texture: u32) {
if self.triangles_to_commit > 0 {
let command = Command {
kind,
@@ -585,16 +580,12 @@ impl DrawingContext {
} else { 0 },
triangle_count: self.triangles_to_commit,
};
let index = self.command_buffer.len();
self.command_buffer.push(command);
self.triangles_to_commit = 0;
Some(index)
} else {
None
}
}
pub fn draw_text(&mut self, position: Vec2, formatted_text: &FormattedText) -> Option<usize> {
pub fn draw_text(&mut self, position: Vec2, formatted_text: &FormattedText) {
for element in formatted_text.glyphs.iter() {
let final_bounds = Rect::new(
position.x + element.bounds.x,
@@ -604,14 +595,14 @@ impl DrawingContext {
self.push_rect_filled(&final_bounds, Some(&element.tex_coords), element.color);
}
return self.commit(CommandKind::Geometry, formatted_text.texture);
self.commit(CommandKind::Geometry, formatted_text.texture)
}
pub fn commit_clip_rect(&mut self, clip_rect: &Rect<f32>) -> usize {
pub fn commit_clip_rect(&mut self, clip_rect: &Rect<f32>) {
self.push_rect_filled(clip_rect, None, Color::black());
let command_index = self.commit(CommandKind::Clip, 0).unwrap();
self.clip_cmd_stack.push(command_index);
command_index
let index = self.command_buffer.len();
self.commit(CommandKind::Clip, 0);
self.clip_cmd_stack.push(index);
}
pub fn ready_to_draw(&self) -> bool {
+408 -208
View File
@@ -84,6 +84,7 @@ pub enum Visibility {
#[derive(Debug)]
pub struct Text {
owner_handle: Handle<UINode>,
need_update: bool,
text: String,
font: Handle<Font>,
@@ -92,9 +93,30 @@ pub struct Text {
formatted_text: Option<FormattedText>,
}
impl Drawable for Text {
fn draw(&mut self, drawing_context: &mut DrawingContext, font_cache: &Pool<Font>, bounds: &Rect<f32>, color: Color) {
if self.need_update {
if let Some(font) = font_cache.borrow(&self.font) {
let formatted_text = FormattedTextBuilder::reuse(self.formatted_text.take().unwrap())
.with_size(Vec2::make(bounds.w, bounds.h))
.with_font(font)
.with_text(self.text.as_str())
.with_color(color)
.with_horizontal_alignment(self.horizontal_alignment)
.with_vertical_alignment(self.vertical_alignment)
.build();
self.formatted_text = Some(formatted_text);
}
self.need_update = true; // TODO
}
drawing_context.draw_text(Vec2::make(bounds.x, bounds.y), self.formatted_text.as_ref().unwrap());
}
}
impl Text {
pub fn new() -> Text {
Text {
owner_handle: Handle::none(),
text: String::new(),
need_update: true,
vertical_alignment: VerticalAlignment::Top,
@@ -331,7 +353,7 @@ impl CanvasBuilder {
impl_default_builder_methods!();
pub fn build(self, ui: &mut UserInterface) -> Handle<UINode> {
GenericNodeBuilder::new(UINodeKind::Canvas(Canvas {}), self.common).build(ui)
GenericNodeBuilder::new(UINodeKind::Canvas(Canvas::new()), self.common).build(ui)
}
}
@@ -439,17 +461,30 @@ impl BorderBuilder {
}
}
pub trait Layout {
trait Layout {
fn measure_override(&mut self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, available_size: &Vec2) -> Vec2;
fn arrange_override(&self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, final_size: &Vec2) -> Vec2;
}
trait Drawable {
fn draw(&mut self, drawing_context: &mut DrawingContext, font_cache: &Pool<Font>, bounds: &Rect<f32>, color: Color);
}
#[derive(Debug)]
pub struct Border {
owner_handle: Handle<UINode>,
stroke_thickness: Thickness,
stroke_color: Color,
}
impl Drawable for Border {
fn draw(&mut self, drawing_context: &mut DrawingContext, font_cache: &Pool<Font>, bounds: &Rect<f32>, color: Color) {
drawing_context.push_rect_filled(&bounds, None, color);
drawing_context.push_rect_vary(&bounds, self.stroke_thickness, self.stroke_color);
drawing_context.commit(CommandKind::Geometry, 0);
}
}
impl Layout for Border {
fn measure_override(&mut self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, available_size: &Vec2) -> Vec2 {
let margin_x = self.stroke_thickness.left + self.stroke_thickness.right;
@@ -496,28 +531,25 @@ impl Layout for Border {
impl Layout for UINodeKind {
fn measure_override(&mut self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, available_size: &Vec2) -> Vec2 {
match self {
UINodeKind::Border(border) => border.measure_override(ui, children, available_size),
UINodeKind::Canvas(canvas) => canvas.measure_override(ui, children, available_size),
UINodeKind::Grid(grid) => grid.measure_override(ui, children, available_size),
UINodeKind::Border(border) => border.measure_override( ui, children, available_size),
UINodeKind::Canvas(canvas) => canvas.measure_override( ui, children, available_size),
UINodeKind::Grid(grid) => grid.measure_override( ui, children, available_size),
UINodeKind::ScrollContentPresenter(scp) => scp.measure_override( ui, children, available_size),
UINodeKind::ScrollViewer(scroll_viewer) => scroll_viewer.measure_override( ui, children, available_size),
UINodeKind::ScrollBar(scroll_bar) => scroll_bar.measure_override( ui, children, available_size),
_ => ui.default_measure_override(children, available_size)
}
}
fn arrange_override(&self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, final_size: &Vec2) -> Vec2 {
match self {
UINodeKind::Border(border) => border.arrange_override(ui, children, final_size),
UINodeKind::Canvas(canvas) => canvas.arrange_override(ui, children, final_size),
UINodeKind::Grid(grid) => grid.arrange_override(ui, children, final_size),
// Default arrangement
_ => {
let final_rect = Rect::new(0.0, 0.0, final_size.x, final_size.y);
for child_handle in children.iter() {
ui.arrange(child_handle, &final_rect);
}
*final_size
}
UINodeKind::Border(border) => border.arrange_override( ui, children, final_size),
UINodeKind::Canvas(canvas) => canvas.arrange_override( ui, children, final_size),
UINodeKind::Grid(grid) => grid.arrange_override( ui, children, final_size),
UINodeKind::ScrollContentPresenter(scp) => scp.arrange_override( ui, children, final_size),
UINodeKind::ScrollViewer(scroll_viewer) => scroll_viewer.arrange_override( ui, children, final_size),
UINodeKind::ScrollBar(scroll_bar) => scroll_bar.arrange_override( ui, children, final_size),
_ => ui.default_arrange_override(children, final_size)
}
}
}
@@ -525,6 +557,7 @@ impl Layout for UINodeKind {
impl Border {
pub fn new() -> Border {
Border {
owner_handle: Handle::none(),
stroke_thickness: Thickness {
left: 1.0,
right: 1.0,
@@ -547,16 +580,25 @@ impl Border {
}
pub struct Image {
texture: RcHandle<Resource>
owner_handle: Handle<UINode>,
texture: RcHandle<Resource>,
}
pub type ButtonClickEventHandler = dyn FnMut(&mut UserInterface, Handle<UINode>);
pub struct Button {
click: Option<Box<ButtonClickEventHandler>>
owner_handle: Handle<UINode>,
click: Option<Box<ButtonClickEventHandler>>,
}
impl Button {
pub fn new() -> Self {
Self {
owner_handle: Handle::none(),
click: None,
}
}
pub fn set_on_click(&mut self, handler: Box<ButtonClickEventHandler>) {
self.click = Some(handler);
}
@@ -604,8 +646,11 @@ impl ButtonBuilder {
let pressed_color = Color::opaque(100, 100, 100);
let hover_color = Color::opaque(160, 160, 160);
let mut button = Button::new();
button.click = self.click;
GenericNodeBuilder::new(
UINodeKind::Button(Button { click: self.click }), self.common)
UINodeKind::Button(button), self.common)
.with_handler(RoutedEventHandlerType::MouseDown, Box::new(move |ui, handle, _evt| {
ui.capture_mouse(&handle);
}))
@@ -681,9 +726,8 @@ impl ButtonBuilder {
}
}
pub type ValueChanged = dyn FnMut(&mut UserInterface, Handle<UINode>, f32, f32);
pub struct ScrollBar {
owner_handle: Handle<UINode>,
min: f32,
max: f32,
value: f32,
@@ -691,15 +735,16 @@ pub struct ScrollBar {
orientation: Orientation,
is_dragging: bool,
offset: Vec2,
value_changed: Option<Box<ValueChanged>>,
value_changed: bool,
}
impl ScrollBar {
const PART_CANVAS: &'static str = "PART_Canvas";
const PART_INDICATOR: &'static str = "PART_Indicator";
pub const PART_CANVAS: &'static str = "PART_Canvas";
pub const PART_INDICATOR: &'static str = "PART_Indicator";
pub fn new() -> Self {
fn new() -> Self {
Self {
owner_handle: Handle::none(),
min: 0.0,
max: 100.0,
value: 0.0,
@@ -707,73 +752,56 @@ impl ScrollBar {
orientation: Orientation::Horizontal,
is_dragging: false,
offset: Vec2::new(),
value_changed: None,
value_changed: false,
}
}
pub fn set_value(ui: &mut UserInterface, handle: &Handle<UINode>, value: f32) {
let mut value_changed = None;
let old_value;
let new_value;
let min;
let max;
let orientation;
match ui.nodes.borrow_mut(handle) {
Some(scroll_bar_node) => {
match scroll_bar_node.get_kind_mut() {
UINodeKind::ScrollBar(scroll_bar) => {
orientation = scroll_bar.orientation;
min = scroll_bar.min;
max = scroll_bar.max;
old_value = scroll_bar.value;
new_value = math::clampf(value, min, max);
if new_value != old_value {
scroll_bar.value = new_value;
value_changed = scroll_bar.value_changed.take();
}
}
_ => return
}
}
_ => return
pub fn set_value(&mut self, value: f32) {
let old_value = self.value;
let new_value = math::clampf(value, self.min, self.max);
if new_value != old_value {
self.value = new_value;
self.value_changed = true;
}
}
}
if let Some(ref mut handler) = value_changed {
handler(ui, handle.clone(), new_value, old_value);
}
impl Layout for ScrollBar {
fn measure_override(&mut self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, available_size: &Vec2) -> Vec2 {
ui.default_measure_override(children, available_size)
}
if let Some(scroll_bar_node) = ui.nodes.borrow_mut(handle) {
if let UINodeKind::ScrollBar(scroll_bar) = scroll_bar_node.get_kind_mut() {
scroll_bar.value_changed = value_changed.take();
}
}
fn arrange_override(&self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, final_size: &Vec2) -> Vec2 {
let size = ui.default_arrange_override(children, final_size);
// Update indicator
let percent = (new_value - min) / (max - min);
// Adjust indicator position according to current value
let percent = (self.value - self.min) / (self.max - self.min);
let field_size = match ui.borrow_by_name_down(handle, Self::PART_CANVAS) {
let field_size = match ui.borrow_by_name_down(&self.owner_handle, Self::PART_CANVAS) {
Some(canvas) => canvas.actual_size,
None => {
println!("Unable to find part canvas!");
return;
}
None => return size
};
if let Some(node) = ui.borrow_by_name_down_mut(handle, Self::PART_INDICATOR) {
match orientation {
if let Some(node) = ui.borrow_by_name_down_mut(&self.owner_handle, Self::PART_INDICATOR) {
match self.orientation {
Orientation::Horizontal => {
node.desired_local_position.x = percent * maxf(0.0, field_size.x - node.actual_size.x);
node.desired_local_position.y = 0.0;
node.set_desired_local_position(Vec2::make(
percent * maxf(0.0, field_size.x - node.actual_size.x),
0.0)
);
node.height = field_size.y;
}
Orientation::Vertical => {
node.desired_local_position.x = 0.0;
node.desired_local_position.y = percent * maxf(0.0, field_size.y - node.actual_size.y);
node.set_desired_local_position(Vec2::make(
0.0,
percent * maxf(0.0, field_size.y - node.actual_size.y))
);
node.width = field_size.x;
}
}
}
size
}
}
@@ -867,25 +895,21 @@ impl ScrollBarBuilder {
Orientation::Horizontal => std::f32::NAN,
Orientation::Vertical => 30.0
})
.with_text("<")
.with_text(match orientation {
Orientation::Horizontal => "<",
Orientation::Vertical => "^"
})
.with_click(Box::new(move |ui, handle| {
let scroll_bar_handle = ui.find_by_criteria_up(&handle, |node| match node.kind {
UINodeKind::ScrollBar(..) => true,
_ => false
});
let new_value = if let Some(scroll_bar_node) = ui.nodes.borrow(&scroll_bar_handle) {
if let UINodeKind::ScrollBar(scroll_bar) = scroll_bar_node.get_kind() {
scroll_bar.value - scroll_bar.step
} else {
return;
if let Some(scroll_bar_node) = ui.nodes.borrow_mut(&scroll_bar_handle) {
if let UINodeKind::ScrollBar(scroll_bar) = scroll_bar_node.get_kind_mut() {
scroll_bar.set_value(scroll_bar.value - scroll_bar.step);
}
} else {
println!("ScrollBar state is already borrowed!");
return;
};
ScrollBar::set_value(ui, &scroll_bar_handle, new_value);
}
}))
.build(ui)
)
@@ -902,7 +926,10 @@ impl ScrollBarBuilder {
.with_child(BorderBuilder::new()
.with_name(ScrollBar::PART_INDICATOR)
.with_stroke_color(Color::opaque(50, 50, 50))
.with_stroke_thickness(Thickness { left: 1.0, top: 0.0, right: 1.0, bottom: 0.0 })
.with_stroke_thickness(match orientation {
Orientation::Horizontal => Thickness { left: 1.0, top: 0.0, right: 1.0, bottom: 0.0 },
Orientation::Vertical => Thickness { left: 0.0, top: 1.0, right: 0.0, bottom: 1.0 }
})
.with_color(Color::opaque(255, 255, 255))
.with_width(30.0)
.with_height(30.0)
@@ -946,26 +973,25 @@ impl ScrollBarBuilder {
_ => return
};
let new_value;
if let Some(scroll_bar_node) = ui.borrow_by_criteria_up(&handle, |node| match node.kind {
let (field_pos, field_size) =
match ui.borrow_by_name_up(&handle, ScrollBar::PART_CANVAS) {
Some(canvas) => (canvas.screen_position, canvas.actual_size),
None => return
};
let bar_size = match ui.nodes.borrow(&handle) {
Some(node) => node.actual_size,
None => return
};
if let Some(scroll_bar_node) = ui.borrow_by_criteria_up_mut(&handle, |node| match node.kind {
UINodeKind::ScrollBar(..) => true,
_ => false
}) {
if let UINodeKind::ScrollBar(scroll_bar) = scroll_bar_node.get_kind() {
if let UINodeKind::ScrollBar(scroll_bar) = scroll_bar_node.get_kind_mut() {
let orientation = scroll_bar.orientation;
if scroll_bar.is_dragging {
let bar_size = match ui.nodes.borrow(&handle) {
Some(node) => node.actual_size,
None => return
};
let (field_pos, field_size) =
match ui.borrow_by_name_up(&handle, ScrollBar::PART_CANVAS) {
Some(canvas) => (canvas.screen_position, canvas.actual_size),
None => return
};
let percent = match orientation {
Orientation::Horizontal => {
let span = field_size.x - bar_size.x;
@@ -987,26 +1013,14 @@ impl ScrollBarBuilder {
}
};
new_value = percent * (scroll_bar.max - scroll_bar.min);
let new_value = percent * (scroll_bar.max - scroll_bar.min);
evt.handled = true;
} else {
return;
scroll_bar.set_value(new_value);
}
} else {
return;
}
} else {
println!("ScrollBar state is already borrowed!");
return;
}
let scroll_bar = ui.find_by_criteria_up(&handle, |node| match node.kind {
UINodeKind::ScrollBar(..) => true,
_ => false
});
ScrollBar::set_value(ui, &scroll_bar, new_value);
}))
.build(ui)
)
@@ -1035,20 +1049,16 @@ impl ScrollBarBuilder {
_ => false
});
let new_value = if let Some(scroll_bar_node) = ui.nodes.borrow(&scroll_bar_handle) {
if let UINodeKind::ScrollBar(scroll_bar) = scroll_bar_node.get_kind() {
scroll_bar.value + scroll_bar.step
} else {
return;
if let Some(scroll_bar_node) = ui.nodes.borrow_mut(&scroll_bar_handle) {
if let UINodeKind::ScrollBar(scroll_bar) = scroll_bar_node.get_kind_mut() {
scroll_bar.set_value(scroll_bar.value + scroll_bar.step);
}
} else {
println!("ScrollBar state is already borrowed!");
return;
};
ScrollBar::set_value(ui, &scroll_bar_handle, new_value);
}
}))
.with_text(">")
.with_text(match orientation {
Orientation::Horizontal => ">",
Orientation::Vertical => "v"
})
.build(ui)
)
.build(ui)
@@ -1056,27 +1066,70 @@ impl ScrollBarBuilder {
.build(ui)
)
.build(ui);
// We have to defer update of scroll bar indicator, because it can't be update right now since
// we do not have enough information about environment.
ui.begin_invoke({
let scroll_bar_handle = scroll_bar_handle.clone();
Box::new(move |ui| {
ScrollBar::set_value(ui, &scroll_bar_handle, min);
})
});
scroll_bar_handle
}
}
pub struct ScrollContentPresenter {
owner_handle: Handle<UINode>,
scroll: Vec2,
vertical_scroll_allowed: bool,
horizontal_scroll_allowed: bool,
}
impl Layout for ScrollContentPresenter {
fn measure_override(&mut self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, available_size: &Vec2) -> Vec2 {
let size_for_child = Vec2::make(
if self.horizontal_scroll_allowed {
std::f32::INFINITY
} else {
available_size.x
},
if self.vertical_scroll_allowed {
std::f32::INFINITY
} else {
available_size.y
},
);
let mut desired_size = Vec2::new();
for child_handle in children.iter() {
ui.measure(child_handle, &size_for_child);
if let Some(child) = ui.nodes.borrow(child_handle) {
if child.desired_size.x > desired_size.x {
desired_size.x = child.desired_size.x;
}
if child.desired_size.y > desired_size.y {
desired_size.y = child.desired_size.y;
}
}
}
desired_size
}
fn arrange_override(&self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, final_size: &Vec2) -> Vec2 {
let child_rect = Rect::new(
-self.scroll.x,
-self.scroll.y,
final_size.x + self.scroll.x,
final_size.y + self.scroll.y,
);
for child_handle in children.iter() {
ui.arrange(child_handle, &child_rect);
}
*final_size
}
}
impl ScrollContentPresenter {
pub fn new() -> Self {
Self {
owner_handle: Handle::none(),
scroll: Vec2::new(),
vertical_scroll_allowed: true,
horizontal_scroll_allowed: true,
@@ -1132,6 +1185,129 @@ impl ScrollContentPresenterBuilder {
}
}
pub struct ScrollViewer {
owner_handle: Handle<UINode>,
}
impl ScrollViewer {
pub const PART_CONTENT_PRESENTER: &'static str = "PART_ContentPresenter";
pub const PART_V_SCROLL_BAR: &'static str = "PART_VScrollBar";
pub const PART_H_SCROLL_BAR: &'static str = "PART_HScrollBar";
pub fn new() -> Self {
Self {
owner_handle: Handle::none(),
}
}
}
impl Layout for ScrollViewer {
fn measure_override(&mut self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, available_size: &Vec2) -> Vec2 {
// Use default measure.
let desired_size = ui.default_measure_override(children, available_size);
// Try to find parts in children first.
let mut content_presenter_handle = Handle::none();
let mut horizontal_scroll_bar_handle = Handle::none();
let mut vertical_scroll_bar_handle = Handle::none();
let cp = ui.find_by_name_down(&self.owner_handle, ScrollViewer::PART_CONTENT_PRESENTER);
if cp.is_some() {
content_presenter_handle = cp;
}
let hor_scroll_bar = ui.find_by_name_down(&self.owner_handle, ScrollViewer::PART_H_SCROLL_BAR);
if hor_scroll_bar.is_some() {
horizontal_scroll_bar_handle = hor_scroll_bar;
}
let ver_scroll_bar = ui.find_by_name_down(&self.owner_handle, ScrollViewer::PART_V_SCROLL_BAR);
if ver_scroll_bar.is_some() {
vertical_scroll_bar_handle = ver_scroll_bar;
}
let mut content_size = Vec2::new();
let mut available_size_for_content = Vec2::new();
if let Some(content_presenter) = ui.nodes.borrow(&content_presenter_handle) {
available_size_for_content = content_presenter.desired_size;
for content_handle in content_presenter.children.iter() {
if let Some(content) = ui.nodes.borrow(content_handle) {
if content.desired_size.x > content_size.x {
content_size.x = content.desired_size.x;
}
if content.desired_size.y > content_size.y {
content_size.y = content.desired_size.y;
}
}
}
}
// Then adjust scroll bars according to content size.
/*
if let Some(horizontal_scroll_bar) = ui.nodes.borrow_mut(&horizontal_scroll_bar_handle) {
if let Some()
}
let max = maxf(0.0, sv -> content -> desired_size.x - sv -> scroll_content_presenter -> desired_size.x);
de_gui_scroll_bar_set_max_value(sv -> hor_scroll_bar, max);
let max = maxf(0.0, sv -> content -> desired_size.y - sv -> scroll_content_presenter -> desired_size.y);
de_gui_scroll_bar_set_max_value(sv -> ver_scroll_bar, max);
*/
desired_size
}
fn arrange_override(&self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, final_size: &Vec2) -> Vec2 {
ui.default_arrange_override(children, final_size)
}
}
pub struct ScrollViewerBuilder {
common: CommonBuilderFields
}
impl ScrollViewerBuilder {
pub fn new() -> Self {
Self {
common: CommonBuilderFields::new()
}
}
impl_default_builder_methods!();
pub fn build(self, ui: &mut UserInterface) -> Handle<UINode> {
GenericNodeBuilder::new(UINodeKind::ScrollViewer(ScrollViewer::new()), self.common)
.with_child(GridBuilder::new()
.add_row(Row::stretch())
.add_row(Row::strict(20.0))
.add_column(Column::stretch())
.add_column(Column::strict(20.0))
.with_child(ScrollContentPresenterBuilder::new()
.with_name(ScrollViewer::PART_CONTENT_PRESENTER)
.with_child(BorderBuilder::new()
.with_color(Color::opaque(200, 0, 0))
.build(ui))
.on_row(0)
.on_column(0)
.build(ui))
.with_child(ScrollBarBuilder::new()
.with_name(ScrollViewer::PART_H_SCROLL_BAR)
.with_orientation(Orientation::Horizontal)
.on_row(1)
.on_column(0)
.build(ui))
.with_child(ScrollBarBuilder::new()
.with_name(ScrollViewer::PART_V_SCROLL_BAR)
.with_orientation(Orientation::Vertical)
.on_row(0)
.on_column(1)
.build(ui))
.build(ui))
.build(ui)
}
}
#[derive(PartialEq)]
pub enum SizeMode {
Strict,
@@ -1230,11 +1406,23 @@ impl Row {
}
pub struct Grid {
owner_handle: Handle<UINode>,
rows: Vec<Row>,
columns: Vec<Column>,
draw_borders: bool,
}
impl Grid {
fn new() -> Self {
Self {
owner_handle: Handle::none(),
rows: Vec::new(),
columns: Vec::new(),
draw_borders: false,
}
}
}
impl Layout for Grid {
fn measure_override(&mut self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, available_size: &Vec2) -> Vec2 {
// In case of no rows or columns, grid acts like default panel.
@@ -1260,10 +1448,8 @@ impl Layout for Grid {
col.actual_width = col.desired_width;
for child_handle in children.iter() {
if let Some(child) = ui.nodes.borrow(child_handle) {
if child.column == i && child.visibility == Visibility::Visible {
if child.desired_size.x > col.actual_width {
col.actual_width = child.desired_size.x;
}
if child.column == i && child.visibility == Visibility::Visible && child.desired_size.x > col.actual_width {
col.actual_width = child.desired_size.x;
}
}
}
@@ -1477,11 +1663,11 @@ impl GridBuilder {
}
pub fn build(mut self, ui: &mut UserInterface) -> Handle<UINode> {
let node = UINode::new(UINodeKind::Grid(Grid {
columns: self.columns,
rows: self.rows,
draw_borders: false,
}));
let mut grid = Grid::new();
grid.columns = self.columns;
grid.rows = self.rows;
let node = UINode::new(UINodeKind::Grid(grid));
let handle = ui.add_node(node);
self.common.apply(ui, &handle);
@@ -1501,7 +1687,17 @@ impl Grid {
}
}
pub struct Canvas {}
pub struct Canvas {
owner_handle: Handle<UINode>
}
impl Canvas {
pub fn new() -> Self {
Self {
owner_handle: Handle::none()
}
}
}
impl Layout for Canvas {
fn measure_override(&mut self, ui: &mut UserInterface, children: &UnsafeCollectionView<Handle<UINode>>, _available_size: &Vec2) -> Vec2 {
@@ -1539,29 +1735,28 @@ impl Layout for Canvas {
}
pub enum UINodeKind {
Base,
Text(Text),
Border(Border),
/// TODO
Window,
Button(Button),
ScrollBar(ScrollBar),
/// TODO
ScrollViewer,
/// TODO
TextBox,
/// TODO
Image,
ScrollViewer(ScrollViewer),
Image(Image),
/// Automatically arranges children by rows and columns
Grid(Grid),
/// Allows user to directly set position and size of a node
Canvas(Canvas),
/// Allows user to scroll content
ScrollContentPresenter(ScrollContentPresenter),
/// TODO
SlideSelector,
/// TODO
CheckBox,
}
impl Drawable for UINodeKind {
fn draw(&mut self, drawing_context: &mut DrawingContext, font_cache: &Pool<Font>, bounds: &Rect<f32>, color: Color) {
match self {
UINodeKind::Text(text) => text.draw(drawing_context, font_cache, bounds, color),
UINodeKind::Border(border) => border.draw(drawing_context, font_cache, bounds, color),
_ => ()
}
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
@@ -1698,25 +1893,46 @@ fn minf(a: f32, b: f32) -> f32 {
}
}
struct ArrangeData {
size: Vec2,
size_without_margin: Vec2,
origin: Vec2
}
impl UserInterface {
pub fn new(default_font: Handle<Font>) -> UserInterface {
let mut nodes = Pool::new();
UserInterface {
let mut ui = UserInterface {
visual_debug: false,
default_font,
captured_node: Handle::none(),
root_canvas: nodes.spawn(UINode::new(UINodeKind::Canvas(Canvas {}))),
nodes,
root_canvas: Handle::none(),
nodes: Pool::new(),
mouse_position: Vec2::new(),
drawing_context: DrawingContext::new(),
picked_node: Handle::none(),
prev_picked_node: Handle::none(),
deferred_actions: VecDeque::new(),
}
};
ui.root_canvas = ui.add_node(UINode::new(UINodeKind::Canvas(Canvas::new())));
ui
}
pub fn add_node(&mut self, node: UINode) -> Handle<UINode> {
let node_handle = self.nodes.spawn(node);
// Notify kind about owner. This is a bit hackish but it'll make a lot of things easier.
if let Some(node) = self.nodes.borrow_mut(&node_handle) {
match &mut node.kind {
UINodeKind::ScrollBar(scroll_bar) => scroll_bar.owner_handle = node_handle.clone(),
UINodeKind::Text(text) => text.owner_handle = node_handle.clone(),
UINodeKind::Border(border) => border.owner_handle = node_handle.clone(),
UINodeKind::Button(button) => button.owner_handle = node_handle.clone(),
UINodeKind::ScrollViewer(scroll_viewer) => scroll_viewer.owner_handle = node_handle.clone(),
UINodeKind::Image(image) => image.owner_handle = node_handle.clone(),
UINodeKind::Grid(grid) => grid.owner_handle = node_handle.clone(),
UINodeKind::Canvas(canvas) => canvas.owner_handle = node_handle.clone(),
UINodeKind::ScrollContentPresenter(scp) => scp.owner_handle = node_handle.clone(),
}
}
self.link_nodes(&node_handle, &self.root_canvas.clone());
node_handle
}
@@ -1872,7 +2088,7 @@ impl UserInterface {
}
}
let desired_size = (unsafe { &mut *node_kind }).measure_override(self, &children, &size_for_child);
let desired_size = (unsafe { &mut *node_kind }).measure_override( self, &children, &size_for_child);
if let Some(node) = self.nodes.borrow_mut(&node_handle) {
node.desired_size = desired_size;
@@ -1909,7 +2125,18 @@ impl UserInterface {
}
}
fn default_arrange_override(&mut self, children: &UnsafeCollectionView<Handle<UINode>>, final_size: &Vec2) -> Vec2 {
let final_rect = Rect::new(0.0, 0.0, final_size.x, final_size.y);
for child_handle in children.iter() {
self.arrange(child_handle, &final_rect);
}
*final_size
}
fn arrange(&mut self, node_handle: &Handle<UINode>, final_rect: &Rect<f32>) {
let children;
let mut size;
let size_without_margin;
@@ -2032,40 +2259,20 @@ impl UserInterface {
let mut children: UnsafeCollectionView<Handle<UINode>> = UnsafeCollectionView::empty();
if let Some(node) = self.nodes.borrow_mut(node_handle) {
let start_index = self.drawing_context.get_commands().len();
let bounds = node.get_screen_bounds();
self.drawing_context.set_nesting(nesting);
node.command_indices.push(self.drawing_context.commit_clip_rect(&bounds.inflate(0.9, 0.9)));
self.drawing_context.commit_clip_rect(&bounds.inflate(0.9, 0.9));
match &mut node.kind {
UINodeKind::Border(border) => {
self.drawing_context.push_rect_filled(&bounds, None, node.color);
self.drawing_context.push_rect_vary(&bounds, border.stroke_thickness, border.stroke_color);
node.command_indices.push(self.drawing_context.commit(CommandKind::Geometry, 0).unwrap());
}
UINodeKind::Text(text) => {
if text.need_update {
if let Some(font) = font_cache.borrow(&text.font) {
let formatted_text = FormattedTextBuilder::reuse(text.formatted_text.take().unwrap())
.with_size(node.actual_size)
.with_font(font)
.with_text(text.text.as_str())
.with_color(node.color)
.with_horizontal_alignment(text.horizontal_alignment)
.with_vertical_alignment(text.vertical_alignment)
.build();
text.formatted_text = Some(formatted_text);
}
text.need_update = true; // TODO
}
if let Some(command_index) = self.drawing_context.draw_text(node.screen_position, text.formatted_text.as_ref().unwrap()) {
node.command_indices.push(command_index);
}
}
_ => ()
}
node.kind.draw(&mut self.drawing_context, font_cache, &bounds, node.color);
children = UnsafeCollectionView::from_vec(&node.children);
let end_index = self.drawing_context.get_commands().len();
for i in start_index..end_index {
node.command_indices.push(i);
}
}
// Continue on children
@@ -2111,21 +2318,16 @@ impl UserInterface {
for command_index in node.command_indices.iter() {
if let Some(command) = self.drawing_context.get_commands().get(*command_index) {
if *command.get_kind() == CommandKind::Clip {
if self.drawing_context.is_command_contains_point(command, pt) {
clipped = false;
break;
}
if *command.get_kind() == CommandKind::Clip && self.drawing_context.is_command_contains_point(command, pt) {
clipped = false;
break;
}
}
}
// Point can be clipped by parent's clipping geometry.
if !node.parent.is_none() {
if !clipped {
clipped |= self.is_node_clipped(&node.parent, pt);
}
if !node.parent.is_none() && !clipped {
clipped |= self.is_node_clipped(&node.parent, pt);
}
}
@@ -2141,10 +2343,8 @@ impl UserInterface {
if !self.is_node_clipped(node_handle, pt) {
for command_index in node.command_indices.iter() {
if let Some(command) = self.drawing_context.get_commands().get(*command_index) {
if *command.get_kind() == CommandKind::Geometry {
if self.drawing_context.is_command_contains_point(command, pt) {
return true;
}
if *command.get_kind() == CommandKind::Geometry && self.drawing_context.is_command_contains_point(command, pt) {
return true;
}
}
}
+4 -4
View File
@@ -110,11 +110,11 @@ pub fn vec3_to_vec2_by_plane(plane_class: PlaneClass, normal: Vec3, point: Vec3)
}
}
pub fn is_point_inside_2d_triangle(point: Vec2, a: Vec2, b: Vec2, c: Vec2) -> bool {
let ba = b - a;
let ca = c - a;
pub fn is_point_inside_2d_triangle(point: Vec2, pt_a: Vec2, pt_b: Vec2, pt_c: Vec2) -> bool {
let ba = pt_b - pt_a;
let ca = pt_c - pt_a;
let vp = point - a;
let vp = point - pt_a;
let ba_dot_ba = ba.dot(ba);
let ca_dot_ba = ca.dot(ba);
+2 -2
View File
@@ -43,7 +43,7 @@ impl Ray {
let discr_root = discriminant.sqrt();
let r1 = (-b + discr_root) / 2.0;
let r2 = (-b - discr_root) / 2.0;
return Some((self.origin + self.dir.scale(r1), self.origin + self.dir.scale(r2)));
Some((self.origin + self.dir.scale(r1), self.origin + self.dir.scale(r2)))
}
/// Checks intersection with sphere.
@@ -54,7 +54,7 @@ impl Ray {
let b = 2.0 * self.dir.dot(&d);
let c = d.dot(&d) - radius * radius;
let discriminant = b * b - 4.0 * a * c;
return discriminant >= 0.0;
discriminant >= 0.0
}
/// Returns t factor (at pt=o+d*t equation) for projection of given point at ray
+5 -6
View File
@@ -2,7 +2,7 @@ use crate::{
math::{
vec2::*,
vec3::*,
self
self,
}
};
use std::fmt;
@@ -80,10 +80,9 @@ fn is_ear(poly: &Polygon, prev: &Vertex, ear: &Vertex, next: &Vertex) -> bool {
let mut i = poly.head;
loop {
let vertex = &poly.vertices[i];
if i != prev.index && i != ear.index && i != next.index {
if math::is_point_inside_2d_triangle(vertex.position, prev.position, ear.position, next.position) {
return false;
}
if i != prev.index && i != ear.index && i != next.index &&
math::is_point_inside_2d_triangle(vertex.position, prev.position, ear.position, next.position) {
return false;
}
i = vertex.next;
if i == poly.head {
@@ -91,7 +90,7 @@ fn is_ear(poly: &Polygon, prev: &Vertex, ear: &Vertex, next: &Vertex) -> bool {
}
}
return true;
true
}
///
+1 -1
View File
@@ -635,7 +635,7 @@ impl Renderer {
1.0);
gl::UniformMatrix4fv(self.ui_shader.wvp_matrix, 1, gl::FALSE, ortho.f.as_ptr() as *const f32);
for cmd in drawing_context.get_command_buffer() {
for cmd in drawing_context.get_commands() {
let index_count = cmd.get_triangle_count() * 3;
if cmd.get_nesting() != 0 {
gl::Enable(gl::STENCIL_TEST);
+12 -14
View File
@@ -4,7 +4,7 @@ use crate::{
math::{vec4::*, vec3::*, vec2::*, mat4::*, quat::*, triangulator::*},
scene::{*, node::*},
renderer::surface::{SurfaceSharedData, Surface, Vertex},
engine::State
engine::State,
};
pub enum FbxAttribute {
@@ -291,18 +291,18 @@ struct FbxNode {
impl FbxNode {
fn get_vec3_at(&self, n: usize) -> Result<Vec3, String> {
return Ok(Vec3 {
Ok(Vec3 {
x: self.get_attrib(n)?.as_f32()?,
y: self.get_attrib(n + 1)?.as_f32()?,
z: self.get_attrib(n + 2)?.as_f32()?,
});
})
}
fn get_vec2_at(&self, n: usize) -> Result<Vec2, String> {
return Ok(Vec2 {
Ok(Vec2 {
x: self.get_attrib(n)?.as_f32()?,
y: self.get_attrib(n + 1)?.as_f32()?,
});
})
}
fn get_attrib(&self, n: usize) -> Result<&FbxAttribute, String> {
@@ -448,7 +448,7 @@ impl FbxGeometry {
}
}
return Ok(geom);
Ok(geom)
}
}
@@ -559,7 +559,7 @@ impl FbxModel {
_ => () // Unused properties
}
}
return Ok(model);
Ok(model)
}
}
@@ -807,12 +807,10 @@ fn read_ascii(path: &Path) -> Result<Fbx, String> {
return Err(String::from("FBX: Failed to fetch node by handle when committing attribute"));
}
value.clear();
} else if !read_value {
name.push(symbol);
} else {
if !read_value {
name.push(symbol);
} else {
value.push(symbol);
}
value.push(symbol);
}
}
}
@@ -912,7 +910,7 @@ fn prepare_next_face(geom: &FbxGeometry,
}
}
return vertex_per_face;
vertex_per_face
}
fn convert_vertex(geom: &FbxGeometry,
@@ -1057,7 +1055,7 @@ impl Fbx {
}
}
return Ok(());
Ok(())
}
fn convert_light(&self, light: &mut Light, fbx_light: &FbxLight) {
+24 -27
View File
@@ -3,16 +3,16 @@
use crate::{
math::{
vec2::Vec2,
Rect
Rect,
},
utils::pool::{Pool, Handle}
utils::pool::{Pool, Handle},
};
use std::{
cmp::Ordering,
collections::HashMap,
path::{Path},
path::Path,
fs::File,
io::Read
io::Read,
};
const ON_CURVE_POINT: u8 = 1;
@@ -214,7 +214,7 @@ impl Bitmap {
return 0.0;
}
return self.pixels[y * self.width + x] as f32 / 255.0;
self.pixels[y * self.width + x] as f32 / 255.0
}
}
@@ -223,7 +223,7 @@ fn get_u16(p: *const u8) -> u16
unsafe {
let b0 = *p as u32;
let b1 = *p.offset(1) as u32;
return (b0 * 256 + b1) as u16;
(b0 * 256 + b1) as u16
}
}
@@ -232,7 +232,7 @@ fn get_i16(p: *const u8) -> i16
unsafe {
let b0 = *p as i32;
let b1 = *p.offset(1) as i32;
return (b0 * 256 + b1) as i16;
(b0 * 256 + b1) as i16
}
}
@@ -243,7 +243,7 @@ fn get_u32(p: *const u8) -> u32
let b1 = *p.offset(1) as u32;
let b2 = *p.offset(2) as u32;
let b3 = *p.offset(3) as u32;
return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
(b0 << 24) + (b1 << 16) + (b2 << 8) + b3
}
}
@@ -280,7 +280,7 @@ fn segmented_mapping(subtable: *const u8, unicode: u32) -> usize {
}
}
return 0;
0
}
}
@@ -292,7 +292,7 @@ fn direct_mapping(subtable: *const u8, unicode: u32) -> usize {
}
}
return 0;
0
}
fn dense_mapping(subtable: *const u8, unicode: u32) -> usize {
@@ -306,7 +306,7 @@ fn dense_mapping(subtable: *const u8, unicode: u32) -> usize {
}
}
return 0;
0
}
fn line_line_intersection(a: &Line2, b: &Line2) -> Option<Point> {
@@ -393,8 +393,8 @@ fn polygons_to_scanlines(polys: &Vec<Polygon>, width: f32, height: f32, scale: f
if intersections.len() > 0 {
for i in (0..(intersections.len() - 1)).step_by(2) {
let line = Line2 {
begin: Point { x: intersections[i].x, y: y, flags: 0 },
end: Point { x: intersections[i + 1].x, y: y, flags: 0 },
begin: Point { x: intersections[i].x, y, flags: 0 },
end: Point { x: intersections[i + 1].x, y, flags: 0 },
};
lines.push(line);
}
@@ -447,7 +447,7 @@ fn raster_scanlines(w: usize, h: usize, lines: &Vec<Line2>) -> Bitmap {
}
}
return out_bitmap;
out_bitmap
}
impl TrueType {
@@ -521,7 +521,7 @@ impl TrueType {
}
}
return 0;
0
}
fn get_glyph_offset(&self, index: usize) -> isize {
@@ -673,11 +673,9 @@ impl TrueType {
let dx = *coords as i32;
coords = coords.offset(1);
x += if (pt.flags & 16) != 0 { dx } else { -dx };
} else {
if (pt.flags & 16) == 0 {
x += get_i16(coords) as i32;
coords = coords.offset(2);
}
} else if (pt.flags & 16) == 0 {
x += get_i16(coords) as i32;
coords = coords.offset(2);
}
pt.x = x as f32;
}
@@ -690,12 +688,11 @@ impl TrueType {
let dy = *coords as i32;
coords = coords.offset(1);
y += if (pt.flags & 32) != 0 { dy } else { -dy };
} else {
if (pt.flags & 32) == 0 {
y += get_i16(coords) as i32;
coords = coords.offset(2);
}
} else if (pt.flags & 32) == 0 {
y += get_i16(coords) as i32;
coords = coords.offset(2);
}
pt.y = y as f32;
}
@@ -941,7 +938,7 @@ impl Font {
}
#[inline]
pub fn set_texture_id(&mut self, id: u32) {
pub fn set_texture_id(&mut self, id: u32) {
self.texture_id = id;
}
@@ -1057,7 +1054,7 @@ impl FontGlyph {
#[test]
fn font_test() {
use image::ColorType;
use std::path::{PathBuf};
use std::path::PathBuf;
let font = Font::load(Path::new("data/fonts/font.ttf"), 40.0, (0..255).collect()).unwrap();
let raster_path = Path::new("data/raster");