亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

J2me點陣字

系統 1871 0

前言:開發J2ME過程中,我們會發現平臺本身提供的字體太小,而且樣式有限,嚴重影響游戲性的提高。不廢話,進入正題。

????? 首先,我們了解到:一個GB2312漢字是由兩個字節編碼的,范圍為A1A1~FEFE。A1-A9為符號區,B0到F7為漢字區。每一個區有94個字符(注意:這只是編碼的許可范圍,不一定都有字型對應,比如符號區就有很多編碼空白區域)。下面以漢字“我”為例,介紹如何在HZK16文件中找到它對應的32個字節的字模數據。
????? 前面說到一個漢字占兩個字節,這兩個中前一個字節為該漢字的區號,后一個字節為該字的位號。其中,每個區記錄94個漢字,位號為該字在該區中的位置。所以要找到“我”在hzk16庫中的位置就必須得到它的區碼和位碼。(為了區別使用了區碼和區號,其實是一個東西,別被我誤導了)
????? 區碼:區號(漢字的第一個字節)-0xa0 (因為漢字編碼是從0xa0區開始的,所以文件最前面就是從0xa0區開始,要算出相對區碼)
????? 位碼:位號(漢字的第二個字節)-0xa0
????? 這樣我們就可以得到漢字在HZK16中的絕對偏移位置: offset=(94*(區碼-1)+(位碼-1))*32
????? 注解:?
????? 1、區碼減1是因為數組是以0為開始而區號位號是以1為開始的?
????? 2、(94*(區號-1)+位號-1)是一個漢字字模占用的字節數
????? 3、最后乘以32是因為漢字庫文應從該位置起的32字節信息記錄該字的字模信息(前面提到一個漢字要有32個字節顯示)

?????? 代碼如下:

