Created
March 2, 2019 19:50
-
-
Save TuckerBMorgan/35b798cd8bad38f73d3ed6bf07f75274 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use sdl2::render::{WindowCanvas, BlendMode}; | |
| use sdl2::pixels::Color; | |
| use sdl2::rect::{Point, Rect}; | |
| pub trait FauxGFX { | |
| fn draw_quadrants(&mut self, p: Point, dp: Point, f: i32) -> Result<(), String>; | |
| fn pixel_rgba_weight(&mut self, p: Point, color: Color, weight: i32) -> Result<(), String>; | |
| fn pixel_rgba(&mut self, p: Point, color: Color) -> Result<(), String>; | |
| fn pixel(&mut self, p: Point) -> Result<(), String>; | |
| fn vline(&mut self, x: i32, y1: i32, y2: i32) -> Result<(), String>; | |
| fn vline_rgba(&mut self, x: i32, y1: i32, y2: i32, color: Color) -> Result<(), String>; | |
| fn hline(&mut self, x1: i32, x2: i32, y: i32) -> Result<(), String>; | |
| fn hline_rgba(&mut self, x1: i32, x2: i32, y: i32, color: Color) -> Result<(), String>; | |
| fn ellipse_rgba(&mut self, p: Point, radius_x: i16, radius_y: i16, color: Color, f: i32) -> Result<(), String>; | |
| fn filled_circle(&mut self, p: Point, rad: i16, color: Color) -> Result<(), String>; | |
| fn filled_polygon_rgba_mt(&mut self, verts: Vec<Point>, color: Color) -> Result<(), String>; | |
| fn thick_line(&mut self, start: Point, end: Point, width: i32, color: Color)-> Result<(), String>; | |
| fn box_rgba(&mut self, top_right: Point, bottom_left: Point, color: Color) -> Result<(), String>; | |
| fn line_rgba(&mut self, start: Point, end: Point, color: Color) -> Result<(), String>; | |
| fn rectangle_rgba(&mut self, top_right: Point, bottom_left: Point, color: Color) -> Result<(), String>; | |
| fn rounded_rentangle_rgba(&mut self, top_right: Point, bottom_left: Point, radius: i32, color: Color)-> Result<(), String>; | |
| fn arc_rgba(&mut self,p: Point, radius: i32, start: i32, end: i32, color: Color) -> Result<(), String>; | |
| } | |
| impl FauxGFX for WindowCanvas { | |
| fn line_rgba(&mut self, start: Point, end: Point, color: Color) -> Result<(), String> { | |
| let blend_mode : BlendMode; | |
| if color.a == 255 { | |
| blend_mode = BlendMode::None; | |
| } | |
| else { | |
| blend_mode = BlendMode::Blend; | |
| } | |
| self.set_blend_mode(blend_mode); | |
| self.set_draw_color(color); | |
| return self.draw_line(start, end); | |
| } | |
| fn hline_rgba(&mut self, x1: i32, x2: i32, y: i32, color: Color) -> Result<(), String> { | |
| let blend_mode : BlendMode; | |
| if color.a == 255 { | |
| blend_mode = BlendMode::None; | |
| } | |
| else { | |
| blend_mode = BlendMode::Blend; | |
| } | |
| self.set_blend_mode(blend_mode); | |
| self.set_draw_color(color); | |
| return self.draw_line(Point::new(x1, y), Point::new(x2, y)); | |
| } | |
| fn vline_rgba(&mut self, x: i32, y1: i32, y2: i32, color: Color ) -> Result<(), String> { | |
| let blend_mode : BlendMode; | |
| if color.a == 255 { | |
| blend_mode = BlendMode::None; | |
| } | |
| else { | |
| blend_mode = BlendMode::Blend; | |
| } | |
| self.set_blend_mode(blend_mode); | |
| self.set_draw_color(color); | |
| return self.draw_line(Point::new(x, y1), Point::new(x, y2)); | |
| } | |
| fn box_rgba(&mut self, top_right: Point, bottom_left: Point, color: Color) -> Result<(), String> { | |
| if top_right.x == bottom_left.x { | |
| if top_right.y == bottom_left.y { | |
| return self.pixel_rgba(top_right, color); | |
| } else { | |
| return self.vline_rgba(top_right.x, top_right.y, bottom_left.y , color); | |
| } | |
| } else if top_right.y == bottom_left.y { | |
| return self.hline_rgba(top_right.x, bottom_left.x, top_right.y, color); | |
| } | |
| let mut x_1 = top_right.x; | |
| let mut x_2 = bottom_left.x; | |
| let mut y_1 = top_right.y; | |
| let mut y_2 = bottom_left.y; | |
| if x_1 > x_2 { | |
| let tmp = x_1; | |
| x_1 = x_2; | |
| x_2 = tmp; | |
| } | |
| if y_1 > y_2 { | |
| let tmp = y_1; | |
| y_1 = y_2; | |
| y_2 = tmp; | |
| } | |
| let rect = Rect::new(x_1, y_1, (x_2 - x_1 + 1) as u32, (y_2 - y_1 + 1) as u32); | |
| let blend_mode : BlendMode; | |
| if color.a == 255 { | |
| blend_mode = BlendMode::None; | |
| } | |
| else { | |
| blend_mode = BlendMode::Blend; | |
| } | |
| self.set_blend_mode(blend_mode); | |
| self.set_draw_color(color); | |
| return self.fill_rect(rect); | |
| } | |
| fn thick_line(&mut self, start: Point, end: Point, width: i32, color: Color) -> Result<(), String> { | |
| if width < 1 { | |
| return Err(String::from("Width not valid for line")); | |
| } | |
| if start.x == end.x && start.y == start.y { | |
| let wh = width / 2; | |
| return self.box_rgba(Point::new(start.x - wh, start.y - wh), Point::new(end.x + width, end.y + width), color); | |
| } | |
| if width == 1 { | |
| return self.line_rgba(start, end, color); | |
| } | |
| let dx = (end.x - start.x) as f32; | |
| let dy = (end.y - start.y) as f32; | |
| let l = (dx * dx + dy * dy).sqrt(); | |
| let ang = dx.atan2(dy); | |
| let adj = 0.1 + 0.9 * (2.0 * ang).cos().abs(); | |
| let wl2 = ((width as f32) - adj) / (2.0 * l); | |
| let nx = dx * wl2; | |
| let ny = dy * wl2; | |
| let dx1 = start.x as f32; | |
| let dy1 = start.y as f32; | |
| let dx2 = end.x as f32; | |
| let dy2 = end.y as f32; | |
| let verts = vec![Point::new((dx1 + ny) as i32, (dy1 - nx) as i32), | |
| Point::new((dx1 - ny) as i32, (dy1 + nx) as i32), | |
| Point::new((dx2 - ny) as i32, (dy2 + nx) as i32), | |
| Point::new((dx2 + ny) as i32, (dy2 - nx) as i32)]; | |
| return self.filled_polygon_rgba_mt(verts, color); | |
| } | |
| fn filled_polygon_rgba_mt(&mut self, verts: Vec<Point>, color: Color) -> Result<(), String> { | |
| if verts.len() < 3 { | |
| return Err(String::from("Not enough vertices")); | |
| } | |
| let mut polygon_indices : Vec<i32> = vec![0; verts.len()]; | |
| let mut min_y = verts[0].y; | |
| let mut max_y = verts[0].y; | |
| for vert in &verts { | |
| if vert.y < min_y { | |
| min_y = vert.y; | |
| } | |
| else if vert.y > max_y { | |
| max_y = vert.y; | |
| } | |
| } | |
| let mut indices_1; | |
| let mut indices_2; | |
| let mut y_1; | |
| let mut y_2; | |
| let mut x_1; | |
| let mut x_2; | |
| for y in min_y..=max_y { | |
| let mut ints = 0; | |
| for i in 0..verts.len() { | |
| if i == 0 { | |
| indices_1 = verts.len() - 1; | |
| indices_2 = 0; | |
| } | |
| else { | |
| indices_1 = i - 1; | |
| indices_2 = i; | |
| } | |
| y_1 = verts[indices_1].y; | |
| y_2 = verts[indices_2].y; | |
| if y_1 < y_2 { | |
| x_1 = verts[indices_1].x; | |
| x_2 = verts[indices_2].x; | |
| } | |
| else if y_1 > y_2 { | |
| y_2 = verts[indices_1].y; | |
| y_1 = verts[indices_2].y; | |
| x_2 = verts[indices_1].x; | |
| x_1 = verts[indices_2].x; | |
| } | |
| else { | |
| continue; | |
| } | |
| if ((y >= y_1) && (y < y_2)) || ((y == max_y) && (y > y_1) && (y <= y_2)) { | |
| polygon_indices[ints] = ((65536 * (y - y_1)) / (y_2 - y_1)) * (x_2 - x_1) + (65536 * x_1); | |
| ints += 1; | |
| } | |
| } | |
| polygon_indices.sort_unstable(); | |
| let blend_mode : BlendMode; | |
| if color.a == 255 { | |
| blend_mode = BlendMode::None; | |
| } | |
| else { | |
| blend_mode = BlendMode::Blend; | |
| } | |
| self.set_blend_mode(blend_mode); | |
| self.set_draw_color(color); | |
| let mut i = 0; | |
| let mut x_a; | |
| let mut x_b; | |
| while i < ints { | |
| x_a = polygon_indices[i] + 1; | |
| x_a = (x_a >> 16) + ((x_a & 32768) >> 15); | |
| x_b = polygon_indices[i + 1] - 1; | |
| x_b = (x_b >> 16) + ((x_b & 32768) >> 15); | |
| i += 2; | |
| let result = self.hline(x_a, x_b, y); | |
| if result.is_err() { | |
| return result; | |
| } | |
| } | |
| } | |
| return Ok(()); | |
| } | |
| fn draw_quadrants(&mut self, p: Point, dp: Point, f: i32) -> Result<(), String> { | |
| if dp.x == 0 { | |
| if dp.y == 0 { | |
| return self.pixel(p); | |
| } else { | |
| let ypdy = p.y + dp.y; | |
| let ymdy = p.y - dp.y; | |
| if f != 0 { | |
| return self.vline(p.x, ymdy, ypdy); | |
| } | |
| else { | |
| return self.pixel(Point::new(p.x, ypdy)).and_then(|_| { | |
| return self.pixel(Point::new(p.x, ymdy)); | |
| }); | |
| } | |
| } | |
| } else { | |
| let xpdx = p.x + dp.x; | |
| let xmdx = p.x - dp.x; | |
| let ypdy = p.y + dp.y; | |
| let ymdy = p.y - dp.y; | |
| if f != 0 { | |
| return self.vline(xpdx, ymdy, ypdy).and_then(|_|{ | |
| return self.vline(xmdx, ymdy, ypdy); | |
| }); | |
| } else { | |
| return self.pixel(Point::new(xpdx, ypdy)).and_then(|_|{ | |
| return self.pixel(Point::new(xmdx, ypdy)).and_then(|_|{ | |
| return self.pixel(Point::new(xpdx, ymdy)).and_then(|_| { | |
| return self.pixel(Point::new(xmdx, ymdy)); | |
| }); | |
| }); | |
| }); | |
| } | |
| } | |
| } | |
| fn pixel_rgba_weight(&mut self, p: Point, color: Color, weight: i32) -> Result<(), String> { | |
| let mut a_x = color.a as i32; | |
| a_x = (a_x * weight) >> 8; | |
| if a_x > 255 { | |
| a_x = 255; | |
| } else { | |
| a_x = a_x & 0x000000ff; | |
| } | |
| let new_color = Color::RGBA(color.r, color.g, color.b, a_x as u8); | |
| return self.pixel_rgba(p, new_color); | |
| } | |
| fn pixel_rgba(&mut self, p: Point, color: Color) -> Result<(), String> { | |
| let blend_mode : BlendMode; | |
| if color.a == 255 { | |
| blend_mode = BlendMode::None; | |
| } | |
| else { | |
| blend_mode = BlendMode::Blend; | |
| } | |
| self.set_blend_mode(blend_mode); | |
| self.set_draw_color(color); | |
| return self.draw_point(p); | |
| } | |
| fn pixel(&mut self, p: Point) -> Result<(), String> { | |
| return self.draw_point(p); | |
| } | |
| fn vline(&mut self, x: i32, y1: i32, y2: i32) -> Result<(), String> { | |
| return self.draw_line(Point::new(x , y1), Point::new(x, y2)); | |
| } | |
| fn hline(&mut self, x1: i32, x2: i32, y: i32) -> Result<(), String> { | |
| return self.draw_line(Point::new(x1, y), Point::new(x2, y)); | |
| } | |
| fn ellipse_rgba(&mut self, p: Point, radius_x: i16, radius_y: i16, color: Color, f: i32) -> Result<(), String> { | |
| // println!("{} {}", radius_x, radius_y); | |
| if radius_x < 0 || radius_y < 0 { | |
| return Err(String::from("")); | |
| } | |
| let default_eclipse_overscan = 4; | |
| let blend_mode : BlendMode; | |
| if color.a == 255 { | |
| blend_mode = BlendMode::None; | |
| } | |
| else { | |
| blend_mode = BlendMode::Blend; | |
| } | |
| self.set_blend_mode(blend_mode); | |
| self.set_draw_color(color); | |
| if radius_x == 0 { | |
| if radius_y == 0 { | |
| return self.pixel(p); | |
| } else { | |
| return self.vline(p.x, p.y - radius_y as i32, p.y + radius_y as i32); | |
| } | |
| } else { | |
| if radius_y == 0 { | |
| return self.hline(p.x - radius_x as i32, p.x + radius_x as i32, p.y); | |
| } | |
| } | |
| let mut rxi : i32 = radius_x as i32; | |
| let mut ryi : i32 = radius_y as i32; | |
| let ellipse_overscan; | |
| if rxi >= 512 || ryi >= 512 { | |
| ellipse_overscan = default_eclipse_overscan / 4; | |
| } | |
| else if rxi >= 256 || ryi >= 256 { | |
| ellipse_overscan = default_eclipse_overscan / 2; | |
| } | |
| else { | |
| ellipse_overscan = default_eclipse_overscan / 1; | |
| } | |
| let mut old_x : i32 = 0; | |
| let mut old_y : i32 = 0; | |
| let mut src_x : i32 = 0; | |
| let mut src_y : i32; | |
| let result = self.draw_quadrants(p, Point::new(0, radius_y as i32), f); | |
| if result.is_err() { | |
| return result; | |
| } | |
| rxi *= ellipse_overscan; | |
| ryi *= ellipse_overscan; | |
| let rx2 : i32 = rxi * rxi; | |
| let rx22 : i32 = rx2 + rx2; | |
| let ry2 : i32 = ryi * ryi; | |
| let ry22 : i32 = ry2 + ry2; | |
| let mut curX : i32 = 0; | |
| let mut curY : i32 = ryi; | |
| let mut deltaX : i32 = 0; | |
| let mut deltaY : i32 = rx22 * curY; | |
| let mut error : i32 = ry2 - rx2 * ryi + rx2 / 4; | |
| while deltaX <= deltaY | |
| { | |
| curX+=1; | |
| deltaX += ry22; | |
| error += deltaX + ry2; | |
| if error >= 0 | |
| { | |
| curY-=1; | |
| deltaY -= rx22; | |
| error -= deltaY; | |
| } | |
| src_x = curX / ellipse_overscan; | |
| src_y = curY / ellipse_overscan; | |
| if (src_x != old_x && src_y == old_y) || (src_x != old_x && src_y != old_y) { | |
| let result = self.draw_quadrants(p, Point::new(src_x as i32, src_y as i32), f); | |
| if result.is_err() { | |
| return result; | |
| } | |
| old_x = src_x; | |
| old_y = src_y; | |
| } | |
| } | |
| if curY > 0 | |
| { | |
| let curXp1 = curX + 1; | |
| let curYm1 = curY - 1; | |
| //As best as I an tell SDL_GFX is using the under/over flow behavior of the these varibles to figure out what to do | |
| let inner = ry2 + 3; | |
| let inner_2 = inner / 4; | |
| let head = curX.wrapping_mul(curXp1); | |
| let head_head = ry2.wrapping_mul(head); | |
| let head_inner = head_head.wrapping_add(inner_2); | |
| let first_mul = rx2.wrapping_mul(curYm1); | |
| let second_mul = first_mul.wrapping_mul(curYm1); | |
| let final_mul = rx2.wrapping_mul(ry2); | |
| error = head_inner.wrapping_add(second_mul.wrapping_sub(final_mul)); | |
| while curY > 0 | |
| { | |
| curY-=1; | |
| deltaY -= rx22; | |
| error += rx2; | |
| error -= deltaY; | |
| if error <= 0 | |
| { | |
| curX+=1; | |
| deltaX += ry22; | |
| error += deltaX; | |
| } | |
| src_x = curX / ellipse_overscan; | |
| src_y = curY / ellipse_overscan; | |
| if (src_x != old_x && src_y == old_y) || (src_x != old_x && src_y != old_y) { | |
| old_y-=1; | |
| while old_y >= src_y { | |
| self.draw_quadrants(p , Point::new(src_x, old_y), f)?; | |
| if f != 0 { | |
| old_y = src_y - 1; | |
| } | |
| old_y -=1; | |
| } | |
| old_x = src_x; | |
| old_y = src_y; | |
| } | |
| } | |
| /* Remaining points in vertical */ | |
| if f != 0 { | |
| old_y-=1; | |
| for i in old_y..=0 { | |
| self.draw_quadrants(p , Point::new(src_x, i), f)?; | |
| } | |
| } | |
| } | |
| return Ok(()); | |
| } | |
| fn filled_circle(&mut self, p: Point, rad: i16, color: Color) -> Result<(), String> { | |
| return self.ellipse_rgba(p, rad, rad, color, 1); | |
| } | |
| fn rectangle_rgba(&mut self, top_right: Point, bottom_left: Point, color: Color) -> Result<(), String> { | |
| if top_right.x == bottom_left.x { | |
| if top_right.y == bottom_left.y { | |
| return self.pixel_rgba(top_right, color); | |
| } | |
| else { | |
| return self.vline_rgba(top_right.x, top_right.y, bottom_left.y, color); | |
| } | |
| } | |
| else if top_right.y == bottom_left.y { | |
| return self.hline_rgba(top_right.x, bottom_left.x, top_right.y, color); | |
| } | |
| let mut x_1 = top_right.x; | |
| let mut x_2 = bottom_left.x; | |
| let mut y_1 = top_right.y; | |
| let mut y_2 = bottom_left.y; | |
| if x_1 > x_2 { | |
| let tmp = x_1; | |
| x_1 = x_2; | |
| x_2 = tmp; | |
| } | |
| if y_1 > y_2 { | |
| let tmp = y_1; | |
| y_1 = y_2; | |
| y_2 = tmp; | |
| } | |
| let rect = Rect::new(x_1, y_1, (x_2 - x_1 + 1) as u32, (y_2 - y_1 + 1) as u32); | |
| let blend_mode : BlendMode; | |
| if color.a == 255 { | |
| blend_mode = BlendMode::None; | |
| } | |
| else { | |
| blend_mode = BlendMode::Blend; | |
| } | |
| self.set_blend_mode(blend_mode); | |
| self.set_draw_color(color); | |
| return self.fill_rect(rect); | |
| } | |
| fn rounded_rentangle_rgba(&mut self, top_right: Point, bottom_left: Point, radius: i32, color: Color) -> Result<(), String> { | |
| if radius < 0 { | |
| return Err(String::from("less then 0 radius not allowed")); | |
| } | |
| if radius <= 1 { | |
| return self.rectangle_rgba(top_right, bottom_left, color); | |
| } | |
| if top_right.x == bottom_left.x { | |
| if top_right.y == bottom_left.y { | |
| return self.pixel_rgba(top_right, color); | |
| } | |
| else { | |
| return self.vline_rgba(top_right.x, top_right.y, bottom_left.y, color); | |
| } | |
| } | |
| else if top_right.y == bottom_left.y { | |
| return self.hline_rgba(top_right.x, bottom_left.x, top_right.y, color); | |
| } | |
| let mut x_1 = top_right.x; | |
| let mut x_2 = bottom_left.x; | |
| let mut y_1 = top_right.y; | |
| let mut y_2 = bottom_left.y; | |
| if x_1 > x_2 { | |
| let tmp = x_1; | |
| x_1 = x_2; | |
| x_2 = tmp; | |
| } | |
| if y_1 > y_2 { | |
| let tmp = y_1; | |
| y_1 = y_2; | |
| y_2 = tmp; | |
| } | |
| let mut rad = radius; | |
| let mut w = bottom_left.x - top_right.x; | |
| let mut h = bottom_left.y - top_right.y; | |
| if rad * 2 > w { | |
| rad = w / 2; | |
| } | |
| if rad * w > h { | |
| rad = h / 2; | |
| } | |
| return Ok(()); | |
| } | |
| fn arc_rgba(&mut self,p: Point, radius: i32, start: i32, end: i32, color: Color) -> Result<(), String>{ | |
| if radius < 0 { | |
| return Err(String::from("Cannot draw arc with radius les then 0")); | |
| } | |
| let mut cy = radius; | |
| let df = 1 - radius; | |
| let d_e = 3; | |
| let d_se = -2 * radius + 5; | |
| if radius == 0 { | |
| return self.pixel_rgba(p, color); | |
| } | |
| let mut drawoct = 0; | |
| let mut use_start = start % 360; | |
| let mut use_end = end % 360; | |
| while use_start < 0 { | |
| use_start += 360; | |
| } | |
| while use_end < 0 { | |
| use_end += 360; | |
| } | |
| use_start %= 360; | |
| use_end %= 360; | |
| let mut start_oct = use_start / 45; | |
| let mut end_oct = use_end / 45; | |
| let mut oct = start_oct - 1; | |
| let mut dstart : f32; | |
| let mut dend : f32; | |
| let mut temp : f32 = 0.0; | |
| let mut stopval_start : i32; | |
| let mut stopval_end : i32; | |
| //this is replicate the do while loop | |
| //of the original source code | |
| let mut once = true; | |
| while once || oct != end_oct { | |
| once = false; | |
| oct = (oct + 1) % 8; | |
| if oct == start_oct { | |
| dstart = use_start as f32; | |
| match oct { | |
| 0 | 3 => { | |
| temp = (dstart * std::f32::consts::PI / 180.0).sin() | |
| }, | |
| 1 | 6 => { | |
| temp = (dstart * std::f32::consts::PI / 180.0).cos() | |
| }, | |
| 2 | 5 => { | |
| temp = -(dstart * std::f32::consts::PI / 180.0).cos() | |
| }, | |
| 4 | 7 => { | |
| temp = -(dstart * std::f32::consts::PI / 180.0).sin() | |
| } | |
| _ => { | |
| } | |
| } | |
| temp = temp * radius as f32; | |
| stopval_start = temp as i32; | |
| if oct % 2 != 0 { | |
| drawoct |= 1 << oct; | |
| } else { | |
| drawoct &= 255 - (1 << oct); | |
| } | |
| } | |
| if oct == end_oct { | |
| dend = use_end as f32; | |
| match oct { | |
| 0 | 3 => { | |
| temp = (dend * std::f32::consts::PI / 180.0).sin() | |
| }, | |
| 1 | 6 => { | |
| temp = (dend * std::f32::consts::PI / 180.0).cos() | |
| }, | |
| 2 | 5 => { | |
| temp = -(dend * std::f32::consts::PI / 180.0).cos() | |
| }, | |
| 4 | 7 => { | |
| temp = -(dend * std::f32::consts::PI / 180.0).sin() | |
| } | |
| _ => { | |
| } | |
| } | |
| temp = temp * radius as f32; | |
| stopval_end = temp as i32; | |
| if start_oct == end_oct { | |
| if use_start > use_end { | |
| drawoct = 255; | |
| } else { | |
| drawoct &= 255 - (1 << oct); | |
| } | |
| } | |
| else if oct % 2 != 0 { | |
| drawoct &= 255 - (1 << oct); | |
| } else { | |
| drawoct |= 1 << oct; | |
| } | |
| } else if start_oct != oct { | |
| drawoct |= 1 << end_oct; | |
| } | |
| } | |
| let blend_mode : BlendMode; | |
| if color.a == 255 { | |
| blend_mode = BlendMode::None; | |
| } | |
| else { | |
| blend_mode = BlendMode::Blend; | |
| } | |
| self.set_blend_mode(blend_mode); | |
| self.set_draw_color(color); | |
| let mut once = true; | |
| let mut cx = 0; | |
| let mut ypcy; | |
| let mut ymcy; | |
| let mut xpcx; | |
| let mut xmcx; | |
| while once || cx <= cy { | |
| once = false; | |
| ypcy = p.y + cy; | |
| ymcy = p.y - cy; | |
| if cx > 0 { | |
| xpcx = p.x + cx; | |
| xmcx = p.x - cx; | |
| } else { | |
| } | |
| } | |
| return Ok(()); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment