Program: 157423
Project: 157423
Buggy source:
private void onBufferDraw(Canvas canvas){
  if (mKeyboardChanged) {
    invalidateAllKeys();
    mKeyboardChanged=false;
  }
  canvas.getClipBounds(mDirtyRect);
  if (mKeyboard == null)   return;
  final boolean drawKeyboardNameText=(mKeyboardNameTextSize > 1f) && AnyApplication.getConfig().getShowKeyboardNameText();
  final boolean drawHintText=(mHintTextSize > 1) && AnyApplication.getConfig().getShowHintTextOnKeys();
  final boolean useCustomKeyTextColor=false;
  final ColorStateList keyTextColor=useCustomKeyTextColor ? new ColorStateList(new int[][]{{0}},new int[]{0xFF6666FF}) : mKeyTextColor;
  final boolean useCustomHintColor=drawHintText && false;
  final ColorStateList hintColor=useCustomHintColor ? new ColorStateList(new int[][]{{0}},new int[]{0xFFFF6666}) : mHintTextColor;
  final boolean useCustomHintAlign=drawHintText && AnyApplication.getConfig().getUseCustomHintAlign();
  final int hintAlign=useCustomHintAlign ? AnyApplication.getConfig().getCustomHintAlign() : mHintLabelAlign;
  final int hintVAlign=useCustomHintAlign ? AnyApplication.getConfig().getCustomHintVAlign() : mHintLabelVAlign;
  final Paint paint=mPaint;
  final Drawable keyBackground=mKeyBackground;
  final Rect clipRegion=mClipRegion;
  final int kbdPaddingLeft=getPaddingLeft();
  final int kbdPaddingTop=getPaddingTop();
  final Key[] keys=mKeys;
  final Key invalidKey=mInvalidatedKey;
  boolean drawSingleKey=false;
  if (invalidKey != null && canvas.getClipBounds(clipRegion)) {
    if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left && invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top && invalidKey.x + invalidKey.width + kbdPaddingLeft+ 1 >= clipRegion.right && invalidKey.y + invalidKey.height + kbdPaddingTop+ 1 >= clipRegion.bottom) {
      drawSingleKey=true;
    }
  }
  for (  Key keyBase : keys) {
    final AnyKey key=(AnyKey)keyBase;
    final boolean keyIsSpace=isSpaceKey(key);
    if (drawSingleKey && (invalidKey != key)) {
      continue;
    }
    if (!mDirtyRect.intersects(key.x + kbdPaddingLeft,key.y + kbdPaddingTop,key.x + key.width + kbdPaddingLeft,key.y + key.height + kbdPaddingTop)) {
      continue;
    }
    int[] drawableState=key.getCurrentDrawableState(mDrawableStatesProvider);
    if (keyIsSpace)     paint.setColor(mKeyboardNameTextColor.getColorForState(drawableState,0xFF000000));
 else     paint.setColor(keyTextColor.getColorForState(drawableState,0xFF000000));
    keyBackground.setState(drawableState);
    CharSequence label=key.label == null ? null : adjustCase(key).toString();
    final Rect bounds=keyBackground.getBounds();
    if ((key.width != bounds.right) || (key.height != bounds.bottom)) {
      keyBackground.setBounds(0,0,key.width,key.height);
    }
    canvas.translate(key.x + kbdPaddingLeft,key.y + kbdPaddingTop);
    keyBackground.draw(canvas);
    if (TextUtils.isEmpty(label)) {
      Drawable iconToDraw=getIconToDrawForKey(key,false);
      if (iconToDraw != null) {
        final boolean is9Patch=iconToDraw.getCurrent() instanceof NinePatchDrawable;
        final int drawableWidth;
        final int drawableHeight;
        final int drawableX;
        final int drawableY;
        drawableWidth=is9Patch ? key.width : iconToDraw.getIntrinsicWidth();
        drawableHeight=is9Patch ? key.height : iconToDraw.getIntrinsicHeight();
        drawableX=(key.width + mKeyBackgroundPadding.left - mKeyBackgroundPadding.right - drawableWidth) / 2;
        drawableY=(key.height + mKeyBackgroundPadding.top - mKeyBackgroundPadding.bottom - drawableHeight) / 2;
        canvas.translate(drawableX,drawableY);
        iconToDraw.setBounds(0,0,drawableWidth,drawableHeight);
        iconToDraw.draw(canvas);
        canvas.translate(-drawableX,-drawableY);
        if (keyIsSpace && drawKeyboardNameText) {
          label=mKeyboardName;
        }
      }
 else {
        label=guessLabelForKey(key.codes[0]);
        if (TextUtils.isEmpty(label)) {
          Log.w(TAG,"String_Node_Str" + key.codes[0] + "String_Node_Str"+ key.x+ "String_Node_Str"+ key.y+ "String_Node_Str"+ mKeyboardActionType);
        }
      }
    }
    if (label != null) {
      final FontMetrics fm;
      if (keyIsSpace) {
        paint.setTextSize(mKeyboardNameTextSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD);
        if (mKeyboardNameFM == null)         mKeyboardNameFM=paint.getFontMetrics();
        fm=mKeyboardNameFM;
      }
 else       if (label.length() > 1 && key.codes.length < 2) {
        setPaintForLabelText(paint);
        if (mLabelFM == null)         mLabelFM=paint.getFontMetrics();
        fm=mLabelFM;
      }
 else {
        setPaintToKeyText(paint);
        if (mTextFM == null)         mTextFM=paint.getFontMetrics();
        fm=mTextFM;
      }
      final float labelHeight=-fm.top;
      paint.setShadowLayer(mShadowRadius,mShadowOffsetX,mShadowOffsetY,mShadowColor);
      float textWidth=paint.measureText(label,0,label.length());
      if (textWidth > key.width) {
        Log.d(TAG,"String_Node_Str" + label + "String_Node_Str");
        paint.setTextSize(mKeyTextSize / 1.5f);
        textWidth=paint.measureText(label,0,label.length());
        if (textWidth > key.width) {
          Log.d(TAG,"String_Node_Str" + label + "String_Node_Str");
          paint.setTextSize(mKeyTextSize / 2.5f);
          textWidth=paint.measureText(label,0,label.length());
          if (textWidth > key.width) {
            Log.d(TAG,"String_Node_Str" + label + "String_Node_Str");
            paint.setTextSize(0f);
            textWidth=paint.measureText(label,0,label.length());
          }
        }
      }
      final float centerY=mKeyBackgroundPadding.top + ((key.height - mKeyBackgroundPadding.top - mKeyBackgroundPadding.bottom) / (keyIsSpace ? 3 : 2));
      final float textX=mKeyBackgroundPadding.left + (key.width - mKeyBackgroundPadding.left - mKeyBackgroundPadding.right) / 2;
      final float textY;
      if (label.length() > 1 && !AnyApplication.getConfig().workaround_alwaysUseDrawText()) {
        textY=centerY - ((labelHeight - paint.descent()) / 2);
        canvas.translate(textX,textY);
        Log.d(TAG,"String_Node_Str" + label + "String_Node_Str");
        StaticLayout labelText=new StaticLayout(label,new TextPaint(paint),(int)textWidth,Alignment.ALIGN_NORMAL,1.0f,0.0f,false);
        labelText.draw(canvas);
      }
 else {
        textY=centerY + ((labelHeight - paint.descent()) / 2);
        canvas.translate(textX,textY);
        canvas.drawText(label,0,label.length(),0,0,paint);
      }
      canvas.translate(-textX,-textY);
      paint.setShadowLayer(0,0,0,0);
    }
    if (drawHintText) {
      if ((key.popupCharacters != null && key.popupCharacters.length() > 0) || (key.popupResId != 0) || (key.longPressCode != 0)) {
        Align oldAlign=paint.getTextAlign();
        String hintText=null;
        if (key.hintLabel != null && key.hintLabel.length() > 0) {
          hintText=key.hintLabel.toString();
        }
 else         if (key.longPressCode != 0) {
          if (Character.isLetterOrDigit(key.longPressCode))           hintText=Character.toString((char)key.longPressCode);
        }
 else         if (key.popupCharacters != null) {
          final String hintString=key.popupCharacters.toString();
          final int hintLength=hintString.length();
          if (hintLength <= 3)           hintText=hintString;
        }
        if (hintText == null) {
          if (mHintOverflowLabel != null)           hintText=mHintOverflowLabel;
 else {
            if (hintVAlign == Gravity.TOP)             hintText="String_Node_Str";
 else             hintText="String_Node_Str";
          }
        }
        if (mKeyboard.isShifted())         hintText=hintText.toUpperCase(getKeyboard().getLocale());
        paint.setTypeface(Typeface.DEFAULT);
        paint.setColor(hintColor.getColorForState(drawableState,0xFF000000));
        paint.setTextSize(mHintTextSize);
        if (mHintTextFM == null) {
          mHintTextFM=paint.getFontMetrics();
        }
        final float hintX;
        final float hintY;
        if (hintAlign == Gravity.START) {
          paint.setTextAlign(Align.LEFT);
          hintX=mKeyBackgroundPadding.left + (float)0.5;
        }
 else         if (hintAlign == Gravity.CENTER) {
          paint.setTextAlign(Align.CENTER);
          hintX=mKeyBackgroundPadding.left + (key.width - mKeyBackgroundPadding.left - mKeyBackgroundPadding.right) / 2;
        }
 else {
          paint.setTextAlign(Align.RIGHT);
          hintX=key.width - mKeyBackgroundPadding.right - (float)0.5;
        }
        if (hintVAlign == Gravity.TOP) {
          hintY=mKeyBackgroundPadding.top - mHintTextFM.top + (float)0.5;
        }
 else {
          hintY=key.height - mKeyBackgroundPadding.bottom - mHintTextFM.bottom- (float)0.5;
        }
        canvas.drawText(hintText,hintX,hintY,paint);
        paint.setTextAlign(oldAlign);
      }
    }
    canvas.translate(-key.x - kbdPaddingLeft,-key.y - kbdPaddingTop);
  }
  mInvalidatedKey=null;
  if (mMiniKeyboard != null && mMiniKeyboardVisible) {
    paint.setColor((int)(mBackgroundDimAmount * 0xFF) << 24);
    canvas.drawRect(0,0,getWidth(),getHeight(),paint);
  }
  mDrawPending=false;
  mDirtyRect.setEmpty();
}

