R/utils-opt.R

Defines functions get_bleed_color get_piece_opt_helper get_ps_color get_ps_text get_ps_cex get_ps_fontsize get_ps_fontfamily get_ps_fontface get_ps_element get_rank_fontsize get_dm_fontsize get_suit_fontsize get_dm_cex get_dm_fontfamily get_dm_fontface are_suits_dm get_suit_cex get_suit_fontface get_suit_fontfamily get_suit_fonts get_rank_fontface get_rank_fontfamily get_rank_cex get_rank_symbol use_suit_as_ace expand_rank_elements expand_suit_elements get_suit_symbols get_rank_symbols get_suit_symbol get_edge_color get_mat_width get_mat_color get_gridline_lex get_gridline_color get_suit_color get_background_color get_dm_color get_dm_text get_dm_symbols get_ps_r get_ps_t get_dm_r get_dm_t is_suited should_invert get_suit_color_helper get_n_vertices get_shape get_shape_r get_shape_t get_border_lex get_border_color get_border_colors get_background_color_helper is_edge make_get_style_fn check_spdx_id warn_cfg is_legit_piece is_legit_suit is_legit_rank is_legit_style is_legit_cfg_style get_style_element has_rank get_side get_piece

get_piece <- function(piece_side) {
    strsplit(piece_side, "_")[[1]][1]
}
get_side <- function(piece_side) {
    strsplit(piece_side, "_")[[1]][2]
}

has_rank <- function(cs) {
    !(cs %in% c("tile_back", "coin_back", "suitdie_face",
                "pawn_face", "pawn_back", "belt_face",
                "saucer_face", "saucer_back"))
}

PYRAMID_WIDTHS <- seq(from = 1/2, to = 27/32, length.out = 6)
PYRAMID_HEIGHTS <- 1.538842 * PYRAMID_WIDTHS
PYRAMID_DIAGONALS <- sqrt(PYRAMID_HEIGHTS^2 + (0.5*PYRAMID_WIDTHS)^2)
PYRAMID_LAYOUT_WIDTHS <- PYRAMID_HEIGHTS
PYRAMID_LAYOUT_HEIGHTS <- 2*PYRAMID_DIAGONALS
W <- 3/16
S <- 1
MATCHSTICK_WIDTHS <- c(2*W, rep(W, 5))
MATCHSTICK_HEIGHTS <- c(2*W, S-W, sqrt(2)*S-W, 2*S-W, sqrt(5*S^2)-W, 2*sqrt(2)*S-W)

# nolint start
# piece_side="pawn_face"
# suit=0
# rank=0
# style="font"
#
# if(is.na(piece_side)) {
#     piece <- NULL
# } else {
#     piece <- get_piece(piece_side)
# }
# suited <- is_suited(piece_side, suit, cfg) %||% FALSE
# piece_affixes <- c(paste0(".", piece_side), paste0(".", piece), "")
# piece_score <- c(2, 1, 0)
# rank_affixes <- c(paste0(".r", rank), "")
# rank_score <- c(1, 0)
# suit_affixes <- c(paste0(".s", suit), ifelse(suited, ".suited", ".unsuited"), "")
# suit_score <- c(2, 1, 0)
# dfs <- expand.grid(piece_affixes, rank_affixes, suit_affixes, stringsAsFactors=FALSE)
# names(dfs) <- c("piece", "rank", "suit")
# dfs$order <- 1:nrow(dfs)
# dfs <- left_join(dfs, data.frame(piece=piece_affixes, piece_score, stringsAsFactors=FALSE), by="piece")
# dfs <- left_join(dfs, data.frame(rank=rank_affixes, rank_score, stringsAsFactors=FALSE), by="rank")
# dfs <- left_join(dfs, data.frame(suit=suit_affixes, suit_score, stringsAsFactors=FALSE), by="suit")
# dfs <- mutate(dfs, score = 1e3 * piece_score + 1e2 * rank_score + 1e1 * suit_score,
#               affix = paste0(suit, rank, piece))
# dfs <- arrange(dfs, desc(score))
# dfs$order
# nolint end

style_ordering <- c(1, 7, 13, 4, 10, 16, 2, 8, 14, 5, 11, 17, 3, 9, 15, 6, 12, 18)

