*
* The MIT License (MIT)
*
- * Copyright (C) 2016 Kevin Lamonte
+ * Copyright (C) 2017 Kevin Lamonte
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
/**
* If true, use triple buffering thread.
*/
- private static final boolean tripleBuffer = true;
+ private static boolean tripleBuffer = true;
/**
* Cursor style to draw.
* Public constructor.
*
* @param screen the Screen that Backend talks to
+ * @param fontSize the size in points. Good values to pick are: 16,
+ * 20, 22, and 24.
*/
- public SwingFrame(final SwingScreen screen) {
+ public SwingFrame(final SwingScreen screen, final int fontSize) {
this.screen = screen;
setDOSColors();
cursorStyle = CursorStyle.BLOCK;
}
+ if (System.getProperty("jexer.Swing.tripleBuffer") != null) {
+ if (System.getProperty("jexer.Swing.tripleBuffer").
+ equals("false")) {
+
+ SwingScreen.tripleBuffer = false;
+ }
+ }
+
setTitle("Jexer Application");
setBackground(Color.black);
getContextClassLoader();
InputStream in = loader.getResourceAsStream(FONTFILE);
Font terminusRoot = Font.createFont(Font.TRUETYPE_FONT, in);
- Font terminus = terminusRoot.deriveFont(Font.PLAIN, 20);
+ Font terminus = terminusRoot.deriveFont(Font.PLAIN, fontSize);
setFont(terminus);
gotTerminus = true;
} catch (Exception e) {
e.printStackTrace();
// setFont(new Font("Liberation Mono", Font.PLAIN, 24));
- setFont(new Font(Font.MONOSPACED, Font.PLAIN, 24));
+ setFont(new Font(Font.MONOSPACED, Font.PLAIN, fontSize));
}
pack();
}
}
+ /**
+ * Figure out what textAdjustX and textAdjustY should be, based on
+ * the location of a vertical bar (to find textAdjustY) and a
+ * horizontal bar (to find textAdjustX).
+ *
+ * @return true if textAdjustX and textAdjustY were guessed at
+ * correctly
+ */
+ private boolean getFontAdjustments() {
+ BufferedImage image = null;
+
+ // What SHOULD happen is that the topmost/leftmost white pixel is
+ // at position (gr2x, gr2y). But it might also be off by a pixel
+ // in either direction.
+
+ Graphics2D gr2 = null;
+ int gr2x = 3;
+ int gr2y = 3;
+ image = new BufferedImage(textWidth * 2, textHeight * 2,
+ BufferedImage.TYPE_INT_ARGB);
+
+ gr2 = image.createGraphics();
+ gr2.setFont(getFont());
+ gr2.setColor(java.awt.Color.BLACK);
+ gr2.fillRect(0, 0, textWidth * 2, textHeight * 2);
+ gr2.setColor(java.awt.Color.WHITE);
+ char [] chars = new char[1];
+ chars[0] = jexer.bits.GraphicsChars.VERTICAL_BAR;
+ gr2.drawChars(chars, 0, 1, gr2x, gr2y + textHeight - maxDescent);
+ gr2.dispose();
+
+ for (int x = 0; x < textWidth; x++) {
+ for (int y = 0; y < textHeight; y++) {
+
+ /*
+ System.err.println("X: " + x + " Y: " + y + " " +
+ image.getRGB(x, y));
+ */
+
+ if ((image.getRGB(x, y) & 0xFFFFFF) != 0) {
+ textAdjustY = (gr2y - y);
+
+ // System.err.println("textAdjustY: " + textAdjustY);
+ x = textWidth;
+ break;
+ }
+ }
+ }
+
+ gr2 = image.createGraphics();
+ gr2.setFont(getFont());
+ gr2.setColor(java.awt.Color.BLACK);
+ gr2.fillRect(0, 0, textWidth * 2, textHeight * 2);
+ gr2.setColor(java.awt.Color.WHITE);
+ chars[0] = jexer.bits.GraphicsChars.SINGLE_BAR;
+ gr2.drawChars(chars, 0, 1, gr2x, gr2y + textHeight - maxDescent);
+ gr2.dispose();
+
+ for (int x = 0; x < textWidth; x++) {
+ for (int y = 0; y < textHeight; y++) {
+
+ /*
+ System.err.println("X: " + x + " Y: " + y + " " +
+ image.getRGB(x, y));
+ */
+
+ if ((image.getRGB(x, y) & 0xFFFFFF) != 0) {
+ textAdjustX = (gr2x - x);
+
+ // System.err.println("textAdjustX: " + textAdjustX);
+ return true;
+ }
+ }
+ }
+
+ // Something weird happened, don't rely on this function.
+ // System.err.println("getFontAdjustments: false");
+ return false;
+ }
+
+
/**
* Figure out my font dimensions.
*/
textHeight++;
}
- if (System.getProperty("os.name").startsWith("Windows")) {
- textAdjustY = -1;
- textAdjustX = 0;
- }
- if (System.getProperty("os.name").startsWith("Mac")) {
- textAdjustY = -1;
- textAdjustX = 0;
+ if (getFontAdjustments() == false) {
+ // We were unable to programmatically determine textAdjustX
+ // and textAdjustY, so try some guesses based on VM vendor.
+ String runtime = System.getProperty("java.runtime.name");
+ if ((runtime != null) && (runtime.contains("Java(TM)"))) {
+ textAdjustY = -1;
+ textAdjustX = 0;
+ }
}
}
}
// Generate glyph and draw it.
-
- image = new BufferedImage(textWidth, textHeight,
- BufferedImage.TYPE_INT_ARGB);
- Graphics2D gr2 = image.createGraphics();
- gr2.setFont(getFont());
+ Graphics2D gr2 = null;
+ int gr2x = xPixel;
+ int gr2y = yPixel;
+ if (tripleBuffer) {
+ image = new BufferedImage(textWidth, textHeight,
+ BufferedImage.TYPE_INT_ARGB);
+ gr2 = image.createGraphics();
+ gr2.setFont(getFont());
+ gr2x = 0;
+ gr2y = 0;
+ } else {
+ gr2 = (Graphics2D) gr;
+ }
Cell cellColor = new Cell();
cellColor.setTo(cell);
// Draw the background rectangle, then the foreground character.
gr2.setColor(attrToBackgroundColor(cellColor));
- gr2.fillRect(0, 0, textWidth, textHeight);
+ gr2.fillRect(gr2x, gr2y, textWidth, textHeight);
// Handle blink and underline
if (!cell.isBlink()
gr2.setColor(attrToForegroundColor(cellColor));
char [] chars = new char[1];
chars[0] = cell.getChar();
- gr2.drawChars(chars, 0, 1, 0 + textAdjustX,
- 0 + textHeight - maxDescent + textAdjustY);
+ gr2.drawChars(chars, 0, 1, gr2x + textAdjustX,
+ gr2y + textHeight - maxDescent + textAdjustY);
if (cell.isUnderline()) {
- gr2.fillRect(0, 0 + textHeight - 2, textWidth, 2);
+ gr2.fillRect(gr2x, gr2y + textHeight - 2, textWidth, 2);
}
}
- gr2.dispose();
- // We need a new key that will not be mutated by invertCell().
- Cell key = new Cell();
- key.setTo(cell);
- if (cell.isBlink() && !cursorBlinkVisible) {
- glyphCacheBlink.put(key, image);
- } else {
- glyphCache.put(key, image);
+ if (tripleBuffer) {
+ gr2.dispose();
+
+ // We need a new key that will not be mutated by
+ // invertCell().
+ Cell key = new Cell();
+ key.setTo(cell);
+ if (cell.isBlink() && !cursorBlinkVisible) {
+ glyphCacheBlink.put(key, image);
+ } else {
+ glyphCache.put(key, image);
+ }
+
+ gr.drawImage(image, xPixel, yPixel, this);
}
- gr.drawImage(image, xPixel, yPixel, this);
}
/**
/**
* Public constructor.
+ *
+ * @param windowWidth the number of text columns to start with
+ * @param windowHeight the number of text rows to start with
+ * @param fontSize the size in points. Good values to pick are: 16, 20,
+ * 22, and 24.
*/
- public SwingScreen() {
+ public SwingScreen(final int windowWidth, final int windowHeight,
+ final int fontSize) {
+
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- SwingScreen.this.frame = new SwingFrame(SwingScreen.this);
+ SwingScreen.this.frame = new SwingFrame(SwingScreen.this,
+ fontSize);
SwingScreen.this.sessionInfo =
new SwingSessionInfo(SwingScreen.this.frame,
- frame.textWidth,
- frame.textHeight);
+ frame.textWidth, frame.textHeight,
+ windowWidth, windowHeight);
SwingScreen.this.setDimensions(sessionInfo.getWindowWidth(),
sessionInfo.getWindowHeight());