Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rtl textrich taging #105

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 105 additions & 43 deletions Assets/RTLTMPro/Scripts/Runtime/FastStringBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,74 @@
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Text;
namespace RTLTMPro {
public class FastStringBuilder {
namespace RTLTMPro
{
public class FastStringBuilder
{
// Using fields to be as efficient as possible
private int length;
public int Length {
public int Length
{
get { return length; }
set {
set
{
if (value <= length) length = value;
}
}
private int[] array;
private int capacity;

public FastStringBuilder(int capacity) {
public FastStringBuilder(int capacity)
{
if (capacity < 0)
throw new ArgumentOutOfRangeException(nameof(capacity));

this.capacity = capacity;
array = new int[capacity];
}

public FastStringBuilder(string text) : this(text, text.Length) {
public FastStringBuilder(string text) : this(text, text.Length)
{
}

public FastStringBuilder(string text, int capacity) : this(capacity) {
public FastStringBuilder(string text, int capacity) : this(capacity)
{
SetValue(text);
}

public static implicit operator string(FastStringBuilder x) {
public static implicit operator string(FastStringBuilder x)
{
return x.ToString();
}

public static implicit operator FastStringBuilder(string x) {
public static implicit operator FastStringBuilder(string x)
{
return new FastStringBuilder(x);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Get(int index) {
public int Get(int index)
{
return array[index];
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Set(int index, int ch) {
public void Set(int index, int ch)
{
array[index] = ch;
}

public void SetValue(string text) {
public void SetValue(string text)
{
int len = 0;
length = text.Length;
EnsureCapacity(length, false);

for (int i = 0; i < text.Length; i++) {
for (int i = 0; i < text.Length; i++)
{
int unicode32CodePoint = char.ConvertToUtf32(text, i);
if (unicode32CodePoint > 0xffff) {
if (unicode32CodePoint > 0xffff)
{
i++;
}
array[len++] = unicode32CodePoint;
Expand All @@ -64,49 +78,57 @@ public class FastStringBuilder {
length = len;
}

public void SetValue(FastStringBuilder other) {
public void SetValue(FastStringBuilder other)
{
EnsureCapacity(other.length, false);
Copy(other.array, array);
length = other.length;
}

public void Append(int ch) {
public void Append(int ch)
{
length++;
if (capacity < length)
EnsureCapacity(length, true);

array[length - 1] = ch;
}

public void Append(char ch) {
public void Append(char ch)
{
length++;
if (capacity < length)
EnsureCapacity(length, true);

array[length - 1] = ch;
}

public void Insert(int pos, FastStringBuilder str, int offset, int count) {
public void Insert(int pos, FastStringBuilder str, int offset, int count)
{
if (str == this) throw new InvalidOperationException("You cannot pass the same string builder to insert");
if (count == 0) return;

length += count;
EnsureCapacity(length, true);

for (int i = length - count - 1; i >= pos; i--) {
for (int i = length - count - 1; i >= pos; i--)
{
array[i + count] = array[i];
}

for (int i = 0; i < count; i++) {
for (int i = 0; i < count; i++)
{
array[pos + i] = str.array[offset + i];
}
}

public void Insert(int pos, FastStringBuilder str) {
public void Insert(int pos, FastStringBuilder str)
{
Insert(pos, str, 0, str.length);
}

public void Insert(int pos, int ch) {
public void Insert(int pos, int ch)
{
length++;
EnsureCapacity(length, true);

Expand All @@ -116,10 +138,12 @@ public class FastStringBuilder {
array[pos] = ch;
}

public void RemoveAll(int character) {
public void RemoveAll(int character)
{
int j = 0; // write index
int i = 0; // read index
for (; i < length; i++) {
for (; i < length; i++)
{
if (array[i] == character) continue;

array[j] = array[i];
Expand All @@ -129,16 +153,20 @@ public class FastStringBuilder {
length = j;
}

public void Remove(int start, int length) {
for (int i = start; i < this.length - length; i++) {
public void Remove(int start, int length)
{
for (int i = start; i < this.length - length; i++)
{
array[i] = array[i + length];
}

this.length -= length;
}

public void Reverse(int startIndex, int length) {
for (int i = 0; i < length / 2; i++) {
public void Reverse(int startIndex, int length)
{
for (int i = 0; i < length / 2; i++)
{
int firstIndex = startIndex + i;
int secondIndex = startIndex + length - i - 1;

Expand All @@ -150,24 +178,30 @@ public class FastStringBuilder {
}
}

public void Reverse() {
public void Reverse()
{
Reverse(0, length);
}

public void Substring(FastStringBuilder output, int start, int length) {
public void Substring(FastStringBuilder output, int start, int length)
{
output.length = 0;
for (int i = 0; i < length; i++)
output.Append(array[start + i]);
}

public override string ToString() {
public string get_str(int index)
{
return char.ConvertFromUtf32(array[index]);
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
for (int i = 0; i < length; i++)
{
sb.Append(char.ConvertFromUtf32(array[i]));
}
return sb.ToString();
}

public string ToDebugString()
{
StringBuilder sb = new StringBuilder();
Expand All @@ -178,14 +212,36 @@ public string ToDebugString()
}
return sb.ToString();
}

public void Replace(int oldChar, int newChar) {
for (int i = 0; i < length; i++) {
public void Replace(int oldChar, int newChar)
{
for (int i = 0; i < length; i++)
{
if (array[i] == oldChar)
array[i] = newChar;
}
}

public void ReplaceOne(int oldChar, int newChar)
{
for (int i = 0; i < length; i++)
{
if (array[i] == oldChar)
{
array[i] = newChar;
break;
}
}
}
public void ReplaceOne(int oldChar, int newChar, int start)
{
for (int i = start; i < length; i++)
{
if (array[i] == oldChar)
{
array[i] = newChar;
break;
}
}
}
public void Replace(FastStringBuilder oldStr, FastStringBuilder newStr)
{
for (int i = 0; i < length; i++)
Expand Down Expand Up @@ -251,11 +307,13 @@ public void Replace(FastStringBuilder oldStr, FastStringBuilder newStr)
}
}

public void Clear() {
public void Clear()
{
length = 0;
}

private void EnsureCapacity(int cap, bool keepValues) {
private void EnsureCapacity(int cap, bool keepValues)
{
if (capacity >= cap)
return;

Expand All @@ -265,16 +323,20 @@ public void Replace(FastStringBuilder oldStr, FastStringBuilder newStr)
while (capacity < cap)
capacity *= 2;

if (keepValues) {
if (keepValues)
{
int[] newArray = new int[capacity];
Copy(array, newArray);
array = newArray;
} else {
}
else
{
array = new int[capacity];
}
}

private static void Copy(int[] src, int[] dst) {
private static void Copy(int[] src, int[] dst)
{
for (int i = 0; i < src.Length; i++)
dst[i] = src[i];
}
Expand Down
52 changes: 48 additions & 4 deletions Assets/RTLTMPro/Scripts/Runtime/GlyphFixer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,47 @@ public static class GlyphFixer
[(char)EnglishNumbers.Nine] = (char)HinduNumbers.Nine,
};

public static void Fix_Taged(FastStringBuilder output, FastStringBuilder originalshape, bool farsi)
{

FixLa(output);
FixLa(originalshape);
int j = 0; // write index
for (int i = 0; i < output.Length; i++)
{
int iChar = output.Get(i);

if (iChar < 0xFFFF && TextUtils.IsGlyphFixedArabicCharacter((char)iChar))
{
int jChar = originalshape.Get(j);

if (jChar < 0xFFFF && TextUtils.IsGlyphFixedArabicCharacter((char)jChar))
{
output.ReplaceOne(iChar, jChar, i);
j++;
}
}
}

}
public static void FixLa(FastStringBuilder str)
{
for (int i = 0; i < str.Length; i++)
{
int iChar = str.Get(i);
if (iChar < 0xFFFF && TextUtils.IsGlyphFixedArabicCharacter((char)iChar))
{

string jStr = iChar.ToString("X");
if (jStr == "FEFC" || jStr == "FEFB")
{
str.ReplaceOne(iChar, 0xFE8E, i);
str.Insert(i + 1, 0xFEE0);
}

}
}
}
/// <summary>
/// Fixes the shape of letters based on their position.
/// </summary>
Expand Down Expand Up @@ -77,10 +117,12 @@ public static void Fix(FastStringBuilder input, FastStringBuilder output, bool p
if (IsMiddleLetter(input, i))
{
output.Set(i, (char)(converted + 3));
} else if (IsFinishingLetter(input, i))
}
else if (IsFinishingLetter(input, i))
{
output.Set(i, (char)(converted + 1));
} else if (IsLeadingLetter(input, i))
}
else if (IsLeadingLetter(input, i))
{
output.Set(i, (char)(converted + 2));
} else
Expand All @@ -102,7 +144,8 @@ public static void Fix(FastStringBuilder input, FastStringBuilder output, bool p
if (fixTextTags)
{
FixNumbersOutsideOfTags(output, farsi);
} else
}
else
{
FixNumbers(output, farsi);
}
Expand Down Expand Up @@ -212,7 +255,8 @@ public static void FixNumbersOutsideOfTags(FastStringBuilder text, bool farsi)
if ((j == i + 1 && jChar == ' ') || jChar == '<')
{
break;
} else if (jChar == '>')
}
else if (jChar == '>')
{
i = j;
sawValidTag = true;
Expand Down
Loading