get_style_element <- function(style, piece_side=NA, cfg=list(), default=NULL, suit=0, rank=0) {

    if (is.na(piece_side)) {
        piece <- NULL
    } else {
        piece <- get_piece(piece_side)
    }
    suited <- is_suited(piece_side, suit, rank, cfg) %||% FALSE

    piece_affixes <- c(paste0(".", piece_side), paste0(".", piece), "")
    rank_affixes <- c(paste0(".r", rank), "")
    suit_affixes <- c(paste0(".s", suit), ifelse(suited, ".suited", ".unsuited"), "")
    dfs <- expand.grid(piece_affixes, rank_affixes, suit_affixes, stringsAsFactors=FALSE)
    names(dfs) <- c("piece", "rank", "suit")
    affixes <- paste0(dfs$suit, dfs$rank, dfs$piece)[style_ordering]

    for (affix in affixes) {
        string <- paste0(style, affix)
        value <- cfg[[string]]
        if (!is.null(value)) return(value)
    }
    return(default)
}

is_legit_cfg_style <- function(cfg_style) {
    # style
    # style.suit
    # style.rank
    # style.piece
    # style.suit.rank
    # style.suit.piece
    # style.rank.piece
    # style.suit.rank.piece
    ss <- cleave2(cfg_style, sep="\\.")
    if (!is_legit_style(ss[1])) return(FALSE)
    if (length(ss) == 2) {
        return(is_legit_suit(ss[2]) || is_legit_rank(ss[2]) || is_legit_piece(ss[2]))
    }
    if (length(ss) == 3) {
        return((is_legit_suit(ss[2]) && (is_legit_rank(ss[3]) || is_legit_piece(ss[3]))) ||
                  (is_legit_rank(ss[2]) && is_legit_piece(ss[3])))
    }
    if (length(ss) == 4) {
        return(is_legit_suit(ss[2]) && is_legit_rank(ss[3]) && is_legit_piece(ss[4]))
    }
    if (length(ss) > 4) return(FALSE)
    TRUE
}

styles <- c(paste(c("ps", "dm"),
                  rep(c("text", "fontface", "fontfamily", "fontsize", "cex", "t", "r", "color"), each=2),
                  sep="_"),
            "shape", "shape_t", "shape_r", "background_color",
            "invert_colors", "border_color", "border_lex",
            "gridline_color", "gridline_lex", "edge_color", "annotation_color",
            "mat_color", "mat_width", "suit_color",
            paste(c("rank", "suit"),
                  rep(c("text", "fontface", "fontfamily", "cex"), each=2),
                  sep="_"),
            "use_suit_as_ace", "fontfamily", "fontface", "cex", "n_ranks", "n_suits",
            "coin_arrangement", "die_arrangement",
            "width", "height", "depth",
            "grob_fn", "op_grob_fn", "grob_with_bleed_fn",
            "obj_fn", "rayrender_fn", "rayvertex_fn", "rgl_fn",
            "lacks_rank", "lacks_suit",
            "title", "description", "credit", "copyright", "spdx_id")
is_legit_style <- function(style) {
    style %in% styles
}
is_legit_rank <- function(rank) {
    grepl("r[[:digit:]]+", rank)
}
is_legit_suit <- function(suit) {
    (suit %in% c("suited", "unsuited")) || grepl("s[[:digit:]]", suit)
}
pieces <- c(paste0(rep(c("tile", "coin", "pawn", "saucer", "matchstick", "pyramid", "bit", "board", "card"), 3),
                   rep(c("", "_face", "_back"), each=9)),
            "die", "belt", "die_face", "belt_face", "pyramid_left", "pyramid_right")
is_legit_piece <- function(piece) {
    piece %in% pieces
}
warn_cfg <- function(cfg) {
    for (nn in names(cfg)) {
        if (!is_legit_cfg_style(nn)) {
            warn(paste(nn, "is not a recognized configuration"))
        }
    }
    if (!is.null(cfg$spdx_id)) {
        check_spdx_id(cfg$spdx_id)
    }
}

check_spdx_id <- function(spdx_id) {
    if (!(spdx_id %in% piecepackr::spdx_license_list$id)) {
        warn(c(sprintf("'%s' not recognized as an appropriate SPDX Identifier.", spdx_id),
               i = "See https://spdx.org/licenses/ for list of SPDX Identifiers."),
             class = "piecepackr_unrecognized_spdx_id")
    } else if (piecepackr::spdx_license_list[spdx_id, "deprecated"]) {
        inform(c(sprintf("'%s' is a deprecated SPDX Identifier.", spdx_id),
                 i = "See https://spdx.org/licenses/ for list of SPDX Identifiers."),
               class = "piecepackr_deprecated_spdx_id")
    }
}

