+! Change Interval and Box behaviour

This includes imcompatible changes.
Now Interval.Last is increased by 1.
This commit is contained in:
Vovanium 2023-03-14 01:51:45 +03:00
parent f6ca9c30d0
commit f723a6f767
10 changed files with 58 additions and 29 deletions

View File

@ -14,7 +14,7 @@ package Video.Images.Raster.Generic_Fixed is
end record;
overriding function Bounding_Box (Source : Image) return Box
is ((Source.X_First, Source.X_Last), (Source.Y_First, Source.Y_Last));
is ((Source.X_First, Source.X_Last - 1), (Source.Y_First, Source.Y_Last - 1));
overriding function Pixel (
Source : Image;

View File

@ -5,8 +5,8 @@ package body Video.Images.Raster.Generic_Unbounded is
Data : access Raster_Images.Raster_Type := Source.Pixels.Reference;
R : Raster_Images.Raster_Type renames Data.all;
begin
return (X => (R'First (2), R'Last (2)),
Y => (R'First (1), R'Last (1)));
return (X => (R'First (2), R'Last (2) - 1),
Y => (R'First (1), R'Last (1) - 1));
end;
overriding function Pixel (

View File

@ -1,10 +1,39 @@
package Video.Integer_Geometry with Pure is
subtype Coordinate is Integer;
subtype Distance is Coordinate'Base range 0 .. (
if Coordinate'Last > Coordinate'Base'Last + Coordinate'First then
Coordinate'Base'Last else Coordinate'Last - Coordinate'First);
type Point is record
X, Y : Integer;
X, Y : Coordinate;
end record;
-- A 2D vector
-- Note: As in many other graphics systems integral coordinate points
-- between pixels. Pixel center is 0.5 away from it.
-- Y
-- ^
-- |
-- 3 +--
-- | * | __ Pixel center at (1.5, 1.5)
-- 2 +---+ /
-- | * | *
-- 1 +---+---+-
-- | * | * | * |
-- 0 +---+---+---+--> X
-- 0 1 2 3
-- When dealing with rasters and their index ranges offset by -1 appear at the Last index.
-- Note on simple hairline graphics: It generally takes integer coordinates
-- and use them to address adjacent pixel usually centered at (+0.5, +0.5).
-- Clipping is (believed to be) performed correctly against pixel edges.
function "+" (Q : Point) return Point is (Q);
function "-" (Q : Point) return Point is (X => -Q.X, Y => -Q.Y);
function "+" (P, Q : Point) return Point is (X => P.X + Q.X, Y => P.Y + Q.Y);
function "-" (P, Q : Point) return Point is (X => P.X - Q.X, Y => P.Y - Q.Y);
@ -17,34 +46,34 @@ package Video.Integer_Geometry with Pure is
--
type Interval is record
First, Last : Integer;
First, Last : Coordinate;
end record;
-- A type like an Ada range (but a type)
function Empty_Interval return Interval is (Integer'Last, Integer'First);
function Empty_Interval return Interval is (Coordinate'Last, Coordinate'First);
function Is_Empty (A : Interval) return Boolean is (A.First > A.Last);
function Is_Empty (A : Interval) return Boolean is (A.First >= A.Last);
function Length (A : Interval) return Natural is
(if Is_Empty (A) then 0 else A.Last - A.First + 1);
function Length (A : Interval) return Distance is
(if Is_Empty (A) then 0 else A.Last - A.First);
function Contains (A : Interval; X : Integer) return Boolean is (X in A.First .. A.Last);
function Contains (A : Interval; X : Coordinate) return Boolean is (X in A.First .. A.Last);
function Center (A : Interval) return Integer
function Center (A : Interval) return Coordinate
is (A.First / 2 + A.Last / 2 + (A.First rem 2 + A.Last rem 2) / 2);
function "+" (A : Interval; B : Integer) return Interval is
function "+" (A : Interval; B : Coordinate) return Interval is
(A.First + B, A.Last + B);
-- Translate interval
function "and" (A, B : Interval) return Interval is
(Integer'Max (A.First, B.First), Integer'Min (A.Last, B.Last));
(Coordinate'Max (A.First, B.First), Coordinate'Min (A.Last, B.Last));
-- Intersection
function "or" (A, B : Interval) return Interval is
(if Is_Empty (A) then B
elsif Is_Empty (B) then A
else (Integer'Min (A.First, B.First), Integer'Max (A.Last, B.Last)));
else (Coordinate'Min (A.First, B.First), Coordinate'Max (A.Last, B.Last)));
-- Minimal interval enclosing both arguments
type Box is record

View File

