1 # -*- encoding: utf-8 -*-
4 # Copyright (C) 2002-2004, 2006, 2013 Jörg Lehmann <joergl@users.sourceforge.net>
5 # Copyright (C) 2003-2006 Michael Schindler <m-schindler@users.sourceforge.net>
6 # Copyright (C) 2002-2011 André Wobst <wobsta@users.sourceforge.net>
8 # This file is part of PyX (http://pyx.sourceforge.net/).
10 # PyX is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # PyX is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with PyX; if not, write to the Free Software
22 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 import binascii
, colorsys
, logging
, math
, struct
25 from . import attr
, style
, pdfwriter
27 logger
= logging
.getLogger("pyx")
29 # device-dependent (nonlinear) functions for color conversion
30 # UCRx : [0,1] -> [-1, 1] UnderColorRemoval (removes black from c, y, m)
31 # BG : [0,1] -> [0, 1] BlackGeneration (generate the black from the nominal k-value)
32 # as long as we have no further knowledge we define them linearly with constants 1
33 def _UCRc(x
): return x
34 def _UCRm(x
): return x
35 def _UCRy(x
): return x
38 def set(UCRc
=None, UCRm
=None, UCRy
=None, BG
=None):
54 class color(attr
.exclusiveattr
, style
.strokestyle
, style
.fillstyle
):
55 """base class for all colors"""
57 super().__init
__(color
)
59 def processSVGattrs(self
, attrs
, writer
, context
, registry
):
60 if context
.strokeattr
:
61 context
.strokecolor
= self
.rgb().tohexstring()
63 context
.fillcolor
= self
.rgb().tohexstring()
66 clear
= attr
.clearclass(color
)
73 def __init__(self
, g
=0.0):
76 raise ValueError("Value g out of range [0,1]")
79 def processPS(self
, file, writer
, context
, registry
):
80 file.write("%f setgray\n" % self
.g
)
82 def processPDF(self
, file, writer
, context
, registry
):
83 if context
.strokeattr
:
84 file.write("%f G\n" % self
.g
)
86 file.write("%f g\n" % self
.g
)
89 return cmyk(0, 0, 0, 1 - self
.g
)
96 return hsb(0, 0, self
.g
)
99 return rgb(self
.g
, self
.g
, self
.g
)
101 def colorspacestring(self
):
104 def to8bitbytes(self
):
105 return bytes((int(self
.g
*255),))
107 gray
.black
= gray(0.0)
108 gray
.white
= gray(1.0)
116 def __init__(self
, r
=0.0, g
=0.0, b
=0.0):
119 raise ValueError("Value r out of range [0,1]")
121 raise ValueError("Value g out of range [0,1]")
123 raise ValueError("Value b out of range [0,1]")
128 def processPS(self
, file, writer
, context
, registry
):
129 file.write("%f %f %f setrgbcolor\n" % (self
.r
, self
.g
, self
.b
))
131 def processPDF(self
, file, writer
, context
, registry
):
132 if context
.strokeattr
:
133 file.write("%f %f %f RG\n" % (self
.r
, self
.g
, self
.b
))
135 file.write("%f %f %f rg\n" % (self
.r
, self
.g
, self
.b
))
139 c
, m
, y
= 1 - self
.r
, 1 - self
.g
, 1 - self
.b
140 # conversion from cmy to cmyk with device-dependent functions
142 return cmyk(min(1, max(0, c
- _UCRc(k
))),
143 min(1, max(0, m
- _UCRm(k
))),
144 min(1, max(0, y
- _UCRy(k
))),
148 return gray(0.3*self
.r
+ 0.59*self
.g
+ 0.11*self
.b
)
152 h
, s
, b
= colorsys
.rgb_to_hsv(self
.r
, self
.g
, self
.b
)
156 return rgb(self
.r
, self
.g
, self
.b
)
158 def colorspacestring(self
):
161 def to8bitbytes(self
):
162 return struct
.pack("BBB", int(self
.r
*255), int(self
.g
*255), int(self
.b
*255))
164 def tohexstring(self
, cssstrip
=1, addhash
=1):
165 hexstring
= binascii
.b2a_hex(self
.to8bitbytes()).decode('ascii')
166 if cssstrip
and hexstring
[0] == hexstring
[1] and hexstring
[2] == hexstring
[3] and hexstring
[4] == hexstring
[5]:
167 hexstring
= "".join([hexstring
[0], hexstring
[2], hexstring
[4]])
169 hexstring
= "#" + hexstring
173 def rgbfromhexstring(hexstring
):
174 hexstring
= hexstring
.strip().lstrip("#")
175 if len(hexstring
) == 3:
176 hexstring
= "".join([hexstring
[0], hexstring
[0], hexstring
[1], hexstring
[1], hexstring
[2], hexstring
[2]])
177 elif len(hexstring
) != 6:
178 raise ValueError("3 or 6 digit hex number expected (with optional leading hash character)")
179 return rgb(*[value
/255.0 for value
in struct
.unpack("BBB", binascii
.a2b_hex(hexstring
))])
181 rgb
.red
= rgb(1, 0, 0)
182 rgb
.green
= rgb(0, 1, 0)
183 rgb
.blue
= rgb(0, 0, 1)
184 rgb
.white
= rgb(1, 1, 1)
185 rgb
.black
= rgb(0, 0, 0)
192 def __init__(self
, h
=0.0, s
=0.0, b
=0.0):
195 raise ValueError("Value h out of range [0,1]")
197 raise ValueError("Value s out of range [0,1]")
199 raise ValueError("Value b out of range [0,1]")
204 def processPS(self
, file, writer
, context
, registry
):
205 file.write("%f %f %f sethsbcolor\n" % (self
.h
, self
.s
, self
.b
))
207 def processPDF(self
, file, writer
, context
, registry
):
208 self
.rgb().processPDF(file, writer
, context
, registry
)
211 return self
.rgb().cmyk()
214 return self
.rgb().gray()
218 return hsb(self
.h
, self
.s
, self
.b
)
221 r
, g
, b
= colorsys
.hsv_to_rgb(self
.h
, self
.s
, self
.b
)
224 def colorspacestring(self
):
225 raise RuntimeError("colorspace string not available for hsb colors")
232 def __init__(self
, c
=0.0, m
=0.0, y
=0.0, k
=0.0):
235 raise ValueError("Value c out of range [0,1]")
237 raise ValueError("Value m out of range [0,1]")
239 raise ValueError("Value y out of range [0,1]")
241 raise ValueError("Value k out of range [0,1]")
247 def processPS(self
, file, writer
, context
, registry
):
248 file.write("%f %f %f %f setcmykcolor\n" % (self
.c
, self
.m
, self
.y
, self
.k
))
250 def processPDF(self
, file, writer
, context
, registry
):
251 if context
.strokeattr
:
252 file.write("%f %f %f %f K\n" % (self
.c
, self
.m
, self
.y
, self
.k
))
254 file.write("%f %f %f %f k\n" % (self
.c
, self
.m
, self
.y
, self
.k
))
257 return cmyk(self
.c
, self
.m
, self
.y
, self
.k
)
260 return gray(1 - min([1, 0.3*self
.c
+ 0.59*self
.m
+ 0.11*self
.y
+ self
.k
]))
264 return self
.rgb().hsb()
268 c
= min(1, self
.c
+ self
.k
)
269 m
= min(1, self
.m
+ self
.k
)
270 y
= min(1, self
.y
+ self
.k
)
271 # conversion from cmy to rgb:
272 return rgb(1 - c
, 1 - m
, 1 - y
)
274 def colorspacestring(self
):
277 def to8bitbytes(self
):
278 return struct
.pack("BBBB", int(self
.c
*255), int(self
.m
*255), int(self
.y
*255), int(self
.k
*255))
280 cmyk
.GreenYellow
= cmyk(0.15, 0, 0.69, 0)
281 cmyk
.Yellow
= cmyk(0, 0, 1, 0)
282 cmyk
.Goldenrod
= cmyk(0, 0.10, 0.84, 0)
283 cmyk
.Dandelion
= cmyk(0, 0.29, 0.84, 0)
284 cmyk
.Apricot
= cmyk(0, 0.32, 0.52, 0)
285 cmyk
.Peach
= cmyk(0, 0.50, 0.70, 0)
286 cmyk
.Melon
= cmyk(0, 0.46, 0.50, 0)
287 cmyk
.YellowOrange
= cmyk(0, 0.42, 1, 0)
288 cmyk
.Orange
= cmyk(0, 0.61, 0.87, 0)
289 cmyk
.BurntOrange
= cmyk(0, 0.51, 1, 0)
290 cmyk
.Bittersweet
= cmyk(0, 0.75, 1, 0.24)
291 cmyk
.RedOrange
= cmyk(0, 0.77, 0.87, 0)
292 cmyk
.Mahogany
= cmyk(0, 0.85, 0.87, 0.35)
293 cmyk
.Maroon
= cmyk(0, 0.87, 0.68, 0.32)
294 cmyk
.BrickRed
= cmyk(0, 0.89, 0.94, 0.28)
295 cmyk
.Red
= cmyk(0, 1, 1, 0)
296 cmyk
.OrangeRed
= cmyk(0, 1, 0.50, 0)
297 cmyk
.RubineRed
= cmyk(0, 1, 0.13, 0)
298 cmyk
.WildStrawberry
= cmyk(0, 0.96, 0.39, 0)
299 cmyk
.Salmon
= cmyk(0, 0.53, 0.38, 0)
300 cmyk
.CarnationPink
= cmyk(0, 0.63, 0, 0)
301 cmyk
.Magenta
= cmyk(0, 1, 0, 0)
302 cmyk
.VioletRed
= cmyk(0, 0.81, 0, 0)
303 cmyk
.Rhodamine
= cmyk(0, 0.82, 0, 0)
304 cmyk
.Mulberry
= cmyk(0.34, 0.90, 0, 0.02)
305 cmyk
.RedViolet
= cmyk(0.07, 0.90, 0, 0.34)
306 cmyk
.Fuchsia
= cmyk(0.47, 0.91, 0, 0.08)
307 cmyk
.Lavender
= cmyk(0, 0.48, 0, 0)
308 cmyk
.Thistle
= cmyk(0.12, 0.59, 0, 0)
309 cmyk
.Orchid
= cmyk(0.32, 0.64, 0, 0)
310 cmyk
.DarkOrchid
= cmyk(0.40, 0.80, 0.20, 0)
311 cmyk
.Purple
= cmyk(0.45, 0.86, 0, 0)
312 cmyk
.Plum
= cmyk(0.50, 1, 0, 0)
313 cmyk
.Violet
= cmyk(0.79, 0.88, 0, 0)
314 cmyk
.RoyalPurple
= cmyk(0.75, 0.90, 0, 0)
315 cmyk
.BlueViolet
= cmyk(0.86, 0.91, 0, 0.04)
316 cmyk
.Periwinkle
= cmyk(0.57, 0.55, 0, 0)
317 cmyk
.CadetBlue
= cmyk(0.62, 0.57, 0.23, 0)
318 cmyk
.CornflowerBlue
= cmyk(0.65, 0.13, 0, 0)
319 cmyk
.MidnightBlue
= cmyk(0.98, 0.13, 0, 0.43)
320 cmyk
.NavyBlue
= cmyk(0.94, 0.54, 0, 0)
321 cmyk
.RoyalBlue
= cmyk(1, 0.50, 0, 0)
322 cmyk
.Blue
= cmyk(1, 1, 0, 0)
323 cmyk
.Cerulean
= cmyk(0.94, 0.11, 0, 0)
324 cmyk
.Cyan
= cmyk(1, 0, 0, 0)
325 cmyk
.ProcessBlue
= cmyk(0.96, 0, 0, 0)
326 cmyk
.SkyBlue
= cmyk(0.62, 0, 0.12, 0)
327 cmyk
.Turquoise
= cmyk(0.85, 0, 0.20, 0)
328 cmyk
.TealBlue
= cmyk(0.86, 0, 0.34, 0.02)
329 cmyk
.Aquamarine
= cmyk(0.82, 0, 0.30, 0)
330 cmyk
.BlueGreen
= cmyk(0.85, 0, 0.33, 0)
331 cmyk
.Emerald
= cmyk(1, 0, 0.50, 0)
332 cmyk
.JungleGreen
= cmyk(0.99, 0, 0.52, 0)
333 cmyk
.SeaGreen
= cmyk(0.69, 0, 0.50, 0)
334 cmyk
.Green
= cmyk(1, 0, 1, 0)
335 cmyk
.ForestGreen
= cmyk(0.91, 0, 0.88, 0.12)
336 cmyk
.PineGreen
= cmyk(0.92, 0, 0.59, 0.25)
337 cmyk
.LimeGreen
= cmyk(0.50, 0, 1, 0)
338 cmyk
.YellowGreen
= cmyk(0.44, 0, 0.74, 0)
339 cmyk
.SpringGreen
= cmyk(0.26, 0, 0.76, 0)
340 cmyk
.OliveGreen
= cmyk(0.64, 0, 0.95, 0.40)
341 cmyk
.RawSienna
= cmyk(0, 0.72, 1, 0.45)
342 cmyk
.Sepia
= cmyk(0, 0.83, 1, 0.70)
343 cmyk
.Brown
= cmyk(0, 0.81, 1, 0.60)
344 cmyk
.Tan
= cmyk(0.14, 0.42, 0.56, 0)
345 cmyk
.Gray
= cmyk(0, 0, 0, 0.50)
346 cmyk
.Grey
= cmyk
.Gray
347 cmyk
.Black
= cmyk(0, 0, 0, 1)
348 cmyk
.White
= cmyk(0, 0, 0, 0)
349 cmyk
.white
= cmyk
.White
350 cmyk
.black
= cmyk
.Black
353 class palette(attr
.changelist
):
356 A color palette is a discrete, ordered list of colors"""
358 palette
.clear
= attr
.clearclass(palette
)
364 class gradient(attr
.changeattr
):
366 """base class for color gradients
368 A gradient is a continuous collection of colors with a single parameter ranging from 0 to 1
371 def getcolor(self
, param
):
372 """return color corresponding to param"""
375 def select(self
, index
, n_indices
):
376 """return a color corresponding to an index out of n_indices"""
380 param
= index
/ (n_indices
- 1.0)
381 return self
.getcolor(param
)
383 gradient
.clear
= attr
.clearclass(gradient
)
386 # gradient with arbitrary non-linear dependency
389 class functiongradient_gray(gradient
):
391 """arbitrary non-linear gradients of gray colors
393 f_gray: a function mapping [0,1] to the gray value
396 def __init__(self
, f_gray
):
400 def getcolor(self
, param
):
401 return gray(self
.f_gray(param
))
404 class functiongradient_cmyk(gradient
):
406 """arbitrary non-linear gradients of cmyk colors
408 f_c: a function mapping [0,1] to the c component
409 f_m: a function mapping [0,1] to the m component
410 f_y: a function mapping [0,1] to the y component
411 f_k: a function mapping [0,1] to the k component
414 def __init__(self
, f_c
, f_m
, f_y
, f_k
):
421 def getcolor(self
, param
):
422 return cmyk(self
.f_c(param
), self
.f_m(param
), self
.f_y(param
), self
.f_k(param
))
425 class functiongradient_hsb(gradient
):
427 """arbitrary non-linear gradients of hsb colors
429 f_h: a function mapping [0,1] to the h component
430 f_s: a function mapping [0,1] to the s component
431 f_b: a function mapping [0,1] to the b component
434 def __init__(self
, f_h
, f_s
, f_b
):
440 def getcolor(self
, param
):
441 return hsb(self
.f_h(param
), self
.f_s(param
), self
.f_b(param
))
444 class functiongradient_rgb(gradient
):
446 """arbitrary non-linear gradients of rgb colors
448 f_r: a function mapping [0,1] to the r component
449 f_g: a function mapping [0,1] to the b component
450 f_b: a function mapping [0,1] to the b component
453 def __init__(self
, f_r
, f_g
, f_b
):
459 def getcolor(self
, param
):
460 return rgb(self
.f_r(param
), self
.f_g(param
), self
.f_b(param
))
463 # factory functions for gradients interpolating linearly between two colors
466 def lineargradient_cmyk(mincolor
, maxcolor
):
467 return functiongradient_cmyk(lambda x
:maxcolor
.c
* x
+ mincolor
.c
* (1-x
),
468 lambda x
:maxcolor
.m
* x
+ mincolor
.m
* (1-x
),
469 lambda x
:maxcolor
.y
* x
+ mincolor
.y
* (1-x
),
470 lambda x
:maxcolor
.k
* x
+ mincolor
.k
* (1-x
))
472 def lineargradient_gray(mincolor
, maxcolor
):
473 return functiongradient_gray(lambda x
:maxcolor
.g
* x
+ mincolor
.g
* (1-x
))
475 def lineargradient_hsb(mincolor
, maxcolor
):
476 return functiongradient_hsb(lambda x
:maxcolor
.h
* x
+ mincolor
.h
* (1-x
),
477 lambda x
:maxcolor
.s
* x
+ mincolor
.s
* (1-x
),
478 lambda x
:maxcolor
.b
* x
+ mincolor
.b
* (1-x
))
480 def lineargradient_rgb(mincolor
, maxcolor
):
481 return functiongradient_rgb(lambda x
:maxcolor
.r
* x
+ mincolor
.r
* (1-x
),
482 lambda x
:maxcolor
.g
* x
+ mincolor
.g
* (1-x
),
483 lambda x
:maxcolor
.b
* x
+ mincolor
.b
* (1-x
))
487 # gradients converted into other color spaces
490 class rgbgradient(gradient
):
492 "a gradient, which takes another gradient and returns rgb colors"
494 def __init__(self
, gradient
):
496 self
.gradient
= gradient
498 def getcolor(self
, param
):
499 return self
.gradient
.getcolor(param
).rgb()
502 class cmykgradient(gradient
):
504 "a gradient, which takes another gradient and returns cmyk colors"
506 def __init__(self
, gradient
):
508 self
.gradient
= gradient
510 def getcolor(self
, param
):
511 return self
.gradient
.getcolor(param
).cmyk()
514 gradient
.Gray
= lineargradient_gray(gray
.white
, gray
.black
)
515 gradient
.Grey
= gradient
.Gray
516 gradient
.ReverseGray
= lineargradient_gray(gray
.black
, gray
.white
)
517 gradient
.ReverseGrey
= gradient
.ReverseGray
518 gradient
.BlackYellow
= functiongradient_rgb( # compare this with reversegray above
519 f_r
=lambda x
: 2*x
*(1-x
)**5 + 3.5*x
**2*(1-x
)**3 + 2.1*x
*x
*(1-x
)**2 + 3.0*x
**3*(1-x
)**2 + x
**0.5*(1-(1-x
)**2),
520 f_g
=lambda x
: 1.5*x
**2*(1-x
)**3 - 0.8*x
**3*(1-x
)**2 + 2.0*x
**4*(1-x
) + x
**4,
521 f_b
=lambda x
: 5*x
*(1-x
)**5 - 0.5*x
**2*(1-x
)**3 + 0.3*x
*x
*(1-x
)**2 + 5*x
**3*(1-x
)**2 + 0.5*x
**6)
522 gradient
.YellowBlack
= functiongradient_rgb(
523 f_r
=lambda x
: 2*(1-x
)*x
**5 + 3.5*(1-x
)**2*x
**3 + 2.1*(1-x
)*(1-x
)*x
**2 + 3.0*(1-x
)**3*x
**2 + (1-x
)**0.5*(1-x
**2),
524 f_g
=lambda x
: 1.5*(1-x
)**2*x
**3 - 0.8*(1-x
)**3*x
**2 + 2.0*(1-x
)**4*x
+ (1-x
)**4,
525 f_b
=lambda x
: 5*(1-x
)*x
**5 - 0.5*(1-x
)**2*x
**3 + 0.3*(1-x
)*(1-x
)*x
**2 + 5*(1-x
)**3*x
**2 + 0.5*(1-x
)**6)
526 gradient
.RedGreen
= lineargradient_rgb(rgb
.red
, rgb
.green
)
527 gradient
.RedBlue
= lineargradient_rgb(rgb
.red
, rgb
.blue
)
528 gradient
.GreenRed
= lineargradient_rgb(rgb
.green
, rgb
.red
)
529 gradient
.GreenBlue
= lineargradient_rgb(rgb
.green
, rgb
.blue
)
530 gradient
.BlueRed
= lineargradient_rgb(rgb
.blue
, rgb
.red
)
531 gradient
.BlueGreen
= lineargradient_rgb(rgb
.blue
, rgb
.green
)
532 gradient
.RedBlack
= lineargradient_rgb(rgb
.red
, rgb
.black
)
533 gradient
.BlackRed
= lineargradient_rgb(rgb
.black
, rgb
.red
)
534 gradient
.RedWhite
= lineargradient_rgb(rgb
.red
, rgb
.white
)
535 gradient
.WhiteRed
= lineargradient_rgb(rgb
.white
, rgb
.red
)
536 gradient
.GreenBlack
= lineargradient_rgb(rgb
.green
, rgb
.black
)
537 gradient
.BlackGreen
= lineargradient_rgb(rgb
.black
, rgb
.green
)
538 gradient
.GreenWhite
= lineargradient_rgb(rgb
.green
, rgb
.white
)
539 gradient
.WhiteGreen
= lineargradient_rgb(rgb
.white
, rgb
.green
)
540 gradient
.BlueBlack
= lineargradient_rgb(rgb
.blue
, rgb
.black
)
541 gradient
.BlackBlue
= lineargradient_rgb(rgb
.black
, rgb
.blue
)
542 gradient
.BlueWhite
= lineargradient_rgb(rgb
.blue
, rgb
.white
)
543 gradient
.WhiteBlue
= lineargradient_rgb(rgb
.white
, rgb
.blue
)
544 gradient
.Rainbow
= lineargradient_hsb(hsb(0, 1, 1), hsb(2.0/3.0, 1, 1))
545 gradient
.ReverseRainbow
= lineargradient_hsb(hsb(2.0/3.0, 1, 1), hsb(0, 1, 1))
546 gradient
.Hue
= lineargradient_hsb(hsb(0, 1, 1), hsb(1, 1, 1))
547 gradient
.ReverseHue
= lineargradient_hsb(hsb(1, 1, 1), hsb(0, 1, 1))
548 rgbgradient
.Rainbow
= rgbgradient(gradient
.Rainbow
)
549 rgbgradient
.ReverseRainbow
= rgbgradient(gradient
.ReverseRainbow
)
550 rgbgradient
.Hue
= rgbgradient(gradient
.Hue
)
551 rgbgradient
.ReverseHue
= rgbgradient(gradient
.ReverseHue
)
552 cmykgradient
.Rainbow
= cmykgradient(gradient
.Rainbow
)
553 cmykgradient
.ReverseRainbow
= cmykgradient(gradient
.ReverseRainbow
)
554 cmykgradient
.Hue
= cmykgradient(gradient
.Hue
)
555 cmykgradient
.ReverseHue
= cmykgradient(gradient
.ReverseHue
)
557 if x
< 0.38: return 0
558 elif x
< 0.62: return (x
-0.38)/(0.62-0.38)
559 elif x
< 0.87: return 1
560 else: return 0.5 + 0.5*(1-x
)/(1-0.87)
562 if x
< 0.13: return 0
563 elif x
< 0.38: return (x
-0.13)/(0.38-0.13)
564 elif x
< 0.62: return 1
565 elif x
< 0.87: return (0.87-x
)/(0.87-0.62)
568 if x
< 0.13: return 0.5 + 0.5*x
/0.13
569 elif x
< 0.38: return 1
570 elif x
< 0.62: return 1-(x
-0.38)/(0.62-0.38)
572 gradient
.Jet
= functiongradient_rgb(f_r
=jet_r
, f_g
=jet_g
, f_b
=jet_b
)
573 gradient
.ReverseJet
= functiongradient_rgb(f_r
=lambda x
: jet_r(1-x
), f_g
=lambda x
: jet_g(1-x
), f_b
=lambda x
: jet_b(1-x
))
574 cmykgradient
.Jet
= cmykgradient(gradient
.Jet
)
575 cmykgradient
.ReverseJet
= cmykgradient(gradient
.ReverseJet
)
579 class PDFextgstate(pdfwriter
.PDFobject
):
581 def __init__(self
, name
, extgstate
, registry
):
582 pdfwriter
.PDFobject
.__init
__(self
, "extgstate", name
)
583 registry
.addresource("ExtGState", name
, self
)
585 self
.extgstate
= extgstate
587 def write(self
, file, writer
, registry
):
588 file.write("%s\n" % self
.extgstate
)
591 class transparency(attr
.exclusiveattr
, style
.strokestyle
, style
.fillstyle
):
593 def __init__(self
, value
):
595 attr
.exclusiveattr
.__init
__(self
, transparency
)
597 def processPS(self
, file, writer
, context
, registry
):
598 logger
.warning("Transparency not available in PostScript, proprietary ghostscript extension code inserted.")
599 file.write("%f .setshapealpha\n" % self
.value
)
601 def processPDF(self
, file, writer
, context
, registry
):
602 if context
.strokeattr
and context
.fillattr
:
603 registry
.add(PDFextgstate("Transparency-%f" % self
.value
,
604 "<< /Type /ExtGState /CA %f /ca %f >>" % (self
.value
, self
.value
), registry
))
605 file.write("/Transparency-%f gs\n" % self
.value
)
606 elif context
.strokeattr
:
607 registry
.add(PDFextgstate("Transparency-Stroke-%f" % self
.value
,
608 "<< /Type /ExtGState /CA %f >>" % self
.value
, registry
))
609 file.write("/Transparency-Stroke-%f gs\n" % self
.value
)
610 elif context
.fillattr
:
611 registry
.add(PDFextgstate("Transparency-Fill-%f" % self
.value
,
612 "<< /Type /ExtGState /ca %f >>" % self
.value
, registry
))
613 file.write("/Transparency-Fill-%f gs\n" % self
.value
)
615 def processSVGattrs(self
, attrs
, writer
, context
, registry
):
616 if context
.strokeattr
:
617 context
.strokeopacity
= self
.value
619 context
.fillopacity
= self
.value