make_get_style_fn <- function(style, default) {
    function(cfg=list()) get_style_element(style, cfg=cfg, default=default)
}

is_edge <- function(piece_side) {
    (get_side(piece_side) %in% c("top", "left", "right", "base")) &&
    (get_piece(piece_side) != "pyramid")
}

get_background_color_helper <- function(piece_side, suit, rank, cfg) {
    default <- ifelse(is_edge(piece_side),
                      get_edge_color(paste0(get_piece(piece_side), "_face"), suit, rank, cfg),
                      "white")
    colors <- col_cleave(get_style_element("background_color", piece_side, cfg, default, suit, rank))
    expand_suit_elements(colors, "background_colors", piece_side, cfg)[suit]
}

get_border_colors <- function(piece_side=NA, suit=0, rank=0, cfg=list(), expand=TRUE) {
    border_colors <- col_cleave(get_style_element("border_color", piece_side, cfg, "grey", suit, rank))
    if (expand)
        border_colors <- expand_suit_elements(border_colors, "border_colors", piece_side, cfg)
    border_colors
}

get_border_color <- function(piece_side, suit, rank, cfg) {
    get_border_colors(piece_side, suit, rank, cfg)[suit]
}

get_border_lex <- function(piece_side, suit, rank, cfg) {
    lex <- get_style_element("border_lex", piece_side, cfg, 1, suit, rank)
    lex
}

get_shape_t <- function(piece_side, suit, rank, cfg) {
    t <- numeric_cleave(get_style_element("shape_t", piece_side, cfg, 90, suit, rank))
    t <- expand_suit_elements(t, "shape_t", piece_side, cfg)
    t[suit]
}

get_shape_r <- function(piece_side, suit, rank, cfg) {
    shape <- get_shape(piece_side, suit, rank, cfg)
    piece <- get_piece(piece_side)
    default <- switch(shape,
                      kite = 0.25,
                      roundrect = switch(piece,
                                         tile = 0.12,
                                         0.06),
                      0.2)
    r <- numeric_cleave(get_style_element("shape_r", piece_side, cfg, default, suit, rank))
    r <- expand_suit_elements(r, "shape_r", piece_side, cfg)
    r[suit]
}

get_shape <- function(piece_side, suit, rank, cfg) {
    default <- switch(piece_side,
               coin_back = "circle",
               coin_face = "circle",
               bit_face = "circle",
               bit_back = "circle",
               pawn_face = "halma",
               pawn_back = "halma",
               saucer_face = "circle",
               saucer_back = "circle",
               pyramid_face = "pyramid",
               pyramid_left = "pyramid",
               pyramid_right = "pyramid",
               pyramid_back = "pyramid",
               "rect")
    get_style_element("shape", piece_side, cfg, default, suit, rank)
}

get_n_vertices <- function(shape) {
    as.numeric(gsub("convex|concave", "", shape))
}

get_suit_color_helper <- function(piece_side, suit, rank, cfg=list()) {
    default <- ifelse(is_edge(piece_side),
                      get_edge_color(paste0(get_piece(piece_side), "_face"), suit, rank, cfg),
                      "#D55E00,#000000,#009E73,#56B4E9,#E69F00")
    suit_colors <- col_cleave(get_style_element("suit_color", piece_side, cfg,
                            default, suit, rank))
    suit_colors <- expand_suit_elements(suit_colors, "suit_colors", piece_side, cfg)
    n_suits <- cfg$n_suits
    ifelse(suit <= n_suits, suit_colors[suit], suit_colors[n_suits + 1L])
}

should_invert <- function(piece_side, suit, rank, cfg) {
    should_inverts <- get_style_element("invert_colors", piece_side, cfg, FALSE, suit, rank)
    expand_suit_elements(should_inverts, "should_inverts", piece_side, cfg)[suit]
}

is_suited <- function(piece_side, suit, rank, cfg) {
    if (is.na(piece_side))
        FALSE
    else
        !(piece_side %in% cfg$lacks_suit) && (suit <= cfg$n_suits + 1L)
}

