author | unC0Rr |
Tue, 17 Dec 2024 15:44:21 +0100 | |
branch | transitional_engine |
changeset 16078 | db18f1a30b0c |
parent 16004 | 2146cb7be36f |
permissions | -rw-r--r-- |
4976 | 1 |
(* |
2 |
* Hedgewars, a free turn based strategy game |
|
11046 | 3 |
* Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com> |
4976 | 4 |
* |
5 |
* This program is free software; you can redistribute it and/or modify |
|
6 |
* it under the terms of the GNU General Public License as published by |
|
7 |
* the Free Software Foundation; version 2 of the License |
|
8 |
* |
|
9 |
* This program is distributed in the hope that it will be useful, |
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
* GNU General Public License for more details. |
|
13 |
* |
|
14 |
* You should have received a copy of the GNU General Public License |
|
15 |
* along with this program; if not, write to the Free Software |
|
10108
c68cf030eded
update FSF address. note: two sdl include files (by Sam Lantinga) still have the old FSF address in their copyright - but I ain't gonna touch their copyright headers
sheepluva
parents:
10107
diff
changeset
|
16 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
4976 | 17 |
*) |
18 |
||
4380 | 19 |
{$INCLUDE "options.inc"} |
4976 | 20 |
|
4380 | 21 |
unit uRenderUtils; |
22 |
||
23 |
interface |
|
24 |
uses SDLh, uTypes; |
|
25 |
||
26 |
procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean); |
|
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
27 |
|
4380 | 28 |
procedure copyRotatedSurface(src, dest: PSDL_Surface); // this is necessary since width/height are read only in SDL |
15929
128ace913837
Introduce hwengine-future library, use Land allocated in it
unC0Rr
parents:
15874
diff
changeset
|
29 |
procedure copyToXY(src, dest: PSDL_Surface; destX, destY: LongInt); |
7013 | 30 |
procedure copyToXYFromRect(src, dest: PSDL_Surface; srcX, srcY, srcW, srcH, destX, destY: LongInt); |
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
31 |
|
16001
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
32 |
function GetSurfaceFrameCoordinateX(Surface: PSDL_Surface; Frame, frameWidth, frameHeight: LongInt): LongInt; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
33 |
function GetSurfaceFrameCoordinateY(Surface: PSDL_Surface; Frame, frameHeight: LongInt): LongInt; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
34 |
|
16004 | 35 |
procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); |
7013 | 36 |
procedure DrawSpriteFrame2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt; frame: LongInt); |
6620
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
37 |
procedure DrawLine2Surf(dest: PSDL_Surface; x0,y0,x1,y1:LongInt; r,g,b: byte); |
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
38 |
procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean); |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
39 |
|
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
40 |
function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture; |
7013 | 41 |
function RenderStringTexLim(s: ansistring; Color: Longword; font: THWFont; maxLength: LongWord): PTexture; |
4380 | 42 |
function RenderSpeechBubbleTex(s: ansistring; SpeechType: Longword; font: THWFont): PTexture; |
43 |
||
15929
128ace913837
Introduce hwengine-future library, use Land allocated in it
unC0Rr
parents:
15874
diff
changeset
|
44 |
function IsTooDarkToRead(TextColor: Longword): boolean; |
14757
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
45 |
|
4380 | 46 |
implementation |
11821 | 47 |
uses uVariables, uConsts, uTextures, SysUtils, uUtils, uDebug; |
4380 | 48 |
|
49 |
procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean); |
|
50 |
var r: TSDL_Rect; |
|
51 |
begin |
|
52 |
r:= rect^; |
|
6580
6155187bf599
A partial reformatting of the pascal code to have consistent syntax. Things that are still inconsistent.
lovelacer
parents:
6286
diff
changeset
|
53 |
if Clear then |
14655
b055360684bd
Remove black pixels at corners of DrawRoundRect rectangles
Wuzzy <Wuzzy2@mail.ru>
parents:
13490
diff
changeset
|
54 |
SDL_FillRect(Surface, @r, SDL_MapRGBA(Surface^.format, 0, 0, 0, 0)); |
4380 | 55 |
|
56 |
BorderColor:= SDL_MapRGB(Surface^.format, BorderColor shr 16, BorderColor shr 8, BorderColor and $FF); |
|
57 |
FillColor:= SDL_MapRGB(Surface^.format, FillColor shr 16, FillColor shr 8, FillColor and $FF); |
|
58 |
||
11836 | 59 |
r.y:= rect^.y + cFontBorder div 2; |
60 |
r.h:= rect^.h - cFontBorder; |
|
4380 | 61 |
SDL_FillRect(Surface, @r, BorderColor); |
11836 | 62 |
r.x:= rect^.x + cFontBorder div 2; |
63 |
r.w:= rect^.w - cFontBorder; |
|
4380 | 64 |
r.y:= rect^.y; |
65 |
r.h:= rect^.h; |
|
66 |
SDL_FillRect(Surface, @r, BorderColor); |
|
11836 | 67 |
r.x:= rect^.x + cFontBorder; |
68 |
r.y:= rect^.y + cFontBorder div 2; |
|
69 |
r.w:= rect^.w - cFontBorder * 2; |
|
70 |
r.h:= rect^.h - cFontBorder; |
|
4380 | 71 |
SDL_FillRect(Surface, @r, FillColor); |
11836 | 72 |
r.x:= rect^.x + cFontBorder div 2; |
73 |
r.y:= rect^.y + cFontBorder; |
|
74 |
r.w:= rect^.w - cFontBorder; |
|
75 |
r.h:= rect^.h - cFontBorder * 2; |
|
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
76 |
SDL_FillRect(Surface, @r, FillColor); |
4380 | 77 |
end; |
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
78 |
(* |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
79 |
function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect; |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
80 |
begin |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
81 |
WriteInRoundRect:= WriteInRoundRect(Surface, X, Y, Color, Font, s, 0); |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
82 |
end;*) |
4380 | 83 |
|
16001
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
84 |
function GetSurfaceFrameCoordinateX(Surface: PSDL_Surface; Frame, frameWidth, frameHeight: LongInt): LongInt; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
85 |
var nx, ny: LongInt; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
86 |
begin |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
87 |
nx:= Surface^.w div frameWidth; // number of horizontal frames |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
88 |
if nx = 0 then nx:= 1; // one frame is minimum |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
89 |
ny:= Surface^.h div frameHeight; // number of vertical frames |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
90 |
if ny = 0 then ny:= 1; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
91 |
GetSurfaceFrameCoordinateX:= (Frame div ny) * frameWidth; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
92 |
end; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
93 |
|
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
94 |
function GetSurfaceFrameCoordinateY(Surface: PSDL_Surface; Frame, frameHeight: LongInt): LongInt; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
95 |
var ny: LongInt; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
96 |
begin |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
97 |
ny:= Surface^.h div frameHeight; // number of vertical frames |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
98 |
if ny = 0 then ny:= 1; // one frame is minimum |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
99 |
GetSurfaceFrameCoordinateY:= (Frame mod ny) * frameHeight; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
100 |
end; |
cee831693af1
Add ExtraDamage icon variant for locales with comma as decimal separator
Wuzzy <Wuzzy@disroot.org>
parents:
15987
diff
changeset
|
101 |
|
16004 | 102 |
function IsTooDarkToRead(TextColor: LongWord): boolean; |
14757
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
103 |
var clr: TSDL_Color; |
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
104 |
begin |
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
105 |
clr.r:= (TextColor shr 16) and $FF; |
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
106 |
clr.g:= (TextColor shr 8) and $FF; |
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
107 |
clr.b:= TextColor and $FF; |
14766
7cc768094d66
Refactor IsTooDarkToRead to fix pas2c crash
Wuzzy <Wuzzy2@mail.ru>
parents:
14757
diff
changeset
|
108 |
IsTooDarkToRead:= not ((clr.r >= cInvertTextColorAt) or (clr.g >= cInvertTextColorAt) or (clr.b >= cInvertTextColorAt)); |
14757
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
109 |
end; |
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
110 |
|
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
111 |
function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring; maxLength: LongWord): TSDL_Rect; |
10494 | 112 |
var w, h: Longword; |
4380 | 113 |
tmpsurf: PSDL_Surface; |
14757
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
114 |
finalRect, textRect: TSDL_Rect; |
4380 | 115 |
clr: TSDL_Color; |
116 |
begin |
|
10127 | 117 |
TTF_SizeUTF8(Fontz[Font].Handle, PChar(s), @w, @h); |
16003
8bb07b0f50ca
add some round() so that the scale factor compiles at least with non-integer values
nemo
parents:
16001
diff
changeset
|
118 |
if (maxLength > 0) and (w > round(maxLength * HDPIScaleFactor)) then w := round(maxLength * HDPIScaleFactor); |
4380 | 119 |
finalRect.x:= X; |
120 |
finalRect.y:= Y; |
|
11836 | 121 |
finalRect.w:= w + cFontBorder * 2 + cFontPadding * 2; |
6982 | 122 |
finalRect.h:= h + cFontBorder * 2; |
6750 | 123 |
textRect.x:= X; |
124 |
textRect.y:= Y; |
|
125 |
textRect.w:= w; |
|
126 |
textRect.h:= h; |
|
4380 | 127 |
clr.r:= (Color shr 16) and $FF; |
128 |
clr.g:= (Color shr 8) and $FF; |
|
129 |
clr.b:= Color and $FF; |
|
14768
7dfc6ed13337
Fix uninitialized alpha values of rendered text
Wuzzy <Wuzzy2@mail.ru>
parents:
14766
diff
changeset
|
130 |
clr.a:= $FF; |
14766
7cc768094d66
Refactor IsTooDarkToRead to fix pas2c crash
Wuzzy <Wuzzy2@mail.ru>
parents:
14757
diff
changeset
|
131 |
if (not IsTooDarkToRead(Color)) then |
14757
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
132 |
DrawRoundRect(@finalRect, cWhiteColor, cNearBlackColor, Surface, true) |
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
133 |
else |
8563cc40fc1e
Invert colors if clan color is very dark
Wuzzy <Wuzzy2@mail.ru>
parents:
14655
diff
changeset
|
134 |
DrawRoundRect(@finalRect, cNearBlackColor, cWhiteColor, Surface, true); |
10127 | 135 |
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, PChar(s), clr); |
11836 | 136 |
finalRect.x:= X + cFontBorder + cFontPadding; |
6982 | 137 |
finalRect.y:= Y + cFontBorder; |
11507 | 138 |
if SDLCheck(tmpsurf <> nil, 'TTF_RenderUTF8_Blended', true) then |
15775 | 139 |
exit(finalRect); |
6750 | 140 |
SDL_UpperBlit(tmpsurf, @textRect, Surface, @finalRect); |
4380 | 141 |
SDL_FreeSurface(tmpsurf); |
142 |
finalRect.x:= X; |
|
143 |
finalRect.y:= Y; |
|
11836 | 144 |
finalRect.w:= w + cFontBorder * 2 + cFontPadding * 2; |
6982 | 145 |
finalRect.h:= h + cFontBorder * 2; |
4380 | 146 |
WriteInRoundRect:= finalRect; |
147 |
end; |
|
148 |
||
149 |
procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean); |
|
150 |
var y, x, i, j: LongInt; |
|
151 |
tmpPixel: Longword; |
|
152 |
pixels: PLongWordArray; |
|
153 |
begin |
|
11532 | 154 |
if checkFails(Surface^.format^.BytesPerPixel = 4, 'flipSurface failed, expecting 32 bit surface', true) then |
155 |
exit; |
|
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
156 |
SDL_LockSurface(Surface); |
4380 | 157 |
pixels:= Surface^.pixels; |
158 |
if Vertical then |
|
159 |
for y := 0 to (Surface^.h div 2) - 1 do |
|
160 |
for x := 0 to Surface^.w - 1 do |
|
161 |
begin |
|
162 |
i:= y * Surface^.w + x; |
|
163 |
j:= (Surface^.h - y - 1) * Surface^.w + x; |
|
164 |
tmpPixel:= pixels^[i]; |
|
165 |
pixels^[i]:= pixels^[j]; |
|
166 |
pixels^[j]:= tmpPixel; |
|
167 |
end |
|
168 |
else |
|
169 |
for x := 0 to (Surface^.w div 2) - 1 do |
|
11532 | 170 |
for y := 0 to Surface^.h - 1 do |
4380 | 171 |
begin |
172 |
i:= y*Surface^.w + x; |
|
173 |
j:= y*Surface^.w + (Surface^.w - x - 1); |
|
174 |
tmpPixel:= pixels^[i]; |
|
175 |
pixels^[i]:= pixels^[j]; |
|
176 |
pixels^[j]:= tmpPixel; |
|
177 |
end; |
|
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
178 |
SDL_UnlockSurface(Surface); |
4380 | 179 |
end; |
180 |
||
15929
128ace913837
Introduce hwengine-future library, use Land allocated in it
unC0Rr
parents:
15874
diff
changeset
|
181 |
procedure copyToXY(src, dest: PSDL_Surface; destX, destY: LongInt); |
6620
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
182 |
begin |
12098
966a9739812f
copyToXYFromRect: fix pixels overflowing pixel lines in dest
sheepluva
parents:
11836
diff
changeset
|
183 |
// copy from complete src |
7013 | 184 |
copyToXYFromRect(src, dest, 0, 0, src^.w, src^.h, destX, destY); |
6620
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
185 |
end; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
186 |
|
7013 | 187 |
procedure copyToXYFromRect(src, dest: PSDL_Surface; srcX, srcY, srcW, srcH, destX, destY: LongInt); |
12099 | 188 |
var spi, dpi, iX, iY, dX, dY, lX, lY, aT: LongInt; |
4380 | 189 |
srcPixels, destPixels: PLongWordArray; |
12099 | 190 |
rD, gD, bD, aD, rT, gT, bT: Byte; |
4380 | 191 |
begin |
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
192 |
SDL_LockSurface(src); |
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
193 |
SDL_LockSurface(dest); |
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
194 |
|
4380 | 195 |
srcPixels:= src^.pixels; |
196 |
destPixels:= dest^.pixels; |
|
197 |
||
12098
966a9739812f
copyToXYFromRect: fix pixels overflowing pixel lines in dest
sheepluva
parents:
11836
diff
changeset
|
198 |
// what's the offset between src and dest coords? |
966a9739812f
copyToXYFromRect: fix pixels overflowing pixel lines in dest
sheepluva
parents:
11836
diff
changeset
|
199 |
dX:= destX - srcX; |
966a9739812f
copyToXYFromRect: fix pixels overflowing pixel lines in dest
sheepluva
parents:
11836
diff
changeset
|
200 |
dY:= destY - srcY; |
966a9739812f
copyToXYFromRect: fix pixels overflowing pixel lines in dest
sheepluva
parents:
11836
diff
changeset
|
201 |
|
966a9739812f
copyToXYFromRect: fix pixels overflowing pixel lines in dest
sheepluva
parents:
11836
diff
changeset
|
202 |
// let's figure out where the rectangle we can actually copy ends |
12101
2e70ef81e281
copyToXYFromRect: simplify my math (so that it actually, you know, works...)
sheepluva
parents:
12099
diff
changeset
|
203 |
lX:= min(srcX + srcW, src^.w) - 1; |
2e70ef81e281
copyToXYFromRect: simplify my math (so that it actually, you know, works...)
sheepluva
parents:
12099
diff
changeset
|
204 |
if lX + dx >= dest^.w then lX:= dest^.w - dx - 1; |
2e70ef81e281
copyToXYFromRect: simplify my math (so that it actually, you know, works...)
sheepluva
parents:
12099
diff
changeset
|
205 |
lY:= min(srcY + srcH, src^.h) - 1; |
2e70ef81e281
copyToXYFromRect: simplify my math (so that it actually, you know, works...)
sheepluva
parents:
12099
diff
changeset
|
206 |
if lY + dy >= dest^.h then lY:= dest^.h - dy - 1; |
12098
966a9739812f
copyToXYFromRect: fix pixels overflowing pixel lines in dest
sheepluva
parents:
11836
diff
changeset
|
207 |
|
966a9739812f
copyToXYFromRect: fix pixels overflowing pixel lines in dest
sheepluva
parents:
11836
diff
changeset
|
208 |
for iX:= srcX to lX do |
966a9739812f
copyToXYFromRect: fix pixels overflowing pixel lines in dest
sheepluva
parents:
11836
diff
changeset
|
209 |
for iY:= srcY to lY do |
4380 | 210 |
begin |
12099 | 211 |
// src pixel index |
15874
c4561095666a
Fix texture copying routine not taking pitch into account
unc0rr
parents:
15775
diff
changeset
|
212 |
spi:= iY * src^.pitch div 4 + iX; |
12099 | 213 |
// dest pixel index |
15874
c4561095666a
Fix texture copying routine not taking pitch into account
unc0rr
parents:
15775
diff
changeset
|
214 |
dpi:= (iY + dY) * dest^.pitch div 4 + (iX + dX); |
12099 | 215 |
|
216 |
// get src alpha (and set it as target alpha for now) |
|
217 |
aT:= (srcPixels^[spi] and AMask) shr AShift; |
|
218 |
||
219 |
// src pixel opaque? |
|
220 |
if aT = 255 then |
|
4380 | 221 |
begin |
12099 | 222 |
// just copy full pixel |
223 |
destPixels^[dpi]:= srcPixels^[spi]; |
|
224 |
continue; |
|
4380 | 225 |
end; |
12099 | 226 |
|
227 |
// get dst alpha (without shift for now) |
|
228 |
aD:= (destPixels^[dpi] and AMask) shr AShift; |
|
229 |
||
230 |
// dest completely transparent? |
|
231 |
if aD = 0 then |
|
232 |
begin |
|
233 |
// just copy src pixel |
|
234 |
destPixels^[dpi]:= srcPixels^[spi]; |
|
235 |
continue; |
|
236 |
end; |
|
237 |
||
238 |
// looks like some blending is necessary |
|
239 |
||
240 |
// set color of target RGB to src for now |
|
241 |
SDL_GetRGB(srcPixels^[spi], src^.format, @rT, @gT, @bT); |
|
242 |
SDL_GetRGB(destPixels^[dpi], dest^.format, @rD, @gD, @bD); |
|
243 |
// note: this is not how to correctly blend RGB, just sayin' (R,G,B are not linear...) |
|
244 |
rT:= (rD * (255 - aT) + rT * aT) div 255; |
|
245 |
gT:= (gD * (255 - aT) + gT * aT) div 255; |
|
246 |
bT:= (bD * (255 - aT) + bT * aT) div 255; |
|
247 |
aT:= aD + ((255 - LongInt(aD)) * aT div 255); |
|
248 |
||
12102
51596d30a724
fix chat SDL surfaces being in wrong color format (didn't play well with copyToXY's new quick pixel copies)
sheepluva
parents:
12101
diff
changeset
|
249 |
destPixels^[dpi]:= SDL_MapRGBA(dest^.format, rT, gT, bT, Byte(aT)); |
51596d30a724
fix chat SDL surfaces being in wrong color format (didn't play well with copyToXY's new quick pixel copies)
sheepluva
parents:
12101
diff
changeset
|
250 |
|
4380 | 251 |
end; |
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
252 |
|
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
253 |
SDL_UnlockSurface(src); |
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
254 |
SDL_UnlockSurface(dest); |
4380 | 255 |
end; |
256 |
||
15929
128ace913837
Introduce hwengine-future library, use Land allocated in it
unC0Rr
parents:
15874
diff
changeset
|
257 |
procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); |
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
258 |
begin |
12099 | 259 |
DrawSpriteFrame2Surf(sprite, dest, x, y, 0); |
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
260 |
end; |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
261 |
|
7013 | 262 |
procedure DrawSpriteFrame2Surf(sprite: TSprite; dest: PSDL_Surface; x,y,frame: LongInt); |
6620
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
263 |
var numFramesFirstCol, row, col: LongInt; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
264 |
begin |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
265 |
numFramesFirstCol:= SpritesData[sprite].imageHeight div SpritesData[sprite].Height; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
266 |
row:= Frame mod numFramesFirstCol; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
267 |
col:= Frame div numFramesFirstCol; |
10015 | 268 |
|
269 |
copyToXYFromRect(SpritesData[sprite].Surface, dest, |
|
270 |
col*SpritesData[sprite].Width, |
|
271 |
row*SpritesData[sprite].Height, |
|
272 |
SpritesData[sprite].Width, |
|
273 |
spritesData[sprite].Height, |
|
6620
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
274 |
x,y); |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
275 |
end; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
276 |
|
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
277 |
procedure DrawLine2Surf(dest: PSDL_Surface; x0, y0,x1,y1: LongInt; r,g,b: byte); |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
278 |
var |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
279 |
dx,dy,err,e2,sx,sy: LongInt; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
280 |
yMax: LongInt; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
281 |
destPixels: PLongwordArray; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
282 |
begin |
6992 | 283 |
//max:= (dest^.pitch div 4) * dest^.h; |
6620
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
284 |
yMax:= dest^.pitch div 4; |
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
285 |
|
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
286 |
SDL_LockSurface(dest); |
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
287 |
|
6620
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
288 |
destPixels:= dest^.pixels; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
289 |
|
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
290 |
dx:= abs(x1-x0); |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
291 |
dy:= abs(y1-y0); |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
292 |
if x0 < x1 then sx:= 1 else sx:= -1; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
293 |
if y0 < y1 then sy:= 1 else sy:= -1; |
10015 | 294 |
err:= dx-dy; |
6620
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
295 |
|
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
296 |
while(true) do |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
297 |
begin |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
298 |
destPixels^[(y0 * yMax) + x0]:= SDL_MapRGB(dest^.format, r,g,b); //But will it blend? no |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
299 |
|
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
300 |
if (x0 = x1) and (y0 = y1) then break; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
301 |
|
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
302 |
e2:= 2*err; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
303 |
if e2 > -dy then |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
304 |
begin |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
305 |
err:= err - dy; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
306 |
x0 := x0 + sx; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
307 |
end; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
308 |
|
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
309 |
if e2 < dx then |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
310 |
begin |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
311 |
err:= err + dx; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
312 |
y0:=y0+sy |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
313 |
end; |
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
314 |
end; |
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
315 |
SDL_UnlockSurface(dest); |
6620
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
316 |
end; |
b211d0b690de
Expanded copyToXY, it doesn't copy the whole src sprite, srcX/Y to srcW/h, added DrawSprite2Surf and DrawLine2Surf
Xeli
parents:
6580
diff
changeset
|
317 |
|
4380 | 318 |
procedure copyRotatedSurface(src, dest: PSDL_Surface); // this is necessary since width/height are read only in SDL, apparently |
319 |
var y, x, i, j: LongInt; |
|
320 |
srcPixels, destPixels: PLongWordArray; |
|
321 |
begin |
|
11532 | 322 |
checkFails(src^.format^.BytesPerPixel = 4, 'rotateSurface failed, expecting 32 bit surface', true); |
323 |
checkFails(dest^.format^.BytesPerPixel = 4, 'rotateSurface failed, expecting 32 bit surface', true); |
|
324 |
if not allOK then exit; |
|
4380 | 325 |
|
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
326 |
SDL_LockSurface(src); |
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
327 |
SDL_LockSurface(dest); |
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
328 |
|
4380 | 329 |
srcPixels:= src^.pixels; |
330 |
destPixels:= dest^.pixels; |
|
331 |
||
332 |
j:= 0; |
|
333 |
for x := 0 to src^.w - 1 do |
|
334 |
for y := 0 to src^.h - 1 do |
|
335 |
begin |
|
336 |
i:= (src^.h - 1 - y) * (src^.pitch div 4) + x; |
|
337 |
destPixels^[j]:= srcPixels^[i]; |
|
338 |
inc(j) |
|
339 |
end; |
|
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
340 |
|
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
341 |
SDL_UnlockSurface(src); |
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
342 |
SDL_UnlockSurface(dest); |
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
343 |
|
4380 | 344 |
end; |
345 |
||
15987
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
346 |
{$IFNDEF PAS2C} |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
347 |
// Wraps the text s by inserting breakStr as newlines with |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
348 |
// maximum column length maxCol. |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
349 |
// Same as Pascal's WrapText, but without the annoying |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
350 |
// behavior that text enclosed in " and ' disables word-wrapping |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
351 |
function SimpleWrapText(s, breakStr: string; maxCol: integer): string; |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
352 |
var |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
353 |
breakChars: set of char = [#9,' ','-']; |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
354 |
begin |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
355 |
// escape the " and ' characters before calling WrapText |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
356 |
// using ASCII ESC control character |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
357 |
s:= StringReplace(s, '"', #27+'Q', [rfReplaceAll]); |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
358 |
s:= StringReplace(s, '''', #27+'q', [rfReplaceAll]); |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
359 |
|
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
360 |
s:= WrapText(s, #1, breakChars, maxCol); |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
361 |
|
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
362 |
// Undo the escapes |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
363 |
s:= StringReplace(s, #27+'Q', '"', [rfReplaceAll]); |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
364 |
s:= StringReplace(s, #27+'q', '''', [rfReplaceAll]); |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
365 |
SimpleWrapText:= s; |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
366 |
end; |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
367 |
{$ENDIF} |
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
368 |
|
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
369 |
function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture; |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
370 |
begin |
7013 | 371 |
RenderStringTex:= RenderStringTexLim(s, Color, font, 0); |
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
372 |
end; |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6982
diff
changeset
|
373 |
|
7013 | 374 |
function RenderStringTexLim(s: ansistring; Color: Longword; font: THWFont; maxLength: LongWord): PTexture; |
10494 | 375 |
var w, h: Longword; |
4380 | 376 |
finalSurface: PSDL_Surface; |
377 |
begin |
|
10139 | 378 |
if cOnlyStats then |
379 |
begin |
|
380 |
RenderStringTexLim:= nil; |
|
381 |
end |
|
382 |
else |
|
383 |
begin |
|
384 |
if length(s) = 0 then s:= _S' '; |
|
385 |
font:= CheckCJKFont(s, font); |
|
386 |
w:= 0; h:= 0; // avoid compiler hints |
|
387 |
TTF_SizeUTF8(Fontz[font].Handle, PChar(s), @w, @h); |
|
16003
8bb07b0f50ca
add some round() so that the scale factor compiles at least with non-integer values
nemo
parents:
16001
diff
changeset
|
388 |
if (maxLength > 0) and (w > round(maxLength * HDPIScaleFactor)) then w := round(maxLength * HDPIScaleFactor); |
4380 | 389 |
|
11836 | 390 |
finalSurface:= SDL_CreateRGBSurface(SDL_SWSURFACE, w + cFontBorder*2 + cFontPadding*2, h + cFontBorder * 2, |
10139 | 391 |
32, RMask, GMask, BMask, AMask); |
4380 | 392 |
|
11532 | 393 |
if checkFails(finalSurface <> nil, 'RenderString: fail to create surface', true) then |
394 |
exit(nil); |
|
10139 | 395 |
|
396 |
WriteInRoundRect(finalSurface, 0, 0, Color, font, s, maxLength); |
|
4380 | 397 |
|
12591 | 398 |
checkFails(SDL_SetColorKey(finalSurface, SDL_TRUE, 0) = 0, errmsgTransparentSet, false); |
4380 | 399 |
|
10139 | 400 |
RenderStringTexLim:= Surface2Tex(finalSurface, false); |
4380 | 401 |
|
10139 | 402 |
SDL_FreeSurface(finalSurface); |
403 |
end; |
|
4380 | 404 |
end; |
405 |
||
10689
692649e341fc
change string types of speech bubbles fix to work with pas2c
sheepluva
parents:
10687
diff
changeset
|
406 |
function GetNextSpeechLine(s: ansistring; ldelim: char; var startFrom: LongInt; out substr: ansistring): boolean; |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
407 |
var p, l, m, r: Integer; |
10691
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
408 |
newl, skip: boolean; |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
409 |
c : char; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
410 |
begin |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
411 |
m:= Length(s); |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
412 |
|
10690 | 413 |
substr:= ''; |
414 |
||
10689
692649e341fc
change string types of speech bubbles fix to work with pas2c
sheepluva
parents:
10687
diff
changeset
|
415 |
SetLengthA(substr, m); |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
416 |
|
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
417 |
// number of chars read |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
418 |
r:= 0; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
419 |
|
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
420 |
// number of chars to be written |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
421 |
l:= 0; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
422 |
|
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
423 |
newl:= true; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
424 |
|
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
425 |
for p:= max(1, startFrom) to m do |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
426 |
begin |
10691
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
427 |
|
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
428 |
inc(r); |
10691
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
429 |
// read char from source string |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
430 |
c:= s[p]; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
431 |
|
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
432 |
// strip empty lines, spaces and newlines on beginnings of line |
10691
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
433 |
skip:= ((newl or (p = m)) and ((c = ' ') or (c = ldelim))); |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
434 |
|
10691
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
435 |
if (not skip) then |
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
436 |
begin |
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
437 |
newl:= (c = ldelim); |
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
438 |
// stop if we went past the end of the line |
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
439 |
if newl then |
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
440 |
break; |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
441 |
|
10691
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
442 |
// copy current char to output substring |
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
443 |
inc(l); |
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
444 |
substr[l]:= c; |
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
445 |
end; |
97f45f1374be
change speechfix implementation (no "continue" anymore
sheepluva
parents:
10690
diff
changeset
|
446 |
|
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
447 |
end; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
448 |
|
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
449 |
inc(startFrom, r); |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
450 |
|
10689
692649e341fc
change string types of speech bubbles fix to work with pas2c
sheepluva
parents:
10687
diff
changeset
|
451 |
SetLengthA(substr, l); |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
452 |
|
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
453 |
GetNextSpeechLine:= (l > 0); |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
454 |
end; |
4380 | 455 |
|
456 |
function RenderSpeechBubbleTex(s: ansistring; SpeechType: Longword; font: THWFont): PTexture; |
|
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
457 |
var textWidth, textHeight, x, y, w, h, i, j, pos, line, numLines, edgeWidth, edgeHeight, cornerWidth, cornerHeight: LongInt; |
4380 | 458 |
finalSurface, tmpsurf, rotatedEdge: PSDL_Surface; |
459 |
rect: TSDL_Rect; |
|
10689
692649e341fc
change string types of speech bubbles fix to work with pas2c
sheepluva
parents:
10687
diff
changeset
|
460 |
substr: ansistring; |
4380 | 461 |
edge, corner, tail: TSPrite; |
462 |
begin |
|
10139 | 463 |
if cOnlyStats then exit(nil); |
464 |
||
4380 | 465 |
case SpeechType of |
10142 | 466 |
1: begin |
10139 | 467 |
edge:= sprSpeechEdge; |
468 |
corner:= sprSpeechCorner; |
|
469 |
tail:= sprSpeechTail; |
|
470 |
end; |
|
10142 | 471 |
2: begin |
10139 | 472 |
edge:= sprThoughtEdge; |
473 |
corner:= sprThoughtCorner; |
|
474 |
tail:= sprThoughtTail; |
|
475 |
end; |
|
10142 | 476 |
3: begin |
10139 | 477 |
edge:= sprShoutEdge; |
478 |
corner:= sprShoutCorner; |
|
479 |
tail:= sprShoutTail; |
|
10142 | 480 |
end |
481 |
else |
|
482 |
exit(nil) |
|
4380 | 483 |
end; |
484 |
edgeHeight:= SpritesData[edge].Height; |
|
485 |
edgeWidth:= SpritesData[edge].Width; |
|
486 |
cornerWidth:= SpritesData[corner].Width; |
|
487 |
cornerHeight:= SpritesData[corner].Height; |
|
488 |
||
489 |
numLines:= 0; |
|
490 |
||
6580
6155187bf599
A partial reformatting of the pascal code to have consistent syntax. Things that are still inconsistent.
lovelacer
parents:
6286
diff
changeset
|
491 |
if length(s) = 0 then |
6155187bf599
A partial reformatting of the pascal code to have consistent syntax. Things that are still inconsistent.
lovelacer
parents:
6286
diff
changeset
|
492 |
s:= '...'; |
4380 | 493 |
font:= CheckCJKFont(s, font); |
494 |
w:= 0; h:= 0; // avoid compiler hints |
|
10127 | 495 |
TTF_SizeUTF8(Fontz[font].Handle, PChar(s), @w, @h); |
6580
6155187bf599
A partial reformatting of the pascal code to have consistent syntax. Things that are still inconsistent.
lovelacer
parents:
6286
diff
changeset
|
496 |
if w<8 then |
6155187bf599
A partial reformatting of the pascal code to have consistent syntax. Things that are still inconsistent.
lovelacer
parents:
6286
diff
changeset
|
497 |
w:= 8; |
4380 | 498 |
j:= 0; |
499 |
if (length(s) > 20) then |
|
500 |
begin |
|
501 |
w:= 0; |
|
502 |
i:= round(Sqrt(length(s)) * 2); |
|
10127 | 503 |
{$IFNDEF PAS2C} |
15987
e8d94f84d294
Fix speech bubble not wrapping if contain quote marks (bug 753)
Wuzzy <Wuzzy@disroot.org>
parents:
15874
diff
changeset
|
504 |
s:= SimpleWrapText(s, #1, i); |
10127 | 505 |
{$ENDIF} |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
506 |
pos:= 1; line:= 0; |
4380 | 507 |
// Find the longest line for the purposes of centring the text. Font dependant. |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
508 |
while GetNextSpeechLine(s, #1, pos, substr) do |
4380 | 509 |
begin |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
510 |
inc(numLines); |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
511 |
i:= 0; j:= 0; |
10689
692649e341fc
change string types of speech bubbles fix to work with pas2c
sheepluva
parents:
10687
diff
changeset
|
512 |
TTF_SizeUTF8(Fontz[font].Handle, PChar(substr), @i, @j); |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
513 |
if i > w then |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
514 |
w:= i; |
4380 | 515 |
end; |
516 |
end |
|
517 |
else numLines := 1; |
|
518 |
||
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
519 |
if numLines < 1 then |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
520 |
begin |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
521 |
s:= '...'; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
522 |
numLines:= 1; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
523 |
end; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
524 |
|
4380 | 525 |
textWidth:=((w-(cornerWidth-edgeWidth)*2) div edgeWidth)*edgeWidth+edgeWidth; |
526 |
textHeight:=(((numlines * h + 2)-((cornerHeight-edgeWidth)*2)) div edgeWidth)*edgeWidth; |
|
527 |
||
528 |
textHeight:=max(textHeight,edgeWidth); |
|
529 |
//textWidth:=max(textWidth,SpritesData[tail].Width); |
|
530 |
rect.x:= 0; |
|
531 |
rect.y:= 0; |
|
532 |
rect.w:= textWidth + (cornerWidth * 2); |
|
533 |
rect.h:= textHeight + cornerHeight*2 - edgeHeight + SpritesData[tail].Height; |
|
534 |
//s:= inttostr(w) + ' ' + inttostr(numlines) + ' ' + inttostr(rect.x) + ' '+inttostr(rect.y) + ' ' + inttostr(rect.w) + ' ' + inttostr(rect.h); |
|
535 |
||
536 |
finalSurface:= SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, rect.h, 32, RMask, GMask, BMask, AMask); |
|
537 |
||
11532 | 538 |
if checkFails(finalSurface <> nil, 'RenderString: fail to create surface', true) then |
539 |
exit(nil); |
|
4380 | 540 |
|
541 |
//////////////////////////////// CORNERS /////////////////////////////// |
|
542 |
copyToXY(SpritesData[corner].Surface, finalSurface, 0, 0); /////////////////// NW |
|
543 |
||
544 |
flipSurface(SpritesData[corner].Surface, true); // store all 4 versions in memory to avoid repeated flips? |
|
545 |
x:= 0; |
|
546 |
y:= textHeight + cornerHeight -1; |
|
547 |
copyToXY(SpritesData[corner].Surface, finalSurface, x, y); /////////////////// SW |
|
548 |
||
549 |
flipSurface(SpritesData[corner].Surface, false); |
|
550 |
x:= rect.w-cornerWidth-1; |
|
551 |
y:= textHeight + cornerHeight -1; |
|
552 |
copyToXY(SpritesData[corner].Surface, finalSurface, x, y); /////////////////// SE |
|
553 |
||
554 |
flipSurface(SpritesData[corner].Surface, true); |
|
555 |
x:= rect.w-cornerWidth-1; |
|
556 |
y:= 0; |
|
557 |
copyToXY(SpritesData[corner].Surface, finalSurface, x, y); /////////////////// NE |
|
558 |
flipSurface(SpritesData[corner].Surface, false); // restore original position |
|
559 |
//////////////////////////////// END CORNERS /////////////////////////////// |
|
560 |
||
561 |
//////////////////////////////// EDGES ////////////////////////////////////// |
|
562 |
x:= cornerWidth; |
|
563 |
y:= 0; |
|
564 |
while x < rect.w-cornerWidth-1 do |
|
565 |
begin |
|
566 |
copyToXY(SpritesData[edge].Surface, finalSurface, x, y); ///////////////// top edge |
|
567 |
inc(x,edgeWidth); |
|
568 |
end; |
|
569 |
flipSurface(SpritesData[edge].Surface, true); |
|
570 |
x:= cornerWidth; |
|
571 |
y:= textHeight + cornerHeight*2 - edgeHeight-1; |
|
572 |
while x < rect.w-cornerWidth-1 do |
|
573 |
begin |
|
574 |
copyToXY(SpritesData[edge].Surface, finalSurface, x, y); ///////////////// bottom edge |
|
575 |
inc(x,edgeWidth); |
|
576 |
end; |
|
577 |
flipSurface(SpritesData[edge].Surface, true); // restore original position |
|
578 |
||
579 |
rotatedEdge:= SDL_CreateRGBSurface(SDL_SWSURFACE, edgeHeight, edgeWidth, 32, RMask, GMask, BMask, AMask); |
|
580 |
x:= rect.w - edgeHeight - 1; |
|
581 |
y:= cornerHeight; |
|
582 |
//// initially was going to rotate in place, but the SDL spec claims width/height are read only |
|
583 |
copyRotatedSurface(SpritesData[edge].Surface,rotatedEdge); |
|
584 |
while y < textHeight + cornerHeight do |
|
585 |
begin |
|
586 |
copyToXY(rotatedEdge, finalSurface, x, y); |
|
587 |
inc(y,edgeWidth); |
|
588 |
end; |
|
589 |
flipSurface(rotatedEdge, false); // restore original position |
|
590 |
x:= 0; |
|
591 |
y:= cornerHeight; |
|
592 |
while y < textHeight + cornerHeight do |
|
593 |
begin |
|
594 |
copyToXY(rotatedEdge, finalSurface, x, y); |
|
595 |
inc(y,edgeWidth); |
|
596 |
end; |
|
597 |
//////////////////////////////// END EDGES ////////////////////////////////////// |
|
598 |
||
599 |
x:= cornerWidth; |
|
600 |
y:= textHeight + cornerHeight * 2 - edgeHeight - 1; |
|
601 |
copyToXY(SpritesData[tail].Surface, finalSurface, x, y); |
|
602 |
||
603 |
rect.x:= edgeHeight; |
|
604 |
rect.y:= edgeHeight; |
|
605 |
rect.w:= rect.w - edgeHeight * 2; |
|
606 |
rect.h:= textHeight + cornerHeight * 2 - edgeHeight * 2; |
|
607 |
i:= rect.w; |
|
608 |
j:= rect.h; |
|
13490
8935dcc0e130
Always use SDL_Map(A)RGB in SDL_FillRect for color
Wuzzy <Wuzzy2@mail.ru>
parents:
12591
diff
changeset
|
609 |
SDL_FillRect(finalSurface, @rect, SDL_MapRGB(finalSurface^.format, cWhiteColor shr 16, cWhiteColor shr 8, cWhiteColor and $FF)); |
4380 | 610 |
|
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
611 |
pos:= 1; line:= 0; |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
612 |
while GetNextSpeechLine(s, #1, pos, substr) do |
4380 | 613 |
begin |
10689
692649e341fc
change string types of speech bubbles fix to work with pas2c
sheepluva
parents:
10687
diff
changeset
|
614 |
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, PChar(substr), cNearBlackColorChannels); |
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
615 |
rect.x:= edgeHeight + 1 + ((i - w) div 2); |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
616 |
// trying to more evenly position the text, vertically |
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
617 |
rect.y:= edgeHeight + ((j-(numLines*h)) div 2) + line * h; |
11507 | 618 |
if not SDLCheck(tmpsurf <> nil, 'TTF_RenderUTF8_Blended', true) then |
619 |
begin |
|
620 |
SDL_UpperBlit(tmpsurf, nil, finalSurface, @rect); |
|
621 |
SDL_FreeSurface(tmpsurf); |
|
622 |
end; |
|
10687
2e921409b5b1
cleanup speech bubble code a little. this fixes issue 719
sheepluva
parents:
10494
diff
changeset
|
623 |
inc(line); |
4380 | 624 |
end; |
625 |
||
626 |
RenderSpeechBubbleTex:= Surface2Tex(finalSurface, true); |
|
627 |
||
628 |
SDL_FreeSurface(rotatedEdge); |
|
629 |
SDL_FreeSurface(finalSurface); |
|
8026
4a4f21070479
merge xymeng's gsoc engine with a few updates (and further checks on symbol definitions)
koda
parents:
7546
diff
changeset
|
630 |
|
4380 | 631 |
end; |
632 |
||
4611 | 633 |
end. |