Example #1
0
 def test_template_with_max_attribute_can_render(self):
     c1 = ColorLayer("color1",
                     content="Green",
                     left=NA(0),
                     width=NA(50),
                     top=NA(0),
                     height=NA(50))
     c2 = ColorLayer("color2",
                     content="Blue",
                     left=NA(0),
                     width=NA(60),
                     top=SA("color1.bottom"),
                     height=NA(50))
     text = PTL("test",
                "Arial",
                15,
                "Black",
                content="Hello World",
                left=MinA(SA("color1.right"), SA("color2.right")),
                top=SA("color2.bottom"))
     bg = ColorBackgroundLayer("name", content="White")
     layers = [c1, c2, bg, text]
     temp = Template("temp",
                     *layers,
                     left=NA(0),
                     top=NA(0),
                     width=NA(300),
                     height=NA(300))
     temp.update_bounds()
     assert text["left"] == 60
Example #2
0
    def test_can_order_layers_for_rendering(self):
        kwargs = {
            "left": SA("parent.left"),
            "right": SA("parent.right"),
            "top": SA("parent.top"),
            "bottom": SA("parent.bottom")
        }
        l1 = ColorLayer("layer_1", content="#FF0000", order=1, **kwargs)
        l2 = ColorLayer("layer_1", content="#00FF00", order=2, **kwargs)
        temp = Template("temp",
                        l1,
                        l2,
                        left=NA(0),
                        width=NA(50),
                        top=NA(0),
                        height=NA(50))

        temp.update_bounds()

        green_above = temp.render()
        color_of_top_left_most_pixel = green_above.export_pixels(width=1,
                                                                 height=1)
        # RGBA, [1] is green
        assert color_of_top_left_most_pixel[:3] == [0, 255, 0]

        l1.order = 3  # move red above
        red_above = temp.render()
        color_of_top_left_most_pixel = red_above.export_pixels(width=1,
                                                               height=1)
        assert color_of_top_left_most_pixel[:3] == [255, 0, 0]
Example #3
0
 def test_can_unset_attributes_evaluated_values(self):
     """Because the content of pt is changing per iteration, the left of
     square should change as well (top should change due to p in people)."""
     content_list = ["hello world", "people"]
     square_lefts = []  # stores left values per iteration
     square_tops = []
     pt = PTL("pt", "Arial", 15, "Black", left=NA(0), top=NA(0))
     square = ColorLayer("square",
                         content="Red",
                         left=AA(SA("pt.right")),
                         top=SA("pt.bottom"),
                         width=NA(20),
                         height=NA(20))
     bg = ColorBackgroundLayer("bg", content="White")
     temp = Template("temp",
                     pt,
                     square,
                     bg,
                     left=NA(0),
                     top=NA(0),
                     height=NA(100),
                     width=NA(100))
     for i, content in enumerate(content_list):
         pt.pre_render = None
         pt.content = content
         temp.unset_bounds_and_attributes()
         temp.update_bounds()
         temp.render().save(
             filename=
             f"tests/images/{i}_test_can_unset_attributes_evaluated_values.png"
         )
         square_lefts.append(temp.get_layer("square")["left"])
         square_tops.append(temp.get_layer("square")["top"])
     assert square_lefts[0] != square_lefts[1]
     assert square_tops[0] != square_tops[1]
Example #4
0
 def __init__(self, name, *args, width=None, height=None, **kwargs):
     initial_width = SA("self.initial_width")
     initial_height = SA("self.initial_height")
     ratio_attr = MaxA(DivA(width, initial_width),
                       DivA(height, initial_height))
     super().__init__(name,
                      *args,
                      width=MulA(initial_width, ratio_attr),
                      height=MulA(initial_height, ratio_attr),
                      **kwargs)
Example #5
0
    def test_can_have_templates_within_templates(self):
        pt = PointTextLayer("point_text_layer", content="Point Text Layer", font="Arial", size=35, color="Black",
                left=NA(0), top=NA(0))
        bg = ColorLayer("bg", content="Red", left=NA(0),
                width=SA("parent.width"), height=SA("parent.height"), top=NA(0))
        temp = Template("temp",  pt, bg, left=NA(0), right=SA("point_text_layer.right"),
                top=NA(0), height=NA(100))
        temp2 = Template("temp", temp, left=NA(0), right=SA("point_text_layer.right"),
                top=NA(0), height=NA(500))

        temp2.update_bounds()
Example #6
0
    def test_this_configuration_can_render(self):
        pt = PointTextLayer("ptl", "Arial", 15, "Black", content="Hello World", left=AA(SA("parent.left"), NA(5)),
            top=SA("parent.top"))
        bg = ColorBackgroundLayer("bg", content="Green")
        temp = Template("temp",  pt, bg, left=NA(10), right=SA("ptl.right"),
                top=SA("parent.top"), height=NA(100))

        temp2 = Template("temp2", temp, left=NA(0), right=NA(100),
                top=NA(0), height=NA(100))

        temp2.update_bounds()
        image = temp2.render()
Example #7
0
    def test_template_variable_get_set_correctly(self):
        pt = PointTextLayer("ptl", "Arial", 15, "Black", content="Hello World", left=AA(SA("parent.left"), NA(5)),
            top=SA("parent.top"))
        bg = ColorBackgroundLayer("bg", content="Green")
        temp = Template("temp",  pt, bg, left=NA(10), right=SA("ptl.right"),
                top=SA("parent.top"), height=NA(100))

        temp2 = Template("temp2", temp, left=NA(0), right=NA(100),
                top=NA(0), height=NA(100))
        assert pt.template == bg.template
        assert pt.parent == temp
        assert pt.template == temp2
        assert pt.template == temp.template
