浏览代码

added back texture

Unknown 6 年之前
父节点
当前提交
ddd1bc7dec
共有 3 个文件被更改,包括 847 次插入73 次删除
  1. 426 6
      vectoredit/umain.lfm
  2. 110 10
      vectoredit/umain.pas
  3. 311 57
      vectoredit/uvectororiginal.pas

+ 426 - 6
vectoredit/umain.lfm

@@ -1,11 +1,11 @@
 object Form1: TForm1
-  Left = 530
+  Left = 364
   Height = 475
-  Top = 25
-  Width = 627
+  Top = 95
+  Width = 981
   Caption = 'Vector Edit'
   ClientHeight = 475
-  ClientWidth = 627
+  ClientWidth = 981
   KeyPreview = True
   OnCreate = FormCreate
   OnDestroy = FormDestroy
@@ -15,7 +15,7 @@ object Form1: TForm1
     Left = 60
     Height = 431
     Top = 44
-    Width = 567
+    Width = 921
     OnRedraw = BGRAVirtualScreen1Redraw
     Align = alClient
     Alignment = taLeftJustify
@@ -171,7 +171,7 @@ object Form1: TForm1
     Left = 0
     Height = 44
     Top = 0
-    Width = 627
+    Width = 981
     Align = alTop
     Background.Color = clBtnFace
     Background.ColorOpacity = 255
@@ -531,6 +531,422 @@ object Form1: TForm1
       TabStop = True
       UseDockManager = False
     end
