com.bluebillywig.bbnativeplayersdk.fonts — Functions
fromResource
fun fromResource(@FontRes id: Int) : Typeface?
/** A downloaded font file, validated by [BBFontRegistry]. Null when it is not usable. */
fun fromFile(path: String): Typeface?
/** `Typeface.create(name, style)`. Never null in practice; Android substitutes silently. */
fun system(name: String, style: Int): Typeface?
/**
* True when [tf] renders identically to the platform default for [style], which is how
* Android reports "I have never heard of that family name" - it substitutes instead of
* failing. Measured, not compared by identity: `Typeface.create` may hand back a distinct
* object that still wraps the default family.
*/
fun isDefaultSubstitution(tf: Typeface, style: Int): Boolean
/** `Typeface.create(tf, style)`; picks a real face from the family or lets the OS synthesise. */
fun withStyle(tf: Typeface, style: Int): Typeface
}
/**
* @suppress
*/
class AndroidTypefaceLoader(context: Context) : TypefaceLoader
The bundled Lato faces. Null when the resource cannot be loaded.
fromFile
fun fromFile(path: String) : Typeface?
/** `Typeface.create(name, style)`. Never null in practice; Android substitutes silently. */
fun system(name: String, style: Int): Typeface?
/**
* True when [tf] renders identically to the platform default for [style], which is how
* Android reports "I have never heard of that family name" - it substitutes instead of
* failing. Measured, not compared by identity: `Typeface.create` may hand back a distinct
* object that still wraps the default family.
*/
fun isDefaultSubstitution(tf: Typeface, style: Int): Boolean
/** `Typeface.create(tf, style)`; picks a real face from the family or lets the OS synthesise. */
fun withStyle(tf: Typeface, style: Int): Typeface
}
/**
* @suppress
*/
class AndroidTypefaceLoader(context: Context) : TypefaceLoader
A downloaded font file, validated by [BBFontRegistry]. Null when it is not usable.
system
fun system(name: String, style: Int) : Typeface?
/**
* True when [tf] renders identically to the platform default for [style], which is how
* Android reports "I have never heard of that family name" - it substitutes instead of
* failing. Measured, not compared by identity: `Typeface.create` may hand back a distinct
* object that still wraps the default family.
*/
fun isDefaultSubstitution(tf: Typeface, style: Int): Boolean
/** `Typeface.create(tf, style)`; picks a real face from the family or lets the OS synthesise. */
fun withStyle(tf: Typeface, style: Int): Typeface
}
/**
* @suppress
*/
class AndroidTypefaceLoader(context: Context) : TypefaceLoader
Typeface.create(name, style). Never null in practice; Android substitutes silently.
isDefaultSubstitution
fun isDefaultSubstitution(tf: Typeface, style: Int) : Boolean
/** `Typeface.create(tf, style)`; picks a real face from the family or lets the OS synthesise. */
fun withStyle(tf: Typeface, style: Int): Typeface
}
/**
* @suppress
*/
class AndroidTypefaceLoader(context: Context) : TypefaceLoader
True when [tf] renders identically to the platform default for [style], which is how
Android reports "I have never heard of that family name" - it substitutes instead of
failing. Measured, not compared by identity: Typeface.create may hand back a distinct
object that still wraps the default family.
withStyle
fun withStyle(tf: Typeface, style: Int) : Typeface
}
/**
* @suppress
*/
class AndroidTypefaceLoader(context: Context) : TypefaceLoader
Typeface.create(tf, style); picks a real face from the family or lets the OS synthesise.
specs
fun specs(rawJson: String, current: Map<FontRole, FontSpec>) : Map<FontRole, FontSpec>
The new spec per role for a raw playout payload, e.g. the playoutDataJsonString handed to
updatePlayoutWithJson. Returns [current] unchanged when the payload is not a json object.
specsFromOptions
fun specsFromOptions(options: Map<String, Any?>?, current: Map<FontRole, FontSpec>) : Map<FontRole, FontSpec>
The same rule for the create-options map handed to BBNativePlayer.createPlayerView. The
option keys are the playout's own (skin_fontHeadingId, skin_fontHeading,
skin_fontBodyId, skin_fontBody) so the semantics are identical, and a present key
overrides the playout for the lifetime of the view.
optionOverrides
fun optionOverrides(options: Map<String, Any?>?) : Map<FontRole, FontSpec>
Which roles carry a create-time option override, and what into. Unlike [specsFromOptions]
this never falls back to a "current" map: a role absent from [options] is simply absent from
the result, so the caller can tell "no override" apart from "overridden to [FontSpec.None]"
and keep the override across every later playout update - a runtime updatePlayoutWithJson
must not be able to erase a create-time option, and in player mode Shorts' AppConfig fonts
travel through this same options map into the inner player (#20290 review finding 2). In
list mode there is no inner player: BBNativeShortsView resolves the same specs with its own
provider for the shelf, without this map.
effective
fun effective(playout: Map<FontRole, FontSpec>, options: Map<FontRole, FontSpec>) : Map<FontRole, FontSpec>
Effective spec per role: [options] wins when it carries an entry for the role, else [playout] decides, else [FontSpec.None]. However [playout] changes afterwards, an option entry already in [options] is never overwritten (#20290 review finding 2).
compute
fun compute(
rootIds: Map<FontRole, String?>,
rootNames: Map<FontRole, String?>,
options: Map<String, Any?>?
) : Layers
[rootIds] / [rootNames] are the app config's raw values per role, [options] the map the host
passed at creation. Presence of a role's id key in [options] is what makes it an override -
the name key alone never decides anything, exactly as in FontPlayoutDelta.
needed
fun needed(current: FontResolver?, baseUrl: String, defaultMediaAssetPath: String) : Boolean
True when [current] cannot serve [baseUrl] + [defaultMediaAssetPath], so the caller must
construct a resolver that can, __destruct this one and cancel any retry queued for it.
False keeps the instance, and that is the point of asking: its per-clip-id memo and its in-flight downloads were resolved against exactly this pair and are still the right answers, so replacing a resolver on a repeat embed of the same publication throws away a working memo and re-downloads fonts the view already has.
typefaceFor
fun typefaceFor(path: String) : Typeface?
The Typeface for [path], or null when the file is missing, empty, unparseable or renders no glyphs. Failures are remembered so a broken file is not re-parsed on every re-apply.
apply
fun apply(root: View?, provider: BBFontProvider?)
XML opt-in for a body-role TextView.
apply
fun apply(root: View?, provider: BBFontProvider?)
XML opt-in for a heading-role TextView.
apply
fun apply(root: View?, provider: BBFontProvider?)
Depth-first over [root]; a no-op only when [root] itself is null. A null [provider] -
routinely the case from a screen's init, which runs before BBNativePlayerView can inject
its own - applies [BBFontProvider.latoFallback] instead of doing nothing, so the tree never
sits in the platform default between inflate and owner assignment (#20290 review).
set
fun set(view: TextView, provider: BBFontProvider?, role: FontRole, style: BBFontStyle)
Mark [view] as belonging to [role] at [style] and give it the matching typeface now.
Programmatic sites use this instead of ResourcesCompat.getFont, so a later [apply] can
find them again.
tag
fun tag(view: View, role: FontRole, style: BBFontStyle)
Tags only, no typeface change.
onResolved
fun onResolved(
specs: Map<FontRole, FontSpec>,
heading: FontResolution,
body: FontResolution,
isRetry: Boolean,
retryPending: Boolean,
startedWith: FontResolver?,
current: FontResolver?,
provider: BBFontProvider,
scheduleRetry: (specs: Map<FontRole, FontSpec>) -> Unit
)
Apply [heading] and [body] to [provider], unless this verdict is stale or its resolver is no longer the owner's, and schedule a retry when a role came back transiently [FontResolution.Unavailable].
Parameters:
| Name | Description |
|---|---|
specs | the specs this resolution was started for |
isRetry | true for the resolution [scheduleRetry] itself started: one retry per |
| resolution, never a chain | |
retryPending | true while a retry runnable is already queued - the one-shot budget for |
| the current specs, which the owner cancels when the specs change | |
startedWith | the resolver resolveBoth was called on, captured when this resolution |
| started | |
current | the owner's resolver now, read at callback time: another instance once |
| the publication changed, null once the owner has let go of it | |
scheduleRetry | called with [specs] when this verdict earns a retry |