APIs do Brush

As APIs Ink Brush oferecem uma maneira de criar e personalizar pincéis para desenhar em uma tela.

Criar um pincel

Para criar um pincel, use os métodos de fábrica Brush com argumentos nomeados, como Brush.createWithColorLong(). Essa classe permite definir as seguintes propriedades:

  • family: o estilo do pincel, análogo a um tipo ou fonte em texto. Consulte StockBrushes para conferir os valores de BrushFamily disponíveis.
  • color: a cor do pincel. É possível definir a cor usando um ColorLong.
  • size: a espessura básica dos traços criados com o pincel.
  • epsilon: a menor distância em que dois pontos no traço precisam ser considerados distintos, o que controla o nível de detalhe ou fidelidade da geometria do traço.
    • Valores mais altos simplificam mais o traço, o que usa menos memória e renderiza mais rápido, mas pode resultar em artefatos visíveis, como bordas irregulares, quando há zoom.
    • Valores mais baixos preservam mais detalhes para zoom de alta qualidade, mas aumentam o uso da memória.
    • Para prototipagem com uma escala de unidade de 1 px, 0,1 é um bom ponto de partida. Para apps de produção que oferecem suporte a várias densidades de tela, use unidades independentes de densidade (como dp) e ajuste o epsilon de acordo.
val redBrush = Brush.createWithColorLong(
  family = StockBrushes.pressurePen(),
  colorLong = Color.RED.pack(),
  size = 5F,
  epsilon = 0.1F
)

Modificar propriedades do pincel

É possível criar uma cópia de um pincel usando o método copy(). Esse método permite mudar qualquer uma das propriedades do pincel.

val blueBrush = redBrush.copy(colorLong = Color.BLUE.pack())

Pincéis personalizados

Embora StockBrushes ofereça um conjunto versátil de pincéis comuns, a API Ink também oferece um caminho avançado para criar comportamentos de pincel totalmente novos para efeitos artísticos exclusivos ou para replicar pincéis específicos existentes para compatibilidade com versões anteriores.

Um BrushFamily personalizado é carregado do formato serializado. O formato obrigatório é a codificação binária compactada com gzip do buffer de protocolo BrushFamily. Isso permite carregar e usar arquivos de pincel personalizados hoje mesmo. Depois de desserializado, o BrushFamily personalizado pode ser usado para criar um novo Brush com uma cor e um tamanho específicos, assim como qualquer uma das famílias StockBrushes.

class CustomBrushes(val context: Context) {

  private const val TAG = "CustomBrushes"

  val brushes by lazy { loadCustomBrushes(context) }

  @OptIn(ExperimentalInkCustomBrushApi::class)
  private fun loadCustomBrushes(): List<CustomBrush> {
    val brushFiles = mapOf(
        "Calligraphy" to (R.raw.calligraphy to R.drawable.draw_24px),
        "Flag Banner" to (R.raw.flag_banner to R.drawable.flag_24px),
        "Graffiti" to (R.raw.graffiti to R.drawable.format_paint_24px),
    // ...
    )

    val loadedBrushes = brushFiles.mapNotNull { (name, pair) ->
      val (resourceId, icon) = pair
      val brushFamily = context.resources.openRawResource(resourceId).use
      { inputStream ->
          BrushFamily.decode(inputStream)
      }
      CustomBrush(name, icon, brushFamily.copy(clientBrushFamilyId = name))     
    }
    return loadedBrushes
  }
}

data class CustomBrush(
  val name: String,
  val icon: Int,
  val brushFamily: BrushFamily
)