예제 #1
0
  /**
   * 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);
  }
예제 #2
0
  @Override
  public void setScrollingRegion(int top, int bottom) {
    if (top > bottom) {
      LOG.error("Top margin of scroll region can't be greater then bottom: " + top + ">" + bottom);
    }
    myScrollRegionTop = Math.max(1, top);
    myScrollRegionBottom = Math.min(myTerminalHeight, bottom);

    // DECSTBM moves the cursor to column 1, line 1 of the page
    cursorPosition(1, 1);
  }
예제 #3
0
 public void eraseInLine(int arg) {
   myTerminalTextBuffer.lock();
   try {
     switch (arg) {
       case 0:
         if (myCursorX < myTerminalWidth) {
           myTerminalTextBuffer.eraseCharacters(myCursorX, myTerminalWidth, myCursorY - 1);
         }
         // delete to the end of line : line is no more wrapped
         myTerminalTextBuffer.getLine(myCursorY - 1).setWrapped(false);
         break;
       case 1:
         final int extent = Math.min(myCursorX + 1, myTerminalWidth);
         myTerminalTextBuffer.eraseCharacters(0, extent, myCursorY - 1);
         break;
       case 2:
         myTerminalTextBuffer.eraseCharacters(0, myTerminalWidth, myCursorY - 1);
         break;
       default:
         LOG.error("Unsupported erase in line mode:" + arg);
         break;
     }
   } finally {
     myTerminalTextBuffer.unlock();
   }
 }
예제 #4
0
 @Override
 public void insertBlankCharacters(int count) {
   myTerminalTextBuffer.lock();
   try {
     final int extent = Math.min(count, myTerminalWidth - myCursorX);
     myTerminalTextBuffer.insertBlankCharacters(myCursorX, myCursorY - 1, extent);
   } finally {
     myTerminalTextBuffer.unlock();
   }
 }
예제 #5
0
  @Override
  public void cursorPosition(int x, int y) {
    if (isOriginMode()) {
      myCursorY = y + scrollingRegionTop() - 1;
    } else {
      myCursorY = y;
    }

    if (myCursorY > scrollingRegionBottom()) {
      myCursorY = scrollingRegionBottom();
    }

    // avoid issue due to malformed sequence
    myCursorX = Math.max(0, x - 1);
    myCursorX = Math.min(myCursorX, myTerminalWidth - 1);

    myCursorY = Math.max(0, myCursorY);

    myDisplay.setCursor(myCursorX, myCursorY);
  }
예제 #6
0
 @Override
 public void cursorDown(final int dY) {
   myTerminalTextBuffer.lock();
   try {
     myCursorY += dY;
     myCursorY = Math.min(myCursorY, scrollingRegionBottom());
     myDisplay.setCursor(myCursorX, myCursorY);
   } finally {
     myTerminalTextBuffer.unlock();
   }
 }
예제 #7
0
 @Override
 public void cursorUp(final int countY) {
   myTerminalTextBuffer.lock();
   try {
     myCursorY -= countY;
     myCursorY = Math.max(myCursorY, scrollingRegionTop());
     myDisplay.setCursor(myCursorX, myCursorY);
   } finally {
     myTerminalTextBuffer.unlock();
   }
 }
예제 #8
0
 public void writeUnwrappedString(String string) {
   int length = string.length();
   int off = 0;
   while (off < length) {
     int amountInLine = Math.min(distanceToLineEnd(), length - off);
     writeString(string.substring(off, off + amountInLine));
     wrapLines();
     scrollY();
     off += amountInLine;
   }
 }
예제 #9
0
 @Override
 public void eraseCharacters(int count) {
   // Clear the next n characters on the cursor's line, including the cursor's
   // position.
   myTerminalTextBuffer.lock();
   try {
     final int extent = Math.min(count, myTerminalWidth - myCursorX);
     myTerminalTextBuffer.eraseCharacters(myCursorX, myCursorX + extent, myCursorY - 1);
   } finally {
     myTerminalTextBuffer.unlock();
   }
 }
예제 #10
0
    @Override
    public int previousTab(int position) {
      int tabStop = 0;

      // Search for the first tab stop before the given position...
      SortedSet<Integer> headSet = myTabStops.headSet(Integer.valueOf(position));
      if (!headSet.isEmpty()) {
        tabStop = headSet.last();
      }

      // Don't go beyond the start of the line...
      return Math.max(0, tabStop);
    }
예제 #11
0
    @Override
    public int nextTab(int position) {
      int tabStop = Integer.MAX_VALUE;

      // Search for the first tab stop after the given position...
      SortedSet<Integer> tailSet = myTabStops.tailSet(position + 1);
      if (!tailSet.isEmpty()) {
        tabStop = tailSet.first();
      }

      // Don't go beyond the end of the line...
      return Math.min(tabStop, (myWidth - 1));
    }
예제 #12
0
  private void drawCharacters(int x, int y, TextStyle style, CharBuffer buf, Graphics2D gfx) {
    int xCoord = x * myCharSize.width;
    int yCoord = y * myCharSize.height;

    if (xCoord < 0 || xCoord > getWidth() || yCoord < 0 || yCoord > getHeight()) {
      return;
    }

    gfx.setColor(getPalette().getColor(myStyleState.getBackground(style.getBackgroundForRun())));
    int textLength =
        CharUtils.getTextLengthDoubleWidthAware(
            buf.getBuf(),
            buf.getStart(),
            buf.length(),
            mySettingsProvider.ambiguousCharsAreDoubleWidth());

    gfx.fillRect(
        xCoord,
        yCoord,
        Math.min(textLength * myCharSize.width, getWidth() - xCoord),
        Math.min(myCharSize.height, getHeight() - yCoord));

    if (buf.isNul()) {
      return; // nothing more to do
    }

    drawChars(x, y, buf, style, gfx);

    gfx.setColor(getPalette().getColor(myStyleState.getForeground(style.getForegroundForRun())));

    int baseLine = (y + 1) * myCharSize.height - myDescent;

    if (style.hasOption(TextStyle.Option.UNDERLINED)) {
      gfx.drawLine(xCoord, baseLine + 1, (x + textLength) * myCharSize.width, baseLine + 1);
    }
  }
예제 #13
0
 @Override
 public void horizontalTab() {
   if (myCursorX >= myTerminalWidth) {
     return;
   }
   int length = myTerminalTextBuffer.getLine(myCursorY - 1).getText().length();
   int stop = myTabulator.nextTab(myCursorX);
   myCursorX = Math.max(myCursorX, length);
   if (myCursorX < stop) {
     char[] chars = new char[stop - myCursorX];
     Arrays.fill(chars, CharUtils.EMPTY_CHAR);
     doWriteString(new String(chars));
   } else {
     myCursorX = stop;
   }
   myDisplay.setCursor(myCursorX, myCursorY);
 }
예제 #14
0
 protected Point panelToCharCoords(final Point p) {
   int x = Math.min(p.x / myCharSize.width, getColumnCount() - 1);
   x = Math.max(0, x);
   int y = Math.min(p.y / myCharSize.height, getRowCount() - 1) + myClientScrollOrigin;
   return new Point(x, y);
 }
예제 #15
0
 @Override
 public void cursorBackward(final int dX) {
   myCursorX -= dX;
   myCursorX = Math.max(myCursorX, 0);
   myDisplay.setCursor(myCursorX, myCursorY);
 }
예제 #16
0
 @Override
 public void cursorForward(final int dX) {
   myCursorX += dX;
   myCursorX = Math.min(myCursorX, myTerminalWidth - 1);
   myDisplay.setCursor(myCursorX, myCursorY);
 }