get_dm_t <- function(piece_side, suit, rank, cfg) {
    default <- ifelse(piece_side %in% c("tile_face", "die_face", "suitdie_face"), 135, 90)
    default <- ifelse(piece_side == "matchstick_face" && rank == 1, 135, default)
    t <- numeric_cleave(get_style_element("dm_t", piece_side, cfg, default, suit, rank))
    expand_suit_elements(t, "dm_t", piece_side, cfg)[suit]
}
get_dm_r <- function(piece_side, suit, rank, cfg) {
    shape <- get_shape(piece_side, suit, rank, cfg)
    r_corner <- sqrt(0.25^2 + 0.25^2)
    default <- switch(shape,
                     rect = switch(piece_side,
                                   matchstick_face = ifelse(rank > 1, 0.4, r_corner),
                                   r_corner),
                     circle = switch(piece_side,
                                     saucer_face = 0.3,
                                     saucer_back = 0.3,
                                     r_corner),
                     halma = 0.25,
                     pyramid = 0.1,
                     0.3)
    r <- numeric_cleave(get_style_element("dm_r", piece_side, cfg, default, suit, rank))
    expand_suit_elements(r, "dm_r", piece_side, cfg)[suit]
}

get_ps_t <- function(piece_side, suit, rank, cfg) {
    shape <- get_shape(piece_side, suit, rank, cfg)
    default <- switch(shape, halma=-90, pyramid=-90, 0)
    t <- numeric_cleave(get_style_element("ps_t", piece_side, cfg, default, suit, rank))
    expand_suit_elements(t, "ps_t", piece_side, cfg)[suit]
}
get_ps_r <- function(piece_side, suit, rank, cfg) {
    shape <- get_shape(piece_side, suit, rank, cfg)
    default <- switch(shape, halma=0.25, pyramid=0.25, 0.0)
    r <- numeric_cleave(get_style_element("ps_r", piece_side, cfg, default, suit, rank))
    expand_suit_elements(r, "ps_r", piece_side, cfg)[suit]
}

get_dm_symbols <- function(piece_side, suit=0, rank=0, cfg=list()) {
    default <- {
        if (is_edge(piece_side)) {
            dm_symbols <- ""
        } else if (piece_side %in% c("coin_back", "coin_face")) {
            dm_symbols <- "\u25cf"
        } else if (piece_side %in% c("saucer_back", "saucer_face")) {
            dm_symbols <- "\u25b2"
        } else if (piece_side %in% c("pawn_face", "pyramid_face")) {
            dm_symbols <- "\u0298\u0298"
        } else if (piece_side %in% c("suitdie_face", "pawn_back",
                                         "belt_face", "tile_back", "matchstick_back", "card_back",
                                         "pyramid_left", "pyramid_right", "pyramid_back")) {
            dm_symbols <- ""
        } else {
            dm_symbols <- get_suit_symbols(piece_side, suit, rank, cfg)
        }
    }
    default <- paste(default, collapse=",")
    dm_symbols <- cleave2(get_style_element("dm_text", piece_side, cfg, default, suit, rank))
    dm_symbols <- expand_suit_elements(dm_symbols, "suit_symbols", piece_side, cfg)
    dm_symbols
}

get_dm_text <- function(piece_side, suit, rank, cfg) {
    get_dm_symbols(piece_side, suit, rank, cfg)[suit]
}

get_dm_color <- function(piece_side, suit, rank, cfg) {
    default <- get_suit_color(piece_side, suit, rank, cfg)
    colors <- get_style_element("dm_color", piece_side, cfg, default, suit, rank)
    colors <- col_cleave(colors)
    colors <- expand_suit_elements(colors, "suit_colors", piece_side, cfg)
    colors[suit]
}

get_background_color <- function(piece_side, suit, rank, cfg) {
    bcol <- get_background_color_helper(piece_side, suit, rank, cfg)
    scol <- get_suit_color_helper(piece_side, suit, rank, cfg)
    if (should_invert(piece_side, suit, rank, cfg))
        scol
    else
        bcol
}

get_suit_color <- function(piece_side, suit, rank, cfg) {
    bcol <- get_background_color_helper(piece_side, suit, rank, cfg)
    scol <- get_suit_color_helper(piece_side, suit, rank, cfg)
    if (should_invert(piece_side, suit, rank, cfg))
        bcol
    else
        scol
}
get_gridline_color <- function(piece_side, suit, rank, cfg) {
    default <- switch(piece_side,
                      tile_back = get_suit_color(piece_side, cfg$n_suits + 1L, rank, cfg),
                      board_face = get_suit_color(piece_side, suit, rank, cfg),
                      board_back = get_suit_color(piece_side, suit, rank, cfg),
                      "transparent")
    colors <- get_style_element("gridline_color", piece_side, cfg, default, suit, rank)
    colors <- col_cleave(colors)
    colors <- expand_suit_elements(colors, "gridline_colors", piece_side, cfg)
    colors[suit]
}

