// main.cpp #include #include #include #include #include #include #include "BitmapView.h" #include "BitmapBuffer.h" #include "FontManager.h" #include "Painter.h" const pattern kStripes = (pattern){ { 0xc7, 0x8f, 0x1f, 0x3e, 0x7c, 0xf8, 0xf1, 0xe3 } }; const pattern kDotted = (pattern){ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa } }; const pattern kDottedBigger = (pattern){ { 0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc } }; // test_straight_lines template bigtime_t test_straight_lines(Surface& s, uint32 width, uint32 height) { bigtime_t now = system_time(); s.SetPenSize(1.0); s.SetDrawingMode(B_OP_COPY); s.SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); s.SetHighColor(0, 0, 0, 255); s.SetLowColor(130, 0, 20, 255); const pattern pat = B_SOLID_HIGH; for (uint32 y = 0; y <= height; y += 5) { s.StrokeLine(BPoint(0, y), BPoint(width - 1, y), pat); } for (uint32 x = 0; x <= width; x += 5) { s.StrokeLine(BPoint(x, 0), BPoint(x, height - 1), pat); } s.Sync(); return system_time() - now; } // test_fill_rect template bigtime_t test_fill_rect(Surface& s, uint32 width, uint32 height) { bigtime_t now = system_time(); s.SetPenSize(1.0); s.SetDrawingMode(B_OP_COPY); s.SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); s.SetHighColor(0, 0, 0, 255); s.SetLowColor(130, 0, 20, 255); const pattern pat = B_SOLID_HIGH; BRect r; for (uint32 y = 10; y <= height; y += 20) { for (uint32 x = 10; x <= width; x += 20) { r.Set(x - 9, y - 9, x + 9, y + 9); s.FillRect(r, pat); } } s.Sync(); return system_time() - now; } // test_ellipses template bigtime_t test_ellipses(Surface& s, uint32 width, uint32 height) { bigtime_t now = system_time(); s.SetPenSize(2.0); s.SetDrawingMode(B_OP_COPY); s.SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); s.SetHighColor(0, 0, 0, 255); s.SetLowColor(130, 0, 20, 255); const pattern pat = B_SOLID_HIGH; BPoint center(floorf(width / 2.0), floorf(height / 2.0)); float xRadius = width / 2.0; float yRadius = height / 2.0; uint32 count = 40; for (uint32 i = 0; i < count; i ++) { s.StrokeEllipse(center, xRadius * (i / (float)count), yRadius * (i / (float)count), pat); } s.Sync(); return system_time() - now; } // test_lines template bigtime_t test_lines(Surface& s, uint32 width, uint32 height) { bigtime_t now = system_time(); s.SetPenSize(1.0); s.SetDrawingMode(B_OP_COPY); s.SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); s.SetHighColor(0, 0, 0, 255); s.SetLowColor(130, 0, 20, 255); const pattern pat = B_SOLID_HIGH; for (uint32 y = 0; y <= height; y += 10) { s.StrokeLine(BPoint(0, 0), BPoint(width, y), pat); s.StrokeLine(BPoint(width - 1, 0), BPoint(0, y), pat); } for (uint32 x = 0; x <= width; x += 10) { s.StrokeLine(BPoint(0, 0), BPoint(x, height), pat); s.StrokeLine(BPoint(width - 1, 0), BPoint(x, height), pat); } s.Sync(); return system_time() - now; } // test template bigtime_t test(Surface& s, uint32 width, uint32 height, BBitmap* testBitmap) { bigtime_t now = system_time(); // TODO: Painter behaves differently when origin has subpixel offset // BPoint origin(20.3, 10.8); BPoint origin(20, 10); BPoint center(width / 2.0, height / 2.0); float xRadius = 30.0; float yRadius = 20.0; s.SetOrigin(origin); s.SetScale(1.0); s.SetDrawingMode(B_OP_COPY); // s.SetDrawingMode(B_OP_SUBTRACT); // s.SetDrawingMode(B_OP_OVER); s.SetHighColor(20, 20, 20, 255); s.SetLowColor(220, 120, 80, 255); for (uint32 y = 0; y <= height / 2; y += 10) s.StrokeLine(BPoint(0, 0), BPoint(width / 2, y)/*, kDottedBigger*/); for (uint32 x = 0; x <= width; x += 10) s.StrokeLine(BPoint(0, 0), BPoint(x, height)/*, kDottedBigger*/); s.SetPenSize(1.0 * 5); s.SetHighColor(255, 0, 0, 255); s.SetLowColor(0, 0, 255, 255); // s.SetScale(1.0); // s.SetOrigin(B_ORIGIN); // s.SetDrawingMode(B_OP_INVERT); s.SetDrawingMode(B_OP_COPY); // s.StrokeRect(BRect(20.2, 45.6, 219.0, 139.0)); s.StrokeRect(BRect(20.2, 45.6, 219.0, 139.0), kStripes); // s.ConstrainClipping(noClip); /* s.SetPenLocation(BPoint(230.0, 30.0)); s.StrokeLine(BPoint(250.0, 30.0)); s.StrokeLine(BPoint(250.0, 50.0)); s.StrokeLine(BPoint(230.0, 50.0)); s.StrokeLine(BPoint(230.0, 30.0));*/ s.SetHighColor(255, 255, 0, 255); s.SetLowColor(128, 0, 50, 255); // s.SetDrawingMode(B_OP_OVER); s.SetDrawingMode(B_OP_ERASE); s.StrokeEllipse(center, xRadius, yRadius, kDottedBigger); s.SetHighColor(255, 0, 0, 255); s.SetDrawingMode(B_OP_INVERT); s.FillArc(center, xRadius * 2, yRadius * 2, 40.0, 230.0); // s.StrokeArc(center, xRadius * 2, yRadius * 2, 40.0, 230.0); s.SetDrawingMode(B_OP_OVER); s.SetPenSize(2.0); s.StrokeEllipse(center, xRadius * 3, yRadius * 2); // s.FillEllipse(center, xRadius * 3, yRadius * 2); // s.StrokeLine(bounds.RightTop()); // s.FillRect(rect); s.SetHighColor(0, 0, 255, 255); s.SetLowColor(255, 0, 0, 255); s.SetPenSize(1.0); // s.SetDrawingMode(B_OP_SELECT); s.StrokeRoundRect(BRect(40, 100, 250, 220.0), 40, 40); // s.FillRoundRect(BRect(40, 100, 250, 220.0), 40, 40); // text rendering const char* string1 = "The Quick Brown Fox..."; const char* string2 = "jumps!"; BPoint stringLocation1(10.0, 220.0); BPoint stringLocation2(30.0 / 2.5, 115.0 / 2.5); BFont font(be_plain_font); font.SetSize(12.0); font.SetRotation(8.0); // font.SetFamilyAndStyle(1); s.SetFont(&font); s.SetHighColor(91, 105, 98, 120); s.SetDrawingMode(B_OP_OVER); s.DrawString(string1, stringLocation1); s.DrawString(string2); s.StrokeLine(BPoint(width - 1, 0)); // s.SetScale(2.5); s.SetDrawingMode(B_OP_INVERT); s.SetHighColor(200, 200, 200, 255); s.DrawString("H", stringLocation2); s.DrawString("e"); s.DrawString("l"); s.DrawString("l"); s.DrawString("o"); s.DrawString(" "); s.DrawString("N"); s.DrawString("u"); s.DrawString("r"); s.DrawString("s"); s.DrawString("e"); s.DrawString("!"); // do the char locations match up? // s.SetHighColor(0, 60, 240); // s.DrawString("Hello Nurse!", stringLocation2); // bitmap drawing BRect testBitmapCrop(testBitmap->Bounds()); testBitmapCrop.left += 20.0; BRect testBitmapDestRect(testBitmapCrop); testBitmapDestRect.OffsetBy(50, 20); s.SetScale(1.5); s.SetDrawingMode(B_OP_ALPHA); s.SetHighColor(0, 0, 0, 120); s.DrawBitmap(testBitmap, testBitmapCrop, testBitmapDestRect); s.Sync(); return system_time() - now; } // main int main(int argc, char **argv) { BApplication* app = new BApplication("application/x.vnd-YellowBites.TestApp"); // create the default instance of the FontManager // It takes a bit to scan through the font files; // "true" means to do the font scanning inline, not // in a separate thread. fprintf(stdout, "scanning font files..."); fflush(stdout); FontManager::CreateDefault(true); fprintf(stdout, "done\n"); BRect bounds(0.0, 0.0, 319.0, 239.0); // test the clipping BRegion noClip(bounds); int32 clipCount = 5; BRegion clip; float h = bounds.Width() / clipCount; float v = bounds.Height() / clipCount; float hInset = (h / 2.0) * 0.5; float vInset = (v / 2.0) * 0.5; for (int32 i = 0; i < clipCount; i++) { /* BRect b(h * i, bounds.top, h * i, bounds.bottom); b.InsetBy(-hInset, 0.0); clip.Include(b); b.Set(bounds.left, v * i, bounds.right, v * i); b.InsetBy(0.0, -vInset); clip.Include(b);*/ BRect b(bounds.left, v * i, bounds.right, v * i); b.InsetBy(0.0, -vInset); clip.Include(b); b.Set(h * i, bounds.top, h * i, bounds.bottom); b.InsetBy(-hInset, 0.0); clip.Include(b); } // prepare a test bitmap for bitmap rendering BBitmap* testBitmap = new BBitmap(BRect(20, 0, 150, 50), 0, B_RGB32); // fill testBitmap with content uint8* bits = (uint8*)testBitmap->Bits(); uint32 bitmapWidth = testBitmap->Bounds().IntegerWidth() + 1; uint32 bitmapHeight = testBitmap->Bounds().IntegerHeight() + 1; uint32 bpr = testBitmap->BytesPerRow(); for (uint32 y = 0; y < bitmapHeight; y++) { uint8* h = bits; for (uint32 x = 0; x < bitmapWidth; x++) { h[0] = (uint8)((float)x / (float)bitmapWidth * 255.0); h[1] = (uint8)((float)y / (float)bitmapHeight * 255.0); h[2] = 255 - (uint8)((float)y / (float)bitmapHeight * 255.0); h[3] = (uint8)((float)y / (float)bitmapHeight * 255.0); h += 4; } bits += bpr; } // make corners a black pixel for testing bits = (uint8*)testBitmap->Bits(); *(uint32*)(&bits[0]) = 0; *(uint32*)(&bits[(bitmapWidth - 1) * 4]) = 0; *(uint32*)(&bits[(bitmapHeight - 1) * bpr]) = 0; *(uint32*)(&bits[(bitmapHeight - 1) * bpr + (bitmapWidth - 1) * 4]) = 0; // create a frame buffer BBitmap* bitmap = new BBitmap(bounds, B_RGB32); //memset(bitmap->Bits(), 0, bitmap->BitsLength()); BitmapBuffer* buffer = new BitmapBuffer(bitmap); Painter painter; painter.AttachToBuffer(buffer); uint32 width = buffer->Width(); uint32 height = buffer->Height(); // painter.ConstrainClipping(clip); int32 iterations = 40; fprintf(stdout, "Painter..."); fflush(stdout); bigtime_t painterNow = 0; for (int32 i = 0; i < iterations; i++) { // reset bitmap contents memset(bitmap->Bits(), 255, bitmap->BitsLength()); // run test // painterNow += test(painter, width, height, testBitmap); // painterNow += test_lines(painter, width, height); // painterNow += test_straight_lines(painter, width, height); painterNow += test_fill_rect(painter, width, height); // painterNow += test_ellipses(painter, width, height); } fprintf(stdout, " %lld µsecs\n", painterNow / iterations); BitmapView* painterView = new BitmapView(bounds, "view", bitmap); bitmap = new BBitmap(bounds, B_RGB32, true); BView* view = new BView(bounds, NULL, B_FOLLOW_NONE, B_WILL_DRAW); //memset(bitmap->Bits(), 0, bitmap->BitsLength()); bitmap->Lock(); bitmap->AddChild(view); // view->ConstrainClippingRegion(&clip); fprintf(stdout, "BView..."); fflush(stdout); bigtime_t viewNow = 0; for (int32 i = 0; i < iterations; i++) { // reset bitmap contents memset(bitmap->Bits(), 255, bitmap->BitsLength()); // run test // viewNow += test(*view, width, height, testBitmap); // viewNow += test_lines(*view, width, height); // viewNow += test_straight_lines(*view, width, height); viewNow += test_fill_rect(*view, width, height); // viewNow += test_ellipses(*view, width, height); } bitmap->Unlock(); fprintf(stdout, " %lld µsecs\n", viewNow / iterations); if (painterNow > viewNow) printf("BView is %.2f times faster.\n", (float)painterNow / (float)viewNow); else printf("Painter is %.2f times faster.\n", (float)viewNow / (float)painterNow); BitmapView* bViewView = new BitmapView(bounds, "view", bitmap); bViewView->MoveTo(BPoint(bounds.left, bounds.bottom + 1)); BWindow* window = new BWindow(BRect(50.0, 50.0, 50.0 + bounds.Width(), 50.0 + bounds.Height() * 2 + 1), "Painter Test", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE); window->AddChild(painterView); window->AddChild(bViewView); window->Show(); app->Run(); delete app; return 0; }