Example #8
0
 def test_can_render_color_overlay(self):
     pt = PTL("pt",
              "Arial",
              15,
              "Black",
              content="PT",
              left=NA(0),
              top=NA(0))
     pt2 = PTL("pt2",
               "Arial",
               15,
               "Black",
               content="PT2",
               left=NA(0),
               top=AA(SA("pt.bottom"), NA(5)))
     bg = ColorBackgroundLayer("bg", content="Red")
     temp = Template("temp",
                     pt,
                     pt2,
                     bg,
                     left=NA(0),
                     width=NA(50),
                     top=NA(0),
                     height=NA(50))
     temp.update_bounds()
     image = temp.render()
     image.save(filename="tests/images/test_can_render_color_overlay_1.png")
     overlay = pt2.color_overlay("Blue")
     image.composite(overlay, int(pt2["left"]), int(pt2["top"]))
     image.save(filename="tests/images/test_can_render_color_overlay_2.png")
Example #9
0
 def test_can_render_shadow(self):
     pt = PTL("pt",
              "Arial",
              15,
              "Black",
              content="PT",
              left=NA(0),
              top=NA(0))
     pt2 = PTL("pt2",
               "Arial",
               15,
               "Black",
               content="PT2",
               left=NA(0),
               top=AA(SA("pt.bottom"), NA(5)))
     bg = ColorBackgroundLayer("bg", content="White")
     temp = Template("temp",
                     pt,
                     pt2,
                     bg,
                     left=NA(0),
                     width=NA(50),
                     top=NA(0),
                     height=NA(50))
     temp.update_bounds()
     image = temp.render()
     image.save(filename="tests/images/test_can_render_shadow_1.png")
     shadow = pt2.shadow(2, 2, radius=4, sigma=2)
     image.composite(shadow, 0, 0)
     image.save(filename="tests/images/test_can_render_shadow_2.png")
Example #10
0
 def test_idm_works_for_text_layer_without_content(self):
     bg = ColorBackgroundLayer("bg", content="White")
     # content is None
     layer = PointTextLayer("layer",
                            "Arial",
                            12,
                            "Black",
                            left=NA(0),
                            base=NA(40))
     square = ColorLayer("sqr",
                         content="Red",
                         width=NA(20),
                         height=NA(20),
                         bottom=SA("layer.cap"),
                         left=NA(25))
     temp = Template("temp",
                     layer,
                     square,
                     bg,
                     left=NA(0),
                     width=NA(50),
                     top=NA(0),
                     height=NA(50))
     temp.update_bounds()
     temp.render().save(
         filename=
         "tests/images/test_idm_works_for_text_layer_without_content.png")
Example #11
0
    def test_template_with_add_attribute_can_render(self):
        title = PTL("title",
                    "Arial",
                    15,
                    "Black",
                    content="Hello World",
                    left=NA(0),
                    top=NA(0))
        sub_title = PTL("sub_title",
                        "Arial",
                        15,
                        "Black",
                        content="Bottom Text",
                        left=NA(10),
                        bottom=AA(SA("template.height"), NA(45,
                                                            negative=True)))
        bg = ColorBackgroundLayer("bg", content="White")
        temp = Template("temp",
                        title,
                        sub_title,
                        bg,
                        left=NA(0),
                        top=NA(0),
                        width=NA(200),
                        height=NA(200))

        temp.update_bounds()
        image = temp.render()
        image.save(
            filename=
            f"tests/images/test_template_with_add_attribute_can_render.jpg")
Example #12
0
 def test_can_make_a_text_layer_with_percent_bounds(self):
     l = PointTextLayer("layer",
                        "Arial",
                        12,
                        "Black",
                        YP40=NA(30),
                        XP50_50=SA("title.left"))
Example #13
0
 def test_cannot_make_text_layer_with_bad_coords(self):
     with pytest.raises(ValueError):
         PointTextLayer("layer",
                        "Arial",
                        12,
                        "Black",
                        test=SA("parent.height"),
                        wow=NA(12))
Example #14
0
    def test_layers_passed_in_first_without_order_are_rendered_first(
            self, save_images):
        kwargs = {
            "left": SA("parent.left"),
            "right": SA("parent.right"),
            "top": SA("parent.top"),
            "bottom": SA("parent.bottom")
        }
        l1 = ColorLayer("layer_1", content="#FF0000", **kwargs)  # red
        l2 = ColorLayer("layer_1", content="#00FF00", **kwargs)  # green
        # l1 is first, is rendered first; therefore l2 (green) should be on top
        temp = Template("temp",
                        l1,
                        l2,
                        left=NA(0),
                        width=NA(50),
                        top=NA(0),
                        height=NA(50))
        temp.update_bounds()

        green_above = temp.render()
        color_of_top_left_most_pixel = green_above.export_pixels(width=1,
                                                                 height=1)
        assert color_of_top_left_most_pixel[:3] == [0, 255,
                                                    0]  # RGBA, [1] is green

        # remake template, now l2 is first, l1 rendered last
        temp = Template("temp",
                        l2,
                        l1,
                        left=NA(0),
                        width=NA(50),
                        top=NA(0),
                        height=NA(50))
        temp.update_bounds()
        red_above = temp.render()

        color_of_top_left_most_pixel = red_above.export_pixels(width=1,
                                                               height=1)
        assert color_of_top_left_most_pixel[:3] == [255, 0, 0]
        if save_images:
            green_above.save(filename="tests/images/green_above.png")
            red_above.save(filename="tests/images/red_above.png")
