-
Notifications
You must be signed in to change notification settings - Fork 1
/
RTL.pbp
262 lines (226 loc) · 5.07 KB
/
RTL.pbp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
; Right-to-Left script support
#ifdef __comment
Logic for main loop:
Modes:
normal - moving right, printing -> scanning
scanning - moving right, not printing -> printing
printing - moving left, printing -> skipping
skipping - moving right, not printing -> normal
scanning = 0
0: normal >> p
1+: scanning >> .
-1-: printing << p
+0x7F: skipping >> .
iter = mkiter
curr_char = iter.currchar
curr_char_adv = advance(curr_char)
adv_till_now = 0
while 1:
if scanning < 0: # printing
next_full_adv = adv_till_now - curr_char_adv
else:
next_full_adv = adv_till_now + curr_char_adv
if next_full_adv > max_adv:
if scanning > 0 and scanning != 0x7f:
GOTO switch_to_printing
break
if scanning <= 0:
calculate points
print()
if scanning < 0:
iter.prev()
scanning ++
if scanning == 0:
scanning = 0x7f
else:
iter.next()
if iter.ended:
if scanning > 0 and scanning != 0x7f: # scanning
GOTO switch_to_printing
adv_till_now = next_full_adv
break
if iter.currchar == '\n':
if scanning > 0 and scanning != 0x7f: # scanning
GOTO switch_to_printing
...
adv_till_now = next_full_adv
break
if scanning == 0 and is_rtl_starter:
scanning++
if scanning > 0 and scanning != 0x7f and is_rtl_stopper:
GOTO switch_to_printing
if scanning == 0x7f and is_rtl_stopper:
scanning = 0
curr_char_adv = advance(curr_char)
if scanning > 0 and scanning != 0x7f: # scanning
_tmp = # ??? FIXME XXX
adv_till_now = next_full_adv
continue
switch_to_printing:
scanning = -scanning
iter.prev()
continue
rollback etc
#endif
{
proc mainloop
; before was: stock initialization
STR R9, [SP, 0xC] ; instead of next_full_adv_cache
MOV R9, 0 ; it will contain our scanning flag
loop:
LDR R2, [SP, 0x14] ; added_char_advance
LDR R3, [SP, 0x10] ; max_allowed_width
CMP R9, 0
BLT printing_1 ; if <0
; not printing
ADD R12, R11, R7
ADD R2, R12
CMP R2, R3
BLE p1_cont
; should either stop or switch to printing
CMP R9, 0
BLE break
CMP R9, 0x7f
BEQ break
B switch_to_printing
printing_1:
SUB R12, R11, R7
ADD R2, R12
p1_cont:
CMP R9, 0
BGT not_print
; print
LDR R2, [R4, 4] ; linedata.box_origin
LDR R0, [R6, 0xC] ; TLI.font
LDRH R8, [R4, 4] ; linedata.box_origin.x
STR R2, [SP, 0x24] ; charrect.origin
STRH R7, [SP, 0x28] ; charrect.size.w
BL gfont_get_max_height
ADD R3, R11, R8
STRH R0, [SP, 0x2A] ; charrect.size.h
STRH R3, [SP, 0x24] ; charrect.origin.x
LDR R3, [SP, 0x28] ; charrect.size
STR R3, [SP, 0] ; a0: rect.size
MOV R0, R10 ; gctx?
LDR R3, [SP, 0x24] ; R3: charrect.origin
STR R5, [SP, 4] ; a1: codepoint
MOV R1, R6 ; R1: tli
MOV R2, R4 ; R2: linedata
LDR R8, [SP, 0xC]
BLX R8
not_print:
CMP R9, 0
BLT printing_2
; not printing
;iter.next()
ADD R0, SP, 0x2C ; pciter
LDR R8, [SP, 0x4C] ; currchar
BL iterator_next
CBZ R0, ended
LDR R5, [SP, 0x4C] ; currchar
CMP R5, 0xA ; \n
BNE not_ended
LDR R3, [SP, 0x1C] ; overflow_is_fill
CBZ R3, ended
MOV R5, ' '
not_ended:
B p2_cont
ended:
CMP R9, 0
BLE ended_indeed
CMP R9, 0x7F
BNE switch_to_printing
ended_indeed:
MOV R11, R12
B break
printing_2:
ADD R0, SP, 0x2C ; pciter
LDR R8, [SP, 0x4C] ; currchar
BL iterator_prev
ADD R9, 1
CBNZ R9, dont_switch
MOV R9, 0x7f
dont_switch:
p2_cont:
CMP R9, 0
BEQ regular
BLT p3_cont
; looking for stopper
MOV R0, R5
BL is_rtl_stopper
CBZ R0, p3_cont
CMP R9, 0x7f
BNE switch_to_printing
MOV R9, 0 ; -> regular
B p3_cont
regular:
MOV R0, R5
BL is_rtl_starter
CBZ R0, p3_cont
MOV R9, 1 ; -> scanning
p3_cont:
LDR R0, [SP, 0x18] ; text_ctx
LDR R1, [R6, 0xC] ; TLI.font
MOV R2, R5 ; charcode
BL text_layout_get_char_advance
MOV R7, R0
MOV R11, R12
B loop
switch_to_printing:
SUB R9, 0, R9
iter.prev()
B loop
break:
B end_of_loop
}
{
proc is_rtl_starter
; R0: charcode
; returns: R0=1 if RTL char
PUSH {R1}
MOV R1, 0x202E ; RTL override
CMP R0,R1
BEQ ret1
MOV R1, 0x0590 ; start of hebrew
CMP R0, R1
BLT ret0
MOV R1, 0x06FF ; end of arabic
CMP R0, R1
BLE ret1
ret0:
MOV R0, 0
B ret
ret1:
MOV R0, 1
ret:
POP {R1}
BX LR
}
{
proc is_rtl_stopper
PUSH {R1}
MOV R1, 0x202D ; LTR override
CMP R0,R1
BEQ ret1
CMP R0, '0'
BLT ret0
BMP R0, '9'
BLE ret1
CMP R0, 'A'
BLT ret0
CMP R0, 'Z'
BLE ret1
CMP R0, 'a'
BLT ret0
CMP R0, 'z'
BLE ret1
; TODO cyrillic
ret0:
MOV R0, 0
B ret
ret1:
MOV R0, 1
ret:
POP {R1}
BX LR
}