最近在Android平台上生成PDF文件时,碰到了内嵌字体的问题。大部分打印厂的机器是不支持PDF内嵌字体的,
所以要想将文字按指定的字体印刷出来,只能转曲。
转曲
转曲的意思就是把文字转成曲线线段,可以想象成把文字的轮廓勾勒出来。
Android中的Paint.getTextPath
方法可以获得String的Path,而PathMeasure可以获得Path中的关键点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setTextSize(yourTextSize); Path fontPath = new Path(); paint.getTextPath(yourText, 0, yourText.length(), 0f, paint.getFontSpacing(), fontPath); PathMeasure pathMeasure = new PathMeasure(fontPath, false); float[] pos = new float[2]; do { float distance = 0f; while (distance < pathMeasure.getLength()) { pathMeasure.getPosTan(distance, pos, null); distance += 0.1f; } } while (pathMeasure.nextContour());
|
计算曲线嵌套层数
得到文字曲线后还不能直接印刷,因为我们只是得到了文字的轮廓,还得往轮廓里填色。
当然不能所有轮廓都填黑色,这样文字会变成一坨一坨的黑色……
我们需要计算每条曲线被多少条曲线全包围(注意我们现在得到的曲线全都是头尾相连的)。
如果被偶数条曲线(包含0条)包围,则填黑色;如果被奇数条曲线包围,则填白色(底色)。
Android或Java本身不提供这样的方法,还好已经有人帮我们研究出方法了,详细参看http://alienryderflex.com/polygon/。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| static class Polygon { private float[] polyY, polyX; private int polySides;
public Polygon( float[] px, float[] py, int ps ) { polyX = px; polyY = py; polySides = ps; }
public boolean contains( float x, float y ) { boolean oddTransitions = false; for( int i = 0, j = polySides -1; i < polySides; j = i++ ) { if((Float.compare(polyY[i], y) < 0 && Float.compare(polyY[j], y) >= 0 ) || ( Float.compare(polyY[j], y) < 0 && Float.compare(polyY[i], y) >= 0)){ if(Float.compare(polyX[i] + ( y - polyY[i] ) / ( polyY[j] - polyY[i] ) * ( polyX[j] - polyX[i] ), x) < 0 ) { oddTransitions = !oddTransitions; } } } return oddTransitions; } }
|
Polygon的构造方法前两个参数填多边形(可以将曲线理解为多边形)横坐标和纵坐标的数组,第三个参数填多边形的边数,即坐标的个数。
contains方法即可检查某个点是否在这个多边形中。
那么思路就很简单了:如果曲线A的任一关键点不在曲线B中,B就没有包围A。
代码就不贴了。
填色
如上所述,如果被偶数条曲线包围,填黑色;被奇数条曲线包围,填白色。
1 2 3 4 5 6 7
| int nestingNum = surroundedNumber(pathPointsList, pathPoints); if (nestingNum % 2 == 0) { paint.setColor(Color.BLACK); } else { paint.setColor(Color.WHITE); } canvas.drawPath(path, paint);
|
大功告成~
详细代码请参考https://gist.github.com/qq157755587/32e927e77e259cd84631