+    object BackImage: TImage
+      Left = 506
+      Height = 25
+      Top = 8
+      Width = 27
+      OnClick = BackImageClick
+      Visible = False
+    end
+    object ButtonLoadTex: TBCButton
+      Left = 472
+      Height = 25
+      Top = 8
+      Width = 28
+      StateClicked.Background.Color = clBlack
+      StateClicked.Background.ColorOpacity = 255
+      StateClicked.Background.Gradient1.StartColor = 16577765
+      StateClicked.Background.Gradient1.StartColorOpacity = 255
+      StateClicked.Background.Gradient1.DrawMode = dmSet
+      StateClicked.Background.Gradient1.EndColor = 16180676
+      StateClicked.Background.Gradient1.EndColorOpacity = 255
+      StateClicked.Background.Gradient1.ColorCorrection = True
+      StateClicked.Background.Gradient1.GradientType = gtLinear
+      StateClicked.Background.Gradient1.Point1XPercent = 0
+      StateClicked.Background.Gradient1.Point1YPercent = 0
+      StateClicked.Background.Gradient1.Point2XPercent = 0
+      StateClicked.Background.Gradient1.Point2YPercent = 100
+      StateClicked.Background.Gradient1.Sinus = False
+      StateClicked.Background.Gradient2.StartColor = 15716760
+      StateClicked.Background.Gradient2.StartColorOpacity = 255
+      StateClicked.Background.Gradient2.DrawMode = dmSet
+      StateClicked.Background.Gradient2.EndColor = 14398312
+      StateClicked.Background.Gradient2.EndColorOpacity = 255
+      StateClicked.Background.Gradient2.ColorCorrection = True
+      StateClicked.Background.Gradient2.GradientType = gtLinear
+      StateClicked.Background.Gradient2.Point1XPercent = 0
+      StateClicked.Background.Gradient2.Point1YPercent = 0
+      StateClicked.Background.Gradient2.Point2XPercent = 0
+      StateClicked.Background.Gradient2.Point2YPercent = 100
+      StateClicked.Background.Gradient2.Sinus = False
+      StateClicked.Background.Gradient1EndPercent = 55
+      StateClicked.Background.Style = bbsGradient
+      StateClicked.Border.Color = 9134636
+      StateClicked.Border.ColorOpacity = 255
+      StateClicked.Border.LightColor = clBlack
+      StateClicked.Border.LightOpacity = 100
+      StateClicked.Border.LightWidth = 1
+      StateClicked.Border.Style = bboSolid
+      StateClicked.Border.Width = 1
+      StateClicked.FontEx.Color = clBlack
+      StateClicked.FontEx.EndEllipsis = False
+      StateClicked.FontEx.FontQuality = fqSystemClearType
+      StateClicked.FontEx.Height = 0
+      StateClicked.FontEx.SingleLine = True
+      StateClicked.FontEx.Shadow = False
+      StateClicked.FontEx.ShadowColor = clBlack
+      StateClicked.FontEx.ShadowColorOpacity = 255
+      StateClicked.FontEx.ShadowRadius = 5
+      StateClicked.FontEx.ShadowOffsetX = 5
+      StateClicked.FontEx.ShadowOffsetY = 5
+      StateClicked.FontEx.Style = []
+      StateClicked.FontEx.TextAlignment = bcaCenter
+      StateClicked.FontEx.WordBreak = False
+      StateHover.Background.Color = clBlack
+      StateHover.Background.ColorOpacity = 255
+      StateHover.Background.Gradient1.StartColor = 16643818
+      StateHover.Background.Gradient1.StartColorOpacity = 255
+      StateHover.Background.Gradient1.DrawMode = dmSet
+      StateHover.Background.Gradient1.EndColor = 16576729
+      StateHover.Background.Gradient1.EndColorOpacity = 255
+      StateHover.Background.Gradient1.ColorCorrection = True
+      StateHover.Background.Gradient1.GradientType = gtLinear
+      StateHover.Background.Gradient1.Point1XPercent = 0
+      StateHover.Background.Gradient1.Point1YPercent = 0
+      StateHover.Background.Gradient1.Point2XPercent = 0
+      StateHover.Background.Gradient1.Point2YPercent = 100
+      StateHover.Background.Gradient1.Sinus = False
+      StateHover.Background.Gradient2.StartColor = 16639678
+      StateHover.Background.Gradient2.StartColorOpacity = 255
+      StateHover.Background.Gradient2.DrawMode = dmSet
+      StateHover.Background.Gradient2.EndColor = 16112039
+      StateHover.Background.Gradient2.EndColorOpacity = 255
+      StateHover.Background.Gradient2.ColorCorrection = True
+      StateHover.Background.Gradient2.GradientType = gtLinear
+      StateHover.Background.Gradient2.Point1XPercent = 0
+      StateHover.Background.Gradient2.Point1YPercent = 0
+      StateHover.Background.Gradient2.Point2XPercent = 0
+      StateHover.Background.Gradient2.Point2YPercent = 100
+      StateHover.Background.Gradient2.Sinus = False
+      StateHover.Background.Gradient1EndPercent = 50
+      StateHover.Background.Style = bbsGradient
+      StateHover.Border.Color = 11632444
+      StateHover.Border.ColorOpacity = 255
+      StateHover.Border.LightColor = clWhite
+      StateHover.Border.LightOpacity = 200
+      StateHover.Border.LightWidth = 1
+      StateHover.Border.Style = bboSolid
+      StateHover.Border.Width = 1
+      StateHover.FontEx.Color = clBlack
+      StateHover.FontEx.EndEllipsis = False
+      StateHover.FontEx.FontQuality = fqSystemClearType
+      StateHover.FontEx.Height = 0
+      StateHover.FontEx.SingleLine = True
+      StateHover.FontEx.Shadow = False
+      StateHover.FontEx.ShadowColor = clBlack
+      StateHover.FontEx.ShadowColorOpacity = 255
+      StateHover.FontEx.ShadowRadius = 5
+      StateHover.FontEx.ShadowOffsetX = 5
+      StateHover.FontEx.ShadowOffsetY = 5
+      StateHover.FontEx.Style = []
+      StateHover.FontEx.TextAlignment = bcaCenter
+      StateHover.FontEx.WordBreak = False
+      StateNormal.Background.Color = clBlack
+      StateNormal.Background.ColorOpacity = 255
+      StateNormal.Background.Gradient1.StartColor = 15921906
+      StateNormal.Background.Gradient1.StartColorOpacity = 255
+      StateNormal.Background.Gradient1.DrawMode = dmSet
+      StateNormal.Background.Gradient1.EndColor = 15461355
+      StateNormal.Background.Gradient1.EndColorOpacity = 255
+      StateNormal.Background.Gradient1.ColorCorrection = True
+      StateNormal.Background.Gradient1.GradientType = gtLinear
+      StateNormal.Background.Gradient1.Point1XPercent = 0
+      StateNormal.Background.Gradient1.Point1YPercent = 0
+      StateNormal.Background.Gradient1.Point2XPercent = 0
+      StateNormal.Background.Gradient1.Point2YPercent = 100
+      StateNormal.Background.Gradient1.Sinus = False
+      StateNormal.Background.Gradient2.StartColor = 14540253
+      StateNormal.Background.Gradient2.StartColorOpacity = 255
+      StateNormal.Background.Gradient2.DrawMode = dmSet
+      StateNormal.Background.Gradient2.EndColor = 13619151
+      StateNormal.Background.Gradient2.EndColorOpacity = 255
+      StateNormal.Background.Gradient2.ColorCorrection = True
+      StateNormal.Background.Gradient2.GradientType = gtLinear
+      StateNormal.Background.Gradient2.Point1XPercent = 0
+      StateNormal.Background.Gradient2.Point1YPercent = 0
+      StateNormal.Background.Gradient2.Point2XPercent = 0
+      StateNormal.Background.Gradient2.Point2YPercent = 100
+      StateNormal.Background.Gradient2.Sinus = False
+      StateNormal.Background.Gradient1EndPercent = 50
+      StateNormal.Background.Style = bbsGradient
+      StateNormal.Border.Color = 7368816
+      StateNormal.Border.ColorOpacity = 255
+      StateNormal.Border.LightColor = clWhite
+      StateNormal.Border.LightOpacity = 200
+      StateNormal.Border.LightWidth = 1
+      StateNormal.Border.Style = bboSolid
+      StateNormal.Border.Width = 1
+      StateNormal.FontEx.Color = clBlack
+      StateNormal.FontEx.EndEllipsis = False
+      StateNormal.FontEx.FontQuality = fqSystemClearType
+      StateNormal.FontEx.Height = 0
+      StateNormal.FontEx.SingleLine = True
+      StateNormal.FontEx.Shadow = False
+      StateNormal.FontEx.ShadowColor = clBlack
+      StateNormal.FontEx.ShadowColorOpacity = 255
+      StateNormal.FontEx.ShadowRadius = 5
+      StateNormal.FontEx.ShadowOffsetX = 5
+      StateNormal.FontEx.ShadowOffsetY = 5
+      StateNormal.FontEx.Style = []
+      StateNormal.FontEx.TextAlignment = bcaCenter
+      StateNormal.FontEx.WordBreak = False
+      Color = clNone
+      DropDownWidth = 16
+      DropDownArrowSize = 8
+      GlobalOpacity = 255
+      Glyph.Data = {
+        36040000424D3604000000000000360000002800000010000000100000000100
+        2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+        FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+        FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004D55577F425F
+        67FF4E5455FF4E5455FF4E5455FF4E5455FF4E5455FF4E5455FF4E5455FF4E54
+        55FF4E5455FF4E5455FF4E5556AF4D57590F0000000000000000435E66FF2B7A
+        92FF71ACAEFF9BFFFFFF9BFFFFFF9BFFFFFF9BFFFFFF9BFFFFFF9BFFFFFF9BFF
+        FFFF9BFFFFFF9BFFFFFF67979AFF475A5F8F000000000000000040616AFF2592
+        B1FF5D9197FF8DF9FCFF52E1F3FF52E1F3FF52E1F3FF52E1F3FF52E1F3FF52E1
+        F3FF52E1F3FF64E9F6FF90EAEBFF426068DF00000000000000003B6672FF25B3
+        D8FF396977FF94F5F6FF66E9F6FF5FE7F5FF5FE7F5FF5FE7F5FF5FE7F5FF5FE7
+        F5FF5FE7F5FF5FE7F5FF94FCFDFF4E828BFF3B66722F00000000356B7BFF25B3
+        D8FF29839CFF74C7CDFF80F4FAFF6DECF7FF6DECF7FF6DECF7FF6DECF7FF6DEC
+        F7FF6DECF7FF6DECF7FF87F7FBFF62ABB4FF356B7A8F000000002E7185FF4CCC
+        E5FF2AA1BDFF519DAAFF94FCFEFF7AF2FAFF7AF2FAFF7AF2FAFF7AF2FAFF7AF2
+        FAFF7AF2FAFF7AF2FAFF85F6FBFF87E4E7FF2F7084CF0000000028768FFF41C5
+        E1FF20B3D6FF29768DFF93F6F8FF8AF8FCFF88F7FCFF88F7FCFF88F7FCFF88F7
+        FCFF88F7FCFF88F7FCFF88F7FCFF9AFEFEFF307E94FF28778F1F227C98FF80ED
+        F6FF3CCCE6FF2D99B4FF4FADBEFF9BFFFFFF9AFEFEFF98FEFEFF98FEFEFF96FD
+        FEFF95FDFEFF95FDFEFF95FDFEFF99FEFEFF50ACBDFF237B976F1B82A2FF65DC
+        EDFF34C1E0FF2EBADAFF2290AFFF1D81A0FF2589A6FF3CA1B8FF44A8BEFF83E7
+        EDFF9BFFFFFF9BFFFFFF9BFFFFFF9BFFFFFF5CC0CFFF1D81A0AF1587ABFF9BFF
+        FFFF82F5FBFF7CF1F9FF74EBF6FF60DDEEFF54D5EAFF46C1D9FF3FB7D1FF2B9A
+        B8FF1786A9FF1786A9FF1786A9FF1786A9FF1786A9FF1885A74F1894B9FF65DC
+        EDFF60DAECFF60DAECFF60DAECFF60DAECFF5FD8EBFF5CD6EAFF5CD6EAFF5CD6
+        EAFF56D1E7FF0C90B9FF00000000000000000000000000000000119AC3FF91F8
+        FBFF9BFFFFFF9BFFFFFF9BFFFFFF91F8FBFF2CAECFFF0893BEFF0893BEFF0893
+        BEFF0893BEFF0992BD7F000000000000000000000000000000000398C77F0299
+        C8FF0299C8FF0299C8FF0299C8FF0299C8FF0398C77F00000000000000000000
+        0000000000000000000000000000000000000000000000000000FFFFFF00FFFF
+        FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+        FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+        FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+        FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+      }
+      InnerMargin = 0
+      OnClick = ButtonLoadTexClick
+      ParentColor = False
+      Rounding.RoundX = 3
+      Rounding.RoundY = 3
+      Rounding.RoundOptions = []
+      RoundingDropDown.RoundX = 1
+      RoundingDropDown.RoundY = 1
+      RoundingDropDown.RoundOptions = []
+      TextApplyGlobalOpacity = False
+      MemoryUsage = bmuHigh
+    end
+    object ButtonNoTex: TBCButton
+      Left = 539
+      Height = 25
+      Top = 8
+      Width = 29
+      StateClicked.Background.Color = clBlack
+      StateClicked.Background.ColorOpacity = 255
+      StateClicked.Background.Gradient1.StartColor = 16577765
+      StateClicked.Background.Gradient1.StartColorOpacity = 255
+      StateClicked.Background.Gradient1.DrawMode = dmSet
+      StateClicked.Background.Gradient1.EndColor = 16180676
+      StateClicked.Background.Gradient1.EndColorOpacity = 255
+      StateClicked.Background.Gradient1.ColorCorrection = True
+      StateClicked.Background.Gradient1.GradientType = gtLinear
+      StateClicked.Background.Gradient1.Point1XPercent = 0
+      StateClicked.Background.Gradient1.Point1YPercent = 0
+      StateClicked.Background.Gradient1.Point2XPercent = 0
+      StateClicked.Background.Gradient1.Point2YPercent = 100
+      StateClicked.Background.Gradient1.Sinus = False
+      StateClicked.Background.Gradient2.StartColor = 15716760
+      StateClicked.Background.Gradient2.StartColorOpacity = 255
+      StateClicked.Background.Gradient2.DrawMode = dmSet
+      StateClicked.Background.Gradient2.EndColor = 14398312
+      StateClicked.Background.Gradient2.EndColorOpacity = 255
+      StateClicked.Background.Gradient2.ColorCorrection = True
+      StateClicked.Background.Gradient2.GradientType = gtLinear
+      StateClicked.Background.Gradient2.Point1XPercent = 0
+      StateClicked.Background.Gradient2.Point1YPercent = 0
+      StateClicked.Background.Gradient2.Point2XPercent = 0
+      StateClicked.Background.Gradient2.Point2YPercent = 100
+      StateClicked.Background.Gradient2.Sinus = False
+      StateClicked.Background.Gradient1EndPercent = 55
+      StateClicked.Background.Style = bbsGradient
+      StateClicked.Border.Color = 9134636
+      StateClicked.Border.ColorOpacity = 255
+      StateClicked.Border.LightColor = clBlack
+      StateClicked.Border.LightOpacity = 100
+      StateClicked.Border.LightWidth = 1
+      StateClicked.Border.Style = bboSolid
+      StateClicked.Border.Width = 1
+      StateClicked.FontEx.Color = clBlack
+      StateClicked.FontEx.EndEllipsis = False
+      StateClicked.FontEx.FontQuality = fqSystemClearType
+      StateClicked.FontEx.Height = 0
+      StateClicked.FontEx.SingleLine = True
+      StateClicked.FontEx.Shadow = False
+      StateClicked.FontEx.ShadowColor = clBlack
+      StateClicked.FontEx.ShadowColorOpacity = 255
+      StateClicked.FontEx.ShadowRadius = 5
+      StateClicked.FontEx.ShadowOffsetX = 5
+      StateClicked.FontEx.ShadowOffsetY = 5
+      StateClicked.FontEx.Style = []
+      StateClicked.FontEx.TextAlignment = bcaCenter
+      StateClicked.FontEx.WordBreak = False
+      StateHover.Background.Color = clBlack
+      StateHover.Background.ColorOpacity = 255
+      StateHover.Background.Gradient1.StartColor = 16643818
+      StateHover.Background.Gradient1.StartColorOpacity = 255
+      StateHover.Background.Gradient1.DrawMode = dmSet
+      StateHover.Background.Gradient1.EndColor = 16576729
+      StateHover.Background.Gradient1.EndColorOpacity = 255
+      StateHover.Background.Gradient1.ColorCorrection = True
+      StateHover.Background.Gradient1.GradientType = gtLinear
+      StateHover.Background.Gradient1.Point1XPercent = 0
+      StateHover.Background.Gradient1.Point1YPercent = 0
+      StateHover.Background.Gradient1.Point2XPercent = 0
+      StateHover.Background.Gradient1.Point2YPercent = 100
+      StateHover.Background.Gradient1.Sinus = False
+      StateHover.Background.Gradient2.StartColor = 16639678
+      StateHover.Background.Gradient2.StartColorOpacity = 255
+      StateHover.Background.Gradient2.DrawMode = dmSet
+      StateHover.Background.Gradient2.EndColor = 16112039
+      StateHover.Background.Gradient2.EndColorOpacity = 255
+      StateHover.Background.Gradient2.ColorCorrection = True
+      StateHover.Background.Gradient2.GradientType = gtLinear
+      StateHover.Background.Gradient2.Point1XPercent = 0
+      StateHover.Background.Gradient2.Point1YPercent = 0
+      StateHover.Background.Gradient2.Point2XPercent = 0
+      StateHover.Background.Gradient2.Point2YPercent = 100
+      StateHover.Background.Gradient2.Sinus = False
+      StateHover.Background.Gradient1EndPercent = 50
+      StateHover.Background.Style = bbsGradient
+      StateHover.Border.Color = 11632444
+      StateHover.Border.ColorOpacity = 255
+      StateHover.Border.LightColor = clWhite
+      StateHover.Border.LightOpacity = 200
+      StateHover.Border.LightWidth = 1
+      StateHover.Border.Style = bboSolid
+      StateHover.Border.Width = 1
+      StateHover.FontEx.Color = clBlack
+      StateHover.FontEx.EndEllipsis = False
+      StateHover.FontEx.FontQuality = fqSystemClearType
+      StateHover.FontEx.Height = 0
+      StateHover.FontEx.SingleLine = True
+      StateHover.FontEx.Shadow = False
+      StateHover.FontEx.ShadowColor = clBlack
+      StateHover.FontEx.ShadowColorOpacity = 255
+      StateHover.FontEx.ShadowRadius = 5
+      StateHover.FontEx.ShadowOffsetX = 5
+      StateHover.FontEx.ShadowOffsetY = 5
+      StateHover.FontEx.Style = []
+      StateHover.FontEx.TextAlignment = bcaCenter
+      StateHover.FontEx.WordBreak = False
+      StateNormal.Background.Color = clBlack
+      StateNormal.Background.ColorOpacity = 255
+      StateNormal.Background.Gradient1.StartColor = 15921906
+      StateNormal.Background.Gradient1.StartColorOpacity = 255
+      StateNormal.Background.Gradient1.DrawMode = dmSet
+      StateNormal.Background.Gradient1.EndColor = 15461355
+      StateNormal.Background.Gradient1.EndColorOpacity = 255
+      StateNormal.Background.Gradient1.ColorCorrection = True
+      StateNormal.Background.Gradient1.GradientType = gtLinear
+      StateNormal.Background.Gradient1.Point1XPercent = 0
+      StateNormal.Background.Gradient1.Point1YPercent = 0
+      StateNormal.Background.Gradient1.Point2XPercent = 0
+      StateNormal.Background.Gradient1.Point2YPercent = 100
+      StateNormal.Background.Gradient1.Sinus = False
+      StateNormal.Background.Gradient2.StartColor = 14540253
+      StateNormal.Background.Gradient2.StartColorOpacity = 255
+      StateNormal.Background.Gradient2.DrawMode = dmSet
+      StateNormal.Background.Gradient2.EndColor = 13619151
+      StateNormal.Background.Gradient2.EndColorOpacity = 255
+      StateNormal.Background.Gradient2.ColorCorrection = True
+      StateNormal.Background.Gradient2.GradientType = gtLinear
+      StateNormal.Background.Gradient2.Point1XPercent = 0
+      StateNormal.Background.Gradient2.Point1YPercent = 0
+      StateNormal.Background.Gradient2.Point2XPercent = 0
+      StateNormal.Background.Gradient2.Point2YPercent = 100
+      StateNormal.Background.Gradient2.Sinus = False
+      StateNormal.Background.Gradient1EndPercent = 50
+      StateNormal.Background.Style = bbsGradient
+      StateNormal.Border.Color = 7368816
+      StateNormal.Border.ColorOpacity = 255
+      StateNormal.Border.LightColor = clWhite
+      StateNormal.Border.LightOpacity = 200
+      StateNormal.Border.LightWidth = 1
+      StateNormal.Border.Style = bboSolid
+      StateNormal.Border.Width = 1
+      StateNormal.FontEx.Color = clBlack
+      StateNormal.FontEx.EndEllipsis = False
+      StateNormal.FontEx.FontQuality = fqSystemClearType
+      StateNormal.FontEx.Height = 0
+      StateNormal.FontEx.SingleLine = True
+      StateNormal.FontEx.Shadow = False
+      StateNormal.FontEx.ShadowColor = clBlack
+      StateNormal.FontEx.ShadowColorOpacity = 255
+      StateNormal.FontEx.ShadowRadius = 5
+      StateNormal.FontEx.ShadowOffsetX = 5
+      StateNormal.FontEx.ShadowOffsetY = 5
+      StateNormal.FontEx.Style = []
+      StateNormal.FontEx.TextAlignment = bcaCenter
+      StateNormal.FontEx.WordBreak = False
+      Color = clNone
+      DropDownWidth = 16
+      DropDownArrowSize = 8
+      GlobalOpacity = 255
+      Glyph.Data = {
+        36040000424D3604000000000000360000002800000010000000100000000100
+        2000000000000004000064000000640000000000000000000000000000002222
+        0D00383800001D1D291114141D0D25253C000000000000000000000000000000
+        000000004E000000450900003A140000000100000800000000002A2A1E001F1F
+        A100252568331A1A95BB19197DA31313311D19194E0000000000000000000D0D
+        8300060671102020A9902222AAC509096A47FFFFFF0000000E00252580002828
+        64321717A4CE0505DBFF0C0CC7FE191981AF1111321D1717520010107F000909
+        6A102020A8983636CFFC4444DFFF2C2CB9DD07076C476767FF0042422D091C1C
+        98B10404E4FF0000E7FF0000DAFF0D0DC0FE191983AF0E0E331C0E0E690F1F1F
+        A3982C2CC4FC3838D1FF4747E0FF5252ECFF2626B3C40000381454540A032121
+        90870A0AD2FC0000E7FF0000D9FF0101CBFF0F0FB7FE191987B41D1D97A62222
+        B9FB2828C2FF3737D0FF4848E1FF4848E2FD2020B69000003007303067003838
+        510D202093920B0BCCFB0000DAFF0000C9FF0101B8FF1010AFFF1717AFFF1919
+        B2FF2828C0FF3838D1FF3D3DD7FC2121B5980000781004048D00000000002C2C
+        6C003333580D1F1F96920C0CC6FB0000CBFF0000B6FF0000A3FF0808A1FF1818
+        B0FF2929C2FF3333CDFC2020B0980000751006068A0000000000000000000000
+        0000292972002F2F5D0C2020969A0D0DBFFF0606C0FF0A0AB8FF0F0FB7FF1A1A
+        BBFF2929C3FF1D1DA4A601016E0F090984000000000000000000000000000000
+        00002323630025254A0F1D1D919F1C1CC5FF2C2CD6FF3131D9FF3030D9FF3030
+        D5FF3030CBFF1A1A96B401013C1C070763000000000000000000000000002626
+        5F00292948101C1C8F982525C8FC4B4BDEFF5757E0FF4A4AD8FF4A4AD8FF5656
+        E0FF5252DDFF3E3ED0FE1B1B99AF0000421D050568000000000029295A002C2C
+        43101B1B8C982E2ECCFC6B6BE6FF7D7DE6FF6868DFFF2C2CBFFE2F2FBFFE6A6A
+        DFFF7C7CE6FF7474E6FF4E4ED9FE1B1B9EAF0000431C03036A00494909041E1E
+        8B8C3737D1FD8C8CEEFFA2A2EDFF8888E8FF3535C4FC1A1A989F1D1DA29A4040
+        C7FA8C8CE7FFA1A1EDFF9797EEFF5E5EE1FF1C1CA0A300001C0C43432F091B1B
+        9BAF5353E5FFC0C0F5FFA8A8F0FF3D3DCBFC1919969819195C0F10107E0C1E1E
+        AA925050D0FBAFAFEFFFC2C2F4FF7E7EEFFF2727BDBA00004310252581002929
+        6F2D2020A9C96161E3FF4646CFFC191994981C1C58101E1E6D00121291000A0A
+        800D1E1EAF926060D8FB8383EAFF3333C7CE080898321919C1004D4D37001818
+        94002727752D1B1B9FAF1B1B938B202056112020680000000000000000000E0E
+        95000606870E2020B4872525BCB20C0C95321C1CD30000003A00000000005252
+        1F0097970000333349092E2E44052F2F4F000000000000000000000000000000
+        000000008000000077050000780A000000000000340000000000
+      }
+      InnerMargin = 0
+      OnClick = ButtonNoTexClick
+      ParentColor = False
+      Rounding.RoundX = 3
+      Rounding.RoundY = 3
+      Rounding.RoundOptions = []
+      RoundingDropDown.RoundX = 1
+      RoundingDropDown.RoundY = 1
+      RoundingDropDown.RoundOptions = []
+      TextApplyGlobalOpacity = False
+      MemoryUsage = bmuHigh
+    end
   end
   object ColorDialog1: TColorDialog
     Color = clBlack