Example #15
0
    def test_can_get_mean_indepth_font_metrics_for_ptl(self):
        bg = ColorBackgroundLayer("bg", content="White")
        l = PointTextLayer("l",
                           "Arial",
                           12,
                           "Black",
                           content="Hpqrs",
                           left=NA(0),
                           base=NA(20))
        l2 = PointTextLayer("l2",
                            "Arial",
                            12,
                            "Black",
                            content="e",
                            left=NA(10),
                            median=NA(50))
        # l3 = PointTextLayer("l3", "Arial", 12, "Black", content="l", left=NA(20), descender=NA(50))
        l4 = PointTextLayer("l4",
                            "Arial",
                            12,
                            "Black",
                            content="l",
                            left=NA(30),
                            cap=NA(50))
        # l5 = PointTextLayer("l5", "Arial", 12, "Black", content="o", left=NA(40), ascender=NA(50))

        temp = Template(
            "temp",
            l,
            l2,
            bg,
            left=NA(0),
            # temp = Template("temp", l, l2, l3, l4, l5, left=NA(0),
            # right=SA("l5.right"), top=NA(0), bottom=SA("l5.bottom"))
            right=SA("l.right"),
            top=NA(0),
            bottom=SA("l.bottom"))
        temp.update_bounds()
        temp.render().save(
            filename=
            "tests/images/test_can_get_mean_indepth_font_metrics_for_ptl.png")
Example #16
0
    def test_can_make_negative_numeric_attribute(self):
        """Tests if negative NAs can be initialised
        and if the different conventions will produce the same result"""
        negative_num_attr_1 = NA(-30)
        negative_num_attr_2 = NA(30, True)

        # test_layer_1 and test_layer_2 will have same left value
        title = PTL("title",
                    "Arial",
                    15,
                    "Black",
                    content="Hello World",
                    left=NA(0),
                    top=NA(0))

        test_layer_1 = ColorLayer("test_layer_1",
                                  content="Blue",
                                  left=negative_num_attr_1,
                                  right=SA("parent.right"),
                                  top=SA("title.top"),
                                  height=NA(20))

        test_layer_2 = ColorLayer("test_layer_2",
                                  content="Green",
                                  left=negative_num_attr_2,
                                  right=SA("parent.right"),
                                  top=SA("test_layer_1.top"),
                                  height=NA(20))

        temp = Template("temp",
                        title,
                        test_layer_1,
                        test_layer_2,
                        left=NA(0),
                        width=NA(100),
                        top=NA(0),
                        height=NA(100))

        temp.update_bounds()
        assert test_layer_1["left"] == test_layer_2["left"]
Example #17
0
 def test_exception_raised_if_no_existant_layer_is_referenced_in_SA(self):
     with pytest.raises(LayerDoesNotExistError):
         pt = PTL("test",
                  "Arial",
                  15,
                  "Black",
                  content="Hello",
                  left=NA(0),
                  top=NA(0))
         sq = ColorLayer("square",
                         content="Red",
                         left=NA(0),
                         top=SA("doesnotexist.bottom"),
                         width=NA(20),
                         height=NA(20))
         bg = ColorBackgroundLayer("bg", content="Green")
         bg2 = ColorBackgroundLayer("bg2", content="White")
         temp2 = Template("temp2",
                          sq,
                          bg,
                          left=NA(0),
                          width=NA(25),
                          top=NA(0),
                          height=NA(25))
         temp = Template("temp",
                         pt,
                         bg2,
                         temp2,
                         left=NA(0),
                         width=NA(100),
                         top=NA(0),
                         height=NA(100))
         temp.update_bounds()
         # from pprint import pprint
         # pprint(temp.get_layer("temp2").__dict__)
         temp.render().save(
             filename=
             "tests/images/test_exception_raised_if_no_existant_layer_is_referenced_in_SA.png"
         )
Example #18
0
    def __init__(self, deckName):
        self.RESOURCE_DIR = join(os.getcwd(), "resources")

        # self.TEST_DIR = "test_images"

        # FONTS
        self.MPLANTIN = join(self.RESOURCE_DIR, "fonts", "MPlantin.ttf")
        self.BELEREN_SC = join(self.RESOURCE_DIR, "fonts",
                               "Beleren_small_caps.ttf")
        self.BELEREN = join(self.RESOURCE_DIR, "fonts",
                            "Jace_Beleren_bold.ttf")
        self.MPLANTIN_BOLD = join(self.RESOURCE_DIR, "fonts",
                                  "MPlantin_bold.ttf")
        self.MPLANTIN_ITAL = join(self.RESOURCE_DIR, "fonts",
                                  "MPlantin_italic.ttf")
        self.RELAY = join(self.RESOURCE_DIR, "fonts", "Relay_medium.ttf")
        self.FC = "White"
        self.FLAVOR_SPLIT_COLOR = "RGBA(255, 255, 255, 0.6)"
        self.SHADOW_COLOR = "#181510"
        self.FLAVOR_SPLIT_OFFSET = 40

        self.SET_DOT_LANG_WIDTH = 5
        self.INFO_SIZE = 18
        self.NAME_SIZE = 38
        self.FLAVOR_NAME_SIZE = 25
        self.TYPE_SIZE = 33
        self.PT_LOYAL_SIZE = 40
        self.RULES_TEXT_SIZE = 25

        self.INNER_BORDER = 40
        self.INNER_RULES_BORDER = 50
        self.INNER_HEIGHT = 1040
        self.INNER_WIDTH = 745

        self.HEIGHT = 1080
        self.WIDTH = 773

        self.SPLIT_CENTER = 460
        self.SPLIT_END = 870
        self.SPLIT_HEIGHT = self.SPLIT_END - self.SPLIT_CENTER
        self.SPLIT_SHADOW_SIZE = 50

        self.OUTER_X_BORDER = (self.WIDTH - self.INNER_WIDTH) / 2
        self.TOTAL_Y_BORDER = (self.HEIGHT - self.INNER_HEIGHT)
        self.OUTER_Y_BOTTOM_BORDER = 21
        self.TOP_OUTER_BORDER = 20
        self.STANDARD_BORDER = 40
        self.BORDER = self.STANDARD_BORDER + self.OUTER_X_BORDER
        self.TOP_BORDER = self.STANDARD_BORDER + self.TOP_OUTER_BORDER
        self.BOTTOM_BORDER = self.STANDARD_BORDER + self.OUTER_Y_BOTTOM_BORDER
        self.RULES_BORDER = 50 + self.OUTER_X_BORDER
        self.BORDER_PATH = join(self.RESOURCE_DIR, "Border5.png")

        self.B = 29
        self.MIN_ART_HEIGHT = 850 - self.B
        self.B_ART_WIDTH = self.WIDTH
        self.rarity_colors = {
            "M": "#D15003",
            "R": "#DFBD6C",
            "U": "#C8C8C8",
            "C": self.FC,
            "L": self.FC,
            "T": self.FC,
        }

        self.la = AA(MA(SA("language.right"), SA("number.right")), NA(3))
        self.lmiddle = AA(
            NA(self.WIDTH / 2),
            DivA(AA(SA("artist_brush.width"), NA(3), SA("artist.width")),
                 NA(2),
                 negative=True))

        self.BOTTOM_BASE_INFO = NA(self.HEIGHT - 45)
        self.TOP_BASE_INFO = AA(SA("set.cap"), NA(-3))

        self.pdf = Image(filename=join(self.RESOURCE_DIR, "PrintPdf.png"))
        self.text_to_use = "text"
        self.PDF_SAVE_LOCATION = join("test_images", "pdfs", deckName)
        if not os.path.exists(self.PDF_SAVE_LOCATION):
            os.makedirs(self.PDF_SAVE_LOCATION)
