home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_14 / Font / Charset.cpp next >
Encoding:
C/C++ Source or Header  |  2000-05-12  |  11.3 KB  |  456 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : charset.cpp                                                         //
  10. //  Description: KCharSetView class                                                  //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <tchar.h>
  19. #include <assert.h>
  20.  
  21. #include "..\..\include\Win.h"
  22. #include "..\..\include\Canvas.h"
  23. #include "..\..\include\ScrollCanvas.h"
  24. #include "..\..\include\MVC.h"
  25. #include "..\..\include\logfont.h"
  26.  
  27. #include "CharSet.h"
  28. #include "Resource.h"
  29.  
  30. class KDBCSMap
  31. {
  32.     WCHAR    m_map[4096];
  33.     int        m_size;
  34.  
  35. public:
  36.     KDBCSMap(void)
  37.     {
  38.         m_size = 0;
  39.     }
  40.  
  41.     void Add(WCHAR from, WCHAR to);
  42.  
  43.     int GetSize(void) const
  44.     {
  45.         return m_size;
  46.     }
  47.  
  48.     WCHAR GetRowFirst(int row)
  49.     {
  50.         return m_map[row];
  51.     }
  52. };
  53.  
  54. void KDBCSMap::Add(WCHAR from, WCHAR to)
  55. {
  56.     for (unsigned f=from; f<=to; f+=16)
  57.     {
  58.         if ( m_size < 4096 )
  59.             m_map[m_size++] = (WCHAR) f;
  60.         else
  61.             assert(FALSE);
  62.     }
  63. }
  64.  
  65. KDBCSMap Map_932;
  66. KDBCSMap Map_936;
  67. KDBCSMap Map_949;
  68. KDBCSMap Map_950;
  69. KDBCSMap Map_UC;
  70.  
  71. void InitMaps(void)
  72. {
  73.     int high;
  74.  
  75.     // Japanese
  76.     for (high = 0x8100; high <= 0xFC00; high += 256)
  77.     {
  78.         if ( (high>0x8400) && (high<0x8700) ) 
  79.             continue;
  80.  
  81.         if ( (high>0x9F00) && (high<0xE000) )
  82.             continue;
  83.  
  84.         if ( (high>0xEA00) && (high<0xED00) )
  85.             continue;
  86.  
  87.         if ( (high>0xEE00) && (high<0xFA00) )
  88.             continue;
  89.  
  90.         int minlow = 0x40;
  91.         int maxlow = 0xF0;
  92.  
  93.         switch ( high )
  94.         {
  95.             case 0x8300: maxlow = 0xD0; break;
  96.             case 0x8400: maxlow = 0xB0; break;
  97.             case 0x8700: maxlow = 0x90; break;
  98.             case 0x8800: minlow = 0x90; break;
  99.             
  100.             case 0xEA00: maxlow = 0xA0; break;    
  101.             case 0xFC00: maxlow = 0x40; break;
  102.         }
  103.         Map_932.Add(high + minlow, high + maxlow);
  104.     }
  105.  
  106.     // Simplified Chinese
  107.     for (high = 0xA100; high <= 0xF700; high += 256)
  108.     {
  109.         if ( (high>0xA900) && (high<0xB000) )
  110.             continue;
  111.  
  112.         int minlow = 0xA0;
  113.         int maxlow = 0xF0;
  114.  
  115.         switch ( high )
  116.         {
  117.             case 0xA200: minlow = 0xB0; break;
  118.             case 0xA600: maxlow = 0xD0; break;
  119.             case 0xA800: 
  120.             case 0xA900: maxlow = 0xE0; break;
  121.         }
  122.         Map_936.Add(high + minlow, high + maxlow);
  123.  
  124.     }
  125.  
  126.     // Traditional Chinese
  127.     for (high = 0xA100; high <= 0xF900; high += 256)
  128.     {
  129.         if ( (high>0xC600) && (high<0xC900) )
  130.             continue;
  131.         
  132.         Map_950.Add(high + 0x40, high + 0x70);
  133.  
  134.         int maxlow = 0xF0;
  135.  
  136.         switch ( high )
  137.         {
  138.             case 0xA300: maxlow = 0xB0; break;
  139.             case 0xC600: continue;
  140.         }
  141.  
  142.         Map_950.Add(high + 0xA0, high + maxlow);
  143.     }
  144.  
  145.     // Korean
  146.     for (high = 0x8100; high <= 0xFD00; high+= 256)
  147.     {
  148.         if ( high==0xC900 )
  149.             continue;
  150.  
  151.         int minlow = 0x40;
  152.         int maxlow = 0xF0;
  153.  
  154.         if ( high > 0xC700 )
  155.             minlow = 0xA0;
  156.         
  157.         switch ( high )
  158.         {
  159.             case 0xA200: 
  160.             case 0xA600: 
  161.             case 0xA700: 
  162.                 maxlow = 0xE0; 
  163.                 break;
  164.             
  165.             case 0xAD00: 
  166.             case 0xAE00: 
  167.             case 0xAF00: 
  168.                 maxlow = 0xA0; 
  169.                 break;
  170.  
  171.             case 0xC600:
  172.                 Map_949.Add(high + 0x40, high + 0x50);
  173.                 minlow = 0xA0;
  174.         }
  175.  
  176.         Map_949.Add(high + minlow, high + maxlow);
  177.     }
  178.  
  179.     Map_UC.Add(0x0100, 0x04F0);
  180.     Map_UC.Add(0x0530, 0x06F0);
  181.     Map_UC.Add(0x0900, 0x0D70);
  182.     Map_UC.Add(0x0E00, 0x0FB0);
  183.     Map_UC.Add(0x10A0, 0x11F0);
  184.     Map_UC.Add(0x1E00, 0x27B0);
  185.     Map_UC.Add(0x3000, 0x3190);
  186.     Map_UC.Add(0x3200, 0x33F0);
  187.     Map_UC.Add(0x4E00, 0x9FF0);
  188.     Map_UC.Add(0xAC00, 0xD7A0);
  189.     Map_UC.Add(0xD800, 0xFDF0);
  190.     Map_UC.Add(0xFE20, 0xFFF0);
  191. /*
  192. Unassigned Blocks
  193. 0500..052F    (48) {General Scripts Area}
  194. 0700..08FF   (512) {General Scripts Area}
  195. 0D80..0DFF   (128) {General Scripts Area}
  196. 0FC0..109F   (224) {General Scripts Area}
  197. 1200..1DFF  (3072) {General Scripts Area}
  198. 27C0..2FFF  (2112) {Symbols Area}
  199. 31A0..31FF    (96) {CJK Phonetics and Symbols Area}
  200. 3400..4DFF  (6656) {NO AREA}
  201. A000..ABFF  (3072) {NO AREA}
  202. D7B0..D7FF    (80) {NO AREA}
  203. FE00..FE1F    (32) {Compatibility Area and Specials}
  204.  
  205.  
  206.  
  207. Assigned Blocks 
  208. 0220..024F    (48) [Latin Extended-B]
  209. 02F0..02FF    (16) [Spacing Modifier Letters]
  210. 0350..035F    (16) [Combining Diacritical Marks]
  211. 0AF0..0AFF    (16) [Gujarati]
  212. 0C70..0C7F    (16) [Telugu]
  213. 0CF0..0CFF    (16) [Kannada]
  214. 0D70..0D7F    (16) [Malayalam]
  215. 0E60..0E7F    (32) [Thai]
  216. 0EE0..0EFF    (32) [Lao]
  217. 2050..205F    (16) [General Punctuation]
  218. 2090..209F    (16) [Superscripts and Subscripts]
  219. 20B0..20CF    (32) [Currency Symbols]
  220. 20F0..20FF    (16) [Combining Marks for Symbols]
  221. 2140..214F    (16) [Letterlike Symbols]
  222. 21F0..21FF    (16) [Arrows]
  223. 2380..23FF   (128) [Miscellaneous Technical]
  224. 2430..243F    (16) [Control Pictures]
  225. 2450..245F    (16) [Optical Character Recognition]
  226. 24F0..24FF    (16) [Enclosed Alphanumerics]
  227. 25F0..25FF    (16) [Geometric Shapes]
  228. 2670..26FF   (144) [Miscellaneous Symbols]
  229. 3250..325F    (16) [Enclosed CJK Letters and Months]
  230. 9FB0..9FFF    (80) [CJK Unified Ideographs]
  231. FA30..FAFF   (208) [CJK Compatibility Ideographs]
  232. FBC0..FBCF    (16) [Arabic Presentation Forms-A]
  233. FD40..FD4F    (16) [Arabic Presentation Forms-A]
  234. FDD0..FDEF    (32) [Arabic Presentation Forms-A]
  235.  */
  236. }
  237.  
  238.  
  239. BOOL CALLBACK EnumCodePagesProc(LPTSTR lpCodePageString)
  240. {
  241.     return TRUE;
  242. }
  243.  
  244.  
  245.  
  246. KCharSetView::KCharSetView(void)
  247. {
  248.     InitMaps();
  249.  
  250.     m_width           = 40;
  251.     m_height       = 36;
  252.     m_font           = 32;
  253.     m_row           = 16;
  254.  
  255.     m_nCharSet     = DEFAULT_CHARSET;
  256.     m_hAnsiFont       = NULL;
  257.  
  258.     m_nPixelWidth  = 16 * m_width + 100;
  259.     m_nPixelHeight = m_row * m_height + 100;
  260.  
  261.     EnumSystemCodePages(EnumCodePagesProc, CP_SUPPORTED);
  262.  
  263.     KLogFont ansifont(26, "Times New Roman");
  264.     ansifont.SetCharSet(DEFAULT_CHARSET);
  265.                 
  266.     m_hAnsiFont = ansifont.Create();
  267. }
  268.  
  269.  
  270. int KCharSetView::OnCommand(int cmd, HWND hWnd)
  271. {
  272.     BYTE cs = m_nCharSet;
  273.     int     row = 16;
  274.     int     width = m_width;
  275.  
  276.     switch ( cmd )
  277.     {
  278.         case IDM_CP_ANSI:            cs = ANSI_CHARSET;            break;
  279.         case IDM_CP_ARABIC:            cs = ARABIC_CHARSET;        break;
  280.         case IDM_CP_BALTIC:            cs = BALTIC_CHARSET;        break;
  281.         case IDM_CP_EASTEUROPE:        cs = EASTEUROPE_CHARSET;    break;
  282.         case IDM_CP_OEM:            cs = OEM_CHARSET;            break;
  283.         case IDM_CP_MAC:            cs = MAC_CHARSET;            break;
  284.         case IDM_CP_RUSSIAN:        cs = RUSSIAN_CHARSET;        break;
  285.         case IDM_CP_SYMBOL:            cs = SYMBOL_CHARSET;        break;
  286.         case IDM_CP_TURKISH:        cs = TURKISH_CHARSET;        break;
  287.         case IDM_CP_GREEK:            cs = GREEK_CHARSET;            break;
  288.         case IDM_CP_HEBREW:            cs = HEBREW_CHARSET;        break;
  289.         case IDM_CP_THAI:            cs = THAI_CHARSET;            break;
  290.         case IDM_CP_VIETNAMESE:        cs = VIETNAMESE_CHARSET;    break;
  291.  
  292.         case IDM_CP_CHINESEBIG5:    cs = CHINESEBIG5_CHARSET;    row += Map_950.GetSize(); break; // (0xF9-0xA1+1)*10; break;
  293.         case IDM_CP_GB2312:            cs = GB2312_CHARSET;        row += Map_936.GetSize(); break; // (0xF7-0xA1+1)* 6; break;
  294.         case IDM_CP_SHIFTJIS:        cs = SHIFTJIS_CHARSET;        row += Map_932.GetSize(); break; // (0xFC-0x81+1)*12; break;
  295.         case IDM_CP_HANGUL:            cs = HANGUL_CHARSET;        row += Map_949.GetSize(); break; // (0xFD-0x81+1)*12; break;
  296.                     
  297.         case IDM_CP_UNICODE:        cs = UNICODE_CHARSET;       row += Map_UC.GetSize(); break; // 256 * 16; break;
  298.  
  299.         case IDM_VIEW_SMALL:        width = 20; break;
  300.         case IDM_VIEW_MEDIUM:        width = 40; break;
  301.         case IDM_VIEW_LARGE:        width = 60; break;
  302.     }
  303.  
  304.     int rslt = View_NoChange;
  305.             
  306.     if ( row != m_row )
  307.     {
  308.         m_row          = row;
  309.         m_nPixelWidth  = 16 * m_width + 100;
  310.         m_nPixelHeight = row * m_height + 100;
  311.         rslt           = View_Resize;
  312.     }
  313.  
  314.     if ( cs!= m_nCharSet )
  315.     {
  316.         m_nCharSet = cs;
  317.         
  318.         rslt |= View_Redraw;
  319.     }
  320.  
  321.     if ( width != m_width )
  322.     {
  323.         m_width   = width;
  324.         m_height  = width - 4;
  325.         m_font    = width - 8;
  326.  
  327.         m_nPixelWidth  = 16 * m_width + 100;
  328.         m_nPixelHeight = m_row * m_height + 100;
  329.         
  330.         rslt = View_Redraw | View_Resize;
  331.     }
  332.  
  333.     return rslt;
  334. }
  335.  
  336.  
  337. void KCharSetView::DispRow(HDC hDC, int x0, int y0, int y, WCHAR ch, int length)
  338. {
  339.     RECT rect = { x0, 
  340.                   y0 + y  * m_height,
  341.                   x0 + 15 * m_width  + m_width-1,
  342.                   y0 + y  * m_height + m_height-1 };
  343.     
  344.     if ( ! RectVisible(hDC, & rect) )
  345.         return;
  346.  
  347.     char temp[10];
  348.  
  349.     if ( length==1 )
  350.         wsprintf(temp, "%02X", ch & 0xFF);
  351.     else 
  352.         wsprintf(temp, "%04X", ch & 0xFFFF);
  353.     
  354.     int align = SetTextAlign(hDC, TA_RIGHT);
  355.  
  356.     HGDIOBJ hOld = SelectObject(hDC, m_hAnsiFont);
  357.  
  358.     TextOut(hDC, rect.left-5, rect.top, temp, strlen(temp));
  359.     SelectObject(hDC, hOld);
  360.  
  361.     SetTextAlign(hDC, align);
  362.  
  363.     for (int x=0; x<16; x++)
  364.     {
  365.         rect.right = rect.left + m_width - 1;        
  366.         
  367.         if ( length==1 )
  368.         {
  369.             char c = (char) (ch + x);
  370.             
  371.             DrawTextA(hDC, & c, 1, & rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  372.         }
  373.         else if ( length==2 )
  374.         {
  375.             char c[2] = { HIBYTE(ch), LOBYTE(ch) + x };
  376.  
  377.             DrawTextA(hDC, c, 2, & rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  378.         }
  379.         else
  380.         {
  381.             WCHAR c = ch + x;
  382.  
  383.             DrawTextW(hDC, & c, 1, & rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  384.         }
  385.  
  386.         rect.left = rect.right + 1;
  387.     }
  388. }
  389.  
  390.  
  391. int KCharSetView::OnDraw(HDC hdc, const RECT * rcPaint)
  392. {
  393.     KLogFont logfont(m_font, "Times New Roman");
  394.  
  395.     if ( m_nCharSet!=UNICODE_CHARSET )
  396.         logfont.SetCharSet(m_nCharSet);
  397.     else
  398.         logfont.SetCharSet(GB2312_CHARSET);
  399.  
  400.     HFONT hFont = logfont.Create();
  401.     HGDIOBJ hOld = SelectObject(hdc, hFont);
  402.  
  403.     int x0 = 120; int y0 = 30;
  404.  
  405.     for (int i=0; i<=m_row; i++)
  406.     {
  407.         MoveToEx(hdc, x0 + 0,          y0 + i*m_height, NULL); 
  408.         LineTo(hdc,   x0 + 16*m_width, y0 + i*m_height);
  409.  
  410.         if ( i<=16 )
  411.         {
  412.             MoveToEx(hdc, x0 + i*m_width, y0 + 0, NULL);  
  413.               LineTo(hdc, x0 + i*m_width, y0 + m_row*m_height);
  414.         }
  415.     }
  416.  
  417.     for (int y=0; y<16; y++)
  418.         DispRow(hdc, x0, y0, y, y * 16, 1);
  419.     
  420. //    const int MapBIG5[] = { 4, 5, 6, 7, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
  421.  
  422.     if ( m_row>16 )
  423.         for (y=0; y<(m_row-16); y++)
  424.             switch ( m_nCharSet )
  425.             {
  426.                 case GB2312_CHARSET:
  427.                 //    DispRow(hdc, x0, 30+16 * m_height, y, 0xA1 + y/6, 0xA0 + (y%6)*16, 2);
  428.                     DispRow(hdc, x0, 30+16 * m_height, y, Map_936.GetRowFirst(y), 2);
  429.                     break;
  430.  
  431.                 case SHIFTJIS_CHARSET:
  432.                     DispRow(hdc, x0, 30+16 * m_height, y, Map_932.GetRowFirst(y), 2);
  433.                 //    DispRow(hdc, x0, 30+16 * m_height, y, 0x81 + y/12, 0x40 + (y%12)*16, 2);
  434.                     break;
  435.  
  436.                 case CHINESEBIG5_CHARSET:
  437.                     DispRow(hdc, x0, 30+16 * m_height, y, Map_950.GetRowFirst(y), 2);
  438.                 //    DispRow(hdc, x0, 30+16 * m_height, y, 0xA1 + y/10, MapBIG5[y%10]*16, 2);
  439.                     break;
  440.  
  441.                 case HANGUL_CHARSET:
  442. //                    DispRow(hdc, x0, 30+16 * m_height, y, 0xA1 + y/12, 0x40 + (y%12)*16, 2);
  443.                     DispRow(hdc, x0, 30+16 * m_height, y, Map_949.GetRowFirst(y), 2);
  444.                     break;
  445.  
  446.                 case UNICODE_CHARSET:
  447.                     DispRow(hdc, x0, 30+16 * m_height, y, Map_UC.GetRowFirst(y), 3);
  448.             }
  449.  
  450.     SelectObject(hdc, hOld);
  451.     DeleteObject(hFont);
  452.  
  453.     return View_NoChange;
  454. }
  455.  
  456.