View difference between Paste ID: gF2tHgib and qFpjSz0w
SHOW: | | - or go back to the newest paste.
1
class UWindowHTMLTextArea expands UWindowDynamicTextArea;
2
3
/*
4
5
HTML Currently Supported
6
========================
7
8
Parsed on add
9
-------------
10
<body bgcolor=#ffffff link=red alink=#yellow>...</body>
11
<font color=#ffffff bgcolor=#ffffff>...</font>
12
<br>
13
<center>....</center>
14
<p>
15
<h1>...</h1>
16
17
Parsed on add and display
18
-------------------------
19
<nobr>...</nobr>
20
<a href="...">...</a>
21
<b>...</b>
22
<u>...</u>
23
<blink>...</blink>
24
25
Parsed only on display
26
----------------------
27
&gt;
28
&lt;
29
&amp;
30
&nbsp;
31
32
Planned improvements
33
--------------------
34
<ul><li>item 1<li>item 2...</ul>
35
<table>...</table>
36
37
Bugs
38
----
39
The parsing is pretty slack!
40
41
*/
42
43
// default styles
44
var Color TextColor;
45
var Color BGColor;
46
var Color LinkColor;
47
var Color ALinkColor;
48
var float LastBlinkTime;
49
var bool bShowBlink;
50
var bool bReleased;
51
52
function SetHTML(string HTML)
53
{
54
	Clear();
55
	ReplaceText(HTML, Chr(13)$Chr(10), " ");
56
	ReplaceText(HTML, Chr(13), " ");
57
	ReplaceText(HTML, Chr(10), " ");
58
	AddText(HTML);
59
}
60
61
function BeforePaint(Canvas C, float X, float Y)
62
{
63
	Super.BeforePaint(C, X, Y);
64
	Cursor = Root.NormalCursor;
65
}
66
67
function Paint(Canvas C, float X, float Y)
68
{
69
	C.DrawColor = BGColor;
70
	DrawStretchedTexture(C, 0, 0, WinWidth, WinHeight, Texture'WhiteTexture');
71
	Super.Paint(C, X, Y);
72
	bReleased = False;
73
}
74
75
function Click(float X, float Y)
76
{
77
	Super.Click(X, Y);
78
	bReleased = True;
79
}
80
81
function ProcessURL(string URL)
82
{
83
	Log("Clicked Link: >>"$URL$"<<");
84
85
	if ( Left(URL, 7) ~= "mailto:" )
86
		GetPlayerOwner().ConsoleCommand("start "$URL);
87
	if ( Left(URL, 7) ~= "http://" )
88
		GetPlayerOwner().ConsoleCommand("start "$URL);
89
	if ( Left(URL, 8) ~= "https://" )
90
		GetPlayerOwner().ConsoleCommand("start "$URL);
91
	if ( Left(URL, 6) ~= "ftp://" )
92
		GetPlayerOwner().ConsoleCommand("start "$URL);
93
	if ( Left(URL, 9) ~= "telnet://" )
94
		GetPlayerOwner().ConsoleCommand("start "$URL);
95
	if ( Left(URL, 9) ~= "gopher://" )
96
		GetPlayerOwner().ConsoleCommand("start "$URL);
97
	if ( Left(URL, 4) ~= "www." )
98
		GetPlayerOwner().ConsoleCommand("start http://"$URL);
99
	if ( Left(URL, 4) ~= "ftp." )
100
		GetPlayerOwner().ConsoleCommand("start ftp://"$URL);
101
	else if ( Left(URL, 9) ~= "unreal://" )
102
		LaunchUnrealURL(URL);
103
}
104
105
function OverURL(string URL)
106
{
107
}
108
109
function LaunchUnrealURL(string URL)
110
{
111
	GetPlayerOwner().ClientTravel(URL, TRAVEL_Absolute, false);
112
}
113
114
function TextAreaTextSize(Canvas C, string Text, out float W, out float H)
115
{
116
	ReplaceText(Text, "&nbsp;", " ");
117
	ReplaceText(Text, "&gt;", ">");
118
	ReplaceText(Text, "&lt;", "<");
119
	ReplaceText(Text, "&amp;", "&");
120
121
	TextSize(C, Text, W, H);
122
}
123
124
function TextAreaClipText(Canvas C, float DrawX, float DrawY, coerce string Text, optional bool bCheckHotkey, optional color Col )
125
{
126
	ReplaceText(Text, "&nbsp;", " ");
127
	ReplaceText(Text, "&gt;", ">");
128
	ReplaceText(Text, "&lt;", "<");
129
	ReplaceText(Text, "&amp;", "&");
130
131
	ClipText(C, DrawX, DrawY, Text, bCheckHotKey);
132
}
133
134
///////////////////////////////////////////////////////
135
// Overloaded functions from UWindowDynamicTextArea
136
///////////////////////////////////////////////////////
137
138
function WrapRow(Canvas C, UWindowDynamicTextRow L)
139
{
140
	local HTMLStyle CurrentStyle;
141
	local UWindowHTMLTextRow R;
142
	local string Input, LeftText, HTML, RightText;
143
144
	Super.WrapRow(C, L);
145
146
	// Generate the DisplayString and StyleString lines for each row
147
	R = UWindowHTMLTextRow(L);
148
	while (R != None && (R == L || R.WrapParent == L))
149
	{
150
		R.DisplayString = "";
151
		R.StyleString = "";
152
153
		CurrentStyle = R.StartStyle;
154
155
		Input = R.Text;
156
		while (Input != "")
157
		{
158
			ParseHTML(Input, LeftText, HTML, RightText);
159
160
			if (LeftText != "" || R.DisplayString == "")
161
			{
162
				R.DisplayString = R.DisplayString $ LeftText;
163
				R.StyleString = R.StyleString $ WriteStyleText(CurrentStyle, Len(LeftText));
164
			}
165
166
			ProcessInlineHTML(HTML, CurrentStyle);
167
			SetCanvasStyle(C, CurrentStyle);
168
169
			Input = RightText;
170
		}
171
172
		R = UWindowHTMLTextRow(R.Next);
173
	}
174
}
175
176
function float DrawTextLine(Canvas C, UWindowDynamicTextRow L, float Y)
177
{
178
	local float X, W, H, MouseX, MouseY;
179
	local HTMLStyle CurrentStyle;
180
	local float RowHeight;
181
	local Color OldColor;
182
	local int StylePos, DisplayPos, i;
183
	local string S;
184
185
	RowHeight = 0;
186
187
	CurrentStyle = UWindowHTMLTextRow(L).StartStyle;
188
	if (CurrentStyle.bCenter)
189
	{
190
		W = CalcHTMLTextWidth(C, L.Text, CurrentStyle);
191
		if (VertSB.bWindowVisible)
192
			X = int(((WinWidth - VertSB.WinWidth) - W) / 2);
193
		else
194
			X = int((WinWidth - W) / 2);
195
	}
196
	else
197
		X = 2;
198
199
	if (GetEntryLevel().TimeSeconds > LastBlinkTime + 0.5)
200
	{
201
		bShowBlink = !bShowBlink;
202
		LastBlinkTime = GetEntryLevel().TimeSeconds;
203
	}
204
205
	if (UWindowHTMLTextRow(L).DisplayString == "")
206
		SetCanvasStyle(C, CurrentStyle);
207
	else
208
	{
209
		while (DisplayPos < Len(UWindowHTMLTextRow(L).DisplayString))
210
		{
211
			i = ReadStyleText(UWindowHTMLTextRow(L).StyleString, StylePos, CurrentStyle);
212
			S = Mid(UWindowHTMLTextRow(L).DisplayString, DisplayPos, i);
213
			DisplayPos += i;
214
			SetCanvasStyle(C, CurrentStyle);
215
216
			TextAreaTextSize(C, S, W, H);
217
			if (H > RowHeight)
218
				RowHeight = H;
219
220
			if (CurrentStyle.bLink)
221
			{
222
				GetMouseXY(MouseX, MouseY);
223
				if (X < MouseX && X + W > MouseX && Y < MouseY && Y + H > MouseY)
224
				{
225
					Cursor = Root.HandCursor;
226
					OverURL(CurrentStyle.LinkDestination);
227
228
					if (bMouseDown || bReleased)
229
					{
230
						if (bReleased)
231
						{
232
							ProcessURL(CurrentStyle.LinkDestination);
233
							bReleased = False;
234
						}
235
						else
236
							C.DrawColor = ALinkColor;
237
					}
238
				}
239
			}
240
241
			if (CurrentStyle.BGColor != BGColor)
242
			{
243
				OldColor = C.DrawColor;
244
				C.DrawColor = CurrentStyle.BGColor;
245
				DrawStretchedTexture(C, X, Y, W, H, Texture'WhiteTexture');
246
				C.DrawColor = OldColor;
247
			}
248
			if (!CurrentStyle.bBlink || bShowBlink)
249
				TextAreaClipText(C, X, Y, S);
250
			if (CurrentStyle.bLink || CurrentStyle.bUnderline)
251
				DrawStretchedTexture(C, X, Y+H-1, W, 1, Texture'WhiteTexture');
252
253
			X += W;
254
		}
255
	}
256
	if (RowHeight == 0)
257
		TextAreaTextSize(C, "A", W, RowHeight);
258
259
	return RowHeight;
260
}
261
262
function UWindowDynamicTextRow SplitRowAt(UWindowDynamicTextRow L, int SplitPos)
263
{
264
	local UWindowDynamicTextRow N;
265
	local HTMLStyle CurrentStyle;
266
267
	N = Super.SplitRowAt(L, SplitPos);
268
269
	// update the style by processing from the start of L to the split position.
270
	UWindowHTMLTextRow(N).EndStyle = UWindowHTMLTextRow(L).EndStyle;
271
	CurrentStyle = UWindowHTMLTextRow(L).StartStyle;
272
	HTMLUpdateStyle(L.Text, CurrentStyle);
273
	UWindowHTMLTextRow(L).EndStyle = CurrentStyle;
274
	UWindowHTMLTextRow(N).StartStyle = CurrentStyle;
275
276
	return N;
277
}
278
279
function RemoveWrap(UWindowDynamicTextRow L)
280
{
281
	local UWindowDynamicTextRow N;
282
283
	// copy final endstyle to current row
284
	N = UWindowDynamicTextRow(L.Next);
285
	while (N != None && N.WrapParent == L)
286
	{
287
		UWindowHTMLTextRow(L).EndStyle = UWindowHTMLTextRow(N).EndStyle;
288
		N = UWindowDynamicTextRow(N.Next);
289
	}
290
291
	Super.RemoveWrap(L);
292
}
293
294
function int GetWrapPos(Canvas C, UWindowDynamicTextRow L, float MaxWidth)
295
{
296
	local float LineWidth, NextWordWidth;
297
	local string Input, NextWord;
298
	local int WordsThisRow, WrapPos;
299
	local HTMLStyle CurrentStyle;
300
301
	CurrentStyle = UWindowHTMLTextRow(L).StartStyle;
302
303
	// quick check
304
	if (CalcHTMLTextWidth(C, L.Text, CurrentStyle) <= MaxWidth)
305
		return -1;
306
307
	Input = L.Text;
308
	WordsThisRow = 0;
309
	LineWidth = 0;
310
	WrapPos = 0;
311
	NextWord = "";
312
	CurrentStyle = UWindowHTMLTextRow(L).StartStyle;
313
314
	while (Input != "" || NextWord != "")
315
	{
316
		if (NextWord == "")
317
		{
318
			RemoveNextWord(Input, NextWord);
319
			NextWordWidth = CalcHTMLTextWidth(C, NextWord, CurrentStyle);
320
		}
321
		if (WordsThisRow > 0 && LineWidth + NextWordWidth > MaxWidth)
322
		{
323
			return WrapPos;
324
		}
325
		else
326
		{
327
			WrapPos += Len(NextWord);
328
			LineWidth += NextWordWidth;
329
			NextWord = "";
330
			WordsThisRow++;
331
		}
332
	}
333
	return -1;
334
}
335
336
// Find the next word - but don't split up HTML tags.
337
function RemoveNextWord(out string Text, out string NextWord)
338
{
339
	local int i;
340
	local bool bInsideTag;
341
	local string Ch;
342
343
	bInsideTag = False;
344
345
	for (i=0; i<Len(Text); i++)
346
	{
347
		Ch = Mid(Text, i, 1);
348
		if (Ch == ">")
349
			bInsideTag = False;
350
		if (Ch == "<")
351
			bInsideTag = True;
352
		if (Ch == " " && !bInsideTag)
353
			break;
354
	}
355
	while (Mid(Text, i, 1) == " ")
356
		i++;
357
	NextWord = Left(Text, i);
358
	Text = Mid(Text, i);
359
}
360
361
function UWindowDynamicTextRow AddText(string NewLine, optional color TxtCol )
362
{
363
	local string Input, Output, LeftText, RightText, HTML, Temp;
364
	local int i;
365
	local UWindowDynamicTextRow L;
366
	local HTMLStyle CurrentStyle, StartStyle;
367
368
	if (List.Last == List)
369
	{
370
		CurrentStyle.BulletLevel = 0;
371
		CurrentStyle.LinkDestination = "";
372
		CurrentStyle.TextColor = TextColor;
373
		CurrentStyle.BGColor = BGColor;
374
		CurrentStyle.bCenter = bHCenter;
375
		CurrentStyle.bLink = False;
376
		CurrentStyle.bUnderline = False;
377
		CurrentStyle.bNoBR = False;
378
		CurrentStyle.bHeading = False;
379
		CurrentStyle.bBold = False;
380
		CurrentStyle.bBlink = False;
381
	}
382
	else
383
		CurrentStyle = UWindowHTMLTextRow(List.Last).EndStyle;
384
	StartStyle = CurrentStyle;
385
386
	// convert \\n's -> <br>'s
387
	i = InStr(NewLine, "\\n");
388
	while (i != -1)
389
	{
390
		NewLine = Left(NewLine, i) $ "<br>" $ Mid(NewLine, i + 2);
391
		i = InStr(NewLine, "\\n");
392
	}
393
394
	Input = NewLine;
395
	Output = "";
396
	while (Input != "")
397
	{
398
		ParseHTML(Input, LeftText, HTML, RightText);
399
400
		switch (GetTag(HTML))
401
		{
402
			// multiline HTML tags
403
		case "P":
404
			if ((Output $ LeftText) != "")
405
			{
406
				L = Super.AddText(Output $ LeftText);
407
				Output = "";
408
				UWindowHTMLTextRow(L).StartStyle = StartStyle;
409
				UWindowHTMLTextRow(L).EndStyle = CurrentStyle;
410
			}
411
			StartStyle = CurrentStyle;
412
			L = Super.AddText("");
413
			UWindowHTMLTextRow(L).StartStyle = StartStyle;
414
			UWindowHTMLTextRow(L).EndStyle = CurrentStyle;
415
			break;
416
		case "BR":
417
			L = Super.AddText(Output $ LeftText);
418
			Output = "";
419
			UWindowHTMLTextRow(L).StartStyle = StartStyle;
420
			UWindowHTMLTextRow(L).EndStyle = CurrentStyle;
421
			StartStyle = CurrentStyle;
422
			break;
423
		case "BODY":
424
			Temp = GetOption(HTML, "BGCOLOR=");
425
			if (Temp != "")
426
			{
427
				BGColor = ParseColor(Temp);
428
				CurrentStyle.BGColor = BGColor;
429
				StartStyle.BGColor = BGColor;
430
			}
431
432
			Temp = GetOption(HTML, "LINK=");
433
			if (Temp != "")
434
				LinkColor = ParseColor(Temp);
435
436
			Temp = GetOption(HTML, "ALINK=");
437
			if (Temp != "")
438
				ALinkColor = ParseColor(Temp);
439
440
			Temp = GetOption(HTML, "TEXT=");
441
			if (Temp != "")
442
			{
443
				TextColor = ParseColor(Temp);
444
				CurrentStyle.TextColor = TextColor;
445
			}
446
			Output = Output $ LeftText;
447
			break;
448
		case "CENTER":
449
			if ((Output $ LeftText) != "")
450
			{
451
				L = Super.AddText(Output $ LeftText);
452
				Output = "";
453
				UWindowHTMLTextRow(L).StartStyle = StartStyle;
454
				UWindowHTMLTextRow(L).EndStyle = CurrentStyle;
455
			}
456
			CurrentStyle.bCenter = True;
457
			StartStyle = CurrentStyle;
458
			break;
459
		case "/CENTER":
460
			L = Super.AddText(Output $ LeftText);
461
			Output = "";
462
			UWindowHTMLTextRow(L).StartStyle = StartStyle;
463
			UWindowHTMLTextRow(L).EndStyle = CurrentStyle;
464
			CurrentStyle.bCenter = False;
465
			StartStyle = CurrentStyle;
466
			break;
467
			// Inline HTML tags
468
		case "H1":
469
			if ((Output $ LeftText) != "")
470
			{
471
				L = Super.AddText(Output $ LeftText);
472
				Output = "";
473
				UWindowHTMLTextRow(L).StartStyle = StartStyle;
474
				UWindowHTMLTextRow(L).EndStyle = CurrentStyle;
475
			}
476
			CurrentStyle.bHeading = True;
477
			StartStyle = CurrentStyle;
478
			break;
479
		case "/H1":
480
			L = Super.AddText(Output $ LeftText);
481
			Output = "";
482
			UWindowHTMLTextRow(L).StartStyle = StartStyle;
483
			UWindowHTMLTextRow(L).EndStyle = CurrentStyle;
484
			CurrentStyle.bHeading = False;
485
			StartStyle = CurrentStyle;
486
			break;
487
		case "FONT":
488
			Output = Output $ LeftText $ HTML;
489
			Temp = GetOption(HTML, "COLOR=");
490
			if (Temp != "")
491
				CurrentStyle.TextColor = ParseColor(Temp);
492
			Temp = GetOption(HTML, "BGCOLOR=");
493
			if (Temp != "")
494
				CurrentStyle.BGColor = ParseColor(Temp);
495
			break;
496
		case "/FONT":
497
			Output = Output $ LeftText $ HTML;
498
			CurrentStyle.TextColor = TextColor;
499
			CurrentStyle.BGColor = BGColor;
500
			break;
501
		case "B":
502
			Output = Output $ LeftText $ HTML;
503
			CurrentStyle.bBold = True;
504
			break;
505
		case "/B":
506
			Output = Output $ LeftText $ HTML;
507
			CurrentStyle.bBold = False;
508
			break;
509
		case "U":
510
			Output = Output $ LeftText $ HTML;
511
			CurrentStyle.bUnderline = True;
512
			break;
513
		case "/U":
514
			Output = Output $ LeftText $ HTML;
515
			CurrentStyle.bUnderline = False;
516
			break;
517
		case "A":
518
			Output = Output $ LeftText $ HTML;
519
			CurrentStyle.bLink = True;
520
			CurrentStyle.LinkDestination = GetOption(HTML, "HREF=");
521
			break;
522
		case "/A":
523
			Output = Output $ LeftText $ HTML;
524
			CurrentStyle.bLink = False;
525
			CurrentStyle.LinkDestination = "";
526
			break;
527
		case "NOBR":
528
			Output = Output $ LeftText $ HTML;
529
			CurrentStyle.bNoBR = True;
530
			break;
531
		case "/NOBR":
532
			Output = Output $ LeftText $ HTML;
533
			CurrentStyle.bNoBR = False;
534
			break;
535
		case "BLINK":
536
			Output = Output $ LeftText $ HTML;
537
			CurrentStyle.bBlink = True;
538
			break;
539
		case "/BLINK":
540
			Output = Output $ LeftText $ HTML;
541
			CurrentStyle.bBlink = False;
542
			break;
543
		default:
544
			Output = Output $ LeftText;
545
			break;
546
		}
547
		Input = RightText;
548
	}
549
550
	L = Super.AddText(Output);
551
	UWindowHTMLTextRow(L).StartStyle = StartStyle;
552
	UWindowHTMLTextRow(L).EndStyle = CurrentStyle;
553
554
	return L;
555
}
556
557
///////////////////////////////////////////////////
558
// HTML Text Processing
559
///////////////////////////////////////////////////
560
561
// Get the next HTML tag, the text before it and everthing after it.
562
function ParseHTML(string Input, out string LeftText, out string HTML, out string RightText)
563
{
564
	local int i;
565
566
	i = InStr(Input, "<");
567
	if (i == -1)
568
	{
569
		LeftText = Input;
570
		HTML = "";
571
		RightText = "";
572
		return;
573
	}
574
575
	LeftText = Left(Input, i);
576
	HTML = Mid(Input, i);
577
578
	i = InStr(HTML, ">");
579
	if (i == -1)
580
	{
581
		RightText = "";
582
		return;
583
	}
584
585
	RightText = Mid(HTML, i+1);
586
	HTML = Left(HTML, i+1);
587
}
588
589
function float CalcHTMLTextWidth(Canvas C, string Text, out HTMLStyle CurrentStyle)
590
{
591
	local string Input, LeftText, HTML, RightText;
592
	local float W, H, Width;
593
594
	Width = 0;
595
	Input = Text;
596
	while (Input != "")
597
	{
598
		ParseHTML(Input, LeftText, HTML, RightText);
599
600
		SetCanvasStyle(C, CurrentStyle);
601
		TextAreaTextSize(C, LeftText, W, H);
602
		Width += W;
603
604
		ProcessInlineHTML(HTML, CurrentStyle);
605
606
		Input = RightText;
607
	}
608
609
	return Width;
610
}
611
612
// Update CurrentStyle based on the contents of the HTML tag provided
613
function ProcessInlineHTML(string HTML, out HTMLStyle CurrentStyle)
614
{
615
	local string Temp;
616
617
	if (HTML == "")
618
		return;
619
620
	switch (GetTag(HTML))
621
	{
622
	case "H1":
623
		CurrentStyle.bHeading = True;
624
		break;
625
	case "/H1":
626
		CurrentStyle.bHeading = False;
627
		break;
628
	case "FONT":
629
		Temp = GetOption(HTML, "COLOR=");
630
		if (Temp != "")
631
			CurrentStyle.TextColor = ParseColor(Temp);
632
		Temp = GetOption(HTML, "BGCOLOR=");
633
		if (Temp != "")
634
			CurrentStyle.BGColor = ParseColor(Temp);
635
		break;
636
	case "/FONT":
637
		CurrentStyle.TextColor = TextColor;
638
		CurrentStyle.BGColor = BGColor;
639
		break;
640
	case "B":
641
		CurrentStyle.bBold = True;
642
		break;
643
	case "/B":
644
		CurrentStyle.bBold = False;
645
		break;
646
	case "U":
647
		CurrentStyle.bUnderline = True;
648
		break;
649
	case "/U":
650
		CurrentStyle.bUnderline = False;
651
		break;
652
	case "A":
653
		CurrentStyle.bLink = True;
654
		CurrentStyle.LinkDestination = GetOption(HTML, "HREF=");
655
		break;
656
	case "/A":
657
		CurrentStyle.bLink = False;
658
		CurrentStyle.LinkDestination = "";
659
		break;
660
	case "NOBR":
661
		CurrentStyle.bNoBR = True;
662
		break;
663
	case "/NOBR":
664
		CurrentStyle.bNoBR = False;
665
		break;
666
	case "BLINK":
667
		CurrentStyle.bBlink = True;
668
		break;
669
	case "/BLINK":
670
		CurrentStyle.bBlink = False;
671
		break;
672
	}
673
}
674
675
// update the current style based on some text input
676
function HTMLUpdateStyle(string Input, out HTMLStyle CurrentStyle)
677
{
678
	local string LeftText, HTML, RightText;
679
680
	while (Input != "")
681
	{
682
		ParseHTML(Input, LeftText, HTML, RightText);
683
		ProcessInlineHTML(HTML, CurrentStyle);
684
		Input = RightText;
685
	}
686
}
687
688
final function string GetOption(string HTML, string Option)
689
{
690
	local int i, j;
691
	local string s;
692
693
	i = InStr(Caps(HTML), Caps(Option));
694
695
	if (i == 1 || Mid(HTML, i-1, 1) == " ")
696
	{
697
		s = Mid(HTML, i+Len(Option));
698
		j = FirstMatching(InStr(s, ">"), InStr(s, " "));
699
		s = Left(s, j);
700
701
		if (Left(s, 1) == "\"")
702
			s = Mid(s, 1);
703
704
		if (Right(s, 1) == "\"")
705
			s = Left(s, Len(s) - 1);
706
707
		return s;
708
	}
709
	return "";
710
}
711
712
final function string GetTag(string HTML)
713
{
714
	local int i;
715
716
	if (HTML == "")
717
		return "";
718
719
	HTML = Mid(HTML, 1); // lose <
720
721
	i = FirstMatching(InStr(HTML, ">"), InStr(HTML, " "));
722
	if (i == -1)
723
		return Caps(HTML);
724
	else
725
		return Caps(Left(HTML, i));
726
}
727
728
function Color ParseColor(string S)
729
{
730
	local Color C;
731
732
	if (Left(S, 1) == "#")
733
		S = Mid(S, 1);
734
735
	if ( S~="red" )
736
	{
737
		C.R = 255;
738
		C.G = 0;
739
		C.B = 0;
740
	}
741
	else if ( S~="blue" )
742
	{
743
		C.R = 0;
744
		C.G = 0;
745
		C.B = 255;
746
	}
747
	else if ( S~="green" )
748
	{
749
		C.R = 0;
750
		C.G = 255;
751
		C.B = 0;
752
	}
753
	else if ( S~="yellow" )
754
	{
755
		C.R = 255;
756
		C.G = 255;
757
		C.B = 0;
758
	}
759
	else if ( S~="white" )
760
	{
761
		C.R = 255;
762
		C.G = 255;
763
		C.B = 255;
764
	}
765
	else if ( S~="black" )
766
	{
767
		C.R = 0;
768
		C.G = 0;
769
		C.B = 0;
770
	}
771
	else
772
	{
773
		C.R = 16 * GetHexDigit(Mid(S, 0, 1)) + GetHexDigit(Mid(S, 1, 1));
774
		C.G = 16 * GetHexDigit(Mid(S, 2, 1)) + GetHexDigit(Mid(S, 3, 1));
775
		C.B = 16 * GetHexDigit(Mid(S, 4, 1)) + GetHexDigit(Mid(S, 5, 1));
776
	}
777
778
	return C;
779
}
780
781
final function int GetHexDigit(string D)
782
{
783
	switch (caps(D))
784
	{
785
	case "0":
786
		return 0;
787
	case "1":
788
		return 1;
789
	case "2":
790
		return 2;
791
	case "3":
792
		return 3;
793
	case "4":
794
		return 4;
795
	case "5":
796
		return 5;
797
	case "6":
798
		return 6;
799
	case "7":
800
		return 7;
801
	case "8":
802
		return 8;
803
	case "9":
804
		return 9;
805
	case "A":
806
		return 10;
807
	case "B":
808
		return 11;
809
	case "C":
810
		return 12;
811
	case "D":
812
		return 13;
813
	case "E":
814
		return 14;
815
	case "F":
816
		return 15;
817
	}
818
819
	return 0;
820
}
821
822
function int FirstMatching(int i, int j)
823
{
824
	if (i == -1)
825
		return j;
826
827
	if (j == -1)
828
		return i;
829
	else
830
		return Min(i, j);
831
}
832
833
function SetCanvasStyle(Canvas C, HTMLStyle CurrentStyle)
834
{
835
	if (CurrentStyle.bLink)
836
		C.DrawColor = LinkColor;
837
	else
838
		C.DrawColor = CurrentStyle.TextColor;
839
840
	if (CurrentStyle.bHeading)
841
		C.Font = Root.Fonts[F_LargeBold];
842
	else if (CurrentStyle.bBold)
843
		C.Font = Root.Fonts[F_Bold];
844
	else
845
		C.Font = Root.Fonts[F_Normal];
846
}
847
848
function string WriteStyleText(HTMLStyle CurrentStyle, int CharCount)
849
{
850
	local string Pad;
851
	local string Temp;
852
	local string Output;
853
854
	Pad = "0000";
855
856
	Temp = string(CharCount);
857
	Output = Left(Pad, 4 - Len(Temp)) $ Temp;
858
859
	Temp = string(Len(CurrentStyle.LinkDestination));
860
	Output = Output $ Left(Pad, 4 - Len(Temp)) $ Temp $ CurrentStyle.LinkDestination;
861
862
	Temp = string(CurrentStyle.TextColor.R);
863
	Output = Output $ Left(Pad, 3 - Len(Temp)) $ Temp;
864
	Temp = string(CurrentStyle.TextColor.G);
865
	Output = Output $ Left(Pad, 3 - Len(Temp)) $ Temp;
866
	Temp = string(CurrentStyle.TextColor.B);
867
	Output = Output $ Left(Pad, 3 - Len(Temp)) $ Temp;
868
869
	Temp = string(CurrentStyle.BGColor.R);
870
	Output = Output $ Left(Pad, 3 - Len(Temp)) $ Temp;
871
	Temp = string(CurrentStyle.BGColor.G);
872
	Output = Output $ Left(Pad, 3 - Len(Temp)) $ Temp;
873
	Temp = string(CurrentStyle.BGColor.B);
874
	Output = Output $ Left(Pad, 3 - Len(Temp)) $ Temp;
875
876
	if (CurrentStyle.bCenter)
877
		Output = Output $ "T";
878
	else
879
		Output = Output $ "F";
880
881
	if (CurrentStyle.bLink)
882
		Output = Output $ "T";
883
	else
884
		Output = Output $ "F";
885
886
	if (CurrentStyle.bUnderline)
887
		Output = Output $ "T";
888
	else
889
		Output = Output $ "F";
890
891
	if (CurrentStyle.bNoBR)
892
		Output = Output $ "T";
893
	else
894
		Output = Output $ "F";
895
896
	if (CurrentStyle.bHeading)
897
		Output = Output $ "T";
898
	else
899
		Output = Output $ "F";
900
901
	if (CurrentStyle.bBold)
902
		Output = Output $ "T";
903
	else
904
		Output = Output $ "F";
905
906
	if (CurrentStyle.bBlink)
907
		Output = Output $ "T";
908
	else
909
		Output = Output $ "F";
910
911
	return Output;
912
}
913
914
function int ReadStyleText(string StyleString, out int StylePos, out HTMLStyle CurrentStyle)
915
{
916
	local int CharCount;
917
	local int i;
918
919
	CharCount = Int(Mid(StyleString, StylePos, 4));
920
	StylePos += 4;
921
922
	i = Int(Mid(StyleString, StylePos, 4));
923
	StylePos += 4;
924
925
	CurrentStyle.LinkDestination = Mid(StyleString, StylePos, i);
926
	StylePos += i;
927
928
	CurrentStyle.TextColor.R = Int(Mid(StyleString, StylePos, 3));
929
	StylePos += 3;
930
	CurrentStyle.TextColor.G = Int(Mid(StyleString, StylePos, 3));
931
	StylePos += 3;
932
	CurrentStyle.TextColor.B = Int(Mid(StyleString, StylePos, 3));
933
	StylePos += 3;
934
935
	CurrentStyle.BGColor.R = Int(Mid(StyleString, StylePos, 3));
936
	StylePos += 3;
937
	CurrentStyle.BGColor.G = Int(Mid(StyleString, StylePos, 3));
938
	StylePos += 3;
939
	CurrentStyle.BGColor.B = Int(Mid(StyleString, StylePos, 3));
940
	StylePos += 3;
941
942
	CurrentStyle.bCenter = Mid(StyleString, StylePos++, 1) == "T";
943
	CurrentStyle.bLink = Mid(StyleString, StylePos++, 1) == "T";
944
	CurrentStyle.bUnderline = Mid(StyleString, StylePos++, 1) == "T";
945
	CurrentStyle.bNoBR = Mid(StyleString, StylePos++, 1) == "T";
946
	CurrentStyle.bHeading = Mid(StyleString, StylePos++, 1) == "T";
947
	CurrentStyle.bBold = Mid(StyleString, StylePos++, 1) == "T";
948
	CurrentStyle.bBlink = Mid(StyleString, StylePos++, 1) == "T";
949
950
	return CharCount;
951
}
952
953
defaultproperties
954
{
955
				TextColor=(R=255,G=255,B=255)
956
				LinkColor=(B=255)
957
				ALinkColor=(R=255)
958
				bTopCentric=True
959
				bAutoScrollbar=True
960
				bVariableRowHeight=True
961
				RowClass=Class'UWindow.UWindowHTMLTextRow'
962
				bIgnoreLDoubleClick=True
963
}