Program: 193470
Project: 193470
Buggy source:
void generate(Builder b,boolean includepad,boolean trackpad){
  CharSequence source=b.mText;
  int bufStart=b.mStart;
  int bufEnd=b.mEnd;
  TextPaint paint=b.mPaint;
  int outerWidth=b.mWidth;
  TextDirectionHeuristic textDir=b.mTextDir;
  float spacingmult=b.mSpacingMult;
  float spacingadd=b.mSpacingAdd;
  float ellipsizedWidth=b.mEllipsizedWidth;
  TextUtils.TruncateAt ellipsize=b.mEllipsize;
  LineBreaks lineBreaks=new LineBreaks();
  int[] spanEndCache=new int[4];
  int[] fmCache=new int[4 * 4];
  b.setLocale(paint.getTextLocale());
  mLineCount=0;
  int v=0;
  boolean needMultiply=(spacingmult != 1 || spacingadd != 0);
  Paint.FontMetricsInt fm=b.mFontMetricsInt;
  int[] chooseHtv=null;
  MeasuredText measured=b.mMeasuredText;
  Spanned spanned=null;
  if (source instanceof Spanned)   spanned=(Spanned)source;
  int paraEnd;
  for (int paraStart=bufStart; paraStart <= bufEnd; paraStart=paraEnd) {
    paraEnd=TextUtils.indexOf(source,CHAR_NEW_LINE,paraStart,bufEnd);
    if (paraEnd < 0)     paraEnd=bufEnd;
 else     paraEnd++;
    int firstWidthLineCount=1;
    int firstWidth=outerWidth;
    int restWidth=outerWidth;
    LineHeightSpan[] chooseHt=null;
    if (spanned != null) {
      LeadingMarginSpan[] sp=getParagraphSpans(spanned,paraStart,paraEnd,LeadingMarginSpan.class);
      for (int i=0; i < sp.length; i++) {
        LeadingMarginSpan lms=sp[i];
        firstWidth-=sp[i].getLeadingMargin(true);
        restWidth-=sp[i].getLeadingMargin(false);
        if (lms instanceof LeadingMarginSpan2) {
          LeadingMarginSpan2 lms2=(LeadingMarginSpan2)lms;
          firstWidthLineCount=Math.max(firstWidthLineCount,lms2.getLeadingMarginLineCount());
        }
      }
      chooseHt=getParagraphSpans(spanned,paraStart,paraEnd,LineHeightSpan.class);
      if (chooseHt.length != 0) {
        if (chooseHtv == null || chooseHtv.length < chooseHt.length) {
          chooseHtv=ArrayUtils.newUnpaddedIntArray(chooseHt.length);
        }
        for (int i=0; i < chooseHt.length; i++) {
          int o=spanned.getSpanStart(chooseHt[i]);
          if (o < paraStart) {
            chooseHtv[i]=getLineTop(getLineForOffset(o));
          }
 else {
            chooseHtv[i]=v;
          }
        }
      }
    }
    measured.setPara(source,paraStart,paraEnd,textDir,b);
    char[] chs=measured.mChars;
    float[] widths=measured.mWidths;
    byte[] chdirs=measured.mLevels;
    int dir=measured.mDir;
    boolean easy=measured.mEasy;
    int[] variableTabStops=null;
    if (spanned != null) {
      TabStopSpan[] spans=getParagraphSpans(spanned,paraStart,paraEnd,TabStopSpan.class);
      if (spans.length > 0) {
        int[] stops=new int[spans.length];
        for (int i=0; i < spans.length; i++) {
          stops[i]=spans[i].getTabStop();
        }
        Arrays.sort(stops,0,stops.length);
        variableTabStops=stops;
      }
    }
    nSetupParagraph(b.mNativePtr,chs,paraEnd - paraStart,firstWidth,firstWidthLineCount,restWidth,variableTabStops,TAB_INCREMENT,b.mBreakStrategy,b.mHyphenationFrequency);
    if (mLeftIndents != null || mRightIndents != null) {
      int leftLen=mLeftIndents == null ? 0 : mLeftIndents.length;
      int rightLen=mRightIndents == null ? 0 : mRightIndents.length;
      int indentsLen=Math.max(1,Math.min(leftLen,rightLen) - mLineCount);
      int[] indents=new int[indentsLen];
      for (int i=0; i < indentsLen; i++) {
        int leftMargin=mLeftIndents == null ? 0 : mLeftIndents[Math.min(i + mLineCount,leftLen - 1)];
        int rightMargin=mRightIndents == null ? 0 : mRightIndents[Math.min(i + mLineCount,rightLen - 1)];
        indents[i]=leftMargin + rightMargin;
      }
      nSetIndents(b.mNativePtr,indents);
    }
    int fmCacheCount=0;
    int spanEndCacheCount=0;
    for (int spanStart=paraStart, spanEnd; spanStart < paraEnd; spanStart=spanEnd) {
      if (fmCacheCount * 4 >= fmCache.length) {
        int[] grow=new int[fmCacheCount * 4 * 2];
        System.arraycopy(fmCache,0,grow,0,fmCacheCount * 4);
        fmCache=grow;
      }
      if (spanEndCacheCount >= spanEndCache.length) {
        int[] grow=new int[spanEndCacheCount * 2];
        System.arraycopy(spanEndCache,0,grow,0,spanEndCacheCount);
        spanEndCache=grow;
      }
      if (spanned == null) {
        spanEnd=paraEnd;
        int spanLen=spanEnd - spanStart;
        measured.addStyleRun(paint,spanLen,fm);
      }
 else {
        spanEnd=spanned.nextSpanTransition(spanStart,paraEnd,MetricAffectingSpan.class);
        int spanLen=spanEnd - spanStart;
        MetricAffectingSpan[] spans=spanned.getSpans(spanStart,spanEnd,MetricAffectingSpan.class);
        spans=TextUtils.removeEmptySpans(spans,spanned,MetricAffectingSpan.class);
        measured.addStyleRun(paint,spans,spanLen,fm);
      }
      fmCache[fmCacheCount * 4 + 0]=fm.top;
      fmCache[fmCacheCount * 4 + 1]=fm.bottom;
      fmCache[fmCacheCount * 4 + 2]=fm.ascent;
      fmCache[fmCacheCount * 4 + 3]=fm.descent;
      fmCacheCount++;
      spanEndCache[spanEndCacheCount]=spanEnd;
      spanEndCacheCount++;
    }
    nGetWidths(b.mNativePtr,widths);
    int breakCount=nComputeLineBreaks(b.mNativePtr,lineBreaks,lineBreaks.breaks,lineBreaks.widths,lineBreaks.flags,lineBreaks.breaks.length);
    int[] breaks=lineBreaks.breaks;
    float[] lineWidths=lineBreaks.widths;
    int[] flags=lineBreaks.flags;
    final int remainingLineCount=mMaximumVisibleLineCount - mLineCount;
    final boolean ellipsisMayBeApplied=ellipsize != null && (ellipsize == TextUtils.TruncateAt.END || (mMaximumVisibleLineCount == 1 && ellipsize != TextUtils.TruncateAt.MARQUEE));
    if (remainingLineCount > 0 && remainingLineCount < breakCount && ellipsisMayBeApplied) {
      breaks[remainingLineCount - 1]=breaks[breakCount - 1];
      float width=0;
      int flag=0;
      for (int i=remainingLineCount - 1; i < breakCount; i++) {
        width+=lineWidths[i];
        flag|=flags[i] & TAB_MASK;
      }
      lineWidths[remainingLineCount - 1]=width;
      flags[remainingLineCount - 1]=flag;
      breakCount=remainingLineCount;
    }
    int here=paraStart;
    int fmTop=0, fmBottom=0, fmAscent=0, fmDescent=0;
    int fmCacheIndex=0;
    int spanEndCacheIndex=0;
    int breakIndex=0;
    for (int spanStart=paraStart, spanEnd; spanStart < paraEnd; spanStart=spanEnd) {
      spanEnd=spanEndCache[spanEndCacheIndex++];
      fm.top=fmCache[fmCacheIndex * 4 + 0];
      fm.bottom=fmCache[fmCacheIndex * 4 + 1];
      fm.ascent=fmCache[fmCacheIndex * 4 + 2];
      fm.descent=fmCache[fmCacheIndex * 4 + 3];
      fmCacheIndex++;
      if (fm.top < fmTop) {
        fmTop=fm.top;
      }
      if (fm.ascent < fmAscent) {
        fmAscent=fm.ascent;
      }
      if (fm.descent > fmDescent) {
        fmDescent=fm.descent;
      }
      if (fm.bottom > fmBottom) {
        fmBottom=fm.bottom;
      }
      while (breakIndex < breakCount && paraStart + breaks[breakIndex] < spanStart) {
        breakIndex++;
      }
      while (breakIndex < breakCount && paraStart + breaks[breakIndex] <= spanEnd) {
        int endPos=paraStart + breaks[breakIndex];
        boolean moreChars=(endPos < bufEnd);
        v=out(source,here,endPos,fmAscent,fmDescent,fmTop,fmBottom,v,spacingmult,spacingadd,chooseHt,chooseHtv,fm,flags[breakIndex],needMultiply,chdirs,dir,easy,bufEnd,includepad,trackpad,chs,widths,paraStart,ellipsize,ellipsizedWidth,lineWidths[breakIndex],paint,moreChars);
        if (endPos < spanEnd) {
          fmTop=fm.top;
          fmBottom=fm.bottom;
          fmAscent=fm.ascent;
          fmDescent=fm.descent;
        }
 else {
          fmTop=fmBottom=fmAscent=fmDescent=0;
        }
        here=endPos;
        breakIndex++;
        if (mLineCount >= mMaximumVisibleLineCount) {
          return;
        }
      }
    }
    if (paraEnd == bufEnd)     break;
  }
  if ((bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) && mLineCount < mMaximumVisibleLineCount) {
    measured.setPara(source,bufEnd,bufEnd,textDir,b);
    paint.getFontMetricsInt(fm);
    v=out(source,bufEnd,bufEnd,fm.ascent,fm.descent,fm.top,fm.bottom,v,spacingmult,spacingadd,null,null,fm,0,needMultiply,measured.mLevels,measured.mDir,measured.mEasy,bufEnd,includepad,trackpad,null,null,bufStart,ellipsize,ellipsizedWidth,0,paint,false);
  }
}