@ -7,8 +7,8 @@ package body Video.Rasters.Generic_Blits.Masked is
Bounds : in Video.Integer_Geometry.Box)
is
begin
for Y in Bounds.Y.First .. Bounds.Y.Last loop
for X in Bounds.X.First .. Bounds.X.Last loop
for Y in Bounds.Y.First .. Bounds.Y.Last - 1 loop
for X in Bounds.X.First .. Bounds.X.Last - 1 loop
if Mask (Y - Offset.Y, X - Offset.X) /= Mask_Value then
Target (Y, X) := Color;
end if;

View File

@ -9,8 +9,8 @@ package body Video.Rasters.Generic_Blits is
Bounds : in Video.Integer_Geometry.Box)
is
begin
for Y in Bounds.Y.First .. Bounds.Y.Last loop
for X in Bounds.X.First .. Bounds.X.Last loop
for Y in Bounds.Y.First .. Bounds.Y.Last - 1 loop
for X in Bounds.X.First .. Bounds.X.Last - 1 loop
Target (Y, X) := Color;
end loop;
end loop;

View File

@ -4,8 +4,8 @@ package body Video.Rasters.Generic_Holders is
function Bounding_Box (Source : Holder) return Box is (
if Source.Data /= null then (
X => (Source.Data.all'First (2), Source.Data.all'Last (2)),
Y => (Source.Data.all'First (1), Source.Data.all'Last (1)))
X => (Source.Data.all'First (2), Source.Data.all'Last (2) + 1),
Y => (Source.Data.all'First (1), Source.Data.all'Last (1) + 1))
else
Empty_Box);
@ -46,8 +46,8 @@ package body Video.Rasters.Generic_Holders is
begin
if not Is_Empty (Bounds) then
Target.Data := new Raster_Type (
Bounds.Y.First .. Bounds.Y.Last,
Bounds.X.First .. Bounds.X.Last);
Bounds.Y.First .. Bounds.Y.Last - 1,
Bounds.X.First .. Bounds.X.Last - 1);
end if;
end Allocate;

View File

@ -33,8 +33,8 @@ package body Video.Rasters.Generic_Renderers is
Paint : in Pixel)
is
begin
for Y in Bounds.Y.First .. Bounds.Y.Last loop
for X in Bounds.X.First .. Bounds.X.Last loop
for Y in Bounds.Y.First .. Bounds.Y.Last - 1 loop
for X in Bounds.X.First .. Bounds.X.Last - 1 loop
Target.Target (Y, X) := Paint;
end loop;
end loop;

View File

@ -10,7 +10,7 @@ package Video.Rasters.Generic_Renderers is
type Renderer (Target : access Raster) is limited new Pixel_Renderables.Renderable with null record;
overriding function Bounding_Box (S : Renderer) return Integer_Geometry.Box
is (X => (S.Target'First (2), S.Target'Last (2)), Y => (S.Target'First (1), S.Target'Last (1)));
is (X => (S.Target'First (2), S.Target'Last (2) - 1), Y => (S.Target'First (1), S.Target'Last (1) - 1));
overriding procedure Clear (
Target : in out Renderer;

View File

@ -8,7 +8,7 @@ begin
R.Clear (Video.Colors.RGB_8 (0, 0, 0));
R.Fill_Rectangle (
Bounds => ((200, 399), (200, 299)),
Bounds => ((200, 400), (200, 300)),
Paint => Video.Colors.RGB_8 (16#FA#, 16#CE#, 16#8D#));
for Y in 0 .. 255 loop

View File

@ -11,16 +11,16 @@ package Video.SDL2.Rectangles is
X : SDL.Coordinate;
W : SDL.Natural_Dimension)
return Interval
is (First => Integer (X), Last => Integer (X + W - 1));
is (First => Coordinate (X), Last => Coordinate (X + W));
function From_SDL (P : SDL.Video.Rectangles.Point) return Point
is (X => Integer (P.X), Y => Integer (P.Y));
is (X => Coordinate (P.X), Y => Coordinate (P.Y));
function To_SDL (P : Point) return SDL.Video.Rectangles.Point
is (X => SDL.Coordinate (P.X), Y => SDL.Coordinate (P.Y));
function From_SDL (R : SDL.Sizes) return Box
is (X => (0, Integer (R.Width) - 1), Y => (0, Integer (R.Height) - 1));
is (X => (0, Coordinate (R.Width)), Y => (0, Coordinate (R.Height)));
function From_SDL (R : SDL.Video.Rectangles.Rectangle) return Box
is (X => To_Interval (R.X, R.Width), Y => To_Interval (R.Y, R.Height));