gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/internal/f32/f32.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  /*
     4  Package f32 is an internal version of the public package f32 with
     5  extra types for internal use.
     6  */
     7  package f32
     8  
     9  import (
    10  	"image"
    11  	"math"
    12  
    13  	"gioui.org/f32"
    14  )
    15  
    16  type Point = f32.Point
    17  
    18  type Affine2D = f32.Affine2D
    19  
    20  var NewAffine2D = f32.NewAffine2D
    21  
    22  // A Rectangle contains the points (X, Y) where Min.X <= X < Max.X,
    23  // Min.Y <= Y < Max.Y.
    24  type Rectangle struct {
    25  	Min, Max Point
    26  }
    27  
    28  // String return a string representation of r.
    29  func (r Rectangle) String() string {
    30  	return r.Min.String() + "-" + r.Max.String()
    31  }
    32  
    33  // Rect is a shorthand for Rectangle{Point{x0, y0}, Point{x1, y1}}.
    34  // The returned Rectangle has x0 and y0 swapped if necessary so that
    35  // it's correctly formed.
    36  func Rect(x0, y0, x1, y1 float32) Rectangle {
    37  	if x0 > x1 {
    38  		x0, x1 = x1, x0
    39  	}
    40  	if y0 > y1 {
    41  		y0, y1 = y1, y0
    42  	}
    43  	return Rectangle{Point{x0, y0}, Point{x1, y1}}
    44  }
    45  
    46  // Pt is shorthand for Point{X: x, Y: y}.
    47  var Pt = f32.Pt
    48  
    49  // Size returns r's width and height.
    50  func (r Rectangle) Size() Point {
    51  	return Point{X: r.Dx(), Y: r.Dy()}
    52  }
    53  
    54  // Dx returns r's width.
    55  func (r Rectangle) Dx() float32 {
    56  	return r.Max.X - r.Min.X
    57  }
    58  
    59  // Dy returns r's Height.
    60  func (r Rectangle) Dy() float32 {
    61  	return r.Max.Y - r.Min.Y
    62  }
    63  
    64  // Intersect returns the intersection of r and s.
    65  func (r Rectangle) Intersect(s Rectangle) Rectangle {
    66  	if r.Min.X < s.Min.X {
    67  		r.Min.X = s.Min.X
    68  	}
    69  	if r.Min.Y < s.Min.Y {
    70  		r.Min.Y = s.Min.Y
    71  	}
    72  	if r.Max.X > s.Max.X {
    73  		r.Max.X = s.Max.X
    74  	}
    75  	if r.Max.Y > s.Max.Y {
    76  		r.Max.Y = s.Max.Y
    77  	}
    78  	if r.Empty() {
    79  		return Rectangle{}
    80  	}
    81  	return r
    82  }
    83  
    84  // Union returns the union of r and s.
    85  func (r Rectangle) Union(s Rectangle) Rectangle {
    86  	if r.Empty() {
    87  		return s
    88  	}
    89  	if s.Empty() {
    90  		return r
    91  	}
    92  	if r.Min.X > s.Min.X {
    93  		r.Min.X = s.Min.X
    94  	}
    95  	if r.Min.Y > s.Min.Y {
    96  		r.Min.Y = s.Min.Y
    97  	}
    98  	if r.Max.X < s.Max.X {
    99  		r.Max.X = s.Max.X
   100  	}
   101  	if r.Max.Y < s.Max.Y {
   102  		r.Max.Y = s.Max.Y
   103  	}
   104  	return r
   105  }
   106  
   107  // Canon returns the canonical version of r, where Min is to
   108  // the upper left of Max.
   109  func (r Rectangle) Canon() Rectangle {
   110  	if r.Max.X < r.Min.X {
   111  		r.Min.X, r.Max.X = r.Max.X, r.Min.X
   112  	}
   113  	if r.Max.Y < r.Min.Y {
   114  		r.Min.Y, r.Max.Y = r.Max.Y, r.Min.Y
   115  	}
   116  	return r
   117  }
   118  
   119  // Empty reports whether r represents the empty area.
   120  func (r Rectangle) Empty() bool {
   121  	return r.Min.X >= r.Max.X || r.Min.Y >= r.Max.Y
   122  }
   123  
   124  // Add offsets r with the vector p.
   125  func (r Rectangle) Add(p Point) Rectangle {
   126  	return Rectangle{
   127  		Point{r.Min.X + p.X, r.Min.Y + p.Y},
   128  		Point{r.Max.X + p.X, r.Max.Y + p.Y},
   129  	}
   130  }
   131  
   132  // Sub offsets r with the vector -p.
   133  func (r Rectangle) Sub(p Point) Rectangle {
   134  	return Rectangle{
   135  		Point{r.Min.X - p.X, r.Min.Y - p.Y},
   136  		Point{r.Max.X - p.X, r.Max.Y - p.Y},
   137  	}
   138  }
   139  
   140  // Round returns the smallest integer rectangle that
   141  // contains r.
   142  func (r Rectangle) Round() image.Rectangle {
   143  	return image.Rectangle{
   144  		Min: image.Point{
   145  			X: int(floor(r.Min.X)),
   146  			Y: int(floor(r.Min.Y)),
   147  		},
   148  		Max: image.Point{
   149  			X: int(ceil(r.Max.X)),
   150  			Y: int(ceil(r.Max.Y)),
   151  		},
   152  	}
   153  }
   154  
   155  // fRect converts a rectangle to a f32internal.Rectangle.
   156  func FRect(r image.Rectangle) Rectangle {
   157  	return Rectangle{
   158  		Min: FPt(r.Min), Max: FPt(r.Max),
   159  	}
   160  }
   161  
   162  // Fpt converts an point to a f32.Point.
   163  func FPt(p image.Point) Point {
   164  	return Point{
   165  		X: float32(p.X), Y: float32(p.Y),
   166  	}
   167  }
   168  
   169  func ceil(v float32) int {
   170  	return int(math.Ceil(float64(v)))
   171  }
   172  
   173  func floor(v float32) int {
   174  	return int(math.Floor(float64(v)))
   175  }