--- nono/lib/bitmap.cpp 2026/04/29 17:05:30 1.1.1.6 +++ nono/lib/bitmap.cpp 2026/04/29 17:05:47 1.1.1.7 @@ -518,18 +518,17 @@ BitmapRGBX::DrawBitmapI8Scale(const Rect } } -// (dx, dy) にビットマップ(RGBX) src を描画する。 +// (dx, dy) にビットマップ(RGBX) src の範囲 sr を描画する。 // 描画範囲をはみ出さないこと。 void -BitmapRGBX::DrawBitmap(int dx, int dy, const BitmapRGBX& src) +BitmapRGBX::DrawBitmap(int dx, int dy, const BitmapRGBX& src, const Rect& sr) { assert(buf); - const uint32 *s = (const uint32 *)src.GetBuf(); - - for (uint y = 0; y < src.GetHeight(); y++) { + for (uint y = 0; y < sr.h; y++) { uint32 *d = (uint32 *)GetPtr(dx, dy + y); - for (uint x = 0; x < src.GetWidth(); x++) { + const uint32 *s = (const uint32 *)src.GetPtr(sr.x, sr.y + y); + for (uint x = 0; x < sr.w; x++) { *d++ = *s++; } } @@ -868,6 +867,15 @@ BitmapRGBX::Mean(const RectF& sr) const return Color(sum_r, sum_g, sum_b); } +// (x, y) に点を描画する。 +// 描画範囲をはみ出さないこと。 +void +BitmapRGBX::DrawPoint(Color c, int x, int y) +{ + uint32 *d = (uint32 *)GetPtr(x, y); + *d = c.u32; +} + // 直線 (x1, y1) - (x2, y2) を描画する。終点は開区間。 // 描画範囲をはみ出さないこと。 void @@ -963,6 +971,49 @@ BitmapRGBX::DrawRect(Color c, const Rect DrawLineV(c, l, b, t); // 左辺↑ } +// 矩形 rect に内接する正円あるいは楕円を描画して中を塗りつぶす。 +// 描画範囲をはみ出さないこと。 +void +BitmapRGBX::DrawFillCircle(Color border, Color fill, const Rect& rect) +{ + int D = rect.h; // 高さを基準にした直径 + float r = D / 2; + float r2 = r * (r + 0.5); // 半径の二乗 + float prev_d = -1; + + // Y 方向を 1 px ずつステップしながら上下両側を対称に描画する。 + // 奇数個のときは真ん中を 2 回書くため、D&1 で補正。 + for (int i = 0, end = r + (D & 1); i < end; i++) { + // x^2 + y^2 = r^2 を解いて、楕円の係数を掛ける。 + float d = std::sqrt(r2 - r * r) * rect.w / rect.h; + r--; + + for (int j = 0; j < 2; j++) { + int y; + if (j == 0) { + y = rect.y + i; + } else { + y = rect.GetBottom() - i; + } + + int x1 = rect.x + rect.w / 2 - d; + int x2 = rect.x + rect.w / 2 + d; + + DrawLineH(fill, x1, y, x2); + + DrawPoint(border, x1, y); + DrawPoint(border, x2, y); + + int prev_x1 = rect.x + rect.w / 2 - prev_d; + int prev_x2 = rect.x + rect.w / 2 + prev_d; + DrawLineH(border, x1, y, prev_x1); + DrawLineH(border, x2, y, prev_x2); + } + + prev_d = d; + } +} + // 全域を RGB に変換。 void BitmapRGBX::ConvertToRGB(BitmapRGB& dst) const