C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[43140] Re:Re:비트맵 폰트를 이용한 shift-jis 출력
elliclaura [kiss2u] 2171 읽음    2006-01-01 04:43
. 님이 쓰신 글 :
: elliclaura 님이 쓰신 글 :
: : unsigned int TForm1::sjis2num(unsigned int code)
: : {
: :     unsigned int cl, ch;
: :     /* to jis */
: :     ch = (code >> 8) & 0xFF;
: :     cl = code & 0xFF;
: :
: :     ch -= (ch > 0x9F) ? 0xC1: 0x81;
: :     if (cl >= 0x9F) {
: :         ch = (ch << 1) + 0x22;
: :         cl -= 0x7E;
: :     } else {
: :         ch = (ch << 1) + 0x21;
: :         cl -= ((cl <= 0x7E) ? 0x1F: 0x20);
: :     }
: :     /* to num */
: :     if (ch > 0x2A){
: :         return (cl - 0x40 + (ch - 0x25) * 96) << 5;
: :     }else{
: :         return (cl - 0x20 + (ch - 0x20) * 96) << 5;
: : }
: :
: : 먼저 하려고 하는 작업은 첨부된 비트맵폰트(16X16)를 이용해서
: : 일본어(shift-jis)코드를 뿌려주려고 합니다.
: : 폰트를 읽어서 화면에 출력 하는 부분은 되었습니다만,
: : 해당 일본어문자의 s-jis코드를 가지고 fnt파일내의 오프셋 주소를 계산하는게 여의치 않습니다.
: :
: : 예를 들어 ぁ,あ 의 경우 0x829F, 0x82A0 입니다. 이것의 fnt내 시작주소는 0x3140, 0x3160이 되지요
: : 제 나름데로 여러 자료 찾아가며 구현하여 일단 위 소스라는 약간 어의없는결과물이 나왔습니다. 계산하면 0x3040이 나오더군요. ㅡㅡ; 그리고 폰트가 그냥 쭉 이어진 도 아니고 중간중간 건너뛰기도 하고 해서
: : 어지럽네요.
: :
: : 아시는 분 계시면 설명 부탁 드리고 싶습니다.
:
:
: #define IsValidSJISLeadByte(c) ( ((c)>=0x81&&(c)<=0x9F) || ((c)>=0xE0&&(c)<=0xFC) )
: //#define IsValidSJISTrailByte(c) ( ((c)>=0x40&&(c)<=0x7E) || ((c)>=0x80&&(c)<=0xFC) )
: #define IsValidSJISTrailByte(c) ( ((c)>=0x40&&(c)<=0x7E) || ((c)>=0x80&&(c)<=0xEF) )
: #define IsValidSJISCharCode(c) ( IsValidSJISLeadByte((c)&0xff) &&  IsValidSJISTrailByte(((c)>>8)&0xFF) )
: int FontIndexFromCharCodeSJIS(DWORD charcode)
: {
: /* Code Page: 932 */
: /* Valid Lead Byte : 0x81~0x9F, 0xE0~0xFC(0xE0~0xEF) */
: /* Valid Trail Byte : 0x40~0x7E, 0x80~0xFC */
:  if(!IsValidSJISCharCode(charcode)) return -1;
:  static const int char_count_per_page = 0xFC-0x40;
:  int lb,tb,page,offset;
:  lb = charcode&0xFF;
:  tb = (charcode>>8)&0xff;
:  if(lb<=0x9F) page=lb-0x81;
:  else  page=(0x9F-0x80)+lb-0xE0;
:  if(tb<0x7F) offset = tb-0x40;
:  else  offset = tb-0x40-1; /* Strip 0x7F */
:  return (page*char_count_per_page+offset);
: }
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
:  int fontindex=FontIndexFromCharCodeSJIS(charcode);
:  if(fontindex<0){
:   //오류처리
:    return;
:  }
:
:   // 파일 선두로부터 0x70 * 32 위치에서 실제 폰트 정보가 시작됨  (32는 폰트 하나의 바이트수)
:  int font_info_pos = (fontindex + 0x70) * 32;
:  //여기에서 작업
: }
:
: 참고로,
: "예를 들어 ぁ,あ 의 경우 0x829F, 0x82A0 입니다"라고 말씀하셨는데요,
: 사실은 그게 아닙니다.
: 아래가 맞습니다. 
: ぁ: 0x9F82
: あ: 0xA082
:
: "Lead bytes are unique to double-byte character sets (DBCS). A lead byte is the first byte of a 2-byte character in a DBCS. Lead bytes occupy a specific range of byte values."

먼저 답변 감사합니다.
답변 주신거 확인전에 해결했습니다.
제가 사용한 방법은

jis.fnt 의 앞부분은 아스키코드와 반각문자를 위한 8x16으로 되어 있고,
전각 s-jis 코드는 16x16으로 되어있습니다.
.
jis.fnt 구조에 대해 부연설명을 하면 s-jis 코드배열 XX40~XXFC 형태로 연달아 저장되어 있고,
XX7F 는 빠져있습니다.


아래는 16x16 s-jis 코드로부터 jis.fnt 파일 오프셋 얻는 부분입니다.
unsigned int cl, ch;

// 상위, 하위 바이트 분리
ch = (code >> 8) & 0xFF;
cl = code & 0xFF;

// s-jis 첫코드 0x8140 를 뺀다.
ch -= 0x81;
cl -= 0x40;

// s-jis 코드가 0x8140 ~ 0x9FFC, 0xE040 ~ 0xEAXX 이므로, 중간의 공백 0x4000 을 뺀다.
if (ch > 0x1E) ch -= 0x40;

// XX7F 코드 제거
if (cl >= 0x3F) cl -= 1;

// 상위코드당 0xBC개(XX40~XXFC, 0x7F제외)가 저장되어 있고, 반각문자 0x70개의 오프셋을 더한다.
// 한 문자당 32바이트를 차지한다.
return (ch * 0xBC + cl + 0x70) * 32;

이렇게 구현하여 처리하였습니다. ^^;
DOS시절 DOS/V없이 DOSJP라는 램상주 일본어 표출 프로그램(?)을 제작하셨던 분의 도움을 받았습니다.
휴 이걸로 한시름 놓았네요. 이젠 사전검색을 통해 히라가나>칸지(한자)부를 구현하러 전 이만...

+ -

관련 글 리스트
43116 비트맵 폰트를 이용한 shift-jis 출력 elliclaura 1461 2005/12/29
43125     Re:비트맵 폰트를 이용한 shift-jis 출력 . 1233 2005/12/30
43140         Re:Re:비트맵 폰트를 이용한 shift-jis 출력 elliclaura 2171 2006/01/01
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.