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

J2me點(diǎn)陣字

系統(tǒng) 2184 0

前言:開發(fā)J2ME過程中,我們會(huì)發(fā)現(xiàn)平臺(tái)本身提供的字體太小,而且樣式有限,嚴(yán)重影響游戲性的提高。不廢話,進(jìn)入正題。

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

?????? 代碼如下:

Java代碼 復(fù)制代碼
  1. import ?java.io.InputStream; ??
  2. ??
  3. import ?javax.microedition.lcdui.Graphics; ??
  4. ??
  5. ??
  6. /** ?
  7. ?*?點(diǎn)陣字,可以實(shí)現(xiàn)9*9,10*10,11*11,12*12,13*13,14*14,15*15,16*16等點(diǎn)陣字的繪制 ?
  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;???? //點(diǎn)陣字文件名 ??
  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. ?????*?繪制點(diǎn)陣中文漢字,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;???????? //兩字節(jié)一行,即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位整形值,注意先通過與運(yùn)算轉(zhuǎn)為int ??
  56. ???????????????????? for ( int ?i= 0 ;i<diameter;i++) ??
  57. ????????????????????{ ??
  58. ???????????????????????? if ?((i16?&?( 0x8000 ?>>?i))?!=? 0 ){?????? //逐位測試:通過與1進(jìn)行與運(yùn)算 ??
  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??區(qū)碼 ?
  71. ?????*?@param?posCode???位碼 ?
  72. ?????*?@return??????文字?jǐn)?shù)據(jù) ?
  73. ?????*/ ??
  74. ???? protected ? byte []?read( int ?areaCode,? int ?posCode)?{ ??
  75. ???????? byte []?data?=? null ; ??
  76. ???????? try ?{ ??
  77. ???????????? int ?area?=?areaCode?-? 0xa0 ;? //?獲得真實(shí)區(qū)碼 ??
  78. ???????????? int ?pos?=?posCode?-? 0xa0 ;??? //?獲得真實(shí)位碼 ??
  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. ?????*?獲得文字的區(qū)位碼 ?
  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;


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

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

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

 /**
  * 繪制點(diǎn)陣中文漢字,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;  //兩字節(jié)一行,即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位整形值,注意先通過與運(yùn)算轉(zhuǎn)為int
     for(int i=0;i<diameter;i++)
     {
      if ((i16 & (0x8000 >> i)) != 0){  //逐位測試:通過與1進(jìn)行與運(yùn)算
       g.drawLine(x +i+interval, y + line, x+i+interval, y + line);
      }
     }
    }
   }
  }
 }

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

   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;
 }

 /**
  * 獲得文字的區(qū)位碼
  * 
  * @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;
 }

}
  

???? 另外,經(jīng)過測試,我發(fā)現(xiàn)如果采用稀疏矩陣來保存點(diǎn)陣圖可以節(jié)省不少內(nèi)存,請(qǐng)大家看看以下是HZK16的統(tǒng)計(jì)數(shù)據(jù):

統(tǒng)計(jì)結(jié)果:零位有:1538534,非零位有:602394,總位數(shù)為:2140928,非零位占百分比:0.28

?

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

J2me點(diǎn)陣字


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 国产一区二区亚洲精品 | 国产亚洲一区二区精品 | 成人短视频在线观看免费 | 日韩一区视频在线 | 一级白嫩美女毛片免费 | 久久久久亚洲国产 | 日本一级特黄毛片免费视频 | 美女一级毛片免费观看 | 久久日韩精品中文字幕网 | 亚洲精品欧美日韩 | 亚洲精品亚洲九十七页 | 久久综合一本 | 深夜免费看片 | 2020年国产高中毛片在线视频 | 国产在线毛片 | 亚洲精品久久九九精品 | 二级毛片免费观看全程 | 国产 麻豆 欧美亚洲综合久久 | 久久这里只有精品2 | 一级片视频免费观看 | 九九视频精品全部免费播放 | 国产成人亚洲精品久久 | 亚洲不卡视频 | 在线视频一区二区日韩国产 | 日日摸夜夜添夜夜添一区二区 | 性xxx免费| 国产精品视频网站 | 一级黄色毛片 | 橘梨纱视频一区二区在线观看 | 欧美一级高清在线观看 | 国产精品网址你懂的 | 亚洲视频在线精品 | 一本久道久久综合狠狠爱 | 国产一级大片免费看 | 欧美另类69xxxxx视频 | 国产精品成人四虎免费视频 | 一级女性全黄生活片看看 | 国产精品久久永久免费 | 伊人色视频 | 有码在线 | 日韩国产成人精品视频 |