A library that gives full control over text related technologies such as bidirectional algorithm, open type shaping, text typesetting and text rendering

Overview

Tehreer-Android

License Maven Central

Tehreer is a library which gives full control over following text related technologies.

  • Bidirectional Algorithm
  • OpenType Shaping Engine
  • Text Typesetting
  • Text / Glyph Rendering

It is a wrapper over mature C libraries, FreeType, SheenBidi and SheenFigure. So a part of the library has been written in JNI in order to access the functionality of said libraries.

Screenshots

Installation

If you are building with Gradle, simply add the following line to the dependencies section of your build.gradle file:

compile 'com.github.mta452:tehreer-android:2.5'

Proguard

-keepclassmembers, includedescriptorclasses class * {
    native <methods>;
}

API Reference

The Javadocs are available for online browsing. The Javadocs are also bundled as source Jars with each distribution for consumption in the IDE.

License

Copyright (C) 2016-2021 Muhammad Tayyab Akram

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • coloured text rendering

    coloured text rendering

    as-Salamu alaykum wa rahmatuLLahi wa barakatuh.

    Brother please consider implementing coloured rendering in widget like regular textview does when applying setText with formatted strings like this:

    <item><![CDATA[<br>some <font color="#00ff00">couloured</font> text]]></item> <item><![CDATA[<br><font color="#2693ff">another</font> one]]></item>

    Due to lack of knowledge of android internals and java in general i've only done partial demo app modification. Now it's accepting formatted strings like above example. Here is gist with patch and images https://gist.github.com/AbdullahRusi/0a55169396653a06db3452ba79c7f4dd As seen on screenshots standart textview lacks of good font rendering/shaping engine. It produce many artifacts(broken ligatures, marks not on right places). Your excellent library does that part (shaping and rendering glyphs) very well (besides vertical line). On desctop firefox browser is correctly rendering that formatted text. As i know it uses Harfbuzz or something, so it's good.

    so it may become very useful for many Muslims and big sawab(ajr) for you inshaaLLah

    enhancement 
    opened by AbdullahRusi 15
  • ClickableSpan support in widget

    ClickableSpan support in widget

    السلام علیکم ورحمة الله وبرکاته

    Brother please consider implementing this useful feature, use cases include support of clicking on individual word, having some links with references etc

    As of now widget doesn't have ClickableSpan support to use something like this:

    static View.OnTouchListener ssilkaToch = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { boolean ret = false; CharSequence text = ((TextView) v).getText(); Spannable stext = Spannable.Factory.getInstance().newSpannable(text); TextView widget = (TextView) v; int action = event.getAction();
    		if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
    			int x = (int) event.getX();
    			int y = (int) event.getY();
    
    			x -= widget.getTotalPaddingLeft();
    			y -= widget.getTotalPaddingTop();
    
    			x += widget.getScrollX();
    			y += widget.getScrollY();
    
    			Layout layout = widget.getLayout();
    			int line = layout.getLineForVertical(y);
    			int off = layout.getOffsetForHorizontal(line, x);
    
    			ClickableSpan[] link = stext.getSpans(off, off, ClickableSpan.class);
    
    			if (link.length != 0) {
    				if (action == MotionEvent.ACTION_UP) {
    					link[0].onClick(widget);
    				}
    				ret = true;
    			}
    		}
    		return ret;
    	}
    };
    

    My use case is support of clicking on individual word and get it recitated or meaning searched through dictionary. Also needed setLineSpacing Thank you for your effort and support

    enhancement 
    opened by AbdullahRusi 12
  • Any chance for iOS version?

    Any chance for iOS version?

    السلام عليكم ورحمة الله وبركاته

    @mta452 Brother is there any chance for iOS version of your excellent library?

    Got Xcode 11 GM and tested stock iOS 13 UITextView in simulator and found awful rendering with lots of glitches

    with fonts which are working well in android when using your library.

    Also i tried SheenFigureLegacy and managed to compile and run demo both with CG and latest FT (both seemed perform same) last one required extra steps:

    1. select standart architecture and build only for active in build settings (otherwise it compiles for i386)
    2. get ftapi.c from previous FT versions and place to base folder
    3. include ftgzip.c
    4. add this lines to it to fix error:
    int z_verbose = 0;
    
    void z_error(/* should be const */char* message)
    {
        printf(message);
    }
    1. do not comment out ttdriver in FT module config (otherwise app will fall with exception)

    it's already better than stock, but it contains old bugs that were already fixed in tehreer

    • vertikal lines mentioned here https://github.com/Tehreer/Tehreer-Android/issues/1#issuecomment-353013921
    • expecting all bugs mentioned there present
    • some marks are not on places
    • there is no support for color rendering (attributed strings) which is implemented in tehreer in it's way
    • there is crash with one font (Quran_4.ttf) while it works well with tehreer
    opened by AbdullahRusi 4
  • java.lang.UnsatisfiedLinkError: Couldn't load tehreerjni from loader

    java.lang.UnsatisfiedLinkError: Couldn't load tehreerjni from loader

    Hello I am currently upgrading my app from 2.0 to 2.1 of your library to fix the issues with Android 4.x.

    At this line I am getting an UnsatisfiedLinkError: tehreerTypeface = new com.mta.tehreer.graphics.Typeface(context.getAssets(), "fonts/font.ttf");

    The Exception:

    java.lang.UnsatisfiedLinkError: Couldn't load tehreerjni from loader dalvik.system.PathClassLoader[dexPath=/data/app/com.jesusfilmmedia.android.jesusfilm-1.apk,libraryPath=/data/app-lib/com.jesusfilmmedia.android.jesusfilm-1]: findLibrary returned null
            at java.lang.Runtime.loadLibrary(Runtime.java:355)
            at java.lang.System.loadLibrary(System.java:525)
            at com.mta.tehreer.internal.JniBridge.loadLibrary(JniBridge.java:27)
            at com.mta.tehreer.graphics.Typeface.<clinit>(Typeface.java:39)
            ...
    

    This does not appear to be an issue on my Pixel (8.1), but it is an issue on my SamsungGalaxy S4 (Android 4.3)

    Please let me know if I am doing something wrong or if I need to wait for this to be fixed on your side.

    opened by KarsonOdette 4
  • Support for cluster splitting in multiple spans

    Support for cluster splitting in multiple spans

    This issue is a continuation of discussion in #1

    Consider three characters form a ligature, but its individual characters have different color spans. The typesetter does not break runs based on color spans, but whole ligature is rendered in a single color, which is a deviation from intended behavior. The same thing happens if multiple characters form a cluster, such as marks followed by a base.

    As characters are not recognizable in a ligature/cluster, they can be estimated by dividing the total advance of the cluster with the number of characters in it. Then, the whole cluster should be rendered in defined edges with clipping mode.

    The end result should be similar to the following image, where the estimated portion of س and ت is rendered in red color.

    enhancement 
    opened by mta452 2
  • Use keep annotation instead of custom sustain annotation

    Use keep annotation instead of custom sustain annotation

    Currently a custom annotation, @Sustain is being used for correct proguard behavior. It can be replaced with @Keep support annotation for the same purpose.

    enhancement 
    opened by mta452 1
  • Label disappears after setting text size

    Label disappears after setting text size

    The steps to reproduce the issue are the following.

    • Set text of a TLabel with typesetter using setTypesetter() method.
    • Set text size of the label using setTextSize() method.
    • The label will become empty. If size is set before the typesetter, the label works as expected.
    bug 
    opened by mta452 1
  • Strikeout position and thickness availability

    Strikeout position and thickness availability

    The Typeface class exposes properties to access underline position and thickness in font units. Similarly, strikeout position and thickness should also be made available. The info can be obtained from OS/2 table.

    enhancement 
    opened by mta452 1
  • Chararacter measurement based on caret range distance

    Chararacter measurement based on caret range distance

    Now that cluster splitting has been implemented for #10 with the use of character extents, it is a good time to replace traditional glyph-based measurement with character-based measurement. The idea is that character distances are calculated during the run creation phase, and then these are used to measure the character range irrespective of glyph advances. With this approach, the measurement could be much faster as it involves just a single subtraction of upper and lower distances.

    enhancement 
    opened by mta452 1
  • Backward shaping order not working in typesetter

    Backward shaping order not working in typesetter

    When script direction is opposite to that of bidi run direction, the rendered characters do not follow the bidi direction. For example, the string "\u202ELive on time" should be rendered reversed due to the presence of RLO character in the beginning.

    bug 
    opened by mta452 1
  • Usage of android support annotations

    Usage of android support annotations

    Android support annotations should be used throughout the project to improve code inspection. Nullability annotations are of particular importance.

    Documentation: https://developer.android.com/studio/write/annotations

    enhancement 
    opened by mta452 1
  • Primitive Collections Testing

    Primitive Collections Testing

    The primitive collections are at the core of the library. Even a minor mistake can have a huge impact on the stability. General test cases should be available to check the correctness of concrete implementations.

    opened by mta452 1
