Changeset 521 for GraphicTest/Packages/bgrabitmap/bgrabitmaptypes.pas
- Timestamp:
- Apr 17, 2019, 12:58:41 AM (5 years ago)
- Location:
- GraphicTest
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest
- Property svn:ignore
-
old new 8 8 GraphicTest.lps 9 9 GraphicTest.dbg 10 heaptrclog.trc
-
- Property svn:ignore
-
GraphicTest/Packages/bgrabitmap/bgrabitmaptypes.pas
r494 r521 33 33 uses 34 34 Classes, Types, BGRAGraphics, 35 FPImage, FPImgCanv{$IFDEF BGRABITMAP_USE_LCL}, GraphType{$ENDIF},35 FPImage, FPImgCanv{$IFDEF BGRABITMAP_USE_LCL}, LCLType, GraphType, LResources{$ENDIF}, 36 36 BGRAMultiFileType; 37 37 … … 40 40 Int32or64 = {$IFDEF CPU64}Int64{$ELSE}LongInt{$ENDIF}; 41 41 UInt32or64 = {$IFDEF CPU64}UInt64{$ELSE}LongWord{$ENDIF}; 42 HDC = {$IFDEF BGRABITMAP_USE_LCL}LCLType.HDC{$ELSE}PtrUInt{$ENDIF}; 42 43 43 44 {=== Miscellaneous types ===} … … 78 79 79 80 TTextLayout = BGRAGraphics.TTextLayout; 81 TFontBidiMode = (fbmAuto, fbmLeftToRight, fbmRightToLeft); 82 TBidiTextAlignment = (btaNatural, btaOpposite, btaLeftJustify, btaRightJustify, btaCenter); 80 83 81 84 const 85 RadialBlurTypeToStr: array[TRadialBlurType] of string = 86 ('Normal','Disk','Corona','Precise','Fast','Box'); 87 88 82 89 tlTop = BGRAGraphics.tlTop; 83 90 tlCenter = BGRAGraphics.tlCenter; … … 285 292 {** Returns the total size of the string provided using the current font. 286 293 Orientation is not taken into account, so that the width is along the text } 287 function TextSize(sUTF8: string): TSize; virtual; abstract; 294 function TextSize(sUTF8: string): TSize; overload; virtual; abstract; 295 function TextSize(sUTF8: string; AMaxWidth: integer; ARightToLeft: boolean): TSize; overload; virtual; abstract; 296 297 function TextFitInfo(sUTF8: string; AMaxWidth: integer): integer; virtual; abstract; 298 function TextSizeAngle(sUTF8: string; {%H-}orientationTenthDegCCW: integer): TSize; virtual; 288 299 289 300 {** Draws the UTF8 encoded string, with color ''c''. … … 292 303 If align is taRightJustify, (''x'',''y'') is the top-right corner. 293 304 The value of ''FontOrientation'' is taken into account, so that the text may be rotated } 294 procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment); virtual; abstract; 305 procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment); overload; virtual; abstract; 306 procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment; {%H-}ARightToLeft: boolean); overload; virtual; 295 307 296 308 {** Same as above functions, except that the text is filled using texture. 297 309 The value of ''FontOrientation'' is taken into account, so that the text may be rotated } 298 procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment); virtual; abstract; 310 procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment); overload; virtual; abstract; 311 procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment; {%H-}ARightToLeft: boolean); overload; virtual; 299 312 300 313 {** Same as above, except that the orientation is specified, overriding the value of the property ''FontOrientation'' } 301 procedure TextOutAngle(ADest: TBGRACustomBitmap; x, y: single; orientationTenthDegCCW: integer; sUTF8: string; c: TBGRAPixel; align: TAlignment); virtual; abstract;314 procedure TextOutAngle(ADest: TBGRACustomBitmap; x, y: single; orientationTenthDegCCW: integer; sUTF8: string; c: TBGRAPixel; align: TAlignment); overload; virtual; abstract; 302 315 {** Same as above, except that the orientation is specified, overriding the value of the property ''FontOrientation'' } 303 procedure TextOutAngle(ADest: TBGRACustomBitmap; x, y: single; orientationTenthDegCCW: integer; sUTF8: string; texture: IBGRAScanner; align: TAlignment); virtual; abstract;316 procedure TextOutAngle(ADest: TBGRACustomBitmap; x, y: single; orientationTenthDegCCW: integer; sUTF8: string; texture: IBGRAScanner; align: TAlignment); overload; virtual; abstract; 304 317 305 318 {** Draw the UTF8 encoded string at the coordinate (''x'',''y''), clipped inside the rectangle ''ARect''. 306 319 Additional style information is provided by the style parameter. 307 320 The color ''c'' is used to fill the text. No rotation is applied. } 308 procedure TextRect(ADest: TBGRACustomBitmap; ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; c: TBGRAPixel); virtual; abstract;321 procedure TextRect(ADest: TBGRACustomBitmap; ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; c: TBGRAPixel); overload; virtual; abstract; 309 322 310 323 {** Same as above except a ''texture'' is used to fill the text } 311 procedure TextRect(ADest: TBGRACustomBitmap; ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; texture: IBGRAScanner); virtual; abstract;324 procedure TextRect(ADest: TBGRACustomBitmap; ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; texture: IBGRAScanner); overload; virtual; abstract; 312 325 313 326 {** Copy the path for the UTF8 encoded string into ''ADest''. … … 316 329 If ''align'' is ''taRightJustify'', (''x'',''y'') is the top-right corner. } 317 330 procedure CopyTextPathTo({%H-}ADest: IBGRAPath; {%H-}x, {%H-}y: single; {%H-}s: string; {%H-}align: TAlignment); virtual; //optional 331 function HandlesTextPath: boolean; virtual; 318 332 end; 319 333 … … 332 346 byte index } 333 347 function RemoveLineEndingUTF8(var sUTF8: string; indexUTF8: integer): boolean; 334 {** Default word break handler , that simply divide when there is a space}348 {** Default word break handler } 335 349 procedure BGRADefaultWordBreakHandler(var ABefore, AAfter: string); 336 350 … … 395 409 ifGif, 396 410 {** BMP format, transparency, no compression. Note that transparency is 397 not supported by all BMP readers so it is notrecommended to avoid411 not supported by all BMP readers so it is recommended to avoid 398 412 storing images with transparency in this format } 399 413 ifBmp, 414 {** iGO BMP (16-bit, rudimentary lossless compression) } 415 ifBmpMioMap, 400 416 {** ICO format, contains different sizes of the same image } 401 417 ifIco, 418 {** CUR format, has hotspot, contains different sizes of the same image } 419 ifCur, 402 420 {** PCX format, opaque, rudimentary lossless compression } 403 421 ifPcx, … … 420 438 {** X-Pixmap, text encoded image, limited support } 421 439 ifXPixMap, 422 {** iGO BMP, limited support } 423 ifBmpMioMap); 440 {** Scalable Vector Graphic, vectorial, read-only as raster } 441 ifSvg); 442 443 {* Image information from superficial analysis } 444 TQuickImageInfo = record 445 {** Width in pixels } 446 Width, 447 {** Height in pixels } 448 Height, 449 {** Bitdepth for colors (1, 2, 4, 8 for images with palette/grayscale, 16, 24 or 48 if each channel is present) } 450 ColorDepth, 451 {** Bitdepth for alpha (0 if no alpha channel, 1 if bit mask, 8 or 16 if alpha channel) } 452 AlphaDepth: integer; 453 end; 454 455 {* Bitmap reader with additional features } 456 TBGRAImageReader = class(TFPCustomImageReader) 457 {** Return bitmap information (size, bit depth) } 458 function GetQuickInfo(AStream: TStream): TQuickImageInfo; virtual; abstract; 459 {** Return a draft of the bitmap, the ratio may change compared to the original width and height (useful to make thumbnails) } 460 function GetBitmapDraft(AStream: TStream; AMaxWidth, AMaxHeight: integer; out AOriginalWidth,AOriginalHeight: integer): TBGRACustomBitmap; virtual; abstract; 461 end; 424 462 425 463 {* Options when loading an image } … … 458 496 {$I bgracustombitmap.inc} 459 497 498 operator =(const AGuid1, AGuid2: TGuid): boolean; 499 500 type 501 { TBGRAResourceManager } 502 503 TBGRAResourceManager = class 504 protected 505 function GetWinResourceType(AExtension: string): pchar; 506 public 507 function GetResourceStream(AFilename: string): TStream; virtual; 508 function IsWinResource(AFilename: string): boolean; virtual; 509 end; 510 511 var 512 BGRAResource : TBGRAResourceManager; 513 460 514 implementation 461 515 462 uses Math, SysUtils, BGRAUTF8, 463 FPRead Tiff, FPReadXwd, FPReadXPM,516 uses Math, SysUtils, BGRAUTF8, BGRAUnicode, 517 FPReadXwd, FPReadXPM, 464 518 FPWriteTiff, FPWriteJPEG, BGRAWritePNG, FPWriteBMP, FPWritePCX, 465 519 FPWriteTGA, FPWriteXPM; … … 532 586 533 587 procedure BGRADefaultWordBreakHandler(var ABefore, AAfter: string); 534 var p: integer; 535 begin 536 if (AAfter <> '') and (ABefore <> '') and (AAfter[1]<> ' ') and (ABefore[length(ABefore)] <> ' ') then 588 const spacingChars = [' ']; 589 wordBreakChars = [' ',#9,'-','?','!']; 590 var p, charLen: integer; 591 u: Cardinal; 592 begin 593 if (AAfter <> '') and (ABefore <> '') and not (AAfter[1] in spacingChars) and not (ABefore[length(ABefore)] in wordBreakChars) then 537 594 begin 538 595 p := length(ABefore); 539 while (p > 1) and (ABefore[p-1] <> ' ') do dec(p); 596 while (p > 1) and not (ABefore[p-1] in wordBreakChars) do dec(p); 597 while (p < length(ABefore)+1) and (ABefore[p] in [#$80..#$BF]) do inc(p); //do not split UTF8 char 598 //keep non-spacing mark together 599 while p <= length(ABefore) do 600 begin 601 charLen := UTF8CharacterLength(@ABefore[p]); 602 if p+charLen > length(ABefore)+1 then charLen := length(ABefore)+1-p; 603 u := UTF8CodepointToUnicode(@ABefore[p],charLen); 604 if GetUnicodeBidiClass(u) = ubcNonSpacingMark then 605 inc(p,charLen) 606 else 607 break; 608 end; 609 610 if p = 1 then 611 begin 612 //keep ideographic punctuation together 613 charLen := UTF8CharacterLength(@AAfter[p]); 614 if charLen > length(AAfter) then charLen := length(AAfter); 615 u := UTF8CodepointToUnicode(@AAfter[p],charLen); 616 case u of 617 UNICODE_IDEOGRAPHIC_COMMA, 618 UNICODE_IDEOGRAPHIC_FULL_STOP, 619 UNICODE_FULLWIDTH_COMMA, 620 UNICODE_HORIZONTAL_ELLIPSIS: 621 begin 622 p := length(ABefore)+1; 623 while p > 1 do 624 begin 625 charLen := 1; 626 dec(p); 627 while (p > 0) and (ABefore[p] in [#$80..#$BF]) do 628 begin 629 dec(p); //do not split UTF8 char 630 inc(charLen); 631 end; 632 if charLen <= 4 then 633 u := UTF8CodepointToUnicode(@ABefore[p],charLen) 634 else 635 u := ord('A'); 636 case GetUnicodeBidiClass(u) of 637 ubcNonSpacingMark: ; // include NSM 638 ubcOtherNeutrals, ubcWhiteSpace, ubcCommonSeparator, ubcEuropeanNumberSeparator: 639 begin 640 p := 1; 641 break; 642 end 643 else 644 break; 645 end; 646 end; 647 end; 648 end; 649 end; 650 540 651 if p > 1 then //can put the word after 541 652 begin … … 547 658 end; 548 659 end; 549 while (ABefore <> '') and (ABefore[length(ABefore)] =' ') do delete(ABefore,length(ABefore),1);550 while (AAfter <> '') and (AAfter[1] =' ') do delete(AAfter,1,1);660 while (ABefore <> '') and (ABefore[length(ABefore)] in spacingChars) do delete(ABefore,length(ABefore),1); 661 while (AAfter <> '') and (AAfter[1] in spacingChars) do delete(AAfter,1,1); 551 662 end; 552 663 … … 567 678 { TBGRACustomFontRenderer } 568 679 680 function TBGRACustomFontRenderer.TextSizeAngle(sUTF8: string; 681 orientationTenthDegCCW: integer): TSize; 682 begin 683 result := TextSize(sUTF8); //ignore orientation by default 684 end; 685 686 procedure TBGRACustomFontRenderer.TextOut(ADest: TBGRACustomBitmap; x, 687 y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment; 688 ARightToLeft: boolean); 689 begin 690 //if RightToLeft is not handled 691 TextOut(ADest,x,y,sUTF8,c,align); 692 end; 693 694 procedure TBGRACustomFontRenderer.TextOut(ADest: TBGRACustomBitmap; x, 695 y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment; 696 ARightToLeft: boolean); 697 begin 698 //if RightToLeft is not handled 699 TextOut(ADest,x,y,sUTF8,texture,align); 700 end; 701 569 702 procedure TBGRACustomFontRenderer.CopyTextPathTo(ADest: IBGRAPath; x, y: single; s: string; align: TAlignment); 570 703 begin {optional implementation} end; 704 705 function TBGRACustomFontRenderer.HandlesTextPath: boolean; 706 begin 707 result := false; 708 end; 571 709 572 710 … … 825 963 end; 826 964 827 if (magic[0] = $00) and (magic[1] = $00) and (magic[2] in[$01,$02]) and (magic[3] = $00) and 828 (magic[4] + (magic[5] shl 8) > 0) then inc(scores[ifIco]); 965 if (magic[0] = $00) and (magic[1] = $00) and (magic[3] = $00) and 966 (magic[4] + (magic[5] shl 8) > 0) then 967 begin 968 if magic[2] = $01 then 969 inc(scores[ifIco]) 970 else if magic[2] = $02 then 971 inc(scores[ifCur]); 972 end; 829 973 830 974 if (copy(magicAsText,1,4) = 'PDN3') then … … 852 996 with CreateBGRAImageReader(ifOpenRaster) do 853 997 try 998 AStream.Position := streamStartPos; 854 999 if CheckContents(AStream) then inc(scores[ifOpenRaster],2); 855 1000 finally … … 866 1011 867 1012 if (copy(magicAsText,1,8) = '/* XPM *') or (copy(magicAsText,1,6) = '! XPM2') then inc(scores[ifXPixMap]); 1013 1014 if (copy(magicAsText,1,6) = '<?xml ') then inc(scores[ifSvg]); 868 1015 869 1016 AStream.Position := streamStartPos; … … 915 1062 if (ext = '.pcx') then result := ifPcx else 916 1063 if (ext = '.bmp') then result := ifBmp else 917 if (ext = '.ico') or (ext = '.cur') then result := ifIco else 1064 if (ext = '.ico') then result := ifIco else 1065 if (ext = '.cur') then result := ifCur else 918 1066 if (ext = '.pdn') then result := ifPaintDotNet else 919 1067 if (ext = '.lzp') then result := ifLazPaint else … … 924 1072 if (ext = '.xwd') then result := ifXwd else 925 1073 if (ext = '.xpm') then result := ifXPixMap else 926 if (ext = '.oxo') then result := ifPhoxo; 1074 if (ext = '.oxo') then result := ifPhoxo else 1075 if (ext = '.svg') then result := ifSvg; 927 1076 end; 928 1077 … … 934 1083 ifGif: result := 'gif'; 935 1084 ifBmp: result := 'bmp'; 1085 ifBmpMioMap: result := 'bmp'; 936 1086 ifIco: result := 'ico'; 1087 ifCur: result := 'ico'; 937 1088 ifPcx: result := 'pcx'; 938 1089 ifPaintDotNet: result := 'pdn'; 939 1090 ifLazPaint: result := 'lzp'; 940 1091 ifOpenRaster: result := 'ora'; 1092 ifPhoxo: result := 'oXo'; 941 1093 ifPsd: result := 'psd'; 942 1094 ifTarga: result := 'tga'; … … 944 1096 ifXwd: result := 'xwd'; 945 1097 ifXPixMap: result := 'xpm'; 946 if BmpMioMap: result := 'bmp';1098 ifSvg: result := 'svg'; 947 1099 else result := '?'; 948 1100 end; … … 957 1109 ifOpenRaster: raise exception.Create('You need to call BGRAOpenRaster.RegisterOpenRasterFormat to read this image.'); 958 1110 ifPaintDotNet: raise exception.Create('You need to call BGRAPaintNet.RegisterPaintNetFormat to read this image.'); 1111 ifSvg: raise exception.Create('You need to call BGRA.RegisterSvgFormat to read this image.'); 959 1112 else 960 1113 raise exception.Create('The image reader is not registered for this image format.'); … … 971 1124 ifUnknown: raise exception.Create('The image format is unknown'); 972 1125 ifOpenRaster: raise exception.Create('You need to call BGRAOpenRaster.RegisterOpenRasterFormat to write with this image format.'); 1126 ifPhoxo: raise exception.Create('You need to call BGRAPhoxo.RegisterPhoxoFormat to write with this image format.'); 973 1127 else 974 1128 raise exception.Create('The image writer is not registered for this image format.'); … … 995 1149 result := DefaultBGRAImageWriter[AFormat].Create; 996 1150 end; 1151 1152 operator =(const AGuid1, AGuid2: TGuid): boolean; 1153 begin 1154 result := CompareMem(@AGuid1, @AGuid2, sizeof(TGuid)); 1155 end; 1156 1157 type 1158 TResourceType = record 1159 ext: string; 1160 code: pchar; 1161 end; 1162 1163 const 1164 ResourceTypes: array[1..7] of TResourceType = 1165 ((ext: 'CUR'; code: RT_GROUP_CURSOR), 1166 (ext: 'BMP'; code: RT_BITMAP), 1167 (ext: 'ICO'; code: RT_GROUP_ICON), 1168 (ext: 'DAT'; code: RT_RCDATA), 1169 (ext: 'DATA'; code: RT_RCDATA), 1170 (ext: 'HTM'; code: RT_HTML), 1171 (ext: 'HTML'; code: RT_HTML)); 1172 1173 { TBGRAResourceManager } 1174 1175 function TBGRAResourceManager.GetWinResourceType(AExtension: string): pchar; 1176 var 1177 i: Integer; 1178 begin 1179 if (AExtension <> '') and (AExtension[1]='.') then delete(AExtension,1,1); 1180 for i := low(ResourceTypes) to high(ResourceTypes) do 1181 if AExtension = ResourceTypes[i].ext then 1182 exit(ResourceTypes[i].code); 1183 1184 exit(RT_RCDATA); 1185 end; 1186 1187 function TBGRAResourceManager.GetResourceStream(AFilename: string): TStream; 1188 var 1189 name,ext: RawByteString; 1190 rt: PChar; 1191 begin 1192 ext := UpperCase(ExtractFileExt(AFilename)); 1193 name := ChangeFileExt(AFilename,''); 1194 rt := GetWinResourceType(ext); 1195 1196 if (rt = RT_GROUP_CURSOR) or (rt = RT_GROUP_ICON) then 1197 raise exception.Create('Not implemented'); 1198 1199 result := TResourceStream.Create(HINSTANCE, name, rt); 1200 end; 1201 1202 function TBGRAResourceManager.IsWinResource(AFilename: string): boolean; 1203 var 1204 name,ext: RawByteString; 1205 rt: PChar; 1206 begin 1207 ext := UpperCase(ExtractFileExt(AFilename)); 1208 name := ChangeFileExt(AFilename,''); 1209 rt := GetWinResourceType(ext); 1210 result := FindResource(HINSTANCE, pchar(name), rt)<>0; 1211 end; 1212 1213 {$IFDEF BGRABITMAP_USE_LCL} 1214 type 1215 1216 { TLCLResourceManager } 1217 1218 TLCLResourceManager = class(TBGRAResourceManager) 1219 protected 1220 function FindLazarusResource(AFilename: string): TLResource; 1221 public 1222 function GetResourceStream(AFilename: string): TStream; override; 1223 function IsWinResource(AFilename: string): boolean; override; 1224 end; 1225 1226 function TLCLResourceManager.FindLazarusResource(AFilename: string): TLResource; 1227 var 1228 name,ext: RawByteString; 1229 begin 1230 ext := UpperCase(ExtractFileExt(AFilename)); 1231 if (ext<>'') and (ext[1]='.') then Delete(ext,1,1); 1232 name := ChangeFileExt(AFilename,''); 1233 if ext<>'' then 1234 result := LazarusResources.Find(name,ext) 1235 else 1236 result := LazarusResources.Find(name); 1237 end; 1238 1239 function TLCLResourceManager.GetResourceStream(AFilename: string): TStream; 1240 var 1241 res: TLResource; 1242 begin 1243 res := FindLazarusResource(AFilename); 1244 if Assigned(res) then 1245 result := TLazarusResourceStream.CreateFromHandle(res) 1246 else 1247 result := inherited GetResourceStream(AFilename); 1248 end; 1249 1250 function TLCLResourceManager.IsWinResource(AFilename: string): boolean; 1251 begin 1252 if FindLazarusResource(AFilename)<>nil then 1253 result := false 1254 else 1255 Result:=inherited IsWinResource(AFilename); 1256 end; 1257 1258 {$ENDIF} 997 1259 998 1260 initialization … … 1013 1275 //writing XWD not implemented 1014 1276 1015 DefaultBGRAImageReader[ifTiff] := TFPReaderTiff;1016 1277 DefaultBGRAImageReader[ifXwd] := TFPReaderXWD; 1017 1278 //the other readers are registered by their unit 1018 1279 1280 {$IFDEF BGRABITMAP_USE_LCL} 1281 BGRAResource := TLCLResourceManager.Create; 1282 {$ELSE} 1283 BGRAResource := TBGRAResourceManager.Create; 1284 {$ENDIF} 1285 1019 1286 finalization 1020 1287 … … 1024 1291 {$DEFINE INCLUDE_FINAL} 1025 1292 {$I bgrapixel.inc} 1293 1294 BGRAResource.Free; 1026 1295 end.
Note:
See TracChangeset
for help on using the changeset viewer.