4W2NJTC3NV4T3OF4KGGR2ADSXCCTV5GVQMN6TR6D5N4QESFWYY4QC
OELP2MAL5RGZ3AZ42V6H7RLGX52JLNHGUD7GV6YIVZ3ACOK5SFSQC
O6D22PJBXFE5XGW27UD7NDIMQYL4NXH4C4T2E73F2NXUSEB4W7QQC
7TQAF4BYIK75EEYCCK7VEUSZHNCWMWIA3HZGQKIILYESUZ5ZZRVQC
BF7TW3EKRIDYC6J2Q2J4YOBAVQF55Y3H6KGZIHNXMH4N72MR6GXQC
5HBC66CSFQ257TO3DJYBUNKE5RKR47CUJNMYP6Y4F7T6W7LNRV4AC
7P3EK7K2AWA3YDMQBFWJY4TVIKGJ5LI7E4P4F7Z2CVAGVETA3JHAC
-- Most of the time, we update the screen_top of nodes from Viewport.y.
-- But here we went the other way.
-- It's very important to avoid creating a recurrence, to avoid running
-- both sides of this feedback loop in a single frame. These apps are
-- not very numerically precise (e.g. we force text lines to start at
-- integer pixels regardless of zoom, because that keeps text crisp),
-- and the computations of Viewport.y and node.top will almost certainly
-- not converge. The resulting bugs are extremely difficult to chase
-- down.
-- The optional skip_updating_screen_top_for arg ensures we don't run
-- the other side of the feedback loop.
-- Most of the time, we update the screen_top of nodes from Viewport.y.
-- But here we went the other way.
-- It's very important to avoid creating a recurrence, to avoid running
-- both sides of this feedback loop in a single frame. These apps are
-- not very numerically precise (e.g. we force text lines to start at
-- integer pixels regardless of zoom, because that keeps text crisp),
-- and the computations of Viewport.y and node.top will almost certainly
-- not converge. The resulting bugs are extremely difficult to chase
-- down.
-- The optional skip_updating_screen_top_for arg ensures we don't run
-- the other side of the feedback loop.