<commit_before># Copyright (c) 2014 <NAME>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import os
import subprocess

from . import bbox

# ToDo:
#   - redefine some operators (lineto) to generate smaller files
#   - generalize state dict

PSDEFAULTS = dict(
  color = (0, 0, 0),
  gray = 0,
  width = 1,
  dash = ([], 0),
)

CESHOWDEF = """
/ceshow { % (string) fontsize fontname x y
    gsave
        moveto findfont exch scalefont setfont % s
        gsave
            dup false charpath flattenpath pathbbox % s x0 y0 x1 y1
        grestore
        3 -1 roll sub % s x0 x1 dy
        3 1 roll sub % s dy -dx
        2 div exch % s -dx/2 dy
        -2 div % s -dx/2 -dy/2
        rmoveto show
    grestore
} bind def
"""

class Canvas:

    def __init__(self):
        self.lines = []
        self.bbox = bbox.BBox()
        self.state = PSDEFAULTS.copy()
        self.CESHOW = False

    def resetbbox(self):
        self.bbox = bbox.BBox()

    def setgray(self, v):
        if self.state['gray'] == v:
            return
        line = "{} setgray".format(v)
        self.lines.append(line)
        self.state['gray'] = v

    def setcolor(self, r, g, b):
        if self.state['color'] == (r, g, b):
            return
        line = "{} {} {} setrgbcolor".format(r, g, b)
        self.lines.append(line)
        self.state['color'] = (r, g, b)

    def setink(self, ink):
        if isinstance(ink, tuple):
            self.setcolor(*ink)
        elif isinstance(ink, (int, float)):
            self.setgray(ink)
        else:
            tname = type(ink).__name__
            raise TypeError("expected int, float or 3-tuple, got {}".format(tname))

    def setwidth(self, w):
        if self.state['width'] == w:
            return
        line = "{} setlinewidth".format(w)
        self.lines.append(line)
        self.state['width'] = w

    def setdash(self, pattern, offset=0):
        if self.state['dash'] == (pattern, offset):
            return
        psarray = "[{}]".format(" ".join(map(str, pattern)))
        line = "{} {} setdash".format(psarray, offset)
        self.lines.append(line)
        self.state['dash'] = (pattern, offset)

    def addcircle(self, center, radius, fill=None, stroke=None):
        x, y = center
        r = radius
        line = "{} {} {} 0 360 arc closepath".format(x, y, r)
        self.lines.append(line)
        if fill is not None:
            if stroke is not None:
                self.lines.append("gsave")
            self.setink(fill)
            self.lines.append("fill")
        if stroke is not None:
            if fill is not None:
                self.lines.append("grestore")
            self.setink(stroke)
            self.lines.append("stroke")
        self.bbox |= bbox.BBox((x - r, y - r), (x + r, y + r))

    def addpolyline(self, points, stroke=None):
        self.lines.append("newpath")
        line = "{} {} moveto".format(*points[0])
        self.lines.append(line)
        for point in points[1:]:
            line = "{} {} lineto".format(*point)
            self.lines.append(line)
        self.setink(stroke)
        self.lines.append("stroke")
        self.bbox |= bbox.BBox(points)

    def addpolygon(self, points, fill=None, stroke=None):
        self.lines.append("newpath")
        line = "{} {} moveto".format(*points[0])
        self.lines.append(line)
        for point in points[1:]:
            line = "{} {} lineto".format(*point)
            self.lines.append(line)
        self.lines.append("closepath")
        if fill is not None:
            if stroke is not None:
                self.lines.append("gsave")
            self.setink(fill)
            self.lines.append("fill")
        if stroke is not None:
            if fill is not None:
                self.lines.append("grestore")
            self.setink(stroke)
            self.lines.append("stroke")
        self.bbox |= bbox.BBox(points)

    def addroundedpolygon(self, points, radius, fill=None, stroke=None):
        self.lines.append("newpath")
        (x1, y1), (x2, y2) = points[:2]
        startend = ((x1 + x2) / 2, (y1 + y2) / 2)
        poly = [startend] + points[1:] + points[:1]
        line = "{} {} moveto".format(*poly[0])
        self.lines.append(line)
        for (x1, y1), (x2, y2) in zip(poly[1:], poly[2:] + poly[:1]):
            line = "{} {} {} {} {} arcto".format(x1, y1, x2, y2, radius)
            self.lines.append(line)
        self.lines.append("closepath")
        if fill is not None:
            if stroke is not None:
                self.lines.append("gsave")
            self.setink(fill)
            self.lines.append("fill")
        if stroke is not None:
            if fill is not None:
                self.lines.append("grestore")
            self.setink(stroke)<commit_msg>Minor change.<commit_after># Copyright (c) 2014 <NAME>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import os
import subprocess

from . import bbox

