Thread
#compose
    n

    nglauber

    2 years ago
    I’m applying the same shape for both background and border, but they’re looking incorrect on the corners. Is it a bug?
    val shape = RoundedCornerShape(8.dp)
        Column(modifier = Modifier.fillMaxSize()) {
            Text(
                text = "Text 1",
                modifier = Modifier.fillMaxWidth()
                    .padding(16.dp)
                    .drawShadow(2.dp, shape)
                    .drawBorder(2.dp, MaterialTheme.colors.secondary, shape)
                    .drawBackground(MaterialTheme.colors.primary, shape)
                    .padding(16.dp)
            )
        }
    l

    Leland Richardson [G]

    2 years ago
    Cc @Nader Jawad
    Nader Jawad

    Nader Jawad

    2 years ago
    The background is drawn as a fill, however, strokes are drawn centered on the shape they are defined in. That is the corner radius of 8.dp defined on the border is centered on the stroke width instead of on the outside corner. If you inset the shape of the background to account for the stroke width, the border should overlap the shape. This is consistent behavior with how Android draws these shapes as well, compose does not change this underlying behavior.
    n

    nglauber

    2 years ago
    yeah… if I do this
    .drawBorder(2.dp, MaterialTheme.colors.secondary, shape)
    .padding(1.dp) // FIX
    .drawBackground(MaterialTheme.colors.primary, shape)
    It works… But I don’t think this is an expected behavior… If I’m using the same shape with the same size, the last one should overlaps the previous one… 🤷‍♂️ (I don’t know how it works under the hood)
    Nader Jawad

    Nader Jawad

    2 years ago
    I think the border implementation attempts to account for the stroke width by insetting the contents of the border by half of the width. That gets it to draw within the same bounds as the round rect background but as the side effect of not matching the corner radius as the 2dp corner radius is drawn at the center of the stroke which is at a small rect. Cc @matvei maybe we can make some tweaks to border?
    Also regarding same shape size, a stroke is always drawn on the outer bounds of the shape that is being drawn so a stroked shape will be larger than the filled in one by half of its stroke width. The the border API leverages Paint.Style.STROKE behind the scenes, while the filled uses Android's Paint.Style.FILL. There is also Paint.Style.FILL_AND_STROKE which will fill in the region while simultaneously draw outside the shape for the stroke width. This is equivalent to drawing twice, one with Paint.Style.FILL and again with Paint.Style.STROKE in a single draw call. We don't expose "fill and stroke" currently in compose as it can cause some confusion.
    matvei

    matvei

    2 years ago
    Yeah I can second Nader here. It's an expected behaviour from the implementation side, but shouldn't be from the consumer side. I'm in progress of refactoring
    drawBackground
    and
    drawBorder
    to behave more correct and with better default, so
    Modifier.drawBorder
    will become
    Modifier.border
    and will properly pad and, probably, clip content inside, so there will be no such problem in the future
    n

    nglauber

    2 years ago
    Thanks @matvei! Good to hear that! 🙂
    and thanks for the explanation @Nader Jawad 😉
    Nader Jawad

    Nader Jawad

    2 years ago
    @matvei, I am wondering if we can just inset the radius by half the stroke width similar to what we do to inset the shape. By doing so the outside of the stroked shape should match the desired corner radius without making it rounder than it needs to be exposing the pixels underneath