get_gridline_lex <- function(piece_side, suit, rank, cfg) {
    lex <- get_style_element("gridline_lex", piece_side, cfg, 1, suit, rank)
    lex
}

get_mat_color <- function(piece_side, suit, rank, cfg) {
    default <- {
        if (piece_side %in% c("belt_face", "saucer_face", "saucer_back")) {
            get_suit_color(piece_side, suit, rank, cfg)
        } else {
            "transparent"
        }
    }
    colors <- get_style_element("mat_color", piece_side, cfg, default, suit, rank)
    colors <- col_cleave(colors)
    colors <- expand_suit_elements(colors, "suit_colors", piece_side, cfg)
    colors[suit]
}
get_mat_width <- function(piece_side, suit, rank, cfg) {
    default <- {
        if (piece_side == "belt_face") {
            "0.2,0"
        } else if (piece_side %in% c("saucer_face", "saucer_back")) {
            "0.1428571"  # 1/7 which mimics 5/8" pawn in 7/8" saucer
        } else {
            "0"
        }
    }
    widths <- get_style_element("mat_width", piece_side, cfg, default, suit, rank)
    widths <- numeric_cleave(widths)
}

get_edge_color <- function(piece_side, suit, rank, cfg) {
    background_color <- get_background_color(piece_side, suit=suit, rank=rank, cfg)
    neutral_col <- get_background_color("tile_back", suit=cfg$n_suits + 1L, rank=0L, cfg)

    piece <- get_piece(piece_side)
    default <- switch(piece,
                    bit = background_color,
                    pawn = background_color,
                    die = background_color,
                    matchstick = get_background_color("matchstick_back", suit=suit, rank=rank, cfg),
                    pyramid = background_color,
                    neutral_col)
    colors <- get_style_element("edge_color", piece_side, cfg, default, suit, rank)
    colors <- col_cleave(colors)
    colors <- expand_suit_elements(colors, "suit_colors", piece_side, cfg)
    colors[suit]
}

get_suit_symbol <- function(piece_side, suit, rank, cfg) {
    get_suit_symbols(piece_side, suit, rank, cfg)[suit]
}

get_rank_symbols <- function(piece_side=NA, suit=0, rank=0, cfg=list(), expand=TRUE) {
    default <- "n,a,2,3,4,5"
    rank_symbols <- cleave2(get_style_element("rank_text", piece_side, cfg, default, suit, rank))
    if (expand)
        rank_symbols <- expand_rank_elements(rank_symbols, "rank_symbols", piece_side, cfg)
    rank_symbols
}
get_suit_symbols <- function(piece_side=NA, suit=0, rank=0, cfg=list(), expand=TRUE) {
    default <- "\u2665,\u2660,\u2663,\u2666,\u263c"
    suit_symbols <- cleave2(get_style_element("suit_text", piece_side, cfg, default, suit, rank))
    if (expand)
        suit_symbols <- expand_suit_elements(suit_symbols, "suit_symbols", piece_side, cfg)
    suit_symbols
}

expand_suit_elements <- function(elements, style, piece_side, cfg) {
    n_suits <- cfg$n_suits
    if (length(elements) < n_suits) {
        elements <- rep(elements, length.out=n_suits + 1)
    } else if (length(elements) == n_suits) {
        elements <- c(elements, switch(style, cex=1.0, suit_colors="grey", ""))
    }
    if (length(elements) == n_suits + 1L) {
        elements <- c(elements, switch(style,
                           suit_symbols = switch(ifelse(is.na(piece_side), "NA", piece_side),
                                suitdie_face = "", die_face = "", elements[n_suits + 1L]),
                           gridline_colors = NA,
                           elements[n_suits + 1L]))
    }
    elements
}

expand_rank_elements <- function(elements, style, piece_side, cfg) {
    n_ranks <- cfg$n_ranks
    if (length(elements) < n_ranks) {
        elements <- rep(elements, length.out=n_ranks)
    }
    if (length(elements) == n_ranks)
        elements <- c(elements, switch(style, rank_symbols = "", elements[n_ranks]))
    elements
}

use_suit_as_ace <- function(piece_side=NA, suit=0, rank=0, cfg=list()) {
    use_suit_as_ace <- get_style_element("use_suit_as_ace", piece_side, cfg, FALSE, suit, rank)
    ifelse(use_suit_as_ace && rank == 2, TRUE, FALSE)
}