Releases(v2.8)
  • v2.8(Mar 15, 2022)

    Additions:

    • Added seek bar for adjusting justification level in custom text view demo screen

    FrameResolver:

    • Justification Support: setJustificationEnabled(boolean justificationEnabled), boolean isJustificationEnabled()
    • Justification Level: setJustificationLevel(float justificationLevel), float getJustificationLevel()

    Typesetter:

    • Line Justification: ComposedLine createJustifiedLine(int charStart, int charEnd, float justificationFactor, float justificationWidth)

    TTextView:

    • Justification Properties: justificationEnabled, justificationLevel

    Updates:

    • Introduced CaretEdgesBuilder class for generating caret edges from a set of input parameters
    • Updated getCaretEdges() method in ShapingResult to base on CaretEdgesBuilder
    • Converted TextRun from abstract class to an interface
    • Introduced AbstractTextRun class for providing helper implementation of some methods
    • Introduced TextRunDrawing interface for separating drawing logic from a TextRun implementation
    • Introduced DefaultTextRunDrawing class for reusing drawing logic in a TextRun implementation
    • Updated IntrinsicRun class to base on AbstractTextRun
    • Removed text drawing support from IntrinsicRun
    • Put ReplacementRun related implementation in its own class
    • Introduced CaretEdges class in IntrinsicRunSlice to transform the edges of parent run
    • Updated draw() method in IntrinsicRunSlice to base on DefaultTextRunDrawing
    • Introduced JustifiedRun class to transform an existing text run into a justified one
    • Added justification support in LineResolver and TextContainer
    • Simplified text frame resolving implementation in FrameResolver
    Source code(tar.gz)
    Source code(zip)
  • v2.7(Oct 17, 2021)

    Additions

    • A new custom text view component based on ScrollView
    • Presented Surah Al-Kahf with Tajweed rules in demo project
    • Added variation support in text shaping
    • Added support for named styles in typeface
    • Added support for caching glyph advances during text shaping

    Updates

    • Fixed an issue related to default palette selection in Typeface
    • Broke down Typeface into multiple classes on JNI side
    • Introduced RenderableFace class for holding FT_Face in JNI
    • Introduced ShapableFace class for holding custom implementation of hb_font in JNI
    • Used custom mechanism for handling variation coordinates
    • Moved variable font description handling to Java side
    • Removed references to NameTable in Typeface class
    • Removed suppress warnings of Raw Types in LruCache
    Source code(tar.gz)
    Source code(zip)
  • v2.6(Apr 24, 2021)

  • v2.5(Jan 23, 2021)

    Additions

    • Added support for color fonts consisting of COLR / CPAL tables
    • Covered a color font with palettes in demo project
    • Added support for colored and stroked glyphs' caching

    Typeface:

    • Palette Entry Names: List<String> getPaletteEntryNames()
    • Predefined Palettes: List<ColorPalette> getPredefinedPalettes()
    • Palette Colors: int[] getAssociatedColors()
    • Color Instance: Typeface getColorInstance(int[] colors)

    TLabel:

    • Rendering Style: fill, fill_stroke, stroke
    • Stroke Properties: color, width, cap, join, miter

    Updates

    • Optimized internal architecture to represent text runs
    • Optimized glyph cache for faster access to objects
    • Updated free type to version 2.10.4
    • Updated sheen bidi to version 2.3
    Source code(tar.gz)
    Source code(zip)
    Demo_v2.5.apk(8.26 MB)
  • v2.4(Mar 19, 2019)

    Additions

    • Added support for variable fonts
    • Covered variable fonts in demo project
    • Wrote likable label in demo project

    FontFile:

    • Named Typefaces: List<Typeface> getTypefaces()

    Typeface:

    • Variation Axes: List<VariationAxis> getVariationAxes()
    • Variation Coordinates: float[] getVariationCoordinates()
    • Variation Instance: Typeface getVariationInstance(float[] coordinates)

    ShapingResult:

    • Caret Edges: FloatList getCaretEdges(boolean[] caretStops)

    Updates

    • Added static constructors in table classes
    • Used sheen figure for caret handling
    • Updated free type to version 2.10.0
    Source code(tar.gz)
    Source code(zip)
    Demo_v2.4.apk(9.66 MB)
  • v2.3(Dec 9, 2018)

    Additions

    Added @Nullable, @NonNull, @Size and @ColorInt annotations throughout the project

    ShapingEngine:

    • OpenType Features: setOpenTypeFeatures(Set<OpenTypeFeature> features), Set<OpenTypeFeature> getOpenTypeFeatures()

    Typeface:

    • Strikeout Properties: int getStrikeoutPosition(), int getStrikeoutThickness()

    @IntDef Annotations:

    • BidiClass: @Value
    • GeneralCategory: @Value
    • Script: @Value

    Updates

    • Implemented character measurement based on caret range distance
    • Wrote Precondition class and used it for checking parameter expectations
    • Removed custom @Sustain annotation in favour of androidx @Keep annotation
    • Replaced array with variable args for creating primitive lists
    • Updated SheenFigure to version 1.5

    Fixes

    • Fixed an issue related to text becoming blank in TLabel widge
    • Fixed backward mode glyph run rendering issues
    • Fixed backward mode cluster clipping issues
    • Fixed equals(Object) implementation of NameTable.Record
    Source code(tar.gz)
    Source code(zip)
    Demo_v2.3.apk(9.38 MB)
  • v2.2(Aug 21, 2018)

    Additions

    BidiClass:

    GeneralCategory:

    Script:

    CodePoint:

    • Bidi Class Property: static int getBidiClass(int codePoint)
    • General Category Property: static int getGeneralCategory(int codePoint)
    • Script Property: static int getScript(int codePoint)
    • Mirroring Property: static int getMirror(int codePoint)

    BidiAlgorithm:

    • Bidi Classes: IntList getCharBidiClasses()

    ScriptClassifier:

    • Unicode Standard: UAX #24
    • Resolved Scripts: IntList getCharScripts()
    • Resolved Runs: Iterable<ScriptRun> getScriptRuns(int charStart, int charEnd)

    GlyphRun:

    • Cluster Splitting: int getStartExtraLength(), int getEndExtraLength()

    Added support for cluster splitting in multiple spans Wrote an abstract class for testing IntList implementations Used a dedicated Android.mk file for instrumentation tests

    Updates

    • Integrated script analysis process of UAX #24 in typesetting
    • Made right-to-left glyph drawing with decreasing pen x value in Renderer
    • Reduced synthetic methods generation with package access
    • Enabled JNI symbols stripping in release mode
    • Reduced property methods calling in Renderer
    • Used direct field accesses in GlyphRun
    • Shortened names of native methods with n prefix
    • Refactored names of internal primitive collections
    • Updated FreeType to version 2.9.1
    • Updated SheenBidi to version 2.1
    • Updated SheenFigure to version 1.4

    Fixes

    • Fixed invalid leading and trailing index issues in GlyphRun
    • Fixed accidental deallocation of data in primitive raw list implementations
    • Fixed character measurement of backward segments in typesetting
    • Fixed cluster map copying issue in GlyphRun
    • Fixed redundant type casting warnings in demo project
    Source code(tar.gz)
    Source code(zip)
    Demo_v2.2.apk(9.31 MB)
  • v2.1(Apr 1, 2018)

    Additions

    TypeFamily:

    • Style Matching: getTypefaceByStyle(TypeWidth, TypeWeight, TypeSlope)

    TypefaceManager:

    • Typeface Grouping: getTypeFamily(String familyName)

    TextAlignment:

    • Natural Alignment: INTRINSIC, EXTRINSIC

    GlyphRun:

    • Character Group: int getActualClusterStart(int charIndex), int getActualClusterEnd(int charIndex)
    • Glyph Group: int getLeadingGlyphIndex(int charIndex), int getTrailingGlyphIndex(int charIndex)
    • Hit Testing: float computeCharDistance(int charIndex), int computeNearestCharIndex(float distance)

    ComposedLine:

    • Hit Testing: float computeCharDistance(int charIndex), int computeNearestCharIndex(float distance)
    • Highlighting: float[] computeVisualEdges(int charStart, int charEnd)

    CompsedFrame:

    • Boundary Properties: originX, originY, width, height
    • Hit Testing: int getLineIndexForChar(int charIndex), int getLineIndexForPosition(float x, float y)
    • Highlighting: Path generateSelectionPath(int charStart, int charEnd)

    TLabel:

    • Line Properties: extraLineSpacing, lineHeightMultiplier
    • Text Properties: composedFrame, spanned, typesetter
    • Hit Testing: int hitTestPosition(float x, float y)

    Added FrameResolver class for easier text layout and measurement.

    Added support for following CharacterStyle spans without invoking updateDrawState(TextPaint) or updateMeasureState(TextPaint):

    • ForegroundColorSpan
    • AbsoluteSizeSpan
    • RelativeSizeSpan
    • ReplacementSpan
    • ScaleXSpan
    • StyleSpan
    • SubscriptSpan
    • SuperscriptSpan
    • TextAppearanceSpan
    • TypefaceSpan

    Added support for following ParagraphStyle spans:

    • AlignmentSpan
    • BulletSpan
    • LeadingMarginSpan
    • LeadingMarginSpan2
    • LineBackgroundSpan
    • LineHeightSpan
    • QuoteSpan

    Updates

    • Divided functionality of Typesetter into various logical classes
    • Made TypefaceSpan and TypeSizeSpan conform to MetricAffectingSpan for easier span handling
    • Updated FreeType to version 2.9
    • Updated SheenFigure to version 1.3

    Fixes

    • Fixed NullPointerException caused by NameTable on older android versions
    • Fixed gravity attribute of TLabel with flag format
    • Prohibited offsets and advances scaling in Renderer
    • Made accidentally publicized method createCompactLine private in Typesetter
    Source code(tar.gz)
    Source code(zip)
    Demo_v2.1.apk(9.34 MB)
  • v2.0(Jul 30, 2017)

