title: How to draw a Spanned String with Canvas.drawText in Android
body: <p>I want to draw a <code>SpannedString</code> to a <code>Canvas</code>.</p>
  
  <p><a href="https://i.stack.imgur.com/TDlwU.png" rel="noreferrer"><img src="https://i.stack.imgur.com/TDlwU.png" alt="enter image description here"></a></p>
  
  <pre><code>SpannableString spannableString = new SpannableString("Hello World!");
  ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
  BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
  spannableString.setSpan(foregroundSpan, 1, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  spannableString.setSpan(backgroundSpan, 3, spannableString.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  textView.setText(spannableString);
  </code></pre>
  
  <p>The above example was drawn using a <code>TextView</code>, which in turn uses a <code>Layout</code> to draw text with spans. I know that <a href="https://stackoverflow.com/a/41870464/3681880">using a <code>Layout</code> is the recommended way</a> to draw text to the canvas. However, I am making my own text layout from scratch, so I need to implement this myself.</p>
  
  <p>Doing something like this doesn't work</p>
  
  <pre><code>canvas.drawText(spannableString, 0, spannableString.length(), 0, 0, mTextPaint);
  </code></pre>
  
  <p>because <code>drawText</code> only gets the text from the <code>spannableString</code>, not any of the spans. The drawing colors are handled separately by <code>TextPaint</code>.</p>
  
  <p>How do I use <code>canvas.drawText</code> (or <code>drawTextRun</code>) to draw the span information (specifically foreground and background color here)?</p>
  
  <p><strong>Related</strong></p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/43270575/how-to-loop-through-the-spans-in-a-spannedstring-or-spannablestring-in-android">How to loop through the spans in a SpannedString or SpannableString in Android</a></li>
  <li><a href="https://stackoverflow.com/questions/10410515/is-it-possible-to-display-multi-color-text-with-one-call-to-canvas-drawtext">Is it possible to display multi-color text with one call to Canvas.drawText()?</a></li>
  </ul>
  
  <p><strong>Plan for a solution</strong></p>
  
  <p><em>I was going to directly do a self answer but this is turning out to be more difficult than I thought. So I will post first and then add an answer whenever I can figure it out. (I would of course welcome anyone to answer first.)</em> </p>
  
  <p>Here are the pieces that I have so far:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/a/43270576/3681880">Draw each span range as a separate text run</a> </li>
  <li>Use <a href="https://developer.android.com/reference/android/graphics/Canvas.html#drawTextRun(java.lang.CharSequence,%20int,%20int,%20int,%20int,%20float,%20float,%20boolean,%20android.graphics.Paint)" rel="noreferrer"><code>drawTextRun</code></a> to draw the text (<a href="http://www.programcreek.com/java-api-examples/index.php?class=android.graphics.Canvas&amp;method=drawTextRun" rel="noreferrer">examples</a>) (<strong>update</strong>: not added until API 23)</li>
  <li>Use <a href="https://developer.android.com/reference/android/graphics/Paint.html#getRunAdvance(char[],%20int,%20int,%20int,%20int,%20boolean,%20int)" rel="noreferrer"><code>getRunAdvance</code></a> to measure where to start the next text run  (<strong>update</strong>: not added until API 23, use <code>measureText</code> instead)</li>
  <li>The background color will probably need to be drawn separately (with <code>drawRect</code> or maybe <code>drawPath</code>? See <a href="https://azzits.wordpress.com/tag/android-drawtext-with-background-color/" rel="noreferrer">here</a>, <a href="https://stackoverflow.com/questions/8242439/how-to-draw-text-with-background-color-using-canvas">here</a>, and <a href="https://stackoverflow.com/questions/31877417/android-draw-text-with-solid-background-onto-canvas-to-be-used-as-a-bitmap">here</a>.)</li>
  <li>Source code for <a href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/TextView.java" rel="noreferrer"><code>TextView</code></a>, <a href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/text/StaticLayout.java" rel="noreferrer"><code>StaticLayout</code></a>, and <a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/text/TextLine.java" rel="noreferrer"><code>TextLine</code></a></li>
  </ul>