Developer Guide

Add custom watermark templates, logos, and fonts to PRISM.

Contents

Project Structure

app/src/main/ ├── java/io/prism/ │ ├── data/model/ │ │ ├── FontResource.kt │ │ ├── LogoResource.kt │ │ └── WatermarkStyle.kt ← ColorLocks here │ ├── data/repository/ │ │ └── ResourceRegistry.kt ← Register resources │ └── utils/ │ └── WatermarkRenderer.kt ← Renders layouts └── res/ ├── layout/ │ └── watermark_*.xml ├── drawable/ │ └── logo_*.xml ├── font/ │ └── *.ttf └── values/ └── strings.xml

Adding Templates

Step 1: Create Layout XML

Create file in res/layout/. Required view IDs:

IDTypePurpose
watermarkBGViewGroupRoot container
watermarkLogoImageViewLogo display
watermarkTextTextViewMain text
watermarkDeviceTextTextViewDevice name
watermarkEXIFDataTextTextViewEXIF info

Use android:tag="divider" for vertical dividers.

XML res/layout/watermark_custom.xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/watermarkBG"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="24dp"
    android:gravity="center_vertical"
    android:background="@color/watermark_bg_light">

    <ImageView
        android:id="@+id/watermarkLogo"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginEnd="16dp" />

    <View
        android:layout_width="2dp"
        android:layout_height="40dp"
        android:layout_marginEnd="16dp"
        android:background="@color/watermark_divider"
        android:tag="divider" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/watermarkText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/watermarkDeviceText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:textSize="14sp"
            android:visibility="gone" />

        <TextView
            android:id="@+id/watermarkEXIFDataText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:textSize="12sp"
            android:alpha="0.7" />

    </LinearLayout>
</LinearLayout>

Step 2: Add Strings

XML res/values/strings.xml
<string name="style_custom">Custom</string>
<string name="style_custom_desc">Your custom style</string>

Step 3: Register Style

Kotlin ResourceRegistry.kt
WatermarkStyle(
    id = "custom",
    nameResId = R.string.style_custom,
    layoutResId = R.layout.watermark_custom,
    descriptionResId = R.string.style_custom_desc
)

Adding Logos

Step 1: Add Drawable

XML res/drawable/logo_camera.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000000"
        android:pathData="M12,12m-3.2,0a3.2,3.2..." />
</vector>

Step 2: Add String

XML res/values/strings.xml
<string name="logo_camera">Camera</string>

Step 3: Register Logo

Kotlin ResourceRegistry.kt
LogoResource(
    id = "camera",
    nameResId = R.string.logo_camera,
    drawableResId = R.drawable.logo_camera,
    isMonochrome = true
)
Monochrome: Set isMonochrome = true for single-color logos. They adapt to text color automatically.

Adding Fonts

Step 1: Add Font File

Place TTF/OTF in res/font/. Use lowercase with underscores:

Step 2: Add String

XML res/values/strings.xml
<string name="font_opensans">Open Sans</string>

Step 3: Register Font

Kotlin ResourceRegistry.kt
FontResource(
    id = "opensans",
    nameResId = R.string.font_opensans,
    fontResId = R.font.opensans_regular
)

Color Locks

Lock colors so they cannot be changed by users.

ColorLocks Data Class

Kotlin WatermarkStyle.kt
data class ColorLocks(
    val backgroundColorLocked: Boolean = false,
    val mainTextColorLocked: Boolean = false,
    val exifTextColorLocked: Boolean = false,
    val forcedBackgroundColor: Int? = null,
    val forcedMainTextColor: Int? = null,
    val forcedExifTextColor: Int? = null
)

Example: Branded Dark Style

Kotlin ResourceRegistry.kt
WatermarkStyle(
    id = "branded_dark",
    nameResId = R.string.style_branded_dark,
    layoutResId = R.layout.watermark_standard,
    descriptionResId = R.string.style_branded_dark_desc,
    colorLocks = ColorLocks(
        backgroundColorLocked = true,
        mainTextColorLocked = true,
        exifTextColorLocked = true,
        forcedBackgroundColor = Color.parseColor("#1a1a2e"),
        forcedMainTextColor = Color.parseColor("#edf2f4"),
        forcedExifTextColor = Color.parseColor("#8d99ae")
    )
)
Theme Lock: When both backgroundColorLocked and mainTextColorLocked are true, the Light/Dark theme selector is automatically disabled.

ResourceRegistry

Central place for all built-in resources.

Kotlin ResourceRegistry.kt
object ResourceRegistry {

    val fonts: List<FontResource> = listOf(
        FontResource(
            id = "roboto",
            nameResId = R.string.font_roboto,
            fontResId = R.font.roboto_regular
        )
    )

    val defaultFont = fonts.first()

    val builtInLogos: List<LogoResource> = listOf(
        LogoResource.NO_LOGO.copy(nameResId = R.string.logo_none),
        LogoResource(
            id = "prism",
            nameResId = R.string.logo_prism,
            drawableResId = R.drawable.logo_prism,
            isMonochrome = false
        )
    )

    val defaultLogo = builtInLogos[1]

    val styles: List<WatermarkStyle> = listOf(
        WatermarkStyle(
            id = "standard",
            nameResId = R.string.style_standard,
            layoutResId = R.layout.watermark_standard,
            descriptionResId = R.string.style_standard_desc
        )
    )

    val defaultStyle = styles.first()

    fun findFontById(id: String) = fonts.find { it.id == id }
    fun findLogoById(id: String) = builtInLogos.find { it.id == id }
    fun findStyleById(id: String) = styles.find { it.id == id }
}

Checklist

Important: IDs must be unique. They are used for saving user preferences.