ビット演算>ビットマップ ボールド化

ボールドとは太字のことだ。
下図の様に、ドットがある部分を二重化することで、ボールドとなる。

........
.*......
.*......
.*......
.*****..
.*....*.
.*....*.
.*****..

↓ ホールド化

........
.**.....
.**.....
.**.....
.******.
.**...**
.**...**
.******.

uint64 bits に8×8ビットマップデータが入っているとき、それをボールド化するにはどうしたらいいだろうか?

もし、8×8画像をビットマップを使わず bool pixel[8][8]; で表現していた場合、ボールド処理は以下のように書ける。

void toBold(bool pixel[8][8])
{
    for(int y = 0; y < 8; ++y) {
        for(int x = 8; --x > 0; ) {
            pixel[y][x-1] |= pixel[y][x];
        }
    }
}

2重ループで、論理演算を56回も行う必要がある。

これに対して、ビットマップであれば、以下の1行で済む。

uint64 toBold(uint64 bits)
{
    return ((bits>>1) & 0x7f7f7f7f7f7f7f7f) | bits;
}

基本的には ビットパターンを右にひとつシフトしたものと、もとのパターンの論理和(or)を計算するとよい。
ただし、右端から左端への影響を無くすために、0x7f7f7f7f7f7f7f7f との論理積(and)をとっているというわけだ。
配列を使った場合は56回も必要だった論理演算が、わずか3回で済んでいる。
ビット演算により、ボールド化処理がとんでもなく高速化されるのをご理解いただけたであろうか?