@@ -36280,4 +36696,8 @@ object Form1: TForm1
       0000000000000000000000000000
     }
   end
+  object OpenPictureDialog1: TOpenPictureDialog
+    left = 321
+    top = 152
+  end
 end

+ 110 - 10
vectoredit/umain.pas

@@ -6,9 +6,10 @@ interface
 
 uses
   Classes, SysUtils, Types, FileUtil, Forms, Controls, Graphics, Dialogs,
-  ExtCtrls, StdCtrls, Spin, ComCtrls, BGRAVirtualScreen, BCTrackbarUpdown,
-  BCPanel, BGRAImageList, BGRALazPaint, BGRABitmap, BGRABitmapTypes,
-  BGRATransform, BGRALayerOriginal, uvectororiginal;
+  ExtCtrls, StdCtrls, Spin, ComCtrls, ExtDlgs, BGRAVirtualScreen,
+  BCTrackbarUpdown, BCPanel, BGRAImageList, BCButton, BGRALazPaint, BGRABitmap,
+  BGRABitmapTypes, BGRATransform, BGRALayerOriginal, BGRAGraphics,
+  uvectororiginal;
 
 const
   EditorPointSize = 8;
@@ -30,6 +31,8 @@ type
   { TForm1 }
 
   TForm1 = class(TForm)