Example #19
0
    def layers(self, card):
        art_layers = {
            "bg":
            ColorBackgroundLayer("bg", content=Color(self.SHADOW_COLOR)),
            "art":
            FillIL("art",
                   order=-5,
                   XP50=NA(self.WIDTH / 2),
                   top=NA(self.B + self.TOP_OUTER_BORDER),
                   width=NA(self.B_ART_WIDTH),
                   height=NA(self.MIN_ART_HEIGHT)),
            "border":
            ImageLayer("border",
                       content=self.BORDER_PATH,
                       left=NA(0),
                       top=NA(0))
        }
        layers = {
            "dot":
            PTL("dot",
                self.RELAY,
                25,
                self.FC,
                content=".",
                left=AA(SA("set.right"), NA(self.SET_DOT_LANG_WIDTH)),
                ycenter=SA("set.ycenter")),
            "language":
            PTL("language",
                self.RELAY,
                self.INFO_SIZE,
                self.FC,
                content="EN",
                left=AA(SA("dot.right"), NA(self.SET_DOT_LANG_WIDTH)),
                base=self.BOTTOM_BASE_INFO),
            "artist_brush":
            ResizeIL("artist_brush",
                     content=join(self.RESOURCE_DIR, "artist_brush_white.png"),
                     width=NA(20),
                     left=self.lmiddle,
                     height=SA("set.height"),
                     bottom=self.BOTTOM_BASE_INFO),
            "copyright":
            PTL("copyright",
                self.MPLANTIN,
                self.INFO_SIZE - 5,
                self.FC,
                right=NA(self.WIDTH - self.BORDER),
                bottom=self.BOTTOM_BASE_INFO),
            "name":
            PTL("name",
                self.BELEREN,
                self.NAME_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=NA(70 + self.TOP_OUTER_BORDER)),
            "flavor_name":
            PTL("flavor_name",
                self.MPLANTIN_ITAL,
                self.FLAVOR_NAME_SIZE,
                self.FC,
                left=SA("name.left"),
                base=AA(SA("name.base"), NA(self.FLAVOR_NAME_SIZE + 4))),
            "PT":
            PTL("PT",
                self.BELEREN,
                self.PT_LOYAL_SIZE,
                self.FC,
                right=NA(self.WIDTH - self.BORDER),
                base=self.BOTTOM_BASE_INFO),
            "loyalty":
            PTL("loyalty",
                self.BELEREN,
                self.PT_LOYAL_SIZE,
                self.FC,
                right=NA(self.WIDTH - self.BORDER),
                base=self.BOTTOM_BASE_INFO),
            "set":
            PTL("set",
                self.RELAY,
                self.INFO_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=self.BOTTOM_BASE_INFO),
            "number":
            PTL("number",
                self.RELAY,
                self.INFO_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=self.TOP_BASE_INFO),
            "rarity":
            PTL("rarity",
                self.RELAY,
                self.INFO_SIZE,
                self.FC,
                left=SA("artist_brush.left"),
                base=self.TOP_BASE_INFO),
            "artist":
            PTL("artist",
                self.BELEREN_SC,
                self.INFO_SIZE,
                self.FC,
                left=AA(SA("artist_brush.right"), NA(3)),
                base=self.BOTTOM_BASE_INFO),
            "mana_cost":
            ManaCost("mana_cost",
                     font=self.BELEREN,
                     font_size=self.NAME_SIZE,
                     font_color=self.FC,
                     right=NA(self.WIDTH - self.BORDER),
                     bottom=AA(SA("name.base"), NA(4))),
        }
        standard_rules = {
            "type":
            PTL("type",
                self.BELEREN,
                self.TYPE_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=AA(SA("rules.top"), NA(-10))),
            "rules":
            RulesText("rules",
                      self.MPLANTIN,
                      self.MPLANTIN_ITAL,
                      self.RULES_TEXT_SIZE,
                      self.FC,
                      self.RULES_TEXT_SIZE - 4,
                      left=NA(self.RULES_BORDER),
                      right=NA(self.WIDTH - self.RULES_BORDER),
                      base=AA(SA("rarity.cap"), NA(-6)))
        }
        split_text_layers = {
            "split_name":
            PTL("split_name",
                self.BELEREN,
                self.NAME_SIZE,
                self.FC,
                left=SA("name.left"),
                base=NA(self.SPLIT_CENTER + self.NAME_SIZE)),
            "split_mana_cost":
            ManaCost("split_mana_cost",
                     font=self.BELEREN,
                     font_size=self.NAME_SIZE,
                     font_color=self.FC,
                     right=SA("mana_cost.right"),
                     bottom=AA(SA("split_name.base"), NA(4))),
            "split_type":
            PTL("split_type",
                self.BELEREN,
                self.TYPE_SIZE,
                self.FC,
                left=SA("type.left"),
                base=AA(SA("split_rules.top"), NA(-10))),
            "split_rules":
            RulesText("split_rules",
                      self.MPLANTIN,
                      self.MPLANTIN_ITAL,
                      self.RULES_TEXT_SIZE,
                      self.FC,
                      self.RULES_TEXT_SIZE - 4,
                      left=SA("rules.left"),
                      right=SA("rules.right"),
                      base=AA(SA("split_name.cap"), NA(-6)))
        }

        split_kwargs = {
            "left": NA(0),
            "order": -5,
            "width": NA(self.B_ART_WIDTH),
            "height": NA(self.SPLIT_HEIGHT)
        }
        top_split_kwargs = {
            **split_kwargs, "YP50":
            NA((self.B + self.TOP_OUTER_BORDER + self.SPLIT_CENTER) / 2)
        }
        bottom_split_kwargs = {
            **split_kwargs, "YP50":
            NA((self.SPLIT_CENTER + self.SPLIT_END - 2) / 2)
        }

        split_art_layers = {
            "split_divider_top":
            GradL("split_divider_top",
                  start="RGBA(0,0,0,0.0)",
                  end=self.SHADOW_COLOR,
                  left=NA(0),
                  width=NA(self.WIDTH),
                  bottom=NA(self.SPLIT_CENTER),
                  height=NA(self.SPLIT_SHADOW_SIZE)),
            "split_divider_bottom":
            GradL("split_divider_bottom",
                  start=self.SHADOW_COLOR,
                  end="RGBA(0,0,0,0.0)",
                  left=NA(0),
                  width=NA(self.WIDTH),
                  top=NA(self.SPLIT_CENTER - 1),
                  height=NA(self.SPLIT_SHADOW_SIZE)),
            "split_art_top":
            Mask("split_art_top_mask",
                 FillIL("split_art_top", **top_split_kwargs),
                 **top_split_kwargs),
            "split_art_bottom":
            Mask("split_art_bottom_mask",
                 FillIL("split_art_bottom", **bottom_split_kwargs),
                 **bottom_split_kwargs)
        }
        adventure_rules = {
            "rules_box":
            Template(
                "rules_box",
                *[
                    RulesText("rules",
                              self.MPLANTIN,
                              self.MPLANTIN_ITAL,
                              self.RULES_TEXT_SIZE,
                              self.FC,
                              self.RULES_TEXT_SIZE - 4,
                              left=AA(SA("parent.xcenter"), NA(5)),
                              right=AA(SA("parent.right"),
                                       NA(self.RULES_BORDER, negative=True)),
                              ycenter=SA("template.ycenter")),
                    Template("adventure_box",
                             *[
                                 RulesText("adventure_rules",
                                           self.MPLANTIN,
                                           self.MPLANTIN_ITAL,
                                           self.RULES_TEXT_SIZE,
                                           self.FC,
                                           self.RULES_TEXT_SIZE - 4,
                                           left=NA(0),
                                           right=AA(SA("parent.width"),
                                                    NA(-5)),
                                           top=AA(SA("adventure_type.base"),
                                                  NA(6))),
                                 PTL("adventure_type",
                                     self.MPLANTIN,
                                     self.RULES_TEXT_SIZE + 3,
                                     self.FC,
                                     left=SA("adventure_name.left"),
                                     cap=AA(SA("adventure_name.base"), NA(6))),
                                 PTL("adventure_name",
                                     self.MPLANTIN,
                                     self.RULES_TEXT_SIZE + 5,
                                     self.FC,
                                     left=NA(0),
                                     cap=NA(3)),
                                 ManaCost("adventure_mana_cost",
                                          font=self.BELEREN,
                                          font_size=self.RULES_TEXT_SIZE,
                                          font_color=self.FC,
                                          right=SA("adventure_rules.right"),
                                          top=NA(0),
                                          mana_size=self.RULES_TEXT_SIZE),
                             ],
                             left=NA(self.RULES_BORDER),
                             right=AA(SA("rules.left"), NA(-10)),
                             ycenter=SA("template.ycenter"),
                             height=SA("null.height")),
                ],
                left=NA(0),
                width=NA(self.WIDTH),
                base=AA(
                    SA("self.height"), SA("rarity.cap"), NA(-6),
                    MA(SA("rules.bottom"),
                       SA("adventure_box.bottom"),
                       negative=True)),
                height=SA("template.height")),
            "type":
            PTL("type",
                self.BELEREN,
                self.TYPE_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=AA(SA("rules_box.top"),
                        MinA(SA("adventure_box.top"), SA("rules.top")),
                        NA(-10))),
        }
        if card['layout'] == 'adventure':
            layers = {**layers, **adventure_rules}
        elif card["layout"] == "split":
            layers = {**layers, **standard_rules, **split_text_layers}
            art_layers = {**art_layers, **split_art_layers}
        else:
            layers = {**layers, **standard_rules}

        return list(art_layers.values()), list(layers.values())