Owner
Tehreer
Tehreer
Helper object for injecting typeface into various text views of android.

TypefaceHelper Helper object for injecting typeface into various text views of android. Overview We can use various custom typefaces asset for any tex

Drivemode, Inc. 105 Nov 25, 2022
Custom font library for android | Library to change/add font of Entire Android Application at once without wasting your time - TextViews, EditText, Buttons, Views etc.,

AppFontChanger In a Single shot change font of Entire Android Application - TextViews, EditText, Buttons, Views etc., Kindly use the following links t

Prabhakar Thota 48 Aug 10, 2022
A lightweight Android library for use iconic fonts.

Print A lightweight Android library for use iconic fonts. Download Gradle: compile 'com.github.johnkil.print:print:1.3.1' Maven: <dependency> <gro

Evgeny Shishkin 202 Dec 27, 2022
A lightweight Android library for use iconic fonts.

Print A lightweight Android library for use iconic fonts. Download Gradle: compile 'com.github.johnkil.print:print:1.3.1' Maven: <dependency> <gro

Evgeny Shishkin 202 Dec 27, 2022
An android library to display FontAwesome Icons in any View or a MenuItem

DroidAwesome A library to display FontAwesome Icons in any View or a MenuItem Views Supported: TextView AutoComplete TextView EditText Switch CheckBox

