Introduce glyph fonts to correct spacing.

This commit is contained in:
Alex Hart 2024-03-11 11:14:05 -03:00 committed by GitHub
parent 4dd3b92eda
commit 5c5d55d265
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 114 additions and 17 deletions

Binary file not shown.

View file

@ -7,9 +7,9 @@ import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat
import org.signal.core.util.dp
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.settings.PreferenceModel
import org.thoughtcrime.securesms.fonts.SignalSymbols
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.ContextUtil
import org.thoughtcrime.securesms.util.ServiceUtil
@ -57,20 +57,31 @@ object BioTextPreference {
SpanUtil.appendSpacer(this, 8)
SpanUtil.appendCenteredImageSpanWithoutSpace(this, ContextUtil.requireDrawable(context, R.drawable.ic_official_28), 28, 28)
} else if (recipient.isSystemContact) {
val drawable = ContextUtil.requireDrawable(context, R.drawable.symbol_person_circle_24).apply {
setTint(ContextCompat.getColor(context, R.color.signal_colorOnSurface))
val systemContactGlyph = SignalSymbols.getSpannedString(
context,
SignalSymbols.Weight.BOLD,
SignalSymbols.Glyph.PERSON_CIRCLE
).let {
SpanUtil.ofSize(it, 20)
}
SpanUtil.appendSpacer(this, 8)
SpanUtil.appendCenteredImageSpanWithoutSpace(this, drawable, 24, 24)
append(" ")
append(systemContactGlyph)
}
if (recipient.isIndividual && !recipient.isSelf) {
val drawable = ContextUtil.requireDrawable(context, R.drawable.symbol_chevron_right_24).apply {
setBounds(0, 0, 24.dp, 24.dp)
setTint(ContextCompat.getColor(context, R.color.signal_colorOutline))
val chevronGlyph = SignalSymbols.getSpannedString(
context,
SignalSymbols.Weight.BOLD,
SignalSymbols.Glyph.CHEVRON_RIGHT
).let {
SpanUtil.ofSize(it, 24)
}.let {
SpanUtil.color(ContextCompat.getColor(context, R.color.signal_colorOutline), it)
}
append(SpanUtil.buildCenteredImageSpan(drawable))
append(" ")
append(chevronGlyph)
}
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.fonts
import android.content.Context
import android.graphics.Typeface
import android.text.SpannableStringBuilder
import android.text.TextPaint
import android.text.style.MetricAffectingSpan
/**
* Helper object for working with the SignalSymbols font
*/
object SignalSymbols {
enum class Glyph(val unicode: Char) {
CHEVRON_RIGHT('\uE025'),
PERSON_CIRCLE('\uE05E')
}
enum class Weight {
BOLD
}
private val cache = mutableMapOf<Weight, Typeface>()
fun getSpannedString(
context: Context,
weight: Weight,
glyph: Glyph
): CharSequence {
val typeface = getTypeface(context, weight)
val span = CustomTypefaceSpan(typeface)
val text = SpannableStringBuilder(glyph.unicode.toString())
text.setSpan(span, 0, text.length, 0)
return text
}
private fun getTypeface(context: Context, weight: Weight): Typeface {
return when (weight) {
Weight.BOLD -> getBoldWeightedFont(context)
else -> error("Unsupported weight: $weight")
}
}
private fun getBoldWeightedFont(context: Context): Typeface {
return cache.getOrPut(
Weight.BOLD
) {
Typeface.createFromAsset(
context.assets,
"fonts/SignalSymbols-Bold.otf"
)
}
}
/**
* Custom TypefaceSpan to support TypefaceSpan in API<28
*
* Source: https://www.youtube.com/watch?v=x-FcOX6ErdI&t=486s
*/
private class CustomTypefaceSpan(val font: Typeface?) : MetricAffectingSpan() {
override fun updateMeasureState(textPaint: TextPaint) = update(textPaint)
override fun updateDrawState(textPaint: TextPaint?) = update(textPaint)
private fun update(tp: TextPaint?) {
tp.apply {
val old = this!!.typeface
val oldStyle = old?.style ?: 0
val font = Typeface.create(font, oldStyle)
typeface = font
}
}
}
}

View file

@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon;
import org.thoughtcrime.securesms.components.settings.conversation.preferences.ButtonStripPreference;
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.FallbackPhoto80dp;
import org.thoughtcrime.securesms.fonts.SignalSymbols;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
@ -191,17 +192,22 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
SpanUtil.appendSpacer(nameBuilder, 8);
SpanUtil.appendCenteredImageSpanWithoutSpace(nameBuilder, ContextUtil.requireDrawable(requireContext(), R.drawable.ic_official_28), 28, 28);
} else if (recipient.isSystemContact()) {
Drawable drawable = ContextUtil.requireDrawable(requireContext(), R.drawable.symbol_person_circle_24);
drawable.setTint(ContextCompat.getColor(requireContext(), R.color.signal_colorOnSurface));
SpanUtil.appendSpacer(nameBuilder, 8);
SpanUtil.appendCenteredImageSpanWithoutSpace(nameBuilder, drawable, 24, 24);
CharSequence systemContactGlyph = SignalSymbols.INSTANCE.getSpannedString(requireContext(),
SignalSymbols.Weight.BOLD,
SignalSymbols.Glyph.PERSON_CIRCLE);
nameBuilder.append(" ");
nameBuilder.append(SpanUtil.ofSize(systemContactGlyph, 20));
}
if (!recipient.isSelf() && recipient.isIndividual()) {
Drawable drawable = ContextUtil.requireDrawable(requireContext(), R.drawable.symbol_chevron_right_24);
drawable.setBounds(0, 0, (int) DimensionUnit.DP.toPixels(24), (int) DimensionUnit.DP.toPixels(24));
drawable.setTint(ContextCompat.getColor(requireContext(), R.color.signal_colorOutline));
nameBuilder.append(SpanUtil.buildCenteredImageSpan(drawable));
CharSequence chevronGlyph = SignalSymbols.INSTANCE.getSpannedString(requireContext(),
SignalSymbols.Weight.BOLD,
SignalSymbols.Glyph.CHEVRON_RIGHT);
nameBuilder.append(" ");
nameBuilder.append(SpanUtil.color(ContextCompat.getColor(requireContext(), R.color.signal_colorOutline),
SpanUtil.ofSize(chevronGlyph, 24)));
fullName.setText(nameBuilder);
fullName.setOnClickListener(v -> {