Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

Obsah / Utility / CHARSET / CharFromUnicode

Zdrojový kód: INCLUDE\UTIL\CHARSET.INC, UTIL\CHARSET.ASM


CharFromUnicode - Konverze znaku z kódu Unicode

Funkce CharFromUnicode zkonvertuje znak z kódu Unicode do 1-bajtového kódu.


; -----------------------------------------------------------------------------
;                      Convert character from Unicode
; -----------------------------------------------------------------------------
; INPUT:	EAX = Unicode character
;		EBX = character set structure CHARSET (only singlebyte allowed)
;		DL = invalid character (0=use default character)
; OUTPUT:	EAX = single byte character (0 to 255, EAX <- DL on error)
;		CY = invalid character (EAX <- DL on error)
; NOTES:	Character set must be singlebyte.
; -----------------------------------------------------------------------------

Na vstupu funkce obsahuje registr EAX Unicode kód konvertovaného znaku, registr DL znak, který se použije v případě neplatného znaku, a registr EBX ukazatel na znakovou sadu CHARSET. Je povolena pouze 1-bajtová znaková sada (není funkcí kontrolováno). Na výstupu funkce obsahuje registr EAX 1-bajtový kód zkonvertovaného znaku. Pokud není znak v příslušné znakové sadě podporován, navrátí funkce příznak chyby CY a registr EAX je naplněn neplatným znakem z registru DL.


; ------------- Characters 0 to 7fh are not converted

CharFromUnicode:cmp	eax,byte 7fh	; will have character the same code?
		ja	CharFromUni2	; character will be converted
		clc			; clear error flag
		ret

Má-li znak kód v rozsahu 0 až 7Fh, navrátí se beze změny, protože znaky v tomto rozsahu jsou shodné u všech znakových sad.


; ------------- Check maximal allowed character code

CharFromUni2:	cmp	eax,FONTMAX	; check max. Unicode character
		ja	CharFromUni8	; invalid character

Má-li znak vyšší hodnotu než maximální podporovaný znak FONTMAX, funkce se ukončí s chybou.


; ------------- Push registers

		push	ecx		; push ECX
		push	eax		; push EAX

; ------------- Get page (-> ECX)

		movzx	ecx,ah		; ECX <- page (256 characters)
		shl	ecx,2		; ECX <- offset of page address
		add	ecx,[ebx+CHSET_FromUni] ; ECX <- page address
		mov	ecx,[ecx]	; ECX <- page
		jecxz	CharFromUni6	; page is not valid

K vyhledání odpvídajícího 1-bajtového kódu znaku se použije hashovaná převodní tabulka CHSET_FromUni z popisovače CHARSET. Vyšší bajt kódu znaku se použije jako index, s jehož pomocí se obdrží ukazatel na konverzní stránku. Je-li ukazatel na konverzní stránku nulový, je znak neplatný a funkce se ukončí s chybou.


; ------------- Get character (-> EAX)

		movzx	eax,al		; EAX <- character offset
		mov	al,[ecx+eax]	; EAX <- character
		or	eax,eax		; is character valid?
		jz	CharFromUni6	; character is not valid

; ------------- OK, pop registers (here is NC)

		pop	ecx		; destroy EAX
		pop	ecx		; pop ECX
		ret

Nižší bajt znaku se použije jako index v konverzní stránce, s jehož pomocí se načte kód odpovídajícího 1-bajtového znaku. Je-li kód znaku nulový, funkce se navrátí s chybou.


; ------------- Error, pop registers

CharFromUni6:	pop	eax		; pop EAX
		pop	ecx		; pop ECX

; ------------- Error, invalid character

CharFromUni8:	or	dl,dl		; use default character?
		jnz	CharFromUni9	; no default character
		call	UniCharToASCII	; get ASCII alternative
		stc			; set error flag
		ret

CharFromUni9:	movzx	eax,dl		; EAX <- invalid character
		stc			; set error flag
		ret

Není-li pro danou znakovou sadu k dispozici odpovídající znak, navrátí se funkce s chybou. Obsahuje-li registr DL nenulovou hodnotu, navrátí se při chybě jeho obsah jako náhradní chybový znak. Je-li obsah registru DL nulový, použije se automatický náhradní znak. Za automatický náhradní znak se použije ASCII alternativa znaku, čímž se znak nahradí nejpodobnějším znakem z ASCII tabulky.


Obsah / Utility / CHARSET / CharFromUnicode