Livin 38 Aug 25, 2022
Android Library to use custom fonts with ease.

FontometricsLibrary A Simple Android Library to use Custom Fonts with Ease. Use Customs Fonts in your Android project without adding any .ttf/.otf in

Ishmeet Singh 188 Nov 15, 2022
Fontize is an Android library that enables multi-font selection functionality to diversify your app.

Fontize Android Library Built with ❤︎ by Gourav Khunger Fontize is an Android library, written in kotlin, that enables your android app have multiple

Gourav Khunger 8 Nov 28, 2022
Material and Holo iconic fonts.

Android Icon Fonts Material and Holo iconic fonts. Source Material Extracted 433 Material Design icons from Google's Project Polymer website by Shreya

Evgeny Shishkin 223 Dec 27, 2022
Algorithm for mutual exclusion in a bidirectional ring network topology with unreliable communication channels.

Algorithm for mutual exclusion in a bidirectional ring network topology with unreliable communication channels

Bartlomiej Szal 0 Jan 13, 2022
Twidere-Android Twidere is a powerful twitter client for Android 1.6+ 1 , which gives you a full Holo experience and nearly full Twitter's feature.

Twidere for Android Material Design ready and feature rich Twitter/Mastodon/Fanfou app for Android 4.1+. Enjoy Fediverse now! Twidere-Android is maint

Twidere Project 2.7k Jan 2, 2023
An Android app that gives you a password generated by a given phrase with a custom algorithm, it also has password and biometric security.

An Android app that gives you a password generated by a given phrase with a custom algorithm, it also has password and biometric security.

Marcos Ariel Paccor 1 May 23, 2022
CreditCardHelper 🖊️ A Jetpack-Compose library providing useful credit card utilities such as card type recognition and TextField ViewTransformations

CreditCardHelper ??️ A Jetpack-Compose library providing useful credit card utilities such as card type recognition and TextField ViewTransformations

Stelios Papamichail 18 Dec 19, 2022
Utility for developers and QAs what helps minimize time wasting on writing the same data for testing over and over again. Made by Stfalcon

Stfalcon Fixturer A Utility for developers and QAs which helps minimize time wasting on writing the same data for testing over and over again. You can

Stfalcon LLC 31 Nov 29, 2021
DNS over HTTPS / DNS over Tor / DNSCrypt client, firewall, and connection tracker for Android.

RethinkDNS + Firewall for Android An OpenSnitch-inspired firewall and network monitor + a pi-hole-inspired DNS over HTTPS client with blocklists. In o

null 1.1k Jan 5, 2023
Powerful custom Android Camera with granular control over the video quality and filesize, restricting recordings to landscape only.

