fill.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. # Copyright (c) 2010-2024 openpyxl
  2. from openpyxl.descriptors.serialisable import Serialisable
  3. from openpyxl.descriptors import (
  4. Alias,
  5. Bool,
  6. Integer,
  7. Set,
  8. NoneSet,
  9. Typed,
  10. MinMax,
  11. )
  12. from openpyxl.descriptors.excel import (
  13. Relation,
  14. Percentage,
  15. )
  16. from openpyxl.descriptors.nested import NestedNoneSet, NestedValue
  17. from openpyxl.descriptors.sequence import NestedSequence
  18. from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
  19. from openpyxl.xml.constants import DRAWING_NS
  20. from .colors import (
  21. ColorChoice,
  22. HSLColor,
  23. SystemColor,
  24. SchemeColor,
  25. PRESET_COLORS,
  26. RGBPercent,
  27. )
  28. from .effect import (
  29. AlphaBiLevelEffect,
  30. AlphaCeilingEffect,
  31. AlphaFloorEffect,
  32. AlphaInverseEffect,
  33. AlphaModulateEffect,
  34. AlphaModulateFixedEffect,
  35. AlphaReplaceEffect,
  36. BiLevelEffect,
  37. BlurEffect,
  38. ColorChangeEffect,
  39. ColorReplaceEffect,
  40. DuotoneEffect,
  41. FillOverlayEffect,
  42. GrayscaleEffect,
  43. HSLEffect,
  44. LuminanceEffect,
  45. TintEffect,
  46. )
  47. """
  48. Fill elements from drawing main schema
  49. """
  50. class PatternFillProperties(Serialisable):
  51. tagname = "pattFill"
  52. namespace = DRAWING_NS
  53. prst = NoneSet(values=(['pct5', 'pct10', 'pct20', 'pct25', 'pct30',
  54. 'pct40', 'pct50', 'pct60', 'pct70', 'pct75', 'pct80', 'pct90', 'horz',
  55. 'vert', 'ltHorz', 'ltVert', 'dkHorz', 'dkVert', 'narHorz', 'narVert',
  56. 'dashHorz', 'dashVert', 'cross', 'dnDiag', 'upDiag', 'ltDnDiag',
  57. 'ltUpDiag', 'dkDnDiag', 'dkUpDiag', 'wdDnDiag', 'wdUpDiag', 'dashDnDiag',
  58. 'dashUpDiag', 'diagCross', 'smCheck', 'lgCheck', 'smGrid', 'lgGrid',
  59. 'dotGrid', 'smConfetti', 'lgConfetti', 'horzBrick', 'diagBrick',
  60. 'solidDmnd', 'openDmnd', 'dotDmnd', 'plaid', 'sphere', 'weave', 'divot',
  61. 'shingle', 'wave', 'trellis', 'zigZag']))
  62. preset = Alias("prst")
  63. fgClr = Typed(expected_type=ColorChoice, allow_none=True)
  64. foreground = Alias("fgClr")
  65. bgClr = Typed(expected_type=ColorChoice, allow_none=True)
  66. background = Alias("bgClr")
  67. __elements__ = ("fgClr", "bgClr")
  68. def __init__(self,
  69. prst=None,
  70. fgClr=None,
  71. bgClr=None,
  72. ):
  73. self.prst = prst
  74. self.fgClr = fgClr
  75. self.bgClr = bgClr
  76. class RelativeRect(Serialisable):
  77. tagname = "rect"
  78. namespace = DRAWING_NS
  79. l = Percentage(allow_none=True)
  80. left = Alias('l')
  81. t = Percentage(allow_none=True)
  82. top = Alias('t')
  83. r = Percentage(allow_none=True)
  84. right = Alias('r')
  85. b = Percentage(allow_none=True)
  86. bottom = Alias('b')
  87. def __init__(self,
  88. l=None,
  89. t=None,
  90. r=None,
  91. b=None,
  92. ):
  93. self.l = l
  94. self.t = t
  95. self.r = r
  96. self.b = b
  97. class StretchInfoProperties(Serialisable):
  98. tagname = "stretch"
  99. namespace = DRAWING_NS
  100. fillRect = Typed(expected_type=RelativeRect, allow_none=True)
  101. def __init__(self,
  102. fillRect=RelativeRect(),
  103. ):
  104. self.fillRect = fillRect
  105. class GradientStop(Serialisable):
  106. tagname = "gs"
  107. namespace = DRAWING_NS
  108. pos = MinMax(min=0, max=100000, allow_none=True)
  109. # Color Choice Group
  110. scrgbClr = Typed(expected_type=RGBPercent, allow_none=True)
  111. RGBPercent = Alias('scrgbClr')
  112. srgbClr = NestedValue(expected_type=str, allow_none=True) # needs pattern and can have transform
  113. RGB = Alias('srgbClr')
  114. hslClr = Typed(expected_type=HSLColor, allow_none=True)
  115. sysClr = Typed(expected_type=SystemColor, allow_none=True)
  116. schemeClr = Typed(expected_type=SchemeColor, allow_none=True)
  117. prstClr = NestedNoneSet(values=PRESET_COLORS)
  118. __elements__ = ('scrgbClr', 'srgbClr', 'hslClr', 'sysClr', 'schemeClr', 'prstClr')
  119. def __init__(self,
  120. pos=None,
  121. scrgbClr=None,
  122. srgbClr=None,
  123. hslClr=None,
  124. sysClr=None,
  125. schemeClr=None,
  126. prstClr=None,
  127. ):
  128. if pos is None:
  129. pos = 0
  130. self.pos = pos
  131. self.scrgbClr = scrgbClr
  132. self.srgbClr = srgbClr
  133. self.hslClr = hslClr
  134. self.sysClr = sysClr
  135. self.schemeClr = schemeClr
  136. self.prstClr = prstClr
  137. class LinearShadeProperties(Serialisable):
  138. tagname = "lin"
  139. namespace = DRAWING_NS
  140. ang = Integer()
  141. scaled = Bool(allow_none=True)
  142. def __init__(self,
  143. ang=None,
  144. scaled=None,
  145. ):
  146. self.ang = ang
  147. self.scaled = scaled
  148. class PathShadeProperties(Serialisable):
  149. tagname = "path"
  150. namespace = DRAWING_NS
  151. path = Set(values=(['shape', 'circle', 'rect']))
  152. fillToRect = Typed(expected_type=RelativeRect, allow_none=True)
  153. def __init__(self,
  154. path=None,
  155. fillToRect=None,
  156. ):
  157. self.path = path
  158. self.fillToRect = fillToRect
  159. class GradientFillProperties(Serialisable):
  160. tagname = "gradFill"
  161. namespace = DRAWING_NS
  162. flip = NoneSet(values=(['x', 'y', 'xy']))
  163. rotWithShape = Bool(allow_none=True)
  164. gsLst = NestedSequence(expected_type=GradientStop, count=False)
  165. stop_list = Alias("gsLst")
  166. lin = Typed(expected_type=LinearShadeProperties, allow_none=True)
  167. linear = Alias("lin")
  168. path = Typed(expected_type=PathShadeProperties, allow_none=True)
  169. tileRect = Typed(expected_type=RelativeRect, allow_none=True)
  170. __elements__ = ('gsLst', 'lin', 'path', 'tileRect')
  171. def __init__(self,
  172. flip=None,
  173. rotWithShape=None,
  174. gsLst=(),
  175. lin=None,
  176. path=None,
  177. tileRect=None,
  178. ):
  179. self.flip = flip
  180. self.rotWithShape = rotWithShape
  181. self.gsLst = gsLst
  182. self.lin = lin
  183. self.path = path
  184. self.tileRect = tileRect
  185. class SolidColorFillProperties(Serialisable):
  186. tagname = "solidFill"
  187. # uses element group EG_ColorChoice
  188. scrgbClr = Typed(expected_type=RGBPercent, allow_none=True)
  189. RGBPercent = Alias('scrgbClr')
  190. srgbClr = NestedValue(expected_type=str, allow_none=True) # needs pattern and can have transform
  191. RGB = Alias('srgbClr')
  192. hslClr = Typed(expected_type=HSLColor, allow_none=True)
  193. sysClr = Typed(expected_type=SystemColor, allow_none=True)
  194. schemeClr = Typed(expected_type=SchemeColor, allow_none=True)
  195. prstClr = NestedNoneSet(values=PRESET_COLORS)
  196. __elements__ = ('scrgbClr', 'srgbClr', 'hslClr', 'sysClr', 'schemeClr', 'prstClr')
  197. def __init__(self,
  198. scrgbClr=None,
  199. srgbClr=None,
  200. hslClr=None,
  201. sysClr=None,
  202. schemeClr=None,
  203. prstClr=None,
  204. ):
  205. self.scrgbClr = scrgbClr
  206. self.srgbClr = srgbClr
  207. self.hslClr = hslClr
  208. self.sysClr = sysClr
  209. self.schemeClr = schemeClr
  210. self.prstClr = prstClr
  211. class Blip(Serialisable):
  212. tagname = "blip"
  213. namespace = DRAWING_NS
  214. # Using attribute groupAG_Blob
  215. cstate = NoneSet(values=(['email', 'screen', 'print', 'hqprint']))
  216. embed = Relation() # rId
  217. link = Relation() # hyperlink
  218. noGrp = Bool(allow_none=True)
  219. noSelect = Bool(allow_none=True)
  220. noRot = Bool(allow_none=True)
  221. noChangeAspect = Bool(allow_none=True)
  222. noMove = Bool(allow_none=True)
  223. noResize = Bool(allow_none=True)
  224. noEditPoints = Bool(allow_none=True)
  225. noAdjustHandles = Bool(allow_none=True)
  226. noChangeArrowheads = Bool(allow_none=True)
  227. noChangeShapeType = Bool(allow_none=True)
  228. # some elements are choice
  229. extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
  230. alphaBiLevel = Typed(expected_type=AlphaBiLevelEffect, allow_none=True)
  231. alphaCeiling = Typed(expected_type=AlphaCeilingEffect, allow_none=True)
  232. alphaFloor = Typed(expected_type=AlphaFloorEffect, allow_none=True)
  233. alphaInv = Typed(expected_type=AlphaInverseEffect, allow_none=True)
  234. alphaMod = Typed(expected_type=AlphaModulateEffect, allow_none=True)
  235. alphaModFix = Typed(expected_type=AlphaModulateFixedEffect, allow_none=True)
  236. alphaRepl = Typed(expected_type=AlphaReplaceEffect, allow_none=True)
  237. biLevel = Typed(expected_type=BiLevelEffect, allow_none=True)
  238. blur = Typed(expected_type=BlurEffect, allow_none=True)
  239. clrChange = Typed(expected_type=ColorChangeEffect, allow_none=True)
  240. clrRepl = Typed(expected_type=ColorReplaceEffect, allow_none=True)
  241. duotone = Typed(expected_type=DuotoneEffect, allow_none=True)
  242. fillOverlay = Typed(expected_type=FillOverlayEffect, allow_none=True)
  243. grayscl = Typed(expected_type=GrayscaleEffect, allow_none=True)
  244. hsl = Typed(expected_type=HSLEffect, allow_none=True)
  245. lum = Typed(expected_type=LuminanceEffect, allow_none=True)
  246. tint = Typed(expected_type=TintEffect, allow_none=True)
  247. __elements__ = ('alphaBiLevel', 'alphaCeiling', 'alphaFloor', 'alphaInv',
  248. 'alphaMod', 'alphaModFix', 'alphaRepl', 'biLevel', 'blur', 'clrChange',
  249. 'clrRepl', 'duotone', 'fillOverlay', 'grayscl', 'hsl', 'lum', 'tint')
  250. def __init__(self,
  251. cstate=None,
  252. embed=None,
  253. link=None,
  254. noGrp=None,
  255. noSelect=None,
  256. noRot=None,
  257. noChangeAspect=None,
  258. noMove=None,
  259. noResize=None,
  260. noEditPoints=None,
  261. noAdjustHandles=None,
  262. noChangeArrowheads=None,
  263. noChangeShapeType=None,
  264. extLst=None,
  265. alphaBiLevel=None,
  266. alphaCeiling=None,
  267. alphaFloor=None,
  268. alphaInv=None,
  269. alphaMod=None,
  270. alphaModFix=None,
  271. alphaRepl=None,
  272. biLevel=None,
  273. blur=None,
  274. clrChange=None,
  275. clrRepl=None,
  276. duotone=None,
  277. fillOverlay=None,
  278. grayscl=None,
  279. hsl=None,
  280. lum=None,
  281. tint=None,
  282. ):
  283. self.cstate = cstate
  284. self.embed = embed
  285. self.link = link
  286. self.noGrp = noGrp
  287. self.noSelect = noSelect
  288. self.noRot = noRot
  289. self.noChangeAspect = noChangeAspect
  290. self.noMove = noMove
  291. self.noResize = noResize
  292. self.noEditPoints = noEditPoints
  293. self.noAdjustHandles = noAdjustHandles
  294. self.noChangeArrowheads = noChangeArrowheads
  295. self.noChangeShapeType = noChangeShapeType
  296. self.extLst = extLst
  297. self.alphaBiLevel = alphaBiLevel
  298. self.alphaCeiling = alphaCeiling
  299. self.alphaFloor = alphaFloor
  300. self.alphaInv = alphaInv
  301. self.alphaMod = alphaMod
  302. self.alphaModFix = alphaModFix
  303. self.alphaRepl = alphaRepl
  304. self.biLevel = biLevel
  305. self.blur = blur
  306. self.clrChange = clrChange
  307. self.clrRepl = clrRepl
  308. self.duotone = duotone
  309. self.fillOverlay = fillOverlay
  310. self.grayscl = grayscl
  311. self.hsl = hsl
  312. self.lum = lum
  313. self.tint = tint
  314. class TileInfoProperties(Serialisable):
  315. tx = Integer(allow_none=True)
  316. ty = Integer(allow_none=True)
  317. sx = Integer(allow_none=True)
  318. sy = Integer(allow_none=True)
  319. flip = NoneSet(values=(['x', 'y', 'xy']))
  320. algn = Set(values=(['tl', 't', 'tr', 'l', 'ctr', 'r', 'bl', 'b', 'br']))
  321. def __init__(self,
  322. tx=None,
  323. ty=None,
  324. sx=None,
  325. sy=None,
  326. flip=None,
  327. algn=None,
  328. ):
  329. self.tx = tx
  330. self.ty = ty
  331. self.sx = sx
  332. self.sy = sy
  333. self.flip = flip
  334. self.algn = algn
  335. class BlipFillProperties(Serialisable):
  336. tagname = "blipFill"
  337. dpi = Integer(allow_none=True)
  338. rotWithShape = Bool(allow_none=True)
  339. blip = Typed(expected_type=Blip, allow_none=True)
  340. srcRect = Typed(expected_type=RelativeRect, allow_none=True)
  341. tile = Typed(expected_type=TileInfoProperties, allow_none=True)
  342. stretch = Typed(expected_type=StretchInfoProperties, allow_none=True)
  343. __elements__ = ("blip", "srcRect", "tile", "stretch")
  344. def __init__(self,
  345. dpi=None,
  346. rotWithShape=None,
  347. blip=None,
  348. tile=None,
  349. stretch=StretchInfoProperties(),
  350. srcRect=None,
  351. ):
  352. self.dpi = dpi
  353. self.rotWithShape = rotWithShape
  354. self.blip = blip
  355. self.tile = tile
  356. self.stretch = stretch
  357. self.srcRect = srcRect