1 // main.cpp 2 3 #include <stdio.h> 4 5 #include <Application.h> 6 #include <Bitmap.h> 7 #include <GraphicsDefs.h> 8 #include <Region.h> 9 #include <Window.h> 10 11 #include "BitmapView.h" 12 #include "BitmapBuffer.h" 13 #include "FontManager.h" 14 #include "Painter.h" 15 16 const pattern kStripes = (pattern){ { 0xc7, 0x8f, 0x1f, 0x3e, 0x7c, 0xf8, 0xf1, 0xe3 } }; 17 const pattern kDotted = (pattern){ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa } }; 18 const pattern kDottedBigger = (pattern){ { 0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc } }; 19 20 // test_straight_lines 21 template<class Surface> 22 bigtime_t 23 test_straight_lines(Surface& s, uint32 width, uint32 height) 24 { 25 bigtime_t now = system_time(); 26 27 s.SetPenSize(1.0); 28 s.SetDrawingMode(B_OP_COPY); 29 s.SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); 30 31 s.SetHighColor(0, 0, 0, 255); 32 s.SetLowColor(130, 0, 20, 255); 33 34 const pattern pat = B_SOLID_HIGH; 35 36 for (uint32 y = 0; y <= height; y += 5) { 37 s.StrokeLine(BPoint(0, y), BPoint(width - 1, y), pat); 38 } 39 for (uint32 x = 0; x <= width; x += 5) { 40 s.StrokeLine(BPoint(x, 0), BPoint(x, height - 1), pat); 41 } 42 43 s.Sync(); 44 45 return system_time() - now; 46 } 47 48 // test_fill_rect 49 template<class Surface> 50 bigtime_t 51 test_fill_rect(Surface& s, uint32 width, uint32 height) 52 { 53 bigtime_t now = system_time(); 54 55 s.SetPenSize(1.0); 56 s.SetDrawingMode(B_OP_COPY); 57 s.SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); 58 59 s.SetHighColor(0, 0, 0, 255); 60 s.SetLowColor(130, 0, 20, 255); 61 62 const pattern pat = B_SOLID_HIGH; 63 64 BRect r; 65 for (uint32 y = 10; y <= height; y += 20) { 66 for (uint32 x = 10; x <= width; x += 20) { 67 r.Set(x - 9, y - 9, x + 9, y + 9); 68 s.FillRect(r, pat); 69 } 70 } 71 72 s.Sync(); 73 74 return system_time() - now; 75 } 76 77 // test_ellipses 78 template<class Surface> 79 bigtime_t 80 test_ellipses(Surface& s, uint32 width, uint32 height) 81 { 82 bigtime_t now = system_time(); 83 84 s.SetPenSize(2.0); 85 s.SetDrawingMode(B_OP_COPY); 86 s.SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); 87 88 s.SetHighColor(0, 0, 0, 255); 89 s.SetLowColor(130, 0, 20, 255); 90 91 const pattern pat = B_SOLID_HIGH; 92 93 BPoint center(floorf(width / 2.0), floorf(height / 2.0)); 94 float xRadius = width / 2.0; 95 float yRadius = height / 2.0; 96 97 uint32 count = 40; 98 for (uint32 i = 0; i < count; i ++) { 99 s.StrokeEllipse(center, xRadius * (i / (float)count), 100 yRadius * (i / (float)count), pat); 101 } 102 103 s.Sync(); 104 105 return system_time() - now; 106 } 107 108 // test_lines 109 template<class Surface> 110 bigtime_t 111 test_lines(Surface& s, uint32 width, uint32 height) 112 { 113 bigtime_t now = system_time(); 114 115 s.SetPenSize(1.0); 116 s.SetDrawingMode(B_OP_COPY); 117 s.SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); 118 119 s.SetHighColor(0, 0, 0, 255); 120 s.SetLowColor(130, 0, 20, 255); 121 122 const pattern pat = B_SOLID_HIGH; 123 124 for (uint32 y = 0; y <= height; y += 10) { 125 s.StrokeLine(BPoint(0, 0), BPoint(width, y), pat); 126 s.StrokeLine(BPoint(width - 1, 0), BPoint(0, y), pat); 127 } 128 for (uint32 x = 0; x <= width; x += 10) { 129 s.StrokeLine(BPoint(0, 0), BPoint(x, height), pat); 130 s.StrokeLine(BPoint(width - 1, 0), BPoint(x, height), pat); 131 } 132 133 s.Sync(); 134 135 return system_time() - now; 136 } 137 138 // test 139 template<class Surface> 140 bigtime_t 141 test(Surface& s, uint32 width, uint32 height, BBitmap* testBitmap) 142 { 143 bigtime_t now = system_time(); 144 145 // TODO: Painter behaves differently when origin has subpixel offset 146 // BPoint origin(20.3, 10.8); 147 BPoint origin(20, 10); 148 149 BPoint center(width / 2.0, height / 2.0); 150 float xRadius = 30.0; 151 float yRadius = 20.0; 152 153 s.SetOrigin(origin); 154 s.SetScale(1.0); 155 156 s.SetDrawingMode(B_OP_COPY); 157 // s.SetDrawingMode(B_OP_SUBTRACT); 158 // s.SetDrawingMode(B_OP_OVER); 159 s.SetHighColor(20, 20, 20, 255); 160 s.SetLowColor(220, 120, 80, 255); 161 for (uint32 y = 0; y <= height / 2; y += 10) 162 s.StrokeLine(BPoint(0, 0), BPoint(width / 2, y)/*, kDottedBigger*/); 163 for (uint32 x = 0; x <= width; x += 10) 164 s.StrokeLine(BPoint(0, 0), BPoint(x, height)/*, kDottedBigger*/); 165 s.SetPenSize(1.0 * 5); 166 s.SetHighColor(255, 0, 0, 255); 167 s.SetLowColor(0, 0, 255, 255); 168 // s.SetScale(1.0); 169 // s.SetOrigin(B_ORIGIN); 170 // s.SetDrawingMode(B_OP_INVERT); 171 s.SetDrawingMode(B_OP_COPY); 172 // s.StrokeRect(BRect(20.2, 45.6, 219.0, 139.0)); 173 s.StrokeRect(BRect(20.2, 45.6, 219.0, 139.0), kStripes); 174 175 // s.ConstrainClipping(noClip); 176 /* s.SetPenLocation(BPoint(230.0, 30.0)); 177 s.StrokeLine(BPoint(250.0, 30.0)); 178 s.StrokeLine(BPoint(250.0, 50.0)); 179 s.StrokeLine(BPoint(230.0, 50.0)); 180 s.StrokeLine(BPoint(230.0, 30.0));*/ 181 182 s.SetHighColor(255, 255, 0, 255); 183 s.SetLowColor(128, 0, 50, 255); 184 // s.SetDrawingMode(B_OP_OVER); 185 s.SetDrawingMode(B_OP_ERASE); 186 s.StrokeEllipse(center, xRadius, yRadius, kDottedBigger); 187 s.SetHighColor(255, 0, 0, 255); 188 s.SetDrawingMode(B_OP_INVERT); 189 s.FillArc(center, xRadius * 2, yRadius * 2, 40.0, 230.0); 190 // s.StrokeArc(center, xRadius * 2, yRadius * 2, 40.0, 230.0); 191 s.SetDrawingMode(B_OP_OVER); 192 s.SetPenSize(2.0); 193 s.StrokeEllipse(center, xRadius * 3, yRadius * 2); 194 // s.FillEllipse(center, xRadius * 3, yRadius * 2); 195 // s.StrokeLine(bounds.RightTop()); 196 // s.FillRect(rect); 197 s.SetHighColor(0, 0, 255, 255); 198 s.SetLowColor(255, 0, 0, 255); 199 s.SetPenSize(1.0); 200 // s.SetDrawingMode(B_OP_SELECT); 201 s.StrokeRoundRect(BRect(40, 100, 250, 220.0), 40, 40); 202 // s.FillRoundRect(BRect(40, 100, 250, 220.0), 40, 40); 203 204 // text rendering 205 const char* string1 = "The Quick Brown Fox..."; 206 const char* string2 = "jumps!"; 207 BPoint stringLocation1(10.0, 220.0); 208 BPoint stringLocation2(30.0 / 2.5, 115.0 / 2.5); 209 210 BFont font(be_plain_font); 211 font.SetSize(12.0); 212 font.SetRotation(8.0); 213 // font.SetFamilyAndStyle(1); 214 215 s.SetFont(&font); 216 s.SetHighColor(91, 105, 98, 120); 217 s.SetDrawingMode(B_OP_OVER); 218 s.DrawString(string1, stringLocation1); 219 s.DrawString(string2); 220 s.StrokeLine(BPoint(width - 1, 0)); 221 222 // s.SetScale(2.5); 223 s.SetDrawingMode(B_OP_INVERT); 224 s.SetHighColor(200, 200, 200, 255); 225 s.DrawString("H", stringLocation2); 226 s.DrawString("e"); 227 s.DrawString("l"); 228 s.DrawString("l"); 229 s.DrawString("o"); 230 s.DrawString(" "); 231 s.DrawString("N"); 232 s.DrawString("u"); 233 s.DrawString("r"); 234 s.DrawString("s"); 235 s.DrawString("e"); 236 s.DrawString("!"); 237 // do the char locations match up? 238 // s.SetHighColor(0, 60, 240); 239 // s.DrawString("Hello Nurse!", stringLocation2); 240 241 // bitmap drawing 242 BRect testBitmapCrop(testBitmap->Bounds()); 243 testBitmapCrop.left += 20.0; 244 BRect testBitmapDestRect(testBitmapCrop); 245 testBitmapDestRect.OffsetBy(50, 20); 246 247 s.SetScale(1.5); 248 s.SetDrawingMode(B_OP_ALPHA); 249 s.SetHighColor(0, 0, 0, 120); 250 s.DrawBitmap(testBitmap, testBitmapCrop, testBitmapDestRect); 251 252 s.Sync(); 253 254 return system_time() - now; 255 } 256 257 258 259 // main 260 int 261 main(int argc, char **argv) 262 { 263 BApplication* app = new BApplication("application/x.vnd-YellowBites.TestApp"); 264 265 // create the default instance of the FontManager 266 // It takes a bit to scan through the font files; 267 // "true" means to do the font scanning inline, not 268 // in a separate thread. 269 fprintf(stdout, "scanning font files..."); 270 fflush(stdout); 271 FontManager::CreateDefault(true); 272 fprintf(stdout, "done\n"); 273 274 BRect bounds(0.0, 0.0, 319.0, 239.0); 275 276 // test the clipping 277 BRegion noClip(bounds); 278 279 int32 clipCount = 5; 280 BRegion clip; 281 float h = bounds.Width() / clipCount; 282 float v = bounds.Height() / clipCount; 283 float hInset = (h / 2.0) * 0.5; 284 float vInset = (v / 2.0) * 0.5; 285 for (int32 i = 0; i < clipCount; i++) { 286 /* BRect b(h * i, bounds.top, h * i, bounds.bottom); 287 b.InsetBy(-hInset, 0.0); 288 clip.Include(b); 289 b.Set(bounds.left, v * i, bounds.right, v * i); 290 b.InsetBy(0.0, -vInset); 291 clip.Include(b);*/ 292 BRect b(bounds.left, v * i, bounds.right, v * i); 293 b.InsetBy(0.0, -vInset); 294 clip.Include(b); 295 b.Set(h * i, bounds.top, h * i, bounds.bottom); 296 b.InsetBy(-hInset, 0.0); 297 clip.Include(b); 298 } 299 300 // prepare a test bitmap for bitmap rendering 301 BBitmap* testBitmap = new BBitmap(BRect(20, 0, 150, 50), 0, B_RGB32); 302 // fill testBitmap with content 303 uint8* bits = (uint8*)testBitmap->Bits(); 304 uint32 bitmapWidth = testBitmap->Bounds().IntegerWidth() + 1; 305 uint32 bitmapHeight = testBitmap->Bounds().IntegerHeight() + 1; 306 uint32 bpr = testBitmap->BytesPerRow(); 307 for (uint32 y = 0; y < bitmapHeight; y++) { 308 uint8* h = bits; 309 for (uint32 x = 0; x < bitmapWidth; x++) { 310 h[0] = (uint8)((float)x / (float)bitmapWidth * 255.0); 311 h[1] = (uint8)((float)y / (float)bitmapHeight * 255.0); 312 h[2] = 255 - (uint8)((float)y / (float)bitmapHeight * 255.0); 313 h[3] = (uint8)((float)y / (float)bitmapHeight * 255.0); 314 h += 4; 315 } 316 bits += bpr; 317 } 318 // make corners a black pixel for testing 319 bits = (uint8*)testBitmap->Bits(); 320 *(uint32*)(&bits[0]) = 0; 321 *(uint32*)(&bits[(bitmapWidth - 1) * 4]) = 0; 322 *(uint32*)(&bits[(bitmapHeight - 1) * bpr]) = 0; 323 *(uint32*)(&bits[(bitmapHeight - 1) * bpr + (bitmapWidth - 1) * 4]) = 0; 324 325 // create a frame buffer 326 BBitmap* bitmap = new BBitmap(bounds, B_RGB32); 327 //memset(bitmap->Bits(), 0, bitmap->BitsLength()); 328 BitmapBuffer* buffer = new BitmapBuffer(bitmap); 329 Painter painter; 330 painter.AttachToBuffer(buffer); 331 332 uint32 width = buffer->Width(); 333 uint32 height = buffer->Height(); 334 335 // painter.ConstrainClipping(clip); 336 337 int32 iterations = 40; 338 339 fprintf(stdout, "Painter..."); 340 fflush(stdout); 341 342 bigtime_t painterNow = 0; 343 for (int32 i = 0; i < iterations; i++) { 344 // reset bitmap contents 345 memset(bitmap->Bits(), 255, bitmap->BitsLength()); 346 // run test 347 // painterNow += test(painter, width, height, testBitmap); 348 // painterNow += test_lines(painter, width, height); 349 // painterNow += test_straight_lines(painter, width, height); 350 painterNow += test_fill_rect(painter, width, height); 351 // painterNow += test_ellipses(painter, width, height); 352 } 353 354 fprintf(stdout, " %lld µsecs\n", painterNow / iterations); 355 356 BitmapView* painterView = new BitmapView(bounds, "view", bitmap); 357 358 bitmap = new BBitmap(bounds, B_RGB32, true); 359 BView* view = new BView(bounds, NULL, B_FOLLOW_NONE, B_WILL_DRAW); 360 //memset(bitmap->Bits(), 0, bitmap->BitsLength()); 361 bitmap->Lock(); 362 bitmap->AddChild(view); 363 364 // view->ConstrainClippingRegion(&clip); 365 366 fprintf(stdout, "BView..."); 367 fflush(stdout); 368 369 bigtime_t viewNow = 0; 370 for (int32 i = 0; i < iterations; i++) { 371 // reset bitmap contents 372 memset(bitmap->Bits(), 255, bitmap->BitsLength()); 373 // run test 374 // viewNow += test(*view, width, height, testBitmap); 375 // viewNow += test_lines(*view, width, height); 376 // viewNow += test_straight_lines(*view, width, height); 377 viewNow += test_fill_rect(*view, width, height); 378 // viewNow += test_ellipses(*view, width, height); 379 } 380 381 bitmap->Unlock(); 382 383 fprintf(stdout, " %lld µsecs\n", viewNow / iterations); 384 385 if (painterNow > viewNow) 386 printf("BView is %.2f times faster.\n", (float)painterNow / (float)viewNow); 387 else 388 printf("Painter is %.2f times faster.\n", (float)viewNow / (float)painterNow); 389 390 391 BitmapView* bViewView = new BitmapView(bounds, "view", bitmap); 392 bViewView->MoveTo(BPoint(bounds.left, bounds.bottom + 1)); 393 394 BWindow* window = new BWindow(BRect(50.0, 50.0, 50.0 + bounds.Width(), 50.0 + bounds.Height() * 2 + 1), "Painter Test", 395 B_TITLED_WINDOW, 396 B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE); 397 398 window->AddChild(painterView); 399 window->AddChild(bViewView); 400 401 window->Show(); 402 app->Run(); 403 delete app; 404 return 0; 405 } 406