get_rank_symbol <- function(piece_side, suit, rank, cfg) {
    if (use_suit_as_ace(piece_side, suit, rank, cfg)) {
        suit_symbols <- get_suit_symbols(piece_side, suit, rank, cfg, expand=FALSE)
        expand_suit_elements(suit_symbols, "rank_suit_symbols", piece_side, cfg)[suit]
    } else {
        get_rank_symbols(piece_side, suit, rank, cfg)[rank]
    }
}

get_rank_cex <- function(piece_side, suit, rank, cfg) {
    if (use_suit_as_ace(piece_side, suit, rank, cfg)) {
        get_suit_cex(piece_side, suit, rank, cfg)
    } else {
        cex <- numeric_cleave(get_style_element("rank_cex", piece_side, cfg, 1.0, suit, rank))
        expand_rank_elements(cex, "cex", piece_side, cfg)[rank]
    }
}
get_rank_fontfamily <- function(piece_side, suit, rank, cfg) {
    if (use_suit_as_ace(piece_side, suit, rank, cfg)) {
        get_suit_fontfamily(piece_side, suit,  rank, cfg)
    } else {
        fontfamilies <- cleave2(get_style_element("rank_fontfamily", piece_side, cfg,
                                                  cfg$fontfamily %||% "sans", suit, rank))
        expand_rank_elements(fontfamilies, "font", piece_side, cfg)[rank]
    }
}
get_rank_fontface <- function(piece_side, suit, rank, cfg) {
    if (use_suit_as_ace(piece_side, suit, rank, cfg)) {
        get_suit_fontface(piece_side, suit,  rank, cfg)
    } else {
        fontfaces <- cleave2(get_style_element("rank_fontface", piece_side, cfg, cfg$fontface %||% "plain", suit, rank))
        expand_rank_elements(fontfaces, "fontface", piece_side, cfg)[rank]
    }
}
get_suit_fonts <- function(piece_side, suit, rank, cfg) {
    fonts <- cleave2(get_style_element("suit_fontfamily", piece_side, cfg, cfg$fontfamily %||% "sans", suit, rank))
    expand_suit_elements(fonts, "font", piece_side, cfg)
}
get_suit_fontfamily <- function(piece_side, suit, rank, cfg) {
    get_suit_fonts(piece_side, suit, rank, cfg)[suit]
}
get_suit_fontface <- function(piece_side, suit, rank, cfg) {
    fontfaces <- cleave2(get_style_element("suit_fontface", piece_side, cfg, cfg$fontface %||% "plain", suit, rank))
    expand_suit_elements(fontfaces, "fontface", piece_side, cfg)[suit]
}
get_suit_cex <- function(piece_side, suit, rank, cfg) {
    cex <- numeric_cleave(get_style_element("suit_cex", piece_side, cfg, 1.0, suit, rank))
    expand_suit_elements(cex, "cex", piece_side, cfg)[suit]
}
are_suits_dm <- function(piece_side, suit, rank, cfg) {
    identical(get_dm_symbols(piece_side, suit, rank, cfg),
              get_suit_symbols(piece_side, suit, rank, cfg))
}
get_dm_fontface <- function(piece_side, suit, rank, cfg) {
    if (are_suits_dm(piece_side, suit, rank, cfg)) {
        default <- get_suit_fontface(piece_side, suit, rank, cfg)
    } else {
        default <- cfg$fontface %||% "plain"
    }
    fonts <- cleave2(get_style_element("dm_fontface", piece_side, cfg, default))
    expand_suit_elements(fonts, "fontface", piece_side, cfg)[suit]
}
get_dm_fontfamily <- function(piece_side, suit, rank, cfg) {
    if (are_suits_dm(piece_side, suit, rank, cfg)) {
        default <- get_suit_fontfamily(piece_side, suit, rank, cfg)
    } else {
        default <- cfg$fontfamily %||% "sans"
    }
    fonts <- cleave2(get_style_element("dm_fontfamily", piece_side, cfg, default))
    expand_suit_elements(fonts, "font", piece_side, cfg)[suit]
}
get_dm_cex <- function(piece_side, suit, rank, cfg) {
    if (are_suits_dm(piece_side, suit, rank, cfg)) {
        default <- get_suit_cex(piece_side, suit, rank, cfg)
    } else {
        default <- 1.0
    }
    cex <- numeric_cleave(get_style_element("dm_cex", piece_side, cfg, default, suit, rank))
    expand_suit_elements(cex, "cex", piece_side, cfg)[suit]
}

