📄 waprender.java
字号:
private void dealBaseTag(Enumeration e,Tag tag,Css css){
String tmpName = tag.getName();
Object obj = null;
while(true){
obj = e.nextElement();
curTagId++;
if(obj instanceof Tag){
tag = (Tag)obj;
String name = tag.getName();
// 遇见当前标记的结束符,则退出递归,返回上一级调用
if(name.equals(tmpName) && tag.getState() == Tag.TAG_CLOSE){
return;
}else if(name.equals("p")){
newLine(0,0);
// do something for <p>
dealBaseTag(e,tag,css);
// do something for </p>
newLine(0,0);
}else if(name.equals("div")){
newLine(0,0);
Css css0 = getTagCss(tag,css);
// do something for <div>
int tmpY = curRenderY;
if(css0!=null){
curRenderY += css0.margin_top;
curRenderX += css0.margin_left;
if(css0.height != 0){
Rectangular rect = new Rectangular(lineNum);
rect.setX(curRenderX);
rect.setY(curRenderY);
rect.setSize(browserWidth - css0.margin_right - css0.margin_left,
css0.height);
rect.setColor(css0.bgColor);
if(css0.bgImg!=null) rect.setBgImage(css0.bgImg);
addElement(rect);
}
curRenderY += css0.padding_top;
curRenderX += css0.padding_left;
}
dealBaseTag(e,tag,css0);
newLine(0,0);
// do something for </div>
if(css0!=null){
curRenderY += css0.padding_bottom;
if(curRenderY - tmpY < css0.height){
curRenderY += css0.height - (curRenderY - tmpY);
}
curRenderY += css0.margin_bottom;
}
}else if(name.equals("span")){
// do something for <span>
Css css0 = getTagCss(tag,css);
dealBaseTag(e,tag,getTagCss(tag, css0));
// do something for </span>
}else if(tag.getName().equals("do")){
dealTag_Do(e,tag);
}else if(name.equals("table")){
// wap2.0 table,A bit difficult
}else if(name.equals("a")){
dealTag_A(e,tag,css);
}else if(name.equals("img")){
dealTag_Img(e,tag,css);
}else if(name.equals("anchor")){
dealTag_Anchor(e,tag,css);
}else if(name.equals("br")){
// 无条件换一行显示
if(elementNum > 0){
Element element = (Element)elements.elementAt(elementNum-1);
if(element==null || (element!=null && element.lineId != lineNum)){
// 插入一空行
addElement(new NormalText("",false,-1,lineNum,browser));
curLineMaxHeight = browser.fontHeight;
}
}else{
// 插入一空行
addElement(new NormalText("",false,-1,lineNum,browser));
curLineMaxHeight = browser.fontHeight;
}
if(css!=null){
newLine(0,css.padding_bottom);
}else{
newLine(0,0);
}
}else if(name.equals("input")){
dealTag_Input(e,tag,css);
}else if(name.equals("select")){
dealTag_Select(e,tag,css);
}else if(name.equals("onevent")){
dealTag_Onevent(e,tag);
}else if(name.equals("form")){
if(tag.getState() == Tag.TAG_OPEN){
tmpFormAction = tag.getParm("action");
tmpFormMethod = tag.getParm("method");
// 默认是GET方法
if(tmpFormMethod==null || tmpFormMethod.equals("")){
tmpFormMethod = "GET";
}
tmpFormElement = new Vector();
inForm = true;
dealBaseTag(e,tag,css);
}else{
tmpFormAction = null;
tmpFormMethod = null;
tmpFormElement = null;
inForm = false;
}
}else{
System.out.println("[unknow tag] "+tag);
}
}else{
// 普通文字
dealNormalText((String)obj,css);
}
}
}
/**
* 强制换一新行,所有元素都将在新的一行开始显示
* @param dx 换行后的新x修正坐标
* @param dy 换行后的新y修正坐标
*/
private void newLine(int dx,int dy){
curRenderX = dx;
curRenderY += curLineMaxHeight + dy;
curLineMaxHeight = 0;
lineNum++;
}
/**
* 处理普通文本,即没有被"<>"括起来的文字部分<br>
* 这些文字可能出现在超链接中,也可能是独立的文段
* @param string
* @param css
*/
private void dealNormalText(String string,Css css){
// 初始化文字的对齐方式和颜色等信息
int padding_top = Css._default_padding_top;
int padding_bottom = Css._default_padding_bottom;
int padding_left = Css._default_padding_left;
int padding_right = Css._default_padding_right;
int color = Css._default_foreColor;
if(css!=null){
padding_top = css.padding_top;
padding_bottom = css.padding_bottom;
padding_left = css.padding_left;
padding_right = css.padding_right;
color = css.foreColor;
}
// 当前屏幕X坐标到屏幕右边的距离,以便计算是否有足够的空间显示该段文字
int remainingWidth = browserWidth - curRenderX - padding_left;
int stringWidth = browser.strWidth(string);
// 先判断是否当前的文字本行剩余的空间可以显示完
if(stringWidth <= remainingWidth){
// 这里不换行
NormalText element = new NormalText(string,inHyperlinks,inHyperlinks?hotSpotNum:-1,lineNum,browser);
addElement(element);
element.setColor(color);
curRenderX += padding_left;
element.setX(curRenderX);
element.setY(curRenderY);
curRenderX += stringWidth + padding_right;
if(curLineMaxHeight < browser.fontHeight){
curLineMaxHeight = browser.fontHeight;
}
}else{
String tmp = Tools.CutString(string, remainingWidth);
// 先将上一行填满
if(tmp!=null){
NormalText element = new NormalText(tmp,inHyperlinks,inHyperlinks?hotSpotNum:-1,lineNum,browser);
addElement(element);
element.setColor(color);
curRenderX += padding_left;
element.setX(curRenderX);
element.setY(curRenderY);
if(curLineMaxHeight < browser.fontHeight){
curLineMaxHeight = browser.fontHeight;
}
// 已填满本行,换行
newLine(0,padding_bottom);
}
// 将剩下的换行显示
if(!tmp.equals("")){
tmp = Tools.RepString(string, tmp, "");
}else{
tmp = string;
}
if(!tmp.equals("")){
Vector vector = Tools.DoLine(tmp, browserWidth);
for(int i=0;i<vector.size();i++){
// 如果没有换行,则强制换行
if(curRenderX != 0){
newLine(0,padding_bottom);
}
tmp = (String)vector.elementAt(i);
NormalText element = new NormalText(tmp,inHyperlinks,inHyperlinks?hotSpotNum:-1,lineNum,browser);
addElement(element);
element.setColor(color);
curRenderX += padding_left;
curRenderY += padding_top;
element.setX(curRenderX);
element.setY(curRenderY);
curRenderX += browser.strWidth(tmp) + padding_right;
curLineMaxHeight = browser.fontHeight;
}
}
}
}
/**
* 处理head标记的内容,主要包括:<br>
* -title 标题<br>
* -link 连接的CSS文件<br>
* <br>
* 不可嵌套,不可递归
* <br>
* @param e
* @param tag
*/
private void dealTag_Head(Enumeration e,Tag tag){
Object obj = null;
while(true){
obj = e.nextElement();
curTagId++;
if(obj instanceof Tag){
tag = (Tag)obj;
// 再次遇见head标记且为结束符时,则退出循环
if(tag.getName().equals("head") && tag.getState() == Tag.TAG_CLOSE){
break;
}else if(tag.getName().equals("title") && tag.getState() == Tag.TAG_OPEN){
title = (String)e.nextElement();
System.out.println("Title: "+title);
}else if(tag.getName().equals("link") && tag.getState() == Tag.TAG_SELFCONTAINED){
String href = tag.getParm("href");
if(href!=null && !href.equals("")){
// 加载CSS文件
cssData = browser.loadCss(browser.getUrl(href));
}
}
}else{
// normal text,nothing to do
}
}
}
/**
* do标记(主要是返回按钮)
* @param e
* @param tag
*/
private void dealTag_Do(Enumeration e,Tag tag){
// <?xml version="1.0"?>
// <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
// "http://www.wapforum.org/DTD/wml_1.1.xml">
// <wml>
// <template>
// <do name="back" type="prev" label="Back">
// <prev/>
// </do>
// </template>
//
// <card id="card1" title="Card 1">
// <p>
// Hello World!
// <br/>
// <a href="#card2">Card 2</a>
// </p>
// </card>
//
// <card id="card2" title="Card 2">
// <p>
// From W3Schools!
// <br/>
// <a href="#card1">Card 1</a>
// </p>
// </card>
// </wml>
String name = tag.getParm("name");
String type = tag.getParm("type");
String label = tag.getParm("label");
Object obj = null;
while(true){
obj = e.nextElement();
curTagId++;
if(obj instanceof Tag){
tag = (Tag)obj;
// 再次遇见do标记且为结束符时,则退出循环
if(tag.getName().equals("do") && tag.getState() == Tag.TAG_CLOSE){
break;
}else if(tag.getName().equals("prev") &&
(tag.getState() == Tag.TAG_SELFCONTAINED || tag.getState() == Tag.TAG_CLOSE)){
// 添加一个超链接
HotSpot hotspot = new HotSpot();
hotspot.elementId = elementNum;
hotspot.url = "prev";
hotspot.type = Element.NORMAL_TEXT;
if(label!=null && !label.equals("")){
inHyperlinks = true;
dealNormalText(label,null);
inHyperlinks = false;
addHotSpot(hotspot);
}
}
}else{
// normal text,nothing to do
}
}
}
/**
* onevent所指定的事件,这些事件都在页面解释完毕后执行<br>
* 主要的事件是页面跳转<br>
* <br>
* 不可嵌套,不可递归
* <br>
* @param e
* @param tag
*/
private void dealTag_Onevent(Enumeration e,Tag tag){
// 将onevent事件参数保存在hashtable中
Hashtable table = new Hashtable();
// onevent事件的类型
table.put("type", tag.getParm("type"));
Object obj = null;
while(true){
obj = e.nextElement();
curTagId++;
if(obj instanceof Tag){
tag = (Tag)obj;
// 再次遇见onevent标记且为结束符时,则退出循环
if(tag.getName().equals("onevent") && tag.getState() == Tag.TAG_CLOSE){
break;
}else if(tag.getName().equals("go") &&
(tag.getState() == Tag.TAG_SELFCONTAINED || tag.getState() == Tag.TAG_OPEN )){
// 暂时只考虑href参数
table.put("href", tag.getParm("href"));
}
}else{
// nothing to do
}
}
// 通知browser有onevent事件需要处理,并传入参数
// render线程结束后将处理这些事件
browser.onEvent(table);
}
/**
* 图片标记,遇见该标记时会通过HTTP加载相应的图片,比较慢<br>
* 若优化引擎应首先考虑这里的图片加载机制优化问题<br>
* <br>
* 不可嵌套,不可递归
* <br>
* @param e
* @param tag
* @param css
*/
private void dealTag_Img(Enumeration e,Tag tag,Css css){
String alt = tag.getParm("alt");
String src = tag.getParm("src");
if(src == null) src = "";
src = Tools.RepString(src,"'","");
NormalImage element = new NormalImage(inHyperlinks,inHyperlinks?hotSpotNum:-1,lineNum,browser);
if(alt==null){
element.setAlt("");
}else{
element.setAlt(alt);
}
element.setSrc(src);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -