/** * Draw every char in separate terminal cell to guaranty equal width for different lines. * Nevertheless to improve kerning we draw word characters as one block for monospaced fonts. */ private void drawChars(int x, int y, CharBuffer buf, TextStyle style, Graphics2D gfx) { final int blockLen = 1; int offset = 0; int drawCharsOffset = 0; // workaround to fix Swing bad rendering of bold special chars on Linux // TODO required for italic? CharBuffer renderingBuffer; if (mySettingsProvider.DECCompatibilityMode() && style.hasOption(TextStyle.Option.BOLD)) { renderingBuffer = CharUtils.heavyDecCompatibleBuffer(buf); } else { renderingBuffer = buf; } while (offset + blockLen <= buf.length()) { if (renderingBuffer.getBuf()[buf.getStart() + offset] == CharUtils.DWC) { offset += blockLen; drawCharsOffset += blockLen; continue; // dont' draw second part(fake one) of double width character } Font font = getFontToDisplay(buf.charAt(offset + blockLen - 1), style); // while (myMonospaced && (offset + blockLen < buf.getLength()) && // isWordCharacter(buf.charAt(offset + blockLen - 1)) // && (font == getFontToDisplay(buf.charAt(offset + blockLen - 1), style))) { // blockLen++; // } gfx.setFont(font); int descent = gfx.getFontMetrics(font).getDescent(); int baseLine = (y + 1) * myCharSize.height - descent; int xCoord = (x + drawCharsOffset) * myCharSize.width; int textLength = CharUtils.getTextLengthDoubleWidthAware( buf.getBuf(), buf.getStart() + offset, blockLen, mySettingsProvider.ambiguousCharsAreDoubleWidth()); int yCoord = y * myCharSize.height; gfx.setClip( xCoord, yCoord, Math.min(textLength * myCharSize.width, getWidth() - xCoord), Math.min(myCharSize.height, getHeight() - yCoord)); gfx.setColor(getPalette().getColor(myStyleState.getForeground(style.getForegroundForRun()))); gfx.drawChars(renderingBuffer.getBuf(), buf.getStart() + offset, blockLen, xCoord, baseLine); drawCharsOffset += blockLen; offset += blockLen; } gfx.setClip(null); }
private void establishFontMetrics() { final BufferedImage img = createBufferedImage(1, 1); final Graphics2D graphics = img.createGraphics(); graphics.setFont(myNormalFont); final float lineSpace = mySettingsProvider.getLineSpace(); final FontMetrics fo = graphics.getFontMetrics(); myDescent = fo.getDescent(); myCharSize.width = fo.charWidth('W'); myCharSize.height = fo.getHeight() + (int) (lineSpace * 2); myDescent += lineSpace; myMonospaced = isMonospaced(fo); if (!myMonospaced) { LOG.info("WARNING: Font " + myNormalFont.getName() + " is non-monospaced"); } img.flush(); graphics.dispose(); }
private void drawInputMethodUncommitedChars(Graphics2D gfx) { if (myInputMethodUncommitedChars != null && myInputMethodUncommitedChars.length() > 0) { int x = myCursor.getCoordX() * myCharSize.width; int y = (myCursor.getCoordY()) * myCharSize.height - 2; int len = (myInputMethodUncommitedChars.length()) * myCharSize.width; gfx.setColor(getBackground()); gfx.fillRect(x, (myCursor.getCoordY() - 1) * myCharSize.height, len, myCharSize.height); gfx.setColor(getForeground()); gfx.setFont(myNormalFont); gfx.drawString(myInputMethodUncommitedChars, x, y); Stroke saved = gfx.getStroke(); BasicStroke dotted = new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, new float[] {0, 2, 0, 2}, 0); gfx.setStroke(dotted); gfx.drawLine(x, y, x + len, y); gfx.setStroke(saved); } }