forked from KolibriOS/kolibrios
d3ae4b4e07
@rcher, ac97wav, midamp, rtfread: modified to use function 70 git-svn-id: svn://kolibrios.org@139 a494cfbc-eb01-0410-851d-a64ba20cac60
636 lines
11 KiB
PHP
636 lines
11 KiB
PHP
;workarea: <- RTF_work
|
|
; listptr dd savelist 0
|
|
; szKeyword rb 31 4
|
|
; szParameter rb 21 35
|
|
|
|
include 'rtftype.inc'
|
|
include 'rtfactn.inc'
|
|
|
|
read_next_block:
|
|
inc [cur_block]
|
|
read_block:
|
|
mov esi,I_END
|
|
pusha
|
|
mov ecx,[cur_block]
|
|
mov ebx,fileinfo
|
|
mov eax,ecx
|
|
shl eax,16
|
|
mov [ebx+4],eax
|
|
; mov [ebx+12],esi
|
|
mcall 70
|
|
if DEBUG_BLOCK eq 1
|
|
; dps 'B='
|
|
; dpd ecx
|
|
; dps <13,10>
|
|
end if
|
|
cmp ecx,[max_block]
|
|
je .last
|
|
mov ebx,I_END+RTFSIZE
|
|
jmp .add
|
|
.last:
|
|
mov ebx,[tail]
|
|
; dpd ebx
|
|
.add:
|
|
; dpd ebx
|
|
mov [block_end],ebx
|
|
popa
|
|
; dpd esi
|
|
; dps <13,10>
|
|
ret
|
|
;
|
|
; %%Function: ecRtfParse
|
|
;
|
|
; Step 1:
|
|
; Isolate RTF keywords and send them to ecParseRtfKeyword;
|
|
; Push and pop state at the start and end of RTF groups;
|
|
; Send text to ecParseChar for further processing.
|
|
;
|
|
macro CopySave _src,_dest
|
|
{
|
|
pusha
|
|
mov ecx,SIZE_save
|
|
mov esi,_src
|
|
mov edi,_dest
|
|
rep movsb
|
|
popa
|
|
}
|
|
|
|
RtfParse:
|
|
|
|
if BENCH eq 1
|
|
mcall 26,9
|
|
mov [bench],eax
|
|
end if
|
|
mov [RetroPtr],esi
|
|
CopySave Chp,RetroSave
|
|
push dword[Free+4]
|
|
pop dword[RetroXY]
|
|
xor eax,eax
|
|
mov [cur_block],eax
|
|
mov [RetroBlock],eax
|
|
push [cGroup]
|
|
pop [RetroGroup]
|
|
and [mode],not RTF_BLIND
|
|
mov [listptr],save_stack
|
|
mov [fileinfo.size],128*512
|
|
; test ebp,RTF_HELP
|
|
test [mode],RTF_HELP
|
|
jne .noread
|
|
call read_block
|
|
.noread:
|
|
mov [RetroPtr],esi
|
|
.nib2:
|
|
mov [nibble],2
|
|
and [b],al
|
|
.getc:
|
|
xor eax,eax
|
|
lods_block
|
|
cmp [cGroup],0
|
|
jge .ok1
|
|
Return ecStackUnderflow
|
|
.ok1:
|
|
cmp [ris],risBin
|
|
jne .nobin
|
|
RetError ecParseChar
|
|
.nobin:
|
|
cmp al,'{'
|
|
jne .nobr1
|
|
RetError ecPushRtfState
|
|
.nobr1:
|
|
cmp al,'}'
|
|
jne .nobr2
|
|
RetError ecPopRtfState
|
|
.nobr2:
|
|
cmp al,'\'
|
|
jne .noslash
|
|
RetError ecParseRtfKeyword
|
|
.noslash:
|
|
cmp al,0xd
|
|
je .getc
|
|
cmp al,0xa
|
|
je .getc
|
|
.nouc:
|
|
cmp [ris],risNorm
|
|
jne .nonorm
|
|
call ecParseChar
|
|
cmp eax,ecOutOfWindow
|
|
je .__ex
|
|
test eax,eax
|
|
je .getc
|
|
jmp .__ex
|
|
.nonorm:
|
|
cmp [ris],risHex
|
|
je .noassert
|
|
Return ecAssertion
|
|
.noassert:
|
|
shl [b],4
|
|
isdigit al, .nodig
|
|
sub al,'0'
|
|
add [b],al
|
|
jmp .nibble
|
|
.nodig:
|
|
islower al, .nolow
|
|
cmp al,'a'
|
|
jb .inval
|
|
cmp al,'f'
|
|
ja .inval
|
|
sub al,'a'-10
|
|
jmp .nib0
|
|
.inval:
|
|
if INVALHEX eq 0
|
|
jmp .getc
|
|
else
|
|
; sub esi,I_END+1
|
|
; dpd esi
|
|
; movzx eax,al
|
|
; dpd eax
|
|
; movzx eax,[b]
|
|
; dpd eax
|
|
Return ecInvalidHex
|
|
end if
|
|
.nolow:
|
|
cmp al,'A'
|
|
jb .inval
|
|
cmp al,'F'
|
|
ja .inval
|
|
sub al,'A'-10
|
|
.nib0:
|
|
add [b],al
|
|
.nibble:
|
|
dec [nibble]
|
|
cmp [nibble],0
|
|
jnz .getc
|
|
movzx eax,[b]
|
|
mov [ris],risNorm
|
|
call ecParseChar
|
|
test eax,eax
|
|
jnz .__ex
|
|
; mov [ris],risNorm
|
|
jmp .nib2
|
|
.eof:
|
|
xor eax,eax
|
|
cmp eax,[cGroup]
|
|
je .__ex
|
|
jg .unbr
|
|
Return ecStackUnderflow
|
|
.unbr:
|
|
mov eax,ecUnmatchedBrace
|
|
.__ex:
|
|
ret
|
|
nibble db 2
|
|
b db 0
|
|
RTF_maxlist dd ?
|
|
;
|
|
; %%Function: ecParseRtfKeyword
|
|
;
|
|
; Step 2:
|
|
; get a control word (and its associated value) and
|
|
; call ecTranslateKeyword to dispatch the control.
|
|
;
|
|
|
|
ecParseRtfKeyword:
|
|
; ch-al,bl-fParam, bh-fNeg
|
|
mov [ris],risNorm
|
|
xor eax,eax
|
|
xor ebx,ebx
|
|
push edx
|
|
mov [szKeyword],al
|
|
mov [szParameter],al
|
|
lods_block
|
|
isalpha al,.ctrl
|
|
jmp .alph
|
|
.ctrl:
|
|
push esi
|
|
mov esi,szKeyword
|
|
inc byte[esi]
|
|
mov [esi+1],al
|
|
mov eax,ebx
|
|
xor ebx,ebx
|
|
call ecTranslateKeyword
|
|
pop esi
|
|
jmp .__ex
|
|
.alph:
|
|
push edi
|
|
mov edi,szKeyword+1
|
|
.loop1:
|
|
stosb
|
|
inc [szKeyword]
|
|
lods_block
|
|
isalpha al,.outloop1
|
|
jmp .loop1
|
|
.outloop1:
|
|
pop edi
|
|
cmp al,'-'
|
|
jne .noneg
|
|
not bh
|
|
lods_block
|
|
.noneg:
|
|
isdigit al,.nodig
|
|
not bl
|
|
push edi
|
|
mov edi,szParameter+1
|
|
.loop2:
|
|
stosb
|
|
inc [szParameter]
|
|
lods_block
|
|
isdigit al,.outloop2
|
|
jmp .loop2
|
|
.outloop2:
|
|
pop edi
|
|
push eax esi
|
|
mov esi,szParameter
|
|
atoi
|
|
pop esi
|
|
mov edx,eax
|
|
pop eax
|
|
mov [lParam],edx
|
|
test bh,bh
|
|
jz .nodig
|
|
neg edx
|
|
.nodig:
|
|
cmp al,' '
|
|
je .space
|
|
cmp esi,I_END
|
|
jne .ok_block
|
|
dec [cur_block]
|
|
call read_block
|
|
mov esi,[block_end]
|
|
.ok_block:
|
|
dec esi
|
|
.space:
|
|
mov eax,ebx
|
|
mov ebx,edx
|
|
push esi
|
|
mov esi,szKeyword
|
|
call ecTranslateKeyword
|
|
pop esi
|
|
.__ex:
|
|
pop edx
|
|
ret
|
|
|
|
;
|
|
; %%Function: ecParseChar
|
|
;
|
|
; Route the character to the appropriate destination stream.
|
|
;
|
|
|
|
ecParseChar:
|
|
;in: ch-al, esi->rtf
|
|
cmp [ris],risBin
|
|
jne .nobin
|
|
dec [cbBin]
|
|
cmp [cbBin],0
|
|
jg .nobin
|
|
mov [ris],risNorm
|
|
.nobin:
|
|
cmp [rds],rdsColor
|
|
jne .nodelim
|
|
cmp al,';'
|
|
jne .non
|
|
mov eax,[colorptr]
|
|
cmp eax,ct_end-4
|
|
jae .non
|
|
add [colorptr],4
|
|
jmp .non
|
|
.nodelim:
|
|
cmp [rds],rdsSkip
|
|
je .non
|
|
cmp [rds],rdsNorm
|
|
je ecPrintChar
|
|
; ret
|
|
.non:
|
|
mov eax,ecOK
|
|
ret
|
|
|
|
macro PrintTrap _char
|
|
{
|
|
local .notrap
|
|
cmp byte[esi],_char
|
|
jne .notrap
|
|
sub esi,I_END
|
|
dps 'Trapped at '
|
|
dpd esi
|
|
dps <13,10>
|
|
ud2
|
|
.notrap:
|
|
}
|
|
;
|
|
; %%Function: ecPrintChar
|
|
;
|
|
; Send a character to the output file.
|
|
;
|
|
|
|
ecPrintChar:
|
|
; in:ch-al, esi - rtf pointer
|
|
; stosb
|
|
; jmp .nowrap
|
|
mov ebp,[mode]
|
|
cmp al,0xa
|
|
jne .nopar
|
|
; and ebp,not RTF_NO1STLINE
|
|
and [mode],not RTF_NO1STLINE
|
|
jmp .par
|
|
.nopar:
|
|
cmp al,0x9
|
|
jne .notab
|
|
add word[Free+6],CHARW*3
|
|
jmp .chkwrap
|
|
.notab:
|
|
xor ebx,ebx
|
|
if ~ RENDER eq FREE
|
|
cmp word[Free+4],TOP
|
|
jl .nodraw
|
|
end if
|
|
ansi2oem
|
|
mov [char],al
|
|
; PrintTrap '/'
|
|
pusha
|
|
xor eax,eax
|
|
; test [mode],RTF_BLIND
|
|
test ebp,RTF_BLIND
|
|
je .rend
|
|
; test [mode],RTF_COLORLESS
|
|
test ebp,RTF_COLORLESS
|
|
jz .setcolor
|
|
mov ecx,DEFCOLOR
|
|
jmp .rend
|
|
.setcolor:
|
|
movzx ecx,byte[Chp+3]
|
|
mov ecx,[colortbl+ecx*4]
|
|
.rend:
|
|
if RENDER eq FREE
|
|
mov ebx,Free
|
|
mov dword[ebx+32],eax
|
|
mov [ebx+28],ecx
|
|
; test [mode], RTF_BOTTOM
|
|
test ebp, RTF_BOTTOM
|
|
jne .nodraw2
|
|
cmp word[Free+4],TOP
|
|
jl .nodraw2
|
|
cmp byte[Chp],fTrue
|
|
jne .nobold
|
|
or dword[ebx+32],BGI_BOLD
|
|
.nobold:
|
|
; test [mode], RTF_BLIND
|
|
test ebp, RTF_BLIND
|
|
jne .freet
|
|
.nodraw2:
|
|
or dword[ebx+32],BGI_NODRAW
|
|
.freet:
|
|
BGIfont_Freetext
|
|
|
|
mov [Free+4],eax
|
|
test [mode],RTF_BLIND
|
|
; jmp .nohei
|
|
jne .nohei
|
|
fild word[BGIheight]
|
|
fmul dword[Free+12]
|
|
; fistp word[curheight]
|
|
fistp word[maxheight]
|
|
; movzx eax,[curheight]
|
|
; dpd eax
|
|
; cmp ax,[maxheight]
|
|
; jae .nohei
|
|
; mov [maxheight],ax
|
|
; dps 'M'
|
|
; dpd eax
|
|
|
|
; dps <13,10>
|
|
.nohei:
|
|
else
|
|
and ecx,0xffffff
|
|
mov ebx,[Free+4]
|
|
mov edx,char
|
|
mov esi,1
|
|
end if
|
|
|
|
if RENDER eq BGI
|
|
add ecx,0x44000000
|
|
cmp byte[Chp],fTrue
|
|
jne .nobold
|
|
or esi,BGI_BOLD
|
|
.nobold:
|
|
test ebp,RTF_BLIND
|
|
; test [mode],RTF_BLIND
|
|
jne .freet
|
|
or esi,BGI_NODRAW
|
|
.freet:
|
|
BGIfont_Outtext
|
|
mov [Free+4],eax
|
|
end if
|
|
|
|
if RENDER eq PIX
|
|
; test [mode],RTF_TOEOF
|
|
; jne .blind
|
|
; test [mode],RTF_BOTTOM
|
|
test ebp,RTF_BOTTOM
|
|
jne .nobold
|
|
.blind:
|
|
; test [mode],RTF_BLIND
|
|
test ebp,RTF_BLIND
|
|
je .nobold
|
|
mcall 4
|
|
cmp byte[Chp],fTrue
|
|
jne .nobold
|
|
add ebx,1 shl 16
|
|
mcall
|
|
.nobold:
|
|
end if
|
|
popa
|
|
.nodraw:
|
|
if RENDER eq PIX
|
|
add word[Free+6],CHARW
|
|
end if
|
|
movsx eax,[pitch]
|
|
add word[Free+6],ax
|
|
.chkwrap:
|
|
mov eax,dword[prcinfo+42]
|
|
cmp ax,word[Free+6]
|
|
ja .nowrap
|
|
; or ebp,RTF_NO1STLINE
|
|
or [mode],RTF_NO1STLINE
|
|
.par:
|
|
xor [mode],RTF_BLIND
|
|
; not [blind]
|
|
test [mode] ,RTF_BLIND
|
|
je .makewrap
|
|
; [blind]=false
|
|
movzx eax,word[Free+6]
|
|
sub ax,word[RetroXY+2]
|
|
push dword[RetroXY]
|
|
pop dword[Free+4]
|
|
mov [mark],0xff0000
|
|
test [mode],RTF_ALIGNLESS
|
|
jnz .letsdraw
|
|
cmp byte[Pap+12],justR
|
|
jb .letsdraw
|
|
mov [mark],0xff
|
|
mov ebx,dword[prcinfo+42] ; wnd width
|
|
sub ebx,eax
|
|
cmp byte[Pap+12],justC
|
|
jne .nocenter
|
|
shr ebx,1
|
|
mov [mark],0x00ff00
|
|
.nocenter:
|
|
mov word[Free+6],bx
|
|
.letsdraw:
|
|
; test [mode],RTF_NO1STLINE
|
|
; jnz .no1st
|
|
; add word[Free+6],60
|
|
.no1st:
|
|
if STEPBYSTEP eq 1
|
|
; movzx eax,[mode]
|
|
; dph eax
|
|
; test [mode],RTF_NO1STLINE
|
|
; jnz .no1st
|
|
; mcall 4,[RetroXY],[mark],sym,1
|
|
; dps '1st '
|
|
; .no1st:
|
|
dps <'false ',13,10>
|
|
; dpd eax
|
|
; dpd ebx
|
|
end if
|
|
if SHOWALIGN eq 1
|
|
mcall 4,[RetroXY],[mark],sym,1
|
|
end if
|
|
if STEPBYSTEP eq 1
|
|
mcall 10
|
|
mcall 2
|
|
end if
|
|
mov eax,[RetroBlock]
|
|
cmp eax,[cur_block]
|
|
je .norblock
|
|
mov [cur_block],eax
|
|
call read_block
|
|
.norblock:
|
|
mov esi,[RetroPtr]
|
|
push [RetroGroup]
|
|
pop [cGroup]
|
|
CopySave RetroSave,Chp
|
|
jmp .nowrap
|
|
.makewrap: ; second pass preparing
|
|
; [blind]=true
|
|
if STEPBYSTEP eq 1
|
|
dps 'true '
|
|
mcall 10
|
|
mcall 2
|
|
end if
|
|
mov word[Free+6],LMARGIN
|
|
if RENDER eq FREE
|
|
fld [line_space]
|
|
fimul [maxheight]
|
|
fistp [maxheight]
|
|
movzx eax,[maxheight]
|
|
add word[Free+4],ax
|
|
; and [maxheight],0
|
|
; add word[Free+4],CHARH
|
|
else
|
|
mov eax,CHARH
|
|
add word[Free+4],ax
|
|
end if
|
|
test [mode],RTF_TOEOF
|
|
je .nohdoc
|
|
add [HDoc],eax
|
|
inc [line_count]
|
|
.nohdoc:
|
|
test [mode],RTF_BOTTOM
|
|
jne .text
|
|
; dps '1'
|
|
mov ebx,dword[prcinfo+46]
|
|
cmp bx,word[Free+4]
|
|
jge .text
|
|
or [mode],RTF_BOTTOM
|
|
dps <'btm',13,10>
|
|
test [mode],RTF_TOEOF
|
|
jne .text
|
|
mov eax,ecOutOfWindow
|
|
ret
|
|
; end if
|
|
.text:
|
|
push dword[Free+4]
|
|
pop dword[RetroXY]
|
|
mov word[RetroXY+2],LMARGIN
|
|
mov [RetroPtr],esi
|
|
push [cur_block]
|
|
pop [RetroBlock]
|
|
CopySave Chp,RetroSave
|
|
push [cGroup]
|
|
pop [RetroGroup]
|
|
; if STEPBYSTEP eq 1
|
|
; mcall 10
|
|
; mcall 2
|
|
; end if
|
|
.nowrap:
|
|
mov eax,ecOK
|
|
ret
|
|
mark dd ?
|
|
sym db 0x10
|
|
line_space dd 1.6
|
|
;
|
|
; %%Function: ecPushRtfState
|
|
;
|
|
; Save relevant info on a linked list of SAVE structures.
|
|
;
|
|
|
|
ecPushRtfState:
|
|
pusha
|
|
mov edi,[listptr]
|
|
mov eax,edi
|
|
mov ecx,SIZE_save
|
|
add eax,ecx
|
|
cmp eax,save_limit
|
|
jb .malloc
|
|
Return ecStackOverflow
|
|
.malloc:
|
|
mov esi,Chp
|
|
rep movsb
|
|
mov [listptr],edi
|
|
mov [ris],risNorm
|
|
inc [cGroup]
|
|
xor eax,eax
|
|
Epilog
|
|
|
|
; %%Function: ecPopRtfState
|
|
;
|
|
; If we're ending a destination (that is, the destination is changing),
|
|
; call ecEndGroupAction.
|
|
; Always restore relevant info from the top of the SAVE list.
|
|
|
|
ecPopRtfState:
|
|
pusha
|
|
mov esi,[listptr]
|
|
cmp esi,save_stack
|
|
ja .okpop
|
|
Return ecStackUnderflow
|
|
.okpop:
|
|
movzx eax,[rds]
|
|
cmp al,[esi-2]
|
|
je .noega
|
|
RetError ecEndGroupAction, .noega
|
|
.noega:
|
|
mov ecx,SIZE_save
|
|
sub esi,ecx
|
|
mov [listptr],esi
|
|
mov edi,Chp
|
|
rep movsb
|
|
dec [cGroup]
|
|
xor eax,eax
|
|
Epilog
|
|
|
|
ansitbl:
|
|
db 0xaa,0xba,0xbf,0xaf
|
|
db 0xa7,0xa8,0xa1,0xab,0xb0,0xb2,0xb3,0xb6,0xb7,0xb8,0xb9
|
|
db 0xa2,0xbb,0x93,0x94,0x85
|
|
oematbl:
|
|
if RENDER eq PIX
|
|
db 0xf2,0xf3,0xf5,0xf4
|
|
else
|
|
db 0x85,0xa5,0x69,0x49
|
|
end if
|
|
db 0x15,0xf0,0xf6,0x22,0x1d,0x49,0x69,0x14,0x1c,0xf1,0x23
|
|
db 0xf7,0x22,0x22,0x22,0x16
|
|
uctbl:
|
|
dw 0x451
|
|
oemutbl:
|
|
db 0xb8
|