「ゼロからのOS自作入門」 05日目

試行錯誤メモ

前回は、フレームバッファを引き継いでカーネルから画面描画することを学びました。

今回は、テキストを画面上に描画するための処理を勉強していくことになるみたいです。

5.1 文字を書いてみる

画面上に '文字' を表示するためにはフォントデータが必要になる(計算の都合上、2 のべき乗で表されるサイズだと都合がとてもいい)。

多分、フォントデータの種類にはいくつかあるのだと思うけれども、いわゆるビットマップフォントで実装が進む模様。

// "A" を表すフォントデータ
const uint8_t kFontA[16] = {
  0b00000000, //
  0b00011000, //    **
  0b00011000, //    **
  0b00011000, //    **
  0b00011000, //    **
  0b00100100, //   *  *
  0b00100100, //   *  *
  0b00100100, //   *  *
  0b00100100, //   *  *
  0b01111110, //  ******
  0b01000010, //  *    *
  0b01000010, //  *    *
  0b01000010, //  *    *
  0b11100111, // ***  ***
  0b00000000, //
  0b00000000, //
};

そして、フォントデータ上の任意の座標位置のビット状態を判断して、描画するか/否かを判断するロジックはこんな感じ。 1 ビットずつ左にシフトしていって、0×80(=0b10000000)と AND 演算した結果が真であればそのドットは描画対象になる。

dx0xC1 << dx(0xC1 << dx) & 0xC1結果
00b 00000000 110000010b 00000000 11000001
0b 00000000 10000000
TRUE
10b 00000001 100000100b 00000001 10000010
0b 00000000 10000000
TRUE
20b 00000011 000001000b 00000011 00000100
0b 00000000 10000000
FALSE
30b 00000110 000010000b 00000110 00001000
0b 00000000 10000000
FALSE
40b 00001100 000100000b 00001100 00010000
0b 00000000 10000000
FALSE
50b 00011000 001000000b 00011000 00100000
0b 00000000 10000000
FALSE
60b 01100000 010000000b 01100000 01000000
0b 00000000 10000000
FALSE
70b 11000000 100000000b 11000000 10000000
0b 00000000 10000000
TRUE

あとは、フォントを描画する関数を定義&呼び出してあげれば良い。

void WriteAscii(PixelWriter& writer, int x, int y, char c, const PixelColor& color) {
  if (c != 'A') {
    return;
  }
  for (int dy = 0; dy < 16; ++dy) {
    for (int dx = 0; dx < 8; ++dx) {
      if ((kFontA[dy] << dx) & 0x80u) {
        writer.Write(x + dx, y + dy, color);
      }
    }
  }
}

extern "C" void KernelMain(const FrameBufferConfig& frame_buffer_config) {
  // :
  WriteAscii(*pixel_writer, 50, 50, 'A', {0, 0, 0});
  WriteAscii(*pixel_writer, 58, 50, 'A', {0, 0, 0});
  // :
}

day05a

おおーー! でけた!


(まだ続く…)

© 2021 czu.jp