예제 #1
0
파일: card.py 프로젝트: DiddiZ/pen-plots
def bar_rectangle(w, h, n):
    """
    Bar used for title and type bars
    """
    return concat([
        translate(
            circle(
                n,
                -1 / 4 * np.pi,
                1 / 4 * np.pi,
            ) * h / 2 * np.sqrt(2),
            w - h / 2,
            h / 2,
        ),
        [
            [w, h],
            [0, h],
        ],
        translate(
            circle(
                8,
                3 / 4 * np.pi,
                5 / 4 * np.pi,
            ) * h / 2 * np.sqrt(2),
            h / 2,
            h / 2,
        ),
        [
            [0, 0],
            [w, 0],
        ],
    ])
예제 #2
0
    def test_translate_stroke(self):
        from pen_plots.strokes import translate

        stroke = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0],
                           [0.0, 0.0]])

        translated = translate(stroke, 1, 2)
        expected = [[1.0, 2.0], [2.0, 2.0], [2.0, 3.0], [1.0, 3.0], [1.0, 2.0]]

        assert_array_almost_equal(translated, expected)
예제 #3
0
파일: glyph.py 프로젝트: DiddiZ/pen-plots
def glyphs_to_strokes(glyphs, font_size=21, alignment='left'):
    """
    Converts a list of glyphs to strokes. Glyphs are placed from left to right, spaced according to their margins.

    This can be considered as rendering a single line of text without line breaks.
    """
    offset = 0
    strokes = []
    for glyph in glyphs:
        strokes.extend(translate(glyph.lines, offset - glyph.left, 0))
        offset += glyph.right - glyph.left

    if alignment == 'left':  # Align left-most point to lie of y-axis
        pass
    elif alignment == 'right':  # Align right-most point to lie of y-axis
        strokes = translate(strokes, -offset, 0)
    elif alignment == 'center':  # Align center point to lie on y-axis
        strokes = translate(strokes, -offset / 2, 0)

    return scale(strokes, 25.4 / 72 * font_size / 21)
예제 #4
0
    def test_translate_strokes(self):
        from pen_plots.strokes import translate

        strokes = [
            np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0]]),
            np.array([[0.0, 1.0], [0.0, 0.0]]),
        ]

        translated = translate(strokes, 1, 2)
        expected = [
            [[1.0, 2.0], [2.0, 2.0], [2.0, 3.0]],
            [[1.0, 3.0], [1.0, 2.0]],
        ]

        self.assertEqual(len(translated), len(expected))
        for i in range(len(expected)):
            assert_array_almost_equal(translated[i], expected[i])
