|
|
nono 1.7.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
//
// テキストスクリーン
//
#pragma once
#include "header.h"
#include <vector>
// 属性
class TA
{
public:
enum TextAttr : uint {
// 文字(2バイト)の上位バイトが属性。
//
// 15 14 13 12 11 10 9 8
// +---+---+---+---+---+---+---+---+
// | B | - | Color Code |
// +---+---+---+---+---+---+---+---+
//
// B はボールド。
// Color Code は 4bit の前景色・背景色ペアの固定パレット。
Normal = 0x00U << 8, // 通常描画色
Reverse = 0x01U << 8, // 反転、背景黒
Off = 0x02U << 8, // オフを示す
Disable = 0x03U << 8, // 無効を示す
ReverseRed = 0x04U << 8, // 反転、背景赤
ReverseGreen = 0x05U << 8, // 反転、背景緑
ReverseOrange = 0x06U << 8, // 反転、背景オレンジ
Bold = 0x80U << 8, // ボールド
// エイリアス
On = Reverse, // オンは反転で表現している
Em = Bold | Normal, // 通常色 + 強調のショートカット
} attr {};
TA() { }
TA(TextAttr attr_) : attr(attr_) { }
// uint からのコンストラクタ
TA(uint attr_) : TA((TextAttr)attr_) { }
// uint へのキャスト
operator uint() const {
return (uint)attr;
}
// static member
// val によって On か Off を返す
static const TA OnOff(bool val) {
return (val) ? TA::On : TA::Off;
}
};
//
// テキストスクリーン
//
// col × row で指定されるテキスト画面。
// 表示可能なのは 0x20..0x7e の printable 文字。
// 及び \n (0x0a) は復帰改行する。
// それ以外の 0x20 未満と 0x7f の動作は未定。
// 漢字は 2桁占有する。文字列として指定する時は UTF-8 だが、内部コードは
// Shift_JIS なので、第一水準、第二水準の文字だけを指定すること。
//
// TextScreen() コンストラクタで作成して Init(col, row) するか、
// TextScreen(col, row) コンストラクタを呼ぶかどちらか選択。
// チェックとかはしていないので併用しないこと。
//
// Locate などにより範囲外にカーソルを移動することはできる。
// ただしその位置を始点としての文字出力は無視される。
class TextScreen final
{
public:
// 文字の送りモード
enum ModeKind {
// 右端は無視される
Fixed,
// 右端は次の行に改行し、最終行だったときは上スクロールする
Console,
// 右端は次の行に改行し、最終行右端は左上に戻る
Ring,
} Mode { Fixed };
TextScreen();
TextScreen(int col, int row);
~TextScreen();
// 初期化
void Init(int col, int row, ModeKind mode = ModeKind::Fixed);
// 画面をクリアして、カーソルをホームポジションに移動
void Clear();
// 現在位置を移動
void Locate(int x, int y) {
X = x;
Y = y;
OutOfScreen = (X < 0 || X >= col || Y < 0 || Y >= row);
}
void SetX(int x) {
X = x;
OutOfScreen = (X < 0 || X >= col);
}
void SetY(int y) {
Y = y;
OutOfScreen = (Y < 0 || Y >= row);
}
// 文字出力後の右移動
void Ascend();
// 復帰
void CR() noexcept {
X = 0;
}
// 改行
void LF();
// 復帰改行
void CRLF() {
CR();
LF();
}
// 1行の上スクロール
void ScrollUp();
//
// 出力関数群
// 出力関数はカーソル位置を更新する。
//
// 現在位置に1文字出力 (上位バイトは属性)
void Putc(uint16 ch);
// 座標を指定して1文字出力 (上位バイトは属性)
void Putc(int x, int y, uint16 ch) {
Locate(x, y);
Putc(ch);
}
// 座標と属性を指定して1文字出力
void Putc(int x, int y, TA attr, uint16 ch) {
Locate(x, y);
Putc((uint)attr | ch);
}
// 現在位置に文字列を出力
void Puts(const char *str);
// 現在位置に指定の属性で文字列を出力
void Puts(TA attr, const char *str);
// 座標を指定して文字列を出力
void Puts(int x, int y, const char *str) {
Locate(x, y);
Puts(str);
}
// 座標と属性を指定して、文字列を出力
void Puts(int x, int y, TA attr, const char *str) {
Locate(x, y);
Puts(attr, str);
}
// 現在位置に属性なしで書式付き文字列を出力
void Print(const char *fmt, ...) __printflike(2, 3);
// 座標を指定して属性なしで書式付き文字列を出力
void Print(int x, int y, const char *fmt, ...) __printflike(4, 5);
// 座標と属性を指定して、書式付き文字列を出力
void Print(int x, int y, TA attr, const char *fmt, ...)
__printflike(5, 6);
// 現在のカーソル位置の文字を取得
// カーソルは移動しない。
uint16 Getc();
// 現在のカーソル位置に文字を出力。
// カーソルは移動しない。ch がカーソル移動を伴う制御文字なら動作不定。
void Setc(uint16 ch);
// 指定のカーソル位置に文字を出力。
// カーソルは移動しない。ch がカーソル移動を伴う制御文字なら動作不定。
void Setc(int x, int y, uint16 ch);
// 現在位置の属性を取得
TA GetAttr() const;
// 現在位置の属性を attr に設定
// カーソルは移動しない。
void SetAttr(TA attr);
// バッファを取得。(描画デバイス向け)
const std::vector<uint16>& GetBuf() const { return textbuf; }
// 現在の X 座標を取得
int GetX() const noexcept { return X; }
// 現在の Y 座標を取得
int GetY() const noexcept { return Y; }
// 桁数を取得
int GetCol() const noexcept { return col; }
// 行数を取得
int GetRow() const noexcept { return row; }
// 行単位のコピー
void CopyRowsFrom(int dst_y, int row, const TextScreen& src, int src_y);
// ユーザ定義の引数
// ご自由にお使いください。例えばモニタの出力開始オフセットやアドレス
// など、呼び出し側が設定して書き出す側がそれに従った内容を出力する
// ような用途。
uint64 userdata {};
private:
// バッファ (幅x高さちょうどの長さ、ゼロ終端文字列ではない)
// 上位8ビットは属性、下位8ビットが文字コード。
std::vector<uint16> textbuf {};
// 幅
int col {};
// 高さ
int row {};
// カーソル X 座標
int X {};
// カーソル Y 座標
int Y {};
// カーソルが画面外に位置するとき true
bool OutOfScreen {};
};
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.