Robiłem trochę pracy z Androidem Canvas
, szczególnie próbując ustalić, jak ustalane są jego wyniki getClipBounds
. Rozumiem, że Canvas
wewnętrznie przechowuje transformację Matrix
, która jest aktualizowana podczas wywoływania translate
, scale
itd., Ale próba odtworzenia wyników Matrix
mnie zdziwiła.Jak Canvas określa granice klipu?
@Override
public void onDraw(Canvas canvas) {
Rect clipBounds;
RectF viewport;
canvas.save();
canvas.concat(translationMatrix);
//viewportMatrix.preConcat(canvas.getMatrix());
viewportMatrix.set(canvas.getMatrix());
clipBounds = canvas.getClipBounds();
viewport = GetViewport();
Log.d("clipBounds", clipBounds.toString() + " (" + clipBounds.width() + ", " + clipBounds.height() + ")");
Log.d("viewport", viewport.toString() + " (" + viewport.width() + ", " + viewport.height() + ")");
//drawing is done here
canvas.restore();
}
//viewport code modeled after http://stackoverflow.com/a/17142856/2245528
private RectF GetViewport() {
RectF viewport = new RectF();
viewportMatrix.mapRect(viewport, originalViewport);
return viewport;
}
private void Translate(float x, float y) {
translationMatrix.postTranslate(x, y);
invalidate();
}
private void Scale(float scaleFactor, PointF focusPoint) {
if (focusPoint == null) {
translationMatrix.postScale(scaleFactor, scaleFactor);
}
//keep the focus point in focus if possible
else {
translationMatrix.postScale(scaleFactor, scaleFactor, focusPoint.x, focusPoint.y);
}
invalidate();
}
private final Matrix translationMatrix = new Matrix();
private final RectF originalViewport = new RectF();
private final Matrix viewportMatrix = new Matrix();
originalViewport
jest ustawiony na 0, 0, canvas.getWidth(), canvas.getHeight()
. Translate
i Scale
są wywoływane z procedur obsługi zdarzeń gestów, które działają poprawnie.
Częścią, która mnie myli, jest viewportMatrix
. Nie ma to znaczenia, czy robię
viewportMatrix.set(canvas.getMatrix());
lub
viewportMatrix.preConcat(canvas.getMatrix());
lub nawet wezwanie jednorazowa
viewportMatrix.set(canvas.getMatrix());
na początku następnie side-by-side Translate
/Scale
połączenia z dwiema macierzami. Ja nawet nie próbował całkowicie ignorując „s Canvas
wbudowane Matrix
i przepisywanie GetViewport
jak
//viewport code modeled after http://stackoverflow.com/a/17142856/2245528
private RectF GetViewport() {
RectF viewport = new RectF();
translationMatrix.mapRect(viewport, originalViewport);
return viewport;
}
nigdy nie wydają się dopasować getClipBounds()
, a rozbieżności są dość poważne:
z viewportMatrix.set(canvas.getMatrix)
:
clipBounds: Rect (-97, -97 - 602, 452) (699, 549)
rzutni: RectF (97,04178, 97,06036, 797,04175 647. 06036) (700,0, 550,0)
z :
clipBounds: Rect (-97, -96 - 602, 453) (699, 549)
wziernika: RectF (2708,9663, 2722.2754, 3408.9663, 3272.2754) (700,0, 550,0)
z translationMatrix.mapRect
:
clipBounds: Rect (-96, -96 - 603, 453) (699, 549)
wziernika: RectF (96,73213, 96,85794, 796,7321, 646,8579) (700.0, 550.0)
z jednego -shot wywołanie viewportMatrix.preConcat(canvas.getMatrix())
następnie side-by-side Translate
/Scale
połączeń:
clipBounds: rect (-96, -97 - 603, 452) (699, 549)
wziernika: RectF (96,57738, 97,78168, 796,5774, 647,7817) (700,0, 550.0)
z rozmowy jeden strzał viewportMatrix.set(canvas.getMatrix())
następnie side-by-side Translate
/Scale
połączeń:
clipBounds: Rect (-96, -96 - 603, 453) (699 , 549)
rzutnia: RectF (96,40051, 96,88153, 796,4005, 646,88153) (700,0, 550,0)
nie mogę nawet sprawdzić the Canvas
source, jak cały kod Matrix
znika w prywatnej nat ive połączeń, których kod nie jest wyświetlany.
Dlaczego moje wywołania GetViewport
są tak brutalne, a co dzieje się za kulisami z getClipBounds
?