序言
可信许多在线设计的前端WEB利用会用到字体作为素材的案例,丰富多样的字体等闲是安排在服务器端让用户去抉择,而且能动态安排,利用客户端字体显明是不可取的;
现状
然而中文字体动不动就几个M,做过flash的同学该当懂得嵌入字体是怎么回事,假定嵌入字经验使得swf整个体积变大,而flex现在轻率做到的是全副字体文件编译成swf款式来动态加载。假定必需依据用户输入的文字动态的加载该如何做呢?
最容易的计划是后台依据字体出产位图,这不能中意我的要求,1,位图拉伸后有锯齿2,大一点的位图文件很占空间,前台设计必需起码1000×1000以上能力保证打听度,这么一张图动不动就大于100K。
目标
最健全的一个计划,是能让我的用户输入文字后,生成一个对应字体仅仅包括这几个文字的swf资源文件,这个swf占的空间很小并且在flex管用
source=这个资源>就能够加载。
阿里妈妈bannermaker是有这个计划的,然而商业秘密未曾公布出来,能够确定的是定然在后台端生成swf,至于怎么发生,现在也没找到过现成计划。只能自己琢磨了,穿越一段工夫实践,联合java动态生成swf的一个框架,终于获胜了,20个文字的矢量图,10K不到,而且矢量图和字体大小无关,容易前端怎么拉伸无锯齿。
率先,重述下动态矢量swf字体是什么含义呢?
用户-》抉择1字体并输入‘abc’-》后台生成一个swf,这个swf仅仅包括1字体中abc三个字符并且是矢量的。
相仿于flash IDE里的这秉功能:
嵌入字体并导出资源swf图像。
缺憾的是IDE不轻率和利用整合,如何用代码来告终呢?
告终的中心:java登场了,感谢anotherbigidea大师的盛开和分享
http://om/javaswf/
这曾经是anotherbigidea大师03年时候的杰作了,用java io垄断 依据flash 6字节位组织措施能够从swf
1中提取任何的元素再去动态生成swf 2的内容。
因而,一个设法诞生了,后台放置一个字体a的全量swf1文件,java端获得到用户输入的文字后动态的从swf1拷贝那几个图形文字生成一个swf2
不就ok了么。 果然,如我所料:
1,全量的swf字库怎么做?
可按照上图,在本地安装字体后,嵌入所有字符导出一个swf,良好是swf 6.0款式。(flex和flash分享资源文件现在都用6
)
2,怎么用java动态生成swf?
package test;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import com.anotherbigidea.flash.movie.Font;
import com.anotherbigidea.flash.movie.FontDefinition;
import com.anotherbigidea.flash.movie.FontLoader;
import com.anotherbigidea.flash.movie.Frame;
import com.anotherbigidea.flash.movie.Movie;
import com.anotherbigidea.flash.movie.Text;
import com.anotherbigidea.flash.movie.Font.NoGlyphException;
import com.anotherbigidea.flash.structs.Color;
public class Testtxt {
public static void main(String[] args) throws IOException,
NoGlyphException {
//--Load a font from another movie. That movie should contain only
an
// edit field that is specified to include all the glyphs in
the
// appropriate font.
// Font definitions can be referenced by multiple fonts (for
example if
// there is a font used for a text block and another font used with
an
// edit field which restricts the allowable characters).
//初始化 加载全量字库
java.awt.Font nf =
java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONThttp://www.younineinch.info/lianxiwomen/624.html,
new FileInputStream("www.gree-bj.comc://mnjmb.ttf"));
//第一步http://www.cnword.info/guanyuwomen/606.html,输入文字
String instr =
"文字这个的房贷首付第三方第三方/n/n/n地方地方haha牛x第三方我祖国好地方/n地方/ndfdfdsf";
//第二步:抉择/导入字库
/避免重复加载
String fontpath = "ccxkt";
HashMap fonts
= new HashMap
FontDefinition>();
FontDefinition fontdef = fonts.get(fontpath);
System.out.println("目前利用内存:"+(Runtime.getRuntime().totalMemory() -
Runtime.getRuntime().freeMemory())/1024/1024);
if(fontdef==null){
//导入swf款式的文字类库,当心路径
fontdef = FontLoader.loadFont( "c://"+fontpath+".swf" );
//导入全量的字库,我这里有许多个,为了测验功能,觉察一个中文字体要占30M左右的内存
fonts.put(fontpath, fontdef);
}
//File f = new File("c://ch");
//System.out.println("一共"+f.list().length+"个中文字体");
//for (String s :f.list()){
//System.out.print(s);
//fonts.put(s,FontLoader.loadFont("c://ch//"+s));
//System.out.println(":"+(Runtime.getRuntime().totalMemory() -
Runtime.getRuntime().freeMemory())/1024/1024);
//}
//System.out.println("加载中文字体后内存2:"+(Runtime.getRuntime().totalMemory()
- Runtime.getRuntime().freeMemory())/1024/1024);
//f = new File("c://en");
//System.out.println("一共"+f.list().length+"个英文字体");
//for (String s :f.list()){
//System.out.print(s);
//fonts.put(s,FontLoader.loadFont("c://en//"+s));
//System.out.println(":"+(Runtime.getRuntime().totalMemory() -
Runtime.getRuntime().freeMemory())/1024/1024);
//}
//System.out.println("加载所有字体后内存3:"+(Runtime.getRuntime().totalMemory()
- Runtime.getRuntime().freeMemory())/1024/1024);
/下面是动态生成文字对应的swf局部,功能很不错,io垄断由于是内存拷贝,奇快无比,比后台动态用flex
sdk编译措施还要快
//初始化参数
int fontsize = 100;//默认字体大小,由于矢量款式,大小没联系(swf文件大小不受此参数波及)
Color c = new Color(0,0,0);//文字颜色
//--Create a text object with a default transform
Text text = new Text(null);
//--The font references the Font Definition and pulls over only
the
// glyph definitions that are required for any text referencing the
font
System.out.println("len1:"+fontdef.getGlyphList().size());
Font font = new Font( fontdef );
//第四步:
/处理输入字符串,扶持回车多行解析
StringReader re = new StringReader(instr);
BufferedReader bf = new BufferedReader(re);
String s = bf.readLine();
int i=0;
while(s!=null){
//多行间定然利用空格
if(s.length()==0){s = http://www.ki7now.info/lianxiwomen/598.html"
";}
//--Add a row of characters - specify the starting (x,y) within the
text symbol
try {
text.addRow(font.chars(s, fontsize), c, 0, fontsize * i + 5,true,
true);
} catch (NoGlyphException e) {
// 某文字未曾该对应字体,疏忽
}
s = bf.readLine();
i++;
}
/解析告终
//--Add another row - different color, no (x,y) specified so the
chars will
// flow immediately after the preceding chars.
// text.row( font.chars( "2嗡炒无敌", 25), new
Color(255,0,255),0,0,false,false);
//计算文本框大小,重要,定然在movie初始化前 这是我改革的代码,先计算大小
text.measureRect(null, null, font, false);
//默认文字x=0, 推算出中文宽度必需多加一个单位的fontsize,偶也不懂得为什么,加了没坏处
Movie movie = new Movie(
(int)text.maxX+fontsize,(int)(text.maxY-text.minY),12,5,null);
Frame frame = movie.appendFrame();
//--instantiate the text
frame.placeSymbol( text, 0, -((int) text.minY
));//让文本框揭示在0,0坐标
//--save the movie
movie.write( "c://output.swf",true );
//输出到流
//movie.write( OutputStream out, boolean compressed )
}
}
最后,大师供给了一个基础,优化需继续
这种措施生成的swf比穿越flexsdk动态编译生成swf要快而且文件要小,精简,许多无用消息都不会生成。
不过也有几个局限:
1,字体swf定然导出flash 6款式, 只能供给了容易的动画接口。
2,后台导入的是一个全量swf库,挪借静态内存极大,要安排50套字体的话
2G内存都不够;动态加载全量字体的话也是不可行的,因为加载一个全量字体花费极大,可琢磨拆分安排,可能按字体文字的字节流引入数据库,再可能可按字体散布多个服务器安排。
这个库曾经久久没人更新了,里面的代码逻辑看得一头雾水,固然功能和功能都穿越了,然而基于继续大师的优化工作还有待继续前行。
参看文献:
http://om/javaswf/
就显得极其的不够用了。写一个“俄罗斯方块”的过程,即便一个“相对混杂”的问题。翻开一本《C++Primer》,