Java代碼 復制代碼
  1. import ?java.io.InputStream; ??
  2. ??
  3. import ?javax.microedition.lcdui.Graphics; ??
  4. ??
  5. ??
  6. /** ?
  7. ?*?點陣字,可以實現9*9,10*10,11*11,12*12,13*13,14*14,15*15,16*16等點陣字的繪制 ?
  8. ?*?@author?夜夢星辰 ?
  9. ?*?@email?babala_234@163.com ?
  10. ?*? ?
  11. ?*/ ??
  12. public ? class ?RasterFont?{ ??
  13. ???? public ? final ? static ?String?ENCODE?=? "GB2312" ; ??
  14. ??
  15. ???? private ?String?fontFileName;???? //點陣字文件名 ??
  16. ???? private ? int ?diameter;??????????? //字大小,支持9-16 ??
  17. ??
  18. ???? /**?Creates?a?new?instance?of?CustomFont?*/ ??
  19. ???? public ?RasterFont(String?fontFileName, int ?diameter)?{ ??
  20. ???????? this .fontFileName?=?fontFileName; ??
  21. ???????? this .diameter=diameter; ??
  22. ????} ??
  23. ??
  24. ???? /** ?
  25. ?????*?繪制點陣中文漢字,gb2312 ?
  26. ?????*? ?
  27. ?????*?@param?g?????????畫筆 ?
  28. ?????*?@param?str???????需要繪制的文字 ?
  29. ?????*?@param?x?????????屏幕顯示位置x ?
  30. ?????*?@param?y?????????屏幕顯示位置y ?
  31. ?????*?@param?color?????文字顏色 ?
  32. ?????*? ?
  33. ?????*/ ??
  34. ???? protected ? void ?drawString(Graphics?g,?String?str,? int ?x,? int ?y,? int ?color)?{ ??
  35. ???????? byte []?data?=? null ; ??
  36. ???????? int []?code?=? null ; ??
  37. ???????? int ?interval;??? //字間間隔 ??
  38. ???????? int ?i16;???????? //兩字節一行,即16位 ??
  39. ????????g.setColor(color); ??
  40. ???????? for ?( int ?index?=? 0 ;?index?<?str.length();?index++)? ??
  41. ????????{ ??
  42. ????????????interval=index*diameter; ??
  43. ???????????? ??
  44. ???????????? if ?(str.charAt(index)?<? 0x80 )? //?非中文 ??
  45. ????????????{ ??
  46. ????????????????g.drawString(str.substring(index,?index?+? 1 ),?x+interval,?y,? 0 ); ??
  47. ????????????} ??
  48. ???????????? else ??
  49. ????????????{ ??
  50. ????????????????code?=?getByteCode(str.substring(index,?index?+? 1 )); ??
  51. ????????????????data?=?read(code[ 0 ],?code[ 1 ]); ??
  52. ???????????????? for ?( int ?line?=? 0 ;?line?<?diameter;?line++)? ??
  53. ????????????????{ ??
  54. ????????????????????i16=?data[line<< 1 ]& 0x000000ff ; ??
  55. ????????????????????i16?=?i16?<<? 8 ?|?(data[(line<< 1 )+ 1 ]& 0x000000ff );? //?16位整形值,注意先通過與運算轉為int ??
  56. ???????????????????? for ( int ?i= 0 ;i<diameter;i++) ??
  57. ????????????????????{ ??
  58. ???????????????????????? if ?((i16?&?( 0x8000 ?>>?i))?!=? 0 ){?????? //逐位測試:通過與1進行與運算 ??
  59. ????????????????????????????g.drawLine(x?+i+interval,?y?+?line,?x+i+interval,?y?+?line); ??
  60. ????????????????????????} ??
  61. ????????????????????} ??
  62. ????????????????} ??
  63. ????????????} ??
  64. ????????} ??
  65. ????} ??
  66. ??
  67. ???? /** ?
  68. ?????*?讀取文字信息 ?
  69. ?????*? ?
  70. ?????*?@param?areaCode??區碼 ?
  71. ?????*?@param?posCode???位碼 ?
  72. ?????*?@return??????文字數據 ?
  73. ?????*/ ??
  74. ???? protected ? byte []?read( int ?areaCode,? int ?posCode)?{ ??
  75. ???????? byte []?data?=? null ; ??
  76. ???????? try ?{ ??
  77. ???????????? int ?area?=?areaCode?-? 0xa0 ;? //?獲得真實區碼 ??
  78. ???????????? int ?pos?=?posCode?-? 0xa0 ;??? //?獲得真實位碼 ??
  79. ??
  80. ????????????InputStream?in?=?getClass().getResourceAsStream(fontFileName); ??
  81. ???????????? int ?bytePerLine=(diameter- 1 )?/ 8 + 1 ; ??
  82. ???????????? int ?bytePerFont=?bytePerLine*diameter; ??
  83. ???????????? long ?offset?=bytePerFont*((area?-? 1 )?*? 94 ?+?pos?-? 1 ); ??
  84. ????????????in.skip(offset); ??
  85. ????????????data?=? new ? byte [bytePerFont]; ??
  86. ????????????in.read(data,? 0 ,?bytePerFont); ??
  87. ????????????in.close(); ??
  88. ????????}? catch ?(Exception?ex)?{ ??
  89. ????????} ??
  90. ???????? return ?data; ??
  91. ????} ??
  92. ??
  93. ???? /** ?
  94. ?????*?獲得文字的區位碼 ?
  95. ?????*? ?
  96. ?????*?@param?str ?
  97. ?????*?@return?int[2] ?
  98. ?????*/ ??
  99. ???? protected ? int []?getByteCode(String?str)?{ ??
  100. ???????? int []?byteCode?=? new ? int [ 2 ]; ??
  101. ???????? try ?{ ??
  102. ???????????? byte []?data?=?str.getBytes(ENCODE); ??
  103. ????????????byteCode[ 0 ]?=?data[ 0 ]& 0x000000ff ; ??
  104. ????????????byteCode[ 1 ]?=?data[ 1 ]& 0x000000ff ; ??
  105. ????????}? catch ?(Exception?e)?{ ??
  106. ????????????e.printStackTrace(); ??
  107. ????????} ??
  108. ???????? return ?byteCode; ??
  109. ????} ??
  110. ??
  111. }??
    import java.io.InputStream;

import javax.microedition.lcdui.Graphics;


/**
 * 點陣字,可以實現9*9,10*10,11*11,12*12,13*13,14*14,15*15,16*16等點陣字的繪制
 * @author 夜夢星辰
 * @email babala_234@163.com
 * 
 */
public class RasterFont {
 public final static String ENCODE = "GB2312";

 private String fontFileName; //點陣字文件名
 private int diameter;   //字大小,支持9-16

 /** Creates a new instance of CustomFont */
 public RasterFont(String fontFileName,int diameter) {
  this.fontFileName = fontFileName;
  this.diameter=diameter;
 }

