blend2d-debug.h (25827B)
1 // This file is part of Blend2D project <https://blend2d.com> 2 // 3 // See blend2d.h or LICENSE.md for license and copyright information 4 // SPDX-License-Identifier: Zlib 5 6 // ---------------------------------------------------------------------------- 7 // IMPORTANT: DO NOT USE THIS HEADER IN PRODUCTION, ONLY FOR BUG REPORTING! 8 // 9 // This file provides debug helpers that are not a part of Blend2D library. 10 // Functions this header provides are not exported, they are only provided 11 // for making it easier to report bugs and to give more information about the 12 // environment where such bugs happened to Blend2D developers. The functions 13 // defined below are not stable and are subject to change in future Blend2D 14 // releases. 15 // 16 // This file can be included by both C and C++ API users. 17 // ---------------------------------------------------------------------------- 18 19 #ifndef BLEND2D_DEBUG_H_INCLUDED 20 #define BLEND2D_DEBUG_H_INCLUDED 21 22 #include <stdio.h> 23 #include "blend2d.h" 24 25 //! \cond INTERNAL 26 27 // Forward Declarations 28 // ==================== 29 30 static void bl_debug_object_(const void* obj, const char* name, int indent); 31 32 // BLDebug - Begin 33 // =============== 34 35 #define BL_DEBUG_OUT(MSG) bl_runtime_message_fmt("%*s%s", indent * 2, "", MSG); 36 #define BL_DEBUG_FMT(FMT, ...) bl_runtime_message_fmt("%*s" FMT, indent * 2, "", __VA_ARGS__); 37 38 // BLDebug - Utilities 39 // =================== 40 41 static const char* bl_debug_get_enum_as_string(uint32_t value, const char* enum_data) { 42 uint32_t i = 0; 43 const char* p = enum_data; 44 45 while (i != value) { 46 // 0 indicates end of data. 47 if (!*p) 48 return "Unknown"; 49 50 // Skip the entire sub-string. 51 while (*++p) 52 continue; 53 54 i++; // Advance the current index. 55 p++; // Skip the zero value. 56 } 57 58 return p; 59 } 60 61 // BLDebug - Runtime 62 // ================= 63 64 static void bl_debug_runtime_cpu_features(char* buf, size_t buf_size, uint32_t arch, uint32_t features) { 65 if (!arch) { 66 #if defined(_M_X64) || defined(__x86_64__) || defined(_M_IX86) || defined(__X86__) || defined(__i386__) 67 arch = BL_RUNTIME_CPU_ARCH_X86; 68 #endif 69 70 #if defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__) || defined(__thumb2__) 71 arch = BL_RUNTIME_CPU_ARCH_ARM; 72 #endif 73 74 #if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) || defined(_MIPS_ARCH_MIPS32) || defined(_M_MRX000) || defined(__mips__) 75 arch = BL_RUNTIME_CPU_ARCH_MIPS; 76 #endif 77 } 78 79 switch (arch) { 80 case BL_RUNTIME_CPU_ARCH_X86: 81 snprintf(buf, buf_size, "%s%s%s%s%s%s%s%s", 82 (features & BL_RUNTIME_CPU_FEATURE_X86_SSE2 ) ? "SSE2 " : "", 83 (features & BL_RUNTIME_CPU_FEATURE_X86_SSE3 ) ? "SSE3 " : "", 84 (features & BL_RUNTIME_CPU_FEATURE_X86_SSSE3 ) ? "SSSE3 " : "", 85 (features & BL_RUNTIME_CPU_FEATURE_X86_SSE4_1) ? "SSE4.1 " : "", 86 (features & BL_RUNTIME_CPU_FEATURE_X86_SSE4_2) ? "SSE4.2 " : "", 87 (features & BL_RUNTIME_CPU_FEATURE_X86_AVX ) ? "AVX " : "", 88 (features & BL_RUNTIME_CPU_FEATURE_X86_AVX2 ) ? "AVX2 " : "", 89 (features & BL_RUNTIME_CPU_FEATURE_X86_AVX512) ? "AVX512 " : ""); 90 break; 91 92 default: 93 buf[0] = '\0'; 94 break; 95 } 96 } 97 98 //! Dumps `BLRuntimeBuildInfo` queried through `bl_runtime_query_info()`. 99 static void bl_debug_runtime_build_info(void) { 100 const char* build_mode = ""; 101 char baseline_cpu_features[128]; 102 char supported_cpu_features[128]; 103 104 BLRuntimeBuildInfo info; 105 bl_runtime_query_info(BL_RUNTIME_INFO_TYPE_BUILD, &info); 106 107 #if defined(BL_STATIC) 108 build_mode = "Static"; 109 #else 110 build_mode = "Shared"; 111 #endif 112 113 bl_debug_runtime_cpu_features(baseline_cpu_features, 128, 0, info.baseline_cpu_features); 114 bl_debug_runtime_cpu_features(supported_cpu_features, 128, 0, info.supported_cpu_features); 115 116 bl_runtime_message_fmt( 117 "BuildInformation: {\n" 118 " Version: %u.%u.%u\n" 119 " BuildType: %s\n" 120 " BuildMode: %s\n" 121 " BaselineCpuFeatures: %s\n" 122 " SupportedCpuFeatures: %s\n" 123 " Compiler: %s\n" 124 " MaxImageSize: %u\n" 125 " MaxThreadCount: %u\n" 126 "}\n", 127 info.major_version, 128 info.minor_version, 129 info.patch_version, 130 info.build_type == BL_RUNTIME_BUILD_TYPE_DEBUG ? "Debug" : "Release", 131 build_mode, 132 baseline_cpu_features, 133 supported_cpu_features, 134 info.compiler_info, 135 info.max_image_size, 136 info.max_thread_count); 137 } 138 139 //! Dumps `BLRuntimeSystemInfo` queried through `bl_runtime_query_info()`. 140 static void bl_debug_runtime_system_info(void) { 141 static const char cpu_arch_enum[] = 142 "NONE\0" 143 "X86\0" 144 "ARM\0" 145 "MIPS\0"; 146 147 const char* os = "Unknown"; 148 char cpu_features[128]; 149 150 BLRuntimeSystemInfo info; 151 bl_runtime_query_info(BL_RUNTIME_INFO_TYPE_SYSTEM, &info); 152 cpu_features[0] = '\0'; 153 154 #if defined(__linux__) 155 os = "Linux"; 156 #elif defined(__APPLE__) 157 os = "Apple"; 158 #elif defined(__DragonFly__) 159 os = "DragonFlyBSD"; 160 #elif defined(__FreeBSD__) 161 os = "FreeBSD"; 162 #elif defined(__NetBSD__) 163 os = "NetBSD"; 164 #elif defined(__OpenBSD__) 165 os = "OpenBSD"; 166 #elif defined(__HAIKU__) 167 os = "Haiku"; 168 #elif defined(_WIN32) 169 os = "Windows"; 170 #endif 171 172 bl_debug_runtime_cpu_features(cpu_features, 128, info.cpu_arch, info.cpu_features); 173 174 bl_runtime_message_fmt( 175 "SystemInformation: {\n" 176 " OperatingSystem: %s\n" 177 " CpuArch: %s [%u bit]\n" 178 " CpuFeatures: %s\n" 179 " ThreadCount: %u\n" 180 " ThreadStackSize: %u\n" 181 " AllocationGranularity: %u\n" 182 "}\n", 183 os, 184 bl_debug_get_enum_as_string(info.cpu_arch, cpu_arch_enum), sizeof(void*) >= 8 ? 64 : 32, 185 cpu_features, 186 info.thread_count, 187 info.thread_stack_size, 188 info.allocation_granularity); 189 } 190 191 // BLDebug - Matrix 192 // ================ 193 194 static void bl_debug_matrix2d_(const BLMatrix2D* obj, const char* name, int indent) { 195 static const char matrix_type_enum[] = 196 "IDENTITY\0" 197 "TRANSLATE\0" 198 "SCALE\0" 199 "SWAP\0" 200 "AFFINE\0" 201 "INVALID\0"; 202 203 BL_DEBUG_FMT("%s: [%s] {\n", name, bl_debug_get_enum_as_string(bl_matrix2d_get_type(obj), matrix_type_enum)); 204 BL_DEBUG_FMT(" [% 3.14f |% 3.14f]\n", obj->m00, obj->m01); 205 BL_DEBUG_FMT(" [% 3.14f |% 3.14f]\n", obj->m10, obj->m11); 206 BL_DEBUG_FMT(" [% 3.14f |% 3.14f]\n", obj->m20, obj->m21); 207 BL_DEBUG_OUT("}\n"); 208 } 209 210 // BLDebug - StrokeOptions 211 // ======================= 212 213 static void bl_debug_stroke_options_(const BLStrokeOptionsCore* obj, const char* name, int indent) { 214 static const char stroke_cap_position_enum[] = 215 "StartCap\0" 216 "EndCap\0"; 217 218 static const char stroke_cap_enum[] = 219 "BUTT\0" 220 "SQUARE\0" 221 "ROUND\0" 222 "ROUND_REV\0" 223 "TRIANGLE\0" 224 "TRIANGLE_REV\0"; 225 226 static const char stroke_join_enum[] = 227 "MITER_CLIP\0" 228 "MITER_BEVEL\0" 229 "MITER_ROUND\0" 230 "BEVEL\0ROUND\0"; 231 232 static const char stroke_transform_order_enum[] = 233 "AFTER\0" 234 "BEFORE\0"; 235 236 uint32_t i; 237 238 BL_DEBUG_FMT("%s: {\n", name); 239 indent++; 240 241 for (i = 0; i <= BL_STROKE_CAP_POSITION_MAX_VALUE; i++) 242 BL_DEBUG_FMT("%s: %s\n", bl_debug_get_enum_as_string(i, stroke_cap_position_enum), bl_debug_get_enum_as_string(obj->caps[i], stroke_cap_enum)); 243 BL_DEBUG_FMT("Join: %s\n", bl_debug_get_enum_as_string(obj->join, stroke_join_enum)); 244 BL_DEBUG_FMT("TransformOrder: %s\n", bl_debug_get_enum_as_string(obj->transform_order, stroke_transform_order_enum)); 245 BL_DEBUG_FMT("Width: %g\n", obj->width); 246 BL_DEBUG_FMT("MiterLimit: %g\n", obj->miter_limit); 247 BL_DEBUG_FMT("DashOffset: %g\n", obj->dash_offset); 248 bl_debug_object_(&obj->dash_array, "DashArray", indent); 249 250 indent--; 251 BL_DEBUG_OUT("}\n"); 252 } 253 static void bl_debug_stroke_options(const BLStrokeOptionsCore* obj) { bl_debug_stroke_options_(obj, "BLStrokeOptions", 0); } 254 255 // BLDebug - Array 256 // =============== 257 258 static void bl_debug_array_(const BLArrayCore* obj, const char* name, int indent) { 259 BLObjectType object_type = bl_var_get_type(obj); 260 const void* void_data = bl_array_get_data(obj); 261 262 size_t i; 263 size_t size = bl_array_get_size(obj); 264 265 if (size == 0) { 266 BL_DEBUG_FMT("%s: {}\n", name); 267 return; 268 } 269 270 BL_DEBUG_FMT("%s: {\n", name); 271 indent++; 272 273 switch (object_type) { 274 case BL_OBJECT_TYPE_ARRAY_OBJECT: { 275 char prefix[64]; 276 const BLObjectCore** data = (const BLObjectCore**)void_data; 277 for (i = 0; i < size; i++) { 278 snprintf(prefix, 64, "[%zu]", i); 279 bl_debug_object_(data[i], prefix, indent); 280 } 281 break; 282 } 283 case BL_OBJECT_TYPE_ARRAY_INT8: { 284 const int8_t* data = (const int8_t*)void_data; 285 for (i = 0; i < size; i++) 286 BL_DEBUG_FMT("[%zu] %d", i, data[i]); 287 break; 288 } 289 case BL_OBJECT_TYPE_ARRAY_UINT8: { 290 const uint8_t* data = (const uint8_t*)void_data; 291 for (i = 0; i < size; i++) 292 BL_DEBUG_FMT("[%zu] %u", i, data[i]); 293 break; 294 } 295 case BL_OBJECT_TYPE_ARRAY_INT16: { 296 const int16_t* data = (const int16_t*)void_data; 297 for (i = 0; i < size; i++) 298 BL_DEBUG_FMT("[%zu] %d", i, data[i]); 299 break; 300 } 301 case BL_OBJECT_TYPE_ARRAY_UINT16: { 302 const uint16_t* data = (const uint16_t*)void_data; 303 for (i = 0; i < size; i++) 304 BL_DEBUG_FMT("[%zu] %u", i, data[i]); 305 break; 306 } 307 case BL_OBJECT_TYPE_ARRAY_INT32: { 308 const int32_t* data = (const int32_t*)void_data; 309 for (i = 0; i < size; i++) 310 BL_DEBUG_FMT("[%zu] %d", i, data[i]); 311 break; 312 } 313 case BL_OBJECT_TYPE_ARRAY_UINT32: { 314 const uint32_t* data = (const uint32_t*)void_data; 315 for (i = 0; i < size; i++) 316 BL_DEBUG_FMT("[%zu] %u", i, data[i]); 317 break; 318 } 319 case BL_OBJECT_TYPE_ARRAY_INT64: { 320 const int64_t* data = (const int64_t*)void_data; 321 for (i = 0; i < size; i++) 322 BL_DEBUG_FMT("[%zu] %lld", i, (long long)data[i]); 323 break; 324 } 325 case BL_OBJECT_TYPE_ARRAY_UINT64: { 326 const uint64_t* data = (const uint64_t*)void_data; 327 for (i = 0; i < size; i++) 328 BL_DEBUG_FMT("[%zu] %llu", i, (unsigned long long)data[i]); 329 break; 330 } 331 case BL_OBJECT_TYPE_ARRAY_FLOAT32: { 332 const float* data = (const float*)void_data; 333 for (i = 0; i < size; i++) 334 BL_DEBUG_FMT("[%zu] %g", i, data[i]); 335 break; 336 } 337 case BL_OBJECT_TYPE_ARRAY_FLOAT64: { 338 const double* data = (const double*)void_data; 339 for (i = 0; i < size; i++) 340 BL_DEBUG_FMT("[%zu] %g", i, data[i]); 341 break; 342 } 343 default: 344 break; 345 } 346 347 indent--; 348 BL_DEBUG_OUT("}\n"); 349 } 350 351 // BLDebug - Image 352 // =============== 353 354 static void bl_debug_image_(const BLImageCore* obj, const char* name, int indent) { 355 static const char format_enum[] = 356 "NONE\0" 357 "PRGB32\0" 358 "XRGB32\0" 359 "A8\0"; 360 361 BLImageData data; 362 bl_image_get_data(obj, &data); 363 364 BL_DEBUG_FMT("%s: {\n", name); 365 BL_DEBUG_FMT(" Size: %ux%u\n", data.size.w, data.size.h); 366 BL_DEBUG_FMT(" Format: %s\n", bl_debug_get_enum_as_string(data.format, format_enum)); 367 BL_DEBUG_OUT("}\n"); 368 } 369 370 // BLDebug - Pattern 371 // ================= 372 373 static void bl_debug_pattern_(const BLPatternCore* obj, const char* name, int indent) { 374 static const char extend_mode_enum[] = 375 "PAD\0" 376 "REPEAT\0" 377 "REFLECT\0" 378 "PAD_X_REPEAT_Y\0" 379 "PAD_X_REFLECT_Y\0" 380 "REPEAT_X_PAD_Y\0" 381 "REPEAT_X_REFLECT_Y\0" 382 "REFLECT_X_PAD_Y\0" 383 "REFLECT_X_REPEAT_Y\0"; 384 385 BLImageCore image; 386 BLMatrix2D transform; 387 388 BLExtendMode extend_mode = bl_pattern_get_extend_mode(obj); 389 390 bl_image_init(&image); 391 bl_pattern_get_image(obj, &image); 392 bl_pattern_get_transform(obj, &transform); 393 394 BL_DEBUG_FMT("%s: {\n", name); 395 { 396 indent++; 397 bl_debug_image_(&image, "Image", indent); 398 BL_DEBUG_FMT("ExtendMode: %s\n", bl_debug_get_enum_as_string(extend_mode, extend_mode_enum)); 399 bl_debug_matrix2d_(&transform, "Transform", indent); 400 indent--; 401 } 402 BL_DEBUG_OUT("}\n"); 403 404 bl_image_destroy(&image); 405 } 406 407 // BLDebug - Gradient 408 // ================== 409 410 static void bl_debug_gradient_(const BLGradientCore* obj, const char* name, int indent) { 411 static const char gradient_type_enum[] = 412 "LINEAR\0" 413 "RADIAL\0" 414 "CONIC\0"; 415 416 static const char extend_mode_enum[] = 417 "PAD\0" 418 "REPEAT\0" 419 "REFLECT\0"; 420 421 size_t i; 422 size_t value_count = 0; 423 BLMatrix2D transform; 424 425 BLGradientType gradient_type = bl_gradient_get_type(obj); 426 BLExtendMode extend_mode = bl_gradient_get_extend_mode(obj); 427 size_t stop_count = bl_gradient_get_size(obj); 428 const BLGradientStop* stop_data = bl_gradient_get_stops(obj); 429 430 bl_gradient_get_transform(obj, &transform); 431 432 switch (gradient_type) { 433 case BL_GRADIENT_TYPE_LINEAR: value_count = 4; break; 434 case BL_GRADIENT_TYPE_RADIAL: value_count = 5; break; 435 case BL_GRADIENT_TYPE_CONIC : value_count = 3; break; 436 default: break; 437 } 438 439 double vals[6]; 440 for (i = 0; i < value_count; i++) 441 vals[i] = bl_gradient_get_value(obj, i); 442 443 BL_DEBUG_FMT("%s: {\n", name); 444 { 445 indent++; 446 BL_DEBUG_FMT("Type: %s\n", bl_debug_get_enum_as_string(gradient_type, gradient_type_enum)); 447 BL_DEBUG_FMT("ExtendMode: %s\n", bl_debug_get_enum_as_string(extend_mode, extend_mode_enum)); 448 449 switch (gradient_type) { 450 case BL_GRADIENT_TYPE_LINEAR: 451 BL_DEBUG_FMT("Values: Start=[%f, %f], End=[%f, %f]\n", 452 vals[0], vals[1], 453 vals[2], vals[3]); 454 break; 455 456 case BL_GRADIENT_TYPE_RADIAL: 457 BL_DEBUG_FMT("Values: Center=[%f, %f], Focal=[%f, %f] R=%f\n", 458 vals[0], vals[1], 459 vals[2], vals[3], 460 vals[4]); 461 break; 462 463 case BL_GRADIENT_TYPE_CONIC: 464 BL_DEBUG_FMT("Values: Center=[%f, %f], Angle=%f\n", 465 vals[0], vals[1], 466 vals[2]); 467 break; 468 469 default: 470 break; 471 } 472 473 BL_DEBUG_OUT("Stops: {\n"); 474 indent++; 475 for (i = 0; i < stop_count; i++) { 476 uint64_t rgba64 = stop_data[i].rgba.value; 477 BL_DEBUG_FMT("[%zu] Offset=%f BLRgba64(R=%d, G=%d, B=%d, A=%d)\n", 478 i, 479 stop_data[i].offset, 480 (rgba64 >> 32) & 0xFFFF, 481 (rgba64 >> 16) & 0xFFFF, 482 (rgba64 >> 0) & 0xFFFF, 483 (rgba64 >> 48) & 0xFFFF); 484 } 485 indent--; 486 BL_DEBUG_OUT("}\n"); 487 488 bl_debug_matrix2d_(&transform, "Transform", indent); 489 indent--; 490 } 491 BL_DEBUG_OUT("}\n"); 492 } 493 494 // BLDebug - Path 495 // ============== 496 497 static void bl_debug_path_(const BLPathCore* obj, const char* name, int indent) { 498 size_t i = 0; 499 size_t size = bl_path_get_size(obj); 500 501 const uint8_t* cmd = bl_path_get_command_data(obj); 502 const BLPoint* vtx = bl_path_get_vertex_data(obj); 503 504 BL_DEBUG_FMT("%s: {\n", name); 505 indent++; 506 507 while (i < size) { 508 switch (cmd[i]) { 509 case BL_PATH_CMD_MOVE: 510 BL_DEBUG_FMT("p.move_to(%g, %g);\n", vtx[i].x, vtx[i].y); 511 i++; 512 continue; 513 case BL_PATH_CMD_ON: 514 BL_DEBUG_FMT("p.line_to(%g, %g);\n", vtx[i].x, vtx[i].y); 515 i++; 516 continue; 517 case BL_PATH_CMD_QUAD: 518 if ((size - i) < 2) 519 break; 520 BL_DEBUG_FMT("p.quad_to(%g, %g, %g, %g);\n", vtx[i].x, vtx[i].y, vtx[i+1].x, vtx[i+1].y); 521 i += 2; 522 continue; 523 case BL_PATH_CMD_CUBIC: 524 if ((size - i) < 3) 525 break; 526 BL_DEBUG_FMT("p.cubic_to(%g, %g, %g, %g, %g, %g);\n", vtx[i].x, vtx[i].y, vtx[i+1].x, vtx[i+1].y, vtx[i+2].x, vtx[i+2].y); 527 i += 3; 528 continue; 529 case BL_PATH_CMD_CLOSE: 530 BL_DEBUG_OUT("p.close();\n"); 531 i++; 532 continue; 533 } 534 535 BL_DEBUG_FMT("p.unknown_command(%u, %g, %g);\n", cmd[i], vtx[i].x, vtx[i].y); 536 i++; 537 } 538 539 indent--; 540 BL_DEBUG_OUT("}\n"); 541 } 542 543 // BLDebug - FontFeatureSettings 544 // ============================= 545 546 static void bl_debug_font_feature_settings_(const BLFontFeatureSettingsCore* obj, const char* name, int indent) { 547 size_t i; 548 BLFontFeatureSettingsView view; 549 550 bl_font_feature_settings_get_view(obj, &view); 551 552 if (view.size == 0) { 553 BL_DEBUG_FMT("%s: {}\n", name); 554 } 555 else { 556 BL_DEBUG_FMT("%s: {\n", name); 557 indent++; 558 559 for (i = 0; i < view.size; i++) { 560 BLTag tag = view.data[i].tag; 561 uint32_t value = view.data[i].value; 562 BL_DEBUG_FMT("'%c%c%c%c': %u\n", 563 (tag >> 24) & 0xFF, 564 (tag >> 16) & 0xFF, 565 (tag >> 8) & 0xFF, 566 (tag >> 0) & 0xFF, 567 (unsigned)value); 568 } 569 570 indent--; 571 BL_DEBUG_OUT("}\n"); 572 } 573 } 574 575 // BLDebug - FontVariationSettings 576 // ============================== 577 578 static void bl_debug_font_variation_settings_(const BLFontVariationSettingsCore* obj, const char* name, int indent) { 579 size_t i; 580 BLFontVariationSettingsView view; 581 582 bl_font_variation_settings_get_view(obj, &view); 583 584 if (view.size == 0) { 585 BL_DEBUG_FMT("%s: {}\n", name); 586 } 587 else { 588 BL_DEBUG_FMT("%s: {\n", name); 589 indent++; 590 591 for (i = 0; i < view.size; i++) { 592 BLTag tag = view.data[i].tag; 593 float value = view.data[i].value; 594 BL_DEBUG_FMT("'%c%c%c%c': %f\n", 595 (tag >> 24) & 0xFF, 596 (tag >> 16) & 0xFF, 597 (tag >> 8) & 0xFF, 598 (tag >> 0) & 0xFF, 599 value); 600 } 601 602 indent--; 603 BL_DEBUG_OUT("}\n"); 604 } 605 } 606 607 // BLDebug - Font 608 // ============== 609 610 static void bl_debug_font_(const BLFontCore* obj, const char* name, int indent) { 611 float size = bl_font_get_size(obj); 612 613 BLStringCore str; 614 BLFontFaceCore face; 615 BLFontFeatureSettingsCore features; 616 BLFontVariationSettingsCore variations; 617 618 bl_string_init(&str); 619 bl_font_face_init(&face); 620 bl_font_feature_settings_init(&features); 621 bl_font_variation_settings_init(&variations); 622 623 bl_font_get_face(obj, &face); 624 bl_font_get_feature_settings(obj, &features); 625 bl_font_get_variation_settings(obj, &variations); 626 627 BL_DEBUG_FMT("%s: {\n", name); 628 { 629 indent++; 630 bl_font_face_get_family_name(&face, &str); 631 BL_DEBUG_FMT("Face: %s\n", bl_string_get_data(&str)); 632 BL_DEBUG_FMT("Size: %f\n", size); 633 bl_debug_font_feature_settings_(&features, "FeatureSettings", indent); 634 bl_debug_font_variation_settings_(&variations, "VariationSettings", indent); 635 indent--; 636 } 637 BL_DEBUG_OUT("}\n"); 638 639 bl_font_variation_settings_destroy(&variations); 640 bl_font_feature_settings_destroy(&features); 641 bl_font_face_destroy(&face); 642 bl_string_destroy(&str); 643 } 644 645 // BLDebug - Context 646 // ================= 647 648 static void bl_debug_context_(const BLContextCore* obj, const char* name, int indent) { 649 static const char context_type_enum[] = 650 "NONE\0" 651 "DUMMY\0" 652 "PROXY\0" 653 "RASTER\0"; 654 655 static const char fill_rule_enum[] = 656 "NON_ZERO\0" 657 "EVEN_ODD\0"; 658 659 const BLContextState* state = ((BLContextImpl*)obj->_d.impl)->state; 660 661 BLVarCore fill_style; 662 BLVarCore stroke_style; 663 664 bl_var_init_null(&fill_style); 665 bl_var_init_null(&stroke_style); 666 667 bl_context_get_transformed_fill_style(obj, &fill_style); 668 bl_context_get_transformed_stroke_style(obj, &stroke_style); 669 670 BL_DEBUG_FMT("%s: {\n", name); 671 { 672 indent++; 673 BL_DEBUG_FMT("Type: %s\n", bl_debug_get_enum_as_string(bl_context_get_type(obj), context_type_enum)); 674 BL_DEBUG_FMT("GlobalAlpha: %f\n", state->global_alpha); 675 BL_DEBUG_FMT("SavedStateCount: %u\n", state->saved_state_count); 676 677 bl_debug_matrix2d_(&state->meta_transform, "MetaTransform", indent); 678 bl_debug_matrix2d_(&state->user_transform, "UserTransform", indent); 679 bl_debug_matrix2d_(&state->final_transform, "FinalTransform", indent); 680 681 bl_debug_object_(&fill_style, "FillStyle", indent); 682 BL_DEBUG_FMT("FillAlpha: %f\n", state->style_alpha[BL_CONTEXT_STYLE_SLOT_FILL]); 683 BL_DEBUG_FMT("FillRule: %s\n", bl_debug_get_enum_as_string(state->fill_rule, fill_rule_enum)); 684 685 bl_debug_object_(&fill_style, "StrokeStyle", indent); 686 BL_DEBUG_FMT("StrokeAlpha: %f\n", state->style_alpha[BL_CONTEXT_STYLE_SLOT_STROKE]); 687 bl_debug_stroke_options_(&state->stroke_options, "StrokeOptions", indent); 688 indent--; 689 } 690 BL_DEBUG_OUT("}\n"); 691 692 bl_var_destroy(&stroke_style); 693 bl_var_destroy(&fill_style); 694 } 695 696 // BLDebug - Object 697 // ================ 698 699 static void bl_debug_object_(const void* obj, const char* name, int indent) { 700 BLObjectType type = bl_var_get_type(obj); 701 switch (type) { 702 case BL_OBJECT_TYPE_RGBA: { 703 BLRgba rgba; 704 bl_var_to_rgba(obj, &rgba); 705 BL_DEBUG_FMT("%s: Rgba(R=%f, G=%f, B=%f, A=%f)\n", 706 name, 707 rgba.r, 708 rgba.g, 709 rgba.b, 710 rgba.a); 711 break; 712 } 713 714 case BL_OBJECT_TYPE_RGBA32: { 715 uint32_t rgba32; 716 bl_var_to_rgba32(obj, &rgba32); 717 BL_DEBUG_FMT("%s: BLRgba32(R=%d, G=%d, B=%d, A=%d)\n", 718 name, 719 (rgba32 >> 16) & 0xFF, 720 (rgba32 >> 8) & 0xFF, 721 (rgba32 >> 0) & 0xFF, 722 (rgba32 >> 24) & 0xFF); 723 break; 724 } 725 726 case BL_OBJECT_TYPE_RGBA64: { 727 uint64_t rgba64; 728 bl_var_to_rgba64(obj, &rgba64); 729 BL_DEBUG_FMT("%s: BLRgba64(R=%d, G=%d, B=%d, A=%d)\n", 730 name, 731 (rgba64 >> 32) & 0xFFFF, 732 (rgba64 >> 16) & 0xFFFF, 733 (rgba64 >> 0) & 0xFFFF, 734 (rgba64 >> 48) & 0xFFFF); 735 break; 736 } 737 738 case BL_OBJECT_TYPE_NULL: { 739 BL_DEBUG_FMT("%s: Null\n", name); 740 break; 741 } 742 743 case BL_OBJECT_TYPE_PATTERN: { 744 bl_debug_pattern_((const BLPatternCore*)obj, name, indent); 745 break; 746 } 747 748 case BL_OBJECT_TYPE_GRADIENT: { 749 bl_debug_gradient_((const BLGradientCore*)obj, name, indent); 750 break; 751 } 752 753 case BL_OBJECT_TYPE_IMAGE: { 754 bl_debug_image_((const BLImageCore*)obj, name, indent); 755 break; 756 } 757 758 case BL_OBJECT_TYPE_PATH: { 759 bl_debug_path_((const BLPathCore*)obj, name, indent); 760 break; 761 } 762 763 case BL_OBJECT_TYPE_FONT: { 764 bl_debug_font_((BLFontCore*)obj, name, indent); 765 break; 766 } 767 768 case BL_OBJECT_TYPE_FONT_FEATURE_SETTINGS: { 769 bl_debug_font_feature_settings_((BLFontFeatureSettingsCore*)obj, name, indent); 770 break; 771 } 772 773 case BL_OBJECT_TYPE_FONT_VARIATION_SETTINGS: { 774 bl_debug_font_variation_settings_((BLFontVariationSettingsCore*)obj, name, indent); 775 break; 776 } 777 778 case BL_OBJECT_TYPE_BOOL: { 779 bool val; 780 bl_var_to_bool(obj, &val); 781 BL_DEBUG_FMT("%s: Bool(%s)\n", name, val ? "true" : "false"); 782 break; 783 } 784 785 case BL_OBJECT_TYPE_INT64: { 786 int64_t val; 787 bl_var_to_int64(obj, &val); 788 BL_DEBUG_FMT("%s: Int64(%lld)\n", name, (long long)val); 789 break; 790 } 791 792 case BL_OBJECT_TYPE_UINT64: { 793 uint64_t val; 794 bl_var_to_uint64(obj, &val); 795 BL_DEBUG_FMT("%s: UInt64(%llu)\n", name, (unsigned long long)val); 796 break; 797 } 798 799 case BL_OBJECT_TYPE_DOUBLE: { 800 double val; 801 bl_var_to_double(obj, &val); 802 BL_DEBUG_FMT("%s: Double(%f)\n", name, val); 803 break; 804 } 805 806 case BL_OBJECT_TYPE_ARRAY_OBJECT: 807 case BL_OBJECT_TYPE_ARRAY_INT8: 808 case BL_OBJECT_TYPE_ARRAY_UINT8: 809 case BL_OBJECT_TYPE_ARRAY_INT16: 810 case BL_OBJECT_TYPE_ARRAY_UINT16: 811 case BL_OBJECT_TYPE_ARRAY_INT32: 812 case BL_OBJECT_TYPE_ARRAY_UINT32: 813 case BL_OBJECT_TYPE_ARRAY_INT64: 814 case BL_OBJECT_TYPE_ARRAY_UINT64: 815 case BL_OBJECT_TYPE_ARRAY_FLOAT32: 816 case BL_OBJECT_TYPE_ARRAY_FLOAT64: 817 case BL_OBJECT_TYPE_ARRAY_STRUCT_1: 818 case BL_OBJECT_TYPE_ARRAY_STRUCT_2: 819 case BL_OBJECT_TYPE_ARRAY_STRUCT_3: 820 case BL_OBJECT_TYPE_ARRAY_STRUCT_4: 821 case BL_OBJECT_TYPE_ARRAY_STRUCT_6: 822 case BL_OBJECT_TYPE_ARRAY_STRUCT_8: 823 case BL_OBJECT_TYPE_ARRAY_STRUCT_10: 824 case BL_OBJECT_TYPE_ARRAY_STRUCT_12: 825 case BL_OBJECT_TYPE_ARRAY_STRUCT_16: 826 case BL_OBJECT_TYPE_ARRAY_STRUCT_20: 827 case BL_OBJECT_TYPE_ARRAY_STRUCT_24: 828 case BL_OBJECT_TYPE_ARRAY_STRUCT_32: 829 bl_debug_array_((const BLArrayCore*)obj, name, indent); 830 break; 831 832 case BL_OBJECT_TYPE_CONTEXT: 833 bl_debug_context_((const BLContextCore*)obj, name, indent); 834 break; 835 836 default: 837 BL_DEBUG_FMT("BLObject { Type: %u }\n", (uint32_t)type); 838 break; 839 } 840 } 841 842 // BLDebug - Public API 843 // ==================== 844 845 //! Dumps both `BLRuntimeBuildInfo` and `BLRuntimeSystemInfo`. 846 //! 847 //! This function should be used to retrieve information for Blend2D bug reports. 848 static void bl_debug_runtime(void) { 849 bl_debug_runtime_build_info(); 850 bl_debug_runtime_system_info(); 851 } 852 853 //! Dumps BLArrayCore or BLArray<T>. 854 static void bl_debug_array(const BLArrayCore* obj) { 855 bl_debug_array_(obj, "BLArray", 0); 856 } 857 858 //! Dumps BLContextCore or BLContext. 859 static void bl_debug_context(const BLContextCore* obj) { 860 bl_debug_context_(obj, "BLContext", 0); 861 } 862 863 //! Dumps BLFontCore or BLFont. 864 static void bl_debug_font(const BLFontCore* obj) { 865 bl_debug_font_(obj, "BLFont", 0); 866 } 867 868 //! Dumps BLFontFeatureSettingsCore or BLFontFeatureSettings. 869 static void bl_debug_font_feature_settings(const BLFontFeatureSettingsCore* obj) { 870 bl_debug_font_feature_settings_(obj, "BLFontFeatureSettings", 0); 871 } 872 873 //! Dumps BLFontVariationSettingsCore or BLFontVariationSettings. 874 static void bl_debug_font_variation_settings(const BLFontVariationSettingsCore* obj) { 875 bl_debug_font_variation_settings_(obj, "BLFontVariationSettings", 0); 876 } 877 878 //! Dumps BLGradientCore or BLGradient. 879 static void bl_debug_gradient(const BLGradientCore* obj) { 880 bl_debug_gradient_(obj, "BLGradient", 0); 881 } 882 883 //! Dumps BLImageCore or BLImage. 884 static void bl_debug_image(const BLImageCore* obj) { 885 bl_debug_image_(obj, "BLImage", 0); 886 } 887 888 static void bl_debug_matrix2d(const BLMatrix2D* obj) { 889 bl_debug_matrix2d_(obj, "BLMatrix", 0); 890 } 891 892 //! Dumps BLObjectCore or BLObject. 893 //! 894 //! You can use this function with any object that implements `BLObject` interface. 895 static void bl_debug_object(const void* obj) { 896 bl_debug_object_(obj, "BLObject", 0); 897 } 898 899 //! Dumps BLPathCore or BLPath. 900 static void bl_debug_path(const BLPathCore* obj) { 901 bl_debug_path_(obj, "BLPath", 0); 902 } 903 904 //! Dumps BLPatternCore or BLPattern. 905 static void bl_debug_pattern(const BLPatternCore* obj) { 906 bl_debug_pattern_(obj, "BLPattern", 0); 907 } 908 909 // BLDebug - End 910 // ============= 911 912 #undef BL_DEBUG_FMT 913 #undef BL_DEBUG_OUT 914 915 //! \endcond 916 917 #endif // BLEND2D_DEBUG_H_INCLUDED