# ToDo:
#   - redefine some operators (lineto) to generate smaller files
#   - generalize state dict

PSDEFAULTS = dict(
  color = (0, 0, 0),
  gray = 0,
  width = 1,
  dash = ([], 0),
)

CESHOWDEF = """
/ceshow { % (string) fontsize fontname x y
    gsave
        moveto findfont exch scalefont setfont % s
        gsave
            dup false charpath flattenpath pathbbox % s x0 y0 x1 y1
        grestore
        3 -1 roll sub % s x0 x1 dy
        3 1 roll sub % s dy -dx
        2 div exch % s -dx/2 dy
        -2 div % s -dx/2 -dy/2
        rmoveto show
    grestore
} bind def
"""

class Canvas:

    def __init__(self):
        self.lines = []
        self.bbox = bbox.BBox()
        self.state = PSDEFAULTS.copy()
        self.CESHOW = False

    def resetbbox(self):
        self.bbox = bbox.BBox()

    def setgray(self, v):
        if self.state['gray'] == v:
            return
        line = "{} setgray".format(v)
        self.lines.append(line)
        self.state['gray'] = v

    def setcolor(self, r, g, b):
        if self.state['color'] == (r, g, b):
            return
        line = "{} {} {} setrgbcolor".format(r, g, b)
        self.lines.append(line)
        self.state['color'] = (r, g, b)

    def setink(self, ink):
        if isinstance(ink, tuple):
            self.setcolor(*ink)
        elif isinstance(ink, (int, float)):
            self.setgray(ink)
        else:
            tname = type(ink).__name__
            raise TypeError("expected int, float or 3-tuple, got {}".format(tname))

    def setwidth(self, w):
        if self.state['width'] == w:
            return
        line = "{} setlinewidth".format(w)
        self.lines.append(line)
        self.state['width'] = w

    def setdash(self, pattern, offset=0):
        if self.state['dash'] == (pattern, offset):
            return
        psarray = "[{}]".format(" ".join(map(str, pattern)))
        line = "{} {} setdash".format(psarray, offset)
        self.lines.append(line)
        self.state['dash'] = (pattern, offset)

    def addcircle(self, center, radius, fill=None, stroke=None):
        x, y = center
        r = radius
        line = "{} {} {} 0 360 arc closepath".format(x, y, r)
        self.lines.append(line)
        if fill is not None:
            if stroke is not None:
                self.lines.append("gsave")
            self.setink(fill)
            self.lines.append("fill")
        if stroke is not None:
            if fill is not None:
                self.lines.append("grestore")
            self.setink(stroke)
            self.lines.append("stroke")
        self.bbox |= bbox.BBox((x - r, y - r), (x + r, y + r))

    def addpolyline(self, points, stroke=None):
        self.lines.append("newpath")
        line = "{} {} moveto".format(*points[0])
        self.lines.append(line)
        for point in points[1:]:
            line = "{} {} lineto".format(*point)
            self.lines.append(line)
        self.setink(stroke)
        self.lines.append("stroke")
        self.bbox |= bbox.BBox(points)

    def addpolygon(self, points, fill=None, stroke=None):
        self.lines.append("newpath")
        line = "{} {} moveto".format(*points[0])
        self.lines.append(line)
        for point in points[1:]:
            line = "{} {} lineto".format(*point)
            self.lines.append(line)
        self.lines.append("closepath")
        if fill is not None:
            if stroke is not None:
                self.lines.append("gsave")
            self.setink(fill)
            self.lines.append("fill")
        if stroke is not None:
            if fill is not None:
                self.lines.append("grestore")
            self.setink(stroke)
            self.lines.append("stroke")
        self.bbox |= bbox.BBox(points)

    def addroundedpolygon(self, points, radius, fill=None, stroke=None):
        self.lines.append("newpath")
        (x1, y1), (x2, y2) = points[:2]
        startend = ((x1 + x2) / 2, (y1 + y2) / 2)
        poly = [startend] + points[1:] + points[:1]
        line = "{} {} moveto".format(*startend)
        self.lines.append(line)
        for (x1, y1), (x2, y2) in zip(poly[1:], poly[2:] + poly[:1]):
            line = "{} {} {} {} {} arcto".format(x1, y1, x2, y2, radius)
            self.lines.append(line)
        self.lines.append("closepath")
        if fill is not None:
            if stroke is not None:
                self.lines.append("gsave")
            self.setink(fill)
            self.lines.append("fill")
        if stroke is not None:
            if fill is not None:
                self.lines.append("grestore")
            self.setink(stroke)
{'fraction_non_alphanumeric': 0.1265658747300216, 'fraction_numerical': 0.010280777537796977, 'mean_word_length': 2.1076510067114094, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '296838', 'n_tokens_mistral': 3586, 'n_tokens_neox': 3476, 'n_words': 1086}