get_suit_fontsize <- function(piece_side, suit, rank, cfg) {
    default <- switch(piece_side,
                 "belt_face" = 22,
                 "coin_back" = 34,
                 "pawn_face" = 28,
                 "pawn_back" = 28,
                 "bit_back" = 34,
                 "saucer_back" = 28,
                 "saucer_face" = 28,
                 "suitdie_face" = 32,
                 "pyramid_face" = 48 * PYRAMID_WIDTHS[rank],
                 "pyramid_back" = 48 * PYRAMID_WIDTHS[rank],
                 24)
    get_style_element("suit_fontsize", piece_side, cfg, default, suit, rank)
}

get_dm_fontsize <- function(piece_side, suit, rank, cfg) {
    default <- switch(piece_side,
                 "tile_face" = 40,
                 "pawn_face" = 12,
                 "pawn_back" = 12,
                 "pyramid_face" = 12 * PYRAMID_WIDTHS[rank],
                 "card_face" = 32,
                 12)
    get_style_element("dm_fontsize", piece_side, cfg, default, suit, rank)
}

get_rank_fontsize <- function(piece_side, suit, rank, cfg) {
    default <- switch(piece_side,
                 "die_face" = 20,
                 "coin_face" = 28,
                 "tile_face" = 72,
                 "bit_face" = 28,
                 "pyramid_left"  = 48 * PYRAMID_WIDTHS[rank],
                 "pyramid_right" = 48 * PYRAMID_WIDTHS[rank],
                 "card_face" = 28,
                 20)
    get_style_element("rank_fontsize", piece_side, cfg, default, suit, rank)
}


