Changeset 494 for GraphicTest/Packages/bgrabitmap/bgragradientscanner.pas
- Timestamp:
- Dec 22, 2016, 8:49:19 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/Packages/bgrabitmap/bgragradientscanner.pas
r472 r494 16 16 private 17 17 FColor1,FColor2: TBGRAPixel; 18 ec1,ec2: TExpandedPixel; 18 19 public 19 20 constructor Create(Color1,Color2: TBGRAPixel); 20 21 function GetColorAt(position: integer): TBGRAPixel; override; 21 22 function GetColorAtF(position: single): TBGRAPixel; override; 23 function GetExpandedColorAt(position: integer): TExpandedPixel; override; 24 function GetExpandedColorAtF(position: single): TExpandedPixel; override; 22 25 function GetAverageColor: TBGRAPixel; override; 23 26 function GetMonochrome: boolean; override; … … 35 38 function GetColorAtF(position: single): TBGRAPixel; override; 36 39 function GetAverageColor: TBGRAPixel; override; 40 function GetExpandedColorAt(position: integer): TExpandedPixel; override; 41 function GetExpandedColorAtF(position: single): TExpandedPixel; override; 42 function GetAverageExpandedColor: TExpandedPixel; override; 37 43 function GetMonochrome: boolean; override; 38 44 end; … … 46 52 private 47 53 FColor1,FColor2: TBGRAPixel; 54 ec1,ec2: TExpandedPixel; 48 55 hsla1,hsla2: THSLAPixel; 49 56 hue1,hue2: longword; 50 57 FOptions: THueGradientOptions; 51 58 procedure Init(c1,c2: THSLAPixel; AOptions: THueGradientOptions); 59 function GetColorNoBoundCheck(position: integer): THSLAPixel; 52 60 public 53 61 constructor Create(Color1,Color2: TBGRAPixel; options: THueGradientOptions); overload; … … 57 65 function GetColorAtF(position: single): TBGRAPixel; override; 58 66 function GetAverageColor: TBGRAPixel; override; 67 function GetExpandedColorAt(position: integer): TExpandedPixel; override; 68 function GetExpandedColorAtF(position: single): TExpandedPixel; override; 69 function GetAverageExpandedColor: TExpandedPixel; override; 59 70 function GetMonochrome: boolean; override; 60 71 end; 72 73 TGradientInterpolationFunction = function(t: single): single of object; 61 74 62 75 { TBGRAMultiGradient } … … 69 82 FEColors: array of TExpandedPixel; 70 83 FCycle: Boolean; 84 FInterpolationFunction: TGradientInterpolationFunction; 71 85 procedure Init(Colors: array of TBGRAPixel; Positions0To1: array of single; AGammaCorrection, ACycle: boolean); 72 86 public 73 87 GammaCorrection: boolean; 88 function CosineInterpolation(t: single): single; 89 function HalfCosineInterpolation(t: single): single; 74 90 constructor Create(Colors: array of TBGRAPixel; Positions0To1: array of single; AGammaCorrection: boolean; ACycle: boolean = false); 75 91 function GetColorAt(position: integer): TBGRAPixel; override; 92 function GetExpandedColorAt(position: integer): TExpandedPixel; override; 76 93 function GetAverageColor: TBGRAPixel; override; 77 94 function GetMonochrome: boolean; override; 95 property InterpolationFunction: TGradientInterpolationFunction read FInterpolationFunction write FInterpolationFunction; 78 96 end; 79 97 … … 88 106 len,aFactor,aFactorF: single; 89 107 mergedColor: TBGRAPixel; 108 mergedExpandedColor: TExpandedPixel; 90 109 FGradient: TBGRACustomGradient; 91 110 FGradientOwner: boolean; 92 111 FHorizColor: TBGRAPixel; 112 FHorizExpandedColor: TExpandedPixel; 93 113 FVertical: boolean; 94 114 FDotProduct,FDotProductPerp: Single; … … 96 116 procedure InitScanInline(x,y: integer); 97 117 function ScanNextInline: TBGRAPixel; inline; 118 function ScanNextExpandedInline: TExpandedPixel; inline; 98 119 public 99 120 constructor Create(c1, c2: TBGRAPixel; gtype: TGradientType; o1, o2: TPointF; … … 103 124 procedure ScanMoveTo(X, Y: Integer); override; 104 125 function ScanNextPixel: TBGRAPixel; override; 126 function ScanNextExpandedPixel: TExpandedPixel; override; 105 127 function ScanAt(X, Y: Single): TBGRAPixel; override; 128 function ScanAtExpanded(X, Y: Single): TExpandedPixel; override; 106 129 procedure ScanPutPixels(pdest: PBGRAPixel; count: integer; mode: TDrawMode); override; 107 130 function IsScanPutPixelsDefined: boolean; override; … … 140 163 function ScanAt(X,Y: Single): TBGRAPixel; override; 141 164 function ScanNextPixel: TBGRAPixel; override; 165 function ScanNextExpandedPixel: TExpandedPixel; override; 142 166 end; 143 167 … … 151 175 FScanNext : TScanNextPixelFunction; 152 176 FScanAt : TScanAtFunction; 177 FMemMask: packed array of TBGRAPixel; 153 178 public 154 179 constructor Create(AMask: TBGRACustomBitmap; AOffset: TPoint; ASolidColor: TBGRAPixel); … … 172 197 FMaskScanAt,FTextureScanAt : TScanAtFunction; 173 198 FGlobalOpacity: Byte; 199 FMemMask, FMemTex: packed array of TBGRAPixel; 174 200 public 175 201 constructor Create(AMask: TBGRACustomBitmap; AOffset: TPoint; ATexture: IBGRAScanner; AGlobalOpacity: Byte = 255); … … 190 216 FScanNext : TScanNextPixelFunction; 191 217 FScanAt : TScanAtFunction; 218 FMemTex: packed array of TBGRAPixel; 192 219 public 193 220 constructor Create(ATexture: IBGRAScanner; AGlobalOpacity: Byte = 255); … … 202 229 implementation 203 230 204 uses BGRABlend ;231 uses BGRABlend, Math; 205 232 206 233 { TBGRAConstantScanner } … … 247 274 FColor1 := HSLAToBGRA(c1); 248 275 FColor2 := HSLAToBGRA(c2); 276 ec1 := GammaExpansion(FColor1); 277 ec2 := GammaExpansion(FColor2); 249 278 FOptions:= AOptions; 250 279 if (hgoLightnessCorrection in AOptions) then … … 276 305 end; 277 306 307 function TBGRAHueGradient.GetColorNoBoundCheck(position: integer): THSLAPixel; 308 var b,b2: LongWord; 309 begin 310 b := position shr 2; 311 b2 := 16384-b; 312 result.hue := ((hue1 * b2 + hue2 * b + 8191) shr 14) and $ffff; 313 result.saturation := (hsla1.saturation * b2 + hsla2.saturation * b + 8191) shr 14; 314 result.lightness := (hsla1.lightness * b2 + hsla2.lightness * b + 8191) shr 14; 315 result.alpha := (hsla1.alpha * b2 + hsla2.alpha * b + 8191) shr 14; 316 if hgoLightnessCorrection in FOptions then 317 begin 318 if not (hgoHueCorrection in FOptions) then 319 result.hue := HtoG(result.hue); 320 end else 321 begin 322 if hgoHueCorrection in FOptions then 323 result.hue := GtoH(result.hue); 324 end; 325 end; 326 278 327 constructor TBGRAHueGradient.Create(Color1, Color2: TBGRAPixel;options: THueGradientOptions); 279 328 begin … … 293 342 294 343 function TBGRAHueGradient.GetColorAt(position: integer): TBGRAPixel; 295 var b,b2: cardinal; 296 interm: THSLAPixel; 344 var interm: THSLAPixel; 297 345 begin 298 346 if hgoRepeat in FOptions then … … 317 365 end; 318 366 end; 319 b := position shr 2; 320 b2 := 16384-b; 321 interm.hue := ((hue1 * b2 + hue2 * b + 8191) shr 14) and $ffff; 322 interm.saturation := (hsla1.saturation * b2 + hsla2.saturation * b + 8191) shr 14; 323 interm.lightness := (hsla1.lightness * b2 + hsla2.lightness * b + 8191) shr 14; 324 interm.alpha := (hsla1.alpha * b2 + hsla2.alpha * b + 8191) shr 14; 367 interm := GetColorNoBoundCheck(position); 325 368 if hgoLightnessCorrection in FOptions then 326 begin 327 if not (hgoHueCorrection in FOptions) then 328 interm.hue := HtoG(interm.hue); 329 result := GSBAToBGRA(interm); 330 end else 331 begin 332 if hgoHueCorrection in FOptions then 333 interm.hue := GtoH(interm.hue); 369 result := GSBAToBGRA(interm) 370 else 334 371 result := HSLAToBGRA(interm); 335 end;336 372 end; 337 373 338 374 function TBGRAHueGradient.GetColorAtF(position: single): TBGRAPixel; 339 var b,b2: cardinal; 340 interm: THSLAPixel; 375 var interm: THSLAPixel; 341 376 begin 342 377 if hgoRepeat in FOptions then … … 361 396 end; 362 397 end; 363 b := round(position*16384); 364 b2 := 16384-b; 365 interm.hue := ((hue1 * b2 + hue2 * b + 8191) shr 14) and $ffff; 366 interm.saturation := (hsla1.saturation * b2 + hsla2.saturation * b + 8191) shr 14; 367 interm.lightness := (hsla1.lightness * b2 + hsla2.lightness * b + 8191) shr 14; 368 interm.alpha := (hsla1.alpha * b2 + hsla2.alpha * b + 8191) shr 14; 398 interm := GetColorNoBoundCheck(round(position*65536)); 369 399 if hgoLightnessCorrection in FOptions then 370 begin 371 if not (hgoHueCorrection in FOptions) then 372 interm.hue := HtoG(interm.hue); 373 result := GSBAToBGRA(interm); 374 end else 375 begin 376 if hgoHueCorrection in FOptions then 377 interm.hue := GtoH(interm.hue); 400 result := GSBAToBGRA(interm) 401 else 378 402 result := HSLAToBGRA(interm); 379 end;380 403 end; 381 404 … … 383 406 begin 384 407 Result:= GetColorAt(32768); 408 end; 409 410 function TBGRAHueGradient.GetExpandedColorAt(position: integer): TExpandedPixel; 411 var interm: THSLAPixel; 412 begin 413 if hgoRepeat in FOptions then 414 begin 415 position := position and $ffff; 416 if position = 0 then 417 begin 418 result := ec1; 419 exit; 420 end; 421 end else 422 begin 423 if position <= 0 then 424 begin 425 result := ec1; 426 exit 427 end else 428 if position >= 65536 then 429 begin 430 result := ec2; 431 exit 432 end; 433 end; 434 interm := GetColorNoBoundCheck(position); 435 if hgoLightnessCorrection in FOptions then 436 result := GSBAToExpanded(interm) 437 else 438 result := HSLAToExpanded(interm); 439 end; 440 441 function TBGRAHueGradient.GetExpandedColorAtF(position: single): TExpandedPixel; 442 var interm: THSLAPixel; 443 begin 444 if hgoRepeat in FOptions then 445 begin 446 position := frac(position); 447 if position = 0 then 448 begin 449 result := ec1; 450 exit; 451 end; 452 end else 453 begin 454 if position <= 0 then 455 begin 456 result := ec1; 457 exit; 458 end else 459 if position >= 1 then 460 begin 461 result := ec2; 462 exit 463 end; 464 end; 465 interm := GetColorNoBoundCheck(round(position*65536)); 466 if hgoLightnessCorrection in FOptions then 467 result := GSBAToExpanded(interm) 468 else 469 result := HSLAToExpanded(interm); 470 end; 471 472 function TBGRAHueGradient.GetAverageExpandedColor: TExpandedPixel; 473 begin 474 Result:= GetExpandedColorAt(32768); 385 475 end; 386 476 … … 417 507 end; 418 508 509 function TBGRAMultiGradient.CosineInterpolation(t: single): single; 510 begin 511 result := (1-cos(t*Pi))*0.5; 512 end; 513 514 function TBGRAMultiGradient.HalfCosineInterpolation(t: single): single; 515 begin 516 result := (1-cos(t*Pi))*0.25 + t*0.5; 517 end; 518 419 519 constructor TBGRAMultiGradient.Create(Colors: array of TBGRAPixel; 420 520 Positions0To1: array of single; AGammaCorrection: boolean; ACycle: boolean); … … 424 524 425 525 function TBGRAMultiGradient.GetColorAt(position: integer): TBGRAPixel; 426 var i: integer;526 var i: NativeInt; 427 527 ec: TExpandedPixel; 528 curPos,posDiff: NativeInt; 428 529 begin 429 530 if FCycle then … … 435 536 begin 436 537 i := 0; 437 while (i < high(FPositions) ) and (position >FPositions[i+1]) do538 while (i < high(FPositions)-1) and (position >= FPositions[i+1]) do 438 539 inc(i); 439 540 440 if Position = FPositions[i +1] then441 result := FColors[i +1]541 if Position = FPositions[i] then 542 result := FColors[i] 442 543 else 443 if GammaCorrection then 444 begin 445 ec.red := FEColors[i].red + (position-FPositions[i])*(FEColors[i+1].red-FEColors[i].red) div (FPositions[i+1]-FPositions[i]); 446 ec.green := FEColors[i].green + (position-FPositions[i])*(FEColors[i+1].green-FEColors[i].green) div (FPositions[i+1]-FPositions[i]); 447 ec.blue := FEColors[i].blue + (position-FPositions[i])*(FEColors[i+1].blue-FEColors[i].blue) div (FPositions[i+1]-FPositions[i]); 448 ec.alpha := FEColors[i].alpha + (position-FPositions[i])*(FEColors[i+1].alpha-FEColors[i].alpha) div (FPositions[i+1]-FPositions[i]); 449 result := GammaCompression(ec); 450 end else 451 begin 452 result.red := FColors[i].red + (position-FPositions[i])*(FColors[i+1].red-FColors[i].red) div (FPositions[i+1]-FPositions[i]); 453 result.green := FColors[i].green + (position-FPositions[i])*(FColors[i+1].green-FColors[i].green) div (FPositions[i+1]-FPositions[i]); 454 result.blue := FColors[i].blue + (position-FPositions[i])*(FColors[i+1].blue-FColors[i].blue) div (FPositions[i+1]-FPositions[i]); 455 result.alpha := FColors[i].alpha + (position-FPositions[i])*(FColors[i+1].alpha-FColors[i].alpha) div (FPositions[i+1]-FPositions[i]); 544 begin 545 curPos := position-FPositions[i]; 546 posDiff := FPositions[i+1]-FPositions[i]; 547 if FInterpolationFunction <> nil then 548 begin 549 curPos := round(FInterpolationFunction(curPos/posDiff)*65536); 550 posDiff := 65536; 551 end; 552 if GammaCorrection then 553 begin 554 if FEColors[i+1].red < FEColors[i].red then 555 ec.red := FEColors[i].red - NativeUInt(curPos)*NativeUInt(FEColors[i].red-FEColors[i+1].red) div NativeUInt(posDiff) else 556 ec.red := FEColors[i].red + NativeUInt(curPos)*NativeUInt(FEColors[i+1].red-FEColors[i].red) div NativeUInt(posDiff); 557 if FEColors[i+1].green < FEColors[i].green then 558 ec.green := FEColors[i].green - NativeUInt(curPos)*NativeUInt(FEColors[i].green-FEColors[i+1].green) div NativeUInt(posDiff) else 559 ec.green := FEColors[i].green + NativeUInt(curPos)*NativeUInt(FEColors[i+1].green-FEColors[i].green) div NativeUInt(posDiff); 560 if FEColors[i+1].blue < FEColors[i].blue then 561 ec.blue := FEColors[i].blue - NativeUInt(curPos)*NativeUInt(FEColors[i].blue-FEColors[i+1].blue) div NativeUInt(posDiff) else 562 ec.blue := FEColors[i].blue + NativeUInt(curPos)*NativeUInt(FEColors[i+1].blue-FEColors[i].blue) div NativeUInt(posDiff); 563 if FEColors[i+1].alpha < FEColors[i].alpha then 564 ec.alpha := FEColors[i].alpha - NativeUInt(curPos)*NativeUInt(FEColors[i].alpha-FEColors[i+1].alpha) div NativeUInt(posDiff) else 565 ec.alpha := FEColors[i].alpha + NativeUInt(curPos)*NativeUInt(FEColors[i+1].alpha-FEColors[i].alpha) div NativeUInt(posDiff); 566 result := GammaCompression(ec); 567 end else 568 begin 569 result.red := FColors[i].red + (curPos)*(FColors[i+1].red-FColors[i].red) div (posDiff); 570 result.green := FColors[i].green + (curPos)*(FColors[i+1].green-FColors[i].green) div (posDiff); 571 result.blue := FColors[i].blue + (curPos)*(FColors[i+1].blue-FColors[i].blue) div (posDiff); 572 result.alpha := FColors[i].alpha + (curPos)*(FColors[i+1].alpha-FColors[i].alpha) div (posDiff); 573 end; 574 end; 575 end; 576 end; 577 578 function TBGRAMultiGradient.GetExpandedColorAt(position: integer 579 ): TExpandedPixel; 580 var i: NativeInt; 581 curPos,posDiff: NativeInt; 582 rw,gw,bw: NativeUInt; 583 begin 584 if FCycle then 585 position := (position-FPositions[0]) mod (FPositions[high(FPositions)] - FPositions[0]) + FPositions[0]; 586 if position <= FPositions[0] then 587 result := FEColors[0] else 588 if position >= FPositions[high(FPositions)] then 589 result := FEColors[high(FColors)] else 590 begin 591 i := 0; 592 while (i < high(FPositions)-1) and (position >= FPositions[i+1]) do 593 inc(i); 594 595 if Position = FPositions[i] then 596 result := FEColors[i] 597 else 598 begin 599 curPos := position-FPositions[i]; 600 posDiff := FPositions[i+1]-FPositions[i]; 601 if FInterpolationFunction <> nil then 602 begin 603 curPos := round(FInterpolationFunction(curPos/posDiff)*65536); 604 posDiff := 65536; 605 end; 606 if GammaCorrection then 607 begin 608 if FEColors[i+1].red < FEColors[i].red then 609 result.red := FEColors[i].red - NativeUInt(curPos)*NativeUInt(FEColors[i].red-FEColors[i+1].red) div NativeUInt(posDiff) else 610 result.red := FEColors[i].red + NativeUInt(curPos)*NativeUInt(FEColors[i+1].red-FEColors[i].red) div NativeUInt(posDiff); 611 if FEColors[i+1].green < FEColors[i].green then 612 result.green := FEColors[i].green - NativeUInt(curPos)*NativeUInt(FEColors[i].green-FEColors[i+1].green) div NativeUInt(posDiff) else 613 result.green := FEColors[i].green + NativeUInt(curPos)*NativeUInt(FEColors[i+1].green-FEColors[i].green) div NativeUInt(posDiff); 614 if FEColors[i+1].blue < FEColors[i].blue then 615 result.blue := FEColors[i].blue - NativeUInt(curPos)*NativeUInt(FEColors[i].blue-FEColors[i+1].blue) div NativeUInt(posDiff) else 616 result.blue := FEColors[i].blue + NativeUInt(curPos)*NativeUInt(FEColors[i+1].blue-FEColors[i].blue) div NativeUInt(posDiff); 617 if FEColors[i+1].alpha < FEColors[i].alpha then 618 result.alpha := FEColors[i].alpha - NativeUInt(curPos)*NativeUInt(FEColors[i].alpha-FEColors[i+1].alpha) div NativeUInt(posDiff) else 619 result.alpha := FEColors[i].alpha + NativeUInt(curPos)*NativeUInt(FEColors[i+1].alpha-FEColors[i].alpha) div NativeUInt(posDiff); 620 end else 621 begin 622 rw := NativeInt(FColors[i].red shl 8) + (((curPos) shl 8)*(FColors[i+1].red-FColors[i].red)) div (posDiff); 623 gw := NativeInt(FColors[i].green shl 8) + (((curPos) shl 8)*(FColors[i+1].green-FColors[i].green)) div (posDiff); 624 bw := NativeInt(FColors[i].blue shl 8) + (((curPos) shl 8)*(FColors[i+1].blue-FColors[i].blue)) div (posDiff); 625 626 if rw >= $ff00 then result.red := $ffff 627 else result.red := (GammaExpansionTab[rw shr 8]*NativeUInt(255 - (rw and 255)) + GammaExpansionTab[(rw shr 8)+1]*NativeUInt(rw and 255)) shr 8; 628 if gw >= $ff00 then result.green := $ffff 629 else result.green := (GammaExpansionTab[gw shr 8]*NativeUInt(255 - (gw and 255)) + GammaExpansionTab[(gw shr 8)+1]*NativeUInt(gw and 255)) shr 8; 630 if bw >= $ff00 then result.blue := $ffff 631 else result.blue := (GammaExpansionTab[bw shr 8]*NativeUInt(255 - (bw and 255)) + GammaExpansionTab[(bw shr 8)+1]*NativeUInt(bw and 255)) shr 8; 632 result.alpha := NativeInt(FColors[i].alpha shl 8) + (((curPos) shl 8)*(FColors[i+1].alpha-FColors[i].alpha)) div (posDiff); 633 result.alpha := result.alpha + (result.alpha shr 8); 634 end; 456 635 end; 457 636 end; … … 544 723 end; 545 724 725 function TBGRASimpleGradientWithGammaCorrection.GetExpandedColorAt( 726 position: integer): TExpandedPixel; 727 var b,b2: cardinal; 728 begin 729 if position <= 0 then 730 result := ec1 else 731 if position >= 65536 then 732 result := ec2 else 733 begin 734 b := position; 735 b2 := 65536-b; 736 result.red := (ec1.red * b2 + ec2.red * b + 32767) shr 16; 737 result.green := (ec1.green * b2 + ec2.green * b + 32767) shr 16; 738 result.blue := (ec1.blue * b2 + ec2.blue * b + 32767) shr 16; 739 result.alpha := (ec1.alpha * b2 + ec2.alpha * b + 32767) shr 16; 740 end; 741 end; 742 743 function TBGRASimpleGradientWithGammaCorrection.GetExpandedColorAtF( 744 position: single): TExpandedPixel; 745 var b,b2: cardinal; 746 begin 747 if position <= 0 then 748 result := ec1 else 749 if position >= 1 then 750 result := ec2 else 751 begin 752 b := round(position*65536); 753 b2 := 65536-b; 754 result.red := (ec1.red * b2 + ec2.red * b + 32767) shr 16; 755 result.green := (ec1.green * b2 + ec2.green * b + 32767) shr 16; 756 result.blue := (ec1.blue * b2 + ec2.blue * b + 32767) shr 16; 757 result.alpha := (ec1.alpha * b2 + ec2.alpha * b + 32767) shr 16; 758 end; 759 end; 760 761 function TBGRASimpleGradientWithGammaCorrection.GetAverageExpandedColor: TExpandedPixel; 762 begin 763 result := MergeBGRA(ec1,ec2); 764 end; 765 546 766 function TBGRASimpleGradientWithGammaCorrection.GetMonochrome: boolean; 547 767 begin … … 556 776 FColor1 := Color1; 557 777 FColor2 := Color2; 778 ec1 := GammaExpansion(Color1); 779 ec2 := GammaExpansion(Color2); 558 780 end; 559 781 … … 577 799 578 800 function TBGRASimpleGradientWithoutGammaCorrection.GetColorAtF(position: single): TBGRAPixel; 579 var b,b2: cardinal;580 801 begin 581 802 if position <= 0 then … … 583 804 if position >= 1 then 584 805 result := FColor2 else 585 begin 586 b := round(position*1024); 806 result := GetColorAt(round(position*65536)); 807 end; 808 809 function TBGRASimpleGradientWithoutGammaCorrection.GetExpandedColorAt( 810 position: integer): TExpandedPixel; 811 var b,b2: cardinal; 812 rw,gw,bw: word; 813 begin 814 if position <= 0 then 815 result := ec1 else 816 if position >= 65536 then 817 result := ec2 else 818 begin 819 b := position shr 6; 587 820 b2 := 1024-b; 588 result.red := (FColor1.red * b2 + FColor2.red * b + 511) shr 10; 589 result.green := (FColor1.green * b2 + FColor2.green * b + 511) shr 10; 590 result.blue := (FColor1.blue * b2 + FColor2.blue * b + 511) shr 10; 591 result.alpha := (FColor1.alpha * b2 + FColor2.alpha * b + 511) shr 10; 592 end; 821 rw := (FColor1.red * b2 + FColor2.red * b + 511) shr 2; 822 gw := (FColor1.green * b2 + FColor2.green * b + 511) shr 2; 823 bw := (FColor1.blue * b2 + FColor2.blue * b + 511) shr 2; 824 825 result.red := (GammaExpansionTab[rw shr 8]*NativeUInt(255 - (rw and 255)) + GammaExpansionTab[(rw shr 8)+1]*NativeUInt(rw and 255)) shr 8; 826 result.green := (GammaExpansionTab[gw shr 8]*NativeUInt(255 - (gw and 255)) + GammaExpansionTab[(gw shr 8)+1]*NativeUInt(gw and 255)) shr 8; 827 result.blue := (GammaExpansionTab[bw shr 8]*NativeUInt(255 - (bw and 255)) + GammaExpansionTab[(bw shr 8)+1]*NativeUInt(bw and 255)) shr 8; 828 result.alpha := (FColor1.alpha * b2 + FColor2.alpha * b + 511) shr 2; 829 end; 830 end; 831 832 function TBGRASimpleGradientWithoutGammaCorrection.GetExpandedColorAtF( 833 position: single): TExpandedPixel; 834 begin 835 if position <= 0 then 836 result := ec1 else 837 if position >= 1 then 838 result := ec2 else 839 result := GetExpandedColorAt(round(position*65536)); 593 840 end; 594 841 … … 675 922 end; 676 923 924 function TBGRAGradientTriangleScanner.ScanNextExpandedPixel: TExpandedPixel; 925 var r,g,b,a: int64; 926 begin 927 r := round(FCurColor[1]); 928 g := round(FCurColor[2]); 929 b := round(FCurColor[3]); 930 a := round(FCurColor[4]); 931 if r > 65535 then r := 65535 else 932 if r < 0 then r := 0; 933 if g > 65535 then g := 65535 else 934 if g < 0 then g := 0; 935 if b > 65535 then b := 65535 else 936 if b < 0 then b := 0; 937 if a > 65535 then a := 65535 else 938 if a < 0 then a := 0; 939 result.red := r; 940 result.green := g; 941 result.blue := b; 942 result.alpha := a; 943 FCurColor += FStep; 944 end; 945 677 946 { TBGRAGradientScanner } 678 947 … … 704 973 FVertical := (((gtype =gtLinear) or (gtype=gtReflected)) and (o1.x=o2.x)) or FGradient.Monochrome; 705 974 mergedColor := FGradient.GetAverageColor; 975 mergedExpandedColor := FGradient.GetAverageExpandedColor; 706 976 end; 707 977 … … 763 1033 end; 764 1034 1035 function TBGRAGradientScanner.ScanNextExpandedInline: TExpandedPixel; 1036 var 1037 a,a2: single; 1038 ai: integer; 1039 begin 1040 if FGradientType >= gtDiamond then 1041 begin 1042 if FGradientType = gtRadial then 1043 begin 1044 a := sqrt(sqr(FDotProduct) + sqr(FDotProductPerp)); 1045 FDotProduct += u.x; 1046 FDotProductPerp += u.y; 1047 end else 1048 begin 1049 a := abs(FDotProduct); 1050 a2 := abs(FDotProductPerp); 1051 if a2 > a then a := a2; 1052 FDotProduct += u.x; 1053 FDotProductPerp += u.y; 1054 end; 1055 end else 1056 if FGradientType = gtReflected then 1057 begin 1058 a := abs(FDotProduct); 1059 FDotProduct += u.x; 1060 end else 1061 begin 1062 a := FDotProduct; 1063 FDotProduct += u.x; 1064 end; 1065 1066 if FSinus then 1067 begin 1068 a *= aFactor; 1069 if a <= low(int64) then 1070 result := FGradient.GetAverageExpandedColor 1071 else 1072 if a >= high(int64) then 1073 result := FGradient.GetAverageExpandedColor 1074 else 1075 begin 1076 ai := Sin65536(round(a)); 1077 result := FGradient.GetExpandedColorAt(ai); 1078 end; 1079 end else 1080 result := FGradient.GetExpandedColorAtF(a*aFactorF); 1081 end; 1082 765 1083 constructor TBGRAGradientScanner.Create(c1, c2: TBGRAPixel; 766 1084 gtype: TGradientType; o1, o2: TPointF; gammaColorCorrection: boolean; … … 814 1132 InitScanInline(X,Y); 815 1133 if FVertical then 1134 begin 816 1135 FHorizColor := ScanNextInline; 1136 FHorizExpandedColor := ScanNextExpandedInline; 1137 end; 817 1138 end; 818 1139 … … 823 1144 else 824 1145 result := ScanNextInline; 1146 end; 1147 1148 function TBGRAGradientScanner.ScanNextExpandedPixel: TExpandedPixel; 1149 begin 1150 if FVertical then 1151 result := FHorizExpandedColor 1152 else 1153 result := ScanNextExpandedInline; 825 1154 end; 826 1155 … … 853 1182 begin 854 1183 a := a*aFactor; 855 if a <= low(int64) then 856 result := FGradient.GetAverageColor 857 else 858 if a >= high(int64) then 859 result := FGradient.GetAverageColor 1184 if (a <= low(int64)) or (a >= high(int64)) then 1185 result := mergedColor 860 1186 else 861 1187 begin … … 865 1191 end else 866 1192 result := FGradient.GetColorAtF(a*aFactorF); 1193 end; 1194 1195 function TBGRAGradientScanner.ScanAtExpanded(X, Y: Single): TExpandedPixel; 1196 var p: TPointF; 1197 a,a2: single; 1198 ai: integer; 1199 begin 1200 if len = 0 then 1201 begin 1202 result := mergedExpandedColor; 1203 exit; 1204 end; 1205 1206 p.x := X - FOrigin1.x; 1207 p.y := Y - FOrigin1.y; 1208 case FGradientType of 1209 gtLinear: a := p.x * u.x + p.y * u.y; 1210 gtReflected: a := abs(p.x * u.x + p.y * u.y); 1211 gtDiamond: 1212 begin 1213 a := abs(p.x * u.x + p.y * u.y); 1214 a2 := abs(p.x * u.y - p.y * u.x); 1215 if a2 > a then a := a2; 1216 end; 1217 gtRadial: a := sqrt(sqr(p.x * u.x + p.y * u.y) + sqr(p.x * u.y - p.y * u.x)); 1218 end; 1219 1220 if FSinus then 1221 begin 1222 a := a*aFactor; 1223 if (a <= low(int64)) or (a >= high(int64)) then 1224 result := mergedExpandedColor 1225 else 1226 begin 1227 ai := Sin65536(round(a)); 1228 result := FGradient.GetExpandedColorAt(ai); 1229 end; 1230 end else 1231 result := FGradient.GetExpandedColorAtF(a*aFactorF); 867 1232 end; 868 1233 … … 961 1326 var c: TBGRAPixel; 962 1327 alpha: byte; 963 MemMask, pmask, MemTex, ptex: pbgrapixel;1328 pmask, ptex: pbgrapixel; 964 1329 965 1330 function GetNext: TBGRAPixel; inline; … … 982 1347 983 1348 begin 984 getmem(MemMask, count*sizeof(TBGRAPixel));985 ScannerPutPixels(FMask,MemMask,count,dmSet);986 getmem(MemTex, count*sizeof(TBGRAPixel));987 ScannerPutPixels(FTexture, MemTex,count,dmSet);988 989 pmask := MemMask;990 ptex := MemTex;1349 if count > length(FMemMask) then setlength(FMemMask, max(length(FMemMask)*2,count)); 1350 if count > length(FMemTex) then setlength(FMemTex, max(length(FMemTex)*2,count)); 1351 ScannerPutPixels(FMask,@FMemMask[0],count,dmSet); 1352 ScannerPutPixels(FTexture,@FMemTex[0],count,dmSet); 1353 1354 pmask := @FMemMask[0]; 1355 ptex := @FMemTex[0]; 991 1356 992 1357 if FGlobalOpacity <> 255 then … … 1071 1436 end; 1072 1437 end; 1073 1074 freemem(MemMask);1075 freemem(MemTex);1076 1438 end; 1077 1439 … … 1125 1487 var c: TBGRAPixel; 1126 1488 alpha: byte; 1127 MemMask,pmask: pbgrapixel;1489 pmask: pbgrapixel; 1128 1490 1129 1491 function GetNext: TBGRAPixel; inline; … … 1136 1498 1137 1499 begin 1138 getmem(MemMask, count*sizeof(TBGRAPixel));1139 ScannerPutPixels(FMask, MemMask,count,dmSet);1140 1141 pmask := MemMask;1500 if count > length(FMemMask) then setlength(FMemMask, max(length(FMemMask)*2,count)); 1501 ScannerPutPixels(FMask,@FMemMask[0],count,dmSet); 1502 1503 pmask := @FMemMask[0]; 1142 1504 1143 1505 case mode of … … 1179 1541 end; 1180 1542 end; 1181 1182 freemem(MemMask);1183 1543 end; 1184 1544 … … 1229 1589 mode: TDrawMode); 1230 1590 var c: TBGRAPixel; 1231 MemTex,ptex: pbgrapixel;1591 ptex: pbgrapixel; 1232 1592 1233 1593 function GetNext: TBGRAPixel; inline; … … 1239 1599 1240 1600 begin 1241 getmem(MemTex, count*sizeof(TBGRAPixel));1242 ScannerPutPixels(FTexture, MemTex,count,dmSet);1243 1244 ptex := MemTex;1601 if count > length(FMemTex) then setlength(FMemTex, max(length(FMemTex)*2,count)); 1602 ScannerPutPixels(FTexture,@FMemTex[0],count,dmSet); 1603 1604 ptex := @FMemTex[0]; 1245 1605 1246 1606 case mode of … … 1282 1642 end; 1283 1643 end; 1284 1285 freemem(MemTex);1286 1644 end; 1287 1645
Note:
See TracChangeset
for help on using the changeset viewer.