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