Android中希伯来语元音点的对齐
我想使用Canvas.drawText界面显示带有元音点(nikkud)的希伯来文文本。元音点出现错位,如下图所示,使用摩托罗拉Defy+设备拍摄: hiriq在resh和yod之间,holam在vav和nun之间。 我已经将rtl代码(\u200F)添加到字符串的两端,没有乐趣。 我知道有一些应用程序已经解决了这个问题,比如Smart Siddur。基于文本的应用程序和基于图形的应用程序之间有区别吗?我认为在这两种情况下,相同的引擎呈现文本。我想我可以拆分字符串并分别放置元音,但这似乎非常痛苦,而且无法扩展。Android中希伯来语元音点的对齐,android,text,hebrew,Android,Text,Hebrew,我想使用Canvas.drawText界面显示带有元音点(nikkud)的希伯来文文本。元音点出现错位,如下图所示,使用摩托罗拉Defy+设备拍摄: hiriq在resh和yod之间,holam在vav和nun之间。 我已经将rtl代码(\u200F)添加到字符串的两端,没有乐趣。 我知道有一些应用程序已经解决了这个问题,比如Smart Siddur。基于文本的应用程序和基于图形的应用程序之间有区别吗?我认为在这两种情况下,相同的引擎呈现文本。我想我可以拆分字符串并分别放置元音,但这似乎非常痛
TIA提供任何线索。这可能是您使用的字体有问题,因为您也可能在台式计算机上重现相同的问题。尽管安卓系统本身现在有希伯来文的标志符号,但供应商之间有很大的差异,所以即使它在一台设备上运行良好,也不能在其他所有设备上运行良好
我的建议是通过提供自己的字体来解决这个问题。例如,您可以使用来自的字体,这些字体是免费的,并且大多数已知的字体足以支持希伯来语元音点 这可能是您使用的字体的问题,因为您也可能在桌面计算机上重现相同的问题。尽管安卓系统本身现在有希伯来文的标志符号,但供应商之间有很大的差异,所以即使它在一台设备上运行良好,也不能在其他所有设备上运行良好
我的建议是通过提供自己的字体来解决这个问题。例如,您可以使用来自的字体,这些字体是免费的,并且大多数已知的字体足以支持希伯来语元音点 好吧,下面的方法很有效。我仍然不明白为什么我必须实施它,但这确实有效
package com.lomda.ong2;
import java.util.HashMap;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Typeface;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.Log;
// render Hebrew strings with diacritic marks
//
public class HebRender {
Paint paint;
HashMap<String, Integer> spaces;
String charString;
String prevChar = "";
final String TAG = "HebRender";
public HebRender(Context svContext){
paint = new Paint();
Typeface t = Typeface.createFromAsset(svContext.getAssets(),"fonts/SimpleCLM-Bold.ttf");
//Typeface t = Typeface.createFromAsset(svContext.getAssets(),"fonts/gisha.ttf");
paint.setTypeface(t);
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(48);
paint.setAntiAlias(true);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setTextAlign(Align.CENTER);
}
public void drawText( Canvas canvas, String word, Point locate, int color) {
Rect bounds = new Rect();
Rect prevBounds = new Rect(0,0,0,0);
paint.getTextBounds(word, 0, word.length(), bounds);
paint.setColor(color);
int wordWidth = bounds.width();
// move to right edge (parameter is center)
locate.x += wordWidth/2;
// initialize bounds of individual characters
bounds = new Rect(0,0,0,0);
// for each character
for (int i = 0; i < word.length(); i++) {
// locate and write letter
char c = word.charAt(i);
charString = String.valueOf(c);
if (c >= 1488 && c <=1514) {// is in consonant range
paint.getTextBounds(charString, 0, charString.length(), bounds); // get current char dimensions
if (!prevChar.equals("")) {
int moveOver = bounds.width()/2 + prevBounds.width()/2 + (int) paint.getTextSize()/10;
locate.x -= moveOver;
}
Log.d(TAG, String.format("Char: %s, Prev char width: %d, char width: %d", charString, prevBounds.width(), bounds.width()));
canvas.drawText(charString, locate.x, locate.y, paint);
prevChar = charString;
prevBounds.set(bounds); // save previous dimensions
} else {// for each diacritic locate and write
canvas.drawText(charString, locate.x + getOffset(c, bounds.width()), locate.y, paint);
}
}
}
// some diacritic marks need to be moved
private int getOffset(char c, int charWidth) {
int offset = 0;
switch (c){
case 0x05C1: // shin dot
offset = charWidth/2;
break;
case 0x05C2: // sin dot
offset = -charWidth/2;
break;
case 0x05BC: // dagesh
offset = findDagesh(c, charWidth);
break;
case 0x05B9: // holam
offset = -(3*charWidth/5);
break;
}
return offset;
}
// move dagesh around for certain characters
private int findDagesh(char c, int charWidth) {
int offset = 0;
if (prevChar.equals("ג")) {
offset = Math.min(2, -charWidth/3);
} else if (prevChar.equals("ו") ||prevChar.equals("ז") || prevChar.equals("י")){
offset = Math.min(7, -7*charWidth/10);
} else if (prevChar.equals("ע") || prevChar.equals("ש") ) {
offset = Math.max(1, charWidth/3);
} else if (prevChar.equals("פ")){
offset = Math.max(2, charWidth/3);
}
return offset;
}
package com.lomda.ong2;
导入java.util.HashMap;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.Paint.FontMetricsInt;
导入android.graphics.Typeface;
导入android.graphics.Paint.Align;
导入android.graphics.Paint.FontMetrics;
导入android.graphics.Point;
导入android.graphics.Rect;
导入android.util.Log;
//用变音符号呈现希伯来语字符串
//
公共类希布伦德{
油漆;
HashMap空间;
字符串字符串;
字符串prevChar=“”;
最后一个字符串标记=“HebRender”;
公共HebRender(上下文svContext){
油漆=新油漆();
Typeface t=Typeface.createFromAsset(svContext.getAssets(),“font/simplecm Bold.ttf”);
//Typeface t=Typeface.createFromAsset(svContext.getAssets(),“fonts/gisha.ttf”);
油漆。设置字体(t);
绘制.设置样式(绘制.样式.填充);
油漆.尺寸(48);
paint.setAntiAlias(真);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setTextAlign(Align.CENTER);
}
公共void drawText(画布、字符串字、点定位、int颜色){
Rect bounds=new Rect();
Rect prevBounds=新的Rect(0,0,0,0);
paint.getTextBounds(word,0,word.length(),bounds);
油漆。设置颜色(颜色);
int wordWidth=bounds.width();
//移动到右边缘(参数为“中心”)
locate.x+=wordWidth/2;
//初始化单个字符的边界
边界=新的矩形(0,0,0,0);
//对于每个字符
for(int i=0;i 如果(c>=1488&&c那么,下面的方法行得通。我仍然不明白为什么要实现它,但这确实行得通
package com.lomda.ong2;
import java.util.HashMap;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Typeface;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.Log;
// render Hebrew strings with diacritic marks
//
public class HebRender {
Paint paint;
HashMap<String, Integer> spaces;
String charString;
String prevChar = "";
final String TAG = "HebRender";
public HebRender(Context svContext){
paint = new Paint();
Typeface t = Typeface.createFromAsset(svContext.getAssets(),"fonts/SimpleCLM-Bold.ttf");
//Typeface t = Typeface.createFromAsset(svContext.getAssets(),"fonts/gisha.ttf");
paint.setTypeface(t);
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(48);
paint.setAntiAlias(true);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setTextAlign(Align.CENTER);
}
public void drawText( Canvas canvas, String word, Point locate, int color) {
Rect bounds = new Rect();
Rect prevBounds = new Rect(0,0,0,0);
paint.getTextBounds(word, 0, word.length(), bounds);
paint.setColor(color);
int wordWidth = bounds.width();
// move to right edge (parameter is center)
locate.x += wordWidth/2;
// initialize bounds of individual characters
bounds = new Rect(0,0,0,0);
// for each character
for (int i = 0; i < word.length(); i++) {
// locate and write letter
char c = word.charAt(i);
charString = String.valueOf(c);
if (c >= 1488 && c <=1514) {// is in consonant range
paint.getTextBounds(charString, 0, charString.length(), bounds); // get current char dimensions
if (!prevChar.equals("")) {
int moveOver = bounds.width()/2 + prevBounds.width()/2 + (int) paint.getTextSize()/10;
locate.x -= moveOver;
}
Log.d(TAG, String.format("Char: %s, Prev char width: %d, char width: %d", charString, prevBounds.width(), bounds.width()));
canvas.drawText(charString, locate.x, locate.y, paint);
prevChar = charString;
prevBounds.set(bounds); // save previous dimensions
} else {// for each diacritic locate and write
canvas.drawText(charString, locate.x + getOffset(c, bounds.width()), locate.y, paint);
}
}
}
// some diacritic marks need to be moved
private int getOffset(char c, int charWidth) {
int offset = 0;
switch (c){
case 0x05C1: // shin dot
offset = charWidth/2;
break;
case 0x05C2: // sin dot
offset = -charWidth/2;
break;
case 0x05BC: // dagesh
offset = findDagesh(c, charWidth);
break;
case 0x05B9: // holam
offset = -(3*charWidth/5);
break;
}
return offset;
}
// move dagesh around for certain characters
private int findDagesh(char c, int charWidth) {
int offset = 0;
if (prevChar.equals("ג")) {
offset = Math.min(2, -charWidth/3);
} else if (prevChar.equals("ו") ||prevChar.equals("ז") || prevChar.equals("י")){
offset = Math.min(7, -7*charWidth/10);
} else if (prevChar.equals("ע") || prevChar.equals("ש") ) {
offset = Math.max(1, charWidth/3);
} else if (prevChar.equals("פ")){
offset = Math.max(2, charWidth/3);
}
return offset;
}
package com.lomda.ong2;
导入java.util.HashMap;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.Paint.FontMetricsInt;
导入android.graphics.Typeface;
导入android.graphics.Paint.Align;
导入android.graphics.Paint.FontMetrics;
导入android.graphics.Point;
导入android.graphics.Rect;
导入android.util.Log;
//用变音符号呈现希伯来语字符串
//
公共类希布伦德{
油漆;
HashMap空间;
字符串字符串;
字符串prevChar=“”;
最后一个字符串标记=“HebRender”;
公共HebRender(上下文svContext){
油漆=新油漆();
Typeface t=Typeface.createFromAsset(svContext.getAssets(),“font/simplecm Bold.ttf”);
//Typeface t=Typeface.createFromAsset(svContext.getAssets(),“fonts/gisha.ttf”);
油漆。设置字体(t);
绘制.设置样式(绘制.样式.填充);
油漆.尺寸(48);
paint.setAntiAlias(真);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setTextAlign(Align.CENTER);
}
公共void drawText(画布、字符串字、点定位、int颜色){
Rect bounds=new Rect();
Rect prevBounds=新的Rect(0,0,0,0);
paint.getTextBounds(word,0,word.length(),bounds);
油漆。设置颜色(颜色);
int wordWidth=bounds.width();
//移动到右边缘(参数为“中心”)
locate.x+=wordWidth/2;
//初始化单个字符的边界
边界=新的矩形(0,0,0,0);
//对于每个字符
for(int i=0;i 如果(c>=1488&&c我尝试了来自Culmus的Gisha字体和简单字体。两者都没有乐趣。我尝试了在字符串两端添加\u200F的所有可能组合。组合和单独使用时,我尝试了paint.setTextAlign(Align.RIGHT/Align.LEFT/Align.Center)。这些参数似乎都没有任何效果。
此时,我正在尝试实现一个手动解决方案,分别迭代每个代码点。我不敢相信这还没有解决。我尝试了Gisha字体和Culmus的简单字体。两者都没有乐趣。我尝试了所有可能的方法