File:  [Isaki's NoNo m68k/m88k emulator] / nono / lib / bitmap.h
Revision 1.1.1.7 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:47 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, v026, v025, HEAD
nono 1.5.0

//
// nono
// Copyright (C) 2021 nono project
// Licensed under nono-license.txt
//

//
// ビットマップ
//

#pragma once

#include "header.h"
#include "alignedarray.h"
#include "color.h"
#include "rect.h"

// ビットマップ (基本クラス)
class BitmapBase
{
 protected:
	BitmapBase(uint depth_, uint width_, uint height_, const void *buf_);

	// サイズを指定してキャンバスを作成。
	// buf_ は NULL ならこっちでメモリを確保。
	void Create(uint width_, uint height_, const void *buf_);
 public:
	virtual ~BitmapBase();

	// コピーコンストラクタ
	BitmapBase(const BitmapBase& src);
	// コピー代入演算子
	BitmapBase& operator=(const BitmapBase& src);

	// サイズを指定してキャンバスを作成。
	void Create(uint width_, uint height_) {
		Create(width_, height_, NULL);
	}

	uint GetWidth() const { return width; }
	uint GetHeight() const { return height; }
	uint GetStride() const { return stride; }

	uint8 *GetBuf() { return buf; }
	const uint8 *GetBuf() const { return buf; }

	// y 行目先頭のアドレスを返す
	uint8 *GetRowPtr(int y) const {
		assertmsg(y < height, "y=%d height=%u", y, height);
		return &buf[y * stride];
	}

	// (x, y) のアドレスを返す
	virtual uint8 *GetPtr(int x, int y) const {
		assertmsg(x < width, "x=%d width=%u", x, width);
		assertmsg(y < height, "y=%d height=%u", y, height);
		return &buf[y * stride + x * depth / 8];
	}

	// 全域をコピーしてくる。
	void CopyFrom(const BitmapBase *src);

 protected:
	uint width {};		// 幅   [pixel]
	uint height {};		// 高さ [pixel]
	uint stride {};		// ストライド [byte]
	uint depth {};		// 色深度 [bit]

	uint8 *buf {};
	AlignedArray<uint8, 32> owned_buf {};
};

// 1bpp ビットマップ
class BitmapI1 : public BitmapBase
{
	using inherited = BitmapBase;
 public:
	BitmapI1();
	BitmapI1(uint width_, uint height_);
	BitmapI1(const void *buf_, uint width_, uint height_);
	~BitmapI1() override;

	uint8 *GetPtr(int x, int y) const override;

	// このビットマップ(フォント)をボールドにした新しいビットマップを返す。
	BitmapI1 ConvertToBold() const;
	// このビットマップ(フォント)をイタリックにした新しいビットマップを返す。
	BitmapI1 ConvertToItalic() const;
};

// 8bpp ビットマップ
class BitmapI8 : public BitmapBase
{
	using inherited = BitmapBase;
 public:
	BitmapI8();
	BitmapI8(uint width_, uint height_);
	BitmapI8(const void *buf_, uint width_, uint height_);
	~BitmapI8() override;
};

// 24bpp ビットマップ
class BitmapRGB : public BitmapBase
{
	using inherited = BitmapBase;
 public:
	BitmapRGB();
	BitmapRGB(uint width_, uint height_);
	BitmapRGB(const void *buf_, uint width_, uint height_);
	~BitmapRGB() override;
};

// 32bpp (RGBX) ビットマップ。
// メモリ上 { R, G, B, X } の順。X は不問。
class BitmapRGBX : public BitmapBase
{
	using inherited = BitmapBase;
 public:
	BitmapRGBX();
	BitmapRGBX(uint width_, uint height_);
	BitmapRGBX(const void *buf_, uint width_, uint height_);
	~BitmapRGBX() override;

	// 色 c で全体を塗りつぶす
	void Fill(Color c) {
		FillRect(c, Rect(0, 0, width, height));
	}
	void FillRect(Color c, int dx, int dy, uint dw, uint dh) {
		FillRect(c, Rect(dx, dy, dw, dh));
	}
	void FillRect(Color c, const Rect& rect);

	// rect の一番上のラスターを rect の残りのラスターにコピーする
	void CopyFromTop(const Rect& rect);

	void DrawPoint(Color c, int x, int y);

	void DrawLine(Color c, int x1, int y1, int x2, int y2);
	void DrawLineH(Color c, int x1, int y1, int x2);
	void DrawLineV(Color c, int x1, int y1, int y2);

	void DrawRect(Color c, int dx, int dy, uint dw, uint dh) {
		DrawRect(c, Rect(dx, dy, dw, dh));
	}
	void DrawRect(Color c, const Rect& rect);

	void DrawFillCircle(Color b, Color f, int dx, int dy, uint dw, uint dh) {
		DrawFillCircle(b, f, Rect(dx, dy, dw, dh));
	}
	void DrawFillCircle(Color border, Color fill, const Rect& rect);

	// I1 画像を描画
	void DrawBitmapI1(int dx, int dy, const BitmapI1& src,
		const Color *palette);
	// I1 画像を scale 倍に拡大して描画
	void DrawBitmapI1Scale(int dx, int dy, const BitmapI1& src,
		const Color *palette, int scale);

	// I8 画像を描画
	void DrawBitmapI8(int dx, int dy, const BitmapI8& src, const Color *palette)
	{
		Rect sr(0, 0, src.GetWidth(), src.GetHeight());
		DrawBitmapI8(dx, dy, src, palette, sr);
	}
	// I8 画像の指定範囲を描画
	void DrawBitmapI8(int dx, int dy, const BitmapI8& src, const Color *palette,
		const Rect& sr);
	// I8 画像の全域を指定ラスターのみ描画
	void DrawBitmapI8Raster(const BitmapI8& src, const Color *palette,
		const uint8 *update_raster);

	// I8 画像を分数で拡大縮小して描画
	void DrawBitmapI8Scale(const Rect& dr, const BitmapI8& src,
		const Color *palette,
		int sxN, int sxD, int sxS, int syN, int syD, int syS);

	// RGBX 画像を描画
	void DrawBitmap(int dx, int dy, const BitmapRGBX& src, const Rect& sr);
	void DrawBitmap(int dx, int dy, const BitmapRGBX& src) {
		DrawBitmap(dx, dy, src, Rect(0, 0, src.GetWidth(), src.GetHeight()));
	}

	// RGBX 画像が dr のサイズになるよう拡大縮小して描画
	void DrawBitmapStretch(const Rect& dr, const BitmapRGBX& src);

	// RGBX 画像を (N-1)/N 倍に縮小して描画
	void DrawBitmapNtoNm1(const Rect& dr, const BitmapRGBX& src, uint N);

	// RGBX 画像を N/(N-1) 倍に拡大して描画
	void DrawBitmapNm1toN(const Rect& dr, const BitmapRGBX& src, uint N);

	// RGBX 画像が dr のサイズになるよう面積平均法で拡大縮小して描画
	void DrawBitmapMean(const Rect& dr, const BitmapRGBX& src);

	// RGB に変換。
	void ConvertToRGB(BitmapRGB& dst) const;

 private:
	// 呼ばれなくて存在しない関数宣言は無視されるので並べて書く。

	void CopyLineI8_gen(uint32 *d, const uint8 *s, uint width,
		const Color *palette);
	void CopyLineI8_avx2(uint32 *d, const uint8 *s, uint width,
		const Color *palette);

	Color Mean(const RectF& sr) const;

	void ConvertToRGB_gen(BitmapRGB& dst) const;
	void ConvertToRGB_avx2(BitmapRGB& dst) const;

#if defined(HAVE_AVX2)
	bool enable_avx2 {};
#endif
};

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.