get_ps_element <- function(piece_side, suit_element, rank_element, neither_element=NA) {
    if (piece_side %in% c("coin_face", "die_face", "tile_face",
                          "pyramid_left", "pyramid_right", "matchstick_face",
                          "bit_face", "card_face")) {
        rank_element
    } else if (piece_side %in% c("tile_back", "matchstick_back", "card_back")) {
        neither_element
    } else if (is_edge(piece_side)) {
        neither_element
    } else {
        suit_element
    }
}
get_ps_fontface <- function(piece_side, suit, rank, cfg) {
    rank_fontface <- get_rank_fontface(piece_side, suit, rank, cfg)
    suit_fontface <- get_suit_fontface(piece_side, suit, rank, cfg)
    default <- get_ps_element(piece_side, suit_fontface, rank_fontface, "plain")
    get_style_element("ps_fontface", piece_side, cfg, default, suit, rank)
}
get_ps_fontfamily <- function(piece_side, suit, rank, cfg) {
    rank_font <- get_rank_fontfamily(piece_side, suit, rank, cfg)
    suit_font <- get_suit_fontfamily(piece_side, suit, rank, cfg)
    default <- get_ps_element(piece_side, suit_font, rank_font)
    get_style_element("ps_fontfamily", piece_side, cfg, default, suit, rank)
}
get_ps_fontsize <- function(piece_side, suit, rank, cfg) {
    rank_fontsize <- get_rank_fontsize(piece_side, suit, rank, cfg)
    suit_fontsize <- get_suit_fontsize(piece_side, suit, rank, cfg)
    default <- get_ps_element(piece_side, suit_fontsize, rank_fontsize)
    get_style_element("ps_fontsize", piece_side, cfg, default, suit, rank)
}
get_ps_cex <- function(piece_side, suit, rank, cfg) {
    rank_cex <- get_rank_cex(piece_side, suit, rank, cfg)
    suit_cex <- get_suit_cex(piece_side, suit, rank, cfg)
    default <- get_ps_element(piece_side, suit_cex, rank_cex)
    get_style_element("ps_cex", piece_side, cfg, default, suit, rank)
}
get_ps_text <- function(piece_side, suit, rank, cfg) {
    rank_symbol <- get_rank_symbol(piece_side, suit, rank, cfg)
    suit_symbol <- get_suit_symbol(piece_side, suit, rank, cfg)
    default <- get_ps_element(piece_side, suit_symbol, rank_symbol, "")
    get_style_element("ps_text", piece_side, cfg, default, suit, rank)
}
get_ps_color <- function(piece_side, suit, rank, cfg) {
    default <- get_suit_color(piece_side, suit, rank, cfg)
    get_style_element("ps_color", piece_side, cfg, default, suit, rank)
}
get_piece_opt_helper <- function(piece_side, suit, rank, cfg) {
    # Shape
    shape <- get_shape(piece_side, suit, rank, cfg)
    shape_r <- get_shape_r(piece_side, suit, rank, cfg)
    shape_t <- get_shape_t(piece_side, suit, rank, cfg)
    back <- grepl("back", piece_side)

    # Additional colors
    background_color <- get_background_color(piece_side, suit, rank, cfg)
    border_color <- get_border_color(piece_side, suit, rank, cfg)
    border_lex <- get_border_lex(piece_side, suit, rank, cfg)
    gridline_color <- get_gridline_color(piece_side, suit, rank, cfg)
    gridline_lex <- get_gridline_lex(piece_side, suit, rank, cfg)
    mat_color <- get_mat_color(piece_side, suit, rank, cfg)
    mat_width <- get_mat_width(piece_side, suit, rank, cfg)
    edge_color <- get_edge_color(piece_side, suit, rank, cfg)

    # Overall scaling factor
    cex <- cfg[["cex"]] %||% 1.0

    # Directional mark symbol
    dm_color <- get_dm_color(piece_side, suit, rank, cfg)
    dm_cex <- get_dm_cex(piece_side, suit, rank, cfg)
    dm_fontfamily <- get_dm_fontfamily(piece_side, suit, rank, cfg)
    dm_fontface <- get_dm_fontface(piece_side, suit, rank, cfg)
    dm_fontsize <- cex * dm_cex * get_dm_fontsize(piece_side, suit, rank, cfg)
    dm_text <- get_dm_text(piece_side, suit, rank, cfg)
    dm_t <- get_dm_t(piece_side, suit, rank, cfg)
    dm_r <- get_dm_r(piece_side, suit, rank, cfg)
    dm_x <- to_x(dm_t, dm_r) + 0.5
    dm_y <- to_y(dm_t, dm_r) + 0.5

    # Primary symbol
    ps_color <- get_ps_color(piece_side, suit, rank, cfg)
    ps_cex <- get_ps_cex(piece_side, suit, rank, cfg)
    ps_fontfamily <- get_ps_fontfamily(piece_side, suit, rank, cfg)
    ps_fontface <- get_ps_fontface(piece_side, suit, rank, cfg)
    ps_fontsize <- cex * ps_cex * get_ps_fontsize(piece_side, suit, rank, cfg)
    ps_text <- get_ps_text(piece_side, suit, rank, cfg)
    ps_t <- get_ps_t(piece_side, suit, rank, cfg)
    ps_r <- get_ps_r(piece_side, suit, rank, cfg)
    ps_x <- to_x(ps_t, ps_r) + 0.5
    ps_y <- to_y(ps_t, ps_r) + 0.5

    # Extra info
    rank_text <- get_rank_symbol(piece_side, suit, rank, cfg)
    suit_text <- get_suit_symbol(piece_side, suit, rank, cfg)

    opt <- list(shape=shape, shape_r=shape_r, shape_t=shape_t, back=back,
                background_color=background_color, edge_color=edge_color,
                border_color=border_color, border_lex=border_lex,
                gridline_color=gridline_color, gridline_lex=gridline_lex,
                mat_color=mat_color, mat_width=mat_width,
                dm_color=dm_color, dm_text=dm_text,
                dm_fontsize=dm_fontsize,
                dm_fontfamily=dm_fontfamily, dm_fontface=dm_fontface,
                dm_x=dm_x, dm_y=dm_y,
                ps_color=ps_color, ps_text=ps_text,
                ps_fontsize=ps_fontsize,
                ps_fontfamily=ps_fontfamily, ps_fontface=ps_fontface,
                ps_x=ps_x, ps_y=ps_y,
                rank_text=rank_text, suit_text=suit_text)
    opt$bleed_color <- get_bleed_color(opt)
    opt
}

get_bleed_color <- function(opt) {
    if (!is_color_invisible(opt$border_color) && !nigh(opt$border_lex, 0))
        return(opt$border_color)
    if (!is_color_invisible(opt$mat_color) && !nigh(opt$mat_width, 0))
        return(opt$mat_color)
    if (!is_color_invisible(opt$background_color))
        return(opt$background_color)
    return("transparent")
}
trevorld/piecepack documentation built on Jan. 19, 2024, 5:41 a.m.