summaryrefslogtreecommitdiffstats
path: root/tools/layoutlib
diff options
context:
space:
mode:
authorDudy Kohen <kohen.d@gmail.com>2010-06-18 10:48:17 -0400
committerSteve Kondik <shade@chemlab.org>2010-06-30 21:35:22 -0400
commit1b0aca31c3e03a5a323276cd15a8df4203a1792c (patch)
tree36afd8be86105e713a889d50f8beb5d6cf1e14de /tools/layoutlib
parent97f215132cd1085f7e05e165cce1c79590d85beb (diff)
downloadframeworks_base-1b0aca31c3e03a5a323276cd15a8df4203a1792c.zip
frameworks_base-1b0aca31c3e03a5a323276cd15a8df4203a1792c.tar.gz
frameworks_base-1b0aca31c3e03a5a323276cd15a8df4203a1792c.tar.bz2
Improved BiDi text rendering.
Diffstat (limited to 'tools/layoutlib')
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Canvas.java159
1 files changed, 141 insertions, 18 deletions
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas.java b/tools/layoutlib/bridge/src/android/graphics/Canvas.java
index d5d315e..08092a2 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas.java
@@ -49,6 +49,8 @@ import javax.microedition.khronos.opengles.GL;
*/
public class Canvas extends _Original_Canvas {
+ private static final char FIRST_RIGHT_TO_LEFT = '\u0590';
+ private static final char LAST_RIGHT_TO_LEFT = '\u07b1';
private BufferedImage mBufferedImage;
private final Stack<Graphics2D> mGraphicsStack = new Stack<Graphics2D>();
private final ILayoutLog mLogger;
@@ -644,11 +646,111 @@ public class Canvas extends _Original_Canvas {
getGraphics2d().scale(sx, sy);
}
- /* (non-Javadoc)
- * @see android.graphics.Canvas#drawText(char[], int, int, float, float, android.graphics.Paint)
- */
- @Override
- public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
+ public char[] bidiProcess(char[] text,int start,int src_count) {
+ String str;
+ String oldstr=new String(text,start,src_count);
+ boolean hasbidi=false;
+ int strlen=oldstr.length();
+ char[] ca=new char[strlen];
+
+ oldstr.getChars(0, strlen, ca, 0);
+ for (int i=0;i<oldstr.length();i++){
+ if (ca[i]>=FIRST_RIGHT_TO_LEFT&&ca[i]<=LAST_RIGHT_TO_LEFT){
+ hasbidi=true;
+ break;
+ }
+ }
+ if (hasbidi) {
+ char[] ca2=new char[strlen];
+ int count=0,srcindex=0;
+ boolean rtlmode=true;
+ for (int i=0;i<strlen;i++){
+ srcindex=strlen-1-i;
+ if (ca[srcindex]>=FIRST_RIGHT_TO_LEFT&&ca[srcindex]<=LAST_RIGHT_TO_LEFT){
+ ca2[i]=ca[srcindex];
+ rtlmode=true;
+ }
+ else {
+ srcindex=strlen-1-i;
+ if (count==0) {
+ if (ca[srcindex]<='\u002f' ||
+ (ca[srcindex]>'\u0039' && ca[srcindex]<='\u0040') ||
+ (ca[srcindex]>'\u005a' && ca[srcindex]<='\u0060')||
+ (ca[srcindex]>'\u007a' && ca[srcindex]<='\u00BF')) {
+
+ if (rtlmode){
+ switch (ca[srcindex]) {
+ case '[':
+ ca2[i]=']';
+ break;
+ case ']':
+ ca2[i]='[';
+ break;
+ case '}':
+ ca2[i]='{';
+ break;
+ case '{':
+ ca2[i]='}';
+ break;
+ case '(':
+ ca2[i]=')';
+ break;
+ case ')':
+ ca2[i]='(';
+ break;
+ case '>':
+ ca2[i]='<';
+ break;
+ case '<':
+ ca2[i]='>';
+ break;
+ default:
+ ca2[i]=ca[srcindex];
+ break;
+ }
+ } else ca2[i]=ca[srcindex];
+ } else {
+
+ while (((srcindex-count)>=0)&&(ca[srcindex-count]<FIRST_RIGHT_TO_LEFT)){
+ count++;
+ }
+ int index=0;
+ int punctuation_marks=0;
+
+ while ((srcindex-(count)>=0) &&
+ (ca[srcindex-(count-1)]<='\u002f' ||
+ (ca[srcindex-(count-1)]>'\u0039' && ca[srcindex-(count-1)]<='\u0040') ||
+ (ca[srcindex-(count-1)]>'\u005a' && ca[srcindex-(count-1)]<='\u0060')||
+ (ca[srcindex-(count-1)]>'\u007a' && ca[srcindex-(count-1)]<='\u00BF'))){
+ ca2[i+(count-1)]=ca[srcindex-(count-1)];
+ count--;
+ punctuation_marks++;
+ }
+
+ while (count>0){
+ ca2[i+index]=ca[srcindex-(count-1)];
+ count--;
+ index++;
+ }
+ count=index+punctuation_marks-1;
+ }
+ }
+ else {
+ count--;
+ }
+ rtlmode=false;
+ }
+ }
+ str=new String(ca2);
+ } else
+ {
+ str=new String(oldstr);
+ }
+ return str.toCharArray();
+
+ }
+
+ public void drawText(char[] text, int index, int count, float x, float y, Paint paint, boolean bidi) {
// WARNING: the logic in this method is similar to Paint.measureText.
// Any change to this method should be reflected in Paint.measureText
Graphics2D g = getGraphics2d();
@@ -681,21 +783,29 @@ public class Canvas extends _Original_Canvas {
FontInfo mainFont = fonts.get(0);
int i = index;
int lastIndex = index + count;
+ char[] bidiText;
+ if (bidi) {
+ bidiText=bidiProcess(text,index,count);
+ i=0;
+ lastIndex=count;
+ } else {
+ bidiText=text;
+ }
while (i < lastIndex) {
// always start with the main font.
- int upTo = mainFont.mFont.canDisplayUpTo(text, i, lastIndex);
+ int upTo = mainFont.mFont.canDisplayUpTo(bidiText, i, lastIndex);
if (upTo == -1) {
// draw all the rest and exit.
g.setFont(mainFont.mFont);
- g.drawChars(text, i, lastIndex - i, (int)x, (int)y);
+ g.drawChars(bidiText, i, lastIndex - i, (int)x, (int)y);
return;
} else if (upTo > 0) {
// draw what's possible
g.setFont(mainFont.mFont);
- g.drawChars(text, i, upTo - i, (int)x, (int)y);
+ g.drawChars(bidiText, i, upTo - i, (int)x, (int)y);
// compute the width that was drawn to increase x
- x += mainFont.mMetrics.charsWidth(text, i, upTo - i);
+ x += mainFont.mMetrics.charsWidth(bidiText, i, upTo - i);
// move index to the first non displayed char.
i = upTo;
@@ -715,15 +825,15 @@ public class Canvas extends _Original_Canvas {
// need to check that the font can display the character. We test
// differently if the char is a high surrogate.
- int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
- upTo = fontInfo.mFont.canDisplayUpTo(text, i, i + charCount);
+ int charCount = Character.isHighSurrogate(bidiText[i]) ? 2 : 1;
+ upTo = fontInfo.mFont.canDisplayUpTo(bidiText, i, i + charCount);
if (upTo == -1) {
// draw that char
g.setFont(fontInfo.mFont);
- g.drawChars(text, i, charCount, (int)x, (int)y);
+ g.drawChars(bidiText, i, charCount, (int)x, (int)y);
// update x
- x += fontInfo.mMetrics.charsWidth(text, i, charCount);
+ x += fontInfo.mMetrics.charsWidth(bidiText, i, charCount);
// update the index in the text, and move on
i += charCount;
@@ -736,13 +846,13 @@ public class Canvas extends _Original_Canvas {
// in case no font can display the char, display it with the main font.
// (it'll put a square probably)
if (foundFont == false) {
- int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
+ int charCount = Character.isHighSurrogate(bidiText[i]) ? 2 : 1;
g.setFont(mainFont.mFont);
- g.drawChars(text, i, charCount, (int)x, (int)y);
+ g.drawChars(bidiText, i, charCount, (int)x, (int)y);
// measure it to advance x
- x += mainFont.mMetrics.charsWidth(text, i, charCount);
+ x += mainFont.mMetrics.charsWidth(bidiText, i, charCount);
// and move to the next chars.
i += charCount;
@@ -755,6 +865,13 @@ public class Canvas extends _Original_Canvas {
}
/* (non-Javadoc)
+ * @see android.graphics.Canvas#drawText(char[], int, int, float, float, android.graphics.Paint)
+ */
+ @Override
+ public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
+ drawText(text, index, count, x, y, paint, true);
+ }
+ /* (non-Javadoc)
* @see android.graphics.Canvas#drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint)
*/
@Override
@@ -1140,7 +1257,10 @@ public class Canvas extends _Original_Canvas {
public void drawTextOnPath(char[] text, int index, int count, Path path, float offset,
float offset2, Paint paint) {
// TODO Auto-generated method stub
- super.drawTextOnPath(text, index, count, path, offset, offset2, paint);
+ int i = 0;
+ char[] bidiText;
+ bidiText=bidiProcess(text,index,count);
+ super.drawTextOnPath(bidiText, i, count, path, offset, offset2, paint);
}
/* (non-Javadoc)
@@ -1149,7 +1269,10 @@ public class Canvas extends _Original_Canvas {
@Override
public void drawTextOnPath(String text, Path path, float offset, float offset2, Paint paint) {
// TODO Auto-generated method stub
- super.drawTextOnPath(text, path, offset, offset2, paint);
+ int i = 0;
+ String bidiText;
+ bidiText=new String(bidiProcess(text.toCharArray(),0,text.length()));
+ super.drawTextOnPath(bidiText, path, offset, offset2, paint);
}
/* (non-Javadoc)