1SheenBidi
2=========
3[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
4[![Travis-CI Build Status](https://api.travis-ci.org/Tehreer/SheenBidi.svg?branch=master)](https://travis-ci.org/Tehreer/SheenBidi)
5[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/k2vvegcdqsb9ld5a?svg=true)](https://ci.appveyor.com/project/mta452/sheenbidi)
6[![Coverage Status](https://coveralls.io/repos/github/Tehreer/SheenBidi/badge.svg?branch=master)](https://coveralls.io/github/Tehreer/SheenBidi)
7
8SheenBidi implements Unicode Bidirectional Algorithm available at http://www.unicode.org/reports/tr9. It is a sophisticated implementaion which provides the developers an easy way to use UBA in their applications.
9
10Here are some of the advantages of SheenBidi.
11
12* Object based.
13* Optimized to the core.
14* Designed to be thread safe.
15* Lightweight API for interaction.
16* Supports UTF-8, UTF-16 and UTF-32 encodings.
17
18## API
19<img src="https://user-images.githubusercontent.com/2664112/39663208-716af1c4-5088-11e8-855c-ababe3e58c58.png" width="350">
20The above screenshot depicts a visual representation of the API on a sample text.
21
22### SBCodepointSequence
23It works as a code point decoder by accepting a string buffer in specified encoding.
24
25### SBAlgorithm
26It provides bidirectional type of each code unit in source string. Paragraph boundaries can be quried from it as determined by rule [P1](https://www.unicode.org/reports/tr9/#P1). Individual paragraph objects can be created from it by explicitly specifying the base level or deriving it from rules [P2](https://www.unicode.org/reports/tr9/#P2)-[P3](https://www.unicode.org/reports/tr9/#P3).
27
28### SBParagraph
29It represents a single paragraph of text processed with rules [X1](https://www.unicode.org/reports/tr9/#X1)-[I2](https://www.unicode.org/reports/tr9/#I2). It provides resolved embedding levels of all the code units of a paragraph.
30
31### SBLine
32It represents a single line of text processed with rules [L1](https://www.unicode.org/reports/tr9/#L1)-[L2](https://www.unicode.org/reports/tr9/#L2). However, it provides reordered level runs instead of reordered characters.
33
34### SBRun
35It represents a sequence of characters which have the same embedding level. The direction of a run would be right-to-left, if its embedding level is odd.
36
37### SBMirrorLocator
38It provides the facility to find out the mirrored characters in a line as determined by rule [L4](https://www.unicode.org/reports/tr9/#L4).
39
40### SBScriptLocator
41Not directly related to UBA but can be useful for text shaping. It provides the facility to find out the script runs as specified in [UAX #24](https://www.unicode.org/reports/tr24/).
42
43## Dependency
44SheenBidi does not depend on any external library. It only uses standard C library headers ```stddef.h```, ```stdint.h``` and ```stdlib.h```.
45
46## Configuration
47The configuration options are available in `Headers/SBConfig.h`.
48
49* ```SB_CONFIG_LOG``` logs every activity performed in order to apply bidirectional algorithm.
50* ```SB_CONFIG_UNITY``` builds the library as a single module and lets the compiler make decisions to inline functions.
51
52## Compiling
53SheenBidi can be compiled with any C compiler. The best way for compiling is to add all the files in an IDE and hit build. The only thing to consider however is that if ```SB_CONFIG_UNITY``` is enabled then only ```Source/SheenBidi.c``` should be compiled.
54
55## Example
56Here is a simple example written in C11.
57
58```c
59#include <stdint.h>
60#include <stdio.h>
61#include <string.h>
62
63#include <SheenBidi.h>
64
65int main(int argc, const char * argv[]) {
66    /* Create code point sequence for a sample bidirectional text. */
67    const char *bidiText = "یہ ایک )car( ہے۔";
68    SBCodepointSequence codepointSequence = { SBStringEncodingUTF8, (void *)bidiText, strlen(bidiText) };
69
70    /* Extract the first bidirectional paragraph. */
71    SBAlgorithmRef bidiAlgorithm = SBAlgorithmCreate(&codepointSequence);
72    SBParagraphRef firstParagraph = SBAlgorithmCreateParagraph(bidiAlgorithm, 0, INT32_MAX, SBLevelDefaultLTR);
73    SBUInteger paragraphLength = SBParagraphGetLength(firstParagraph);
74
75    /* Create a line consisting of whole paragraph and get its runs. */
76    SBLineRef paragraphLine = SBParagraphCreateLine(firstParagraph, 0, paragraphLength);
77    SBUInteger runCount = SBLineGetRunCount(paragraphLine);
78    const SBRun *runArray = SBLineGetRunsPtr(paragraphLine);
79
80    /* Log the details of each run in the line. */
81    for (SBUInteger i = 0; i < runCount; i++) {
82        printf("Run Offset: %ld\n", (long)runArray[i].offset);
83        printf("Run Length: %ld\n", (long)runArray[i].length);
84        printf("Run Level: %ld\n\n", (long)runArray[i].level);
85    }
86
87    /* Create a mirror locator and load the line in it. */
88    SBMirrorLocatorRef mirrorLocator = SBMirrorLocatorCreate();
89    SBMirrorLocatorLoadLine(mirrorLocator, paragraphLine, (void *)bidiText);
90    const SBMirrorAgent *mirrorAgent = SBMirrorLocatorGetAgent(mirrorLocator);
91
92    /* Log the details of each mirror in the line. */
93    while (SBMirrorLocatorMoveNext(mirrorLocator)) {
94        printf("Mirror Index: %ld\n", (long)mirrorAgent->index);
95        printf("Actual Code Point: %ld\n", (long)mirrorAgent->codepoint);
96        printf("Mirrored Code Point: %ld\n\n", (long)mirrorAgent->mirror);
97    }
98
99    /* Release all objects. */
100    SBMirrorLocatorRelease(mirrorLocator);
101    SBLineRelease(paragraphLine);
102    SBParagraphRelease(firstParagraph);
103    SBAlgorithmRelease(bidiAlgorithm);
104
105    return 0;
106}
107```
108