日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

J2me點(diǎn)陣字

系統(tǒng) 2039 0

前言:開(kāi)發(fā)J2ME過(guò)程中,我們會(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ù)。
????? 前面說(shuō)到一個(gè)漢字占兩個(gè)字節(jié),這兩個(gè)中前一個(gè)字節(jié)為該漢字的區(qū)號(hào),后一個(gè)字節(jié)為該字的位號(hào)。其中,每個(gè)區(qū)記錄94個(gè)漢字,位號(hào)為該字在該區(qū)中的位置。所以要找到“我”在hzk16庫(kù)中的位置就必須得到它的區(qū)碼和位碼。(為了區(qū)別使用了區(qū)碼和區(qū)號(hào),其實(shí)是一個(gè)東西,別被我誤導(dǎo)了)
????? 區(qū)碼:區(qū)號(hào)(漢字的第一個(gè)字節(jié))-0xa0 (因?yàn)闈h字編碼是從0xa0區(qū)開(kāi)始的,所以文件最前面就是從0xa0區(qū)開(kāi)始,要算出相對(duì)區(qū)碼)
????? 位碼:位號(hào)(漢字的第二個(gè)字節(jié))-0xa0
????? 這樣我們就可以得到漢字在HZK16中的絕對(duì)偏移位置: offset=(94*(區(qū)碼-1)+(位碼-1))*32
????? 注解:?
????? 1、區(qū)碼減1是因?yàn)閿?shù)組是以0為開(kāi)始而區(qū)號(hào)位號(hào)是以1為開(kāi)始的?
????? 2、(94*(區(qū)號(hào)-1)+位號(hào)-1)是一個(gè)漢字字模占用的字節(jié)數(shù)
????? 3、最后乘以32是因?yàn)闈h字庫(kù)文應(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?夜夢(mèng)星辰 ?
  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?????????畫(huà)筆 ?
  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位整形值,注意先通過(guò)與運(yùn)算轉(zhuǎn)為int ??
  56. ???????????????????? for ( int ?i= 0 ;i<diameter;i++) ??
  57. ????????????????????{ ??
  58. ???????????????????????? if ?((i16?&?( 0x8000 ?>>?i))?!=? 0 ){?????? //逐位測(cè)試:通過(guò)與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 夜夢(mèng)星辰
 * @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   畫(huà)筆
  * @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位整形值,注意先通過(guò)與運(yùn)算轉(zhuǎn)為int
     for(int i=0;i<diameter;i++)
     {
      if ((i16 & (0x8000 >> i)) != 0){  //逐位測(cè)試:通過(guò)與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)過(guò)測(cè)試,我發(fā)現(xiàn)如果采用稀疏矩陣來(lái)保存點(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

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

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

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 贵港市| 沭阳县| 渑池县| 上饶县| 德清县| 若羌县| 平和县| 通渭县| 田阳县| 金平| 抚松县| 珠海市| 桑植县| 辛集市| 巍山| 潮安县| 扶绥县| 乡宁县| 祁阳县| 罗山县| 吴堡县| 甘谷县| 教育| 曲靖市| 鹤壁市| 大港区| 章丘市| 通辽市| 洛川县| 驻马店市| 仁布县| 洪泽县| 佳木斯市| 和平县| 应城市| 北海市| 赤峰市| 元江| 廉江市| 定襄县| 响水县|