Files

70 lines
2.6 KiB
Go

// Cthulhu screen reader.
// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
package atspi
import "math"
// Rectangle uses AT-SPI screen coordinates. Negative positions are valid on
// multi-monitor desktops. Edges use int64 arithmetic to avoid native gint
// overflow. Zero-sized rectangles cannot contribute a flat-review zone.
type Rectangle struct {
X, Y, Width, Height int32
}
func (rect Rectangle) Valid() bool {
return rect.Width > 0 && rect.Height > 0 && rect.X != math.MinInt32 && rect.Y != math.MinInt32
}
// Intersection clips a screen rectangle without wrapping at native integer
// limits. A disjoint, empty, or unavailable rectangle has no intersection.
func (rect Rectangle) Intersection(other Rectangle) (Rectangle, bool) {
if !rect.Valid() || !other.Valid() {
return Rectangle{}, false
}
left := max(int64(rect.X), int64(other.X))
top := max(int64(rect.Y), int64(other.Y))
right := min(int64(rect.X)+int64(rect.Width), int64(other.X)+int64(other.Width))
bottom := min(int64(rect.Y)+int64(rect.Height), int64(other.Y)+int64(other.Height))
if right <= left || bottom <= top {
return Rectangle{}, false
}
return Rectangle{int32(left), int32(top), int32(right - left), int32(bottom - top)}, true
}
// Geometry is owned capture-time component data, separate from focus snapshots.
// Bounds are meaningful only when visibility is known and the object is both
// visible and showing. Neither state establishes that another window does not
// obscure the object. Unsupported components retain unknown bounds.
type Geometry struct {
Bounds Rectangle
BoundsKnown bool
VisibilityKnown bool
Visible bool
Showing bool
}
func (geometry Geometry) valid() bool {
if !geometry.VisibilityKnown && (geometry.Visible || geometry.Showing) {
return false
}
if geometry.BoundsKnown {
return geometry.VisibilityKnown && geometry.Visible && geometry.Showing && geometry.Bounds.Valid()
}
return geometry.Bounds == (Rectangle{})
}