|
129 | 129 | if (_log.Count > MaxLogEntries) |
130 | 130 | _log.RemoveAt(_log.Count - 1); |
131 | 131 |
|
| 132 | + // Scale CSS-pixel coordinates to canvas pixels (device DPI). |
| 133 | + // Touch events arrive in CSS pixels, but the SkiaSharp surface |
| 134 | + // renders at device pixel ratio when IgnorePixelScaling is false. |
| 135 | + var dpi = _canvasView?.Dpi ?? 1f; |
| 136 | + var scaledLocation = new SKPoint(e.Location.X * dpi, e.Location.Y * dpi); |
| 137 | + |
132 | 138 | // Drawing strokes |
133 | 139 | switch (e.ActionType) |
134 | 140 | { |
135 | 141 | case SKTouchAction.Pressed: |
136 | 142 | var stroke = new Stroke { DeviceType = e.DeviceType }; |
137 | | - stroke.Points.Add(e.Location); |
| 143 | + stroke.Points.Add(scaledLocation); |
138 | 144 | _strokes.Add(stroke); |
139 | 145 | _activeStrokes[e.Id] = stroke; |
140 | 146 | break; |
141 | 147 |
|
142 | 148 | case SKTouchAction.Moved: |
143 | 149 | if (_activeStrokes.TryGetValue(e.Id, out var active)) |
144 | | - active.Points.Add(e.Location); |
| 150 | + active.Points.Add(scaledLocation); |
145 | 151 | break; |
146 | 152 |
|
147 | 153 | case SKTouchAction.Released: |
148 | 154 | case SKTouchAction.Cancelled: |
149 | 155 | if (_activeStrokes.TryGetValue(e.Id, out var finished)) |
150 | 156 | { |
151 | | - finished.Points.Add(e.Location); |
| 157 | + finished.Points.Add(scaledLocation); |
152 | 158 | _activeStrokes.Remove(e.Id); |
153 | 159 | } |
154 | 160 | break; |
|
165 | 171 | var canvas = e.Surface.Canvas; |
166 | 172 | canvas.Clear(SKColors.White); |
167 | 173 |
|
| 174 | + // Scale stroke width and legend by DPI so they look correct at device resolution |
| 175 | + var dpi = _canvasView?.Dpi ?? 1f; |
| 176 | + |
168 | 177 | using var paint = new SKPaint |
169 | 178 | { |
170 | 179 | IsAntialias = true, |
171 | | - StrokeWidth = 3, |
| 180 | + StrokeWidth = 3 * dpi, |
172 | 181 | Style = SKPaintStyle.Stroke, |
173 | 182 | StrokeCap = SKStrokeCap.Round, |
174 | 183 | StrokeJoin = SKStrokeJoin.Round, |
|
188 | 197 | canvas.DrawPath(path, paint); |
189 | 198 | } |
190 | 199 |
|
191 | | - // Legend in top-left corner |
192 | | - using var legendFont = new SKFont { Size = 12, Edging = SKFontEdging.SubpixelAntialias }; |
| 200 | + // Legend in top-left corner (scaled by DPI) |
| 201 | + using var legendFont = new SKFont { Size = 12 * dpi, Edging = SKFontEdging.SubpixelAntialias }; |
193 | 202 | using var legendPaint = new SKPaint { IsAntialias = true }; |
194 | | - var y = 16f; |
| 203 | + var y = 16f * dpi; |
195 | 204 | foreach (var (name, _, color) in DeviceColors) |
196 | 205 | { |
197 | 206 | legendPaint.Color = color; |
198 | | - canvas.DrawCircle(12, y - 4, 5, legendPaint); |
| 207 | + canvas.DrawCircle(12 * dpi, y - 4 * dpi, 5 * dpi, legendPaint); |
199 | 208 | legendPaint.Color = SKColors.Black; |
200 | | - canvas.DrawText(name, 22, y, SKTextAlign.Left, legendFont, legendPaint); |
201 | | - y += 18; |
| 209 | + canvas.DrawText(name, 22 * dpi, y, SKTextAlign.Left, legendFont, legendPaint); |
| 210 | + y += 18 * dpi; |
202 | 211 | } |
203 | 212 | } |
204 | 213 |
|
|
0 commit comments