Buggy code:
int [ ] lineWidth ; static class StyleItem { TextStyle style ; int start ; int length ; int width ; int ascent ; int descent ; boolean lineBreak ; boolean softBreak ; boolean tab ; } public TextLayout ( Device device ) { } void checkLayout ( ) { } void computeRuns ( GC gc ) { } public void dispose ( ) { } public void draw ( GC gc , int x , int y ) { } public void draw ( GC gc , int x , int y , int selectionStart , int selectionEnd , Color selectionForeground , Color selectionBackground ) { } void freeRuns ( ) { } public int getAlignment ( ) { } public int getAscent ( ) { } public Rectangle getBounds ( ) { } public Rectangle getBounds ( int start , int end ) { } public int getDescent ( ) { } public Font getFont ( ) { } public int getLevel ( int offset ) { } public int [ ] getLineOffsets ( ) { } public Rectangle getLineBounds ( int lineIndex ) { } public int getLineCount ( ) { } public int getLineIndex ( int offset ) { } public FontMetrics getLineMetrics ( int lineIndex ) { } public Point getLocation ( int offset , boolean trailing ) { } Font getItemFont ( TextLayout . StyleItem item ) { } public int getNextOffset ( int offset , int movement ) { } public int getOffset ( Point point , int [ ] trailing ) { } public int getOffset ( int x , int y , int [ ] trailing ) { checkLayout ( ) ; if ( ( trailing != null ) && ( ( trailing . length ) < 1 ) ) SWT . error ( ERROR_INVALID_ARGUMENT ) ; computeRuns ( null ) ; int line ; int lineCount = runs . length ; for ( line = 0 ; line < lineCount ; line ++ ) { if ( ( lineY [ ( line + 1 ) ] ) > y ) break ; } line = Math . min ( line , ( ( runs . length ) - 1 ) ) ; if ( ( wrapWidth ) != ( - 1 ) ) { switch ( alignment ) { case SWT . CENTER : x -= ( ( wrapWidth ) - ( lineWidth [ line ] ) ) // 2 ; break ; case SWT . RIGHT : x -= ( wrapWidth ) - ( lineWidth [ line ] ) ; break ; } } if ( x >= ( lineWidth [ line ] ) ) x = ( lineWidth [ line ] ) - 1 ; if ( x < 0 ) x = 0 ; TextLayout . StyleItem [ ] lineRuns = runs [ line ] ; int width = 0 ; for ( int i = 0 ; i < ( lineRuns . length ) ; i ++ ) { TextLayout . StyleItem run = lineRuns [ i ] ; if ( ( run . lineBreak ) && ( ! ( run . softBreak ) ) ) return run . start ; if ( ( width + ( run . width ) ) > x ) { if ( run . tab ) { if ( trailing != null ) { trailing [ 0 ] = ( x < ( width + ( ( run . width ) // 2 ) ) ) ? 0 : 1 ; } return run . start ; } int offset = 0 ; GC gc = new GC ( device ) ; gc . setFont ( getItemFont ( run ) ) ; char [ ] chars = new char [ run . length ] ; text . getChars ( run . start , ( ( run . start ) + ( run . length ) ) , chars , 0 ) ; for ( offset = 0 ; offset < ( chars . length ) ; offset ++ ) { <START_BUG> int charWidth = gc . stringExtent ( String . valueOf ( chars [ 0 ] ) ) . x ; <END_BUG> if ( ( width + charWidth ) > x ) { if ( trailing != null ) { trailing [ 0 ] = ( x < ( width + ( charWidth // 2 ) ) ) ? 0 : 1 ; } break ; } width += charWidth ; } gc . dispose ( ) ; return ( run . start ) + offset ; } width += run . width ; } if ( trailing != null ) trailing [ 0 ] = 0 ; return lineOffset [ ( line + 1 ) ] ; } public int getOrientation ( ) { } public int getPreviousOffset ( int offset , int movement ) { } public int getSpacing ( ) { } public int [ ] getSegments ( ) { } public TextStyle getStyle ( int offset ) { } public int [ ] getTabs ( ) { } public String getText ( ) { } public int getWidth ( ) { } public boolean isDisposed ( ) { } TextLayout . StyleItem [ ] itemize ( ) { } TextLayout . StyleItem [ ] merge ( TextLayout . StyleItem [ ] items , int itemCount ) { } void place ( GC gc , TextLayout . StyleItem run ) { } public void setAlignment ( int alignment ) { } public void setAscent ( int ascent ) { } public void setDescent ( int descent ) { } public void setFont ( Font font ) { } public void setOrientation ( int orientation ) { } public void setSpacing ( int spacing ) { } public void setSegments ( int [ ] segments ) { } public void setStyle ( TextStyle style , int start , int end ) { }

Fix:
int charWidth = gc . stringExtent ( String . valueOf ( chars [ offset ] ) ) . x ;