// 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 . 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{}) }