kolibrios/programs/rtfread/trunk/rtf_lite.inc
Andrey Halyavin (halyavin) 065b8d32b2 programs sources added
git-svn-id: svn://kolibrios.org@31 a494cfbc-eb01-0410-851d-a64ba20cac60
2006-01-03 09:43:31 +00:00

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,7
mov [ebx+4],eax
; mov [ebx+12],esi
mcall 58
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
; 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