--- nono/lib/bitmap.cpp 2026/04/29 17:05:08 1.1.1.1 +++ nono/lib/bitmap.cpp 2026/04/29 17:05:22 1.1.1.4 @@ -16,14 +16,11 @@ // // コンストラクタ -BitmapBase::BitmapBase() +BitmapBase::BitmapBase(int depth_, int width_, int height_, const void *buf_) + : depth(depth_) { -} - -// コンストラクタ -BitmapBase::BitmapBase(int width_, int height_, int depth_) -{ - Create(width_, height_, depth_); + assert(depth == 1 || (depth % 8) == 0); + Create(width_, height_, buf_); } // デストラクタ @@ -31,20 +28,41 @@ BitmapBase::~BitmapBase() { } -// 作成 +// サイズを指定してビットマップを作成する。 +// width_, height_ は 0 が指定される場合もある(初期状態)。 +// buf_ が NULL ならこっちでメモリを確保。 void -BitmapBase::Create(int width_, int height_, int depth_) +BitmapBase::Create(int width_, int height_, const void *buf_) { - assert(depth_ == 1 || depth_ == 8 || depth_ == 24); - - width = width_; + width = width_; height = height_; - if (depth_ == 1) { + if (depth == 1) { stride = (width + 7) / 8; } else { - stride = width * depth_ / 8; + stride = width * depth / 8; } + + owned_buf.reset(); + if (buf_) { + buf = static_cast(const_cast(buf_)); + } else { + if (width > 0 && height > 0) { + owned_buf.reset(new uint8[stride * height]); + } + buf = owned_buf.get(); + } +} + +// 全域をコピーしてくる。 +void +BitmapBase::CopyFrom(const BitmapBase *src) +{ + assert(src); + assert(stride == src->stride); + assert(height == src->height); + + memcpy(buf, src->buf, stride * height); } @@ -54,20 +72,20 @@ BitmapBase::Create(int width_, int heigh // コンストラクタ BitmapI1::BitmapI1() + : BitmapI1(0, 0) // 移譲 { } // コンストラクタ BitmapI1::BitmapI1(int width_, int height_) + : BitmapI1(NULL, width_, height_) // 移譲 { - Create(width_, height_); } // コンストラクタ BitmapI1::BitmapI1(const void *buf_, int width_, int height_) - : inherited(width_, height_, 1) + : inherited(1, width_, height_, buf_) { - buf = static_cast(const_cast(buf_)); } // デストラクタ @@ -75,24 +93,12 @@ BitmapI1::~BitmapI1() { } -// 作成 -void -BitmapI1::Create(int width_, int height_) -{ - inherited::Create(width_, height_, 1); - - owned_buf.reset(new uint8[stride * height]); - buf = owned_buf.get(); -} - -// カラーコード cc で全体を塗りつぶす。 -// 未使用ビットも変更される。 -void -BitmapI1::Fill(int cc) +// (x, y) のアドレスを返す関数だが、I1 ではサポートしていない。 +uint8 * +BitmapI1::GetPtr(int x, int y) const { - assert(buf); - - memset(buf, (cc ? 0xff : 0), stride * height); + assertmsg(false, "GetPtr() not work for BitmapI1"); + return NULL; } @@ -102,20 +108,20 @@ BitmapI1::Fill(int cc) // コンストラクタ BitmapI8::BitmapI8() + : BitmapI8(0, 0) // 移譲 { } // コンストラクタ BitmapI8::BitmapI8(int width_, int height_) + : BitmapI8(NULL, width_, height_) // 移譲 { - Create(width_, height_); } // コンストラクタ BitmapI8::BitmapI8(const void *buf_, int width_, int height_) - : inherited(width_, height_, 8) + : inherited(8, width_, height_, buf_) { - buf = static_cast(const_cast(buf_)); } // デストラクタ @@ -123,16 +129,6 @@ BitmapI8::~BitmapI8() { } -// 作成 -void -BitmapI8::Create(int width_, int height_) -{ - inherited::Create(width_, height_, 8); - - owned_buf.reset(new uint8[stride * height]); - buf = owned_buf.get(); -} - // カラーコード cc で全体を塗りつぶす。 // 未使用ビットも変更される。 void @@ -150,20 +146,20 @@ BitmapI8::Fill(int cc) // コンストラクタ BitmapRGB::BitmapRGB() + : BitmapRGB(0, 0) // 移譲 { } // コンストラクタ BitmapRGB::BitmapRGB(int width_, int height_) + : BitmapRGB(NULL, width_, height_) // 移譲 { - Create(width_, height_); } // コンストラクタ BitmapRGB::BitmapRGB(const void *buf_, int width_, int height_) - : inherited(width_, height_, 24) + : inherited(24, width_, height_, buf_) { - buf = static_cast(const_cast(buf_)); } // デストラクタ @@ -171,23 +167,6 @@ BitmapRGB::~BitmapRGB() { } -// 作成 -void -BitmapRGB::Create(int width_, int height_) -{ - inherited::Create(width_, height_, 24); - - owned_buf.reset(new uint8[stride * height]); - buf = owned_buf.get(); -} - -// 色 c で全体を塗りつぶす。 -void -BitmapRGB::Fill(Color c) -{ - FillRect(c, 0, 0, width, height); -} - // (dx, dy) にビットマップ src を描画する。 // 描画範囲をはみ出さないこと。 void @@ -220,6 +199,15 @@ BitmapRGB::DrawBitmap(int dx, int dy, co } } +// (dx, dy) にビットマップ src の全域を描画する。 +// 描画範囲をはみ出さないこと。 +void +BitmapRGB::DrawBitmap(int dx, int dy, const BitmapI8& src, const Color *palette) +{ + Rect sr(0, 0, src.GetWidth(), src.GetHeight()); + DrawBitmap(dx, dy, src, palette, sr); +} + // (dx, dy) にビットマップ src の範囲 sr を描画する。 // 描画範囲をはみ出さないこと。 void @@ -291,6 +279,74 @@ BitmapRGB::DrawScaleUp(int dx, int dy, i } } +// 分数で表現可能な拡大縮小描画。 +// dr にビットマップ src の (sxN / sxD, syN / syD) からを +// dst の 1 ピクセルに対して (sxS / sxD, syS / syD) ずつ動かした位置を +// 読み出し位置として描画する。 +// 描画範囲をはみ出さないこと。 +void +BitmapRGB::DrawScale(const Rect& dr, const BitmapI8& src, const Color *palette, + int sxN, int sxD, int sxS, int syN, int syD, int syS) +{ + assert(buf); + assert(sxD >= 1); + assert(syD >= 1); + assert(sxS != 0); + assert(syS != 0); + + int sxI = sxN / sxD; + int syI = syN / syD; + + sxN %= sxD; + syN %= syD; + + int sxI0 = sxI; + int sxN0 = sxN; + + int sx; + int sy = syI - 1; + + for (int y = 0; y < dr.h; y++) { + uint8 *d = GetPtr(dr.x, dr.y + y); + + if (sy != syI) { + sy = syI; + + sx = sxI0 - 1; + sxI = sxI0; + sxN = sxN0; + + uint8 cc = 0; + for (int x = 0; x < dr.w; x++) { + if (sx != sxI) { + sx = sxI; + const uint8 *s = src.GetPtr(sx, sy); + cc = *s; + } + const Color& c = palette[cc]; + *d++ = c.r; + *d++ = c.g; + *d++ = c.b; + + sxN += sxS; + if (sxN >= sxD) { + sxI += sxN / sxD; + sxN %= sxD; + } + } + } else { + // 前のラスタの中からコピーすればよい + memcpy(d, d - stride, dr.w * 3); + } + + syN += syS; + if (syN >= syD) { + syI += syN / syD; + syN %= syD; + } + } +} + // sr 範囲の色の平均を返す Color BitmapRGB::Mean(const RectD& sr) const @@ -462,14 +518,6 @@ BitmapRGB::DrawLineV(Color c, int x1, in } } -// 矩形 (dx, dy) - (dw * dh) を色 c で塗りつぶす。 -// 描画範囲をはみ出さないこと。 -void -BitmapRGB::FillRect(Color c, int dx, int dy, int dw, int dh) -{ - FillRect(c, Rect(dx, dy, dw, dh)); -} - // 矩形 rect を色 c で塗りつぶす。 // 描画範囲をはみ出さないこと。 void @@ -517,3 +565,31 @@ BitmapRGB::DrawRect(Color c, const Rect& DrawLineH(c, r, b, l); // 下辺← DrawLineV(c, l, b, t); // 左辺↑ } + + +// +// 32bpp (RGBX) ビットマップ +// + +// コンストラクタ +BitmapRGBX::BitmapRGBX() + : BitmapRGBX(0, 0) // 移譲 +{ +} + +// コンストラクタ +BitmapRGBX::BitmapRGBX(int width_, int height_) + : BitmapRGBX(NULL, width_, height_) // 移譲 +{ +} + +// コンストラクタ +BitmapRGBX::BitmapRGBX(const void *buf_, int width_, int height_) + : inherited(32, width_, height_, buf_) +{ +} + +// デストラクタ +BitmapRGBX::~BitmapRGBX() +{ +}