예제 #5
0
파일: card.py 프로젝트: DiddiZ/pen-plots
def create_card(card_title,
                card_type,
                mana_cost=None,
                oracle_text=None,
                power=None,
                toughness=None,
                loyalty=None):
    """
    Creates a MtG card with strokes.

    Parameters
    ----------
    card_title : str
        Name of the card.
    card_type : str
        Type lien of the card.
    mana_cost : str/None
        Mana cost of the card. Uses Scryfall encoding for special symbols, e.g. {R} for pne red mana. May be none to
        indicate no mana costs, e.g. for land.
    oracle_text : str/None
        Oracle text of the card. May be None to indicate no oracle text, i.e. vanilla cards.
    power, toughness : str/None
        Power and toughness of the card. May be None for non-creature cards.
    loyalty : str/None
        Loyality of the card. Mutually exclusive with power/toughness. May be None for non-planeswaker cards.
    Returns
    -------
    list of strokes
        Vectorizes card.
    """
    card_width, card_height = 63, 88
    outer_rounding = 2.5
    bottom_border_extra = 0
    bar_height = 5
    img_height = 39.3

    x_left, x_right = 4.5, card_width - 4.5

    outer_margin, inner_margin = x_left - outer_rounding, 0.5
    y_title_top = card_height - outer_rounding - outer_margin
    y_title_bottom = y_title_top - bar_height
    y_img_top = y_title_bottom - inner_margin
    y_img_bottom = y_img_top - img_height
    y_type_top = y_img_bottom - inner_margin
    y_type_bottom = y_type_top - bar_height

    x_text_left, x_text_right = x_left, x_right
    y_text_top, y_text_bottom = y_type_bottom - inner_margin, outer_rounding + outer_margin + bottom_border_extra

    margin_x_text = 0.5
    oracle_text_line_height = 8 / 3
    oracle_text_par_skip = 2 / 3
    oracle_text_font_size = 5

    strokes = []

    # Outer border
    strokes.append(rounded_rectangle(63, 88, outer_rounding, 8))
    # Outer border inner
    strokes.append(
        translate(
            rounded_rectangle(63 - outer_rounding * 2,
                              88 - outer_rounding * 2 - bottom_border_extra, 1,
                              8),
            x=outer_rounding,
            y=outer_rounding + bottom_border_extra,
        ))

    # Title bar
    strokes.append(
        translate(
            bar_rectangle(x_right - x_left, y_title_top - y_title_bottom, 8),
            x_left, y_title_bottom))

    # Image Box
    strokes.append(
        translate(rectangle(x_right - x_left, y_img_top - y_img_bottom),
                  x_left, y_img_bottom))

    # Type bar
    strokes.append(
        translate(
            bar_rectangle(x_right - x_left, y_type_top - y_type_bottom, 8),
            x_left, y_type_bottom))

    # Power/Toughness, loyality
    if power is not None and toughness is not None or loyalty is not None:
        # P/T bar
        pt_bar_width = 8 if loyalty is None else 4
        pt_bar = translate(bar_rectangle(pt_bar_width, 5, 8),
                           x_right - pt_bar_width, y_text_bottom - 1)
        pt_bar_bbox = bounding_box(pt_bar)
        strokes.append(pt_bar)

        # P/T text
        strokes.extend(
            translate(
                scale_to_fit(
                    glyphs_to_strokes(
                        line_to_glyphs(
                            power + '/' +
                            toughness if loyalty is None else loyalty),
                        font_size=7,
                        alignment='center',
                    ),
                    max_width=pt_bar_width,
                ),
                x_right - pt_bar_width / 2,
                y_text_bottom - 1 + 5 / 2,
            ))
    else:
        pt_bar_bbox = None

    # Text box
    text_box = translate(
        rectangle(x_text_right - x_text_left, y_text_top - y_text_bottom),
        x_text_left, y_text_bottom)
    if pt_bar_bbox is None:
        strokes.append(text_box)
    else:
        # Draw around P/T bar
        strokes.extend(difference([text_box], pt_bar))

    # Mana Cost
    if len(mana_cost) > 0:
        text_mana_cost = glyphs_to_strokes(line_to_glyphs(mana_cost),
                                           font_size=6,
                                           alignment='right')
        x_mana_cost_left = x_right + bounding_box(text_mana_cost)[
            0, 0] - margin_x_text
        strokes.extend(
            translate(
                scale_to_fit(
                    text_mana_cost,
                    max_width=x_right - x_left - margin_x_text * 2,
                ),
                x_right - margin_x_text,
                (y_title_bottom + y_title_top) / 2,
            ))
    else:
        x_mana_cost_left = x_right

    # Title text
    strokes.extend(
        translate(
            scale_to_fit(
                glyphs_to_strokes(line_to_glyphs(card_title), font_size=6),
                max_width=x_mana_cost_left - x_left - margin_x_text * 2,
            ),
            x_left + margin_x_text,
            (y_title_bottom + y_title_top) / 2,
        ))

    # Type Text
    strokes.extend(
        translate(
            scale_to_fit(
                glyphs_to_strokes(line_to_glyphs(card_type), font_size=6),
                max_width=x_right - x_left - margin_x_text * 2,
            ),
            x_left + margin_x_text,
            (y_type_bottom + y_type_top) / 2,
        ))

    # Oracle text
    if len(oracle_text) > 0:
        x_line_left = x_text_left + margin_x_text
        oracle_text_scale = 1
        while True:
            oracle_text_strokes = []
            oracle_text_top_offset = (
                oracle_text_line_height +
                oracle_text_par_skip) * oracle_text_scale / 2
            for oracle_text_line in oracle_text.split('\n'):
                while len(oracle_text_line) > 0:
                    x_line_right = (x_text_right if pt_bar_bbox is None
                                    or pt_bar_bbox[1, 1] < y_text_top -
                                    oracle_text_top_offset -
                                    oracle_text_par_skip * oracle_text_scale
                                    else pt_bar_bbox[0, 0]) - margin_x_text
                    n_line_chars = 42.5 * (
                        x_line_right - x_line_left - margin_x_text * 2) / (
                            x_text_right - x_text_left) / oracle_text_scale

                    line = wrap(oracle_text_line, n_line_chars)[
                        0]  # TODO Calculate wrap based on actual char sizes
                    oracle_text_line = oracle_text_line[len(line) + 1:]

                    oracle_text_strokes.extend(
                        translate(
                            scale_to_fit(
                                glyphs_to_strokes(
                                    line_to_glyphs(line),
                                    font_size=oracle_text_font_size *
                                    oracle_text_scale,
                                ),
                                max_width=x_line_right - x_line_left,
                            ),
                            x_line_left,
                            y_text_top - oracle_text_top_offset,
                        ))
                    oracle_text_top_offset += oracle_text_line_height * oracle_text_scale
                oracle_text_top_offset += oracle_text_par_skip * oracle_text_scale

            # Check if text fits
            if bounding_box(
                    oracle_text_strokes
            )[0][1] > y_text_bottom + oracle_text_par_skip * oracle_text_scale / 2:

                # Check if text doesn't collide with pt bar:
                collision = False
                if pt_bar_bbox is not None:
                    for stroke in oracle_text_strokes:
                        for p in stroke:
                            if p[0] >= pt_bar_bbox[0][0] and p[
                                    0] <= pt_bar_bbox[1][0] and p[
                                        1] >= pt_bar_bbox[0][1] and p[
                                            1] <= pt_bar_bbox[1][1]:
                                collision = True

                if not collision:
                    strokes.extend(oracle_text_strokes)
                    if oracle_text_scale < 1:
                        print('Scaled oracle text to %f' % oracle_text_scale)
                    break
            oracle_text_scale *= 0.99

    return strokes