Fixed version (ground truth):
private void onBufferDraw(Canvas canvas){
  if (mKeyboardChanged) {
    invalidateAllKeys();
    mKeyboardChanged=false;
  }
  canvas.getClipBounds(mDirtyRect);
  if (mKeyboard == null)   return;
  final boolean drawKeyboardNameText=(mKeyboardNameTextSize > 1f) && AnyApplication.getConfig().getShowKeyboardNameText();
  final boolean drawHintText=(mHintTextSize > 1) && AnyApplication.getConfig().getShowHintTextOnKeys();
  final boolean useCustomKeyTextColor=false;
  final ColorStateList keyTextColor=useCustomKeyTextColor ? new ColorStateList(new int[][]{{0}},new int[]{0xFF6666FF}) : mKeyTextColor;
  final boolean useCustomHintColor=drawHintText && false;
  final ColorStateList hintColor=useCustomHintColor ? new ColorStateList(new int[][]{{0}},new int[]{0xFFFF6666}) : mHintTextColor;
  final boolean useCustomHintAlign=drawHintText && AnyApplication.getConfig().getUseCustomHintAlign();
  final int hintAlign=useCustomHintAlign ? AnyApplication.getConfig().getCustomHintAlign() : mHintLabelAlign;
  final int hintVAlign=useCustomHintAlign ? AnyApplication.getConfig().getCustomHintVAlign() : mHintLabelVAlign;
  final Paint paint=mPaint;
  final Drawable keyBackground=mKeyBackground;
  final Rect clipRegion=mClipRegion;
  final int kbdPaddingLeft=getPaddingLeft();
  final int kbdPaddingTop=getPaddingTop();
  final Key[] keys=mKeys;
  final Key invalidKey=mInvalidatedKey;
  boolean drawSingleKey=false;
  if (invalidKey != null && canvas.getClipBounds(clipRegion)) {
    if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left && invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top && invalidKey.x + invalidKey.width + kbdPaddingLeft+ 1 >= clipRegion.right && invalidKey.y + invalidKey.height + kbdPaddingTop+ 1 >= clipRegion.bottom) {
      drawSingleKey=true;
    }
  }
  for (  Key keyBase : keys) {
    final AnyKey key=(AnyKey)keyBase;
    final boolean keyIsSpace=isSpaceKey(key);
    if (drawSingleKey && (invalidKey != key)) {
      continue;
    }
    if (!mDirtyRect.intersects(key.x + kbdPaddingLeft,key.y + kbdPaddingTop,key.x + key.width + kbdPaddingLeft,key.y + key.height + kbdPaddingTop)) {
      continue;
    }
    int[] drawableState=key.getCurrentDrawableState(mDrawableStatesProvider);
    if (keyIsSpace)     paint.setColor(mKeyboardNameTextColor.getColorForState(drawableState,0xFF000000));
 else     paint.setColor(keyTextColor.getColorForState(drawableState,0xFF000000));
    keyBackground.setState(drawableState);
    CharSequence label=key.label == null ? null : adjustCase(key).toString();
    final Rect bounds=keyBackground.getBounds();
    if ((key.width != bounds.right) || (key.height != bounds.bottom)) {
      keyBackground.setBounds(0,0,key.width,key.height);
    }
    canvas.translate(key.x + kbdPaddingLeft,key.y + kbdPaddingTop);
    keyBackground.draw(canvas);
    if (TextUtils.isEmpty(label)) {
      Drawable iconToDraw=getIconToDrawForKey(key,false);
      if (iconToDraw != null) {
        final boolean is9Patch=iconToDraw.getCurrent() instanceof NinePatchDrawable;
        final int drawableWidth;
        final int drawableHeight;
        final int drawableX;
        final int drawableY;
        drawableWidth=is9Patch ? key.width : iconToDraw.getIntrinsicWidth();
        drawableHeight=is9Patch ? key.height : iconToDraw.getIntrinsicHeight();
        drawableX=(key.width + mKeyBackgroundPadding.left - mKeyBackgroundPadding.right - drawableWidth) / 2;
        drawableY=(key.height + mKeyBackgroundPadding.top - mKeyBackgroundPadding.bottom - drawableHeight) / 2;
        canvas.translate(drawableX,drawableY);
        iconToDraw.setBounds(0,0,drawableWidth,drawableHeight);
        iconToDraw.draw(canvas);
        canvas.translate(-drawableX,-drawableY);
        if (keyIsSpace && drawKeyboardNameText) {
          label=mKeyboardName;
        }
      }
 else {
        label=guessLabelForKey(key.codes[0]);
        if (TextUtils.isEmpty(label)) {
          Log.w(TAG,"String_Node_Str" + key.codes[0] + "String_Node_Str"+ key.x+ "String_Node_Str"+ key.y+ "String_Node_Str"+ mKeyboardActionType);
        }
      }
    }
    if (label != null) {
      final FontMetrics fm;
      if (keyIsSpace) {
        paint.setTextSize(mKeyboardNameTextSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD);
        if (mKeyboardNameFM == null)         mKeyboardNameFM=paint.getFontMetrics();
        fm=mKeyboardNameFM;
      }
 else       if (label.length() > 1 && key.codes.length < 2) {
        setPaintForLabelText(paint);
        if (mLabelFM == null)         mLabelFM=paint.getFontMetrics();
        fm=mLabelFM;
      }
 else {
        setPaintToKeyText(paint);
        if (mTextFM == null)         mTextFM=paint.getFontMetrics();
        fm=mTextFM;
      }
      final float labelHeight=-fm.top;
      paint.setShadowLayer(mShadowRadius,mShadowOffsetX,mShadowOffsetY,mShadowColor);
      float textWidth=paint.measureText(label,0,label.length());
      if (textWidth > key.width) {
        Log.d(TAG,"String_Node_Str" + label + "String_Node_Str");
        paint.setTextSize(mKeyTextSize / 1.5f);
        textWidth=paint.measureText(label,0,label.length());
        if (textWidth > key.width) {
          Log.d(TAG,"String_Node_Str" + label + "String_Node_Str");
          paint.setTextSize(mKeyTextSize / 2.5f);
          textWidth=paint.measureText(label,0,label.length());
          if (textWidth > key.width) {
            Log.d(TAG,"String_Node_Str" + label + "String_Node_Str");
            paint.setTextSize(0f);
            textWidth=paint.measureText(label,0,label.length());
          }
        }
      }
      final float centerY=mKeyBackgroundPadding.top + ((key.height - mKeyBackgroundPadding.top - mKeyBackgroundPadding.bottom) / (keyIsSpace ? 3 : 2));
      final float textX=mKeyBackgroundPadding.left + (key.width - mKeyBackgroundPadding.left - mKeyBackgroundPadding.right) / 2;
      final float textY;
      if (label.length() > 1 && !AnyApplication.getConfig().workaround_alwaysUseDrawText()) {
        textY=centerY - ((labelHeight - paint.descent()) / 2);
        canvas.translate(textX,textY);
        Log.d(TAG,"String_Node_Str" + label + "String_Node_Str");
        StaticLayout labelText=new StaticLayout(label,new TextPaint(paint),(int)textWidth,Alignment.ALIGN_NORMAL,1.0f,0.0f,false);
        labelText.draw(canvas);
      }
 else {
        textY=centerY + ((labelHeight - paint.descent()) / 2);
        canvas.translate(textX,textY);
        canvas.drawText(label,0,label.length(),0,0,paint);
      }
      canvas.translate(-textX,-textY);
      paint.setShadowLayer(0,0,0,0);
    }
    if (drawHintText) {
      if ((key.popupCharacters != null && key.popupCharacters.length() > 0) || (key.popupResId != 0) || (key.longPressCode != 0)) {
        Align oldAlign=paint.getTextAlign();
        String hintText=null;
        if (key.hintLabel != null && key.hintLabel.length() > 0) {
          hintText=key.hintLabel.toString();
        }
 else         if (key.longPressCode != 0) {
          if (Character.isLetterOrDigit(key.longPressCode))           hintText=Character.toString((char)key.longPressCode);
        }
 else         if (key.popupCharacters != null) {
          final String hintString=key.popupCharacters.toString();
          final int hintLength=hintString.length();
          if (hintLength <= 3)           hintText=hintString;
        }
        if (hintText == null) {
          if (mHintOverflowLabel != null)           hintText=mHintOverflowLabel;
 else {
            if (hintVAlign == Gravity.TOP)             hintText="String_Node_Str";
 else             hintText="String_Node_Str";
          }
        }
        if (mKeyboard.isShifted())         hintText=hintText.toUpperCase(getKeyboard().getLocale());
        paint.setTypeface(Typeface.DEFAULT);
        paint.setColor(hintColor.getColorForState(drawableState,0xFF000000));
        paint.setTextSize(mHintTextSize);
        if (mHintTextFM == null) {
          mHintTextFM=paint.getFontMetrics();
        }
        final float hintX;
        final float hintY;
        if (hintAlign == Gravity.START) {
          paint.setTextAlign(Align.LEFT);
          hintX=mKeyBackgroundPadding.left + (float)0.5;
        }
 else         if (hintAlign == Gravity.CENTER) {
          paint.setTextAlign(Align.CENTER);
          hintX=mKeyBackgroundPadding.left + (key.width - mKeyBackgroundPadding.left - mKeyBackgroundPadding.right) / 2;
        }
 else {
          paint.setTextAlign(Align.RIGHT);
          hintX=key.width - mKeyBackgroundPadding.right - (float)0.5;
        }
        if (hintVAlign == Gravity.TOP) {
          hintY=mKeyBackgroundPadding.top - mHintTextFM.top + (float)0.5;
        }
 else {
          hintY=key.height - mKeyBackgroundPadding.bottom - mHintTextFM.bottom- (float)0.5;
        }
        canvas.drawText(hintText,hintX,hintY,paint);
        paint.setTextAlign(oldAlign);
      }
    }
    canvas.translate(-key.x - kbdPaddingLeft,-key.y - kbdPaddingTop);
  }
  mInvalidatedKey=null;
  if (mMiniKeyboardPopup.isShowing()) {
    paint.setColor((int)(mBackgroundDimAmount * 0xFF) << 24);
    canvas.drawRect(0,0,getWidth(),getHeight(),paint);
  }
  mDrawPending=false;
  mDirtyRect.setEmpty();
}