LandscapeVideoCamera Highly flexible Android Camera which offers granular control over the video quality and filesize, while restricting recordings to

Jeroen Mols 1.2k Nov 22, 2022
Powerful custom Android Camera with granular control over the video quality and filesize, restricting recordings to landscape only.

LandscapeVideoCamera Highly flexible Android Camera which offers granular control over the video quality and filesize, while restricting recordings to

Jeroen Mols 1.2k Dec 29, 2022
Powerful custom Android Camera with granular control over the video quality and filesize, restricting recordings to landscape only.

LandscapeVideoCamera Highly flexible Android Camera which offers granular control over the video quality and filesize, while restricting recordings to

Jeroen Mols 1.2k Nov 22, 2022
The sample App implements type safe SQL by JOOQ & DB version control by Flyway

The sample App implements type safe SQL by JOOQ & DB version control by Flyway Setup DB(PostgreSQL) $ docker compose up -d Migration $ ./gradlew flywa

t-kurihara 3 Jan 1, 2022
FixedHeaderTableLayout is a powerful Android library for displaying complex data structures and rendering tabular data composed of rows, columns and cells with scrolling and zooming features. FixedHeaderTableLayout is similar in construction and use as to Android's TableLayout

FixedHeaderTableLayout is a powerful Android library for displaying complex data structures and rendering tabular data composed of rows, columns and cells with scrolling and zooming features. FixedHeaderTableLayout is similar in construction and use as to Android's TableLayout

null 33 Dec 8, 2022
Here you can try out Kotlin Multiplatform and Jetpack Compose with some other cutting-edge technologies.

wire The Wire is a Kotlin Multiplatform sample project, currently supporting Android and Windows. Tools And Technolagies Architecture: MVVM MultiThrea

Ali Rezaiyan 9 Aug 16, 2022