Sign in Join
Wiki copytemporary

LCL Unicode Support/ko: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## 소개
22
330.9.25 에서 라자루스는 Gtk1을 제외한 모든 플랫폼에서 유니코드를 완전하게 지원하게 되었다. 이 페이지는 FPC 2.6.4를 사용하는 라자루스 1.4 까지의 유니코드에 대해 다룬다. 2.0을 시작하면서 라자루스는 FPC 3.0+의 특징을 사용하여 유니코드 지원을 개선하였다. 자세한 내용은 다음을 보시길 : [[Unicode Support in Lazarus|라자루스에서 개선 된 유니코드 지원]]
44
55## 사용자를 위한 지침
66
77라자루스가 유니코드 위젯 세트를 가지고 있다지만 모든 것이 유니코드가 아니란 것을 알아야 한다. 문자열 인코딩의 시작이 무엇인지 알고 다른 인코딩을 필요로하는 라이브러리간에 적절히 인코딩하는 것은 개발자의 책임이다.
88
99보통 인코딩은 라이브러리 단위로 이루어진다(예를 들면, 동적 라이브러리인 DLL이나 라자루스 패키지). 각 라이브러리는 한 종류의 인코딩만을 요구하고, 이것들은 대개 Unicode(라자루스에서는 UTF-8) 또는 ANSI 이다(이것은 실제로는 시스템 인코딩으로 UTF-8 이거나 아니라는 뜻이다). 2.6 이하의 FPC의 RTL 과 FCL 은 ANSI 문자열이 필요하다.
1010
1111유니코드와 ANSI는 다음 코드를 사용하여 변환할 수 있다.
1212
1313- **UTF8ToAnsi** 와 **AnsiToUTF8**은 (FPC) System 유닛에서 기능한다.
1414- 또는 **UTF8ToSys** 와 **SysToUTF8**은 (Lazarus) FileUtil 유닛에서 기능한다.
1515
1616두번째 것이 더 빠르고 산뜻하지만 더 많은 코드가 프로그램에 들어가게 된다.
1717
1818- FileUtil:UTF8ToSys 에서 LazUTF8:UTF8ToSys 로 변경되었다. \[1.8.2버전\]
1919
2020### FPC 는 유니코드를 알고 있지 않다
2121
2222현재의 FPC버전(2.6.x 이하)에서 프리파스칼 런타임 라이브러리(RTL)과 프리파스칼 컴포넌트 라이브러리(FCL)은 ANSI라서 유니코드 라이브러리에서 가져오거나 유니코드 라이브러리로 보내는(예, LCL) 경우에는 문자열 변환이 필요하다.
2323
2424String 을 포함하여 FPC 2.7.1 계열의 개발 버전에 중요한 개선점들이 있다. RawByteString 과 UTF8String 에 대해서는 [[FPC Unicode support|FPC의 유니코드 지원]] 을 보세요.
2525
2626### ANSI 와 Unicode 간의 변환
2727
2828> **Note:** AnsiToUTF8 와 UTF8ToAnsi 는 리눅스, BSD, Mac OS X 에서 사용할 경우 widestring 관리자가 필요하다. SysToUTF8 과 UTF8ToSys 함수를 사용할 수 있다.(unit FileUtil) 또는 프로그램이 사용하는 첫번째 uses 섹션에 cwstring을 추가하여 widestring 매니저를 추가할 수 있게된다.
2929
3030예:
3131
3232TEdit에서 문자열을 얻고 어떤 RTL 파일 루틴에 문자열을 보내고 싶다고 하자.
3333
3434``` pascal
3535var
3636 MyString: string; // utf-8 로 인코드 되어 있다.
3737begin
3838 MyString := MyTEdit.Text;
3939 SomeRTLRoutine(UTF8ToAnsi(MyString));
4040end;
4141```
4242
4343반대로 보낼 경우에는:
4444
4545``` pascal
4646var
4747 MyString: string; // ANSI 로 인코드 되어 있다.
4848begin
4949 MyString := SomeRTLRoutine;
5050 MyTEdit.Text := AnsiToUTF8(MyString);
5151end;
5252```
5353
5454### Widestrings 과 Ansistrings
5555
5656widestring 은 2-바이트 크기의 요소를 가지는 기본 데이터의 문자열 타입이다. Widestring은 거의 대부분 UTF-16 로 인코딩된 데이터를 가진다. [[Widestrings|widestring]] 을 보세요
5757
5858Widestring의 배열로 억세스할 수 있는 각 데이터 포인트는 2 바이트를 가지며, UTF-16에서 문자(character)는 1 또는 2 데이터 포인트일 수 있어서, 2 또는 4 바이트를 차지할 수 있다. 이는 Widestring을 배열로 접근하고 이러한 방법으로 UTF-16 문자들을 얻으려고 하는 것은 **확실히 잘못된 것**이어서 문자열에 4 바이트 문자가 들어있을 때는 실패하게 될 것이다. 또한 UTF-8 과 마찬가지로 UTF-16은 분리되는 문자를 가질 수도 있다. 예를 들어 문자 "Á" 는 단일 문자로 인코드할 수 있거나 두개의 문자로 인코드 될 수도 있다: "A" + 수정 액센트. 그러므로 Unicode에서 엑센트 문자를 가진 문장은 다양한 방법으로 인코딩 될 수 있어서 라자루스나 FPC는 자동으로 이들을 다룰 수가 없다.
5959
6060Ansistrings 를 Widestrings 로 전달할 때 인코딩을 변환해야 한다.
6161
6262``` pascal
6363var
6464 w: widestring;
6565begin
6666 w:='Über'; // 틀림, FPC 는 시스템 코드페이지를 UTF16 로 변경할 것이다.
6767 w:=UTF8ToUTF16('Über'); // 맞음
6868 Button1.Caption:=UTF16ToUTF8(w);
6969end;
7070```
7171
7272### UTF8 문자열 과 문자들
7373
7474Lazarus 0.9.30 까지 UTF-8 핸들링 루틴은 LCLProc 유닛 내의 LCL에 있었다. 라자루스 0.9.31+에서 LCLProc 내의 루틴들은 여전히 호환성 문제 때문에 쓸모가 있으나 UTF-8을 다루는 실제코드는 lazutf8 유닛내의 lazutils 패키지에 있다. UTF-8 문자열상에서 실행하기 위해서는 프리파스칼에서 온 SysUtils 루틴 대신에 lazutf8 유닛에 있는 루틴을 사용하는게 좋은데 이는, SysUtils 은 유니코드를 다룰 준비가 되어있지 않으나, lazutf8은 사용할 준비가 되어있기 때문이다. 간단히 Sysutils의 루틴을 lazutf8에 있는 같은 루틴으로 바꾸면 되는데 UTF8 선행사가 붙은 것을 제외하고는 이름이 같기 때문이다.
7575
7676#### UTF-8 String Copy, Length, LowerCase, 등등
7777
7878UTF-8문자열로 실행하기 원하는 거의 모든 동작들은 lazutf 유닛의 루틴으로 대치할 수 있다.(라자루스 0.9.30 이상에서는 LCLProc 유닛) 다음과 같이 lazurf8.pas 에서 나온 루틴의 리스트를 보세요
7979
8080``` pascal
8181function UTF8CharacterLength(p: PChar): integer; // 문자의 길이
8282function UTF8Length(const s: string): PtrInt; // 문자열의 길이
8383function UTF8Length(p: PChar; ByteCount: PtrInt): PtrInt;
8484function UTF8CharacterToUnicode(p: PChar; out CharLen: integer): Cardinal;
8585function UnicodeToUTF8(u: cardinal; Buf: PChar): integer; inline;
8686function UnicodeToUTF8SkipErrors(u: cardinal; Buf: PChar): integer;
8787function UnicodeToUTF8(u: cardinal): shortstring; inline;
8888function UTF8ToDoubleByteString(const s: string): string;
8989function UTF8ToDoubleByte(UTF8Str: PChar; Len: PtrInt; DBStr: PByte): PtrInt;
9090function UTF8FindNearestCharStart(UTF8Str: PChar; Len: integer;
9191 BytePos: integer): integer;
9292// n-번째 UTF8 문자를 찿으며, BIDI 는 무시한다.
9393function UTF8CharStart(UTF8Str: PChar; Len, CharIndex: PtrInt): PChar;
9494// n-번째 UTF8 문자릐 바이트 인덱스를 찾되, BIDI (substr 의 바이트 길이)는 무시한다.
9595function UTF8CharToByteIndex(UTF8Str: PChar; Len, CharIndex: PtrInt): PtrInt;
9696procedure UTF8FixBroken(P: PChar);
9797function UTF8CharacterStrictLength(P: PChar): integer;
9898function UTF8CStringToUTF8String(SourceStart: PChar; SourceLen: PtrInt) : string;
9999function UTF8Pos(const SearchForText, SearchInText: string): PtrInt;
100100function UTF8Copy(const s: string; StartCharIndex, CharCount: PtrInt): string;
101101procedure UTF8Delete(var s: String; StartCharIndex, CharCount: PtrInt);
102102procedure UTF8Insert(const source: String; var s: string; StartCharIndex: PtrInt);
103103
104104function UTF8LowerCase(const AInStr: string; ALanguage: string=''): string;
105105function UTF8UpperCase(const AInStr: string; ALanguage: string=''): string;
106106function FindInvalidUTF8Character(p: PChar; Count: PtrInt;
107107 StopOnNonASCII: Boolean = false): PtrInt;
108108function ValidUTF8String(const s: String): String;
109109
110110procedure AssignUTF8ListToAnsi(UTF8List, AnsiList: TStrings);
111111
112112//비교 함수
113113
114114function UTF8CompareStr(const S1, S2: string): Integer;
115115function UTF8CompareText(const S1, S2: string): Integer;
116116```
117117
118118### 디렉토리 및 파일 이름 다루기
119119
120120라자루스는 UTF-인코딩에서 파일명과 디렉토리명을 제외하고 조절 또는 동작하지만, RTL은 디렉토리 및 파일명에서는 ANSI 스트링을 사용한다.
121121
122122예를 들면, TFileListBox 의 디렉토리 속성을 현재 디렉토리로 설정하는 버튼을 놓아보자. RTL 함수 [[doc:rtl/sysutils/getcurrentdir.html|GetCurrentDir]] 는 ANSI로 Unicode가 아니므로 변환이 필요하다.
123123
124124``` pascal
125125procedure TForm1.Button1Click(Sender: TObject);
126126begin
127127 FileListBox1.Directory:=SysToUTF8(GetCurrentDir);
128128 // 또는 FileUtil 유닛의 함수를 사용하거나
129129 FileListBox1.Directory:=GetCurrentDirUTF8;
130130end;
131131```
132132
133133FileUtil 유닛은 UTF-8 문자열에 관한 공통 파일들을 정의하고 있다.
134134
135135``` pascal
136136// RTL 과 유사하지만 시스템 인코딩 대신 UTF-8 로 동작하는 기본 함수들
137137
138138// AnsiToUTF8 과 UTF8ToAnsi 은 Linux, BSD, Mac OS X에서는 widestring 매니저가 필요하다.
139139// 하지만 이 OS들은 UTF-8 이 기본 시스템 인코딩이기 때문에 widestring 매니저가 필요하지는 않다.
140140function NeedRTLAnsi: boolean;// 시스템 인코딩이 UTF-8이 아니면 true
141141procedure SetNeedRTLAnsi(NewValue: boolean);
142142function UTF8ToSys(const s: string): string;// UTF8ToAnsi 와 같으나 widestring 매니저에 보다 더 독립적이다
143143function SysToUTF8(const s: string): string;// AnsiToUTF8 과 같으나 widestring 매니저에 보다 더 독립적이다
144144
145145// 파일 동작
146146function FileExistsUTF8(const Filename: string): boolean;
147147function FileAgeUTF8(const FileName: string): Longint;
148148function DirectoryExistsUTF8(const Directory: string): Boolean;
149149function ExpandFileNameUTF8(const FileName: string): string;
150150function ExpandUNCFileNameUTF8(const FileName: string): string;
151151{$IFNDEF VER2_2_0}
152152function ExtractShortPathNameUTF8(Const FileName : String) : String;
153153{$ENDIF}
154154function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
155155function FindNextUTF8(var Rslt: TSearchRec): Longint;
156156procedure FindCloseUTF8(var F: TSearchrec);
157157function FileSetDateUTF8(const FileName: String; Age: Longint): Longint;
158158function FileGetAttrUTF8(const FileName: String): Longint;
159159function FileSetAttrUTF8(const Filename: String; Attr: longint): Longint;
160160function DeleteFileUTF8(const FileName: String): Boolean;
161161function RenameFileUTF8(const OldName, NewName: String): Boolean;
162162function FileSearchUTF8(const Name, DirList : String): String;
163163function FileIsReadOnlyUTF8(const FileName: String): Boolean;
164164function GetCurrentDirUTF8: String;
165165function SetCurrentDirUTF8(const NewDir: String): Boolean;
166166function CreateDirUTF8(const NewDir: String): Boolean;
167167function RemoveDirUTF8(const Dir: String): Boolean;
168168function ForceDirectoriesUTF8(const Dir: string): Boolean;
169169
170170// 환경
171171function ParamStrUTF8(Param: Integer): string;
172172function GetEnvironmentStringUTF8(Index : Integer): String;
173173function GetEnvironmentVariableUTF8(const EnvVar: String): String;
174174function GetAppConfigDirUTF8(Global: Boolean): string;
175175```
176176
177177### 윈도우에서 동아시아 언어 들
178178
179179윈도우즈 XP 상의 사용자 인터페이스 컨트롤의 기본 폰트 (Tahoma)는 여러 스크립트/알파벳/언어들을 정확히 표시할 수 있다. 이 언어에는 아라비아, 러시아(Cyrillic 알파벳) 과 서양 언어(라틴/그리스 알파벳)이 해당되며, 한국어, 중국어, 일본어 같은 동아시아 언어는 해당되지 않는다.
180180
181181간단하게 제어판으로가서 지역 설정을 선택하고, 언어 탭을 클릭하고 동아시아 언어팩을 설치하면, 표준 사용자 인터페이스 폰트는 이 언어들을 정확히 표현할 수 있다.이러한 언어에 지역특성화 된 윈도우즈 XP 버전은 이 언어팩을 이마 설치하고 있다. 더 많은 설명은 [여기에](http://newton.uor.edu/Departments&Programs/AsianStudiesDept/Language/asianlanguageinstallation_XP.html)
182182
183183이후의 윈도우즈 버전은 이 언어에 대한 지원을 하고 있다.
184184
185185### UTF-8의 사용
186186
187187자세한 것은 [[UTF8 strings and characters|UTF-8 문자열과 문자를]] 보세요
188188
189189## Free Pascal Particularities
190190
191191### UTF8 와 소스 파일 - the missing BOM
192192
193193라자루스로 소스파일을 만들거나 비-ASCII 문자들을 사용하면 파일은 UTF-8로 저장된다. 이것은 **BOM** (Byte Order Mark)을 사용하지 **않는다**. 소스 에디터 상에서 오른쪽 마우스 클릭하여 / File Settings / Encoding 을 선택하여 인코딩을 설정할 수 있다. UTF-8이 BOM을 갖지 않는 것과는 별도로, BOM이 없는 것은 FPC 가 Ansistring을 다루는 방법 때문이다. 호환성 때문에 LCL은 Ansistring 을 사용하고 이식성 때문에 LCL은 UTF8을 사용한다.
194194
195195Note: 어떤 MS 윈도우즈 텍스트 에디터는 이 파일들을 시스템 코드페이지(OEM 코드페이지)로 인코드하고 부정확한 문자로 표시한다. **BOM 을 추가하면 안된다** 만약 BOM을 추가했다면 모든 문자열 할당을 변경해야만 한다.
196196
197197예를 들면:
198198
199199``` pascal
200200Button1.Caption := 'Über';
201201```
202202
203203BOM 이 없다면 (그리고 코드페이지를 모른다면) 컴파일러는 문자열을 시스템 인코딩으로 다루고 각 바이트를 변환없이 문자열로 복사한다. 이것이 LCL이 문자열을 요구하는 방법이다.
204204
205205``` pascal
206206// 소스파일은 BOM이 없이 UTF 로 저장
207207if FileExists('Über.txt') then ; // 잘못 됨, FileExists 는 시스템 인코딩을 필요로 함
208208if FileExistsUTF8('Über.txt') then ; // 맞음
209209```
210210
211211## Unicode essentials
212212
213213Unicode 표준은 정수 0부터 10FFFF(h) 까지 문자들에 매핑한다. 각 매핑은 코드포인트라고 부른다. 다른말로 말하면, Unicode 문자는 다른 말로 말하면 원칙적으로 코드 포인트는 U+000000 에서 U+10FFFF (0에서 1 114 111) 까지로 정의한다.
214214
215215Unicode 코드 포인트를 유일한 바이트 순서로 표현하는데는 세가지 방법이 있다. 이 방법들은 유니코드 변환 포맷이라고 부르다: UTF-8, UTF-16 및 UTF-32. 이들간에는 모두 변환이 가능하다. 다음에 기초적인 특성을 보여주었다.
216216
217217`                           UTF-8 UTF-16 UTF-32`\
218218`가장 작은 코드 포인트 [hex]    000000 000000 000000`\
219219`가장 큰 토드 포인트  [hex]    10FFFF 10FFFF 10FFFF`\
220220`코드 단위 크기 [bits]           8     16     32`\
221221`문자당 최소 바이트 수             1      2      4`\
222222`문자당 최대 바이트 수             4      4      4`
223223
224224**UTF-8**은 몇가지 중요하고도 유용한 특징이 있다: 이것은 바이트의 순서로 번역 되므로 lo- 와 hi-순서 바이트라는 개념이 없다. U+000 에서 U+007E(ASCII)의 유니코드 문자는 00h에서 7Fh(아스키 호환성)로 간단히 인코드 된다. 7-비트 아스키 문자들을 가진 화일과 문자들은 아스키와 UTF-8에서 모두 같은 인코등을 갖는 다는 것을 의미한다. U+007F를 넘는 모든 문자들은 몇개 바이트의 순서로 인코딩 되어 각각은 두개의 MSB 셋트를 가지게 된다. 더 긴 바이트의 다른 문자에서는 문자의 바이트 순서가 있는 바이트를 얻을 수 있다. 이것은 부분 문자열을 쉽게 검색할 수 있도록 한다. 멀티 바이트(비-아스키 문자를 말함) 중 첫번째는 항상 C0h에서 FDh 사이이며 이것은 이 문자에 대해 얼마나 많은 바이트가 가능한지를 표시하는 것이다. 멀티바이트 순서에서 모든 다른 바이트는 80h에서 BFh 사이에 있어 쉽게 동기화할 수 있게 한다.
225225
226226**UTF-16** 은 다음과 같은 중요한 속성이 있다: 이는 U+0000에서 U+d7ff까지의 단일한 16-비트 워드를 인코딩에 사용하고 나머지 유니코드 문자를 인코딩하기 위해 16-비트 워드 쌍을 사용한다.
227227
228228마지막으로 모든 유니코드 문자는 **UTF-32**에서 단일한 4 바이트/32-비트 유닛으로 표시할 수 있다.
229229
230230더 자세히 보기: [Unicode FAQ - Basic questions](http://www.unicode.org/faq/basic_q.html), [Unicode FAQ - UTF-8, UTF-16, UTF-32 & BOM](http://www.unicode.org/faq/utf_bom.html), [Wikipedia: UTF-8](http://en.wikipedia.org/wiki/UTF-8) [1](http://en.wikipedia.org/wiki/ISO-8859)
231231
232232# 상세한 구현
233233
234234## 라자루스/LCL 은 보통 UTF-8만 사용한다
235235
236236라자루스 0.9.31에서 GTK1 인터페이스에서는 톡특해서 루틴에서 다른 인코딩을 사용할 수 있는 표시를 하지 않았다면, 모든 LCL 인터페이스는 Unicode가 가능하고 LCL을 사용하며 UTF-8로 인코드 된 문자열만 사용할 수 있다.
237237
238238## win32 인터페이스에서 Unicode를 가능하게 하기
239239
240240### 개관
241241
242242무선 가장 중요한 것은 Win32 인터페이스로 패치된 모든 유니코드는 IFDEF WindowsUnicodeSupport 로 끝나야 ANSI 인터페이스가 깨지는 것을 피할 수 있다. 이렇게 안정화 된 후, 모든 ifdefs는 제거되면 Unicode 부분만 남게 될 것이다. 이 싯점에서 ANSI 문자를 사용하는 모든 프로그램은 Unicode로의 이전이 필요하다.
243243
244244### Win9x 상에서 Unicode 미지원
245245
246246Win 9x 이하의 윈도우즈 플랫폼은 ISO 코드 페이지 표준에 기초를 두었기 때문에 유니코드를 부분적으로만 지원할 뿐이다. Windows NT로 윈도우즈 플랫폼 (예, windows 200, XP, Vista, 7, 8) 및 Windows CE는 Unicode를 모두 지원한다. Win 9x 와 NT는 두가지의 API함수를 나란히 지원한다: 이전의 ANSI 가 가능한 *A 와 새로운 Unicode 가 가능한 *W. *W 함수는 wide string을 - UTF-16인코딩 문자열 - 파라메터로 받아들인다.
247247
248248Windows 9x 는 모든 *W 함수를 가지지만 모두 빈 함수 뿐이어서 할 수 있는 것이 없다. 단지 몇개의 *W 함수만이 9x에서 구현되어 있을 뿐이다: 이 들은 다음 섹션인 "Windows 9x에 존재하는 Wide 함수" 에 리스트하였다. 이 속성은 하나의 어플리케이션이 Win9x 와 WinNT 에서 동작할 수 있게 하며 사용할 수 있는 API셋을 실행 시에 찾을 수 있게 한다.
249249
250250Windows CE는 Wide API 함수만을 지원한다.
251251
252252### Wide 함수들이 Windows 9x상에 존재한다
253253
254254몇몇 Wide API 함수가 윈도우즈 9x상에 존재한다. 다음에 그 함수에 관한 리스트가 있다: <http://support.microsoft.com/kb/210341>
255255
256256변환 예:
257257
258258``` pascal
259259GetTextExtentPoint32(hdcNewBitmap, LPSTR(ButtonCaption),
260260Length(ButtonCaption), TextSize);
261261```
262262
263263이렇게:
264264
265265``` pascal
266266{$ifdef WindowsUnicodeSupport}
267267 GetTextExtentPoint32W(hdcNewBitmap, PWideChar(Utf8Decode(ButtonCaption)), Length(WideCaption), TextSize);
268268{$else}
269269 GetTextExtentPoint32(hdcNewBitmap, LPSTR(ButtonCaption), Length(ButtonCaption), TextSize);
270270{$endif}
271271```
272272
273273#### Ansi 와 Wide 버전을 필요로 하는 함수들
274274
275275첫 변환 예:
276276
277277``` pascal
278278function TGDIWindow.GetTitle: String;
279279var
280280 l: Integer;
281281begin
282282 l := Windows.GetWindowTextLength(Handle);
283283 SetLength(Result, l);
284284 Windows.GetWindowText(Handle, @Result[1], l);
285285end;
286286```
287287
288288이렇게:
289289
290290``` pascal
291291function TGDIWindow.GetTitle: String;
292292var
293293 l: Integer;
294294 AnsiBuffer: string;
295295 WideBuffer: WideString;
296296begin
297297
298298{$ifdef WindowsUnicodeSupport}
299299
300300if UnicodeEnabledOS then
301301begin
302302 l := Windows.GetWindowTextLengthW(Handle);
303303 SetLength(WideBuffer, l);
304304 l := Windows.GetWindowTextW(Handle, @WideBuffer[1], l);
305305 SetLength(WideBuffer, l);
306306 Result := Utf8Encode(WideBuffer);
307307end
308308else
309309begin
310310 l := Windows.GetWindowTextLength(Handle);
311311 SetLength(AnsiBuffer, l);
312312 l := Windows.GetWindowText(Handle, @AnsiBuffer[1], l);
313313 SetLength(AnsiBuffer, l);
314314 Result := AnsiToUtf8(AnsiBuffer);
315315end;
316316
317317{$else}
318318
319319 l := Windows.GetWindowTextLength(Handle);
320320 SetLength(Result, l);
321321 Windows.GetWindowText(Handle, @Result[1], l);
322322
323323{$endif}
324324
325325end;
326326```
327327
328328### 스크린 샷
329329
330-<figure>
331-<img src="Lazarus_Unicode_Test.png" title="Lazarus_Unicode_Test.png" />
332-<figcaption>Lazarus_Unicode_Test.png</figcaption>
333-</figure>
330+![](/wiki-images/4/49/Lazarus_Unicode_Test.png)
334331
335332# FPC 코드 페이지
336333
337334컴파일러 (FPC)는 명령어 옵션 *-Fc*(에를 들면, *-Fcutf8*) 및 동일한 표현인 *codepage* 지시어(예, *{\$codepage utf8}*)을 소스 코드에 넣어 코드페이지를 지정하는 것을 지원한다. 이런 경우, 프로그램에서 문자열 상수를 표현하는 바이트를 문자 그대로 복사하기 보다는 컴파일러가 코드페이지에 따라 모든 문자 데이터를 해석하도록 하는 것이 좋다.
338335
339336두가지 가 있다:
340337
341338- 유닉스 플랫폼에서, uses 절에 *swstring*을 추가하여 widestring 매니저를 포함했는지 확인하고, 없다면 프로그램은 실행시 모든 문자 데이터를 정확히 변환할 수 없을 것이다. 유닛이 프로그램이 libc에 종속되게 했을 것이기 때문에 이것이 디폴트는 아니어서 크로스-컴파일을 어렵게 한다.
342339- 컴파일러는 비-아스키 문자를 가진 모든 문자열 상수를 widesring 상수로 변환한다. 이는 자동적을 ansistring으로 변환된다(컴파일시 혹은 실행시), 하지만 이는 두 문자를 합치거나 단일 문자열 상수에 ordinal 값이 있다면 경고를 보여 준다:
343340
344341예를 들면:
345342
346343``` pascal
347344program project1;
348345{$codepage utf8}
349346{$mode objfpc}{$H+}
350347{$ifdef unix}
351348uses cwstring;
352349{$endif}
353350var
354351 a,b,c: string;
355352begin
356353 a:='ä';
357354 b:='='#$C3#$A4; // #$C3#$A4 is UTF-8 for ä
358355 c:='ä='#$C3#$A4;
359356 writeln(a,b); // writes ä=ä
360357 writeln(c); // writes ä=ä
361358end.
362359```
363360
364361컴파일하고 실행하면, 이렇게 쓸 것이다:
365362
366363 ä=ä
367364 ä=ä
368365
369366이유는 *ä* 이 나타나 위에 언급한 대로 'c'에 해당하는 상수 문자열의 나머지 부분이 widestring으로 분류 되기 때문이다. 결과적으로 \#\$C3 와 \#\$A4 는 ansichar 대신 widechar(#\$C3) 와 widechar(#\$A4) 로 해석된다.
370367
371368# 더 보기
372369
373370- [[Character and string types|문자와 문자열 타입]]
374371- [[UTF-8]] - UTF-8 문자열 설명
375372- [[FPC Unicode support|FPC 유니코드 지원]]
376373- [[for-in loop|for-in_loop#Traversing_UTF-8_strings]] - UTF8문자열을 통달하는 방법을 보여주는 코드
377374- [[unicode use cases|유니코드 사용 예]]
378375
379376---
380377*From the Free Pascal wiki, page "LCL Unicode Support/ko", as it stood on 2020-02-19 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history