|
|
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
};
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.