如何 figlet 适合和 smush?

How figlet fit and smush?

我正在用 C++ 创建一个类似 figlet 的代码,我目前正在通过在左侧字符处插入 null 进行拟合,然后找到 min space 并删除 minspace 并将该字符设为 null,(对于理解将 null 视为 '0' )

" __0          "
"| _|0         "
"| |0    _____ "
"| |0   |_____|"
"| |0      $   "
"|__|0         "

(如果有任何 space 行,我在开始时插入 null)现在这里 min space 是 3 所以我删除了 3 space 和 null 并且这段代码完美无瑕通过继承配件 class 并且我将通过插入空值来传递右侧字符

"       0"
"       0"
" _0____ "
"|0_____|"
"   [=11=]   "
"       0"

它会给出这样的结果

" __       0"
"| _|      0"
"| | _0____ "
"| ||0_____|"
"| |   [=12=]   "
"|__|      0"

现在我将存储 null 的 pos 并将其删除,在下一个循环中检查 null 之前的两个字符,如果有一个是 HardBlank 则我 return 函数否则我在下一个循环中将其弄脏,但是由于 HardBlank,以上内容不是 smush(无法正常工作),所以我想知道 figlet 实际上是如何 smush 我从 here 下载了 figlet 代码,但我不理解代码。

  1. There is any better algorithm than this or How figlet actually do fitting and smushing ?

欢迎所有建议, 提前致谢。

我很久以前就问过这个问题,但我现在为未来的读者回答这个问题我前段时间写了比这更好的算法,执行以下操作,

字距调整或调整:

这个东西的主要部分是 trim,所以让我们创建一个函数,它接受两个输入,figs 是左侧的 FIGchar,figc 是右侧的 FIGchar。首先要做的是找到需要从 figs 的右侧和 figc 的左侧删除的 space 的数量,我们可以通过计算 figs 右侧大小的总数 space 来轻松找到它,并且图的左侧。最后取其中的最小值,即必须删除的 space 计数是该实现,

/**
 * @brief trims in a deep
 * 
 * @param figs fig string
 * @param figc fig character
 */
void trim_deep(Figs_type &figs, Figc_type &figc) const
{
    std::vector<size_type> elem;

    for (size_type i = 0; i < figs.size(); ++i)
    {
        int lcount = 0, rcount = 0;

        for (auto itr = figs[i].rbegin(); itr != figs[i].rend(); ++itr)
        {
            if (*itr == ' ')
                ++lcount;
            else
                break;
        }

        for (auto itr = figc[i].begin(); itr != figc[i].end(); ++itr)
        {
            if (*itr == ' ')
                ++rcount;
            else
                break;
        }

        elem.push_back(lcount + rcount);
    }

    size_type space = *std::min_element(elem.begin(), elem.end());

    for (size_type i = 0; i < figs.size(); ++i)
    {
        size_type siz = space;

        while (siz > 0 && figs[i].back() == ' ')
        {
            figs[i].pop_back();
            --siz;
        }

        figc[i].erase(0, siz);
    }
}

捣乱:

使用上面的函数可以很容易地完成这个 smushing,如果它是 smushble 这里是实现,只有 smush 最右边的 figs 字符和 figc 的左边字符,

/**
 * @brief smush rules
 * @param lc left character
 * @param rc right character
 * @return smushed character
 */
char_type smush_rules(char_type lc, char_type rc) const
{
    //()
    if (lc == ' ')
    {
        return rc;
    }

    if (rc == ' ')
    {
        return lc;
    }

    //(Equal character smush)
    if (lc == rc)
    {
        return rc;
    }

    //(Underscores smush)
    if (lc == '_' && this->cvt("|/\[]{}()<>").find(rc) != string_type::npos)
    {
        return rc;
    }

    if (rc == '_' && this->cvt("|/\[]{}()<>").find(lc) != string_type::npos)
    {
        return lc;
    }

    //(Hierarchy Smushing)
    auto find_class = [](char_type ch) -> size_type
    {
        if (ch == '|')
        {
            return 1;
        }

        if (ch == '/' || ch == '\')
        {
            return 3;
        }

        if (ch == '[' || ch == ']')
        {
            return 4;
        }

        if (ch == '{' || ch == '}')
        {
            return 5;
        }

        if (ch == '(' || ch == ')')
        {
            return 6;
        }

        return 0;
    };

    size_type c_lc = find_class(lc);
    size_type c_rc = find_class(rc);

    if (c_lc > c_rc)
    {
        return lc;
    }

    if (c_rc > c_lc)
    {
        return rc;
    }

    //(Opposite smush)
    if (lc == '[' && rc == ']')
    {
        return '|';
    }

    if (lc == ']' && rc == '[')
    {
        return '|';
    }

    if (lc == '{' && rc == '}')
    {
        return '|';
    }

    if (lc == '}' && rc == '{')
    {
        return '|';
    }

    if (lc == '(' && rc == ')')
    {
        return '|';
    }

    if (lc == ')' && rc == '(')
    {
        return '|';
    }

    //(Big X smush)
    if (lc == '/' && rc == '\')
    {
        return '|';
    }

    if (lc == '\' && rc == '/')
    {
        return 'Y';
    }

    if (lc == '>' && rc == '<')
    {
        return 'X';
    }

    //(universel smush)
    return lc;
}

/**
 * @brief smush algoriths on kerned Fig string and character
 * 
 * @param figs 
 * @param figc 
 */
void smush(Figs_type &figs, Figc_type figc, char_type hb) const
{
    bool smushble = true;

    for (size_type i = 0; i < figs.size(); ++i)
    {
        if (figs[i].size() == 0 || figc[i].size() == 0)
        {
            smushble = false;
        }
        else if ((figs[i].back() == hb) && !(figc[i].front() == hb))
        {
            smushble = false;
        }
    }

    if (smushble)
    {
        for (size_type i = 0; i < figs.size(); ++i)
        {
            char_type val = smush_rules(figs[i].back(), figc[i].front());
            figs[i].pop_back();
            figc[i].erase(0, 1);
            figs[i] += string_type(1, val) + figc[i];
        }
    }
    else
    {
        for (size_type i = 0; i < figs.size(); ++i)
        {
            figs[i] += figc[i];
        }
    }
}

这段代码是直接从这个file, So the types can be confusing here is overview Figs_type and Figc_type are just like vector of string and other type are reflects in their name and the repo can be found here复制过来的。