Example #20
0
    env["FLAVOR_SPLIT_OFFSET"] = 40

    env["MIN_ART_HEIGHT"] = 850 - env["B"]
    env["B_ART_WIDTH"] = env["WIDTH"]
    env["OUTER_X_BORDER"] = (env["WIDTH"] - env["INNER_WIDTH"]) / 2
    env["TOTAL_Y_BORDER"] = (env["HEIGHT"] - env["INNER_HEIGHT"])
    env["BORDER"] = env["STANDARD_BORDER"] + env["OUTER_X_BORDER"]
    env["TOP_BORDER"] = env["STANDARD_BORDER"] + env["TOP_OUTER_BORDER"]
    env["BOTTOM_BORDER"] = env["STANDARD_BORDER"] + env["OUTER_Y_BOTTOM_BORDER"]
    env["RULES_BORDER"] = 50 + env["OUTER_X_BORDER"]
    env["BORDER_PATH"] = join(env["RESOURCE_DIR"], "Border5.png")

    return env[key]


la = AA(MA(SA("language.right"), SA("number.right")), NA(3))
lmiddle = AA(
    NA(env("WIDTH") / 2),
    DivA(AA(SA("artist_brush.width"), NA(3), SA("artist.width")),
         NA(2),
         negative=True))

BOTTOM_BASE_INFO = NA(env("HEIGHT") - 45)
TOP_BASE_INFO = AA(SA("set.cap"), NA(-3))