Fixed version (ground truth):
void generate(Builder b,boolean includepad,boolean trackpad){
  CharSequence source=b.mText;
  int bufStart=b.mStart;
  int bufEnd=b.mEnd;
  TextPaint paint=b.mPaint;
  int outerWidth=b.mWidth;
  TextDirectionHeuristic textDir=b.mTextDir;
  float spacingmult=b.mSpacingMult;
  float spacingadd=b.mSpacingAdd;
  float ellipsizedWidth=b.mEllipsizedWidth;
  TextUtils.TruncateAt ellipsize=b.mEllipsize;
  LineBreaks lineBreaks=new LineBreaks();
  int[] spanEndCache=new int[4];
  int[] fmCache=new int[4 * 4];
  b.setLocale(paint.getTextLocale());
  mLineCount=0;
  int v=0;
  boolean needMultiply=(spacingmult != 1 || spacingadd != 0);
  Paint.FontMetricsInt fm=b.mFontMetricsInt;
  int[] chooseHtv=null;
  MeasuredText measured=b.mMeasuredText;
  Spanned spanned=null;
  if (source instanceof Spanned)   spanned=(Spanned)source;
  int paraEnd;
  for (int paraStart=bufStart; paraStart <= bufEnd; paraStart=paraEnd) {
    paraEnd=TextUtils.indexOf(source,CHAR_NEW_LINE,paraStart,bufEnd);
    if (paraEnd < 0)     paraEnd=bufEnd;
 else     paraEnd++;
    int firstWidthLineCount=1;
    int firstWidth=outerWidth;
    int restWidth=outerWidth;
    LineHeightSpan[] chooseHt=null;
    if (spanned != null) {
      LeadingMarginSpan[] sp=getParagraphSpans(spanned,paraStart,paraEnd,LeadingMarginSpan.class);
      for (int i=0; i < sp.length; i++) {
        LeadingMarginSpan lms=sp[i];
        firstWidth-=sp[i].getLeadingMargin(true);
        restWidth-=sp[i].getLeadingMargin(false);
        if (lms instanceof LeadingMarginSpan2) {
          LeadingMarginSpan2 lms2=(LeadingMarginSpan2)lms;
          firstWidthLineCount=Math.max(firstWidthLineCount,lms2.getLeadingMarginLineCount());
        }
      }
      chooseHt=getParagraphSpans(spanned,paraStart,paraEnd,LineHeightSpan.class);
      if (chooseHt.length == 0) {
        chooseHt=null;
      }
 else {
        if (chooseHtv == null || chooseHtv.length < chooseHt.length) {
          chooseHtv=ArrayUtils.newUnpaddedIntArray(chooseHt.length);
        }
        for (int i=0; i < chooseHt.length; i++) {
          int o=spanned.getSpanStart(chooseHt[i]);
          if (o < paraStart) {
            chooseHtv[i]=getLineTop(getLineForOffset(o));
          }
 else {
            chooseHtv[i]=v;
          }
        }
      }
    }
    measured.setPara(source,paraStart,paraEnd,textDir,b);
    char[] chs=measured.mChars;
    float[] widths=measured.mWidths;
    byte[] chdirs=measured.mLevels;
    int dir=measured.mDir;
    boolean easy=measured.mEasy;
    int[] variableTabStops=null;
    if (spanned != null) {
      TabStopSpan[] spans=getParagraphSpans(spanned,paraStart,paraEnd,TabStopSpan.class);
      if (spans.length > 0) {
        int[] stops=new int[spans.length];
        for (int i=0; i < spans.length; i++) {
          stops[i]=spans[i].getTabStop();
        }
        Arrays.sort(stops,0,stops.length);
        variableTabStops=stops;
      }
    }
    nSetupParagraph(b.mNativePtr,chs,paraEnd - paraStart,firstWidth,firstWidthLineCount,restWidth,variableTabStops,TAB_INCREMENT,b.mBreakStrategy,b.mHyphenationFrequency);
    if (mLeftIndents != null || mRightIndents != null) {
      int leftLen=mLeftIndents == null ? 0 : mLeftIndents.length;
      int rightLen=mRightIndents == null ? 0 : mRightIndents.length;
      int indentsLen=Math.max(1,Math.min(leftLen,rightLen) - mLineCount);
      int[] indents=new int[indentsLen];
      for (int i=0; i < indentsLen; i++) {
        int leftMargin=mLeftIndents == null ? 0 : mLeftIndents[Math.min(i + mLineCount,leftLen - 1)];
        int rightMargin=mRightIndents == null ? 0 : mRightIndents[Math.min(i + mLineCount,rightLen - 1)];
        indents[i]=leftMargin + rightMargin;
      }
      nSetIndents(b.mNativePtr,indents);
    }
    int fmCacheCount=0;
    int spanEndCacheCount=0;
    for (int spanStart=paraStart, spanEnd; spanStart < paraEnd; spanStart=spanEnd) {
      if (fmCacheCount * 4 >= fmCache.length) {
        int[] grow=new int[fmCacheCount * 4 * 2];
        System.arraycopy(fmCache,0,grow,0,fmCacheCount * 4);
        fmCache=grow;
      }
      if (spanEndCacheCount >= spanEndCache.length) {
        int[] grow=new int[spanEndCacheCount * 2];
        System.arraycopy(spanEndCache,0,grow,0,spanEndCacheCount);
        spanEndCache=grow;
      }
      if (spanned == null) {
        spanEnd=paraEnd;
        int spanLen=spanEnd - spanStart;
        measured.addStyleRun(paint,spanLen,fm);
      }
 else {
        spanEnd=spanned.nextSpanTransition(spanStart,paraEnd,MetricAffectingSpan.class);
        int spanLen=spanEnd - spanStart;
        MetricAffectingSpan[] spans=spanned.getSpans(spanStart,spanEnd,MetricAffectingSpan.class);
        spans=TextUtils.removeEmptySpans(spans,spanned,MetricAffectingSpan.class);
        measured.addStyleRun(paint,spans,spanLen,fm);
      }
      fmCache[fmCacheCount * 4 + 0]=fm.top;
      fmCache[fmCacheCount * 4 + 1]=fm.bottom;
      fmCache[fmCacheCount * 4 + 2]=fm.ascent;
      fmCache[fmCacheCount * 4 + 3]=fm.descent;
      fmCacheCount++;
      spanEndCache[spanEndCacheCount]=spanEnd;
      spanEndCacheCount++;
    }
    nGetWidths(b.mNativePtr,widths);
    int breakCount=nComputeLineBreaks(b.mNativePtr,lineBreaks,lineBreaks.breaks,lineBreaks.widths,lineBreaks.flags,lineBreaks.breaks.length);
    int[] breaks=lineBreaks.breaks;
    float[] lineWidths=lineBreaks.widths;
    int[] flags=lineBreaks.flags;
    final int remainingLineCount=mMaximumVisibleLineCount - mLineCount;
    final boolean ellipsisMayBeApplied=ellipsize != null && (ellipsize == TextUtils.TruncateAt.END || (mMaximumVisibleLineCount == 1 && ellipsize != TextUtils.TruncateAt.MARQUEE));
    if (remainingLineCount > 0 && remainingLineCount < breakCount && ellipsisMayBeApplied) {
      breaks[remainingLineCount - 1]=breaks[breakCount - 1];
      float width=0;
      int flag=0;
      for (int i=remainingLineCount - 1; i < breakCount; i++) {
        width+=lineWidths[i];
        flag|=flags[i] & TAB_MASK;
      }
      lineWidths[remainingLineCount - 1]=width;
      flags[remainingLineCount - 1]=flag;
      breakCount=remainingLineCount;
    }
    int here=paraStart;
    int fmTop=0, fmBottom=0, fmAscent=0, fmDescent=0;
    int fmCacheIndex=0;
    int spanEndCacheIndex=0;
    int breakIndex=0;
    for (int spanStart=paraStart, spanEnd; spanStart < paraEnd; spanStart=spanEnd) {
      spanEnd=spanEndCache[spanEndCacheIndex++];
      fm.top=fmCache[fmCacheIndex * 4 + 0];
      fm.bottom=fmCache[fmCacheIndex * 4 + 1];
      fm.ascent=fmCache[fmCacheIndex * 4 + 2];
      fm.descent=fmCache[fmCacheIndex * 4 + 3];
      fmCacheIndex++;
      if (fm.top < fmTop) {
        fmTop=fm.top;
      }
      if (fm.ascent < fmAscent) {
        fmAscent=fm.ascent;
      }
      if (fm.descent > fmDescent) {
        fmDescent=fm.descent;
      }
      if (fm.bottom > fmBottom) {
        fmBottom=fm.bottom;
      }
      while (breakIndex < breakCount && paraStart + breaks[breakIndex] < spanStart) {
        breakIndex++;
      }
      while (breakIndex < breakCount && paraStart + breaks[breakIndex] <= spanEnd) {
        int endPos=paraStart + breaks[breakIndex];
        boolean moreChars=(endPos < bufEnd);
        v=out(source,here,endPos,fmAscent,fmDescent,fmTop,fmBottom,v,spacingmult,spacingadd,chooseHt,chooseHtv,fm,flags[breakIndex],needMultiply,chdirs,dir,easy,bufEnd,includepad,trackpad,chs,widths,paraStart,ellipsize,ellipsizedWidth,lineWidths[breakIndex],paint,moreChars);
        if (endPos < spanEnd) {
          fmTop=fm.top;
          fmBottom=fm.bottom;
          fmAscent=fm.ascent;
          fmDescent=fm.descent;
        }
 else {
          fmTop=fmBottom=fmAscent=fmDescent=0;
        }
        here=endPos;
        breakIndex++;
        if (mLineCount >= mMaximumVisibleLineCount) {
          return;
        }
      }
    }
    if (paraEnd == bufEnd)     break;
  }
  if ((bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) && mLineCount < mMaximumVisibleLineCount) {
    measured.setPara(source,bufEnd,bufEnd,textDir,b);
    paint.getFontMetricsInt(fm);
    v=out(source,bufEnd,bufEnd,fm.ascent,fm.descent,fm.top,fm.bottom,v,spacingmult,spacingadd,null,null,fm,0,needMultiply,measured.mLevels,measured.mDir,measured.mEasy,bufEnd,includepad,trackpad,null,null,bufStart,ellipsize,ellipsizedWidth,0,paint,false);
  }
}