source: tags/1.3.1/Packages/CevoComponents/ScreenTools.pas

Last change on this file was 442, checked in by chronos, 2 years ago
  • Modified: Code cleanup.
File size: 56.6 KB
Line 
1unit ScreenTools;
2
3interface
4
5uses
6 {$IFDEF WINDOWS}
7 Windows,
8 {$ENDIF}
9 StringTables, LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, Math,
10 Forms, Menus, GraphType, UGraphicSet, LazFileUtils, UTexture;
11
12type
13 TLoadGraphicFileOption = (gfNoError, gfNoGamma);
14 TLoadGraphicFileOptions = set of TLoadGraphicFileOption;
15
16 TFontType = (ftNormal, ftSmall, ftTiny, ftCaption, ftButton);
17
18{$IFDEF WINDOWS}
19function ChangeResolution(x, y, bpp, freq: integer): boolean;
20{$ENDIF}
21procedure RestoreResolution;
22procedure EmptyMenu(MenuItems: TMenuItem; Keep: Integer = 0);
23function TurnToYear(Turn: integer): integer;
24function TurnToString(Turn: integer): string;
25function MovementToString(Movement: integer): string;
26procedure BtnFrame(ca: TCanvas; p: TRect; T: TTexture);
27procedure EditFrame(ca: TCanvas; p: TRect; T: TTexture);
28function HexStringToColor(S: string): integer;
29function ExtractFileNameWithoutExt(const Filename: string): string;
30function LoadGraphicFile(Bmp: TBitmap; FileName: string; Options: TLoadGraphicFileOptions = []): boolean;
31function LoadGraphicSet(const Name: string; Transparency: Boolean = True): TGraphicSet;
32procedure Dump(dst: TBitmap; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
33procedure BitmapReplaceColor(Dst: TBitmap; X, Y, Width, Height: Integer; OldColor, NewColor: TColor);
34procedure Sprite(Canvas: TCanvas; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
35 overload;
36procedure Sprite(dst: TBitmap; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
37 overload;
38procedure MakeBlue(Dst: TBitmap; X, Y, Width, Height: Integer);
39procedure MakeRed(Dst: TBitmap; X, Y, Width, Height: Integer);
40procedure ImageOp_B(dst, Src: TBitmap; xDst, yDst, xSrc, ySrc, Width, Height: Integer);
41procedure ImageOp_BCC(Dst, Src: TBitmap;
42 xDst, yDst, xSrc, ySrc, Width, Height, Color1, Color2: Integer); overload;
43procedure ImageOp_BCC(Dst, Src: TBitmap;
44 DstPos: TPoint; SrcRect: TRect; Color1, Color2: Integer); overload;
45procedure ImageOp_CBC(Dst, Src: TBitmap; xDst, yDst, xSrc, ySrc, Width, Height,
46 Color0, Color2: Integer);
47procedure ImageOp_CCC(bmp: TBitmap; x, y, Width, Height, Color0, Color1, Color2: Integer);
48function BitBltCanvas(DestCanvas: TCanvas; X, Y, Width, Height: Integer;
49 SrcCanvas: TCanvas; XSrc, YSrc: Integer; Rop: DWORD = SRCCOPY): Boolean; overload;
50function BitBltCanvas(Dest: TCanvas; DestRect: TRect;
51 Src: TCanvas; SrcPos: TPoint; Rop: DWORD = SRCCOPY): Boolean; overload;
52function BitBltBitmap(Dest: TBitmap; X, Y, Width, Height: Integer;
53 Src: TBitmap; XSrc, YSrc: Integer; Rop: DWORD = SRCCOPY): Boolean; overload;
54function BitBltBitmap(Dest: TBitmap; DestRect: TRect;
55 Src: TBitmap; SrcPos: TPoint; Rop: DWORD = SRCCOPY): Boolean; overload;
56procedure SLine(ca: TCanvas; x0, x1, y: integer; cl: TColor);
57procedure DLine(ca: TCanvas; x0, x1, y: integer; cl0, cl1: TColor);
58procedure Frame(ca: TCanvas; x0, y0, x1, y1: integer; cl0, cl1: TColor);
59procedure RFrame(ca: TCanvas; x0, y0, x1, y1: integer; cl0, cl1: TColor);
60procedure CFrame(ca: TCanvas; x0, y0, x1, y1, Corner: integer; cl: TColor);
61procedure FrameImage(ca: TCanvas; Src: TBitmap;
62 x, y, Width, Height, xSrc, ySrc: integer; IsControl: boolean = False);
63procedure GlowFrame(Dst: TBitmap; x0, y0, Width, Height: integer; cl: TColor);
64procedure InitOrnament;
65procedure InitCityMark(T: TTexture);
66procedure Fill(ca: TCanvas; Left, Top, Width, Height, xOffset, yOffset: integer); overload;
67procedure Fill(Canvas: TCanvas; Rect: TRect; Offset: TPoint); overload;
68procedure FillLarge(ca: TCanvas; x0, y0, x1, y1, xm: integer);
69procedure FillSeamless(ca: TCanvas; Left, Top, Width, Height, xOffset, yOffset: integer;
70 const Texture: TBitmap);
71procedure FillRectSeamless(ca: TCanvas; x0, y0, x1, y1, xOffset, yOffset: integer;
72 const Texture: TBitmap);
73procedure PaintBackground(Form: TForm; Left, Top, Width, Height: integer);
74procedure Corner(ca: TCanvas; x, y, Kind: integer; T: TTexture);
75procedure BiColorTextOut(ca: TCanvas; clMain, clBack: TColor; x, y: integer; s: string);
76procedure LoweredTextOut(ca: TCanvas; cl: TColor; T: TTexture;
77 x, y: integer; s: string);
78function BiColorTextWidth(ca: TCanvas; s: string): integer;
79procedure RisedTextOut(ca: TCanvas; x, y: integer; s: string);
80procedure LightGradient(ca: TCanvas; x, y, Width, Color: integer);
81procedure DarkGradient(ca: TCanvas; x, y, Width, Kind: integer);
82procedure VLightGradient(ca: TCanvas; x, y, Height, Color: integer);
83procedure VDarkGradient(ca: TCanvas; x, y, Height, Kind: integer);
84procedure UnderlinedTitleValue(Canvas: TCanvas; Title, Value: string; X, Y, Width: Integer);
85procedure NumberBar(dst: TBitmap; x, y: integer; Cap: string; val: integer;
86 T: TTexture);
87procedure CountBar(dst: TBitmap; x, y, w: integer; Kind: integer;
88 Cap: string; val: integer; T: TTexture);
89procedure PaintProgressBar(ca: TCanvas; Kind, x, y, pos, Growth, max: integer;
90 T: TTexture);
91procedure PaintRelativeProgressBar(ca: TCanvas;
92 Kind, x, y, size, pos, Growth, max: integer; IndicateComplete: boolean;
93 T: TTexture);
94procedure PaintLogo(Canvas: TCanvas; X, Y, LightColor, ShadeColor: integer);
95procedure LoadPhrases;
96procedure Texturize(Dest, Texture: TBitmap; TransparentColor: Cardinal);
97procedure DarkenImage(Bitmap: TBitmap; Change: Integer);
98function ScaleToNative(Value: Integer): Integer;
99function ScaleFromNative(Value: Integer): Integer;
100procedure UnshareBitmap(Bitmap: TBitmap);
101procedure Gtk2Fix;
102
103const
104 TransparentColor1 = $FF00FF;
105 TransparentColor2 = $7F007F;
106
107 // template positions in Templates.png
108 xNation = 1;
109 yNation = 25;
110 xCoal = 1;
111 yCoal = 148;
112
113 // Icons.bmp structure
114 xSizeBig = 56;
115 ySizeBig = 40;
116
117 GlowRange = 8;
118
119 EmptySpaceColor = $101010;
120
121 // color matrix
122 clkAge0 = 1;
123 cliTexture = 0;
124 cliBevelLight = cliTexture + 1;
125 cliBevelShade = cliTexture + 2;
126 cliTextLight = cliTexture + 3;
127 cliTextShade = cliTexture + 4;
128 cliLitText = cliTexture + 5;
129 cliMark = cliTexture + 6;
130 cliDimmedText = cliTexture + 7;
131 cliRoad = 8;
132 cliHouse = cliRoad + 1;
133 cliImp = cliRoad + 2;
134 cliImpProject = cliRoad + 3;
135 cliPage = 13;
136 cliCover = cliPage + 1;
137 clkMisc = 5;
138 cliPaper = 0;
139 cliPaperText = 1;
140 cliPaperCaption = 2;
141 clkCity = 6;
142 cliPlains = 0;
143 cliPrairie = 1;
144 cliHills = 2;
145 cliTundra = 3;
146 cliWater = 4;
147
148var
149 Phrases: TStringTable;
150 Phrases2: TStringTable;
151 GrExt: TGraphicSets;
152
153 HGrSystem: TGraphicSet;
154 CityMark1: TGraphicSetItem;
155 CityMark2: TGraphicSetItem;
156
157 HGrSystem2: TGraphicSet;
158 Ornament: TGraphicSetItem;
159 GBrainNoTerm: TGraphicSetItem;
160 GBrainSuperVirtual: TGraphicSetItem;
161 GBrainTerm: TGraphicSetItem;
162 GBrainRandom: TGraphicSetItem;
163
164 Templates: TGraphicSet;
165 Logo: TGraphicSetItem;
166 BigBook: TGraphicSetItem;
167 SmallBook: TGraphicSetItem;
168 MenuLogo: TGraphicSetItem;
169 LinkArrows: TGraphicSetItem;
170 ScienceNationDot: TGraphicSetItem;
171 ResearchIcon: TGraphicSetItem;
172 ChangeIcon: TGraphicSetItem;
173 TreasuryIcon: TGraphicSetItem;
174 StarshipDeparted: TGraphicSetItem;
175 WeightOn: TGraphicSetItem;
176 WeightOff: TGraphicSetItem;
177
178 ClickFrameColor: Integer;
179 MainTexture: TTexture;
180 Colors: TBitmap;
181 Paper: TBitmap;
182 BigImp: TBitmap;
183 LogoBuffer: TBitmap;
184 FullScreen: Boolean;
185 GenerateNames: Boolean;
186 InitOrnamentDone: Boolean;
187 Phrases2FallenBackToEnglish: Boolean;
188
189 UniFont: array [TFontType] of TFont;
190 Gamma: Integer; // global gamma correction (cent)
191
192procedure LoadAssets;
193procedure UnitInit;
194procedure UnitDone;
195procedure InitGammaLookupTable;
196
197
198implementation
199
200uses
201 Directories, Sound, UPixelPointer;
202
203var
204 {$IFDEF WINDOWS}
205 StartResolution: TDeviceMode;
206 ResolutionChanged: boolean;
207 {$ENDIF}
208
209 GammaLookupTable: array [0..255] of Byte;
210
211{$IFDEF WINDOWS}
212function ChangeResolution(x, y, bpp, freq: integer): boolean;
213var
214 DevMode: TDeviceMode;
215begin
216 EnumDisplaySettings(nil, 0, DevMode);
217 DevMode.dmFields := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL or
218 DM_DISPLAYFREQUENCY;
219 DevMode.dmPelsWidth := x;
220 DevMode.dmPelsHeight := y;
221 DevMode.dmBitsPerPel := bpp;
222 DevMode.dmDisplayFrequency := freq;
223 Result := ChangeDisplaySettings(DevMode, 0) = DISP_CHANGE_SUCCESSFUL;
224 if Result then
225 ResolutionChanged := True;
226end;
227
228{$ENDIF}
229
230procedure RestoreResolution;
231begin
232 {$IFDEF WINDOWS}
233 if ResolutionChanged then
234 ChangeDisplaySettings(StartResolution, 0);
235 ResolutionChanged := False;
236 {$ENDIF}
237end;
238
239procedure EmptyMenu(MenuItems: TMenuItem; Keep: Integer = 0);
240var
241 MenuItem: TMenuItem;
242begin
243 while MenuItems.Count > Keep do begin
244 MenuItem := MenuItems[MenuItems.Count - 1];
245 MenuItems.Delete(MenuItems.Count - 1);
246 FreeAndNil(MenuItem);
247 end;
248end;
249
250function TurnToYear(Turn: Integer): Integer;
251begin
252 Result := -4000;
253 if Turn <= 0 then Exit;
254
255 // Year -4000..-1000, Turn 0..60
256 Inc(Result, Min(60, Turn) * 50);
257 Dec(Turn, Min(60, Turn));
258 if Turn = 0 then Exit;
259
260 // Year -1000..0, Turn 60..100
261 Inc(Result, Min(40, Turn) * 25);
262 Dec(Turn, Min(40, Turn));
263 if Turn = 0 then Exit;
264
265 // Year 0..1500, Turn 100..175
266 Inc(Result, Min(75, Turn) * 20);
267 Dec(Turn, Min(75, Turn));
268 if Turn = 0 then Exit;
269
270 // Year 1500..1750, Turn 175..200
271 Inc(Result, Min(25, Turn) * 10);
272 Dec(Turn, Min(25, Turn));
273 if Turn = 0 then Exit;
274
275 // Year 1750..1850, Turn 200..250
276 Inc(Result, Min(50, Turn) * 2);
277 Dec(Turn, Min(50, Turn));
278 if Turn = 0 then Exit;
279
280 // Year 1850.., Turn 250..
281 Inc(Result, Turn);
282end;
283
284function TurnToString(Turn: Integer): string;
285var
286 Year: Integer;
287begin
288 if GenerateNames then
289 begin
290 Year := TurnToYear(Turn);
291 if Year < 0 then
292 Result := Format(Phrases.Lookup('BC'), [-Year])
293 else
294 Result := Format(Phrases.Lookup('AD'), [Year]);
295 end
296 else
297 Result := IntToStr(Turn);
298end;
299
300function MovementToString(Movement: Integer): string;
301begin
302 if Movement >= 1000 then
303 begin
304 Result := Char(48 + Movement div 1000);
305 Movement := Movement mod 1000;
306 end
307 else
308 Result := '';
309 Result := Result + Char(48 + Movement div 100);
310 Movement := Movement mod 100;
311 if Movement > 0 then
312 begin
313 Result := Result + '.' + Char(48 + Movement div 10);
314 Movement := Movement mod 10;
315 if Movement > 0 then
316 Result := Result + Char(48 + Movement);
317 end;
318end;
319
320procedure BtnFrame(ca: TCanvas; p: TRect; T: TTexture);
321begin
322 RFrame(ca, p.Left - 1, p.Top - 1, p.Right, p.Bottom, T.ColorBevelShade,
323 T.ColorBevelLight);
324end;
325
326procedure EditFrame(ca: TCanvas; p: TRect; T: TTexture);
327begin
328 Frame(ca, p.Left - 1, p.Top - 1, p.Right, p.Bottom, $000000, $000000);
329 Frame(ca, p.Left - 2, p.Top - 2, p.Right + 1, p.Bottom + 1, $000000, $000000);
330 Frame(ca, p.Left - 3, p.Top - 3, p.Right + 2, p.Bottom + 1, $000000, $000000);
331 RFrame(ca, p.Left - 4, p.Top - 4, p.Right + 3, p.Bottom + 2, T.ColorBevelShade,
332 T.ColorBevelLight);
333end;
334
335function HexCharToInt(X: Char): Integer;
336begin
337 case x of
338 '0' .. '9': Result := Ord(X) - Ord('0');
339 'A' .. 'F': Result := Ord(X) - Ord('A') + 10;
340 'a' .. 'f': Result := Ord(X) - Ord('a') + 10;
341 else Result := 0
342 end;
343end;
344
345function HexStringToColor(S: string): Integer;
346begin
347 while (Length(S) > 0) and (S[1] = ' ') do
348 Delete(S, 1, 1);
349 S := S + '000000';
350 if Gamma = 100 then
351 Result := $10 * HexCharToInt(S[1]) + $1 * HexCharToInt(S[2]) +
352 $1000 * HexCharToInt(S[3]) + $100 * HexCharToInt(S[4]) +
353 $100000 * HexCharToInt(S[5]) + $10000 * HexCharToInt(S[6])
354 else
355 Result := GammaLookupTable[$10 * HexCharToInt(S[1]) + HexCharToInt(S[2])] +
356 $100 * GammaLookupTable[$10 * HexCharToInt(S[3]) + HexCharToInt(S[4])] +
357 $10000 * GammaLookupTable[$10 * HexCharToInt(S[5]) + HexCharToInt(S[6])];
358end;
359
360function ApplyGammaToPixel(Pixel: TPixel32): TPixel32;
361begin
362 Result.R := GammaLookupTable[Pixel.R];
363 Result.G := GammaLookupTable[Pixel.G];
364 Result.B := GammaLookupTable[Pixel.B];
365end;
366
367procedure ApplyGammaToBitmap(Bitmap: TBitmap);
368var
369 PixelPtr: TPixelPointer;
370 X, Y: Integer;
371begin
372 Bitmap.BeginUpdate;
373 PixelPtr := PixelPointer(Bitmap);
374 for Y := 0 to ScaleToNative(Bitmap.Height) - 1 do begin
375 for X := 0 to ScaleToNative(Bitmap.Width) - 1 do begin
376 PixelPtr.Pixel^ := ApplyGammaToPixel(PixelPtr.Pixel^);
377 PixelPtr.NextPixel;
378 end;
379 PixelPtr.NextLine;
380 end;
381 Bitmap.EndUpdate;
382end;
383
384procedure CopyGray8BitTo24bitBitmap(Dst, Src: TRasterImage);
385var
386 SrcPtr, DstPtr: TPixelPointer;
387 X, Y: Integer;
388begin
389 //Dst.SetSize(Src.Width, Src.Height);
390 SrcPtr := PixelPointer(Src);
391 DstPtr := PixelPointer(Dst);
392 for Y := 0 to ScaleToNative(Src.Height - 1) do begin
393 for X := 0 to ScaleToNative(Src.Width - 1) do begin
394 DstPtr.Pixel^.B := SrcPtr.Pixel^.B;
395 DstPtr.Pixel^.G := SrcPtr.Pixel^.B;
396 DstPtr.Pixel^.R := SrcPtr.Pixel^.B;
397 SrcPtr.NextPixel;
398 DstPtr.NextPixel;
399 end;
400 SrcPtr.NextLine;
401 DstPtr.NextLine;
402 end;
403end;
404
405function LoadGraphicFile(Bmp: TBitmap; FileName: string; Options:
406 TLoadGraphicFileOptions = []): Boolean;
407var
408 Jpeg: TJpegImage;
409 Png: TPortableNetworkGraphic;
410begin
411 Result := False;
412 if ExtractFileExt(FileName) = '' then
413 FileName := FileName + '.png';
414
415 if FileExists(FileName) then begin
416 if ExtractFileExt(FileName) = '.jpg' then begin
417 Jpeg := TJpegImage.Create;
418 try
419 Jpeg.LoadFromFile(FileName);
420 if not (gfNoGamma in Options) then
421 Bmp.PixelFormat := pf24bit;
422 Bmp.SetSize(Jpeg.Width, Jpeg.Height);
423 Bmp.Canvas.Draw(0, 0, Jpeg);
424 Result := True;
425 except
426 Result := False;
427 end;
428 FreeAndNil(Jpeg);
429 end else
430 if ExtractFileExt(FileName) = '.png' then begin
431 Png := TPortableNetworkGraphic.Create;
432 try
433 Png.PixelFormat := Bmp.PixelFormat;
434 Png.LoadFromFile(FileName);
435 if not (gfNoGamma in Options) then
436 Bmp.PixelFormat := pf24bit;
437 Bmp.SetSize(Png.Width, Png.Height);
438 if (Png.RawImage.Description.Format = ricfGray) then
439 begin
440 // LCL doesn't support 8-bit colors properly. Use 24-bit instead.
441 Bmp.PixelFormat := pf24bit;
442 CopyGray8BitTo24bitBitmap(Bmp, Png);
443 end
444 else
445 Bmp.Canvas.Draw(0, 0, Png);
446 Result := True;
447 except
448 Result := False;
449 end;
450 FreeAndNil(Png);
451 end else
452 if ExtractFileExt(FileName) = '.bmp' then begin
453 try
454 Bmp.LoadFromFile(FileName);
455 if not (gfNoGamma in Options) then
456 Bmp.PixelFormat := pf24bit;
457 Result := True;
458 except
459 Result := False;
460 end;
461 end else
462 raise Exception.Create('Unsupported image file type ' + ExtractFileExt(FileName));
463 end;
464
465 if not Result then begin
466 if not (gfNoError in Options) then
467 raise Exception.Create(Format(Phrases.Lookup('FILENOTFOUND'), [FileName]));
468 end;
469
470 if (not (gfNoGamma in Options)) and (Gamma <> 100) then
471 ApplyGammaToBitmap(Bmp);
472end;
473
474function ExtractFileNameWithoutExt(const Filename: string): string;
475var
476 P: Integer;
477begin
478 Result := Filename;
479 P := Length(Result);
480 while P > 0 do begin
481 case Result[P] of
482 PathDelim: Exit;
483 {$ifdef windows}
484 '/': if ('/' in AllowDirectorySeparators) then Exit;
485 {$endif}
486 '.': Exit(Copy(Result, 1, P - 1));
487 end;
488 Dec(P);
489 end;
490end;
491
492function LoadGraphicSet(const Name: string; Transparency: Boolean = True): TGraphicSet;
493var
494 x: Integer;
495 y: Integer;
496 OriginalColor: Integer;
497 FileName: string;
498 DataPixel: TPixelPointer;
499 MaskPixel: TPixelPointer;
500begin
501 Result := GrExt.SearchByName(Name);
502 if not Assigned(Result) then begin
503 Result := GrExt.AddNew(Name);
504 FileName := GetGraphicsDir + DirectorySeparator + Name;
505 // Do not apply gamma during file load as it would affect also transparency colors
506 if not LoadGraphicFile(Result.Data, FileName, [gfNoGamma]) then begin
507 Result := nil;
508 Exit;
509 end;
510
511 FileName := ExtractFileNameWithoutExt(FileName) + GraphicSetFileExt;
512 if FileExists(FileName) then
513 Result.LoadFromFile(FileName);
514
515 Result.ResetPixUsed;
516
517 if Transparency then begin
518 Result.Mask.SetSize(Result.Data.Width, Result.Data.Height);
519
520 Result.Data.BeginUpdate;
521 Result.Mask.BeginUpdate;
522 DataPixel := PixelPointer(Result.Data);
523 MaskPixel := PixelPointer(Result.Mask);
524 for y := 0 to ScaleToNative(Result.Data.Height) - 1 do begin
525 for x := 0 to ScaleToNative(Result.Data.Width) - 1 do begin
526 OriginalColor := DataPixel.Pixel^.ARGB and $FFFFFF;
527 if (OriginalColor = TransparentColor1) or (OriginalColor = TransparentColor2) then begin
528 MaskPixel.Pixel^.R := $FF;
529 MaskPixel.Pixel^.G := $FF;
530 MaskPixel.Pixel^.B := $FF;
531 DataPixel.Pixel^.R := 0;
532 DataPixel.Pixel^.G := 0;
533 DataPixel.Pixel^.B := 0;
534 end else begin
535 MaskPixel.Pixel^.R := $00;
536 MaskPixel.Pixel^.G := $00;
537 MaskPixel.Pixel^.B := $00;
538 end;
539 DataPixel.NextPixel;
540 MaskPixel.NextPixel;
541 end;
542 DataPixel.NextLine;
543 MaskPixel.NextLine;
544 end;
545 Result.Data.EndUpdate;
546 Result.Mask.EndUpdate;
547
548 if Gamma <> 100 then
549 ApplyGammaToBitmap(Result.Data);
550 end;
551 end;
552end;
553
554procedure Dump(dst: TBitmap; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
555begin
556 BitBltCanvas(dst.Canvas, xDst, yDst, Width, Height,
557 HGr.Data.Canvas, xGr, yGr);
558end;
559
560procedure BitmapReplaceColor(Dst: TBitmap; X, Y, Width, Height: Integer; OldColor, NewColor: TColor);
561var
562 XX, YY: Integer;
563 PixelPtr: TPixelPointer;
564begin
565 Dst.BeginUpdate;
566 PixelPtr := PixelPointer(Dst, ScaleToNative(X), ScaleToNative(Y));
567 for YY := 0 to ScaleToNative(Height) - 1 do begin
568 for XX := 0 to ScaleToNative(Width) - 1 do begin
569 if PixelPtr.Pixel^.RGB = SwapRedBlue(OldColor) then begin
570 PixelPtr.Pixel^.RGB := SwapRedBlue(NewColor);
571 end;
572 PixelPtr.NextPixel;
573 end;
574 PixelPtr.NextLine;
575 end;
576 Dst.EndUpdate;
577end;
578
579procedure MakeBlue(Dst: TBitmap; X, Y, Width, Height: Integer);
580var
581 XX, YY: Integer;
582 PixelPtr: TPixelPointer;
583begin
584 Dst.BeginUpdate;
585 PixelPtr := PixelPointer(Dst, ScaleToNative(X), ScaleToNative(Y));
586 for yy := 0 to ScaleToNative(Height) - 1 do begin
587 for xx := 0 to ScaleToNative(Width) - 1 do begin
588 PixelPtr.Pixel^.B := PixelPtr.Pixel^.B div 2;
589 PixelPtr.Pixel^.G := PixelPtr.Pixel^.G div 2;
590 PixelPtr.Pixel^.R := PixelPtr.Pixel^.R div 2;
591 PixelPtr.NextPixel;
592 end;
593 PixelPtr.NextLine;
594 end;
595 Dst.EndUpdate;
596end;
597
598procedure MakeRed(Dst: TBitmap; X, Y, Width, Height: Integer);
599var
600 XX, YY: Integer;
601 Gray: Integer;
602 PixelPtr: TPixelPointer;
603begin
604 Dst.BeginUpdate;
605 PixelPtr := PixelPointer(Dst, ScaleToNative(X), ScaleToNative(Y));
606 for YY := 0 to ScaleToNative(Height) - 1 do begin
607 for XX := 0 to ScaleToNative(Width) - 1 do begin
608 Gray := (Integer(PixelPtr.Pixel^.B) + Integer(PixelPtr.Pixel^.G) +
609 Integer(PixelPtr.Pixel^.R)) * 85 shr 8;
610 PixelPtr.Pixel^.B := 0;
611 PixelPtr.Pixel^.G := 0;
612 PixelPtr.Pixel^.R := Gray; // 255-(255-gray) div 2;
613 PixelPtr.NextPixel;
614 end;
615 PixelPtr.NextLine;
616 end;
617 Dst.EndUpdate;
618end;
619
620procedure ImageOp_B(dst, Src: TBitmap; xDst, yDst, xSrc, ySrc, Width, Height: Integer);
621// Src is template
622// X channel = background amp (old Dst content), 128=original brightness
623var
624 X, Y: Integer;
625 Brightness, Test: Integer;
626 PixelSrc: TPixelPointer;
627 PixelDst: TPixelPointer;
628begin
629 xDst := ScaleToNative(xDst);
630 yDst := ScaleToNative(yDst);
631 xSrc := ScaleToNative(xSrc);
632 ySrc := ScaleToNative(ySrc);
633 Width := ScaleToNative(Width);
634 Height := ScaleToNative(Height);
635 //Assert(Src.PixelFormat = pf8bit);
636 Assert(dst.PixelFormat = pf24bit);
637 if xDst < 0 then begin
638 Width := Width + xDst;
639 xSrc := xSrc - xDst;
640 xDst := 0;
641 end;
642 if yDst < 0 then begin
643 Height := Height + yDst;
644 ySrc := ySrc - yDst;
645 yDst := 0;
646 end;
647 if xDst + Width > ScaleToNative(dst.Width) then
648 Width := ScaleToNative(dst.Width) - xDst;
649 if yDst + Height > ScaleToNative(dst.Height) then
650 Height := ScaleToNative(dst.Height) - yDst;
651 if (Width < 0) or (Height < 0) then
652 exit;
653
654 dst.BeginUpdate;
655 Src.BeginUpdate;
656 PixelDst := PixelPointer(Dst, xDst, yDst);
657 PixelSrc := PixelPointer(Src, xSrc, ySrc);
658 for Y := 0 to Height - 1 do begin
659 for X := 0 to Width - 1 do begin
660 Brightness := PixelSrc.Pixel^.B; // One byte for 8-bit color
661 test := (PixelDst.Pixel^.R * Brightness) shr 7;
662 if test >= 256 then
663 PixelDst.Pixel^.R := 255
664 else
665 PixelDst.Pixel^.R := test; // Red
666 test := (PixelDst.Pixel^.G * Brightness) shr 7;
667 if test >= 256 then
668 PixelDst.Pixel^.G := 255
669 else
670 PixelDst.Pixel^.G := test; // Green
671 test := (PixelDst.Pixel^.B * Brightness) shr 7;
672 if test >= 256 then
673 PixelDst.Pixel^.R := 255
674 else
675 PixelDst.Pixel^.B := Test; // Blue
676 PixelDst.NextPixel;
677 PixelSrc.NextPixel;
678 end;
679 PixelDst.NextLine;
680 PixelSrc.NextLine;
681 end;
682 src.EndUpdate;
683 dst.EndUpdate;
684end;
685
686procedure ImageOp_BCC(dst, Src: TBitmap; xDst, yDst, xSrc, ySrc, Width, Height,
687 Color1, Color2: Integer);
688// Src is template
689// B channel = background amp (old Dst content), 128=original brightness
690// G channel = Color1 amp, 128=original brightness
691// R channel = Color2 amp, 128=original brightness
692var
693 ix, iy, amp1, amp2, trans, Value: Integer;
694 SrcPixel: TPixelPointer;
695 DstPixel: TPixelPointer;
696begin
697 xDst := ScaleToNative(xDst);
698 yDst := ScaleToNative(yDst);
699 xSrc := ScaleToNative(xSrc);
700 ySrc := ScaleToNative(ySrc);
701 Width := ScaleToNative(Width);
702 Height := ScaleToNative(Height);
703 if xDst < 0 then begin
704 Width := Width + xDst;
705 xSrc := xSrc - xDst;
706 xDst := 0;
707 end;
708 if yDst < 0 then begin
709 Height := Height + yDst;
710 ySrc := ySrc - yDst;
711 yDst := 0;
712 end;
713 if xDst + Width > ScaleToNative(dst.Width) then
714 Width := ScaleToNative(dst.Width) - xDst;
715 if yDst + Height > ScaleToNative(dst.Height) then
716 Height := ScaleToNative(dst.Height) - yDst;
717 if (Width < 0) or (Height < 0) then
718 exit;
719
720 Src.BeginUpdate;
721 dst.BeginUpdate;
722 SrcPixel := PixelPointer(Src, xSrc, ySrc);
723 DstPixel := PixelPointer(Dst, xDst, yDst);
724 for iy := 0 to Height - 1 do begin
725 for ix := 0 to Width - 1 do begin
726 trans := SrcPixel.Pixel^.B * 2; // green channel = transparency
727 amp1 := SrcPixel.Pixel^.G * 2;
728 amp2 := SrcPixel.Pixel^.R * 2;
729 if trans <> $FF then begin
730 Value := (DstPixel.Pixel^.B * trans + ((Color2 shr 16) and $FF) *
731 amp2 + ((Color1 shr 16) and $FF) * amp1) div $FF;
732 DstPixel.Pixel^.B := Min(Value, 255);
733
734 Value := (DstPixel.Pixel^.G * trans + ((Color2 shr 8) and $FF) *
735 amp2 + ((Color1 shr 8) and $FF) * amp1) div $FF;
736 DstPixel.Pixel^.G := Min(Value, 255);
737
738 Value := (DstPixel.Pixel^.R * trans + (Color2 and $FF) *
739 amp2 + (Color1 and $FF) * amp1) div $FF;
740 DstPixel.Pixel^.R := Min(Value, 255);
741 end;
742
743 SrcPixel.NextPixel;
744 DstPixel.NextPixel;
745 end;
746 SrcPixel.NextLine;
747 DstPixel.NextLine;
748 end;
749 Src.EndUpdate;
750 dst.EndUpdate;
751end;
752
753procedure ImageOp_BCC(Dst, Src: TBitmap; DstPos: TPoint; SrcRect: TRect;
754 Color1, Color2: Integer);
755begin
756 ImageOp_BCC(Dst, Src, DstPos.X, DstPos.Y, SrcRect.Left, SrcRect.Top,
757 SrcRect.Width, SrcRect.Height, Color1, Color2);
758end;
759
760procedure ImageOp_CBC(Dst, Src: TBitmap; xDst, yDst, xSrc, ySrc, Width, Height,
761 Color0, Color2: Integer);
762// Src is template
763// B channel = Color0 amp
764// G channel = background amp (old Dst content), 128=original brightness
765// R channel = Color2 amp
766var
767 ix, iy, amp0, amp1, trans, Value: integer;
768 SrcPixel: TPixelPointer;
769 DstPixel: TPixelPointer;
770begin
771 xDst := ScaleToNative(xDst);
772 yDst := ScaleToNative(yDst);
773 xSrc := ScaleToNative(xSrc);
774 ySrc := ScaleToNative(ySrc);
775 Width := ScaleToNative(Width);
776 Height := ScaleToNative(Height);
777 Src.BeginUpdate;
778 Dst.BeginUpdate;
779 SrcPixel := PixelPointer(Src, xSrc, ySrc);
780 DstPixel := PixelPointer(Dst, xDst, yDst);
781 for iy := 0 to Height - 1 do begin
782 for ix := 0 to Width - 1 do begin
783 trans := SrcPixel.Pixel^.B * 2; // green channel = transparency
784 amp0 := SrcPixel.Pixel^.G * 2;
785 amp1 := SrcPixel.Pixel^.R * 2;
786 if trans <> $FF then begin
787 Value := (DstPixel.Pixel^.B * trans + (Color2 shr 16 and $FF) * amp1 +
788 (Color0 shr 16 and $FF) * amp0) div $FF;
789 DstPixel.Pixel^.B := Min(Value, 255);
790
791 Value := (DstPixel.Pixel^.G * trans + (Color2 shr 8 and $FF) * amp1 +
792 (Color0 shr 8 and $FF) * amp0) div $FF;
793 DstPixel.Pixel^.G := Min(Value, 255);
794
795 Value := (DstPixel.Pixel^.R * trans + (Color2 and $FF) * amp1 +
796 (Color0 and $FF) * amp0) div $FF;
797 DstPixel.Pixel^.R := Min(Value, 255);
798 end;
799 SrcPixel.NextPixel;
800 DstPixel.NextPixel;
801 end;
802 SrcPixel.NextLine;
803 DstPixel.NextLine;
804 end;
805 Src.EndUpdate;
806 Dst.EndUpdate;
807end;
808
809procedure ImageOp_CCC(bmp: TBitmap; x, y, Width, Height, Color0, Color1, Color2: Integer);
810// Bmp is template
811// B channel = Color0 amp, 128=original brightness
812// G channel = Color1 amp, 128=original brightness
813// R channel = Color2 amp, 128=original brightness
814var
815 i, Red, Green: Integer;
816 PixelPtr: TPixelPointer;
817begin
818 X := ScaleToNative(X);
819 Y := ScaleToNative(Y);
820 Width := ScaleToNative(Width);
821 Height := ScaleToNative(Height);
822 bmp.BeginUpdate;
823 assert(bmp.PixelFormat = pf24bit);
824 Height := y + Height;
825 PixelPtr := PixelPointer(Bmp, x, y);
826 while y < Height do begin
827 for i := 0 to Width - 1 do begin
828 Red := ((PixelPtr.Pixel^.B * (Color0 and $0000FF) + PixelPtr.Pixel^.G *
829 (Color1 and $0000FF) + PixelPtr.Pixel^.R * (Color2 and $0000FF)) shr 8) and $ff;
830 Green := ((PixelPtr.Pixel^.B * ((Color0 shr 8) and $0000FF) +
831 PixelPtr.Pixel^.G * ((Color1 shr 8) and $0000FF) + PixelPtr.Pixel^.R *
832 ((Color2 shr 8) and $0000FF)) shr 8) and $ff;
833 PixelPtr.Pixel^.B := ((PixelPtr.Pixel^.B * ((Color0 shr 16) and $0000FF) +
834 PixelPtr.Pixel^.G * ((Color1 shr 16) and $0000FF) + PixelPtr.Pixel^.R *
835 ((Color2 shr 16) and $0000FF)) shr 8) and $ff; // Blue
836 PixelPtr.Pixel^.G := Green;
837 PixelPtr.Pixel^.R := Red;
838 PixelPtr.NextPixel;
839 end;
840 Inc(y);
841 PixelPtr.NextLine;
842 end;
843 bmp.EndUpdate;
844end;
845
846procedure Sprite(Canvas: TCanvas; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
847begin
848 BitBltCanvas(Canvas, xDst, yDst, Width, Height,
849 HGr.Mask.Canvas, xGr, yGr, SRCAND);
850 BitBltCanvas(Canvas, xDst, yDst, Width, Height,
851 HGr.Data.Canvas, xGr, yGr, SRCPAINT);
852end;
853
854procedure Sprite(dst: TBitmap; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
855begin
856 BitBltCanvas(dst.Canvas, xDst, yDst, Width, Height,
857 HGr.Mask.Canvas, xGr, yGr, SRCAND);
858 BitBltCanvas(dst.Canvas, xDst, yDst, Width, Height,
859 HGr.Data.Canvas, xGr, yGr, SRCPAINT);
860end;
861
862function BitBltCanvas(DestCanvas: TCanvas; X, Y, Width, Height: Integer;
863 SrcCanvas: TCanvas; XSrc, YSrc: Integer; Rop: DWORD = SRCCOPY): Boolean;
864begin
865 {$IFDEF WINDOWS}
866 // LCLIntf.BitBlt is slower than direct Windows BitBlt
867 Result := Windows.BitBlt(DestCanvas.Handle, X, Y, Width, Height, SrcCanvas.Handle, XSrc, YSrc, Rop);
868 {$ELSE}
869 Result := BitBlt(DestCanvas.Handle, X, Y, Width, Height, SrcCanvas.Handle, XSrc, YSrc, Rop);
870 {$ENDIF}
871end;
872
873function BitBltCanvas(Dest: TCanvas; DestRect: TRect; Src: TCanvas;
874 SrcPos: TPoint; Rop: DWORD): Boolean;
875begin
876 Result := BitBltCanvas(Dest, DestRect.Left, DestRect.Top, DestRect.Width, DestRect.Height,
877 Src, SrcPos.X, SrcPos.Y, Rop);
878end;
879
880function BitBltBitmap(Dest: TBitmap; X, Y, Width, Height: Integer;
881 Src: TBitmap; XSrc, YSrc: Integer; Rop: DWORD): Boolean;
882begin
883 Result := BitBltCanvas(Dest.Canvas, X, Y, Width, Height, Src.Canvas, XSrc, YSrc, Rop);
884end;
885
886function BitBltBitmap(Dest: TBitmap; DestRect: TRect; Src: TBitmap;
887 SrcPos: TPoint; Rop: DWORD): Boolean;
888begin
889 Result := BitBltCanvas(Dest.Canvas, DestRect, Src.Canvas, SrcPos, Rop);
890end;
891
892procedure SLine(ca: TCanvas; x0, x1, y: integer; cl: TColor);
893begin
894 with ca do begin
895 Pen.Color := cl;
896 MoveTo(x0, y);
897 LineTo(x1 + 1, y);
898 end;
899end;
900
901procedure DLine(ca: TCanvas; x0, x1, y: integer; cl0, cl1: TColor);
902begin
903 with ca do begin
904 Pen.Color := cl0;
905 MoveTo(x0, y);
906 LineTo(x1, y);
907 Pen.Color := cl1;
908 MoveTo(x0 + 1, y + 1);
909 LineTo(x1 + 1, y + 1);
910 Pixels[x0, y + 1] := cl0;
911 Pixels[x1, y] := cl1;
912 end;
913end;
914
915procedure Frame(ca: TCanvas; x0, y0, x1, y1: integer; cl0, cl1: TColor);
916begin
917 with ca do begin
918 MoveTo(x0, y1);
919 Pen.Color := cl0;
920 LineTo(x0, y0);
921 LineTo(x1, y0);
922 Pen.Color := cl1;
923 LineTo(x1, y1);
924 LineTo(x0, y1);
925 end;
926end;
927
928procedure RFrame(ca: TCanvas; x0, y0, x1, y1: integer; cl0, cl1: TColor);
929begin
930 with ca do begin
931 Pen.Color := cl0;
932 MoveTo(x0, y0 + 1);
933 LineTo(x0, y1);
934 MoveTo(x0 + 1, y0);
935 LineTo(x1, y0);
936 Pen.Color := cl1;
937 MoveTo(x1, y0 + 1);
938 LineTo(x1, y1);
939 MoveTo(x0 + 1, y1);
940 LineTo(x1, y1);
941 end;
942end;
943
944procedure CFrame(ca: TCanvas; x0, y0, x1, y1, Corner: integer; cl: TColor);
945begin
946 with ca do begin
947 Pen.Color := cl;
948 MoveTo(x0, y0 + Corner - 1);
949 LineTo(x0, y0);
950 LineTo(x0 + Corner, y0);
951 MoveTo(x1, y0 + Corner - 1);
952 LineTo(x1, y0);
953 LineTo(x1 - Corner, y0);
954 MoveTo(x1, y1 - Corner + 1);
955 LineTo(x1, y1);
956 LineTo(x1 - Corner, y1);
957 MoveTo(x0, y1 - Corner + 1);
958 LineTo(x0, y1);
959 LineTo(x0 + Corner, y1);
960 end;
961end;
962
963procedure FrameImage(ca: TCanvas; Src: TBitmap;
964 x, y, Width, Height, xSrc, ySrc: integer; IsControl: boolean = False);
965begin
966 if IsControl then begin
967 Frame(ca, x - 1, y - 1, x + Width, y + Height, $B0B0B0, $FFFFFF);
968 RFrame(ca, x - 2, y - 2, x + Width + 1, y + Height + 1, $FFFFFF, $B0B0B0);
969 end else
970 Frame(ca, x - 1, y - 1, x + Width, y + Height, $000000, $000000);
971 BitBltCanvas(ca, x, y, Width, Height, Src.Canvas, xSrc, ySrc);
972end;
973
974procedure GlowFrame(Dst: TBitmap; x0, y0, Width, Height: Integer; cl: TColor);
975var
976 x, y, ch, r: Integer;
977 DstPtr: TPixelPointer;
978 DpiGlowRange: Integer;
979begin
980 DpiGlowRange := ScaleToNative(GlowRange);
981 X0 := ScaleToNative(X0);
982 Y0 := ScaleToNative(Y0);
983 Width := ScaleToNative(Width);
984 Height := ScaleToNative(Height);
985 Dst.BeginUpdate;
986 DstPtr := PixelPointer(Dst, x0 - DpiGlowRange + 1, y0 - DpiGlowRange + 1);
987 for y := -DpiGlowRange + 1 to Height - 1 + DpiGlowRange - 1 do begin
988 for x := -DpiGlowRange + 1 to Width - 1 + DpiGlowRange - 1 do begin
989 if x < 0 then
990 if y < 0 then
991 r := round(sqrt(sqr(x) + sqr(y)))
992 else if y >= Height then
993 r := round(sqrt(sqr(x) + sqr(y - (Height - 1))))
994 else
995 r := -x
996 else if x >= Width then
997 if y < 0 then
998 r := round(sqrt(sqr(x - (Width - 1)) + sqr(y)))
999 else if y >= Height then
1000 r := round(sqrt(sqr(x - (Width - 1)) + sqr(y - (Height - 1))))
1001 else
1002 r := x - (Width - 1)
1003 else if y < 0 then
1004 r := -y
1005 else if y >= Height then
1006 r := y - (Height - 1)
1007 else begin
1008 DstPtr.NextPixel;
1009 continue;
1010 end;
1011 if r = 0 then
1012 r := 1;
1013 if r < DpiGlowRange then
1014 for ch := 0 to 2 do
1015 DstPtr.Pixel^.Planes[2 - ch] :=
1016 (DstPtr.Pixel^.Planes[2 - ch] * (r - 1) + (cl shr (8 * ch) and $FF) *
1017 (DpiGlowRange - r)) div (DpiGlowRange - 1);
1018 DstPtr.NextPixel;
1019 end;
1020 DstPtr.NextLine;
1021 end;
1022 Dst.EndUpdate;
1023end;
1024
1025procedure InitOrnament;
1026var
1027 P: TColor;
1028 X, Y: Integer;
1029 Light, Shade: TColor32;
1030 PixelPtr: TPixelPointer;
1031begin
1032 if InitOrnamentDone then Exit;
1033 Light := ColorToColor32(MainTexture.ColorBevelLight);
1034 // and $FCFCFC shr 2*3+MainTexture.ColorBevelShade and $FCFCFC shr 2;
1035 Shade := ColorToColor32(MainTexture.ColorBevelShade and $FCFCFC shr 2 * 3 +
1036 MainTexture.ColorBevelLight and $FCFCFC shr 2);
1037 HGrSystem2.Data.BeginUpdate;
1038 PixelPtr := PixelPointer(HGrSystem2.Data, ScaleToNative(Ornament.Left),
1039 ScaleToNative(Ornament.Top));
1040 if PixelPtr.BytesPerPixel = 3 then begin
1041 for Y := 0 to ScaleToNative(Ornament.Height) - 1 do begin
1042 for X := 0 to ScaleToNative(Ornament.Width) - 1 do begin
1043 P := Color32ToColor(PixelPtr.Pixel^.RGB);
1044 if P = $0000FF then PixelPtr.Pixel^.RGB := Light
1045 else if P = $FF0000 then PixelPtr.Pixel^.RGB := Shade;
1046 PixelPtr.NextPixel;
1047 end;
1048 PixelPtr.NextLine;
1049 end;
1050 end else begin
1051 for Y := 0 to ScaleToNative(Ornament.Height) - 1 do begin
1052 for X := 0 to ScaleToNative(Ornament.Width) - 1 do begin
1053 P := Color32ToColor(PixelPtr.Pixel^.ARGB);
1054 if P = $0000FF then PixelPtr.Pixel^.ARGB := Light
1055 else if P = $FF0000 then PixelPtr.Pixel^.ARGB := Shade;
1056 PixelPtr.NextPixel;
1057 end;
1058 PixelPtr.NextLine;
1059 end;
1060 end;
1061 InitOrnamentDone := True;
1062 HGrSystem2.Data.EndUpdate;
1063end;
1064
1065procedure InitCityMark(T: TTexture);
1066var
1067 x: Integer;
1068 y: Integer;
1069 Intensity: Integer;
1070begin
1071 for x := 0 to CityMark1.Width - 1 do begin
1072 for y := 0 to CityMark1.Height - 1 do begin
1073 if HGrSystem.Mask.Canvas.Pixels[CityMark1.Left + x, CityMark1.Top + y] = 0 then
1074 begin
1075 Intensity := HGrSystem.Data.Canvas.Pixels[CityMark1.Left +
1076 x, CityMark1.Top + y] and $FF;
1077 HGrSystem.Data.Canvas.Pixels[CityMark2.Left + x, CityMark2.Top + y] :=
1078 T.ColorMark and $FF * Intensity div $FF + T.ColorMark shr 8 and
1079 $FF * Intensity div $FF shl 8 + T.ColorMark shr 16 and
1080 $FF * Intensity div $FF shl 16;
1081 end;
1082 end;
1083 end;
1084 BitBltCanvas(HGrSystem.Mask.Canvas, CityMark2.Left, CityMark2.Top, CityMark1.Width, CityMark1.Width,
1085 HGrSystem.Mask.Canvas, CityMark1.Left, CityMark1.Top);
1086end;
1087
1088procedure Fill(ca: TCanvas; Left, Top, Width, Height, xOffset, yOffset: Integer);
1089begin
1090 Assert((Left + xOffset >= 0) and (Left + xOffset + Width <= MainTexture.Width) and
1091 (Top + yOffset >= 0) and (Top + yOffset + Height <= MainTexture.Height));
1092 BitBltCanvas(ca, Left, Top, Width, Height, MainTexture.Image.Canvas,
1093 Left + xOffset, Top + yOffset);
1094end;
1095
1096procedure Fill(Canvas: TCanvas; Rect: TRect; Offset: TPoint);
1097begin
1098 Fill(Canvas, Rect.Left, Rect.Top, Rect.Width, Rect.Height, Offset.X, Offset.Y);
1099end;
1100
1101procedure FillLarge(ca: TCanvas; x0, y0, x1, y1, xm: Integer);
1102
1103 function Band(I: Integer): Integer;
1104 var
1105 n: integer;
1106 begin
1107 n := ((MainTexture.Height div 2) div (y1 - y0)) * 2;
1108 while MainTexture.Height div 2 + (I + 1) * (y1 - y0) > MainTexture.Height do
1109 Dec(I, n);
1110 while MainTexture.Height div 2 + I * (y1 - y0) < 0 do
1111 Inc(I, n);
1112 Result := I;
1113 end;
1114
1115var
1116 I: Integer;
1117begin
1118 for I := 0 to (x1 - xm) div MainTexture.Width - 1 do
1119 BitBltCanvas(ca, xm + I * MainTexture.Width, y0, MainTexture.Width, y1 - y0,
1120 MainTexture.Image.Canvas, 0, MainTexture.Height div 2 + Band(I) *
1121 (y1 - y0));
1122 BitBltCanvas(ca, xm + ((x1 - xm) div MainTexture.Width) * MainTexture.Width, y0,
1123 x1 - (xm + ((x1 - xm) div MainTexture.Width) * MainTexture.Width), y1 - y0,
1124 MainTexture.Image.Canvas, 0, MainTexture.Height div 2 + Band(
1125 (x1 - xm) div MainTexture.Width) * (y1 - y0));
1126 for I := 0 to (xm - x0) div MainTexture.Width - 1 do
1127 BitBltCanvas(ca, xm - (I + 1) * MainTexture.Width, y0, MainTexture.Width, y1 - y0,
1128 MainTexture.Image.Canvas, 0, MainTexture.Height div 2 +
1129 Band(-I - 1) * (y1 - y0));
1130 BitBltCanvas(ca, x0, y0, xm - ((xm - x0) div MainTexture.Width) *
1131 MainTexture.Width - x0, y1 - y0, MainTexture.Image.Canvas,
1132 ((xm - x0) div MainTexture.Width + 1) * MainTexture.Width - (xm - x0),
1133 MainTexture.Height div 2 + Band(-(xm - x0) div MainTexture.Width - 1) * (y1 - y0));
1134end;
1135
1136procedure FillSeamless(ca: TCanvas; Left, Top, Width, Height, xOffset, yOffset: Integer;
1137 const Texture: TBitmap);
1138var
1139 x, y, x0cut, y0cut, x1cut, y1cut: Integer;
1140begin
1141 while xOffset < 0 do
1142 Inc(xOffset, Texture.Width);
1143 while yOffset < 0 do
1144 Inc(yOffset, Texture.Height);
1145 for y := (Top + yOffset) div Texture.Height to (Top + yOffset + Height - 1) div
1146 Texture.Height do
1147 begin
1148 y0cut := Top + yOffset - y * Texture.Height;
1149 if y0cut < 0 then
1150 y0cut := 0;
1151 y1cut := (y + 1) * Texture.Height - (Top + yOffset + Height);
1152 if y1cut < 0 then
1153 y1cut := 0;
1154 for x := (Left + xOffset) div Texture.Width to (Left + xOffset + Width - 1) div
1155 Texture.Width do
1156 begin
1157 x0cut := Left + xOffset - x * Texture.Width;
1158 if x0cut < 0 then
1159 x0cut := 0;
1160 x1cut := (x + 1) * Texture.Width - (Left + xOffset + Width);
1161 if x1cut < 0 then
1162 x1cut := 0;
1163 BitBltCanvas(ca, x * Texture.Width + x0cut - xOffset,
1164 y * Texture.Height + y0cut - yOffset, Texture.Width - x0cut - x1cut,
1165 Texture.Height - y0cut - y1cut, Texture.Canvas, x0cut, y0cut);
1166 end;
1167 end;
1168end;
1169
1170procedure FillRectSeamless(ca: TCanvas; x0, y0, x1, y1, xOffset, yOffset: Integer;
1171 const Texture: TBitmap);
1172begin
1173 FillSeamless(ca, x0, y0, x1 - x0, y1 - y0, xOffset, yOffset, Texture);
1174end;
1175
1176procedure PaintBackground(Form: TForm; Left, Top, Width, Height: Integer);
1177begin
1178 Fill(Form.Canvas, Left, Top, Width, Height, (MainTexture.Width - Form.ClientWidth) div
1179 2, (MainTexture.Height - Form.ClientHeight) div 2);
1180end;
1181
1182procedure Corner(ca: TCanvas; x, y, Kind: Integer; T: TTexture);
1183begin
1184 { BitBltCanvas(ca,x,y,8,8,T.HGr.Mask.Canvas,
1185 T.xGr+29+Kind*9,T.yGr+89,SRCAND);
1186 BitBltCanvas(ca,x,y,8,8,T.HGr.Data.Canvas,
1187 T.xGr+29+Kind*9,T.yGr+89,SRCPAINT); }
1188end;
1189
1190procedure BiColorTextOut(ca: TCanvas; clMain, clBack: TColor; x, y: Integer; s: string);
1191
1192 procedure PaintIcon(x, y, Kind: Integer);
1193 begin
1194 BitBltCanvas(ca, x, y + 6, 10, 10, HGrSystem.Mask.Canvas,
1195 66 + Kind mod 11 * 11, 115 + Kind div 11 * 11, SRCAND);
1196 BitBltCanvas(ca, x, y + 6, 10, 10, HGrSystem.Data.Canvas,
1197 66 + Kind mod 11 * 11, 115 + Kind div 11 * 11, SRCPAINT);
1198 end;
1199
1200var
1201 p, xp: Integer;
1202 sp: string;
1203 shadow: Boolean;
1204 Text: string;
1205begin
1206 Inc(x);
1207 Inc(y);
1208 for shadow := True downto False do
1209 with ca do
1210 if not shadow or (clBack <> $7F007F) then
1211 begin
1212 if shadow then
1213 Font.Color := clBack
1214 else
1215 Font.Color := clMain;
1216 sp := s;
1217 xp := x;
1218 repeat
1219 p := pos('%', sp);
1220 if (p = 0) or (p + 1 > Length(sp)) or not
1221 (sp[p + 1] in ['c', 'f', 'l', 'm', 'n', 'o', 'p', 'r', 't', 'w']) then
1222 begin
1223 ca.Textout(xp, y, sp);
1224 Break;
1225 end
1226 else
1227 begin
1228 Text := Copy(sp, 1, p - 1);
1229 Textout(xp, y, Text);
1230 Inc(xp, ca.TextWidth(Text));
1231 if not shadow then
1232 case sp[p + 1] of
1233 'c': PaintIcon(xp + 1, y, 6);
1234 'f': PaintIcon(xp + 1, y, 0);
1235 'l': PaintIcon(xp + 1, y, 8);
1236 'm': PaintIcon(xp + 1, y, 17);
1237 'n': PaintIcon(xp + 1, y, 7);
1238 'o': PaintIcon(xp + 1, y, 16);
1239 'p': PaintIcon(xp + 1, y, 2);
1240 'r': PaintIcon(xp + 1, y, 12);
1241 't': PaintIcon(xp + 1, y, 4);
1242 'w': PaintIcon(xp + 1, y, 13);
1243 end;
1244 Inc(xp, 10);
1245 Delete(sp, 1, p + 1);
1246 end;
1247 until False;
1248 Dec(x);
1249 Dec(y);
1250 end;
1251end;
1252
1253function BiColorTextWidth(ca: TCanvas; s: string): Integer;
1254var
1255 P: Integer;
1256begin
1257 Result := 1;
1258 repeat
1259 P := Pos('%', s);
1260 if (P = 0) or (P = Length(s)) then
1261 begin
1262 Inc(Result, ca.TextWidth(s));
1263 Break;
1264 end
1265 else
1266 begin
1267 if not (s[P + 1] in ['c', 'f', 'l', 'm', 'n', 'o', 'p', 'r', 't', 'w'])
1268 then
1269 Inc(Result, ca.TextWidth(copy(s, 1, P + 1)))
1270 else
1271 Inc(Result, ca.TextWidth(copy(s, 1, P - 1)) + 10);
1272 Delete(s, 1, P + 1);
1273 end;
1274 until False;
1275end;
1276
1277procedure LoweredTextOut(ca: TCanvas; cl: TColor; T: TTexture;
1278 x, y: Integer; s: string);
1279begin
1280 if cl = -2 then
1281 BiColorTextOut(ca, (T.ColorBevelShade and $FEFEFE) shr 1,
1282 T.ColorBevelLight, x, y, s)
1283 else if cl < 0 then
1284 BiColorTextOut(ca, T.ColorTextShade, T.ColorTextLight, x, y, s)
1285 else
1286 BiColorTextOut(ca, cl, T.ColorTextLight, x, y, s);
1287end;
1288
1289procedure RisedTextOut(ca: TCanvas; x, y: integer; s: string);
1290begin
1291 BiColorTextOut(ca, $FFFFFF, $000000, x, y, s);
1292end;
1293
1294procedure Gradient(ca: TCanvas; x, y, dx, dy, Width, Height, Color: Integer;
1295 Brightness: array of integer);
1296var
1297 i, r, g, b: Integer;
1298begin
1299 for i := 0 to Length(Brightness) - 1 do begin // gradient
1300 r := Color and $FF + Brightness[i];
1301 if r < 0 then
1302 r := 0
1303 else if r >= 256 then
1304 r := 255;
1305 g := Color shr 8 and $FF + Brightness[i];
1306 if g < 0 then
1307 g := 0
1308 else if g >= 256 then
1309 g := 255;
1310 b := Color shr 16 and $FF + Brightness[i];
1311 if b < 0 then
1312 b := 0
1313 else if b >= 256 then
1314 b := 255;
1315 ca.Pen.Color := r + g shl 8 + b shl 16;
1316 ca.MoveTo(x + dx * i, y + dy * i);
1317 ca.LineTo(x + dx * i + Width, y + dy * i + Height);
1318 end;
1319 ca.Pen.Color := $000000;
1320 ca.MoveTo(x + 1, y + 16 * dy + Height);
1321 ca.LineTo(x + 16 * dx + Width, y + 16 * dy + Height);
1322 ca.LineTo(x + 16 * dx + Width, y);
1323end;
1324
1325procedure LightGradient(ca: TCanvas; x, y, Width, Color: Integer);
1326const
1327 Brightness: array [0 .. 15] of integer =
1328 (16, 12, 8, 4, 0, -4, -8, -12, -16, -20, -24, -28, -32, -36, -40, -44);
1329begin
1330 Gradient(ca, x, y, 0, 1, Width, 0, Color, Brightness);
1331end;
1332
1333procedure DarkGradient(ca: TCanvas; x, y, Width, Kind: Integer);
1334const
1335 Brightness: array [0 .. 15] of integer =
1336 (16, 12, 8, 4, 0, -4, -8, -12 - 24, -16 + 16, -20, -24, -28, -32, -36, -40, -44);
1337begin
1338 Gradient(ca, x, y, 0, 1, Width, 0, HGrSystem.Data.Canvas.Pixels
1339 [187, 137 + Kind], Brightness);
1340end;
1341
1342procedure VLightGradient(ca: TCanvas; x, y, Height, Color: Integer);
1343const
1344 Brightness: array [0 .. 15] of integer =
1345 (16, 12, 8, 4, 0, -4, -8, -12, -16, -20, -24, -28, -32, -36, -40, -44);
1346begin
1347 Gradient(ca, x, y, 1, 0, 0, Height, Color, Brightness);
1348end;
1349
1350procedure VDarkGradient(ca: TCanvas; x, y, Height, Kind: Integer);
1351const
1352 Brightness: array [0 .. 15] of integer =
1353 (16, 12, 8, 4, 0, -4, -8, -12 - 24, -16 + 16, -20, -24, -28, -32, -36, -40, -44);
1354begin
1355 Gradient(ca, x, y, 1, 0, 0, Height,
1356 HGrSystem.Data.Canvas.Pixels[187, 137 + Kind], Brightness);
1357end;
1358
1359procedure UnderlinedTitleValue(Canvas: TCanvas; Title, Value: string; X, Y, Width: Integer);
1360begin
1361 DLine(Canvas, X, X + Width, Y + 19, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
1362 RisedTextOut(Canvas, X, Y, Title);
1363 RisedTextOut(Canvas, X + Width - BiColorTextWidth(Canvas, Value), Y, Value);
1364end;
1365
1366procedure NumberBar(dst: TBitmap; x, y: integer; Cap: string;
1367 val: Integer; T: TTexture);
1368var
1369 s: string;
1370begin
1371 if val > 0 then
1372 begin
1373 DLine(dst.Canvas, x - 2, x + 170, y + 16, T.ColorBevelShade,
1374 T.ColorBevelLight);
1375 LoweredTextOut(dst.Canvas, -1, T, x - 2, y, Cap);
1376 s := IntToStr(val);
1377 RisedTextOut(dst.Canvas, x + 170 - BiColorTextWidth(dst.Canvas,
1378 s), y, s);
1379 end;
1380end;
1381
1382procedure CountBar(dst: TBitmap; x, y, w: Integer; Kind: Integer;
1383 Cap: string; val: Integer; T: TTexture);
1384var
1385 i, sd, ld, cl, xIcon, yIcon: Integer;
1386 s: string;
1387begin
1388 // val:=random(40); //!!!
1389 if val = 0 then
1390 Exit;
1391 Assert(Kind >= 0);
1392 with dst.Canvas do
1393 begin
1394 // xIcon:=x+100;
1395 // yIcon:=y;
1396 // DLine(dst.Canvas,x-2,x+170+32,y+16,T.ColorBevelShade,T.ColorBevelLight);
1397
1398 xIcon := x - 5;
1399 yIcon := y + 15;
1400 DLine(dst.Canvas, x - 2, xIcon + w + 2, yIcon + 16, T.ColorBevelShade,
1401 T.ColorBevelLight);
1402
1403 s := IntToStr(val);
1404 if val < 0 then
1405 cl := $0000FF
1406 else
1407 cl := -1;
1408 LoweredTextOut(dst.Canvas, cl, T, x - 2, y, Cap);
1409 LoweredTextOut(dst.Canvas, cl, T,
1410 xIcon + w + 2 - BiColorTextWidth(dst.Canvas, s), yIcon, s);
1411
1412 if (Kind = 12) and (val >= 100) then
1413 begin // science with symbol for 100
1414 val := val div 10;
1415 sd := 14 * (val div 10 + val mod 10 - 1);
1416 if sd = 0 then
1417 sd := 1;
1418 if sd < w - 44 then
1419 ld := sd
1420 else
1421 ld := w - 44;
1422 for i := 0 to val mod 10 - 1 do
1423 begin
1424 BitBltCanvas(dst.Canvas, xIcon + 4 + i * (14 * ld div sd), yIcon + 2 + 1, 14,
1425 14, HGrSystem.Mask.Canvas, 67 + Kind mod 8 * 15,
1426 70 + Kind div 8 * 15, SRCAND);
1427 Sprite(dst, HGrSystem, xIcon + 3 + i * (14 * ld div sd), yIcon + 2,
1428 14, 14, 67 + Kind mod 8 * 15, 70 + Kind div 8 * 15);
1429 end;
1430 for i := 0 to val div 10 - 1 do
1431 begin
1432 BitBltCanvas(dst.Canvas, xIcon + 4 + (val mod 10) *
1433 (14 * ld div sd) + i * (14 * ld div sd), yIcon + 3, 14, 14,
1434 HGrSystem.Mask.Canvas, 67 + 7 mod 8 * 15,
1435 70 + 7 div 8 * 15, SRCAND);
1436 Sprite(dst, HGrSystem, xIcon + 3 + (val mod 10) *
1437 (14 * ld div sd) + i * (14 * ld div sd), yIcon + 2, 14,
1438 14, 67 + 7 mod 8 * 15,
1439 70 + 7 div 8 * 15);
1440 end;
1441 end
1442 else
1443 begin
1444 val := abs(val);
1445 if val mod 10 = 0 then
1446 sd := 14 * (val div 10 - 1)
1447 else
1448 sd := 10 * (val mod 10 - 1) + 14 * (val div 10);
1449 if sd = 0 then
1450 sd := 1;
1451 if sd < w - 44 then
1452 ld := sd
1453 else
1454 ld := w - 44;
1455 for i := 0 to val div 10 - 1 do
1456 begin
1457 BitBltCanvas(dst.Canvas, xIcon + 4 + i * (14 * ld div sd), yIcon + 3, 14, 14,
1458 HGrSystem.Mask.Canvas, 67 + Kind mod 8 * 15,
1459 70 + Kind div 8 * 15, SRCAND);
1460 Sprite(dst, HGrSystem, xIcon + 3 + i * (14 * ld div sd), yIcon + 2,
1461 14, 14, 67 + Kind mod 8 * 15, 70 + Kind div 8 * 15);
1462 end;
1463 for i := 0 to val mod 10 - 1 do
1464 begin
1465 BitBltCanvas(dst.Canvas, xIcon + 4 + (val div 10) *
1466 (14 * ld div sd) + i * (10 * ld div sd), yIcon + 7, 10, 10,
1467 HGrSystem.Mask.Canvas, 66 + Kind mod 11 * 11,
1468 115 + Kind div 11 * 11, SRCAND);
1469 Sprite(dst, HGrSystem, xIcon + 3 + (val div 10) *
1470 (14 * ld div sd) + i * (10 * ld div sd), yIcon + 6, 10,
1471 10, 66 + Kind mod 11 * 11,
1472 115 + Kind div 11 * 11);
1473 end;
1474 end;
1475 end;
1476end;
1477
1478procedure PaintProgressBar(ca: TCanvas; Kind, x, y, pos, Growth, max: Integer;
1479 T: TTexture);
1480var
1481 i: Integer;
1482begin
1483 if pos > max then
1484 pos := max;
1485 if Growth < 0 then
1486 begin
1487 pos := pos + Growth;
1488 if pos < 0 then
1489 begin
1490 Growth := Growth - pos;
1491 pos := 0;
1492 end;
1493 end
1494 else if pos + Growth > max then
1495 Growth := max - pos;
1496 Frame(ca, x - 1, y - 1, x + max, y + 7, $000000, $000000);
1497 RFrame(ca, x - 2, y - 2, x + max + 1, y + 8, T.ColorBevelShade,
1498 T.ColorBevelLight);
1499 with ca do
1500 begin
1501 for i := 0 to pos div 8 - 1 do
1502 BitBltCanvas(ca, x + i * 8, y, 8, 7,
1503 HGrSystem.Data.Canvas, 104, 9 + 8 * Kind);
1504 BitBltCanvas(ca, x + 8 * (pos div 8), y, pos - 8 * (pos div 8), 7,
1505 HGrSystem.Data.Canvas, 104, 9 + 8 * Kind);
1506 if Growth > 0 then
1507 begin
1508 for i := 0 to Growth div 8 - 1 do
1509 BitBltCanvas(ca, x + pos + i * 8, y, 8, 7,
1510 HGrSystem.Data.Canvas, 112, 9 + 8 * Kind);
1511 BitBltCanvas(ca, x + pos + 8 * (Growth div 8), y,
1512 Growth - 8 * (Growth div 8), 7, HGrSystem.Data.Canvas,
1513 112, 9 + 8 * Kind);
1514 end
1515 else if Growth < 0 then
1516 begin
1517 for i := 0 to -Growth div 8 - 1 do
1518 BitBltCanvas(ca, x + pos + i * 8, y, 8, 7,
1519 HGrSystem.Data.Canvas, 104, 1);
1520 BitBltCanvas(ca, x + pos + 8 * (-Growth div 8), y, -Growth -
1521 8 * (-Growth div 8), 7,
1522 HGrSystem.Data.Canvas, 104, 1);
1523 end;
1524 Brush.Color := $000000;
1525 FillRect(Rect(x + pos + abs(Growth), y, x + max, y + 7));
1526 Brush.Style := bsClear;
1527 end;
1528end;
1529
1530// pos and growth are relative to max, set size independent
1531procedure PaintRelativeProgressBar(ca: TCanvas;
1532 Kind, x, y, size, pos, Growth, max: Integer; IndicateComplete: Boolean;
1533 T: TTexture);
1534begin
1535 if Growth > 0 then
1536 PaintProgressBar(ca, Kind, x, y, pos * size div max,
1537 (Growth * size + max div 2) div max, size, T)
1538 else
1539 PaintProgressBar(ca, Kind, x, y, pos * size div max,
1540 (Growth * size - max div 2) div max, size, T);
1541 if IndicateComplete and (pos + Growth >= max) then
1542 Sprite(ca, HGrSystem, x + size - 10, y - 7, 23, 16, 1, 129);
1543end;
1544
1545procedure PaintLogo(Canvas: TCanvas; X, Y, LightColor, ShadeColor: Integer);
1546begin
1547 UnshareBitmap(LogoBuffer);
1548 BitBltCanvas(LogoBuffer.Canvas, 0, 0, Logo.Width, Logo.Height, Canvas, X, Y);
1549 ImageOp_BCC(LogoBuffer, Templates.Data, Point(0, 0), Logo.BoundsRect,
1550 LightColor, ShadeColor);
1551 BitBltCanvas(Canvas, X, Y, Logo.Width, Logo.Height, LogoBuffer.Canvas, 0, 0);
1552end;
1553
1554procedure LoadPhrases;
1555begin
1556 if Phrases = nil then Phrases := TStringTable.Create;
1557 if Phrases2 = nil then Phrases2 := TStringTable.Create;
1558 Phrases2FallenBackToEnglish := False;
1559 if FileExists(LocalizedFilePath('Language.txt')) then
1560 begin
1561 Phrases.LoadFromFile(LocalizedFilePath('Language.txt'));
1562 if FileExists(LocalizedFilePath('Language2.txt')) then
1563 Phrases2.LoadFromFile(LocalizedFilePath('Language2.txt'))
1564 else
1565 begin
1566 Phrases2.LoadFromFile(HomeDir + 'Language2.txt');
1567 Phrases2FallenBackToEnglish := True;
1568 end;
1569 end
1570 else
1571 begin
1572 Phrases.LoadFromFile(HomeDir + 'Language.txt');
1573 Phrases2.LoadFromFile(HomeDir + 'Language2.txt');
1574 end;
1575
1576 if Sounds = nil then Sounds := TStringTable.Create;
1577 if not Sounds.LoadFromFile(GetSoundsDir + DirectorySeparator + 'sound.txt') then
1578 begin
1579 FreeAndNil(Sounds);
1580 end;
1581end;
1582
1583procedure Texturize(Dest, Texture: TBitmap; TransparentColor: Cardinal);
1584var
1585 SrcPixel, DstPixel: TPixelPointer;
1586 X, Y: Integer;
1587 TexWidth, TexHeight: Integer;
1588begin
1589 // texturize background
1590 Dest.BeginUpdate;
1591 TexWidth := Texture.Width;
1592 TexHeight := Texture.Height;
1593 DstPixel := PixelPointer(Dest);
1594 SrcPixel := PixelPointer(Texture);
1595 for Y := 0 to ScaleToNative(Dest.Height) - 1 do begin
1596 for X := 0 to ScaleToNative(Dest.Width) - 1 do begin
1597 if (DstPixel.Pixel^.ARGB and $FFFFFF) = TransparentColor then begin
1598 SrcPixel.SetXY(X mod TexWidth, Y mod TexHeight);
1599 DstPixel.Pixel^.B := SrcPixel.Pixel^.B;
1600 DstPixel.Pixel^.G := SrcPixel.Pixel^.G;
1601 DstPixel.Pixel^.R := SrcPixel.Pixel^.R;
1602 end;
1603 DstPixel.NextPixel;
1604 end;
1605 DstPixel.NextLine;
1606 end;
1607 Dest.EndUpdate;
1608end;
1609
1610procedure DarkenImage(Bitmap: TBitmap; Change: Integer);
1611var
1612 x, y: integer;
1613 PicturePixel: TPixelPointer;
1614begin
1615 Bitmap.BeginUpdate;
1616 PicturePixel := PixelPointer(Bitmap);
1617 for y := 0 to ScaleToNative(Bitmap.Height) - 1 do begin
1618 for x := 0 to ScaleToNative(Bitmap.Width) - 1 do begin
1619 PicturePixel.Pixel^.B := Max(PicturePixel.Pixel^.B - Change, 0);
1620 PicturePixel.Pixel^.G := Max(PicturePixel.Pixel^.G - Change, 0);
1621 PicturePixel.Pixel^.R := Max(PicturePixel.Pixel^.R - Change, 0);
1622 PicturePixel.NextPixel;
1623 end;
1624 PicturePixel.NextLine;
1625 end;
1626 Bitmap.EndUpdate;
1627end;
1628
1629function ScaleToNative(Value: Integer): Integer;
1630begin
1631 Result := Value;
1632end;
1633
1634function ScaleFromNative(Value: Integer): Integer;
1635begin
1636 Result := Value;
1637end;
1638
1639procedure UnshareBitmap(Bitmap: TBitmap);
1640begin
1641 // FillRect cause image data to be freed so subsequent BitBlt can access valid image data
1642 Bitmap.Canvas.FillRect(0, 0, 0, 0);
1643end;
1644
1645procedure Gtk2Fix;
1646{$IFDEF UNIX}
1647var
1648 I: Integer;
1649{$ENDIF}
1650begin
1651 {$IFDEF UNIX}
1652 // Wait and process messages little bit to avoid crash or force repaint under Gtk2
1653 for I := 0 to 10 do begin
1654 Sleep(1);
1655 Application.ProcessMessages;
1656 end;
1657 {$ENDIF}
1658end;
1659
1660procedure LoadFonts;
1661var
1662 Section: TFontType;
1663 FontScript: TextFile;
1664 Size: integer;
1665 S: string;
1666 I: integer;
1667 P: integer;
1668begin
1669 Section := ftNormal;
1670 AssignFile(FontScript, LocalizedFilePath('Fonts.txt'));
1671 try
1672 Reset(FontScript);
1673 while not Eof(FontScript) do begin
1674 ReadLn(FontScript, s);
1675 if s <> '' then
1676 if s[1] = '#' then begin
1677 s := TrimRight(s);
1678 if s = '#SMALL' then Section := ftSmall
1679 else if s = '#TINY' then Section := ftTiny
1680 else if s = '#CAPTION' then Section := ftCaption
1681 else if s = '#BUTTON' then Section := ftButton
1682 else Section := ftNormal;
1683 end else begin
1684 p := Pos(',', s);
1685 if p > 0 then begin
1686 UniFont[section].Name := Trim(Copy(s, 1, p - 1));
1687 Size := 0;
1688 for i := p + 1 to Length(s) do
1689 case s[i] of
1690 '0' .. '9':
1691 Size := Size * 10 + Byte(s[i]) - 48;
1692 'B', 'b':
1693 UniFont[section].Style := UniFont[section].Style + [fsBold];
1694 'I', 'i':
1695 UniFont[section].Style := UniFont[section].Style + [fsItalic];
1696 end;
1697 UniFont[section].Size := Round(Size * 72 / UniFont[section].PixelsPerInch);
1698 end;
1699 end;
1700 end;
1701 CloseFile(FontScript);
1702 except
1703 end;
1704end;
1705
1706procedure ReleaseFonts;
1707var
1708 Section: TFontType;
1709begin
1710 for Section := Low(TFontType) to High(TFontType) do
1711 FreeAndNil(UniFont[section]);
1712end;
1713
1714procedure InitGammaLookupTable;
1715var
1716 I: Integer;
1717 P: Integer;
1718begin
1719 GammaLookupTable[0] := 0;
1720 for I := 1 to 255 do begin
1721 P := Round(255.0 * Exp(Ln(I / 255.0) * 100.0 / Gamma));
1722 Assert((P >= 0) and (P < 256));
1723 GammaLookupTable[I] := P;
1724 end;
1725end;
1726
1727procedure LoadAssets;
1728begin
1729 LoadPhrases;
1730 LoadFonts;
1731 Templates := LoadGraphicSet('Templates.png', False);
1732 with Templates do begin
1733 Logo := GetItem('Logo');
1734 BigBook := GetItem('BigBook');
1735 SmallBook := GetItem('SmallBook');
1736 MenuLogo := GetItem('MenuLogo');
1737 LinkArrows := GetItem('LinkArrows');
1738 ScienceNationDot := GetItem('ScienceNationDot');
1739 ResearchIcon := GetItem('Research');
1740 ChangeIcon := GetItem('Change');
1741 TreasuryIcon := GetItem('Treasury');
1742 StarshipDeparted := GetItem('StarshipDeparted');
1743 WeightOn := GetItem('WeightOn');
1744 WeightOff := GetItem('WeightOff');
1745 end;
1746
1747 LoadGraphicFile(Colors, GetGraphicsDir + DirectorySeparator + 'Colors.png');
1748 LoadGraphicFile(Paper, GetGraphicsDir + DirectorySeparator + 'Paper.jpg');
1749 LoadGraphicFile(BigImp, GetGraphicsDir + DirectorySeparator + 'Icons.png');
1750end;
1751
1752procedure UnitInit;
1753var
1754 Section: TFontType;
1755begin
1756 Gamma := 100;
1757 InitGammaLookupTable;
1758
1759 {$IFDEF WINDOWS}
1760 EnumDisplaySettings(nil, $FFFFFFFF, StartResolution);
1761 ResolutionChanged := False;
1762 {$ENDIF}
1763
1764 for Section := Low(TFontType) to High(TFontType) do
1765 UniFont[Section] := TFont.Create;
1766
1767 GrExt := TGraphicSets.Create;
1768
1769 HGrSystem := LoadGraphicSet('System.png');
1770 with HGrSystem do begin
1771 CityMark1 := GetItem('CityMark1');
1772 CityMark2 := GetItem('CityMark2');
1773 end;
1774
1775 HGrSystem2 := LoadGraphicSet('System2.png');
1776 with HGrSystem2 do begin
1777 Ornament := GetItem('Ornament');
1778 GBrainNoTerm := GetItem('BrainNoTerm');
1779 GBrainSuperVirtual := GetItem('BrainSuperVirtual');
1780 GBrainTerm := GetItem('BrainTerm');
1781 GBrainRandom := GetItem('BrainRandom');
1782 end;
1783
1784 Colors := TBitmap.Create;
1785 Colors.PixelFormat := pf24bit;
1786 Paper := TBitmap.Create;
1787 Paper.PixelFormat := pf24bit;
1788 BigImp := TBitmap.Create;
1789 BigImp.PixelFormat := pf24bit;
1790 MainTexture := TTexture.Create;
1791 ClickFrameColor := HGrSystem.Data.Canvas.Pixels[187, 175];
1792 InitOrnamentDone := False;
1793 GenerateNames := True;
1794
1795 LoadAssets;
1796
1797 LogoBuffer := TBitmap.Create;
1798 LogoBuffer.PixelFormat := pf24bit;
1799 LogoBuffer.SetSize(BigBook.Width, BigBook.Height);
1800end;
1801
1802procedure UnitDone;
1803begin
1804 RestoreResolution;
1805 FreeAndNil(GrExt);
1806 ReleaseFonts;
1807 FreeAndNil(Phrases);
1808 FreeAndNil(Phrases2);
1809 FreeAndNil(LogoBuffer);
1810 FreeAndNil(BigImp);
1811 FreeAndNil(Paper);
1812 FreeAndNil(Colors);
1813 FreeAndNil(MainTexture);
1814end;
1815
1816end.
Note: See TracBrowser for help on using the repository browser.