art_layers = {
    "bg":
    ColorBackgroundLayer("bg", content=Color("#181510")),
    "art":
    FillIL("art",
           order=-5,
Example #21
0
    env["FLAVOR_SPLIT_OFFSET"] = 40

    env["MIN_ART_HEIGHT"] = 850 - env["B"]
    env["B_ART_WIDTH"] = env["WIDTH"]
    env["OUTER_X_BORDER"] = (env["WIDTH"] - env["INNER_WIDTH"]) / 2
    env["TOTAL_Y_BORDER"] = (env["HEIGHT"] - env["INNER_HEIGHT"])
    env["BORDER"] = env["STANDARD_BORDER"] + env["OUTER_X_BORDER"]
    env["TOP_BORDER"] = env["STANDARD_BORDER"] + env["TOP_OUTER_BORDER"]
    env["BOTTOM_BORDER"] = env["STANDARD_BORDER"] + env["OUTER_Y_BOTTOM_BORDER"]
    env["RULES_BORDER"] = 50 + env["OUTER_X_BORDER"]
    env["BORDER_PATH"] = join(env["RESOURCE_DIR"], "Border5.png")

    return env[key]


la = AA(MA(SA("language.right"), SA("number.right")), NA(3))
lmiddle = AA(
    NA(env("WIDTH") / 2),
    DivA(AA(SA("artist_brush.width"), NA(3), SA("artist.width")),
         NA(2),
         negative=True))

BOTTOM_BASE_INFO = NA(env("HEIGHT") - 45)
TOP_BASE_INFO = AA(SA("set.cap"), NA(-3))

art_layers = {
    "bg":
    ColorBackgroundLayer("bg", content=Color("#181510")),
    "art":
    FillIL("art",
           order=-5,
Example #22
0
 def test_can_make_string_attribute(self):
     SA("layer.width")
     SA("parent.XP40")
     SA("template.right")
Example #23
0
 def test_can_make_add_attribute(self):
     add_attr = AA(SA("template.height"), NA(-45))
Example #24
0
def main():
    RESOURCE_DIR = join(os.getcwd(), "resources")
    SETS = join(RESOURCE_DIR, "card_data", "sets.json")
    TEST_DIR = "test_images"

    MPLANTIN = join(RESOURCE_DIR, "fonts", "MPlantin.ttf")
    BELEREN_SC = join(RESOURCE_DIR, "fonts", "Beleren_small_caps.ttf")
    BELEREN = join(RESOURCE_DIR, "fonts", "Jace_Beleren_bold.ttf")
    MPLANTIN_BOLD = join(RESOURCE_DIR, "fonts", "MPlantin_bold.ttf")
    MPLANTIN_ITAL = join(RESOURCE_DIR, "fonts", "MPlantin_italic.ttf")
    RELAY = join(RESOURCE_DIR, "fonts", "Relay_medium.ttf")
    FC = "White"
    FLAVOR_SPLIT_COLOR = "RGBA(255, 255, 255, 0.6)"
    FLAVOR_SPLIT_OFFSET = 40

    if os.path.isfile(SETS):
        with open(SETS, "r") as f:
            sets = json.load(f)
    else:
        raise ValueError("sets.json not found.")

    myset = "WAR"
    # JSON = join(RESOURCE_DIR, "card_data", f"{myset}.json")
    # JSON = join(RESOURCE_DIR, "card_data", f"mardu_aristocrats_M20.json")
    # TOKENS = join(RESOURCE_DIR, "card_data", f"tokens.json")
    # ANGELS = join(RESOURCE_DIR, "card_data", f"mardu_angels_M20.json")
    JSON = join(RESOURCE_DIR, "set_data", f"{myset}.json")
    # SULTAI_FLASH = join(RESOURCE_DIR, "card_data", f"sultai_flash.json")

    SAVE_LOCATION = myset
    # SAVE_LOCATION = "sultai_flash"

    # JSON = SULTAI_FLASH
    # JSON = TOKENS
    """make directory in art"""
    # if not os.path.isdir(join(RESOURCE_DIR, "art", myset)): # dir does not exist
    #     os.mkdir(join(RESOURCE_DIR, "art", myset))
    """make directory in render dir"""
    if not os.path.isdir(join("test_images", "all_render",
                              SAVE_LOCATION)):  # dir does not exist
        os.mkdir(join("test_images", "all_render", SAVE_LOCATION))
    """load cards"""
    with open(JSON, "r") as f:
        cards = json.load(f)
    """load tokens"""
    # with open(TOKENS, "r") as f:
    #     tokens = json.load(f)

    BORDER = 45
    RULES_BORDER = 52
    HEIGHT = 1050
    WIDTH = 752
    SET_DOT_LANG_WIDTH = 5
    INFO_SIZE = 18
    # FONT_SIZE = 40
    NAME_SIZE = 38
    TYPE_SIZE = 33
    PT_LOYAL_SIZE = 40
    RULES_TEXT_SIZE = 25

    la = AA(MA(SA("language.right"), SA("number.right")), NA(3))
    lmiddle = AA(
        NA(WIDTH / 2),
        DivA(AA(SA("artist_brush.width"), NA(3), SA("artist.width")),
             NA(2),
             negative=True))

    art_layers = {
        "bg":
        ColorBackgroundLayer("bg", content=Color("Black")),
        "art":
        FillIL("art",
               order=-5,
               XP50=NA(WIDTH / 2),
               YP50=NA(HEIGHT / 2),
               width=NA(WIDTH),
               height=NA(HEIGHT)),
        "shadow1":
        ColorLayer("shadow1",
                   content="RGBA(0,0,0,0.4)",
                   left=NA(0),
                   width=NA(WIDTH),
                   top=NA(0),
                   bottom=SA("shadow2.top")),
        "shadow2":
        GradL("shadow2",
              start="RGBA(0,0,0,0.4)",
              end="RGBA(0,0,0,0.0)",
              left=NA(0),
              width=NA(WIDTH),
              top=SA("name.bottom"),
              height=NA(200)),
        "shadow3":
        GradL("shadow3",
              start="RGBA(0,0,0,0.0)",
              end="RGBA(0,0,0,0.7)",
              left=NA(0),
              width=NA(WIDTH),
              bottom=SA("shadow4.top"),
              top=AA(SA("type.cap"), NA(-150))),
        "shadow4":
        ColorLayer("shadow4",
                   content="RGBA(0,0,0,0.7)",
                   left=NA(0),
                   width=NA(WIDTH),
                   bottom=NA(HEIGHT + 1),
                   top=SA("rules.YP70"))
    }
    no_content_reset = {
        "dot":
        PTL("dot",
            RELAY,
            25,
            FC,
            content=".",
            left=AA(SA("set.right"), NA(SET_DOT_LANG_WIDTH)),
            ycenter=SA("set.ycenter")),
        "language":
        PTL("language",
            RELAY,
            INFO_SIZE,
            FC,
            content="EN",
            left=AA(SA("dot.right"), NA(SET_DOT_LANG_WIDTH)),
            base=NA(HEIGHT - BORDER)),
        "artist_brush":
        ResizeIL("artist_brush",
                 content=join(RESOURCE_DIR, "artist_brush_white.png"),
                 width=NA(20),
                 left=lmiddle,
                 height=SA("set.height"),
                 bottom=NA(HEIGHT - BORDER)),
        "copyright":
        PTL("copyright",
            MPLANTIN,
            INFO_SIZE - 5,
            FC,
            right=NA(WIDTH - BORDER),
            bottom=SA("set.bottom")),
    }
    layers = {
        "name":
        PTL("name", BELEREN, NAME_SIZE, FC, left=NA(BORDER), base=NA(80)),
        "type":
        PTL("type",
            BELEREN,
            TYPE_SIZE,
            FC,
            left=NA(BORDER),
            base=AA(SA("rules.top"), NA(-10))),
        "PT":
        PTL("PT",
            BELEREN,
            PT_LOYAL_SIZE,
            FC,
            right=NA(WIDTH - BORDER),
            base=SA("set.base")),
        "loyalty":
        PTL("loyalty",
            BELEREN,
            PT_LOYAL_SIZE,
            FC,
            right=NA(WIDTH - BORDER),
            base=SA("set.base")),
        "set":
        PTL("set",
            RELAY,
            INFO_SIZE,
            FC,
            left=NA(BORDER),
            base=NA(HEIGHT - BORDER)),
        "number":
        PTL("number",
            RELAY,
            INFO_SIZE,
            FC,
            left=NA(BORDER),
            base=AA(SA("set.cap"), NA(-3))),
        "rarity":
        PTL("rarity",
            RELAY,
            INFO_SIZE,
            FC,
            left=SA("artist_brush.left"),
            base=SA("number.base")),
        "artist":
        PTL("artist",
            BELEREN_SC,
            INFO_SIZE,
            FC,
            left=AA(SA("artist_brush.right"), NA(3)),
            base=SA("set.base")),
        "mana_cost":
        ManaCost("mana_cost",
                 font=BELEREN,
                 font_size=NAME_SIZE,
                 font_color=FC,
                 right=NA(WIDTH - BORDER),
                 bottom=AA(SA("name.base"), NA(4))),
        "rules":
        RulesText("rules",
                  MPLANTIN,
                  MPLANTIN_ITAL,
                  RULES_TEXT_SIZE,
                  FC,
                  RULES_TEXT_SIZE - 4,
                  left=NA(RULES_BORDER),
                  right=NA(WIDTH - RULES_BORDER),
                  bottom=AA(SA("PT.bottom"), NA(-PT_LOYAL_SIZE), NA(-5))),
        # "flavor_split": ColorLayer("flavor_split", left=NA(RULES_BORDER + FLAVOR_SPLIT_OFFSET),
        #     right=NA(WIDTH - RULES_BORDER - FLAVOR_SPLIT_OFFSET), height=NA(2),
        #     bottom=AA(SA("flavor.top"), NA(-5))),
        # "flavor": RulesText("flavor", MPLANTIN, MPLANTIN_ITAL, RULES_TEXT_SIZE, FC,
        #     RULES_TEXT_SIZE - 4, left=NA(RULES_BORDER), right=NA(WIDTH-RULES_BORDER),
        #     bottom=AA(SA("PT.bottom"), NA(-PT_LOYAL_SIZE), NA(-5))),
    }

    text_template = Template("text_temp",
                             *layers.values(),
                             *no_content_reset.values(),
                             left=NA(0),
                             width=NA(WIDTH),
                             top=NA(0),
                             height=NA(HEIGHT))
    art_template = Template("art_temp",
                            *art_layers.values(),
                            order=-5,
                            left=NA(0),
                            width=NA(WIDTH),
                            top=NA(0),
                            height=NA(HEIGHT))

    name = text_template.get_layer("name")

    with_art = list(os.listdir(join(RESOURCE_DIR, "art", myset)))
    cards = [c for c in cards if f"{c['name']}_{c['id']}.jpg" in with_art]
    cards = [c for c in cards if c['name'] == "Nicol Bolas, Dragon-God"]
    print(len(cards))

    # no_content_reset["copyright"].content = f"™ & © {datetime.now().year} Wizards of the Coast"
    # no_content_reset["copyright"].content = f"™ & © {datetime.now().year} WOTC"
    loga = math.ceil(math.log10(len(cards)))
    temp = Template("template",
                    text_template,
                    art_template,
                    left=NA(0),
                    width=NA(WIDTH),
                    top=NA(0),
                    height=NA(HEIGHT))
    temp.mana_image_format = "svg"
    temp.resource_dir = RESOURCE_DIR
    max_card_length = max(len(c['name']) for c in cards)
    row = f"| {{:0{loga}}}/{{:0{loga}}} | {{}} | {{}} | {{:07.3f}} |"
    total = 0

    for i, card in enumerate(sorted(cards, key=lambda x: x['name'])):
        start_time = time.time()
        for shadow in ["shadow3", "shadow4"]:
            l = temp.get_layer(shadow)
            l.pre_render = None

        reset_layers = list(layers) + ["art"]
        for name in reset_layers:
            layer = temp.get_layer(name)
            layer.unset_content_and_pre_render()
            # layer.content = None
            # layer.pre_render = None
            if layer.name in card:
                layer.content = card[layer.name]
        temp.get_layer("artist_brush").pre_shadow = None

        if "Creature" in card["types"]:
            layers["PT"].content = f"{card['power']}/{card['toughness']}"
        # print(card)
        # print(repr(temp.get_layer("name").content))
        count = 999
        sset = [s for s in sets if s['code'] == card['set']]
        if len(sset) == 1:
            count = sset[0]["count"]
        number = card['number'].upper().zfill(3)
        layers["number"].content = f"{number}/{count:03}"
        rarity_colors = {
            "M": "#D15003",
            "R": "#DFBD6C",
            "U": "#C8C8C8",
            "C": FC,
            "L": FC,
            "T": FC,
        }
        rarity = card["rarity"][0].upper()
        layers["rarity"].color = rarity_colors[rarity]
        layers["rarity"].content = rarity

        rules = ""
        text_to_use = "text"
        if card[text_to_use] is not None:
            rules = card[text_to_use]
        if card["flavor"] is not None:
            flavor = "\n".join(
                [f"<i>{f}</i>" for f in card['flavor'].split('\n')])
            if rules == "":
                rules = flavor
            else:
                rules += "\n" + flavor

        if rules != "":
            temp.get_layer("rules").content = rules
        art_path = join(RESOURCE_DIR, "art", card['set'], f"{card['name']}_{card['id']}.jpg") \
                .replace("//", "__")
        temp.get_layer("art").content = art_path if os.path.isfile(
            art_path) else None

        temp.update_bounds()
        render_bg = temp.get_layer("art_temp").render()
        image = render_bg.clone()
        if temp.get_layer("art").content is not None:
            render_text_shadow = temp.get_layer("text_temp").shadow(
                -4, 4, sigma=2, radius=4, color="Black")
            image.composite(render_text_shadow, left=0, top=0)
        render_text = temp.get_layer("text_temp").render()
        render_text.save(filename="test.png")
        image.composite(render_text, left=0, top=0)

        # xb = Bounds(start=BORDER - 10, end=WIDTH - BORDER + 10)
        # yb = Bounds(start=temp.get_layer("type")["top"] - 10,
        #     end=temp.get_layer("rules")['bottom'] + 10)
        # exp = render_bg.export_pixels(x=int(xb['start']), y=int(yb['start']),
        #     width=int(xb['full']), height=int(yb['full']))

        # with Image(width=int(xb['full']), height=int(yb['full']),
        #         background=Color("Transparent")) as blur_image:
        #     blur_image.import_pixels(width=int(xb['full']), height=int(yb['full']),
        #        channel_map="RGBA", storage="char", data=exp)
        #     with Image(width=blur_image.width, height=blur_image.height,
        #             background=Color("RGBA(0,0,0,0.2)")) as dark:
        #         blur_image.composite(dark, 0, 0)
        #     blur_image.blur(radius=10, sigma=5)
        #     with Image(width=blur_image.width, height=blur_image.height,
        #             background=Color("Black")) as mask:
        #         with Drawing() as ctx:
        #             ctx.fill_color = Color("White")
        #             ctx.rectangle(0, 0, width=mask.width,
        #                     height=mask.height, radius=15)
        #             ctx(mask)
        #         apply_mask(blur_image, mask)
        #     image.composite(blur_image, left=int(xb['start']), top=int(yb['start']))

        image.save(filename=join(
            "test_images", "all_render", f"{SAVE_LOCATION}",
            f"{card['name']}_{card['id']}.jpg").replace("//", "__"))
        # image.save(filename=join("test_images", "all_render", "Printing", f"{SAVE_LOCATION}", f"{card['name']}_{card['id']}.jpg").replace("//", "__"))
        # image.save(filename=join("test_images", "all_render", "Printing", f"{SAVE_LOCATION}", f"{card['name']}.jpg").replace("//", "__"))
        temp.unset_bounds_and_attributes()

        delta = time.time() - start_time
        total += delta
        if delta < .250:
            color = "green"
        elif delta < .500:
            color = "yellow"
        else:
            color = "red"
        print(f"\r{row}".format(
            i,
            len(cards) - 1,
            colored(f"{card['name']: <{max_card_length}}", color),
            colored(f"{delta:03.3f}", color), total))