PosToRune returns the rune span and rune indexes for given relative X,Y pixel position, if the pixel position lies within the given text area. If not, returns false. It is robust to left-right out-of-range positions, returning the first or last rune index respectively.
(pos math32.Vector2)
| 102 | // If not, returns false. It is robust to left-right out-of-range positions, |
| 103 | // returning the first or last rune index respectively. |
| 104 | func (tx *Text) PosToRune(pos math32.Vector2) (si, ri int, ok bool) { |
| 105 | ok = false |
| 106 | if pos.X < 0 || pos.Y < 0 { // note: don't bail on X yet |
| 107 | return |
| 108 | } |
| 109 | sz := tx.BBox.Size() |
| 110 | if pos.Y >= sz.Y { |
| 111 | si = len(tx.Spans) - 1 |
| 112 | sr := tx.Spans[si] |
| 113 | ri = len(sr.Render) |
| 114 | ok = true |
| 115 | return |
| 116 | } |
| 117 | if len(tx.Spans) == 0 { |
| 118 | ok = true |
| 119 | return |
| 120 | } |
| 121 | yoff := tx.Spans[0].RelPos.Y // baseline offset applied to everything |
| 122 | for li, sr := range tx.Spans { |
| 123 | st := sr.RelPos |
| 124 | st.Y -= yoff |
| 125 | lp := sr.LastPos |
| 126 | lp.Y += tx.LineHeight - yoff // todo: only for LR |
| 127 | b := math32.Box2{Min: st, Max: lp} |
| 128 | nr := len(sr.Render) |
| 129 | if !b.ContainsPoint(pos) { |
| 130 | if pos.Y >= st.Y && pos.Y < lp.Y { |
| 131 | if pos.X < st.X { |
| 132 | return li, 0, true |
| 133 | } |
| 134 | return li, nr + 1, true |
| 135 | } |
| 136 | continue |
| 137 | } |
| 138 | for j := range sr.Render { |
| 139 | r := &sr.Render[j] |
| 140 | sz := r.Size |
| 141 | sz.Y = tx.LineHeight // todo: only LR |
| 142 | if j < nr-1 { |
| 143 | nxt := &sr.Render[j+1] |
| 144 | sz.X = nxt.RelPos.X - r.RelPos.X |
| 145 | } |
| 146 | ep := st.Add(sz) |
| 147 | b := math32.Box2{Min: st, Max: ep} |
| 148 | if b.ContainsPoint(pos) { |
| 149 | return li, j, true |
| 150 | } |
| 151 | st.X += sz.X // todo: only LR |
| 152 | } |
| 153 | } |
| 154 | return 0, 0, false |
| 155 | } |
| 156 | |
| 157 | ////////////////////////////////////////////////////////////////////////////////// |
| 158 | // TextStyle-based Layout Routines |
no test coverage detected