Commit 5f3d8976 authored by axet's avatar axet 🍄

add RTL support

parent b339e22f
......@@ -280,4 +280,36 @@ final class ZLTextElementAreaVector {
}
return null;
}
public boolean swapRtl(boolean rtlMode, int first, int end) {
boolean detected = false;
for (int i = first; i < end; i++) {
ZLTextElementArea e = myAreas.get(i);
boolean b = ZLTextView.isRtl(e.Element.toString());
if (rtlMode != b) {
int rangeStart = i;
int rangeEnd = i;
while (rangeEnd < end && b == ZLTextView.isRtl(myAreas.get(rangeEnd).Element.toString()))
rangeEnd++;
int rangeLast = rangeEnd - 1;
e = myAreas.get(rtlMode ? rangeLast : rangeStart);
int XStart = e.XStart;
ZLTextElementArea prev = null;
for (int k = rtlMode ? rangeStart : rangeLast; rtlMode ? k <= rangeLast : k >= rangeStart; k += rtlMode ? 1 : -1) {
detected = true;
e = myAreas.get(k);
if (prev != null)
XStart += prev.XStart - e.XEnd;
prev = e;
int XWidth = e.XEnd - e.XStart;
int XEnd = XStart + XWidth;
e = new ZLTextElementArea(e.ParagraphIndex, e.ElementIndex, e.CharIndex, e.Length, e.isLastInElement(), e.AddHyphenationSign, e.ChangeStyle, e.Style, e.Element, XStart, XEnd, e.YStart, e.YEnd, e.ColumnIndex);
myAreas.set(k, e);
XStart = XEnd;
}
i = rangeLast;
}
}
return detected;
}
}
......@@ -60,12 +60,27 @@ public abstract class ZLTextView extends ZLTextViewBase {
private ZLTextRegion.Soul myOutlinedRegionSoul;
private boolean myShowOutline = true;
public boolean rtlDetected = false;
public boolean rtlMode = false;
private final ZLTextSelection mySelection = new ZLTextSelection(this);
private final Set<ZLTextHighlighting> myHighlightings =
Collections.synchronizedSet(new TreeSet<ZLTextHighlighting>());
private CursorManager myCursorManager;
public static boolean isRtl(String s) {
for(char c : s.toCharArray()) {
switch(Character.getDirectionality(c)) {
case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE:
return true;
}
}
return false;
}
public ZLTextView(ZLApplication application) {
super(application);
}
......@@ -85,6 +100,10 @@ public abstract class ZLTextView extends ZLTextViewBase {
if (paragraphsNumber > 0) {
myCurrentPage.moveStartCursor(myCursorManager.get(0));
}
String ln = myModel.getLanguage();
if (ln != null)
rtlMode = ln.startsWith("ar") || ln.startsWith("ps") || ln.startsWith("fa") || ln.startsWith("iw") || ln.startsWith("he");
rtlDetected = false;
}
Application.getViewWidget().reset();
}
......@@ -360,7 +379,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
}
final ZLTextElementArea area = mySelection.getStartArea(page);
if (area != null) {
return new ZLTextSelection.Point(area.XStart, (area.YStart + area.YEnd) / 2);
return new ZLTextSelection.Point(rtlMode ? area.XEnd : area.XStart, (area.YStart + area.YEnd) / 2);
}
} else {
if (mySelection.hasPartAfterPage(page)) {
......@@ -368,7 +387,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
}
final ZLTextElementArea area = mySelection.getEndArea(page);
if (area != null) {
return new ZLTextSelection.Point(area.XEnd, (area.YStart + area.YEnd) / 2);
return new ZLTextSelection.Point(rtlMode ? area.XStart: area.XEnd, (area.YStart + area.YEnd) / 2);
}
}
return null;
......@@ -463,19 +482,21 @@ public abstract class ZLTextView extends ZLTextViewBase {
final ArrayList<ZLTextLineInfo> lineInfos = page.LineInfos;
final int[] labels = new int[lineInfos.size() + 1];
int x = getLeftMargin();
int x = (rtlMode ? ((page.twoColumnView() ? page.getTextWidth() * 2 + getSpaceBetweenColumns() : page.getTextWidth()) + getLeftMargin()) : getLeftMargin());
int y = getTopMargin();
int index = 0;
int columnIndex = 0;
ZLTextLineInfo previousInfo = null;
for (ZLTextLineInfo info : lineInfos) {
info.adjust(previousInfo);
int first = page.TextElementMap.size();
prepareTextLine(page, info, x, y, columnIndex);
rtlDetected |= page.TextElementMap.swapRtl(rtlMode, first, page.TextElementMap.size());
y += info.Height + info.Descent + info.VSpaceAfter;
labels[++index] = page.TextElementMap.size();
if (index == page.Column0Height) {
y = getTopMargin();
x += page.getTextWidth() + getSpaceBetweenColumns();
x += (page.getTextWidth() + getSpaceBetweenColumns()) * (rtlMode ? -1 : 1);
columnIndex = 1;
}
previousInfo = info;
......@@ -483,7 +504,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
final List<ZLTextHighlighting> hilites = findHilites(page);
x = getLeftMargin();
x = rtlMode ? ((page.twoColumnView() ? page.getTextWidth() * 2 + getSpaceBetweenColumns() : page.getTextWidth()) + getLeftMargin()) : getLeftMargin();
y = getTopMargin();
index = 0;
for (ZLTextLineInfo info : lineInfos) {
......@@ -492,7 +513,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
++index;
if (index == page.Column0Height) {
y = getTopMargin();
x += page.getTextWidth() + getSpaceBetweenColumns();
x += (page.getTextWidth() + getSpaceBetweenColumns()) * (rtlMode ? -1 : 1);
}
}
......@@ -1255,15 +1276,15 @@ public abstract class ZLTextView extends ZLTextViewBase {
final boolean endOfParagraph = info.isEndOfParagraph();
boolean wordOccurred = false;
boolean changeStyle = true;
x += info.LeftIndent;
x += info.LeftIndent * (rtlMode ? -1 : 1);
final int maxWidth = page.getTextWidth();
switch (getTextStyle().getAlignment()) {
case ZLTextAlignmentType.ALIGN_RIGHT:
x += maxWidth - getTextStyle().getRightIndent(metrics()) - info.Width;
x += (maxWidth - getTextStyle().getRightIndent(metrics()) - info.Width) * (rtlMode ? 0 : 1);
break;
case ZLTextAlignmentType.ALIGN_CENTER:
x += (maxWidth - getTextStyle().getRightIndent(metrics()) - info.Width) / 2;
x += ((maxWidth - getTextStyle().getRightIndent(metrics()) - info.Width) / 2) * (rtlMode ? -1 : 1);
break;
case ZLTextAlignmentType.ALIGN_JUSTIFY:
if (!endOfParagraph && (paragraphCursor.getElement(info.EndElementIndex) != ZLTextElement.AfterParagraph)) {
......@@ -1271,6 +1292,8 @@ public abstract class ZLTextView extends ZLTextViewBase {
}
break;
case ZLTextAlignmentType.ALIGN_LEFT:
x -= (maxWidth - getTextStyle().getLeftIndent(metrics()) - info.Width) * (rtlMode ? 1 : 0);
break;
case ZLTextAlignmentType.ALIGN_UNDEFINED:
break;
}
......@@ -1294,12 +1317,12 @@ public abstract class ZLTextView extends ZLTextViewBase {
true, // is last in element
false, // add hyphenation sign
false, // changed style
getTextStyle(), element, x, x + spaceLength, y, y, columnIndex
getTextStyle(), element, (rtlMode ? x-spaceLength : x), (rtlMode ? x : x + spaceLength), y, y, columnIndex
);
} else {
spaceElement = null;
}
x += spaceLength;
x += spaceLength * (rtlMode ? -1 : 1);
fullCorrection -= correction;
wordOccurred = false;
--spaceCounter;
......@@ -1318,7 +1341,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
true, // is last in element
false, // add hyphenation sign
changeStyle, getTextStyle(), element,
x, x + width - 1, y - height + 1, y + descent, columnIndex
(rtlMode ? x-width : x), (rtlMode ? x : x + width) - 1, y - height + 1, y + descent, columnIndex
));
changeStyle = false;
wordOccurred = true;
......@@ -1326,7 +1349,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
applyStyleChangeElement(element);
changeStyle = true;
}
x += width;
x += width * (rtlMode ? -1 : 1);
}
if (!endOfParagraph) {
final int len = info.EndCharIndex;
......@@ -1344,7 +1367,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
false, // is last in element
addHyphenationSign,
changeStyle, getTextStyle(), word,
x, x + width - 1, y - height + 1, y + descent, columnIndex
(rtlMode ? x-width : x), (rtlMode ? (x + 1) : (x + width - 1)), y - height + 1, y + descent, columnIndex
)
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment