recover terminal metrics from helix buffer
This commit is contained in:
86
src/main/java/com/gregor/jprototerm/TerminalMetrics.java
Normal file
86
src/main/java/com/gregor/jprototerm/TerminalMetrics.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package com.gregor.jprototerm;
|
||||
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
/**
|
||||
* Cell geometry shared by the {@link Compositor} and every {@link TerminalPane}.
|
||||
*
|
||||
* <p>The nominal cell width/height come from measuring the font, but a grid can't use
|
||||
* fractional cells, so the measured size is snapped to whole (logical) pixels here — that
|
||||
* snapping is why the value isn't purely a property of the font. The compositor owns the
|
||||
* single instance (it holds the canvas, which is the pixel context), hands it to panes so
|
||||
* they can turn their rect into a column/row count themselves, and re-measures it on a font
|
||||
* change so every pane observes the new geometry through the shared reference.
|
||||
*/
|
||||
public final class TerminalMetrics {
|
||||
/** Inset, in pixels, between a pane's edge and its content on every side. */
|
||||
public static final double PADDING = 12.0;
|
||||
|
||||
private String fontFamily;
|
||||
private double fontSize;
|
||||
private Font font;
|
||||
private double cellWidth;
|
||||
private double lineHeight;
|
||||
private double baselineOffset;
|
||||
|
||||
public TerminalMetrics(String fontFamily, double fontSize) {
|
||||
setFont(fontFamily, fontSize);
|
||||
}
|
||||
|
||||
public void setFont(String fontFamily, double fontSize) {
|
||||
this.fontFamily = fontFamily;
|
||||
this.fontSize = fontSize;
|
||||
this.font = Font.font(fontFamily, fontSize);
|
||||
measure(font);
|
||||
}
|
||||
|
||||
public String fontFamily() {
|
||||
return fontFamily;
|
||||
}
|
||||
|
||||
public double fontSize() {
|
||||
return fontSize;
|
||||
}
|
||||
|
||||
public Font font() {
|
||||
return font;
|
||||
}
|
||||
|
||||
public double cellWidth() {
|
||||
return cellWidth;
|
||||
}
|
||||
|
||||
public double lineHeight() {
|
||||
return lineHeight;
|
||||
}
|
||||
|
||||
public double baselineOffset() {
|
||||
return baselineOffset;
|
||||
}
|
||||
|
||||
/** Columns that fit in a pane of the given pixel width (after subtracting the padding). */
|
||||
public int columnsFor(double widthPx) {
|
||||
return Math.max(1, (int) ((widthPx - 2 * PADDING) / cellWidth));
|
||||
}
|
||||
|
||||
/** Rows that fit in a pane of the given pixel height (after subtracting the padding). */
|
||||
public int rowsFor(double heightPx) {
|
||||
return Math.max(1, (int) ((heightPx - 2 * PADDING) / lineHeight));
|
||||
}
|
||||
|
||||
private void measure(Font font) {
|
||||
Text text = new Text("┃MgÅjy");
|
||||
text.setFont(font);
|
||||
// Snap the cell size to whole pixels so cells tile on integer boundaries. Fractional
|
||||
// cell metrics put every cell edge on a sub-pixel position, leaving anti-aliased
|
||||
// seams that show up as a faint grid behind the themed cell backgrounds. Rounding
|
||||
// leaves a few pixels of unused space at the right/bottom edge, which is fine.
|
||||
this.lineHeight = Math.max(1.0, Math.round(text.getLayoutBounds().getHeight()));
|
||||
this.baselineOffset = -text.getLayoutBounds().getMinY();
|
||||
|
||||
Text cell = new Text("M");
|
||||
cell.setFont(font);
|
||||
this.cellWidth = Math.max(1.0, Math.round(cell.getLayoutBounds().getWidth()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user