+    ButtonLoadTex: TBCButton;
+    ButtonNoTex: TBCButton;
     BCPanelToolChoice: TBCPanel;
     BCPanelToolbar: TBCPanel;
     BGRAImageList1: TBGRAImageList;
@@ -38,8 +41,10 @@ type
     ColorDialog1: TColorDialog;
     ComboBoxPenStyle: TComboBox;
     FloatSpinEditPenWidth: TFloatSpinEdit;
+    BackImage: TImage;
     Label1: TLabel;
     Label3: TLabel;
+    OpenPictureDialog1: TOpenPictureDialog;
     ShapeBackColor: TShape;
     ShapePenColor: TShape;
     ToolBar1: TToolBar;
@@ -52,6 +57,7 @@ type
     ToolButtonEllipse: TToolButton;
     UpDownPenAlpha: TBCTrackbarUpdown;
     UpDownBackAlpha: TBCTrackbarUpdown;
+    procedure BackImageClick(Sender: TObject);
     procedure BGRAVirtualScreen1MouseDown(Sender: TObject;
       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
     procedure BGRAVirtualScreen1MouseMove(Sender: TObject; Shift: TShiftState;
@@ -59,21 +65,24 @@ type
     procedure BGRAVirtualScreen1MouseUp(Sender: TObject; Button: TMouseButton;
       Shift: TShiftState; X, Y: Integer);
     procedure BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
+    procedure ButtonLoadTexClick(Sender: TObject);
+    procedure ButtonNoTexClick(Sender: TObject);
     procedure CheckBoxBackChange(Sender: TObject);
     procedure ComboBoxPenStyleChange(Sender: TObject);
     procedure FloatSpinEditPenWidthChange(Sender: TObject);
     procedure FormCreate(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
-    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
-    procedure ShapeBackColorMouseUp(Sender: TObject; Button: TMouseButton;
-      Shift: TShiftState; X, Y: Integer);
-    procedure ShapePenColorMouseUp(Sender: TObject; Button: TMouseButton;
-      Shift: TShiftState; X, Y: Integer);
+    procedure FormKeyDown(Sender: TObject; var Key: Word; {%H-}Shift: TShiftState);
+    procedure ShapeBackColorMouseUp(Sender: TObject; {%H-}Button: TMouseButton;
+      {%H-}Shift: TShiftState; X, Y: Integer);
+    procedure ShapePenColorMouseUp(Sender: TObject; {%H-}Button: TMouseButton;
+      {%H-}Shift: TShiftState; X, Y: Integer);
     procedure ToolButtonClick(Sender: TObject);
     procedure UpDownBackAlphaChange(Sender: TObject; AByUser: boolean);
     procedure UpDownPenAlphaChange(Sender: TObject; AByUser: boolean);
   private
     FPenColor, FBackColor: TBGRAPixel;
+    FBackTexture: TBGRABitmap;
     FPenWidth: single;
     FPenStyle: TBGRAPenStyle;
     FFlattened: TBGRABitmap;
@@ -86,6 +95,7 @@ type
     FUpdatingComboboxSplineStyle : boolean;
     procedure ComboBoxSplineStyleChange(Sender: TObject);
     function GetBackColor: TBGRAPixel;
+    function GetBackTexture: TBGRABitmap;
     function GetPenColor: TBGRAPixel;
     function GetPenStyle: TBGRAPenStyle;
     function GetPenWidth: single;
@@ -96,6 +106,7 @@ type
     procedure OnOriginalChange({%H-}ASender: TObject; AOriginal: TBGRALayerCustomOriginal);
     procedure OnSelectShape(ASender: TObject; AShape: TVectorShape; APreviousShape: TVectorShape);
     procedure SetBackColor(AValue: TBGRAPixel);
+    procedure SetBackTexture(AValue: TBGRABitmap);
     procedure SetCurrentTool(AValue: TPaintTool);
     procedure SetPenColor(AValue: TBGRAPixel);
     procedure SetPenStyle(AValue: TBGRAPenStyle);
@@ -122,6 +133,7 @@ type
     property vectorTransform: TAffineMatrix read GetVectorTransform;
     property penColor: TBGRAPixel read GetPenColor write SetPenColor;
     property backColor: TBGRAPixel read GetBackColor write SetBackColor;
+    property backTexture: TBGRABitmap read GetBackTexture write SetBackTexture;
     property penWidth: single read GetPenWidth write SetPenWidth;
     property penStyle: TBGRAPenStyle read GetPenStyle write SetPenStyle;
     property splineStyle: TSplineStyle read GetSplineStyle write SetSplineStyle;
@@ -133,7 +145,7 @@ var
 
 implementation
 
-uses math, LCLType, BGRAPen;
+uses math, LCLType, BGRAPen, BGRAThumbnail, BGRAGradientScanner;
 
 function IsCreateShapeTool(ATool: TPaintTool): boolean;
 begin
@@ -178,6 +190,27 @@ begin
   FLastEditorBounds := img.DrawEditor(Bitmap, vectorLayer, zoom, EditorPointSize);
 end;
 
+procedure TForm1.ButtonLoadTexClick(Sender: TObject);
+var
+  newTex: TBGRABitmap;
+begin
+  if OpenPictureDialog1.Execute then
+  begin
+    try
+      newTex := TBGRABitmap.Create(OpenPictureDialog1.FileName, true);
+      backTexture := newTex;
+    except
+      on ex: exception do
+        ShowMessage(ex.Message);
+    end;
+  end;
+end;
+
+procedure TForm1.ButtonNoTexClick(Sender: TObject);
+begin
+  backTexture := nil;
+end;
+
 procedure TForm1.CheckBoxBackChange(Sender: TObject);
 begin
   if not CheckBoxBack.Checked and (FBackColor.alpha > 0) then
@@ -228,6 +261,21 @@ begin
   end;
 end;
 
+procedure TForm1.BackImageClick(Sender: TObject);
+var
+  texId: Integer;
+begin
+  if Assigned(vectorOriginal) and Assigned(vectorOriginal.SelectedShape) then
+  begin
+    texId:= vectorOriginal.AddTexture(backTexture);
+    if vectorOriginal.SelectedShape.BackTexture = texId then
+      vectorOriginal.SelectedShape.BackTexture := EmptyTextureId
+    else
+      vectorOriginal.SelectedShape.BackTexture := texId;
+    vectorOriginal.RemoveUnusedTextures;
+  end;
+end;
+
 procedure TForm1.BGRAVirtualScreen1MouseMove(Sender: TObject;
   Shift: TShiftState; X, Y: Integer);
 var
@@ -301,6 +349,7 @@ procedure TForm1.FormDestroy(Sender: TObject);
 begin
   img.Free;
   FFlattened.Free;
+  FBackTexture.Free;
 end;
 
 procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
@@ -396,6 +445,11 @@ begin
   result := FBackColor;
 end;
 
+function TForm1.GetBackTexture: TBGRABitmap;
+begin
+  result := FBackTexture;
+end;
+
 function TForm1.GetPenColor: TBGRAPixel;
 begin
   result := FPenColor;
@@ -487,6 +541,44 @@ begin
   end;
 end;
 
+procedure TForm1.SetBackTexture(AValue: TBGRABitmap);
+var
+  thumb: TBGRABitmap;
+  bmpThumb: TBitmap;
+begin
+  if Assigned(AValue) and Assigned(FBackTexture) and AValue.Equals(FBackTexture) then exit;
+  if AValue = FBackTexture then exit;
+  FreeAndNil(FBackTexture);
+  FBackTexture := AValue;
+  if Assigned(FBackTexture) then
+  begin
+    thumb := GetBitmapThumbnail(FBackTexture, BackImage.Width,BackImage.Height,BGRAPixelTransparent,true);
+    try
+      bmpThumb := thumb.MakeBitmapCopy(clBtnFace);
+      try
+        BackImage.Picture.Assign(bmpThumb);
+      finally
+        bmpThumb.Free;
+      end;
+    finally
+      thumb.Free;
+    end;
+    BackImage.Visible := true;
+  end else
+  begin
+    BackImage.Picture.Clear;
+    BackImage.Visible := false;
+  end;
+  if not FUpdatingFromShape and Assigned(vectorOriginal) then
+  begin
+    if Assigned(vectorOriginal.SelectedShape) then
+    begin
+      vectorOriginal.SelectedShape.BackTexture := vectorOriginal.AddTexture(FBackTexture);
+      vectorOriginal.RemoveUnusedTextures;
+    end;
+  end;
+end;
+
 procedure TForm1.SetCurrentTool(AValue: TPaintTool);
 begin
   if FCurrentTool=AValue then Exit;
@@ -676,6 +768,11 @@ begin
     if vsfPenWidth in f then penWidth:= AShape.PenWidth;
     if vsfPenStyle in f then penStyle:= AShape.PenStyle;
     if vsfBackColor in f then backColor := AShape.BackColor;
+    if vsfBackTexture in f then
+    begin
+      if AShape.BackTexture <> EmptyTextureId then
+        backTexture := vectorOriginal.GetTexture(AShape.BackTexture).Duplicate as TBGRABitmap;
+    end;
     if AShape is TCurveShape then
     begin
       showSplineStyle:= true;
@@ -683,6 +780,7 @@ begin
     end else
       showSplineStyle:= false;
     FUpdatingFromShape := false;
+    BackImage.Cursor:= crHandPoint;
   end else
   begin
     if IsCreateShapeTool(currentTool) then
@@ -695,6 +793,7 @@ begin
       f := [];
       showSplineStyle:= false;
     end;
+    BackImage.Cursor:= crDefault;
   end;
   FloatSpinEditPenWidth.Enabled := vsfPenWidth in f;
   ComboBoxPenStyle.Enabled:= vsfPenStyle in f;
@@ -720,9 +819,10 @@ function TForm1.CreateShape(const APoint1,APoint2: TPointF): TVectorShape;
 begin
   if not IsCreateShapeTool(currentTool) then
     raise exception.Create('No shape type selected');
-  result := PaintToolClass[currentTool].Create;
+  result := PaintToolClass[currentTool].Create(vectorOriginal);
   result.PenColor := penColor;
   result.BackColor := backColor;
+  if vsfBackTexture in Result.Fields then result.BackTexture := vectorOriginal.AddTexture(backTexture);
   result.PenWidth := penWidth;
   result.PenStyle := penStyle;
   if currentTool in[ptClosedCurve,ptPolygon] then

+ 311 - 57
vectoredit/uvectororiginal.pas

@@ -10,12 +10,15 @@ uses
 
 const
   InfiniteRect : TRect = (Left: -MaxLongInt; Top: -MaxLongInt; Right: MaxLongInt; Bottom: MaxLongInt);
+  EmptyTextureId = 0;
 
 type
+  TVectorOriginal = class;
+
   TShapeChangeEvent = procedure(ASender: TObject; ABounds: TRectF) of object;
   TShapeEditingChangeEvent = procedure(ASender: TObject) of object;
 
-  TVectorShapeField = (vsfPenColor, vsfPenWidth, vsfPenStyle, vsfJoinStyle, vsfBackColor);
+  TVectorShapeField = (vsfPenColor, vsfPenWidth, vsfPenStyle, vsfJoinStyle, vsfBackColor, vsfBackTexture);
   TVectorShapeFields = set of TVectorShapeField;
   TVectorShapeUsermode = (vsuEdit, vsuCreate);
   TVectorShapeUsermodes = set of TVectorShapeUsermode;
@@ -29,9 +32,12 @@ type
     FUpdateCount: integer;
     FBoundsBeforeUpdate: TRectF;
     FPenColor,FBackColor: TBGRAPixel;
+    FBackTexture: integer;
     FPenWidth: single;
     FStroker: TBGRAPenStroker;
     FUsermode: TVectorShapeUsermode;
+    FContainer: TVectorOriginal;
+    procedure SetContainer(AValue: TVectorOriginal);
   protected
     procedure BeginUpdate;
     procedure EndUpdate;
@@ -40,17 +46,19 @@ type
     function GetPenStyle: TBGRAPenStyle; virtual;
     function GetJoinStyle: TPenJoinStyle;
     function GetBackColor: TBGRAPixel; virtual;
+    function GetBackTexture: integer; virtual;
     procedure SetPenColor(AValue: TBGRAPixel); virtual;
     procedure SetPenWidth(AValue: single); virtual;
     procedure SetPenStyle({%H-}AValue: TBGRAPenStyle); virtual;
     procedure SetJoinStyle(AValue: TPenJoinStyle);
     procedure SetBackColor(AValue: TBGRAPixel); virtual;
+    procedure SetBackTexture(AValue: integer); virtual;
     procedure SetUsermode(AValue: TVectorShapeUsermode); virtual;
     function ComputeStroke(APoints: ArrayOfTPointF; AClosed: boolean; AStrokeMatrix: TAffineMatrix): ArrayOfTPointF;
     function GetStroker: TBGRAPenStroker;
     property Stroker: TBGRAPenStroker read GetStroker;
   public
-    constructor Create;
+    constructor Create(AContainer: TVectorOriginal);
     destructor Destroy; override;
     procedure QuickDefine(const APoint1,APoint2: TPointF); virtual; abstract;
     procedure Render(ADest: TBGRABitmap; AMatrix: TAffineMatrix; ADraft: boolean); virtual; abstract;
@@ -59,9 +67,9 @@ type
     procedure ConfigureEditor(AEditor: TBGRAOriginalEditor); virtual; abstract;
     procedure LoadFromStorage(AStorage: TBGRACustomOriginalStorage); virtual;
     procedure SaveToStorage(AStorage: TBGRACustomOriginalStorage); virtual;
-    procedure MouseMove(Shift: TShiftState; X, Y: single; out ACursor: TOriginalEditorCursor; out AHandled: boolean); virtual;
-    procedure MouseDown(RightButton: boolean; Shift: TShiftState; X, Y: single; out ACursor: TOriginalEditorCursor; out AHandled: boolean); virtual;
-    procedure MouseUp(RightButton: boolean; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: single; out ACursor: TOriginalEditorCursor; out AHandled: boolean); virtual;
+    procedure MouseMove({%H-}Shift: TShiftState; {%H-}X, {%H-}Y: single; var {%H-}ACursor: TOriginalEditorCursor; var {%H-}AHandled: boolean); virtual;
+    procedure MouseDown({%H-}RightButton: boolean; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: single; var {%H-}ACursor: TOriginalEditorCursor; var {%H-}AHandled: boolean); virtual;
+    procedure MouseUp({%H-}RightButton: boolean; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: single; var {%H-}ACursor: TOriginalEditorCursor; var {%H-}AHandled: boolean); virtual;
     class function StorageClassName: RawByteString; virtual; abstract;
     function GetIsSlow({%H-}AMatrix: TAffineMatrix): boolean; virtual;
     class function Fields: TVectorShapeFields; virtual;
@@ -70,10 +78,12 @@ type
     property OnEditingChange: TShapeEditingChangeEvent read FOnEditingChange write FOnEditingChange;
     property PenColor: TBGRAPixel read GetPenColor write SetPenColor;
     property BackColor: TBGRAPixel read GetBackColor write SetBackColor;
+    property BackTexture: integer read GetBackTexture write SetBackTexture;
     property PenWidth: single read GetPenWidth write SetPenWidth;
     property PenStyle: TBGRAPenStyle read GetPenStyle write SetPenStyle;
     property JoinStyle: TPenJoinStyle read GetJoinStyle write SetJoinStyle;
     property Usermode: TVectorShapeUsermode read FUsermode write SetUsermode;
+    property Container: TVectorOriginal read FContainer write SetContainer;
   end;
   TVectorShapes = specialize TFPGList<TVectorShape>;
   TVectorShapeAny = class of TVectorShape;
@@ -134,7 +144,7 @@ type
     function BackVisible: boolean;
     function GetCornerPositition: single; override;
   public
-    constructor Create;
+    constructor Create(AContainer: TVectorOriginal);
     class function Fields: TVectorShapeFields; override;
     procedure Render(ADest: TBGRABitmap; AMatrix: TAffineMatrix; ADraft: boolean); override;
     function GetRenderBounds({%H-}ADestRect: TRect; AMatrix: TAffineMatrix): TRectF; override;
@@ -170,10 +180,10 @@ type
     procedure SetClosed(AValue: boolean); virtual;
     function PointsEqual(const APoint1, APoint2: TPointF): boolean;
   public
-    constructor Create;
+    constructor Create(AContainer: TVectorOriginal);
     procedure AddPoint(const APoint: TPointF);
-    procedure MouseMove(Shift: TShiftState; X, Y: single; out ACursor: TOriginalEditorCursor; out AHandled: boolean); override;
-    procedure MouseDown(RightButton: boolean; Shift: TShiftState; X, Y: single; out ACursor: TOriginalEditorCursor; out AHandled: boolean); override;
+    procedure MouseMove({%H-}Shift: TShiftState; X, Y: single; var {%H-}ACursor: TOriginalEditorCursor; var AHandled: boolean); override;
+    procedure MouseDown(RightButton: boolean; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: single; var {%H-}ACursor: TOriginalEditorCursor; var AHandled: boolean); override;
     procedure QuickDefine(const APoint1,APoint2: TPointF); override;
     procedure LoadFromStorage(AStorage: TBGRACustomOriginalStorage); override;
     procedure SaveToStorage(AStorage: TBGRACustomOriginalStorage); override;
@@ -209,7 +219,7 @@ type
   protected
     function GetCurve(AMatrix: TAffineMatrix): ArrayOfTPointF; override;
   public
-    constructor Create;
+    constructor Create(AContainer: TVectorOriginal);
     class function StorageClassName: RawByteString; override;
     property SplineStyle: TSplineStyle read FSplineStyle write SetSplineStyle;
   end;
@@ -230,14 +240,26 @@ type
     FFrozenShapesComputed: boolean;
     FFrozenShapeMatrix: TAffineMatrix;
     FOnSelectShape: TVectorOriginalSelectShapeEvent;
+    FTextures: array of record
+                 Bitmap: TBGRABitmap;
+                 Id, Counter: integer;
+               end;
+    FTextureCount: integer;
+    FLastTextureId: integer;
     procedure FreeDeletedShapes;
     procedure OnShapeChange(ASender: TObject; ABounds: TRectF);
-    procedure OnShapeEditingChange(ASender: TObject);
+    procedure OnShapeEditingChange({%H-}ASender: TObject);
     procedure DiscardFrozenShapes;
+    function GetTextureId(ABitmap: TBGRABitmap): integer;
+    function IndexOfTexture(AId: integer): integer;
+    procedure AddTextureWithId(ATexture: TBGRABitmap; AId: integer);
   public
     constructor Create; override;
     destructor Destroy; override;
     procedure Clear;
+    function AddTexture(ATexture: TBGRABitmap): integer;
+    function GetTexture(AId: integer): TBGRABitmap;
+    procedure RemoveUnusedTextures;
     function AddShape(AShape: TVectorShape): integer; overload;
     function AddShape(AShape: TVectorShape; AUsermode: TVectorShapeUsermode): integer; overload;
     function RemoveShape(AShape: TVectorShape): boolean;
@@ -326,9 +348,9 @@ begin
   else result := ComputeOpenedSpline(pts, FSplineStyle);
 end;
 
-constructor TCurveShape.Create;
+constructor TCurveShape.Create(AContainer: TVectorOriginal);
 begin
-  inherited Create;
+  inherited Create(AContainer);
   FSplineStyle:= ssEasyBezier;
 end;
 
@@ -380,12 +402,13 @@ end;
 
 function TPolylineShape.BackVisible: boolean;
 begin
-  result := BackColor.alpha <> 0;
+  result := ((BackTexture = EmptyTextureId) and (BackColor.alpha <> 0)) or
+            ((BackTexture <> EmptyTextureId) and Assigned(Container));
 end;
 
 class function TPolylineShape.Fields: TVectorShapeFields;
 begin
-  Result:= [vsfPenColor, vsfPenWidth, vsfPenStyle, vsfJoinStyle, vsfBackColor];
+  Result:= [vsfPenColor, vsfPenWidth, vsfPenStyle, vsfJoinStyle, vsfBackColor, vsfBackTexture];
 end;
 
 procedure TPolylineShape.Render(ADest: TBGRABitmap; AMatrix: TAffineMatrix;
@@ -398,9 +421,17 @@ begin
   if BackVisible then
   begin
     if ADraft then
-      ADest.FillPoly(pts, BackColor, dmDrawWithTransparency)
+    begin
+      if BackTexture <> EmptyTextureId then
+        ADest.FillPoly(pts, Container.GetTexture(BackTexture), dmDrawWithTransparency) else
+        ADest.FillPoly(pts, BackColor, dmDrawWithTransparency);
+    end
     else
-      ADest.FillPolyAntialias(pts, BackColor);
+    begin
+      if BackTexture <> EmptyTextureId then
+        ADest.FillPolyAntialias(pts, Container.GetTexture(BackTexture)) else
+        ADest.FillPolyAntialias(pts, BackColor);
+    end;
   end;
   if PenVisible then
   begin
@@ -606,9 +637,9 @@ begin
     exit((APoint1.x = APoint2.x) and (APoint1.y = APoint2.y));
 end;
 
-constructor TCustomPolypointShape.Create;
+constructor TCustomPolypointShape.Create(AContainer: TVectorOriginal);
 begin
-  inherited Create;
+  inherited Create(AContainer);
   FMousePos := EmptyPointF;
   FClosed:= false;
 end;
@@ -618,8 +649,8 @@ begin
   Points[PointCount] := APoint;
 end;
 
-procedure TCustomPolypointShape.MouseMove(Shift: TShiftState; X, Y: single; out
-  ACursor: TOriginalEditorCursor; out AHandled: boolean);
+procedure TCustomPolypointShape.MouseMove(Shift: TShiftState; X, Y: single; var
+  ACursor: TOriginalEditorCursor; var AHandled: boolean);
 begin
   FMousePos := PointF(X,Y);
   if FAddingPoint then
@@ -627,11 +658,12 @@ begin
     BeginUpdate;
     FPoints[high(FPoints)].coord := FMousePos;
     EndUpdate;
+    AHandled:= true;
   end;
 end;
 
 procedure TCustomPolypointShape.MouseDown(RightButton: boolean;
-  Shift: TShiftState; X, Y: single; out ACursor: TOriginalEditorCursor; out
+  Shift: TShiftState; X, Y: single; var ACursor: TOriginalEditorCursor; var
   AHandled: boolean);
 begin
   if FAddingPoint then
@@ -763,7 +795,8 @@ end;
 
 function TEllipseShape.BackVisible: boolean;
 begin
-  result := BackColor.alpha <> 0;
+  result := ((BackTexture = EmptyTextureId) and (BackColor.alpha <> 0)) or
+            ((BackTexture <> EmptyTextureId) and Assigned(Container));
 end;
 
 function TEllipseShape.GetCornerPositition: single;
@@ -771,15 +804,15 @@ begin
   result := sqrt(2)/2;
 end;
 
-constructor TEllipseShape.Create;
+constructor TEllipseShape.Create(AContainer: TVectorOriginal);
 begin
-  inherited Create;
+  inherited Create(AContainer);
   inherited SetJoinStyle(pjsRound);
 end;
 
 class function TEllipseShape.Fields: TVectorShapeFields;
 begin
-  Result:= [vsfPenColor, vsfPenWidth, vsfPenStyle, vsfBackColor];
+  Result:= [vsfPenColor, vsfPenWidth, vsfPenStyle, vsfBackColor, vsfBackTexture];
 end;
 
 procedure TEllipseShape.Render(ADest: TBGRABitmap; AMatrix: TAffineMatrix;
@@ -789,6 +822,7 @@ var
   orthoRect: TRectF;
   center, radius: TPointF;
   draftPen, isOrtho: Boolean;
+  r: TRect;
 begin
   isOrtho := GetOrthoRect(AMatrix, orthoRect);
   if isOrtho then
@@ -798,10 +832,18 @@ begin
     If BackVisible then
     begin
       if ADraft then
-        ADest.FillEllipseInRect(rect(round(orthoRect.Left),round(orthoRect.Top),round(orthoRect.Right),round(orthoRect.Bottom)),
-                                BackColor, dmDrawWithTransparency)
+      begin
+        r := rect(round(orthoRect.Left),round(orthoRect.Top),round(orthoRect.Right),round(orthoRect.Bottom));
+        if BackTexture <> EmptyTextureId then
+          ADest.FillEllipseInRect(r, Container.GetTexture(BackTexture), dmDrawWithTransparency) else
+          ADest.FillEllipseInRect(r, BackColor, dmDrawWithTransparency)
+      end
       else
-        ADest.FillEllipseAntialias(center.x, center.y, radius.x, radius.y, BackColor);
+      begin
+        if BackTexture <> EmptyTextureId then
+          ADest.FillEllipseAntialias(center.x, center.y, radius.x, radius.y, Container.GetTexture(BackTexture)) else
+          ADest.FillEllipseAntialias(center.x, center.y, radius.x, radius.y, BackColor);
+       end;
     end;
     if PenVisible then
     begin
@@ -830,9 +872,17 @@ begin
     If BackVisible then
     begin
       if ADraft then
-        ADest.FillPoly(pts, BackColor, dmDrawWithTransparency)
+      begin
+        if BackTexture <> EmptyTextureId then
+          ADest.FillPoly(pts, Container.GetTexture(BackTexture), dmDrawWithTransparency) else
+          ADest.FillPoly(pts, BackColor, dmDrawWithTransparency)
+      end
       else
-        ADest.FillPolyAntialias(pts, BackColor);
+      begin
+        if BackTexture <> EmptyTextureId then
+          ADest.FillPolyAntialias(pts, Container.GetTexture(BackTexture)) else
+          ADest.FillPolyAntialias(pts, BackColor)
+      end;
     end;
     if PenVisible then
     begin
@@ -1172,7 +1222,6 @@ begin
   u := FXAxis - FOrigin;
   v := FYAxis - FOrigin;
   AEditor.AddStartMoveHandler(@OnStartMove);
-  AEditor.AddPoint(FOrigin, @OnMoveOrigin, true);
   AEditor.AddArrow(FOrigin, FXAxis, @OnMoveXAxis);
   AEditor.AddArrow(FOrigin, FYAxis, @OnMoveYAxis);
   AEditor.AddArrow(FOrigin, FOrigin - u, @OnMoveXAxisNeg);
@@ -1185,6 +1234,7 @@ begin
     AEditor.AddPoint(FOrigin + (u-v)*d, @OnMoveXYNegCorner, false);
     AEditor.AddPoint(FOrigin + (-u-v)*d, @OnMoveXNegYNegCorner, false);
   end;
+  AEditor.AddPoint(FOrigin, @OnMoveOrigin, true);
 end;
 
 { TRectShape }
@@ -1196,7 +1246,8 @@ end;
 
 function TRectShape.BackVisible: boolean;
 begin
-  result := BackColor.alpha <> 0;
+  result := ((BackTexture = EmptyTextureId) and (BackColor.alpha <> 0)) or
+            ((BackTexture <> EmptyTextureId) and Assigned(Container));
 end;
 
 function TRectShape.GetCornerPositition: single;
@@ -1230,7 +1281,7 @@ end;
 
 class function TRectShape.Fields: TVectorShapeFields;
 begin
-  Result:= [vsfPenColor, vsfPenWidth, vsfPenStyle, vsfJoinStyle, vsfBackColor];
+  Result:= [vsfPenColor, vsfPenWidth, vsfPenStyle, vsfJoinStyle, vsfBackColor, vsfBackTexture];
 end;
 
 procedure TRectShape.Render(ADest: TBGRABitmap; AMatrix: TAffineMatrix;
@@ -1238,6 +1289,7 @@ procedure TRectShape.Render(ADest: TBGRABitmap; AMatrix: TAffineMatrix;
 var
   pts: Array of TPointF;
   orthoRect: TRectF;
+  r: TRect;
 begin
   pts := GetAffineBox(AMatrix, true).AsPolygon;
   If BackVisible then
@@ -1245,15 +1297,32 @@ begin
     if GetOrthoRect(AMatrix, orthoRect) then
     begin
       if ADraft then
-        ADest.FillRect(round(orthoRect.Left),round(orthoRect.Top),round(orthoRect.Right),round(orthoRect.Bottom), BackColor, dmDrawWithTransparency)
+      begin
+        r:= rect(round(orthoRect.Left),round(orthoRect.Top),round(orthoRect.Right),round(orthoRect.Bottom));
+        if BackTexture <> EmptyTextureId then
+          ADest.FillRect(r, Container.GetTexture(BackTexture), dmDrawWithTransparency) else
+          ADest.FillRect(r, BackColor, dmDrawWithTransparency)
+      end
       else
-        ADest.FillRectAntialias(orthoRect, BackColor);
+      begin
+        if BackTexture <> EmptyTextureId then
+          ADest.FillRectAntialias(orthoRect, Container.GetTexture(BackTexture)) else
+          ADest.FillRectAntialias(orthoRect, BackColor);
+      end;
     end else
     begin
       if ADraft then
-        ADest.FillPoly(pts, BackColor, dmDrawWithTransparency)
+      begin
+        if BackTexture <> EmptyTextureId then
+          ADest.FillPoly(pts, Container.GetTexture(BackTexture), dmDrawWithTransparency) else
+          ADest.FillPoly(pts, BackColor, dmDrawWithTransparency)
+      end
       else
-        ADest.FillPolyAntialias(pts, BackColor);
+      begin
+        if BackTexture <> EmptyTextureId then
+          ADest.FillPolyAntialias(pts, Container.GetTexture(BackTexture)) else
+          ADest.FillPolyAntialias(pts, BackColor);
+      end;
     end;
   end;
   if PenVisible then
@@ -1359,6 +1428,26 @@ begin
   result := [vsuEdit];
 end;
 
+function TVectorShape.GetBackTexture: integer;
+begin
+  result := FBackTexture;
+end;
+
+procedure TVectorShape.SetBackTexture(AValue: integer);
+begin
+  if FBackTexture = AValue then exit;
+  BeginUpdate;
+  FBackTexture := AValue;
+  EndUpdate;
+end;
+
+procedure TVectorShape.SetContainer(AValue: TVectorOriginal);
+begin
+  if FContainer=AValue then Exit;
+  if Assigned(FContainer) then raise exception.Create('Container already assigned');
+  FContainer:=AValue;
+end;
+
 procedure TVectorShape.BeginUpdate;
 begin
   if FUpdateCount = 0 then
@@ -1453,8 +1542,9 @@ begin
   EndUpdate;
 end;
 
-constructor TVectorShape.Create;
+constructor TVectorShape.Create(AContainer: TVectorOriginal);
 begin
+  FContainer := AContainer;
   FPenColor := BGRAPixelTransparent;
   FPenWidth := 1;
   FBackColor := BGRAPixelTransparent;
@@ -1509,20 +1599,20 @@ begin
   if vsfBackColor in f then AStorage.Color['back-color'] := BackColor;
 end;
 
-procedure TVectorShape.MouseMove(Shift: TShiftState; X, Y: single; out
-  ACursor: TOriginalEditorCursor; out AHandled: boolean);
+procedure TVectorShape.MouseMove(Shift: TShiftState; X, Y: single; var
+  ACursor: TOriginalEditorCursor; var AHandled: boolean);
 begin
   //nothing
 end;
 
 procedure TVectorShape.MouseDown(RightButton: boolean; Shift: TShiftState; X,
-  Y: single; out ACursor: TOriginalEditorCursor; out AHandled: boolean);
+  Y: single; var ACursor: TOriginalEditorCursor; var AHandled: boolean);
 begin
   //nothing
 end;
 
 procedure TVectorShape.MouseUp(RightButton: boolean; Shift: TShiftState; X,
-  Y: single; out ACursor: TOriginalEditorCursor; out AHandled: boolean);
+  Y: single; var ACursor: TOriginalEditorCursor; var AHandled: boolean);
 begin
   //nothing
 end;
@@ -1556,6 +1646,36 @@ begin
   FreeAndNil(FFrozenShapesOverSelection);
 end;
 
+function TVectorOriginal.GetTextureId(ABitmap: TBGRABitmap): integer;
+var
+  i: Integer;
+begin
+  if (ABitmap = nil) or (ABitmap.NbPixels = 0) then exit(EmptyTextureId);
+  for i := 0 to FTextureCount-1 do
+    if FTextures[i].Bitmap.Equals(ABitmap) then exit(FTextures[i].Id);
+  exit(-1);
+end;
+
+function TVectorOriginal.IndexOfTexture(AId: integer): integer;
+var
+  i: Integer;
+begin
+  if AId = EmptyTextureId then exit(-1);
+  for i := 0 to FTextureCount-1 do
+    if FTextures[i].Id = AId then exit(i);
+  exit(-1);
+end;
+
+procedure TVectorOriginal.AddTextureWithId(ATexture: TBGRABitmap; AId: integer);
+begin
+  if FTextureCount >= length(FTextures) then
+    setlength(FTextures, FTextureCount*2+2);
+  if AId > FLastTextureId then FLastTextureId:= AId;
+  FTextures[FTextureCount].Bitmap := ATexture.Duplicate as TBGRABitmap;
+  FTextures[FTextureCount].Id := AId;
+  inc(FTextureCount);
+end;
+
 constructor TVectorOriginal.Create;
 begin
   inherited Create;
@@ -1565,6 +1685,7 @@ begin
   FFrozenShapesUnderSelection := nil;
   FFrozenShapesOverSelection := nil;
   FFrozenShapesComputed:= false;
+  FLastTextureId:= EmptyTextureId;
 end;
 
 destructor TVectorOriginal.Destroy;
@@ -1586,12 +1707,68 @@ begin
     for i := 0 to FShapes.Count-1 do
       FDeletedShapes.Add(FShapes[i]);
     FShapes.Clear;
+    for i := 0 to FTextureCount-1 do
+      FreeAndNil(FTextures[i].Bitmap);
+    FTextureCount := 0;
+    FTextures := nil;
+    FLastTextureId:= EmptyTextureId;
     NotifyChange;
   end;
 end;
 
+function TVectorOriginal.AddTexture(ATexture: TBGRABitmap): integer;
+begin
+  result := GetTextureId(ATexture);
+  if result <> -1 then exit;
+  result:= FLastTextureId+1;
+  AddTextureWithId(ATexture, result);
+end;
+
+function TVectorOriginal.GetTexture(AId: integer): TBGRABitmap;
+var
+  index: Integer;
+begin
+  index := IndexOfTexture(AId);
+  if index = -1 then
+    result := nil
+  else
+    result := FTextures[index].Bitmap;
+end;
+
+procedure TVectorOriginal.RemoveUnusedTextures;
+var
+  i, j: Integer;
+  f: TVectorShapeFields;
+begin
+  for i := 0 to FTextureCount-1 do
+    FTextures[i].Counter:= 0;
+  for i := 0 to FShapes.Count-1 do
+  begin
+    f:= FShapes[i].Fields;
+    if (vsfBackTexture in f) and (FShapes[i].BackTexture<>0) then
+      inc(FTextures[IndexOfTexture(FShapes[i].BackTexture)].Counter);
+  end;
+  for i := FTextureCount-1 downto 0 do
+    if FTextures[i].Counter = 0 then
+    begin
+      FreeAndNil(FTextures[i].Bitmap);
+      for j := i to FTextureCount-2 do
+        FTextures[j] := FTextures[j+1];
+      dec(FTextureCount);
+    end;
+  if FTextureCount < length(FTextures) div 2 then
+    setlength(FTextures, FTextureCount);
+end;
+
 function TVectorOriginal.AddShape(AShape: TVectorShape): integer;
 begin
+  if AShape.Container <> self then
+  begin
+    if AShape.Container = nil then
+      AShape.Container := self
+    else
+      raise exception.Create('Container mismatch');
+  end;
   result:= FShapes.Add(AShape);
   AShape.OnChange := @OnShapeChange;
   AShape.OnEditingChange := @OnShapeEditingChange;
@@ -1763,28 +1940,56 @@ procedure TVectorOriginal.LoadFromStorage(AStorage: TBGRACustomOriginalStorage);
 var
   nb: LongInt;
   i: Integer;
-  obj: TBGRACustomOriginalStorage;
-  objClassName: String;
+  shapeObj, texObj: TBGRACustomOriginalStorage;
+  objClassName, texName: String;
   shapeClass: TVectorShapeAny;
   shape: TVectorShape;
+  idList: array of single;
+  mem: TMemoryStream;
+  texId: integer;
 begin
   Clear;
   nb := AStorage.Int['count'];
   for i:= 0 to nb-1 do
   begin
-    obj := AStorage.OpenObject('shape'+inttostr(i+1));
-    if obj <> nil then
-    begin
-      objClassName := obj.RawString['class'];
+    shapeObj := AStorage.OpenObject('shape'+inttostr(i+1));
+    if shapeObj <> nil then
+    try
+      objClassName := shapeObj.RawString['class'];
       if objClassName = '' then raise exception.Create('Shape class not defined');
       shapeClass:= GetVectorShapeByStorageClassName(objClassName);
       if shapeClass = nil then raise exception.Create('Unknown shape class "'+objClassName+'"');
-      shape := shapeClass.Create;
-      shape.LoadFromStorage(obj);
+      shape := shapeClass.Create(self);
+      shape.LoadFromStorage(shapeObj);
       shape.OnChange := @OnShapeChange;
       shape.OnEditingChange := @OnShapeEditingChange;
       FShapes.Add(shape);
-      obj.Free;
+    finally
+      shapeObj.Free;
+    end;
+  end;
+  texObj := AStorage.OpenObject('textures');
+  if Assigned(texObj) then
+  begin
+    try
+      idList := texObj.FloatArray['id'];
+      for i := 0 to high(idList) do
+      begin
+        texId:= round(idList[i]);
+        texName:= 'tex'+inttostr(texId);
+        mem := TMemoryStream.Create;
+        try
+          if not texObj.ReadFile(texName+'.png', mem) and
+             not texObj.ReadFile(texName+'.jpg', mem) then
+             raise exception.Create('Unable to find texture');
+          mem.Position:= 0;
+          AddTextureWithId(TBGRABitmap.Create(mem), texId);
+        finally
+          mem.Free;
+        end;
+      end;
+    finally
+      texObj.Free;
     end;
   end;
   NotifyChange;
@@ -1793,8 +1998,12 @@ end;
 procedure TVectorOriginal.SaveToStorage(AStorage: TBGRACustomOriginalStorage);
 var
   nb: LongInt;
-  i: Integer;
-  obj: TBGRACustomOriginalStorage;
+  i, texIndex: Integer;
+  shapeObj, texObj: TBGRACustomOriginalStorage;
+  idList: array of single;
+  texName: String;
+  mem: TMemoryStream;
+  texId: integer;
 begin
   nb := AStorage.Int['count'];
   for i := 0 to nb-1 do AStorage.RemoveObject('shape'+inttostr(i+1));
@@ -1802,12 +2011,57 @@ begin
 
   for i := 0 to FShapes.Count-1 do
   begin
-    obj := AStorage.CreateObject('shape'+inttostr(i+1));
+    shapeObj := AStorage.CreateObject('shape'+inttostr(i+1));
     try
-      FShapes[i].SaveToStorage(obj);
+      FShapes[i].SaveToStorage(shapeObj);
       AStorage.Int['count'] := i+1;
     finally
-      obj.Free;
+      shapeObj.Free;
+    end;
+  end;
+
+  RemoveUnusedTextures;
+  if FTextureCount = 0 then
+    AStorage.RemoveObject('textures')
+  else
+  begin
+    texObj := nil;
+    try
+      texObj := AStorage.OpenObject('textures');
+      if texObj = nil then
+        texObj := AStorage.CreateObject('textures');
+
+      for i := 0 to FTextureCount-1 do
+        FTextures[i].Counter:= 0;
+
+      idList := texObj.FloatArray['id'];
+      for i := 0 to high(idList) do
+      begin
+        texId := round(idList[i]);
+        texIndex:= IndexOfTexture(texId);
+        if texIndex=-1 then
+        begin
+          texName := 'tex'+inttostr(texId);
+          texObj.RemoveFile(texName+'.png');
+          texObj.RemoveFile(texName+'.jpg');
+        end else
+          inc(FTextures[texIndex].Counter);
+      end;
+
+      for i := 0 to FTextureCount-1 do
+        if FTextures[i].Counter = 0 then
+        begin
+          texName := 'tex'+inttostr(FTextures[i].Id);
+          mem := TMemoryStream.Create;
+          try
+            FTextures[i].Bitmap.SaveToStreamAsPng(mem);
+            texObj.WriteFile(texName+'.png', mem, false);
+          finally
+            mem.Free;
+          end;
+        end;
+    finally
+      texObj.Free;
     end;
   end;