+#define FRAME_CANON_Y_FROM_PIXEL_Y(F, Y) \
+ ((Y) % FRAME_LINE_HEIGHT (F) \
+ ? make_float ((double) (Y) / FRAME_LINE_HEIGHT (F)) \
+ : make_number ((Y) / FRAME_LINE_HEIGHT (F)))
+
+
+\f
+/* Manipulating pixel sizes and character sizes.
+ Knowledge of which factors affect the overall size of the window should
+ be hidden in these macros, if that's possible.
+
+ Return the upper/left pixel position of the character cell on frame F
+ at ROW/COL. */
+
+#define FRAME_LINE_TO_PIXEL_Y(f, row) \
+ (FRAME_INTERNAL_BORDER_WIDTH (f) \
+ + (row) * FRAME_LINE_HEIGHT (f))
+
+#define FRAME_COL_TO_PIXEL_X(f, col) \
+ (FRAME_INTERNAL_BORDER_WIDTH (f) \
+ + (col) * FRAME_COLUMN_WIDTH (f))
+
+/* Return the pixel width/height of frame F if it has
+ COLS columns/LINES rows. */
+
+#define FRAME_TEXT_COLS_TO_PIXEL_WIDTH(f, cols) \
+ (FRAME_COL_TO_PIXEL_X (f, cols) \
+ + (f)->scroll_bar_actual_width \
+ + FRAME_TOTAL_FRINGE_WIDTH (f) \
+ + FRAME_INTERNAL_BORDER_WIDTH (f))
+
+#define FRAME_TEXT_LINES_TO_PIXEL_HEIGHT(f, lines) \
+ (FRAME_LINE_TO_PIXEL_Y (f, lines) \
+ + FRAME_INTERNAL_BORDER_WIDTH (f))
+
+
+/* Return the row/column (zero-based) of the character cell containing
+ the pixel on FRAME at Y/X. */
+
+#define FRAME_PIXEL_Y_TO_LINE(f, y) \
+ (((y) - FRAME_INTERNAL_BORDER_WIDTH (f)) \
+ / FRAME_LINE_HEIGHT (f))
+
+#define FRAME_PIXEL_X_TO_COL(f, x) \
+ (((x) - FRAME_INTERNAL_BORDER_WIDTH (f)) \
+ / FRAME_COLUMN_WIDTH (f))
+
+/* How many columns/rows of text can we fit in WIDTH/HEIGHT pixels on
+ frame F? */
+
+#define FRAME_PIXEL_WIDTH_TO_TEXT_COLS(f, width) \
+ (FRAME_PIXEL_X_TO_COL (f, ((width) \
+ - FRAME_INTERNAL_BORDER_WIDTH (f) \
+ - FRAME_TOTAL_FRINGE_WIDTH (f) \
+ - (f)->scroll_bar_actual_width)))
+
+#define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height) \
+ (FRAME_PIXEL_Y_TO_LINE (f, ((height) \
+ - FRAME_INTERNAL_BORDER_WIDTH (f))))