← Back to chrisjenx/Calligraphy

How to Deploy & Use chrisjenx/Calligraphy

Calligraphy Deployment & Usage Guide

⚠️ End-of-Life Notice: This version of Calligraphy (2.x) is no longer maintained. For new projects, migrate to Calligraphy 3.

Prerequisites

  • Android Studio (Arctic Fox or later recommended)
  • Android SDK (API 16+; supports AppCompat v7)
  • Java 7 or higher (Java 8 recommended)
  • Gradle 3.0+ (via Android Gradle Plugin)
  • Physical device or emulator running Android 4.1+ (API 16)

Installation

1. Add Gradle Dependency

In your app module's build.gradle:

dependencies {
    implementation 'uk.co.chrisjenx:calligraphy:2.3.0'
}

Note: If using older Gradle versions (< 3.0), use compile instead of implementation.

2. Add Font Assets

Place .ttf or .otf files in the assets directory:

app/src/main/assets/
├── fonts/
│   ├── Roboto-Regular.ttf
│   ├── Roboto-Bold.ttf
│   └── CustomFont.ttf

Create the directory if it doesn't exist:

mkdir -p app/src/main/assets/fonts

3. Sync Project

./gradlew sync

Or use File > Sync Project with Gradle Files in Android Studio.

Configuration

1. Initialize in Application Class

Create or modify your Application class:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        
        CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
                .setDefaultFontPath("fonts/Roboto-Regular.ttf")
                .setFontAttrId(R.attr.fontPath)
                .build()
        );
    }
}

Register in AndroidManifest.xml:

<application
    android:name=".MyApplication"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    ... >
</application>

2. Wrap Activity Context

In every Activity where you want font injection:

public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

3. XML Usage

Apply fonts directly to views (no namespace required):

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World"
    fontPath="fonts/Roboto-Bold.ttf"/>

Font Resolution Priority (highest to lowest):

  1. View attribute (fontPath)
  2. Style attribute
  3. TextAppearance attribute
  4. Theme default
  5. CalligraphyConfig default

Build & Run

Development Build

./gradlew assembleDebug

Install on connected device:

./gradlew installDebug

Production Build

./gradlew assembleRelease

Testing Font Injection

Create a test layout:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- Uses default font from CalligraphyConfig -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Default Font" />

    <!-- Uses specific font -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Bold Font"
        fontPath="fonts/Roboto-Bold.ttf"/>
</LinearLayout>

Deployment

Library Development (Publishing AAR)

If modifying Calligraphy itself, publish to Maven:

./gradlew clean build uploadArchives

Configure repository credentials in gradle.properties or local ~/.gradle/gradle.properties:

NEXUS_USERNAME=your_username
NEXUS_PASSWORD=your_password

App Integration (Production)

For apps using Calligraphy:

  1. ProGuard/R8 Rules (if minification enabled):
-keep class uk.co.chrisjenx.calligraphy.** { *; }
-keep class android.support.v7.widget.** { *; }
  1. Bundle Assets: Ensure fonts in src/main/assets/ are included in the APK/AAB. Verify with:
unzip -l app-release.apk | grep assets
  1. Migration Strategy: Since this library is EOL, plan migration to Calligraphy 3 or Compose for new projects.

Troubleshooting

IDE Shows "MissingPrefix" Errors

Android Studio may flag fontPath as an error. Add the tools namespace and ignore attribute:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    ... >

    <TextView
        ...
        fontPath="fonts/MyFont.ttf"
        tools:ignore="MissingPrefix" />
</LinearLayout>

Fonts Not Applying

  1. Verify Context Wrapping: Ensure CalligraphyContextWrapper.wrap() is called in attachBaseContext(), not onCreate()
  2. Check Font Path: Paths are relative to assets/. Use fonts/Filename.ttf, not /fonts/Filename.ttf
  3. Verify Font Files: Ensure font files are valid TTF/OTF and placed in src/main/assets/, not src/main/res/

AppCompat Compatibility

For AppCompat v7 support, ensure you have the dependency:

implementation 'com.android.support:appcompat-v7:28.0.0'

Calligraphy automatically detects and supports AppCompatTextView, Toolbar, and other v7 widgets.

Multi-Typeface TextViews

For mixed fonts in a single TextView, use CalligraphyTypefaceSpan:

SpannableStringBuilder builder = new SpannableStringBuilder("Hello World");
CalligraphyTypefaceSpan span = new CalligraphyTypefaceSpan(
    TypefaceUtils.load(getAssets(), "fonts/Roboto-Bold.ttf")
);
builder.setSpan(span, 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(builder, TextView.BufferType.SPANNABLE);

ActionBar/Toolbar Fonts

For ActionBar titles/subtitles, ensure your theme applies TextView styles:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="actionBarStyle">@style/MyActionBar</item>
</style>