|
5 | 5 | import codecs
|
6 | 6 | import datetime
|
7 | 7 | from enum import Enum
|
| 8 | +import functools |
8 | 9 | import glob
|
9 | 10 | from io import StringIO
|
10 | 11 | import logging
|
@@ -251,6 +252,21 @@ def __init__(self, width, height, pswriter, imagedpi=72):
|
251 | 252 | self._path_collection_id = 0
|
252 | 253 |
|
253 | 254 | self._character_tracker = _backend_pdf_ps.CharacterTracker()
|
| 255 | + self._logwarn_once = functools.lru_cache(None)(_log.warning) |
| 256 | + |
| 257 | + def _is_transparent(self, rgb_or_rgba): |
| 258 | + if rgb_or_rgba is None: |
| 259 | + return True # Consistent with rgbFace semantics. |
| 260 | + elif len(rgb_or_rgba) == 4: |
| 261 | + if rgb_or_rgba[3] == 0: |
| 262 | + return True |
| 263 | + if rgb_or_rgba[3] != 1: |
| 264 | + self._logwarn_once( |
| 265 | + "The PostScript backend does not support transparency; " |
| 266 | + "partially transparent artists will be rendered opaque.") |
| 267 | + return False |
| 268 | + else: # len() == 3. |
| 269 | + return False |
254 | 270 |
|
255 | 271 | def set_color(self, r, g, b, store=True):
|
256 | 272 | if (r, g, b) != self.color:
|
@@ -447,7 +463,7 @@ def draw_markers(
|
447 | 463 |
|
448 | 464 | ps_color = (
|
449 | 465 | None
|
450 |
| - if _is_transparent(rgbFace) |
| 466 | + if self._is_transparent(rgbFace) |
451 | 467 | else '%1.3f setgray' % rgbFace[0]
|
452 | 468 | if rgbFace[0] == rgbFace[1] == rgbFace[2]
|
453 | 469 | else '%1.3f %1.3f %1.3f setrgbcolor' % rgbFace[:3])
|
@@ -540,7 +556,7 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
|
540 | 556 | def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None):
|
541 | 557 | # docstring inherited
|
542 | 558 | if not hasattr(self, "psfrag"):
|
543 |
| - _log.warning( |
| 559 | + self._logwarn_once( |
544 | 560 | "The PS backend determines usetex status solely based on "
|
545 | 561 | "rcParams['text.usetex'] and does not support having "
|
546 | 562 | "usetex=True only for some elements; this element will thus "
|
@@ -579,7 +595,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
|
579 | 595 | if debugPS:
|
580 | 596 | self._pswriter.write("% text\n")
|
581 | 597 |
|
582 |
| - if _is_transparent(gc.get_rgb()): |
| 598 | + if self._is_transparent(gc.get_rgb()): |
583 | 599 | return # Special handling for fully transparent.
|
584 | 600 |
|
585 | 601 | if ismath == 'TeX':
|
@@ -723,10 +739,10 @@ def _draw_ps(self, ps, gc, rgbFace, fill=True, stroke=True, command=None):
|
723 | 739 | if debugPS and command:
|
724 | 740 | write("% "+command+"\n")
|
725 | 741 | mightstroke = (gc.get_linewidth() > 0
|
726 |
| - and not _is_transparent(gc.get_rgb())) |
| 742 | + and not self._is_transparent(gc.get_rgb())) |
727 | 743 | if not mightstroke:
|
728 | 744 | stroke = False
|
729 |
| - if _is_transparent(rgbFace): |
| 745 | + if self._is_transparent(rgbFace): |
730 | 746 | fill = False
|
731 | 747 | hatch = gc.get_hatch()
|
732 | 748 |
|
@@ -764,21 +780,6 @@ def _draw_ps(self, ps, gc, rgbFace, fill=True, stroke=True, command=None):
|
764 | 780 | write("grestore\n")
|
765 | 781 |
|
766 | 782 |
|
767 |
| -def _is_transparent(rgb_or_rgba): |
768 |
| - if rgb_or_rgba is None: |
769 |
| - return True # Consistent with rgbFace semantics. |
770 |
| - elif len(rgb_or_rgba) == 4: |
771 |
| - if rgb_or_rgba[3] == 0: |
772 |
| - return True |
773 |
| - if rgb_or_rgba[3] != 1: |
774 |
| - _log.warning( |
775 |
| - "The PostScript backend does not support transparency; " |
776 |
| - "partially transparent artists will be rendered opaque.") |
777 |
| - return False |
778 |
| - else: # len() == 3. |
779 |
| - return False |
780 |
| - |
781 |
| - |
782 | 783 | @_api.deprecated("3.4", alternative="GraphicsContextBase")
|
783 | 784 | class GraphicsContextPS(GraphicsContextBase):
|
784 | 785 | def get_capstyle(self):
|
|
0 commit comments