 /**
  * 繪制點陣中文漢字,gb2312
  * 
  * @param g   畫筆
  * @param str  需要繪制的文字
  * @param x   屏幕顯示位置x
  * @param y   屏幕顯示位置y
  * @param color  文字顏色
  * 
  */
 protected void drawString(Graphics g, String str, int x, int y, int color) {
  byte[] data = null;
  int[] code = null;
  int interval; //字間間隔
  int i16;  //兩字節一行,即16位
  g.setColor(color);
  for (int index = 0; index < str.length(); index++) 
  {
   interval=index*diameter;
   
   if (str.charAt(index) < 0x80) // 非中文
   {
    g.drawString(str.substring(index, index + 1), x+interval, y, 0);
   }
   else
   {
    code = getByteCode(str.substring(index, index + 1));
    data = read(code[0], code[1]);
    for (int line = 0; line < diameter; line++) 
    {
     i16= data[line<<1]&0x000000ff;
     i16 = i16 << 8 | (data[(line<<1)+1]&0x000000ff); // 16位整形值,注意先通過與運算轉為int
     for(int i=0;i<diameter;i++)
     {
      if ((i16 & (0x8000 >> i)) != 0){  //逐位測試:通過與1進行與運算
       g.drawLine(x +i+interval, y + line, x+i+interval, y + line);
      }
     }
    }
   }
  }
 }

 /**
  * 讀取文字信息
  * 
  * @param areaCode 區碼
  * @param posCode 位碼
  * @return   文字數據
  */
 protected byte[] read(int areaCode, int posCode) {
  byte[] data = null;
  try {
   int area = areaCode - 0xa0; // 獲得真實區碼
   int pos = posCode - 0xa0; // 獲得真實位碼

   InputStream in = getClass().getResourceAsStream(fontFileName);
   int bytePerLine=(diameter-1) /8+1;
   int bytePerFont= bytePerLine*diameter;
   long offset =bytePerFont*((area - 1) * 94 + pos - 1);
   in.skip(offset);
   data = new byte[bytePerFont];
   in.read(data, 0, bytePerFont);
   in.close();
  } catch (Exception ex) {
  }
  return data;
 }

 /**
  * 獲得文字的區位碼
  * 
  * @param str
  * @return int[2]
  */
 protected int[] getByteCode(String str) {
  int[] byteCode = new int[2];
  try {
   byte[] data = str.getBytes(ENCODE);
   byteCode[0] = data[0]&0x000000ff;
   byteCode[1] = data[1]&0x000000ff;
  } catch (Exception e) {
   e.printStackTrace();
  }
  return byteCode;
 }

}
  

???? 另外,經過測試,我發現如果采用稀疏矩陣來保存點陣圖可以節省不少內存,請大家看看以下是HZK16的統計數據:

統計結果:零位有:1538534,非零位有:602394,總位數為:2140928,非零位占百分比:0.28

?

分析:
1個字占的位數是2^8=256位
?如果轉為稀疏矩陣的話,則占的位數為2*0.28*2^8≈144位
?可以節省到56%(≈144/256)的內存

J2me點陣字


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: www.青草视频 | 日韩一级特黄毛片在线看 | 目韩一区二区三区系列片丶 | 欧美三级成人理伦 | 久热精品在线 | 91亚洲国产在人线播放午夜 | 一区二区三区精品国产欧美 | 久久99国产精品久久99小说 | 亚洲专区第一页 | 天海翼一区二区三区高清视频 | 国产日韩欧美亚洲精品95 | 玖玖精品视频 | 久久99国产这里有精品视 | 美女被爆羞羞网站 | 欧美一级在线 | 国产久热精品 | 国产在线精品一区二区三区不卡 | 免费一级欧美毛片 | 国产福利视频精品 | 色福利视频 | 免费看欧美理论片在线 | 操一操| 久久这里是精品 | 日产精品一二三四区国产 | 女色综合 | 伊人精品在线 | 男女一级特黄a大片 | 精品国产乱码一区二区三区 | 成年女人免费 | www.久久| 久久久久久国产精品mv | 亚洲欧洲久久久精品 | 国产福利在线播放 | 亚洲国产男人本色在线观看的a站 | 思思久久99热这里只有精品66 | 乱色专区 | 国产精品久久免费视频 | 毛片免费观看的视频 | 国产福利在线观看视频 | 亚洲专区欧美专区 | 国产99久久久久久免费看 |